X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FHtml.php;h=48b30c7802d8eba18eb493feb7e2bd367cfa1175;hb=4a2085523fce81ba4d75eb6946f5c7ae069bb1d2;hp=890beb0e0d767cad0ccddb5ece7ed7318c8c8a6e;hpb=29906d505b9b3d5f0fd1e6534f077b7fe2c623dc;p=lhc%2Fweb%2Fwiklou.git
diff --git a/includes/Html.php b/includes/Html.php
index 890beb0e0d..48b30c7802 100644
--- a/includes/Html.php
+++ b/includes/Html.php
@@ -38,8 +38,6 @@
*
* $wgMimeType: If this is set to an xml MIME type then output should be
* valid XHTML5.
- * $wgWellFormedXml: If this is set to true, then all output should be
- * well-formed XML (quotes on attributes, self-closing tags, etc.).
*
* This class is meant to be confined to utility functions that are called from
* trusted code paths. It does not do enforcement of policy like not allowing
@@ -48,13 +46,12 @@
* @since 1.16
*/
class Html {
- // List of void elements from HTML5, section 8.1.2 as of 2011-08-12
+ // List of void elements from HTML5, section 8.1.2 as of 2016-09-19
private static $voidElements = [
'area',
'base',
'br',
'col',
- 'command',
'embed',
'hr',
'img',
@@ -158,8 +155,8 @@ class Html {
*
* @param string $contents The raw HTML contents of the element: *not*
* escaped!
- * @param array $attrs Associative array of attributes, e.g., array(
- * 'href' => 'http://www.mediawiki.org/' ). See expandAttributes() for
+ * @param array $attrs Associative array of attributes, e.g., [
+ * 'href' => 'http://www.mediawiki.org/' ]. See expandAttributes() for
* further documentation.
* @param string[] $modifiers classes to add to the button
* @see http://tools.wmflabs.org/styleguide/desktop/index.html for guidance on available modifiers
@@ -178,8 +175,8 @@ class Html {
*
* @param string $contents The raw HTML contents of the element: *not*
* escaped!
- * @param array $attrs Associative array of attributes, e.g., array(
- * 'href' => 'http://www.mediawiki.org/' ). See expandAttributes() for
+ * @param array $attrs Associative array of attributes, e.g., [
+ * 'href' => 'http://www.mediawiki.org/' ]. See expandAttributes() for
* further documentation.
* @param string[] $modifiers classes to add to the button
* @see http://tools.wmflabs.org/styleguide/desktop/index.html for guidance on available modifiers
@@ -199,26 +196,21 @@ class Html {
* This is quite similar to Xml::tags(), but it implements some useful
* HTML-specific logic. For instance, there is no $allowShortTag
* parameter: the closing tag is magically omitted if $element has an empty
- * content model. If $wgWellFormedXml is false, then a few bytes will be
- * shaved off the HTML output as well.
+ * content model.
*
* @param string $element The element's name, e.g., 'a'
- * @param array $attribs Associative array of attributes, e.g., array(
- * 'href' => 'http://www.mediawiki.org/' ). See expandAttributes() for
+ * @param array $attribs Associative array of attributes, e.g., [
+ * 'href' => 'http://www.mediawiki.org/' ]. See expandAttributes() for
* further documentation.
* @param string $contents The raw HTML contents of the element: *not*
* escaped!
* @return string Raw HTML
*/
public static function rawElement( $element, $attribs = [], $contents = '' ) {
- global $wgWellFormedXml;
$start = self::openElement( $element, $attribs );
if ( in_array( $element, self::$voidElements ) ) {
- if ( $wgWellFormedXml ) {
- // Silly XML.
- return substr( $start, 0, -1 ) . '/>';
- }
- return $start;
+ // Silly XML.
+ return substr( $start, 0, -1 ) . '/>';
} else {
return "$start$contents" . self::closeElement( $element );
}
@@ -328,8 +320,8 @@ class Html {
* to the input array (currently per the HTML 5 draft as of 2009-09-06).
*
* @param string $element Name of the element, e.g., 'a'
- * @param array $attribs Associative array of attributes, e.g., array(
- * 'href' => 'http://www.mediawiki.org/' ). See expandAttributes() for
+ * @param array $attribs Associative array of attributes, e.g., [
+ * 'href' => 'http://www.mediawiki.org/' ]. See expandAttributes() for
* further documentation.
* @return array An array of attributes functionally identical to $attribs
*/
@@ -346,7 +338,6 @@ class Html {
'height' => '150',
'width' => '300',
],
- 'command' => [ 'type' => 'command' ],
'form' => [
'action' => 'GET',
'autocomplete' => 'on',
@@ -439,12 +430,10 @@ class Html {
/**
* Given an associative array of element attributes, generate a string
- * to stick after the element name in HTML output. Like array( 'href' =>
- * 'http://www.mediawiki.org/' ) becomes something like
+ * to stick after the element name in HTML output. Like [ 'href' =>
+ * 'http://www.mediawiki.org/' ] becomes something like
* ' href="http://www.mediawiki.org"'. Again, this is like
* Xml::expandAttributes(), but it implements some HTML-specific logic.
- * For instance, it will omit quotation marks if $wgWellFormedXml is false,
- * and will treat boolean attributes specially.
*
* Attributes that can contain space-separated lists ('class', 'accesskey' and 'rel') array
* values are allowed as well, which will automagically be normalized
@@ -454,42 +443,40 @@ class Html {
*
* @par Numerical array
* @code
- * Html::element( 'em', array(
- * 'class' => array( 'foo', 'bar' )
- * ) );
+ * Html::element( 'em', [
+ * 'class' => [ 'foo', 'bar' ]
+ * ] );
* // gives ''
* @endcode
*
* @par Associative array
* @code
- * Html::element( 'em', array(
- * 'class' => array( 'foo', 'bar', 'foo' => false, 'quux' => true )
- * ) );
+ * Html::element( 'em', [
+ * 'class' => [ 'foo', 'bar', 'foo' => false, 'quux' => true ]
+ * ] );
* // gives ''
* @endcode
*
- * @param array $attribs Associative array of attributes, e.g., array(
- * 'href' => 'http://www.mediawiki.org/' ). Values will be HTML-escaped.
+ * @param array $attribs Associative array of attributes, e.g., [
+ * 'href' => 'http://www.mediawiki.org/' ]. Values will be HTML-escaped.
* A value of false means to omit the attribute. For boolean attributes,
- * you can omit the key, e.g., array( 'checked' ) instead of
- * array( 'checked' => 'checked' ) or such.
+ * you can omit the key, e.g., [ 'checked' ] instead of
+ * [ 'checked' => 'checked' ] or such.
*
* @throws MWException If an attribute that doesn't allow lists is set to an array
* @return string HTML fragment that goes between element name and '>'
* (starting with a space if at least one attribute is output)
*/
public static function expandAttributes( array $attribs ) {
- global $wgWellFormedXml;
-
$ret = '';
foreach ( $attribs as $key => $value ) {
- // Support intuitive array( 'checked' => true/false ) form
+ // Support intuitive [ 'checked' => true/false ] form
if ( $value === false || is_null( $value ) ) {
continue;
}
- // For boolean attributes, support array( 'foo' ) instead of
- // requiring array( 'foo' => 'meaningless' ).
+ // For boolean attributes, support [ 'foo' ] instead of
+ // requiring [ 'foo' => 'meaningless' ].
if ( is_int( $key ) && in_array( strtolower( $value ), self::$boolAttribs ) ) {
$key = $value;
}
@@ -546,7 +533,7 @@ class Html {
}
} elseif ( $v ) {
// If the value is truthy but not a string this is likely
- // an array( 'foo' => true ), falsy values don't add strings
+ // an [ 'foo' => true ], falsy values don't add strings
$newValue[] = $k;
}
}
@@ -564,31 +551,10 @@ class Html {
throw new MWException( "HTML attribute $key can not contain a list of values" );
}
- // See the "Attributes" section in the HTML syntax part of HTML5,
- // 9.1.2.3 as of 2009-08-10. Most attributes can have quotation
- // marks omitted, but not all. (Although a literal " is not
- // permitted, we don't check for that, since it will be escaped
- // anyway.)
-
- // See also research done on further characters that need to be
- // escaped: http://code.google.com/p/html5lib/issues/detail?id=93
- $badChars = "\\x00- '=<>`/\x{00a0}\x{1680}\x{180e}\x{180F}\x{2000}\x{2001}"
- . "\x{2002}\x{2003}\x{2004}\x{2005}\x{2006}\x{2007}\x{2008}\x{2009}"
- . "\x{200A}\x{2028}\x{2029}\x{202F}\x{205F}\x{3000}";
- if ( $wgWellFormedXml || $value === '' || preg_match( "![$badChars]!u", $value ) ) {
- $quote = '"';
- } else {
- $quote = '';
- }
+ $quote = '"';
if ( in_array( $key, self::$boolAttribs ) ) {
- // In HTML5, we can leave the value empty. If we don't need
- // well-formed XML, we can omit the = entirely.
- if ( !$wgWellFormedXml ) {
- $ret .= " $key";
- } else {
- $ret .= " $key=\"\"";
- }
+ $ret .= " $key=\"\"";
} else {
// Apparently we need to entity-encode \n, \r, \t, although the
// spec doesn't mention that. Since we're doing strtr() anyway,
@@ -599,22 +565,18 @@ class Html {
// don't because we're stubborn and like our marginal savings on
// byte size from not having to encode unnecessary quotes.
// The only difference between this transform and the one by
- // Sanitizer::encodeAttribute() is '<' is only encoded here if
- // $wgWellFormedXml is set, and ' is not encoded.
+ // Sanitizer::encodeAttribute() is ' is not encoded.
$map = [
'&' => '&',
'"' => '"',
'>' => '>',
+ // '<' allegedly allowed per spec
+ // but breaks some tools if not escaped.
+ "<" => '<',
"\n" => '
',
"\r" => '
',
"\t" => ' '
];
- if ( $wgWellFormedXml ) {
- // This is allowed per spec:
- // But reportedly it breaks some XML tools?
- // @todo FIXME: Is this really true?
- $map['<'] = '<';
- }
$ret .= " $key=$quote" . strtr( $value, $map ) . $quote;
}
}
@@ -631,11 +593,9 @@ class Html {
* @return string Raw HTML
*/
public static function inlineScript( $contents ) {
- global $wgWellFormedXml;
-
$attrs = [];
- if ( $wgWellFormedXml && preg_match( '/[<&]/', $contents ) ) {
+ if ( preg_match( '/[<&]/', $contents ) ) {
$contents = "/**/";
}
@@ -665,9 +625,18 @@ class Html {
* @return string Raw HTML
*/
public static function inlineStyle( $contents, $media = 'all' ) {
- global $wgWellFormedXml;
+ // Don't escape '>' since that is used
+ // as direct child selector.
+ // Remember, in css, there is no "x" for hexadecimal escapes, and
+ // the space immediately after an escape sequence is swallowed.
+ $contents = strtr( $contents, [
+ '<' => '\3C ',
+ // CDATA end tag for good measure, but the main security
+ // is from escaping the '<'.
+ ']]>' => '\5D\5D\3E '
+ ] );
- if ( $wgWellFormedXml && preg_match( '/[<&]/', $contents ) ) {
+ if ( preg_match( '/[<&]/', $contents ) ) {
$contents = "/**/";
}
@@ -975,13 +944,7 @@ class Html {
$attribs['version'] = $wgHtml5Version;
}
- $html = self::openElement( 'html', $attribs );
-
- if ( $html ) {
- $html .= "\n";
- }
-
- $ret .= $html;
+ $ret .= self::openElement( 'html', $attribs );
return $ret;
}
@@ -1046,11 +1009,11 @@ class Html {
*
* @par Example:
* @code
- * Html::srcSet( array(
+ * Html::srcSet( [
* '1x' => 'standard.jpeg',
* '1.5x' => 'large.jpeg',
* '3x' => 'extra-large.jpeg',
- * ) );
+ * ] );
* // gives 'standard.jpeg 1x, large.jpeg 1.5x, extra-large.jpeg 2x'
* @endcode
*
@@ -1060,9 +1023,21 @@ class Html {
static function srcSet( array $urls ) {
$candidates = [];
foreach ( $urls as $density => $url ) {
- // Cast density to float to strip 'x'.
- $candidates[] = $url . ' ' . (float)$density . 'x';
+ // Cast density to float to strip 'x', then back to string to serve
+ // as array index.
+ $density = (string)(float)$density;
+ $candidates[$density] = $url;
}
+
+ // Remove duplicates that are the same as a smaller value
+ ksort( $candidates, SORT_NUMERIC );
+ $candidates = array_unique( $candidates );
+
+ // Append density info to the url
+ foreach ( $candidates as $density => $url ) {
+ $candidates[$density] = $url . ' ' . $density . 'x';
+ }
+
return implode( ", ", $candidates );
}
}