r56479 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r56478‎ | r56479 | r56480 >
Date:01:19, 17 September 2009
Author:dale
Status:deferred
Tags:
Comment:
* Enhanced OutputPage to support js2 style javascript without scriptloader enabled
** loadGM output
** unique request id based on wikiTitle revision / file time
* Moved jsAutoLoadClasses to setup.php ( made conditional )
Modified paths:
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/OutputPage.php (modified) (history)
  • /trunk/phase3/includes/Setup.php (modified) (history)
  • /trunk/phase3/includes/json/FormatJson.php (modified) (history)
  • /trunk/phase3/js2/mwEmbed/jsScriptLoader.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/json/FormatJson.php
@@ -18,15 +18,15 @@
1919 return json_encode($value);
2020 }
2121 }
22 - public static function decode($value, $assoc=false){
 22+ public static function decode( $value, $assoc=false ){
2323 if (!function_exists('json_decode') ) {
2424 $json = new Services_JSON();
25 - $jsonDec = $json->decode($value);
26 - if($assoc)
 25+ $jsonDec = $json->decode( $value );
 26+ if( $assoc )
2727 $jsonDec = wfObjectToArray( $jsonDec );
2828 return $jsonDec;
2929 } else {
30 - return json_decode($value, $assoc);
 30+ return json_decode( $value, $assoc );
3131 }
3232 }
3333 }
Index: trunk/phase3/includes/Setup.php
@@ -319,13 +319,17 @@
320320 wfProfileOut( $fname.'-misc2' );
321321 wfProfileIn( $fname.'-extensions' );
322322
323 -/*
324 - * load the $wgExtensionMessagesFiles for the script loader
325 - * this can't be done in a normal extension type way
326 - * since the script-loader is an entry point
327 - */
 323+# load the $wgExtensionMessagesFiles for the script loader
 324+# this can't be done in a normal extension type way
 325+# since the script-loader is an entry point
 326+#
328327 $wgExtensionMessagesFiles['mwEmbed'] = "{$IP}/js2/mwEmbed/php/languages/mwEmbed.i18n.php";
329328
 329+# Include the js2/mwEmbed autoLoadClasses if js2 is enabled
 330+if( $wgEnableJS2system ){
 331+ require_once("$IP/js2/mwEmbed/php/jsAutoloadLocalClasses.php");
 332+}
 333+
330334 # Extension setup functions for extensions other than skins
331335 # Entries should be added to this variable during the inclusion
332336 # of the extension file. This allows the extension to perform
Index: trunk/phase3/includes/OutputPage.php
@@ -16,10 +16,9 @@
1717
1818 var $mScriptLoaderClassList = array();
1919
20 - // The most recent revision ID of any wikiPage script that is grouped in the script request
21 - var $mLatestScriptRevID = 0;
 20+ var $mScripts = '', $mLinkColours, $mPageLinkTitle = '', $mHeadItems = array();
 21+ var $mInlineMsg = array();
2222
23 - var $mScripts = '', $mLinkColours, $mPageLinkTitle = '', $mHeadItems = array();
2423 var $mTemplateIds = array();
2524
2625 var $mAllowUserJs;
@@ -119,7 +118,7 @@
120119 */
121120 function addScriptFile( $file ) {
122121 global $wgStylePath, $wgScript, $wgUser;
123 - global $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses, $wgEnableScriptLoader, $wgScriptPath;
 122+ global $wgEnableScriptLoader, $wgScriptPath;
124123
125124 if( substr( $file, 0, 1 ) == '/' ) {
126125 $path = $file;
@@ -127,42 +126,41 @@
128127 $path = "{$wgStylePath}/common/{$file}";
129128 }
130129
131 - if( $wgEnableScriptLoader ) {
132 - if( strpos( $path, $wgScript ) !== false ) {
133 - $reqPath = str_replace( $wgScript . '?', '', $path );
134 - $reqArgs = explode( '&', $reqPath );
135 - $reqSet = array();
 130+ // If the class can be determined, use the addScriptClass method
 131+ $js_class = $this->getJsClassFromPath( $path );
 132+ if( $js_class ) {
 133+ $this->addScriptClass( $js_class );
 134+ return true;
 135+ }
136136
137 - foreach( $reqArgs as $arg ) {
138 - list( $key, $var ) = explode( '=', $arg );
139 - $reqSet[$key] = $var;
140 - }
 137+ //do checks for wiki-titles
 138+ if( strpos( $path, $wgScript ) !== false ) {
 139+ $reqPath = str_replace( $wgScript . '?', '', $path );
 140+ $reqArgs = explode( '&', $reqPath );
 141+ $reqSet = array();
141142
142 - if( isset( $reqSet['title'] ) && $reqSet != '' ) {
 143+ foreach( $reqArgs as $arg ) {
 144+ list( $key, $var ) = explode( '=', $arg );
 145+ $reqSet[$key] = $var;
 146+ }
 147+
 148+ if( isset( $reqSet['title'] ) && $reqSet != '' ) {
 149+ $jsTitleClass = 'WT:' . $reqSet['title'];
 150+ if( $wgEnableScriptLoader ) {
143151 // Extract any extra parameters (for now just skin)
144152 $ext_param = ( isset( $reqSet['useskin'] ) && $reqSet['useskin'] != '' )
145153 ? '|useskin=' . ucfirst( $reqSet['useskin'] ) : '';
146 - $this->mScriptLoaderClassList[] = 'WT:' . $reqSet['title'] . $ext_param ;
147 - // Add the title revision to the key.
148 - // If there is no title, we will just use $wgStyleVersion,
149 - // which should be updated on the relevant commits.
150 - $t = Title::newFromText( $reqSet['title'] );
151 - if( $t && $t->exists() ) {
152 - if( $t->getLatestRevID() > $this->mLatestScriptRevID )
153 - $this->mLatestScriptRevID = $t->getLatestRevID();
154 - }
 154+ $this->mScriptLoaderClassList[] = $jsTitleClass . $ext_param ;
155155 return true;
 156+ }else{
 157+ $this->addScript( Html::linkedScript(
 158+ wfAppendQuery( $path, $this->getURIDparam( $jsTitleClass ) )
 159+ )
 160+ );
 161+ return true;
156162 }
157163 }
158 -
159 - // If the class can be determined, add it to the class list to be loaded later
160 - $js_class = $this->getJsClassFromPath( $path );
161 - if( $js_class ) {
162 - $this->mScriptLoaderClassList[] = $js_class;
163 - return true;
164 - }
165164 }
166 -
167165 // If the script loader could not be used, just add the script to the header
168166 $this->addScript( Html::linkedScript( wfAppendQuery( $path, $this->getURIDparam() ) ) );
169167 }
@@ -171,7 +169,7 @@
172170 * Add the core scripts that are included on every page, for later output into the header
173171 */
174172 function addCoreScripts2Top(){
175 - global $wgEnableScriptLoader, $wgJSAutoloadLocalClasses, $wgScriptPath, $wgStylePath, $wgEnableJS2system;
 173+ global $wgEnableScriptLoader, $wgJSAutoloadLocalClasses, $wgScriptPath, $wgEnableJS2system;
176174 // @todo We should deprecate wikibits in favor of mv_embed and jQuery
177175
178176 if( $wgEnableJS2system ){
@@ -181,38 +179,30 @@
182180 }
183181
184182 if( $wgEnableScriptLoader ){
 183+ //add core to top of mScripts
185184 $this->mScripts = $this->getScriptLoaderJs( $core_classes ) . $this->mScripts;
186185 } else {
187186 $so = '';
188 - foreach( $core_classes as $s ){
189 - if( isset( $wgJSAutoloadLocalClasses[$s] ) ){
190 - $path = $wgJSAutoloadLocalClasses[$s];
191 - // @fixme this is an awful hack
192 - if( substr( $path, 0, 4 ) == "http" || substr( $path, 0, 1 ) == '/' ) {
193 - // Assume a full or local path
194 - } elseif( substr( $path, 0, 6 ) == "skins/" ) {
195 - $path = $wgStylePath . substr( $path, 5 );
196 - } else {
197 - $path = $wgScriptPath . "/" . $path;
198 - }
199 - $so .= Html::linkedScript( $path . "?" . $this->getURIDparam() );
200 - }
 187+ //make sure scripts are on top:
 188+ $postMscripts = $this->mScripts;
 189+ $this->mScripts = '';
 190+ foreach( $core_classes as $js_class ){
 191+ $this->addScriptClass( $js_class );
201192 }
202 - $this->mScripts = $so . $this->mScripts;
 193+ $this->mScripts .= $postMscripts;
203194 }
204195 }
205196
206197 /**
207 - * @param $js_class string Name of the JavaScript class
 198+ * @param string $js_class Name of the JavaScript class
208199 * @return boolean False if the class wasn't found, true on success
209200 */
210201 function addScriptClass( $js_class ){
211202 global $wgDebugJavaScript, $wgJSAutoloadLocalClasses, $wgJSAutoloadClasses,
212203 $wgEnableScriptLoader, $wgStyleVersion, $wgScriptPath;
213204
214 - if( isset( $wgJSAutoloadClasses[$js_class] )
215 - || isset( $wgJSAutoloadLocalClasses[$js_class] ) )
216 - {
 205+ $path = jsScriptLoader::getJsPathFromClass( $js_class );
 206+ if( $path !== false ){
217207 if( $wgEnableScriptLoader ) {
218208 // Register it with the script loader
219209 if( !in_array( $js_class, $this->mScriptLoaderClassList ) ) {
@@ -220,17 +210,18 @@
221211 }
222212 } else {
223213 // Source the script directly
224 - $path = $wgScriptPath . '/';
225 - if( isset( $wgJSAutoloadClasses[$js_class] ) ) {
226 - $path .= $wgJSAutoloadClasses[$js_class];
227 - } elseif( isset( $wgJSAutoloadLocalClasses[$js_class] ) ) {
228 - $path .= $wgJSAutoloadLocalClasses[$js_class];
229 - }
230 - $urlAppend = ( $wgDebugJavaScript ) ? time() : $wgStyleVersion;
 214+ $path = $wgScriptPath . '/' . $path;
 215+ $urlAppend = ( $wgDebugJavaScript ) ? time() : $this->getURIDparam( $js_class );
231216 $this->addScript( Html::linkedScript( "$path?$urlAppend" ) );
 217+
 218+ //merge in language text:
 219+ $inlineMsg = jsScriptLoader::getLocalizedMsgsFromClass( $js_class );
 220+ if( $inlineMsg != '' )
 221+ $this->addScript( Html::inlineScript( $inlineMsg ));
232222 }
233223 return true;
234224 }
 225+ print "could not find: $js_class\n";
235226 wfDebug( __METHOD__ . ' could not find js_class: ' . $js_class );
236227 return false; // could not find the class
237228 }
@@ -252,7 +243,7 @@
253244 $wgRequest->getVal( 'debug' ) == '1' )
254245 ? '&debug=true' : '';
255246
256 - return Html::linkedScript( wfScript( 'mwScriptLoader' ) .
 247+ return Html::linkedScript( wfScript( 'mwScriptLoader' ) .
257248 "?class={$class_list}{$debug_param}&" . $this->getURIDparam( $classAry) );
258249 }
259250
@@ -264,9 +255,13 @@
265256 if( $wgDebugJavaScript ) {
266257 return 'urid=' . time();
267258 } else {
268 - $ftime=0;
269 - if($wgScriptModifiedCheck) {
270 - foreach( $classAry as $class ) {
 259+ //support single class_name attr
 260+ if( gettype( $classAry) == 'string' ){
 261+ $classAry = array( $classAry );
 262+ }
 263+ $ftime = $frev = 0;
 264+ foreach( $classAry as $class ) {
 265+ if( $wgScriptModifiedCheck ) {
271266 $js_path = jsScriptLoader::getJsPathFromClass( $class );
272267 if( $js_path ) {
273268 $cur_ftime = filemtime ( $IP ."/". $js_path );
@@ -274,17 +269,27 @@
275270 $ftime = $cur_ftime;
276271 }
277272 }
 273+ // Add the latest revision ID if the class set includes a WT (wiki title)
 274+ if( substr($class, 0, 3) == 'WT:'){
 275+ $title_str = substr($class, 3);
 276+ $t = Title::newFromText( $title_str );
 277+ if( $t && $t->exists() ) {
 278+ if( $t->getLatestRevID() > $frev )
 279+ $frev = $t->getLatestRevID();
 280+ }
 281+ }
278282 }
 283+ //build the actual unique request id:
279284 $urid = "urid={$wgStyleVersion}";
280285
281 - // Add the latest revision ID if we have it
282 - if($this->mLatestScriptRevID != 0 )
283 - $urid .= "_{$this->mLatestScriptRevID}";
284 -
285 - // Add the file modification time
 286+ // Add the file modification time if set
286287 if( $ftime != 0 )
287 - $urid .= "_".$ftime;
 288+ $urid .= "_" . $ftime;
288289
 290+ //add the wiki rev id if set
 291+ if( $frev != 0 )
 292+ $urid.= "_" . $frev;
 293+
289294 return $urid;
290295 }
291296 }
@@ -1691,8 +1696,10 @@
16921697
16931698 /**
16941699 * @return string The doctype, opening <html>, and head element.
 1700+ *
 1701+ * @param $sk Skin The given Skin
16951702 */
1696 - public function headElement( Skin $sk ) {
 1703+ public function headElement( Skin $sk , $includeStyle = true ) {
16971704 global $wgDocType, $wgDTD, $wgContLanguageCode, $wgOutputEncoding, $wgMimeType;
16981705 global $wgXhtmlDefaultNamespace, $wgXhtmlNamespaces;
16991706 global $wgContLang, $wgUseTrackbacks, $wgStyleVersion, $wgEnableScriptLoader, $wgHtml5;
Index: trunk/phase3/includes/AutoLoader.php
@@ -623,11 +623,6 @@
624624 'ajaxCategories' => 'js2/ajaxcategories.js',
625625 );
626626
627 -//Include the js2 autoLoadClasses
628 -//@@todo move jsAutoloadLocalClasses.php to post Setup so we have default values and can check the $wgEnableJS2system var
629 -$wgMwEmbedDirectory = "js2/mwEmbed/";
630 -require_once("$IP/js2/mwEmbed/php/jsAutoloadLocalClasses.php");
631 -
632627 class AutoLoader {
633628 /**
634629 * autoload - take a class name and attempt to load it
Index: trunk/phase3/js2/mwEmbed/jsScriptLoader.php
@@ -22,6 +22,9 @@
2323 var $jsvarurl = false; // whether we should include generated JS (special class '-')
2424 var $doProcReqFlag = true;
2525
 26+ //@@todo fix: will break down if someone does }); in their msg text
 27+ const loadGMregEx = '/loadGM\s*\(\s*{(.*)}\s*\)\s*/siU';
 28+
2629 function doScriptLoader() {
2730 global $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses, $wgEnableScriptLoaderJsFile, $IP,
2831 $wgEnableScriptMinify, $wgUseFileCache;
@@ -229,7 +232,7 @@
230233 $this->rKey .= $reqFile;
231234 }
232235 } else {
233 - $this->error_msg .= 'Not valid requsted JavaScript file' . "\n";
 236+ $this->error_msg .= 'Not valid requested JavaScript file' . "\n";
234237 }
235238 }
236239 }
@@ -256,18 +259,18 @@
257260 return false;
258261 }
259262 }
260 - function doProcessJsFile( $file_name ) {
 263+ function doProcessJsFile( $file_path ) {
261264 global $IP, $wgEnableScriptLocalization, $IP;
262265
263266 // Load the file
264 - $str = @file_get_contents( "{$IP}/{$file_name}" );
 267+ $str = @file_get_contents( "{$IP}/{$file_path}" );
265268
266269 if ( $str === false ) {
267270 // @@todo check PHP error level. Don't want to expose paths if errors are hidden.
268 - $this->error_msg .= 'Requested File: ' . htmlspecialchars( $file_name ) . ' could not be read' . "\n";
 271+ $this->error_msg .= 'Requested File: ' . htmlspecialchars( $file_path ) . ' could not be read' . "\n";
269272 return '';
270273 }
271 - $this->cur_file = $file_name;
 274+ $this->cur_file = $file_path;
272275
273276 // Strip out js_log debug lines. Not much luck with this regExp yet:
274277 // if( !$this->debug )
@@ -276,19 +279,28 @@
277280 // Do language swap
278281 if ( $wgEnableScriptLocalization )
279282 $str = preg_replace_callback(
280 - // @@todo fix: will break down if someone does }) in their msg text
281 - '/loadGM\s*\(\s*{(.*)}\s*\)\s*/siU',
282 - array( $this, 'languageMsgReplace' ),
283 - $str
284 - );
285 -
 283+ self::loadGMregEx,
 284+ array( $this, 'languageMsgReplace' ),
 285+ $str
 286+ );
286287 return $str;
287288 }
288 -
289 - function languageMsgReplace( $jvar ) {
 289+ static public function getLocalizedMsgsFromClass( $class ){
 290+ global $IP;
 291+ $path = self::getJsPathFromClass( $class );
 292+ // Load the file
 293+ $str = @file_get_contents( "{$IP}/{$path}" );
 294+ //extract the msg:
 295+ preg_match(self::loadGMregEx, $str, $matches);
 296+ if( isset( $matches[1] )){
 297+ return self::languageMsgReplace( $matches, false );
 298+ }
 299+ //if could not parse return empty string:
 300+ return '';
 301+ }
 302+ static public function languageMsgReplace( $jvar ) {
290303 if ( !isset( $jvar[1] ) )
291 - return;
292 -
 304+ return '';
293305 $jmsg = FormatJson::decode( '{' . $jvar[1] . '}', true );
294306
295307 // Do the language lookup
@@ -296,14 +308,20 @@
297309 foreach ( $jmsg as $msgKey => $default_en_value ) {
298310 $jmsg[$msgKey] = wfMsgNoTrans( $msgKey );
299311 }
300 - // Return the updated loadGM JSON with fixed new lines
 312+ // Return the updated loadGM JSON with updated msgs:
301313 return 'loadGM( ' . FormatJson::encode( $jmsg ) . ')';
302314 } else {
303 - $this->error_msg .= "Could not parse JSON language msg in File:\n" .
304 - htmlspecialchars ( $this->cur_file ) . "\n";
 315+ print_r($jvar);
 316+
 317+ // Could not parse JSON return error: (maybe a alert?)
 318+ //we just make a note in the code, visitors will get the fallback language,
 319+ //developers will read the js source when its not behaving as expected.
 320+ return "/*
 321+* Could not parse JSON language messages in this file,
 322+* Please check that loadGM call contains valid JSON (not javascript)
 323+*/\n\n" . $jvar[0]; //include the original fallback loadGM
 324+
305325 }
306 - // Could not parse JSON (throw error?)
307 - return $jvar[0];
308326 }
309327 }
310328

Status & tagging log