Index: trunk/phase3/includes/EditPage.php |
— | — | @@ -2056,7 +2056,7 @@ |
2057 | 2057 | * @return string |
2058 | 2058 | */ |
2059 | 2059 | static function getEditToolbar() { |
2060 | | - global $wgStylePath, $wgContLang, $wgLang, $wgJsMimeType; |
| 2060 | + global $wgStylePath, $wgContLang, $wgLang; |
2061 | 2061 | |
2062 | 2062 | /** |
2063 | 2063 | * toolarray an array of arrays which each include the filename of |
— | — | @@ -2171,9 +2171,9 @@ |
2172 | 2172 | ) |
2173 | 2173 | ); |
2174 | 2174 | $toolbar = "<div id='toolbar'>\n"; |
2175 | | - $toolbar.="<script type='$wgJsMimeType'>\n/*<![CDATA[*/\n"; |
2176 | 2175 | |
2177 | | - foreach($toolarray as $tool) { |
| 2176 | + $script = ''; |
| 2177 | + foreach ( $toolarray as $tool ) { |
2178 | 2178 | $params = array( |
2179 | 2179 | $image = $wgStylePath.'/common/images/'.$tool['image'], |
2180 | 2180 | // Note that we use the tip both for the ALT tag and the TITLE tag of the image. |
— | — | @@ -2189,11 +2189,11 @@ |
2190 | 2190 | |
2191 | 2191 | $paramList = implode( ',', |
2192 | 2192 | array_map( array( 'Xml', 'encodeJsVar' ), $params ) ); |
2193 | | - $toolbar.="addButton($paramList);\n"; |
| 2193 | + $script .= "addButton($paramList);\n"; |
2194 | 2194 | } |
| 2195 | + $toolbar .= Html::inlineScript( "\n$script\n" ); |
2195 | 2196 | |
2196 | | - $toolbar.="/*]]>*/\n</script>"; |
2197 | | - $toolbar.="\n</div>"; |
| 2197 | + $toolbar .= "\n</div>"; |
2198 | 2198 | |
2199 | 2199 | wfRunHooks( 'EditPageBeforeEditToolbar', array( &$toolbar ) ); |
2200 | 2200 | |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -907,6 +907,23 @@ |
908 | 908 | */ |
909 | 909 | $wgHtml5 = true; |
910 | 910 | |
| 911 | +/** |
| 912 | + * Should we try to make our HTML output well-formed XML? If set to false, |
| 913 | + * output will be a few bytes shorter, and the HTML will arguably be more |
| 914 | + * readable. If set to true, life will be much easier for the authors of |
| 915 | + * screen-scraping bots, and the HTML will arguably be more readable. |
| 916 | + * |
| 917 | + * Setting this to false may omit quotation marks on some attributes, omit |
| 918 | + * slashes from some self-closing tags, omit some ending tags, etc., where |
| 919 | + * permitted by HTML 5. Setting it to true will not guarantee that all pages |
| 920 | + * will be well-formed, although non-well-formed pages should be rare and it's |
| 921 | + * a bug if you find one. Conversely, setting it to false doesn't mean that |
| 922 | + * all XML-y constructs will be omitted, just that they might be. |
| 923 | + * |
| 924 | + * Because of compatibility with screen-scraping bots, and because it's |
| 925 | + * controversial, this is currently left to true by default. |
| 926 | + */ |
| 927 | +$wgWellFormedXml = true; |
911 | 928 | |
912 | 929 | /** |
913 | 930 | * Permit other namespaces in addition to the w3.org default. |
Index: trunk/phase3/includes/OutputPage.php |
— | — | @@ -109,8 +109,7 @@ |
110 | 110 | * addStyle() and draws from the /skins folder. |
111 | 111 | */ |
112 | 112 | public function addExtensionStyle( $url ) { |
113 | | - $linkarr = array( 'rel' => 'stylesheet', 'href' => $url, 'type' => 'text/css' ); |
114 | | - array_push( $this->mExtStyles, $linkarr ); |
| 113 | + array_push( $this->mExtStyles, $url ); |
115 | 114 | } |
116 | 115 | |
117 | 116 | /** |
— | — | @@ -118,7 +117,7 @@ |
119 | 118 | * @param string $file filename in skins/common or complete on-server path (/foo/bar.js) |
120 | 119 | */ |
121 | 120 | function addScriptFile( $file ) { |
122 | | - global $wgStylePath, $wgStyleVersion, $wgJsMimeType, $wgScript, $wgUser; |
| 121 | + global $wgStylePath, $wgStyleVersion, $wgScript, $wgUser; |
123 | 122 | global $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses, $wgEnableScriptLoader, $wgScriptPath; |
124 | 123 | |
125 | 124 | if( substr( $file, 0, 1 ) == '/' ) { |
— | — | @@ -163,15 +162,7 @@ |
164 | 163 | } |
165 | 164 | |
166 | 165 | // if the script loader did not find a way to add the script than add using addScript |
167 | | - $this->addScript( |
168 | | - Xml::element( 'script', |
169 | | - array( |
170 | | - 'type' => $wgJsMimeType, |
171 | | - 'src' => wfAppendQuery( $path, $this->getURIDparam() ), |
172 | | - ), |
173 | | - '', false |
174 | | - ) |
175 | | - ); |
| 166 | + $this->addScript( Html::linkedScript( wfAppendQuery( $path, $this->getURIDparam() ) ) ); |
176 | 167 | } |
177 | 168 | |
178 | 169 | /** |
— | — | @@ -180,7 +171,7 @@ |
181 | 172 | * different page load types (edit, upload, view, etc) |
182 | 173 | */ |
183 | 174 | function addCoreScripts2Top(){ |
184 | | - global $wgEnableScriptLoader, $wgStyleVersion, $wgJSAutoloadLocalClasses, $wgJsMimeType, $wgScriptPath, $wgEnableJS2system; |
| 175 | + global $wgEnableScriptLoader, $wgStyleVersion, $wgJSAutoloadLocalClasses, $wgScriptPath, $wgEnableJS2system; |
185 | 176 | //@@todo we should deprecate wikibits in favor of mv_embed and native jQuery functions |
186 | 177 | |
187 | 178 | if( $wgEnableJS2system ){ |
— | — | @@ -195,12 +186,7 @@ |
196 | 187 | $so = ''; |
197 | 188 | foreach( $core_classes as $s ){ |
198 | 189 | if( isset( $wgJSAutoloadLocalClasses[$s] ) ){ |
199 | | - $so.= Xml::element( 'script', array( |
200 | | - 'type' => $wgJsMimeType, |
201 | | - 'src' => "{$wgScriptPath}/{$wgJSAutoloadLocalClasses[$s]}?" . $this->getURIDparam() |
202 | | - ), |
203 | | - '', false |
204 | | - ); |
| 190 | + $so .= Html::linkedScript( "{$wgScriptPath}/{$wgJSAutoloadLocalClasses[$s]}?" . $this->getURIDparam() ); |
205 | 191 | } |
206 | 192 | } |
207 | 193 | $this->mScripts = $so . $this->mScripts; |
— | — | @@ -213,7 +199,7 @@ |
214 | 200 | */ |
215 | 201 | function addScriptClass( $js_class ){ |
216 | 202 | global $wgDebugJavaScript, $wgJSAutoloadLocalClasses, $wgJSAutoloadClasses, |
217 | | - $wgJsMimeType, $wgEnableScriptLoader, $wgStyleVersion, $wgScriptPath; |
| 203 | + $wgEnableScriptLoader, $wgStyleVersion, $wgScriptPath; |
218 | 204 | |
219 | 205 | if( isset( $wgJSAutoloadClasses[$js_class] ) || isset( $wgJSAutoloadLocalClasses[$js_class] ) ){ |
220 | 206 | if( $wgEnableScriptLoader ){ |
— | — | @@ -228,16 +214,8 @@ |
229 | 215 | }else if( isset( $wgJSAutoloadLocalClasses[$js_class] ) ){ |
230 | 216 | $path.= $wgJSAutoloadLocalClasses[$js_class]; |
231 | 217 | } |
232 | | - $urlApend = ( $wgDebugJavaScript) ? time() : $wgStyleVersion; |
233 | | - $this->addScript( |
234 | | - Xml::element( 'script', |
235 | | - array( |
236 | | - 'type' => $wgJsMimeType, |
237 | | - 'src' => "$path?" . $urlApend, |
238 | | - ), |
239 | | - '', false |
240 | | - ) |
241 | | - ); |
| 218 | + $urlAppend = ( $wgDebugJavaScript ) ? time() : $wgStyleVersion; |
| 219 | + $this->addScript( Html::linkedScript( "$path?$urlAppend" ) ); |
242 | 220 | } |
243 | 221 | return true; |
244 | 222 | } |
— | — | @@ -250,7 +228,7 @@ |
251 | 229 | * @param $forcClassAry Boolean: false by default |
252 | 230 | */ |
253 | 231 | function getScriptLoaderJs( $forceClassAry = false ){ |
254 | | - global $wgJsMimeType, $wgStyleVersion, $wgRequest, $wgDebugJavaScript; |
| 232 | + global $wgStyleVersion, $wgRequest, $wgDebugJavaScript; |
255 | 233 | |
256 | 234 | if( !$forceClassAry ){ |
257 | 235 | $class_list = implode( ',', $this->mScriptLoaderClassList ); |
— | — | @@ -268,14 +246,7 @@ |
269 | 247 | |
270 | 248 | //generate the unique request param (combine with the most recent revision id of any wiki page with the $wgStyleVersion var) |
271 | 249 | |
272 | | - |
273 | | - return Xml::element( 'script', |
274 | | - array( |
275 | | - 'type' => $wgJsMimeType, |
276 | | - 'src' => wfScript( 'mwScriptLoader' ) . "?class={$class_list}{$debug_param}&".$this->getURIDparam(), |
277 | | - ), |
278 | | - '', false |
279 | | - ); |
| 250 | + return Html::linkedScript( wfScript( 'mwScriptLoader' ) . "?class={$class_list}{$debug_param}&" . $this->getURIDparam() ); |
280 | 251 | } |
281 | 252 | |
282 | 253 | function getURIDparam(){ |
— | — | @@ -304,8 +275,7 @@ |
305 | 276 | * @param string $script JavaScript text, no <script> tags |
306 | 277 | */ |
307 | 278 | function addInlineScript( $script ) { |
308 | | - global $wgJsMimeType; |
309 | | - $this->mScripts .= "\t\t<script type=\"$wgJsMimeType\">/*<![CDATA[*/\n\t\t$script\n\t\t/*]]>*/</script>\n"; |
| 279 | + $this->mScripts .= "\t\t" . Html::inlineScript( "\n\t\t$script\n\t\t" ) . "\n"; |
310 | 280 | } |
311 | 281 | |
312 | 282 | function getScript() { |
— | — | @@ -1056,7 +1026,7 @@ |
1057 | 1027 | public function output() { |
1058 | 1028 | global $wgUser, $wgOutputEncoding, $wgRequest; |
1059 | 1029 | global $wgContLanguageCode, $wgDebugRedirects, $wgMimeType; |
1060 | | - global $wgJsMimeType, $wgUseAjax, $wgAjaxWatch; |
| 1030 | + global $wgUseAjax, $wgAjaxWatch; |
1061 | 1031 | global $wgEnableMWSuggest, $wgUniversalEditButton; |
1062 | 1032 | global $wgArticle; |
1063 | 1033 | |
— | — | @@ -1741,7 +1711,7 @@ |
1742 | 1712 | $this->getHeadItems(), |
1743 | 1713 | )); |
1744 | 1714 | if( $sk->usercss ){ |
1745 | | - $ret .= "<style type='text/css'>{$sk->usercss}</style>"; |
| 1715 | + $ret .= Html::inlineStyle( $sk->usercss ); |
1746 | 1716 | } |
1747 | 1717 | |
1748 | 1718 | if( $wgEnableScriptLoader ) |
— | — | @@ -1922,7 +1892,7 @@ |
1923 | 1893 | * @param $style_css Mixed: inline CSS |
1924 | 1894 | */ |
1925 | 1895 | public function addInlineStyle( $style_css ){ |
1926 | | - $this->mScripts .= "<style type=\"text/css\">$style_css</style>"; |
| 1896 | + $this->mScripts .= Html::inlineStyle( $style_css ); |
1927 | 1897 | } |
1928 | 1898 | |
1929 | 1899 | /** |
— | — | @@ -1956,7 +1926,7 @@ |
1957 | 1927 | return ''; |
1958 | 1928 | } |
1959 | 1929 | } else { |
1960 | | - $media = ''; |
| 1930 | + $media = null; |
1961 | 1931 | } |
1962 | 1932 | |
1963 | 1933 | if( substr( $style, 0, 1 ) == '/' || |
— | — | @@ -1968,16 +1938,8 @@ |
1969 | 1939 | $url = $wgStylePath . '/' . $style . '?' . $wgStyleVersion; |
1970 | 1940 | } |
1971 | 1941 | |
1972 | | - $attribs = array( |
1973 | | - 'rel' => 'stylesheet', |
1974 | | - 'href' => $url, |
1975 | | - 'type' => 'text/css' ); |
1976 | | - if( $media ) { |
1977 | | - $attribs['media'] = $media; |
1978 | | - } |
| 1942 | + $link = Html::linkedStyle( $url, $media ); |
1979 | 1943 | |
1980 | | - $link = Xml::element( 'link', $attribs ); |
1981 | | - |
1982 | 1944 | if( isset( $options['condition'] ) ) { |
1983 | 1945 | $condition = htmlspecialchars( $options['condition'] ); |
1984 | 1946 | $link = "<!--[if $condition]>$link<![endif]-->"; |
Index: trunk/phase3/includes/AutoLoader.php |
— | — | @@ -95,6 +95,7 @@ |
96 | 96 | 'HistoryBlobCurStub' => 'includes/HistoryBlob.php', |
97 | 97 | 'HistoryBlob' => 'includes/HistoryBlob.php', |
98 | 98 | 'HistoryBlobStub' => 'includes/HistoryBlob.php', |
| 99 | + 'Html' => 'includes/Html.php', |
99 | 100 | 'HTMLCacheUpdate' => 'includes/HTMLCacheUpdate.php', |
100 | 101 | 'HTMLCacheUpdateJob' => 'includes/HTMLCacheUpdate.php', |
101 | 102 | 'HTMLFileCache' => 'includes/HTMLFileCache.php', |
Index: trunk/phase3/includes/ChangesList.php |
— | — | @@ -600,15 +600,13 @@ |
601 | 601 | * @ return string |
602 | 602 | */ |
603 | 603 | public function beginRecentChangesList() { |
604 | | - global $wgStylePath, $wgJsMimeType, $wgStyleVersion; |
| 604 | + global $wgStylePath, $wgStyleVersion; |
605 | 605 | $this->rc_cache = array(); |
606 | 606 | $this->rcMoveIndex = 0; |
607 | 607 | $this->rcCacheIndex = 0; |
608 | 608 | $this->lastdate = ''; |
609 | 609 | $this->rclistOpen = false; |
610 | | - $script = Xml::tags( 'script', array( |
611 | | - 'type' => $wgJsMimeType, |
612 | | - 'src' => $wgStylePath . "/common/enhancedchanges.js?$wgStyleVersion" ), '' ); |
| 610 | + $script = Html::linkedScript( $wgStylePath . "/common/enhancedchanges.js?$wgStyleVersion" ); |
613 | 611 | return $script; |
614 | 612 | } |
615 | 613 | /** |
Index: trunk/phase3/includes/Html.php |
— | — | @@ -0,0 +1,217 @@ |
| 2 | +<?php |
| 3 | +# Copyright (C) 2009 Aryeh Gregor |
| 4 | +# http://www.mediawiki.org/ |
| 5 | +# |
| 6 | +# This program is free software; you can redistribute it and/or modify |
| 7 | +# it under the terms of the GNU General Public License as published by |
| 8 | +# the Free Software Foundation; either version 2 of the License, or |
| 9 | +# (at your option) any later version. |
| 10 | +# |
| 11 | +# This program is distributed in the hope that it will be useful, |
| 12 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | +# GNU General Public License for more details. |
| 15 | +# |
| 16 | +# You should have received a copy of the GNU General Public License along |
| 17 | +# with this program; if not, write to the Free Software Foundation, Inc., |
| 18 | +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 19 | +# http://www.gnu.org/copyleft/gpl.html |
| 20 | + |
| 21 | +/** |
| 22 | + * This class is a collection of static functions that serve two purposes: |
| 23 | + * |
| 24 | + * 1) Implement any algorithms specified by HTML 5, or other HTML |
| 25 | + * specifications, in a convenient and self-contained way. |
| 26 | + * |
| 27 | + * 2) Allow HTML elements to be conveniently and safely generated, like the |
| 28 | + * current Xml class but a) less confused (Xml supports HTML-specific things, |
| 29 | + * but only sometimes!) and b) not necessarily confined to XML-compatible |
| 30 | + * output. |
| 31 | + * |
| 32 | + * There are two important configuration options this class uses: |
| 33 | + * |
| 34 | + * $wgHtml5: If this is set to false, then all output should be valid XHTML 1.0 |
| 35 | + * Transitional. |
| 36 | + * $wgWellFormedXml: If this is set to true, then all output should be |
| 37 | + * well-formed XML (quotes on attributes, self-closing tags, etc.). |
| 38 | + * |
| 39 | + * This class is meant to be confined to utility functions that are called from |
| 40 | + * trusted code paths. It does not do enforcement of policy like not allowing |
| 41 | + * <a> elements. |
| 42 | + */ |
| 43 | +class Html { |
| 44 | + # List of void elements from HTML 5, section 9.1.2 as of 2009-08-10 |
| 45 | + private static $voidElements = array( |
| 46 | + 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', |
| 47 | + 'keygen', 'link', 'meta', 'param', 'source' |
| 48 | + ); |
| 49 | + |
| 50 | + /** |
| 51 | + * Returns an HTML element in a string. The major advantage here over |
| 52 | + * manually typing out the HTML is that it will escape all attribute |
| 53 | + * values. If you're hardcoding all the attributes, or there are none, you |
| 54 | + * should probably type out the string yourself. |
| 55 | + * |
| 56 | + * This is quite similar to Xml::element(), but it implements some useful |
| 57 | + * HTML-specific logic. For instance, there is no $allowShortTag |
| 58 | + * parameter: the closing tag is magically omitted if $element has an empty |
| 59 | + * content model. If $wgWellFormedXml is false, then a few bytes will be |
| 60 | + * shaved off the HTML output as well. In the future, other HTML-specific |
| 61 | + * features might be added, like allowing arrays for the values of |
| 62 | + * attributes like class= and media=. |
| 63 | + * |
| 64 | + * One notable difference to Xml::element() is that $contents is *not* |
| 65 | + * escaped. This means that Html::element() can be usefully nested, rather |
| 66 | + * than using the rather clumsy Xml::openElement() and Xml::closeElement(). |
| 67 | + * |
| 68 | + * @param $element string The element's name, e.g., 'a' |
| 69 | + * @param $attribs array Associative array of attributes, e.g., array( |
| 70 | + * 'href' => 'http://www.mediawiki.org/' ). Values will be HTML-escaped. |
| 71 | + * @param $contents string The raw HTML contents of the element: *not* |
| 72 | + * escaped! |
| 73 | + * @return string Raw HTML |
| 74 | + */ |
| 75 | + public static function element( $element, $attribs = array(), $contents = '' ) { |
| 76 | + global $wgWellFormedXml; |
| 77 | + $element = strtolower( $element ); |
| 78 | + $start = "<$element" . self::expandAttributes( $attribs ); |
| 79 | + if ( in_array( $element, self::$voidElements ) ) { |
| 80 | + if ( $wgWellFormedXml ) { |
| 81 | + return "$start />"; |
| 82 | + } |
| 83 | + return "$start>"; |
| 84 | + } else { |
| 85 | + return "$start>$contents</$element>"; |
| 86 | + } |
| 87 | + } |
| 88 | + |
| 89 | + /** |
| 90 | + * Given an associative array of element attributes, generate a string |
| 91 | + * to stick after the element name in HTML output. Like array( 'href' => |
| 92 | + * 'http://www.mediawiki.org/' ) becomes something like |
| 93 | + * ' href="http://www.mediawiki.org"'. Again, this is like |
| 94 | + * Xml::expandAttributes(), but it implements some HTML-specific logic. |
| 95 | + * For instance, it will omit quotation marks if $wgWellFormedXml is false. |
| 96 | + * |
| 97 | + * @param $attribs array Associative array of attributes, e.g., array( |
| 98 | + * 'href' => 'http://www.mediawiki.org/' ). Values will be HTML-escaped. |
| 99 | + * @return string HTML fragment that goes between element name and '>' |
| 100 | + * (starting with a space if at least one attribute is output) |
| 101 | + */ |
| 102 | + public static function expandAttributes( $attribs ) { |
| 103 | + global $wgWellFormedXml; |
| 104 | + |
| 105 | + $ret = ''; |
| 106 | + foreach ( $attribs as $key => $value ) { |
| 107 | + # See the "Attributes" section in the HTML syntax part of HTML 5, |
| 108 | + # 9.1.2.3 as of 2009-08-10. Most attributes can have quotation |
| 109 | + # marks omitted, but not all. (Although a literal " is not |
| 110 | + # permitted, we don't check for that, since it will be escaped |
| 111 | + # anyway.) |
| 112 | + if ( $wgWellFormedXml || $value == '' |
| 113 | + || preg_match( "/[ '=<>]/", $value ) ) { |
| 114 | + $quote = '"'; |
| 115 | + } else { |
| 116 | + $quote = ''; |
| 117 | + } |
| 118 | + |
| 119 | + # Apparently we need to entity-encode \n, \r, \t, although the spec |
| 120 | + # doesn't mention that. Since we're doing strtr() anyway, and we |
| 121 | + # don't need <> escaped here, we may as well not call |
| 122 | + # htmlspecialchars(). FIXME: verify that we actually need to |
| 123 | + # escape \n\r\t here, and explain why, exactly. |
| 124 | + $ret .= " $key=$quote" . strtr( $value, array( |
| 125 | + '&' => '&', |
| 126 | + '"' => '"', |
| 127 | + "\n" => ' ', |
| 128 | + "\r" => ' ', |
| 129 | + "\t" => '	' |
| 130 | + ) ) . $quote; |
| 131 | + } |
| 132 | + return $ret; |
| 133 | + } |
| 134 | + |
| 135 | + /** |
| 136 | + * Output a <script> tag with the given contents. TODO: do some useful |
| 137 | + * escaping as well, like if $contents contains literal '</script>' or (for |
| 138 | + * XML) literal "]]>". |
| 139 | + * |
| 140 | + * @param $contents string JavaScript |
| 141 | + * @return string Raw HTML |
| 142 | + */ |
| 143 | + public static function inlineScript( $contents ) { |
| 144 | + global $wgHtml5, $wgJsMimeType; |
| 145 | + |
| 146 | + $attrs = array(); |
| 147 | + if ( !$wgHtml5 ) { |
| 148 | + $attrs['type'] = $wgJsMimeType; |
| 149 | + $contents = "/*<![CDATA[*/$contents/*]]>*/"; |
| 150 | + } |
| 151 | + return self::element( 'script', $attrs, $contents ); |
| 152 | + } |
| 153 | + |
| 154 | + /** |
| 155 | + * Output a <script> tag linking to the given URL, e.g., |
| 156 | + * <script src=foo.js></script>. |
| 157 | + * |
| 158 | + * @param $url string |
| 159 | + * @return string Raw HTML |
| 160 | + */ |
| 161 | + public static function linkedScript( $url ) { |
| 162 | + global $wgHtml5, $wgJsMimeType; |
| 163 | + |
| 164 | + $attrs = array( 'src' => $url ); |
| 165 | + if ( !$wgHtml5 ) { |
| 166 | + $attrs['type'] = $wgJsMimeType; |
| 167 | + } |
| 168 | + return self::element( 'script', $attrs ); |
| 169 | + } |
| 170 | + |
| 171 | + /** |
| 172 | + * Output a <style> tag with the given contents for the given media type |
| 173 | + * (if any). TODO: do some useful escaping as well, like if $contents |
| 174 | + * contains literal '</style>' (admittedly unlikely). |
| 175 | + * |
| 176 | + * @param $contents string CSS |
| 177 | + * @param $media mixed A media type string, like 'screen', or null for all |
| 178 | + * media |
| 179 | + * @return string Raw HTML |
| 180 | + */ |
| 181 | + public static function inlineStyle( $contents, $media = null ) { |
| 182 | + global $wgHtml5; |
| 183 | + |
| 184 | + $attrs = array(); |
| 185 | + if ( !$wgHtml5 ) { |
| 186 | + # Technically we should probably add CDATA stuff here like with |
| 187 | + # scripts, but in practice, stylesheets tend not to have |
| 188 | + # problematic characters anyway. |
| 189 | + $attrs['type'] = 'text/css'; |
| 190 | + } |
| 191 | + if ( $media !== null ) { |
| 192 | + $attrs['media'] = $media; |
| 193 | + } |
| 194 | + return self::element( 'style', $attrs, $contents ); |
| 195 | + } |
| 196 | + |
| 197 | + /** |
| 198 | + * Output a <link rel=stylesheet> linking to the given URL for the given |
| 199 | + * media type (if any). |
| 200 | + * |
| 201 | + * @param $url string |
| 202 | + * @param $media mixed A media type string, like 'screen', or null for all |
| 203 | + * media |
| 204 | + * @return string Raw HTML |
| 205 | + */ |
| 206 | + public static function linkedStyle( $url, $media = null ) { |
| 207 | + global $wgHtml5; |
| 208 | + |
| 209 | + $attrs = array( 'rel' => 'stylesheet', 'href' => $url ); |
| 210 | + if ( !$wgHtml5 ) { |
| 211 | + $attrs['type'] = 'text/css'; |
| 212 | + } |
| 213 | + if ( $media !== null ) { |
| 214 | + $attrs['media'] = $media; |
| 215 | + } |
| 216 | + return self::element( 'link', $attrs ); |
| 217 | + } |
| 218 | +} |
Property changes on: trunk/phase3/includes/Html.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 219 | + native |
Index: trunk/phase3/includes/Linker.php |
— | — | @@ -1257,7 +1257,6 @@ |
1258 | 1258 | |
1259 | 1259 | /** @todo document */ |
1260 | 1260 | function tocList($toc) { |
1261 | | - global $wgJsMimeType; |
1262 | 1261 | $title = wfMsgHtml('toc') ; |
1263 | 1262 | return |
1264 | 1263 | '<table id="toc" class="toc"><tr><td>' |
— | — | @@ -1266,13 +1265,13 @@ |
1267 | 1266 | # no trailing newline, script should not be wrapped in a |
1268 | 1267 | # paragraph |
1269 | 1268 | . "</ul>\n</td></tr></table>" |
1270 | | - . '<script type="' . $wgJsMimeType . '">' |
1271 | | - . ' if (window.showTocToggle) {' |
1272 | | - . ' var tocShowText = "' . Xml::escapeJsString( wfMsg('showtoc') ) . '";' |
1273 | | - . ' var tocHideText = "' . Xml::escapeJsString( wfMsg('hidetoc') ) . '";' |
1274 | | - . ' showTocToggle();' |
1275 | | - . ' } ' |
1276 | | - . "</script>\n"; |
| 1269 | + . Html::inlineScript( |
| 1270 | + 'if (window.showTocToggle) {' |
| 1271 | + . ' var tocShowText = "' . Xml::escapeJsString( wfMsg('showtoc') ) . '";' |
| 1272 | + . ' var tocHideText = "' . Xml::escapeJsString( wfMsg('hidetoc') ) . '";' |
| 1273 | + . ' showTocToggle();' |
| 1274 | + . ' } ' ) |
| 1275 | + . "\n"; |
1277 | 1276 | } |
1278 | 1277 | |
1279 | 1278 | /** |
Index: trunk/phase3/includes/specials/SpecialSearch.php |
— | — | @@ -801,12 +801,10 @@ |
802 | 802 | } |
803 | 803 | |
804 | 804 | protected function searchFocus() { |
805 | | - global $wgJsMimeType; |
806 | | - return "<script type=\"$wgJsMimeType\">" . |
| 805 | + return Html::inlineScript( |
807 | 806 | "hookEvent(\"load\", function() {" . |
808 | 807 | "document.getElementById('searchText').focus();" . |
809 | | - "});" . |
810 | | - "</script>"; |
| 808 | + "});" ); |
811 | 809 | } |
812 | 810 | |
813 | 811 | protected function formHeader( $term, $resultsShown, $totalNum ) { |
Index: trunk/phase3/includes/Skin.php |
— | — | @@ -333,15 +333,13 @@ |
334 | 334 | } |
335 | 335 | |
336 | 336 | static function makeVariablesScript( $data ) { |
337 | | - global $wgJsMimeType; |
338 | | - |
339 | | - $r = array( "<script type=\"$wgJsMimeType\">/*<![CDATA[*/" ); |
| 337 | + $r = array(); |
340 | 338 | foreach ( $data as $name => $value ) { |
341 | 339 | $encValue = Xml::encodeJsVar( $value ); |
342 | 340 | $r[] = "var $name = $encValue;"; |
343 | 341 | } |
344 | | - $r[] = "/*]]>*/</script>\n"; |
345 | | - return implode( "\n\t\t", $r ); |
| 342 | + return Html::inlineScript( "\n\t\t" . implode( "\n\t\t", $r ) . |
| 343 | + "\n\t\t" ); |
346 | 344 | } |
347 | 345 | |
348 | 346 | /** |
— | — | @@ -632,8 +630,8 @@ |
633 | 631 | ); |
634 | 632 | |
635 | 633 | // Add any extension CSS |
636 | | - foreach( $out->getExtStyle() as $tag ) { |
637 | | - $out->addStyle( $tag['href'] ); |
| 634 | + foreach ( $out->getExtStyle() as $url ) { |
| 635 | + $out->addStyle( $url ); |
638 | 636 | } |
639 | 637 | |
640 | 638 | // If we use the site's dynamic CSS, throw that in, too |
— | — | @@ -978,8 +976,7 @@ |
979 | 977 | * @return String HTML-wrapped JS code to be put before </body> |
980 | 978 | */ |
981 | 979 | function bottomScripts() { |
982 | | - global $wgJsMimeType; |
983 | | - $bottomScriptText = "\n\t\t<script type=\"$wgJsMimeType\">if (window.runOnloadHook) runOnloadHook();</script>\n"; |
| 980 | + $bottomScriptText = "\n\t\t" . Html::inlineScript( 'if (window.runOnloadHook) runOnloadHook();' ) . "\n"; |
984 | 981 | wfRunHooks( 'SkinAfterBottomScripts', array( $this, &$bottomScriptText ) ); |
985 | 982 | return $bottomScriptText; |
986 | 983 | } |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -192,6 +192,9 @@ |
193 | 193 | numbers outside the permitted ranges), etc. |
194 | 194 | ** The summary attribute has been removed from tables of contents. summary is |
195 | 195 | obsolete in HTML 5 and wasn't useful here anyway. |
| 196 | +** Unnecessary type="" attribute removed for CSS and JS. |
| 197 | +** If $wgWellFormedXml is set to false, some bytes will be shaved off of HTML |
| 198 | + output by omitting some things like quotation marks where HTML 5 allows. |
196 | 199 | * Added crop for inline images. |
197 | 200 | |
198 | 201 | === Bug fixes in 1.16 === |
Index: trunk/phase3/maintenance/parserTests.inc |
— | — | @@ -647,6 +647,8 @@ |
648 | 648 | 'wgEnforceHtmlIds' => true, |
649 | 649 | 'wgExternalLinkTarget' => false, |
650 | 650 | 'wgAlwaysUseTidy' => false, |
| 651 | + 'wgHtml5' => true, |
| 652 | + 'wgWellFormedXml' => true, |
651 | 653 | ); |
652 | 654 | |
653 | 655 | if ($config) { |