Merge "Revert "Hide HHVM tag on Special:{Contributions,RecentChanges,...}""
[lhc/web/wiklou.git] / includes / Html.php
index 93a1a04..d312e0a 100644 (file)
@@ -104,7 +104,8 @@ class Html {
        /**
         * Modifies a set of attributes meant for button elements
         * and apply a set of default attributes when $wgUseMediaWikiUIEverywhere enabled.
-        * @param array $modifiers to add to the button
+        * @param array $attrs
+        * @param string[] $modifiers to add to the button
         * @see https://tools.wmflabs.org/styleguide/desktop/index.html for guidance on available modifiers
         * @return array $attrs A modified attribute array
         */
@@ -141,58 +142,57 @@ class Html {
                if ( !$attrs ) {
                        $attrs = array();
                }
-               if ( isset( $attrs['class'] ) ) {
-                       if ( is_array( $attrs['class'] ) ) {
-                               $attrs['class'][] = 'mw-ui-input';
+               if ( $wgUseMediaWikiUIEverywhere ) {
+                       if ( isset( $attrs['class'] ) ) {
+                               if ( is_array( $attrs['class'] ) ) {
+                                       $attrs['class'][] = 'mw-ui-input';
+                               } else {
+                                       $attrs['class'] .= ' mw-ui-input';
+                               }
                        } else {
-                               $attrs['class'] .= ' mw-ui-input';
+                               $attrs['class'] = 'mw-ui-input';
                        }
-               } else {
-                       $attrs['class'] = 'mw-ui-input';
-               }
-               if ( $wgUseMediaWikiUIEverywhere ) {
-                       // Note that size can effect the desired width rendering of mw-ui-input elements
-                       // so it is removed. Left intact when mediawiki ui not enabled.
-                       unset( $attrs['size'] );
                }
                return $attrs;
        }
 
        /**
-        * Returns an HTML link element in a string styled as a button (when $wgUseMediaWikiUIEverywhere is enabled).
+        * Returns an HTML link element in a string styled as a button
+        * (when $wgUseMediaWikiUIEverywhere is enabled).
         *
         * @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
         *   further documentation.
-        * @param array $modifiers to add to the button
+        * @param string[] $modifiers to add to the button
         * @see http://tools.wmflabs.org/styleguide/desktop/index.html for guidance on available modifiers
         * @return string Raw HTML
         */
        public static function linkButton( $contents, $attrs, $modifiers = array() ) {
-               return Html::element( 'a',
+               return self::element( 'a',
                        self::buttonAttributes( $attrs, $modifiers ),
                        $contents
                );
        }
 
        /**
-        * Returns an HTML link element in a string styled as a button (when $wgUseMediaWikiUIEverywhere is enabled).
+        * Returns an HTML link element in a string styled as a button
+        * (when $wgUseMediaWikiUIEverywhere is enabled).
         *
         * @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
         *   further documentation.
-        * @param array $modifiers to add to the button
+        * @param string[] $modifiers to add to the button
         * @see http://tools.wmflabs.org/styleguide/desktop/index.html for guidance on available modifiers
         * @return string Raw HTML
         */
        public static function submitButton( $contents, $attrs, $modifiers = array() ) {
                $attrs['type'] = 'submit';
                $attrs['value'] = $contents;
-               return Html::element( 'input', self::buttonAttributes( $attrs, $modifiers ) );
+               return self::element( 'input', self::buttonAttributes( $attrs, $modifiers ) );
        }
 
        /**
@@ -257,19 +257,11 @@ class Html {
         * @return string
         */
        public static function openElement( $element, $attribs = array() ) {
-               global $wgWellFormedXml;
                $attribs = (array)$attribs;
                // This is not required in HTML5, but let's do it anyway, for
                // consistency and better compression.
                $element = strtolower( $element );
 
-               // In text/html, initial <html> and <head> tags can be omitted under
-               // pretty much any sane circumstances, if they have no attributes.  See:
-               // <http://www.whatwg.org/html/syntax.html#optional-tags>
-               if ( !$wgWellFormedXml && !$attribs && in_array( $element, array( 'html', 'head' ) ) ) {
-                       return '';
-               }
-
                // Remove invalid input types
                if ( $element == 'input' ) {
                        $validTypes = array(
@@ -608,17 +600,20 @@ class Html {
                        } else {
                                // Apparently we need to entity-encode \n, \r, \t, although the
                                // spec doesn't mention that.  Since we're doing strtr() anyway,
-                               // and we don't need <> escaped here, we may as well not call
-                               // htmlspecialchars().
+                               // we may as well not call htmlspecialchars().
                                // @todo FIXME: Verify that we actually need to
                                // escape \n\r\t here, and explain why, exactly.
                                #
                                // We could call Sanitizer::encodeAttribute() for this, but we
                                // 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.
                                $map = array(
                                        '&' => '&amp;',
                                        '"' => '&quot;',
+                                       '>' => '&gt;',
                                        "\n" => '&#10;',
                                        "\r" => '&#13;',
                                        "\t" => '&#9;'
@@ -713,7 +708,7 @@ class Html {
         * new HTML5 input types and attributes.
         *
         * @param string $name Name attribute
-        * @param array $value Value attribute
+        * @param string $value Value attribute
         * @param string $type Type attribute
         * @param array $attribs Associative array of miscellaneous extra
         *   attributes, passed to Html::element()
@@ -724,7 +719,7 @@ class Html {
                $attribs['value'] = $value;
                $attribs['name'] = $name;
                if ( in_array( $type, array( 'text', 'search', 'email', 'password', 'number' ) ) ) {
-                       $attribs = Html::getTextInputAttributes( $attribs );
+                       $attribs = self::getTextInputAttributes( $attribs );
                }
                return self::element( 'input', $attribs );
        }
@@ -735,7 +730,7 @@ class Html {
         * @param string $name Name attribute
         * @param bool $checked Whether the checkbox is checked or not
         * @param array $attribs Array of additional attributes
-        * @return string
+        * @return string Raw HTML
         */
        public static function check( $name, $checked = false, array $attribs = array() ) {
                if ( isset( $attribs['value'] ) ) {
@@ -758,7 +753,7 @@ class Html {
         * @param string $name Name attribute
         * @param bool $checked Whether the checkbox is checked or not
         * @param array $attribs Array of additional attributes
-        * @return string
+        * @return string Raw HTML
         */
        public static function radio( $name, $checked = false, array $attribs = array() ) {
                if ( isset( $attribs['value'] ) ) {
@@ -781,7 +776,7 @@ class Html {
         * @param string $label Contents of the label
         * @param string $id ID of the element being labeled
         * @param array $attribs Additional attributes
-        * @return string
+        * @return string Raw HTML
         */
        public static function label( $label, $id, array $attribs = array() ) {
                $attribs += array(
@@ -827,7 +822,7 @@ class Html {
                } else {
                        $spacedValue = $value;
                }
-               return self::element( 'textarea', Html::getTextInputAttributes( $attribs ), $spacedValue );
+               return self::element( 'textarea', self::getTextInputAttributes( $attribs ), $spacedValue );
        }
 
        /**
@@ -898,7 +893,7 @@ class Html {
                        } elseif ( is_int( $nsId ) ) {
                                $nsName = $wgContLang->convertNamespace( $nsId );
                        }
-                       $optionsHtml[] = Html::element(
+                       $optionsHtml[] = self::element(
                                'option', array(
                                        'disabled' => in_array( $nsId, $params['disable'] ),
                                        'value' => $nsId,
@@ -917,7 +912,7 @@ class Html {
 
                $ret = '';
                if ( isset( $params['label'] ) ) {
-                       $ret .= Html::element(
+                       $ret .= self::element(
                                'label', array(
                                        'for' => isset( $selectAttribs['id'] ) ? $selectAttribs['id'] : null,
                                ), $params['label']
@@ -925,11 +920,11 @@ class Html {
                }
 
                // Wrap options in a <select>
-               $ret .= Html::openElement( 'select', $selectAttribs )
+               $ret .= self::openElement( 'select', $selectAttribs )
                        . "\n"
                        . implode( "\n", $optionsHtml )
                        . "\n"
-                       . Html::closeElement( 'select' );
+                       . self::closeElement( 'select' );
 
                return $ret;
        }
@@ -970,7 +965,7 @@ class Html {
                        $attribs['version'] = $wgHtml5Version;
                }
 
-               $html = Html::openElement( 'html', $attribs );
+               $html = self::openElement( 'html', $attribs );
 
                if ( $html ) {
                        $html .= "\n";
@@ -1005,44 +1000,58 @@ class Html {
         *
         * @return string
         */
-       static function infoBox( $text, $icon, $alt, $class = false ) {
-               $s = Html::openElement( 'div', array( 'class' => "mw-infobox $class" ) );
+       static function infoBox( $text, $icon, $alt, $class = '' ) {
+               $s = self::openElement( 'div', array( 'class' => "mw-infobox $class" ) );
 
-               $s .= Html::openElement( 'div', array( 'class' => 'mw-infobox-left' ) ) .
-                               Html::element( 'img',
+               $s .= self::openElement( 'div', array( 'class' => 'mw-infobox-left' ) ) .
+                               self::element( 'img',
                                        array(
                                                'src' => $icon,
                                                'alt' => $alt,
                                        )
                                ) .
-                               Html::closeElement( 'div' );
+                               self::closeElement( 'div' );
 
-               $s .= Html::openElement( 'div', array( 'class' => 'mw-infobox-right' ) ) .
+               $s .= self::openElement( 'div', array( 'class' => 'mw-infobox-right' ) ) .
                                $text .
-                               Html::closeElement( 'div' );
-               $s .= Html::element( 'div', array( 'style' => 'clear: left;' ), ' ' );
+                               self::closeElement( 'div' );
+               $s .= self::element( 'div', array( 'style' => 'clear: left;' ), ' ' );
 
-               $s .= Html::closeElement( 'div' );
+               $s .= self::closeElement( 'div' );
 
-               $s .= Html::element( 'div', array( 'style' => 'clear: left;' ), ' ' );
+               $s .= self::element( 'div', array( 'style' => 'clear: left;' ), ' ' );
 
                return $s;
        }
 
        /**
-        * Generate a srcset attribute value from an array mapping pixel densities
-        * to URLs. Note that srcset supports width and height values as well, which
-        * are not used here.
+        * Generate a srcset attribute value.
+        *
+        * Generates a srcset attribute value from an array mapping pixel densities
+        * to URLs. A trailing 'x' in pixel density values is optional.
+        *
+        * @note srcset width and height values are not supported.
+        *
+        * @see http://www.whatwg.org/html/embedded-content-1.html#attr-img-srcset
+        *
+        * @par Example:
+        * @code
+        *     Html::srcSet( array(
+        *         '1x'   => 'standard.jpeg',
+        *         '1.5x' => 'large.jpeg',
+        *         '3x'   => 'extra-large.jpeg',
+        *     ) );
+        *     // gives 'standard.jpeg 1x, large.jpeg 1.5x, extra-large.jpeg 2x'
+        * @endcode
         *
-        * @param array $urls
+        * @param string[] $urls
         * @return string
         */
        static function srcSet( $urls ) {
                $candidates = array();
                foreach ( $urls as $density => $url ) {
-                       // Image candidate syntax per current whatwg live spec, 2012-09-23:
-                       // http://www.whatwg.org/html/embedded-content-1.html#attr-img-srcset
-                       $candidates[] = "{$url} {$density}x";
+                       // Cast density to float to strip 'x'.
+                       $candidates[] = $url . ' ' . (float)$density . 'x';
                }
                return implode( ", ", $candidates );
        }