Index: trunk/phase3/includes/json/FormatJson.php |
— | — | @@ -18,15 +18,15 @@ |
19 | 19 | return json_encode($value); |
20 | 20 | } |
21 | 21 | } |
22 | | - public static function decode($value, $assoc=false){ |
| 22 | + public static function decode( $value, $assoc=false ){ |
23 | 23 | if (!function_exists('json_decode') ) { |
24 | 24 | $json = new Services_JSON(); |
25 | | - $jsonDec = $json->decode($value); |
26 | | - if($assoc) |
| 25 | + $jsonDec = $json->decode( $value ); |
| 26 | + if( $assoc ) |
27 | 27 | $jsonDec = wfObjectToArray( $jsonDec ); |
28 | 28 | return $jsonDec; |
29 | 29 | } else { |
30 | | - return json_decode($value, $assoc); |
| 30 | + return json_decode( $value, $assoc ); |
31 | 31 | } |
32 | 32 | } |
33 | 33 | } |
Index: trunk/phase3/includes/Setup.php |
— | — | @@ -319,13 +319,17 @@ |
320 | 320 | wfProfileOut( $fname.'-misc2' ); |
321 | 321 | wfProfileIn( $fname.'-extensions' ); |
322 | 322 | |
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 | +# |
328 | 327 | $wgExtensionMessagesFiles['mwEmbed'] = "{$IP}/js2/mwEmbed/php/languages/mwEmbed.i18n.php"; |
329 | 328 | |
| 329 | +# Include the js2/mwEmbed autoLoadClasses if js2 is enabled |
| 330 | +if( $wgEnableJS2system ){ |
| 331 | + require_once("$IP/js2/mwEmbed/php/jsAutoloadLocalClasses.php"); |
| 332 | +} |
| 333 | + |
330 | 334 | # Extension setup functions for extensions other than skins |
331 | 335 | # Entries should be added to this variable during the inclusion |
332 | 336 | # of the extension file. This allows the extension to perform |
Index: trunk/phase3/includes/OutputPage.php |
— | — | @@ -16,10 +16,9 @@ |
17 | 17 | |
18 | 18 | var $mScriptLoaderClassList = array(); |
19 | 19 | |
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(); |
22 | 22 | |
23 | | - var $mScripts = '', $mLinkColours, $mPageLinkTitle = '', $mHeadItems = array(); |
24 | 23 | var $mTemplateIds = array(); |
25 | 24 | |
26 | 25 | var $mAllowUserJs; |
— | — | @@ -119,7 +118,7 @@ |
120 | 119 | */ |
121 | 120 | function addScriptFile( $file ) { |
122 | 121 | global $wgStylePath, $wgScript, $wgUser; |
123 | | - global $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses, $wgEnableScriptLoader, $wgScriptPath; |
| 122 | + global $wgEnableScriptLoader, $wgScriptPath; |
124 | 123 | |
125 | 124 | if( substr( $file, 0, 1 ) == '/' ) { |
126 | 125 | $path = $file; |
— | — | @@ -127,42 +126,41 @@ |
128 | 127 | $path = "{$wgStylePath}/common/{$file}"; |
129 | 128 | } |
130 | 129 | |
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 | + } |
136 | 136 | |
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(); |
141 | 142 | |
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 ) { |
143 | 151 | // Extract any extra parameters (for now just skin) |
144 | 152 | $ext_param = ( isset( $reqSet['useskin'] ) && $reqSet['useskin'] != '' ) |
145 | 153 | ? '|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 ; |
155 | 155 | return true; |
| 156 | + }else{ |
| 157 | + $this->addScript( Html::linkedScript( |
| 158 | + wfAppendQuery( $path, $this->getURIDparam( $jsTitleClass ) ) |
| 159 | + ) |
| 160 | + ); |
| 161 | + return true; |
156 | 162 | } |
157 | 163 | } |
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 | | - } |
165 | 164 | } |
166 | | - |
167 | 165 | // If the script loader could not be used, just add the script to the header |
168 | 166 | $this->addScript( Html::linkedScript( wfAppendQuery( $path, $this->getURIDparam() ) ) ); |
169 | 167 | } |
— | — | @@ -171,7 +169,7 @@ |
172 | 170 | * Add the core scripts that are included on every page, for later output into the header |
173 | 171 | */ |
174 | 172 | function addCoreScripts2Top(){ |
175 | | - global $wgEnableScriptLoader, $wgJSAutoloadLocalClasses, $wgScriptPath, $wgStylePath, $wgEnableJS2system; |
| 173 | + global $wgEnableScriptLoader, $wgJSAutoloadLocalClasses, $wgScriptPath, $wgEnableJS2system; |
176 | 174 | // @todo We should deprecate wikibits in favor of mv_embed and jQuery |
177 | 175 | |
178 | 176 | if( $wgEnableJS2system ){ |
— | — | @@ -181,38 +179,30 @@ |
182 | 180 | } |
183 | 181 | |
184 | 182 | if( $wgEnableScriptLoader ){ |
| 183 | + //add core to top of mScripts |
185 | 184 | $this->mScripts = $this->getScriptLoaderJs( $core_classes ) . $this->mScripts; |
186 | 185 | } else { |
187 | 186 | $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 ); |
201 | 192 | } |
202 | | - $this->mScripts = $so . $this->mScripts; |
| 193 | + $this->mScripts .= $postMscripts; |
203 | 194 | } |
204 | 195 | } |
205 | 196 | |
206 | 197 | /** |
207 | | - * @param $js_class string Name of the JavaScript class |
| 198 | + * @param string $js_class Name of the JavaScript class |
208 | 199 | * @return boolean False if the class wasn't found, true on success |
209 | 200 | */ |
210 | 201 | function addScriptClass( $js_class ){ |
211 | 202 | global $wgDebugJavaScript, $wgJSAutoloadLocalClasses, $wgJSAutoloadClasses, |
212 | 203 | $wgEnableScriptLoader, $wgStyleVersion, $wgScriptPath; |
213 | 204 | |
214 | | - if( isset( $wgJSAutoloadClasses[$js_class] ) |
215 | | - || isset( $wgJSAutoloadLocalClasses[$js_class] ) ) |
216 | | - { |
| 205 | + $path = jsScriptLoader::getJsPathFromClass( $js_class ); |
| 206 | + if( $path !== false ){ |
217 | 207 | if( $wgEnableScriptLoader ) { |
218 | 208 | // Register it with the script loader |
219 | 209 | if( !in_array( $js_class, $this->mScriptLoaderClassList ) ) { |
— | — | @@ -220,17 +210,18 @@ |
221 | 211 | } |
222 | 212 | } else { |
223 | 213 | // 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 ); |
231 | 216 | $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 )); |
232 | 222 | } |
233 | 223 | return true; |
234 | 224 | } |
| 225 | + print "could not find: $js_class\n"; |
235 | 226 | wfDebug( __METHOD__ . ' could not find js_class: ' . $js_class ); |
236 | 227 | return false; // could not find the class |
237 | 228 | } |
— | — | @@ -252,7 +243,7 @@ |
253 | 244 | $wgRequest->getVal( 'debug' ) == '1' ) |
254 | 245 | ? '&debug=true' : ''; |
255 | 246 | |
256 | | - return Html::linkedScript( wfScript( 'mwScriptLoader' ) . |
| 247 | + return Html::linkedScript( wfScript( 'mwScriptLoader' ) . |
257 | 248 | "?class={$class_list}{$debug_param}&" . $this->getURIDparam( $classAry) ); |
258 | 249 | } |
259 | 250 | |
— | — | @@ -264,9 +255,13 @@ |
265 | 256 | if( $wgDebugJavaScript ) { |
266 | 257 | return 'urid=' . time(); |
267 | 258 | } 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 ) { |
271 | 266 | $js_path = jsScriptLoader::getJsPathFromClass( $class ); |
272 | 267 | if( $js_path ) { |
273 | 268 | $cur_ftime = filemtime ( $IP ."/". $js_path ); |
— | — | @@ -274,17 +269,27 @@ |
275 | 270 | $ftime = $cur_ftime; |
276 | 271 | } |
277 | 272 | } |
| 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 | + } |
278 | 282 | } |
| 283 | + //build the actual unique request id: |
279 | 284 | $urid = "urid={$wgStyleVersion}"; |
280 | 285 | |
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 |
286 | 287 | if( $ftime != 0 ) |
287 | | - $urid .= "_".$ftime; |
| 288 | + $urid .= "_" . $ftime; |
288 | 289 | |
| 290 | + //add the wiki rev id if set |
| 291 | + if( $frev != 0 ) |
| 292 | + $urid.= "_" . $frev; |
| 293 | + |
289 | 294 | return $urid; |
290 | 295 | } |
291 | 296 | } |
— | — | @@ -1691,8 +1696,10 @@ |
1692 | 1697 | |
1693 | 1698 | /** |
1694 | 1699 | * @return string The doctype, opening <html>, and head element. |
| 1700 | + * |
| 1701 | + * @param $sk Skin The given Skin |
1695 | 1702 | */ |
1696 | | - public function headElement( Skin $sk ) { |
| 1703 | + public function headElement( Skin $sk , $includeStyle = true ) { |
1697 | 1704 | global $wgDocType, $wgDTD, $wgContLanguageCode, $wgOutputEncoding, $wgMimeType; |
1698 | 1705 | global $wgXhtmlDefaultNamespace, $wgXhtmlNamespaces; |
1699 | 1706 | global $wgContLang, $wgUseTrackbacks, $wgStyleVersion, $wgEnableScriptLoader, $wgHtml5; |
Index: trunk/phase3/includes/AutoLoader.php |
— | — | @@ -623,11 +623,6 @@ |
624 | 624 | 'ajaxCategories' => 'js2/ajaxcategories.js', |
625 | 625 | ); |
626 | 626 | |
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 | | - |
632 | 627 | class AutoLoader { |
633 | 628 | /** |
634 | 629 | * autoload - take a class name and attempt to load it |
Index: trunk/phase3/js2/mwEmbed/jsScriptLoader.php |
— | — | @@ -22,6 +22,9 @@ |
23 | 23 | var $jsvarurl = false; // whether we should include generated JS (special class '-') |
24 | 24 | var $doProcReqFlag = true; |
25 | 25 | |
| 26 | + //@@todo fix: will break down if someone does }); in their msg text |
| 27 | + const loadGMregEx = '/loadGM\s*\(\s*{(.*)}\s*\)\s*/siU'; |
| 28 | + |
26 | 29 | function doScriptLoader() { |
27 | 30 | global $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses, $wgEnableScriptLoaderJsFile, $IP, |
28 | 31 | $wgEnableScriptMinify, $wgUseFileCache; |
— | — | @@ -229,7 +232,7 @@ |
230 | 233 | $this->rKey .= $reqFile; |
231 | 234 | } |
232 | 235 | } else { |
233 | | - $this->error_msg .= 'Not valid requsted JavaScript file' . "\n"; |
| 236 | + $this->error_msg .= 'Not valid requested JavaScript file' . "\n"; |
234 | 237 | } |
235 | 238 | } |
236 | 239 | } |
— | — | @@ -256,18 +259,18 @@ |
257 | 260 | return false; |
258 | 261 | } |
259 | 262 | } |
260 | | - function doProcessJsFile( $file_name ) { |
| 263 | + function doProcessJsFile( $file_path ) { |
261 | 264 | global $IP, $wgEnableScriptLocalization, $IP; |
262 | 265 | |
263 | 266 | // Load the file |
264 | | - $str = @file_get_contents( "{$IP}/{$file_name}" ); |
| 267 | + $str = @file_get_contents( "{$IP}/{$file_path}" ); |
265 | 268 | |
266 | 269 | if ( $str === false ) { |
267 | 270 | // @@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"; |
269 | 272 | return ''; |
270 | 273 | } |
271 | | - $this->cur_file = $file_name; |
| 274 | + $this->cur_file = $file_path; |
272 | 275 | |
273 | 276 | // Strip out js_log debug lines. Not much luck with this regExp yet: |
274 | 277 | // if( !$this->debug ) |
— | — | @@ -276,19 +279,28 @@ |
277 | 280 | // Do language swap |
278 | 281 | if ( $wgEnableScriptLocalization ) |
279 | 282 | $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 | + ); |
286 | 287 | return $str; |
287 | 288 | } |
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 ) { |
290 | 303 | if ( !isset( $jvar[1] ) ) |
291 | | - return; |
292 | | - |
| 304 | + return ''; |
293 | 305 | $jmsg = FormatJson::decode( '{' . $jvar[1] . '}', true ); |
294 | 306 | |
295 | 307 | // Do the language lookup |
— | — | @@ -296,14 +308,20 @@ |
297 | 309 | foreach ( $jmsg as $msgKey => $default_en_value ) { |
298 | 310 | $jmsg[$msgKey] = wfMsgNoTrans( $msgKey ); |
299 | 311 | } |
300 | | - // Return the updated loadGM JSON with fixed new lines |
| 312 | + // Return the updated loadGM JSON with updated msgs: |
301 | 313 | return 'loadGM( ' . FormatJson::encode( $jmsg ) . ')'; |
302 | 314 | } 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 | + |
305 | 325 | } |
306 | | - // Could not parse JSON (throw error?) |
307 | | - return $jvar[0]; |
308 | 326 | } |
309 | 327 | } |
310 | 328 | |