diff options
Diffstat (limited to 'includes/Html.php')
-rw-r--r-- | includes/Html.php | 192 |
1 files changed, 130 insertions, 62 deletions
diff --git a/includes/Html.php b/includes/Html.php index 2e148140..d312e0a6 100644 --- a/includes/Html.php +++ b/includes/Html.php @@ -102,6 +102,35 @@ class Html { ); /** + * Modifies a set of attributes meant for button elements + * and apply a set of default attributes when $wgUseMediaWikiUIEverywhere enabled. + * @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 + */ + public static function buttonAttributes( $attrs, $modifiers = array() ) { + global $wgUseMediaWikiUIEverywhere; + if ( $wgUseMediaWikiUIEverywhere ) { + if ( isset( $attrs['class'] ) ) { + if ( is_array( $attrs['class'] ) ) { + $attrs['class'][] = 'mw-ui-button'; + $attrs = array_merge( $attrs, $modifiers ); + // ensure compatibility with Xml + $attrs['class'] = implode( ' ', $attrs['class'] ); + } else { + $attrs['class'] .= ' mw-ui-button ' . implode( ' ', $modifiers ); + } + } else { + $attrs['class'] = array( 'mw-ui-button' ); + // ensure compatibility with Xml + $attrs['class'] = implode( ' ', array_merge( $attrs['class'], $modifiers ) ); + } + } + return $attrs; + } + + /** * Modifies a set of attributes meant for text input elements * and apply a set of default attributes. * Removes size attribute when $wgUseMediaWikiUIEverywhere enabled. @@ -113,28 +142,63 @@ 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). + * + * @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 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 self::element( 'a', + self::buttonAttributes( $attrs, $modifiers ), + $contents + ); + } + + /** + * 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 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 self::element( 'input', self::buttonAttributes( $attrs, $modifiers ) ); + } + + /** * Returns an HTML element in a string. The major advantage here over * manually typing out the HTML is that it will escape all attribute - * values. If you're hardcoding all the attributes, or there are none, you - * should probably just type out the html element yourself. + * values. * * This is quite similar to Xml::tags(), but it implements some useful * HTML-specific logic. For instance, there is no $allowShortTag @@ -193,20 +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( @@ -236,8 +291,7 @@ class Html { 'tel', 'color', ); - if ( isset( $attribs['type'] ) - && !in_array( $attribs['type'], $validTypes ) ) { + if ( isset( $attribs['type'] ) && !in_array( $attribs['type'], $validTypes ) ) { unset( $attribs['type'] ); } } @@ -331,8 +385,9 @@ class Html { } // Simple checks using $attribDefaults - if ( isset( $attribDefaults[$element][$lcattrib] ) && - $attribDefaults[$element][$lcattrib] == $value ) { + if ( isset( $attribDefaults[$element][$lcattrib] ) + && $attribDefaults[$element][$lcattrib] == $value + ) { unset( $attribs[$attrib] ); } @@ -342,8 +397,9 @@ class Html { } // More subtle checks - if ( $element === 'link' && isset( $attribs['type'] ) - && strval( $attribs['type'] ) == 'text/css' ) { + if ( $element === 'link' + && isset( $attribs['type'] ) && strval( $attribs['type'] ) == 'text/css' + ) { unset( $attribs['type'] ); } if ( $element === 'input' ) { @@ -442,8 +498,7 @@ class Html { // For boolean attributes, support array( 'foo' ) instead of // requiring array( 'foo' => 'meaningless' ). - if ( is_int( $key ) - && in_array( strtolower( $value ), self::$boolAttribs ) ) { + if ( is_int( $key ) && in_array( strtolower( $value ), self::$boolAttribs ) ) { $key = $value; } @@ -522,14 +577,13 @@ class Html { // 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 ) ) { + if ( $wgWellFormedXml || $value === '' || preg_match( "![$badChars]!u", $value ) ) { $quote = '"'; } else { $quote = ''; @@ -654,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() @@ -665,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 ); } @@ -676,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'] ) ) { @@ -699,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'] ) ) { @@ -722,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( @@ -768,7 +822,7 @@ class Html { } else { $spacedValue = $value; } - return self::element( 'textarea', Html::getTextInputAttributes( $attribs ), $spacedValue ); + return self::element( 'textarea', self::getTextInputAttributes( $attribs ), $spacedValue ); } /** @@ -833,13 +887,13 @@ class Html { continue; } if ( $nsId === NS_MAIN ) { - // For other namespaces use use the namespace prefix as label, but for + // For other namespaces use the namespace prefix as label, but for // main we don't use "" but the user message describing it (e.g. "(Main)" or "(Article)") $nsName = wfMessage( 'blanknamespace' )->text(); } elseif ( is_int( $nsId ) ) { $nsName = $wgContLang->convertNamespace( $nsId ); } - $optionsHtml[] = Html::element( + $optionsHtml[] = self::element( 'option', array( 'disabled' => in_array( $nsId, $params['disable'] ), 'value' => $nsId, @@ -858,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'] @@ -866,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; } @@ -911,7 +965,7 @@ class Html { $attribs['version'] = $wgHtml5Version; } - $html = Html::openElement( 'html', $attribs ); + $html = self::openElement( 'html', $attribs ); if ( $html ) { $html .= "\n"; @@ -946,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 ); } |