Index: trunk/phase3/tests/phpunit/includes/HtmlTest.php |
— | — | @@ -91,4 +91,56 @@ |
92 | 92 | 'Value is a numeric zero' |
93 | 93 | ); |
94 | 94 | } |
| 95 | + |
| 96 | + /** |
| 97 | + * Html::expandAttributes has special features for HTML |
| 98 | + * attributes that use space separated lists and also |
| 99 | + * allows arrays to be used as values. |
| 100 | + */ |
| 101 | + public function testExpandAttributesListValueAttributes() { |
| 102 | + ### STRING VALUES |
| 103 | + $this->AssertEquals( |
| 104 | + ' class="redundant spaces here"', |
| 105 | + Html::expandAttributes( array( 'class' => ' redundant spaces here ' ) ), |
| 106 | + 'Normalization should strip redundant spaces' |
| 107 | + ); |
| 108 | + $this->AssertEquals( |
| 109 | + ' class="foo bar"', |
| 110 | + Html::expandAttributes( array( 'class' => 'foo bar foo bar bar' ) ), |
| 111 | + 'Normalization should remove duplicates in string-lists' |
| 112 | + ); |
| 113 | + ### "EMPTY" ARRAY VALUES |
| 114 | + $this->AssertEquals( |
| 115 | + ' class=""', |
| 116 | + Html::expandAttributes( array( 'class' => array() ) ), |
| 117 | + 'Value with an empty array' |
| 118 | + ); |
| 119 | + $this->AssertEquals( |
| 120 | + ' class=""', |
| 121 | + Html::expandAttributes( array( 'class' => array( null, '', ' ', ' ' ) ) ), |
| 122 | + 'Array with null, empty string and spaces' |
| 123 | + ); |
| 124 | + ### NON-EMPTY ARRAY VALUES |
| 125 | + $this->AssertEquals( |
| 126 | + ' class="foo bar"', |
| 127 | + Html::expandAttributes( array( 'class' => array( |
| 128 | + 'foo', |
| 129 | + 'bar', |
| 130 | + 'foo', |
| 131 | + 'bar', |
| 132 | + 'bar', |
| 133 | + ) ) ), |
| 134 | + 'Normalization should remove duplicates in the array' |
| 135 | + ); |
| 136 | + $this->AssertEquals( |
| 137 | + ' class="foo bar"', |
| 138 | + Html::expandAttributes( array( 'class' => array( |
| 139 | + 'foo bar', |
| 140 | + 'bar foo', |
| 141 | + 'foo', |
| 142 | + 'bar bar', |
| 143 | + ) ) ), |
| 144 | + 'Normalization should remove duplicates in string-lists in the array' |
| 145 | + ); |
| 146 | + } |
95 | 147 | } |
Index: trunk/phase3/includes/Html.php |
— | — | @@ -111,9 +111,7 @@ |
112 | 112 | * HTML-specific logic. For instance, there is no $allowShortTag |
113 | 113 | * parameter: the closing tag is magically omitted if $element has an empty |
114 | 114 | * content model. If $wgWellFormedXml is false, then a few bytes will be |
115 | | - * shaved off the HTML output as well. In the future, other HTML-specific |
116 | | - * features might be added, like allowing arrays for the values of |
117 | | - * attributes like class= and media=. |
| 115 | + * shaved off the HTML output as well. |
118 | 116 | * |
119 | 117 | * @param $element string The element's name, e.g., 'a' |
120 | 118 | * @param $attribs array Associative array of attributes, e.g., array( |
— | — | @@ -415,6 +413,37 @@ |
416 | 414 | continue; |
417 | 415 | } |
418 | 416 | |
| 417 | + // http://www.w3.org/TR/html401/index/attributes.html ("space-separated") |
| 418 | + // http://www.w3.org/TR/html5/index.html#attributes-1 ("space-separated") |
| 419 | + $spaceSeparatedListAttributes = array( |
| 420 | + 'class', // html4, html5 |
| 421 | + 'accesskey', // as of html5, multiple space-separated values allowed |
| 422 | + // html4-spec doesn't document rel= as space-separated |
| 423 | + // but has been used like that and is now documented as such |
| 424 | + // in the html5-spec. |
| 425 | + 'rel', |
| 426 | + ); |
| 427 | + |
| 428 | + # Specific features for attributes that allow a list of space-separated values |
| 429 | + if ( in_array( $key, $spaceSeparatedListAttributes ) ) { |
| 430 | + // Apply some normalization and remove duplicates |
| 431 | + |
| 432 | + // Convert into correct array. Array can contain space-seperated |
| 433 | + // values. Implode/explode to get those into the main array as well. |
| 434 | + if ( is_array( $value ) ) { |
| 435 | + // If input wasn't an array, we can skip this step |
| 436 | + $value = implode( ' ', $value ); |
| 437 | + } |
| 438 | + $value = explode( ' ', $value ); |
| 439 | + |
| 440 | + // Normalize spacing by fixing up cases where people used |
| 441 | + // more than 1 space and/or a trailing/leading space |
| 442 | + $value = array_diff( $value, array( '', ' ') ); |
| 443 | + |
| 444 | + // Remove duplicates and create the string |
| 445 | + $value = implode( ' ', array_unique( $value ) ); |
| 446 | + } |
| 447 | + |
419 | 448 | # See the "Attributes" section in the HTML syntax part of HTML5, |
420 | 449 | # 9.1.2.3 as of 2009-08-10. Most attributes can have quotation |
421 | 450 | # marks omitted, but not all. (Although a literal " is not |