wiki.techinc.nl/includes/tidy/RaggettWrapper.php
Tim Starling d3d682fb45 Hide marked empty elements by default (stage 1)
We originally imagined rolling out the display of empty elements
simultaneously with the Html5Depurate, but now we have added support for
marking empty elements to Html5Depurate and plan on having some sort of
longer migration period. So, move the relevant CSS to content.css, and
remove the concept of CSS dependant on tidy driver.

Add a body class which will allow the effect to be toggled in a gadget or
extension. Actual toggling in the CSS will be in the stage 2 patch, to be
deployed after the varnish cache and parser cache have expired.

I originally imagined that there would be a gadget that overrides the
rule with an !important selector, but that method does not allow you to
recover the original display property, which is often overridden by the
style attribute or site CSS to be "inline".

Also, in RaggettWrapper, switch to the new class mw-empty-elt, following
Html5Depurate, instead of mw-empty-li. The old class will be removed in
the stage 2 patch.

Change-Id: Ic0f432c43a006629ca5a1a7c2dda3552ceb4dc4f
2016-07-14 14:24:27 -07:00

96 lines
2.9 KiB
PHP

<?php
namespace MediaWiki\Tidy;
use ReplacementArray;
use ParserOutput;
use Parser;
/**
* Class used to hide mw:editsection tokens from Tidy so that it doesn't break them
* or break on them. This is a bit of a hack for now, but hopefully in the future
* we may create a real postprocessor or something that will replace this.
* It's called wrapper because for now it basically takes over MWTidy::tidy's task
* of wrapping the text in a xhtml block
*
* This re-uses some of the parser's UNIQ tricks, though some of it is private so it's
* duplicated. Perhaps we should create an abstract marker hiding class.
*
* @ingroup Parser
*/
class RaggettWrapper {
/**
* @var ReplacementArray
*/
protected $mTokens;
protected $mMarkerIndex;
public function __construct() {
$this->mTokens = null;
}
/**
* @param string $text
* @return string
*/
public function getWrapped( $text ) {
$this->mTokens = new ReplacementArray;
$this->mMarkerIndex = 0;
// Replace <mw:editsection> elements with placeholders
$wrappedtext = preg_replace_callback( ParserOutput::EDITSECTION_REGEX,
[ &$this, 'replaceCallback' ], $text );
// ...and <mw:toc> markers
$wrappedtext = preg_replace_callback( '/\<\\/?mw:toc\>/',
[ &$this, 'replaceCallback' ], $wrappedtext );
// ... and <math> tags
$wrappedtext = preg_replace_callback( '/\<math(.*?)\<\\/math\>/s',
[ &$this, 'replaceCallback' ], $wrappedtext );
// Modify inline Microdata <link> and <meta> elements so they say <html-link> and <html-meta> so
// we can trick Tidy into not stripping them out by including them in tidy's new-empty-tags config
$wrappedtext = preg_replace( '!<(link|meta)([^>]*?)(/{0,1}>)!', '<html-$1$2$3', $wrappedtext );
// Preserve empty li elements (T49673) by abusing Tidy's datafld hack
// The whitespace class is as in TY_(InitMap)
$wrappedtext = preg_replace( "!<li>([ \r\n\t\f]*)</li>!",
'<li datafld="" class="mw-empty-elt">\1</li>', $wrappedtext );
// Wrap the whole thing in a doctype and body for Tidy.
$wrappedtext = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' .
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>' .
'<head><title>test</title></head><body>' . $wrappedtext . '</body></html>';
return $wrappedtext;
}
/**
* @param array $m
*
* @return string
*/
public function replaceCallback( $m ) {
$marker = Parser::MARKER_PREFIX . "-item-{$this->mMarkerIndex}" . Parser::MARKER_SUFFIX;
$this->mMarkerIndex++;
$this->mTokens->setPair( $marker, $m[0] );
return $marker;
}
/**
* @param string $text
* @return string
*/
public function postprocess( $text ) {
// Revert <html-{link,meta}> back to <{link,meta}>
$text = preg_replace( '!<html-(link|meta)([^>]*?)(/{0,1}>)!', '<$1$2$3', $text );
// Remove datafld
$text = str_replace( '<li datafld=""', '<li', $text );
// Restore the contents of placeholder tokens
$text = $this->mTokens->replace( $text );
return $text;
}
}