Merge "Set default type attribute for button html elements"
authorAnomie <bjorsch@wikimedia.org>
Tue, 13 Nov 2012 23:08:16 +0000 (23:08 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 13 Nov 2012 23:08:16 +0000 (23:08 +0000)
1  2 
includes/Html.php

diff --combined includes/Html.php
@@@ -48,7 -48,7 +48,7 @@@
   * @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 2011-08-12
        private static $voidElements = array(
                'area',
                'base',
@@@ -68,8 -68,8 +68,8 @@@
                'wbr',
        );
  
 -      # Boolean attributes, which may have the value omitted entirely.  Manually
 -      # collected from the HTML5 spec as of 2011-08-12.
 +      // Boolean attributes, which may have the value omitted entirely.  Manually
 +      // collected from the HTML5 spec as of 2011-08-12.
        private static $boolAttribs = array(
                'async',
                'autofocus',
@@@ -97,7 -97,7 +97,7 @@@
                'selected',
                'truespeed',
                'typemustmatch',
 -              # HTML5 Microdata
 +              // HTML5 Microdata
                'itemscope',
        );
  
                $start = self::openElement( $element, $attribs );
                if ( in_array( $element, self::$voidElements ) ) {
                        if ( $wgWellFormedXml ) {
 -                              # Silly XML.
 +                              // Silly XML.
                                return substr( $start, 0, -1 ) . ' />';
                        }
                        return $start;
         */
        public static function element( $element, $attribs = array(), $contents = '' ) {
                return self::rawElement( $element, $attribs, strtr( $contents, array(
 -                      # There's no point in escaping quotes, >, etc. in the contents of
 -                      # elements.
 +                      // There's no point in escaping quotes, >, etc. in the contents of
 +                      // elements.
                        '&' => '&amp;',
                        '<' => '&lt;'
                ) ) );
        public static function openElement( $element, $attribs = array() ) {
                global $wgHtml5, $wgWellFormedXml;
                $attribs = (array)$attribs;
 -              # This is not required in HTML5, but let's do it anyway, for
 -              # consistency and better compression.
 +              // 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/specs/web-apps/current-work/multipage/syntax.html#optional-tags>
 +              // 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/specs/web-apps/current-work/multipage/syntax.html#optional-tags>
                if ( !$wgWellFormedXml && !$attribs
                && in_array( $element, array( 'html', 'head' ) ) ) {
                        return '';
                }
  
 -              # Remove invalid input types
 +              // Remove invalid input types
                if ( $element == 'input' ) {
                        $validTypes = array(
                                'hidden',
                                'button',
                        );
  
 -                      # Allow more input types in HTML5 mode
 +                      // Allow more input types in HTML5 mode
                        if( $wgHtml5 ) {
                                $validTypes = array_merge( $validTypes, array(
                                        'datetime',
                        unset( $attribs['maxlength'] );
                }
  
+               // According to standard the default type for <button> elements is "submit".
+               // Depending on compatibility mode IE might use "button", instead.
+               // We enforce the standard "submit".
+               if ( $element == 'button' && !isset( $attribs['type'] ) ) {
+                       $attribs['type'] = 'submit';
+               }
                return "<$element" . self::expandAttributes(
                        self::dropDefaults( $element, $attribs ) ) . '>';
        }
  
                $element = strtolower( $element );
  
 -              # Reference:
 -              # http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#optional-tags
 +              // Reference:
 +              // http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#optional-tags
                if ( !$wgWellFormedXml && in_array( $element, array(
                        'html',
                        'head',
         * @return array An array of attributes functionally identical to $attribs
         */
        private static function dropDefaults( $element, $attribs ) {
 -              # Don't bother doing anything if we aren't outputting HTML5; it's too
 -              # much of a pain to maintain two sets of defaults.
 +              // Don't bother doing anything if we aren't outputting HTML5; it's too
 +              // much of a pain to maintain two sets of defaults.
                global $wgHtml5;
                if ( !$wgHtml5 ) {
                        return $attribs;
                }
  
 -              # Whenever altering this array, please provide a covering test case
 -              # in HtmlTest::provideElementsWithAttributesHavingDefaultValues
 +              // Whenever altering this array, please provide a covering test case
 +              // in HtmlTest::provideElementsWithAttributesHavingDefaultValues
                static $attribDefaults = array(
                        'area' => array( 'shape' => 'rect' ),
                        'button' => array(
                                'formaction' => 'GET',
                                'formenctype' => 'application/x-www-form-urlencoded',
-                               'type' => 'submit',
                        ),
                        'canvas' => array(
                                'height' => '150',
                        'keygen' => array( 'keytype' => 'rsa' ),
                        'link' => array( 'media' => 'all' ),
                        'menu' => array( 'type' => 'list' ),
 -                      # Note: the use of text/javascript here instead of other JavaScript
 -                      # MIME types follows the HTML5 spec.
 +                      // Note: the use of text/javascript here instead of other JavaScript
 +                      // MIME types follows the HTML5 spec.
                        'script' => array( 'type' => 'text/javascript' ),
                        'style' => array(
                                'media' => 'all',
                                $value = strval( $value );
                        }
  
 -                      # Simple checks using $attribDefaults
 +                      // Simple checks using $attribDefaults
                        if ( isset( $attribDefaults[$element][$lcattrib] ) &&
                        $attribDefaults[$element][$lcattrib] == $value ) {
                                unset( $attribs[$attrib] );
                        }
                }
  
 -              # More subtle checks
 +              // More subtle checks
                if ( $element === 'link' && isset( $attribs['type'] )
                && strval( $attribs['type'] ) == 'text/css' ) {
                        unset( $attribs['type'] );
                        if ( in_array( 'multiple', $attribs )
                                || ( isset( $attribs['multiple'] ) && $attribs['multiple'] !== false )
                        ) {
 -                              # A multi-select
 +                              // A multi-select
                                if ( strval( $attribs['size'] ) == '4' ) {
                                        unset( $attribs['size'] );
                                }
                        } else {
 -                              # Single select
 +                              // Single select
                                if ( strval( $attribs['size'] ) == '1' ) {
                                        unset( $attribs['size'] );
                                }
                                continue;
                        }
  
 -                      # For boolean attributes, support array( 'foo' ) instead of
 -                      # requiring array( 'foo' => 'meaningless' ).
 +                      // For boolean attributes, support array( 'foo' ) instead of
 +                      // requiring array( 'foo' => 'meaningless' ).
                        if ( is_int( $key )
                        && in_array( strtolower( $value ), self::$boolAttribs ) ) {
                                $key = $value;
                        }
  
 -                      # Not technically required in HTML5, but required in XHTML 1.0,
 -                      # and we'd like consistency and better compression anyway.
 +                      // Not technically required in HTML5, but required in XHTML 1.0,
 +                      // and we'd like consistency and better compression anyway.
                        $key = strtolower( $key );
  
 -                      # Here we're blacklisting some HTML5-only attributes...
 +                      // Here we're blacklisting some HTML5-only attributes...
                        if ( !$wgHtml5 && in_array( $key, self::$HTMLFiveOnlyAttribs )
                         ) {
                                continue;
                        }
  
 -                      # Bug 23769: Blacklist all form validation attributes for now.  Current
 -                      # (June 2010) WebKit has no UI, so the form just refuses to submit
 -                      # without telling the user why, which is much worse than failing
 -                      # server-side validation.  Opera is the only other implementation at
 -                      # this time, and has ugly UI, so just kill the feature entirely until
 -                      # we have at least one good implementation.
 +                      // Bug 23769: Blacklist all form validation attributes for now.  Current
 +                      // (June 2010) WebKit has no UI, so the form just refuses to submit
 +                      // without telling the user why, which is much worse than failing
 +                      // server-side validation.  Opera is the only other implementation at
 +                      // this time, and has ugly UI, so just kill the feature entirely until
 +                      // we have at least one good implementation.
                        if ( in_array( $key, array( 'max', 'min', 'pattern', 'required', 'step' ) ) ) {
                                continue;
                        }
                                'rel',
                        );
  
 -                      # Specific features for attributes that allow a list of space-separated values
 +                      // Specific features for attributes that allow a list of space-separated values
                        if ( in_array( $key, $spaceSeparatedListAttributes ) ) {
                                // Apply some normalization and remove duplicates
  
                                $value = implode( ' ', array_unique( $value ) );
                        }
  
 -                      # 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 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
 +                      // 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 ( in_array( $key, self::$boolAttribs ) ) {
 -                              # In XHTML 1.0 Transitional, the value needs to be equal to the
 -                              # key.  In HTML5, we can leave the value empty instead.  If we
 -                              # don't need well-formed XML, we can omit the = entirely.
 +                              // In XHTML 1.0 Transitional, the value needs to be equal to the
 +                              // key.  In HTML5, we can leave the value empty instead.  If we
 +                              // don't need well-formed XML, we can omit the = entirely.
                                if ( !$wgWellFormedXml ) {
                                        $ret .= " $key";
                                } elseif ( $wgHtml5 ) {
                                        $ret .= " $key=\"$key\"";
                                }
                        } 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().
 -                              # @todo FIXME: Verify that we actually need to
 -                              # escape \n\r\t here, and explain why, exactly.
 +                              // 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().
 +                              // @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.
 +                              // 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.
                                $map = array(
                                        '&' => '&amp;',
                                        '"' => '&quot;',
                                        "\t" => '&#9;'
                                );
                                if ( $wgWellFormedXml ) {
 -                                      # This is allowed per spec: <http://www.w3.org/TR/xml/#NT-AttValue>
 -                                      # But reportedly it breaks some XML tools?
 -                                      # @todo FIXME: Is this really true?
 +                                      // This is allowed per spec: <http://www.w3.org/TR/xml/#NT-AttValue>
 +                                      // But reportedly it breaks some XML tools?
 +                                      // @todo FIXME: Is this really true?
                                        $map['<'] = '&lt;';
                                }
                                $ret .= " $key=$quote" . strtr( $value, $map ) . $quote;