Follows-up9272bc6c47,03c503da22,1e063f6078. One can't wrap arbitrary JavaScript in an if-statement and have its inner-body mean exactly the same. Certain statements are only allowed in the top of a scope (such as hoisted function declarations). These are not allowed inside a block. They're fine in both global scope and local function scope, but not inside an if-block of any scope. The ECMAScript spec only describes what is an allowed token. Any unexpected token should result in a SyntaxError. Chrome's implementation (V8) allows function declarations in blocks and hoists them to *outside* the condition. Firefox's SpiderMonkey silently ignores the statement. Neither throw a SyntaxError. Rgular ResourceLoader responses only contain mw.loader.implement() and mw.loader.state() call which could be wrapped without issues. However such responses don't need wrapping as they're only made by mediawiki.js (in which case mw is obviously loaded). The wrapping is for legacy scripts that execute in the global scope. For those, let's wrap the script tag itself (instead of the response). That seems like the most water-tight and semantically correct solution. Had to bring in $isRaw from ResourceLoader.php, else the startup module would have been wrapped as well (added regression test). Bug: 69924 Change-Id: Iedda0464f734ba5f7a884726487f6c7e07d444f1
95 lines
2.2 KiB
PHP
95 lines
2.2 KiB
PHP
<?php
|
|
|
|
abstract class ResourceLoaderTestCase extends MediaWikiTestCase {
|
|
protected static function getResourceLoaderContext( $lang = 'en' ) {
|
|
$resourceLoader = new ResourceLoader();
|
|
$request = new FauxRequest( array(
|
|
'lang' => $lang,
|
|
'modules' => 'startup',
|
|
'only' => 'scripts',
|
|
'skin' => 'vector',
|
|
'target' => 'test',
|
|
) );
|
|
return new ResourceLoaderContext( $resourceLoader, $request );
|
|
}
|
|
|
|
protected function setUp() {
|
|
parent::setUp();
|
|
|
|
ResourceLoader::clearCache();
|
|
|
|
$this->setMwGlobals( array(
|
|
// For ResourceLoader::inDebugMode since it doesn't have context
|
|
'wgResourceLoaderDebug' => true,
|
|
|
|
// Avoid influence from wgInvalidateCacheOnLocalSettingsChange
|
|
'wgCacheEpoch' => '20140101000000',
|
|
|
|
// For ResourceLoader::__construct()
|
|
'wgResourceLoaderSources' => array(),
|
|
|
|
// For wfScript()
|
|
'wgScriptPath' => '/w',
|
|
'wgScriptExtension' => '.php',
|
|
'wgScript' => '/w/index.php',
|
|
'wgLoadScript' => '/w/load.php',
|
|
) );
|
|
}
|
|
}
|
|
|
|
/* Stubs */
|
|
|
|
class ResourceLoaderTestModule extends ResourceLoaderModule {
|
|
protected $dependencies = array();
|
|
protected $group = null;
|
|
protected $source = 'local';
|
|
protected $script = '';
|
|
protected $styles = '';
|
|
protected $skipFunction = null;
|
|
protected $isRaw = false;
|
|
protected $targets = array( 'test' );
|
|
|
|
public function __construct( $options = array() ) {
|
|
foreach ( $options as $key => $value ) {
|
|
$this->$key = $value;
|
|
}
|
|
}
|
|
|
|
public function getScript( ResourceLoaderContext $context ) {
|
|
return $this->script;
|
|
}
|
|
|
|
public function getStyles( ResourceLoaderContext $context ) {
|
|
return array( '' => $this->styles );
|
|
}
|
|
|
|
public function getDependencies() {
|
|
return $this->dependencies;
|
|
}
|
|
|
|
public function getGroup() {
|
|
return $this->group;
|
|
}
|
|
|
|
public function getSource() {
|
|
return $this->source;
|
|
}
|
|
|
|
public function getSkipFunction() {
|
|
return $this->skipFunction;
|
|
}
|
|
|
|
public function isRaw() {
|
|
return $this->isRaw;
|
|
}
|
|
}
|
|
|
|
class ResourceLoaderFileModuleTestModule extends ResourceLoaderFileModule {
|
|
}
|
|
|
|
class ResourceLoaderWikiModuleTestModule extends ResourceLoaderWikiModule {
|
|
// Override expected via PHPUnit mocks and stubs
|
|
protected function getPages( ResourceLoaderContext $context ) {
|
|
return array();
|
|
}
|
|
}
|