/** * @param ResourceLoader $rl * @return bool */ public static function onResourceLoaderRegisterModules(ResourceLoader $rl) { $moduleDependencies = array('mediawiki.api', 'mediawiki.RegExp', 'mediawiki.Title', 'mediawiki.jqueryMsg', 'mediawiki.Uri', 'moment', 'jquery.jStorage', 'jquery.client', 'jquery.hidpi'); // If EventLogging is present, add the schema as a dependency. if (class_exists('ResourceLoaderSchemaModule')) { $moduleDependencies[] = "schema.Popups"; } $rl->register("ext.popups", array('scripts' => array('resources/ext.popups.core.js', 'resources/ext.popups.logger.js', 'resources/ext.popups.renderer.js', 'resources/ext.popups.renderer.article.js', 'resources/ext.popups.disablenavpop.js', 'resources/ext.popups.settings.js'), 'styles' => array('resources/ext.popups.core.less', 'resources/ext.popups.animation.less', 'resources/ext.popups.settings.less'), 'dependencies' => $moduleDependencies, 'messages' => array('popups-last-edited', "popups-settings-title", "popups-settings-description", "popups-settings-option-simple", "popups-settings-option-simple-description", "popups-settings-option-advanced", "popups-settings-option-advanced-description", "popups-settings-option-off", "popups-settings-option-off-description", "popups-settings-save", "popups-settings-cancel", "popups-settings-enable", "popups-settings-help", "popups-settings-help-ok", "popups-send-feedback"), 'remoteExtPath' => 'Popups', 'localBasePath' => __DIR__)); return true; }
public static function onResourceLoaderRegisterModules(ResourceLoader &$resourceLoader) { global $wgFlowEventLogging, $wgResourceModules; // Only if EventLogging in Flow is enabled & EventLogging exists if ($wgFlowEventLogging && class_exists('ResourceLoaderSchemaModule')) { $resourceLoader->register('schema.FlowReplies', array('class' => 'ResourceLoaderSchemaModule', 'schema' => 'FlowReplies', 'revision' => 10561344)); // Add as dependency to Flow JS $wgResourceModules['ext.flow']['dependencies'][] = 'schema.FlowReplies'; } return true; }
/** * ResourceLoaderRegisterModules hook * * Adds modules to ResourceLoader * * @param ResourceLoader $resourceLoader * @return bool */ public static function resourceLoaderRegisterModules(&$resourceLoader) { global $wgAPIModules; if (array_key_exists('titleblacklist', $wgAPIModules)) { self::$modules['ext.uploadWizard']['dependencies'][] = 'mediawiki.api.titleblacklist'; } if (class_exists('ResourceLoaderSchemaModule')) { self::$modules['ext.uploadWizard.events']['dependencies'] = array('ext.eventLogging', 'schema.UploadWizardTutorialActions', 'schema.UploadWizardUploadActions'); self::$modules['uw.EventFlowLogger']['dependencies'] += array('ext.eventLogging', 'schema.UploadWizardStep', 'schema.UploadWizardFlowEvent', 'schema.UploadWizardErrorFlowEvent', 'schema.UploadWizardExceptionFlowEvent', 'schema.UploadWizardUploadFlowEvent'); } foreach (self::$modules as $name => $resources) { $resourceLoader->register($name, $resources + array('localBasePath' => __DIR__, 'remoteExtPath' => 'UploadWizard')); } return true; }
/** * @group Slow * @slowExecutionTime 0.01651 ms * @dataProvider resourceLoaderModifyMaxAgeDataProvider * * @param $timestamp int timestamp in URL * @param $ttl int expected caching period */ public function testResourceLoaderModifyMaxAge($version, $ttl) { global $wgHooks; $resourceLoader = new ResourceLoader(); $resourceLoader->register('WikiaTestModule', array('class' => 'TestResourceLoaderModule')); $request = new WebRequest(); $request->setVal('modules', 'WikiaTestModule'); $request->setVal('version', join('-', $version)); // set up hooks $wgHooks['ResourceLoaderCacheControlHeaders'][] = 'ResourceLoaderTest::onResourceLoaderCacheControlHeaders'; ob_start(); $resourceLoader->respond(new ResourceLoaderContext($resourceLoader, $request)); ob_end_clean(); // hook ResourceLoaderHooks::onResourceLoaderModifyMaxAge was called // check modified caching period with expected one $this->assertEquals($ttl, self::$ttl, 'TTL should match expected value'); }
public function testValidation() { $module = $this->makeModule(array('foo')); $rl = new ResourceLoader(); $rl->register($module->getName(), $module); $blobStore = $this->makeBlobStore(array('fetchMessage'), $rl); $blobStore->expects($this->once())->method('fetchMessage')->will($this->returnValueMap(array(array('foo', 'en', 'Hello')))); $blob = $blobStore->getBlob($module, 'en'); $this->assertEquals('{"foo":"Hello"}', $blob, 'Generated blob'); // Now, imagine a change to the module is deployed. The module now contains // message 'foo' and 'bar'. While updateMessage() was not called (since no // message values were changed) it should detect the change in list of // message keys. $module = $this->makeModule(array('foo', 'bar')); $rl = new ResourceLoader(); $rl->register($module->getName(), $module); $blobStore = $this->makeBlobStore(array('fetchMessage'), $rl); $blobStore->expects($this->exactly(2))->method('fetchMessage')->will($this->returnValueMap(array(array('foo', 'en', 'Hello'), array('bar', 'en', 'World')))); $blob = $blobStore->getBlob($module, 'en'); $this->assertEquals('{"foo":"Hello","bar":"World"}', $blob, 'Updated blob'); }
/** * ResourceLoaderRegisterModules hook handler * * @see https://www.mediawiki.org/wiki/Manual:Hooks/ResourceLoaderRegisterModules * * @param ResourceLoader &$resourceLoader The ResourceLoader object * @return bool Always true */ public static function registerModules(ResourceLoader &$resourceLoader) { if (class_exists('WikiEditorHooks')) { $resourceLoader->register(array('ext.semanticforms.wikieditor' => array('localBasePath' => __DIR__ . '/..', 'remoteExtPath' => 'SemanticForms', 'scripts' => 'libs/SF_wikieditor.js', 'styles' => 'skins/SF_wikieditor.css', 'dependencies' => array('ext.semanticforms.main', 'jquery.wikiEditor')))); } return true; }
/** * ResourceLoaderRegisterModules hook handler * * Registers the mobile.loggingSchemas module without a dependency on the * ext.EventLogging module so that calls to the various log functions are * effectively NOPs. * * @see https://www.mediawiki.org/wiki/Manual:Hooks/ResourceLoaderRegisterModules * * @param ResourceLoader &$resourceLoader The ResourceLoader object * @return bool Always true */ public static function onResourceLoaderRegisterModules(ResourceLoader &$resourceLoader) { self::registerMobileLoggingSchemasModule(); $config = MobileContext::singleton()->getMFConfig(); // add VisualEditor related modules only, if VisualEditor seems to be installed - T85007 if (class_exists('VisualEditorHooks')) { $resourceLoader->register($config->get('MobileVEModules')); } if (class_exists('CodeMirrorHooks')) { $resourceLoader->register($config->get('MobileCodeMirrorModules')); } // add Echo, if it's installed if (class_exists('MWEchoNotifUser')) { $resourceLoader->register($config->get('MobileEchoModules')); } return true; }
/** * Register resources with the ResourceLoader. * * Handler for Hook: ResourceLoaderRegisterModules hook. */ public static function ResourceLoaderRegisterModules(\ResourceLoader $rl) { self::$_modulesRegistered = true; $rl->register(self::$modules); return true; }
public function testClear() { $module = $this->makeModule(['example']); $rl = new ResourceLoader(); $rl->register($module->getName(), $module); $blobStore = $this->makeBlobStore(['fetchMessage'], $rl); $blobStore->expects($this->exactly(2))->method('fetchMessage')->will($this->onConsecutiveCalls('First', 'Second')); $blob = $blobStore->getBlob($module, 'en'); $this->assertEquals('{"example":"First"}', $blob, 'Generated blob'); $blob = $blobStore->getBlob($module, 'en'); $this->assertEquals('{"example":"First"}', $blob, 'Cache-hit'); $blobStore->clear(); $blob = $blobStore->getBlob($module, 'en'); $this->assertEquals('{"example":"Second"}', $blob, 'Updated blob'); }
/** * @covers ResourceLoader::isModuleRegistered */ public function testIsModuleRegistered() { $rl = new ResourceLoader(); $rl->register('test.module', new ResourceLoaderTestModule()); $this->assertTrue($rl->isModuleRegistered('test.module')); $this->assertFalse($rl->isModuleRegistered('test.modulenotregistered')); }
/** * Register a ResourceLoader module providing styles for each supported language. * * @param ResourceLoader $resourceLoader * @return bool true */ public static function resourceLoaderRegisterModules(&$resourceLoader) { $modules = array(); foreach (self::getSupportedLanguages() as $lang) { $modules["ext.geshi.language.{$lang}"] = array('class' => 'ResourceLoaderGeSHiModule', 'lang' => $lang); } $resourceLoader->register($modules); return true; }
/** * Conditionally register the jquery.uls.data and jquery.i18n modules, in case they've already * been registered by the UniversalLanguageSelector extension or the TemplateData extension. * * @param ResourceLoader $resourceLoader * @return boolean true */ public static function onResourceLoaderRegisterModules(ResourceLoader &$resourceLoader) { $resourceModules = $resourceLoader->getConfig()->get('ResourceModules'); $veResourceTemplate = array('localBasePath' => __DIR__, 'remoteExtPath' => 'VisualEditor'); // Only pull in VisualEditor core's local version of jquery.uls.data if it hasn't been // installed locally already (presumably, by the UniversalLanguageSelector extension). if (!isset($resourceModules['jquery.uls.data']) && !$resourceLoader->isModuleRegistered('jquery.uls.data')) { $resourceLoader->register(array('jquery.uls.data' => $veResourceTemplate + array('scripts' => array('lib/ve/lib/jquery.uls/src/jquery.uls.data.js', 'lib/ve/lib/jquery.uls/src/jquery.uls.data.utils.js'), 'targets' => array('desktop', 'mobile')))); } // Register ext.visualEditor.mwreference here, as it depends on the new // Cite CSS style module ext.cite.style only if the Cite extension is // present. // This is a temporary hack, once the Cite extension uses the new CSS // for everything (and it takes care of loading ext.cite.style itself), // it can be removed from here and put back in extension.json. $mwreferenceModule = $veResourceTemplate + array('scripts' => array('modules/ve-mw/ui/widgets/ve.ui.MWReferenceGroupInputWidget.js', 'modules/ve-mw/ui/widgets/ve.ui.MWReferenceSearchWidget.js', 'modules/ve-mw/ui/widgets/ve.ui.MWReferenceResultWidget.js', 'modules/ve-mw/ui/commands/ve.ui.MWUseExistingReferenceCommand.js', 'modules/ve-mw/ui/dialogs/ve.ui.MWCitationDialog.js', 'modules/ve-mw/ui/dialogs/ve.ui.MWReferencesListDialog.js', 'modules/ve-mw/ui/dialogs/ve.ui.MWReferenceDialog.js', 'modules/ve-mw/ui/tools/ve.ui.MWReferenceDialogTool.js', 'modules/ve-mw/ui/tools/ve.ui.MWCitationDialogTool.js', 'modules/ve-mw/ui/contextitems/ve.ui.MWReferenceContextItem.js', 'modules/ve-mw/ui/contextitems/ve.ui.MWReferencesListContextItem.js', 'modules/ve-mw/ui/contextitems/ve.ui.MWCitationContextItem.js', 'modules/ve-mw/ui/actions/ve.ui.MWCitationAction.js'), 'styles' => array('modules/ve-mw/ui/styles/contextitems/ve.ui.MWReferenceContextItem.css', 'modules/ve-mw/ui/styles/widgets/ve.ui.MWReferenceGroupInputWidget.css', 'modules/ve-mw/ui/styles/widgets/ve.ui.MWReferenceResultWidget.css', 'modules/ve-mw/ui/styles/widgets/ve.ui.MWReferenceSearchWidget.css'), 'dependencies' => array('ext.visualEditor.mwreference.core', 'ext.visualEditor.mwtransclusion', 'ext.visualEditor.mediawiki'), 'messages' => array('visualeditor-dialog-reference-editing-reused', 'visualeditor-dialog-reference-options-group-label', 'visualeditor-dialog-reference-options-group-placeholder', 'visualeditor-dialog-reference-options-name-label', 'visualeditor-dialog-reference-options-section', 'visualeditor-dialog-reference-title', 'visualeditor-dialog-reference-useexisting-full-label', 'visualeditor-dialog-reference-useexisting-label', 'visualeditor-dialog-reference-useexisting-tool', 'visualeditor-dialog-referenceslist-contextitem-description-general', 'visualeditor-dialog-referenceslist-contextitem-description-named', 'visualeditor-dialog-referenceslist-title', 'visualeditor-dialogbutton-reference-full-label', 'visualeditor-dialogbutton-reference-tooltip', 'visualeditor-dialogbutton-reference-title', 'visualeditor-dialogbutton-referenceslist-tooltip', 'visualeditor-reference-input-placeholder'), 'targets' => array('desktop', 'mobile')); if (isset($resourceModules['ext.cite.style']) || $resourceLoader->isModuleRegistered('ext.cite.style')) { $mwreferenceModule['dependencies'][] = 'ext.cite.style'; } $resourceLoader->register(array('ext.visualEditor.mwreference' => $mwreferenceModule)); return true; }
protected static function registerAssetsManagerGroups(ResourceLoader $resourceLoader) { if (empty(self::$assetsManagerGroups)) { return true; } $assetsConfig = new AssetsConfig(); foreach (self::$assetsManagerGroups as $moduleName => $groupName) { $type = $assetsConfig->getGroupType($groupName); $key = null; switch ($type) { case AssetsManager::TYPE_JS: $key = 'scripts'; break; case AssetsManager::TYPE_CSS: case AssetsManager::TYPE_SCSS: $key = 'styles'; break; } if (empty($key)) { // todo: log error continue; } $assets = $assetsConfig->resolve($groupName, false, false); foreach ($assets as $k => $v) { if (!preg_match('#^(extensions|resources|skins)/#', $v)) { unset($assets[$k]); } } $assets = array_values($assets); $module = array(); $module[$key] = $assets; $resourceLoader->register($moduleName, $module); } return true; }
/** * Conditionally register the oojs and oojs-ui modules, in case they've already been registered * by a more recent version of MediaWiki core. * * Also conditionally register the jquery.uls.data and jquery.i18n modules, in case they've already * been registered by the UniversalLanguageSelector extension. * * @param ResourceLoader $resourceLoader * @returns boolean true */ public static function onResourceLoaderRegisterModules(ResourceLoader &$resourceLoader) { global $wgResourceModules, $wgVisualEditorResourceTemplate; $libModules = array('oojs' => $wgVisualEditorResourceTemplate + array('scripts' => array('lib/ve/lib/oojs/oojs.js'), 'targets' => array('desktop', 'mobile')), 'oojs-ui' => $wgVisualEditorResourceTemplate + array('scripts' => array('lib/ve/lib/oojs-ui/oojs-ui.js'), 'styles' => array('lib/ve/lib/oojs-ui/oojs-ui.svg.css'), 'skinStyles' => array('default' => 'lib/ve/lib/oojs-ui/oojs-ui-apex.css'), 'messages' => array('ooui-dialog-action-close', 'ooui-outline-control-move-down', 'ooui-outline-control-move-up', 'ooui-outline-control-remove', 'ooui-toolbar-more', 'ooui-dialog-confirm-title', 'ooui-dialog-confirm-default-prompt', 'ooui-dialog-confirm-default-ok', 'ooui-dialog-confirm-default-cancel'), 'dependencies' => array('oojs'), 'targets' => array('desktop', 'mobile')), 'jquery.uls.data' => $wgVisualEditorResourceTemplate + array('scripts' => array('lib/ve/lib/jquery.uls/src/jquery.uls.data.js', 'lib/ve/lib/jquery.uls/src/jquery.uls.data.utils.js'), 'targets' => array('desktop', 'mobile')), 'jquery.i18n' => $wgVisualEditorResourceTemplate + array('scripts' => array('lib/ve/lib/jquery.i18n/src/jquery.i18n.js', 'lib/ve/lib/jquery.i18n/src/jquery.i18n.messagestore.js', 'lib/ve/lib/jquery.i18n/src/jquery.i18n.parser.js', 'lib/ve/lib/jquery.i18n/src/jquery.i18n.emitter.js', 'lib/ve/lib/jquery.i18n/src/jquery.i18n.language.js'), 'languageScripts' => array('bs' => 'lib/ve/lib/jquery.i18n/src/languages/bs.js', 'dsb' => 'lib/ve/lib/jquery.i18n/src/languages/dsb.js', 'fi' => 'lib/ve/lib/jquery.i18n/src/languages/fi.js', 'ga' => 'lib/ve/lib/jquery.i18n/src/languages/ga.js', 'he' => 'lib/ve/lib/jquery.i18n/src/languages/he.js', 'hsb' => 'lib/ve/lib/jquery.i18n/src/languages/hsb.js', 'hu' => 'lib/ve/lib/jquery.i18n/src/languages/hu.js', 'hy' => 'lib/ve/lib/jquery.i18n/src/languages/hy.js', 'la' => 'lib/ve/lib/jquery.i18n/src/languages/la.js', 'ml' => 'lib/ve/lib/jquery.i18n/src/languages/ml.js', 'os' => 'lib/ve/lib/jquery.i18n/src/languages/os.js', 'ru' => 'lib/ve/lib/jquery.i18n/src/languages/ru.js', 'sl' => 'lib/ve/lib/jquery.i18n/src/languages/sl.js', 'uk' => 'lib/ve/lib/jquery.i18n/src/languages/uk.js'), 'targets' => array('desktop', 'mobile'))); $addModules = array(); foreach ($libModules as $name => $data) { if (!isset($wgResourceModules[$name]) && !$resourceLoader->getModule($name)) { $addModules[$name] = $data; } } $resourceLoader->register($addModules); return true; }
/** * Get the stylesheet of the MediaWiki skin. * * @return string */ public function getCSS() { global $wgStyleDirectory; $moduleNames = array('mediawiki.legacy.shared', 'mediawiki.skinning.interface'); $resourceLoader = new ResourceLoader(); if (file_exists("{$wgStyleDirectory}/Vector/skin.json")) { // Force loading Vector skin if available as a fallback skin // for whatever ResourceLoader wants to have as the default. $registry = new ExtensionRegistry(); $data = $registry->readFromQueue(array("{$wgStyleDirectory}/Vector/skin.json" => 1)); if (isset($data['globals']['wgResourceModules'])) { $resourceLoader->register($data['globals']['wgResourceModules']); } $moduleNames[] = 'skins.vector.styles'; } $moduleNames[] = 'mediawiki.legacy.config'; $rlContext = new ResourceLoaderContext($resourceLoader, new FauxRequest(array('debug' => 'true', 'lang' => $this->getLanguageCode(), 'only' => 'styles'))); $styles = array(); foreach ($moduleNames as $moduleName) { /** @var ResourceLoaderFileModule $module */ $module = $resourceLoader->getModule($moduleName); if (!$module) { // T98043: Don't fatal, but it won't look as pretty. continue; } // Based on: ResourceLoaderFileModule::getStyles (without the DB query) $styles = array_merge($styles, ResourceLoader::makeCombinedStyles($module->readStyleFiles($module->getStyleFiles($rlContext), $module->getFlip($rlContext)))); } return implode("\n", $styles); }
/** * @dataProvider provideValidModules * @depends testCreatingNewResourceLoaderCallsRegistrationHook * @covers ResourceLoader::register * @covers ResourceLoader::getModule */ public function testRegisteredValidModulesAreAccessible($name, ResourceLoaderModule $module, ResourceLoader $resourceLoader) { $resourceLoader->register($name, $module); $this->assertEquals($module, $resourceLoader->getModule($name)); }
/** * Conditionally register the jquery.uls.data and jquery.i18n modules, in case they've already * been registered by the UniversalLanguageSelector extension or the TemplateData extension. * * @param ResourceLoader $resourceLoader * @return boolean true */ public static function onResourceLoaderRegisterModules(ResourceLoader &$resourceLoader) { $resourceModules = $resourceLoader->getConfig()->get('ResourceModules'); $veResourceTemplate = array('localBasePath' => __DIR__, 'remoteExtPath' => 'VisualEditor'); $libModules = array('jquery.uls.data' => $veResourceTemplate + array('scripts' => array('lib/ve/lib/jquery.uls/src/jquery.uls.data.js', 'lib/ve/lib/jquery.uls/src/jquery.uls.data.utils.js'), 'targets' => array('desktop', 'mobile')), 'jquery.i18n' => $veResourceTemplate + array('scripts' => array('lib/ve/lib/jquery.i18n/src/jquery.i18n.js', 'lib/ve/lib/jquery.i18n/src/jquery.i18n.messagestore.js', 'lib/ve/lib/jquery.i18n/src/jquery.i18n.parser.js', 'lib/ve/lib/jquery.i18n/src/jquery.i18n.emitter.js', 'lib/ve/lib/jquery.i18n/src/jquery.i18n.language.js'), 'dependencies' => 'mediawiki.libs.pluralruleparser', 'languageScripts' => array('bs' => 'lib/ve/lib/jquery.i18n/src/languages/bs.js', 'dsb' => 'lib/ve/lib/jquery.i18n/src/languages/dsb.js', 'fi' => 'lib/ve/lib/jquery.i18n/src/languages/fi.js', 'ga' => 'lib/ve/lib/jquery.i18n/src/languages/ga.js', 'he' => 'lib/ve/lib/jquery.i18n/src/languages/he.js', 'hsb' => 'lib/ve/lib/jquery.i18n/src/languages/hsb.js', 'hu' => 'lib/ve/lib/jquery.i18n/src/languages/hu.js', 'hy' => 'lib/ve/lib/jquery.i18n/src/languages/hy.js', 'la' => 'lib/ve/lib/jquery.i18n/src/languages/la.js', 'ml' => 'lib/ve/lib/jquery.i18n/src/languages/ml.js', 'os' => 'lib/ve/lib/jquery.i18n/src/languages/os.js', 'ru' => 'lib/ve/lib/jquery.i18n/src/languages/ru.js', 'sl' => 'lib/ve/lib/jquery.i18n/src/languages/sl.js', 'uk' => 'lib/ve/lib/jquery.i18n/src/languages/uk.js'), 'targets' => array('desktop', 'mobile'))); $addModules = array(); foreach ($libModules as $name => $data) { if (!isset($resourceModules[$name]) && !$resourceLoader->isModuleRegistered($name)) { $addModules[$name] = $data; } } $resourceLoader->register($addModules); return true; }