/** * @dataProvider provideResourceLoaderContext * @covers ResourceLoaderFileModule::compileLessFile */ public function testLessFileCompilation($context) { $basePath = __DIR__ . '/../data/less/module'; $module = new ResourceLoaderFileModule(array('localBasePath' => $basePath, 'styles' => array('styles.less'))); $styles = $module->getStyles($context); $this->assertStringEqualsFile($basePath . '/styles.css', $styles['all']); }
/** * @covers ResourceLoaderFileModule::compileLessFile */ public function testLessFileCompilation() { $context = $this->getResourceLoaderContext(); $basePath = __DIR__ . '/../../data/less/module'; $module = new ResourceLoaderFileModule(['localBasePath' => $basePath, 'styles' => ['styles.less']]); $module->setName('test.less'); $styles = $module->getStyles($context); $this->assertStringEqualsFile($basePath . '/styles.css', $styles['all']); }
/** * What happens when you mix @embed and @noflip? * This really is an integration test, but oh well. */ public function testMixedCssAnnotations() { $basePath = __DIR__ . '/../../data/css'; $testModule = new ResourceLoaderFileModule(array('localBasePath' => $basePath, 'styles' => array('test.css'))); $expectedModule = new ResourceLoaderFileModule(array('localBasePath' => $basePath, 'styles' => array('expected.css'))); $contextLtr = self::getResourceLoaderContext('en'); $contextRtl = self::getResourceLoaderContext('he'); $this->assertEquals($expectedModule->getStyles($contextLtr), $testModule->getStyles($contextLtr), "/*@noflip*/ with /*@embed*/ gives correct results in LTR mode"); $this->assertEquals($expectedModule->getStyles($contextLtr), $testModule->getStyles($contextRtl), "/*@noflip*/ with /*@embed*/ gives correct results in RTL mode"); }
/** * Get all JavaScript code. * * @param ResourceLoaderContext $context * @return string JavaScript code */ public function getScript(ResourceLoaderContext $context) { $script = parent::getScript($context); // Add closure explicitly because raw modules can't be wrapped mw.loader.implement. // Unlike with mw.loader.implement, this closure is immediately invoked. // @see ResourceLoader::makeModuleResponse // @see ResourceLoader::makeLoaderImplementScript return "(function () {\n{$script}\n}());"; }
/** * Get language-specific LESS variables for this module. * * @since 1.27 * @param ResourceLoaderContext $context * @return array */ protected function getLessVars(ResourceLoaderContext $context) { $vars = parent::getLessVars($context); $language = Language::factory($context->getLanguage()); foreach ($language->getImageFiles() as $key => $value) { $vars[$key] = CSSMin::serializeStringValue($value); } return $vars; }
/** * @param ResourceLoaderContext $context * @return string JavaScript code */ public function getScript(ResourceLoaderContext $context) { $fileScript = parent::getScript($context); $tagData = Sanitizer::getRecognizedTagData(); $parserDefaults = array(); $parserDefaults['allowedHtmlElements'] = array_merge(array_keys($tagData['htmlpairs']), array_diff(array_keys($tagData['htmlsingle']), array_keys($tagData['htmlsingleonly']))); $dataScript = Xml::encodeJsCall('mw.jqueryMsg.setParserDefaults', array($parserDefaults)); return $fileScript . $dataScript; }
/** * What happens when you mix @embed and @noflip? * This really is an integration test, but oh well. */ public function testMixedCssAnnotations() { $basePath = __DIR__ . '/../../data/css'; $testModule = new ResourceLoaderFileModule(array('localBasePath' => $basePath, 'styles' => array('test.css'))); $expectedModule = new ResourceLoaderFileModule(array('localBasePath' => $basePath, 'styles' => array('expected.css'))); $contextLtr = self::getResourceLoaderContext('en'); $contextRtl = self::getResourceLoaderContext('he'); // Since we want to compare the effect of @noflip+@embed against the effect of just @embed, and // the @noflip annotations are always preserved, we need to strip them first. $this->assertEquals($expectedModule->getStyles($contextLtr), $this->stripNoflip($testModule->getStyles($contextLtr)), "/*@noflip*/ with /*@embed*/ gives correct results in LTR mode"); $this->assertEquals($expectedModule->getStyles($contextLtr), $this->stripNoflip($testModule->getStyles($contextRtl)), "/*@noflip*/ with /*@embed*/ gives correct results in RTL mode"); }
/** * @covers ResourceLoaderModule::getVersionHash */ public function testGetVersionHash() { $context = $this->getResourceLoaderContext(); $baseParams = ['scripts' => ['foo.js', 'bar.js'], 'dependencies' => ['jquery', 'mediawiki'], 'messages' => ['hello', 'world']]; $module = new ResourceLoaderFileModule($baseParams); $version = json_encode($module->getVersionHash($context)); // Exactly the same $module = new ResourceLoaderFileModule($baseParams); $this->assertEquals($version, json_encode($module->getVersionHash($context)), 'Instance is insignificant'); // Re-order dependencies $module = new ResourceLoaderFileModule(['dependencies' => ['mediawiki', 'jquery']] + $baseParams); $this->assertEquals($version, json_encode($module->getVersionHash($context)), 'Order of dependencies is insignificant'); // Re-order messages $module = new ResourceLoaderFileModule(['messages' => ['world', 'hello']] + $baseParams); $this->assertEquals($version, json_encode($module->getVersionHash($context)), 'Order of messages is insignificant'); // Re-order scripts $module = new ResourceLoaderFileModule(['scripts' => ['bar.js', 'foo.js']] + $baseParams); $this->assertNotEquals($version, json_encode($module->getVersionHash($context)), 'Order of scripts is significant'); // Subclass $module = new ResourceLoaderFileModuleTestModule($baseParams); $this->assertNotEquals($version, json_encode($module->getVersionHash($context)), 'Class is significant'); }
/** * @covers ResourceLoaderModule::getDefinitionSummary * @covers ResourceLoaderFileModule::getDefinitionSummary */ public function testDefinitionSummary() { $context = $this->getResourceLoaderContext(); $baseParams = array('scripts' => array('foo.js', 'bar.js'), 'dependencies' => array('jquery', 'mediawiki'), 'messages' => array('hello', 'world')); $module = new ResourceLoaderFileModule($baseParams); $jsonSummary = json_encode($module->getDefinitionSummary($context)); // Exactly the same $module = new ResourceLoaderFileModule($baseParams); $this->assertEquals($jsonSummary, json_encode($module->getDefinitionSummary($context)), 'Instance is insignificant'); // Re-order dependencies $module = new ResourceLoaderFileModule(array('dependencies' => array('mediawiki', 'jquery')) + $baseParams); $this->assertEquals($jsonSummary, json_encode($module->getDefinitionSummary($context)), 'Order of dependencies is insignificant'); // Re-order messages $module = new ResourceLoaderFileModule(array('messages' => array('world', 'hello')) + $baseParams); $this->assertEquals($jsonSummary, json_encode($module->getDefinitionSummary($context)), 'Order of messages is insignificant'); // Re-order scripts $module = new ResourceLoaderFileModule(array('scripts' => array('bar.js', 'foo.js')) + $baseParams); $this->assertNotEquals($jsonSummary, json_encode($module->getDefinitionSummary($context)), 'Order of scripts is significant'); // Subclass $module = new ResourceLoaderFileModuleTestModule($baseParams); $this->assertNotEquals($jsonSummary, json_encode($module->getDefinitionSummary($context)), 'Class is significant'); }
public function __construct($options = array(), $localBasePath = null, $remoteBasePath = null) { global $wgContLang; parent::__construct($options, $localBasePath, $remoteBasePath); // Get the content language code, and all the fallbacks. The first that // has a ext.cite.style.<lang code>.css file present will be used. $langCodes = array_merge(array($wgContLang->getCode()), $wgContLang->getFallbackLanguages()); foreach ($langCodes as $lang) { $langStyleFile = 'ext.cite.style.' . $lang . '.css'; $localPath = $this->getLocalPath($langStyleFile); if (file_exists($localPath)) { $this->styles[] = $langStyleFile; break; } } }
/** * Get a LESS compiler instance for this module. * * Set our variables in it. * * @throws MWException * @param ResourceLoaderContext $context * @return Less_Parser */ protected function getLessCompiler(ResourceLoaderContext $context = null) { $parser = parent::getLessCompiler(); $parser->ModifyVars($this->getLessVars($context)); return $parser; }
public function testBomConcatenation() { $basePath = __DIR__ . '/../../data/css'; $testModule = new ResourceLoaderFileModule(['localBasePath' => $basePath, 'styles' => ['bom.css']]); $testModule->setName('testing'); $this->assertEquals(substr(file_get_contents("{$basePath}/bom.css"), 0, 10), ".efbbbf", 'File has leading BOM'); $contextLtr = $this->getResourceLoaderContext('en', 'ltr'); $this->assertEquals($testModule->getStyles($contextLtr), ['all' => ".efbbbf_bom_char_at_start_of_file {}\n"], 'Leading BOM removed when concatenating files'); }
/** * @param $context ResourceLoaderContext * @return string: Hash */ public function getModifiedHash(ResourceLoaderContext $context) { $logo = $this->getConfig()->get('Logo'); $logoHD = $this->getConfig()->get('LogoHD'); return md5(parent::getModifiedHash($context) . $logo . json_encode($logoHD)); }
public function getModifiedTime(ResourceLoaderContext $context) { $modifiedTime = parent::getModifiedTime($context); $modifiedTime = max($modifiedTime, $this->getAbTesting()->getConfigModifiedTime()); return $modifiedTime; }
public function __construct($options = array(), $localBasePath = null, $remoteBasePath = null) { $veConfig = ConfigFactory::getDefaultInstance()->makeConfig('visualeditor'); $options['messages'] = array_merge($options['messages'], array_filter($veConfig->get('VisualEditorTabMessages'))); parent::__construct($options, $localBasePath, $remoteBasePath); }
/** * @dataProvider providerGetTemplates * @covers ResourceLoaderFileModule::getTemplates */ public function testGetTemplates($module, $expected) { $rl = new ResourceLoaderFileModule($module); $this->assertEquals($rl->getTemplates(), $expected); }
/** * Get the URL or URLs to load for this module's JS in debug mode. * @param ResourceLoaderContext $context * @return array list of urls * @see ResourceLoaderModule::getScriptURLsForDebug */ public function getScriptURLsForDebug(ResourceLoaderContext $context) { if ($this->hasHackedScriptMode) { $derivative = new DerivativeResourceLoaderContext($context); $derivative->setDebug(true); $derivative->setModules(array($this->getName())); // @todo FIXME: Make this templates and update // makeModuleResponse so that it only outputs template code. // When this is done you can merge with parent array and // retain file names. $derivative->setOnly('scripts'); $rl = $derivative->getResourceLoader(); $urls = array($rl->createLoaderURL($this->getSource(), $derivative)); } else { $urls = parent::getScriptURLsForDebug($context); } return $urls; }
/** * Register a module with the ResourceLoader system. * * @param mixed $name Name of module as a string or List of name/object pairs as an array * @param array $info Module info array. For backwards compatibility with 1.17alpha, * this may also be a ResourceLoaderModule object. Optional when using * multiple-registration calling style. * @throws MWException If a duplicate module registration is attempted * @throws MWException If a module name contains illegal characters (pipes or commas) * @throws MWException If something other than a ResourceLoaderModule is being registered * @return bool False if there were any errors, in which case one or more modules were * not registered */ public function register($name, $info = null) { // Allow multiple modules to be registered in one call $registrations = is_array($name) ? $name : array($name => $info); foreach ($registrations as $name => $info) { // Disallow duplicate registrations if (isset($this->moduleInfos[$name])) { // A module has already been registered by this name throw new MWException('ResourceLoader duplicate registration error. ' . 'Another module has already been registered as ' . $name); } // Check $name for validity if (!self::isValidModuleName($name)) { throw new MWException("ResourceLoader module name '{$name}' is invalid, " . "see ResourceLoader::isValidModuleName()"); } // Attach module if ($info instanceof ResourceLoaderModule) { $this->moduleInfos[$name] = array('object' => $info); $info->setName($name); $this->modules[$name] = $info; } elseif (is_array($info)) { // New calling convention $this->moduleInfos[$name] = $info; } else { throw new MWException('ResourceLoader module info type error for module \'' . $name . '\': expected ResourceLoaderModule or array (got: ' . gettype($info) . ')'); } // Last-minute changes // Apply custom skin-defined styles to existing modules. if ($this->isFileModule($name)) { foreach ($this->config->get('ResourceModuleSkinStyles') as $skinName => $skinStyles) { // If this module already defines skinStyles for this skin, ignore $wgResourceModuleSkinStyles. if (isset($this->moduleInfos[$name]['skinStyles'][$skinName])) { continue; } // If $name is preceded with a '+', the defined style files will be added to 'default' // skinStyles, otherwise 'default' will be ignored as it normally would be. if (isset($skinStyles[$name])) { $paths = (array) $skinStyles[$name]; $styleFiles = array(); } elseif (isset($skinStyles['+' . $name])) { $paths = (array) $skinStyles['+' . $name]; $styleFiles = isset($this->moduleInfos[$name]['skinStyles']['default']) ? (array) $this->moduleInfos[$name]['skinStyles']['default'] : array(); } else { continue; } // Add new file paths, remapping them to refer to our directories and not use settings // from the module we're modifying, which come from the base definition. list($localBasePath, $remoteBasePath) = ResourceLoaderFileModule::extractBasePaths($skinStyles); foreach ($paths as $path) { $styleFiles[] = new ResourceLoaderFilePath($path, $localBasePath, $remoteBasePath); } $this->moduleInfos[$name]['skinStyles'][$skinName] = $styleFiles; } } } }
/** * Get a LESS compiler instance for this module. * * Set our variables in it. * * @throws MWException * @param ResourceLoaderContext $context * @return lessc */ protected function getLessCompiler(ResourceLoaderContext $context = null) { $compiler = parent::getLessCompiler(); $compiler->setVariables($this->getLessVars($context)); return $compiler; }
/** * @dataProvider providerGetModifiedTime * @covers ResourceLoaderFileModule::getModifiedTime */ public function testGetModifiedTime($module, $expected) { $rl = new ResourceLoaderFileModule($module); $ts = $rl->getModifiedTime($this->getResourceLoaderContext()); $this->assertEquals($ts, $expected); }
public function getRemotePath($file) { global $wgServer; $path = parent::getRemotePath($file); return $wgServer . $path; }
/** * @param ResourceLoaderContext $context * @return string JavaScript code */ public function getScript(ResourceLoaderContext $context) { $scripts = parent::getScript($context); return $scripts . Xml::encodeJsCall('ve.dm.MWSyntaxHighlightNode.static.addLanguages', array($this->getLanguages()), ResourceLoader::inDebugMode()); }