public function getScript(ResourceLoaderContext $context) { // Messages $msgInfo = $this->getMessageInfo(); $parsedMessages = array(); $messages = array(); foreach ($msgInfo['args'] as $msgKey => $msgArgs) { $parsedMessages[$msgKey] = call_user_func_array('wfMessage', $msgArgs)->inLanguage($context->getLanguage())->parse(); } foreach ($msgInfo['vals'] as $msgKey => $msgVal) { $messages[$msgKey] = $msgVal; } return 've.init.platform.addParsedMessages(' . FormatJson::encode($parsedMessages, ResourceLoader::inDebugMode()) . ');' . 've.init.platform.addMessages(' . FormatJson::encode($messages, ResourceLoader::inDebugMode()) . ');'; }
public function getScript(ResourceLoaderContext $context) { // Messages $msgInfo = $this->getMessageInfo(); $parsedMessages = array(); $messages = array(); foreach ($msgInfo['args'] as $msgKey => $msgArgs) { $parsedMessages[$msgKey] = call_user_func_array('wfMessage', $msgArgs)->inLanguage($context->getLanguage())->parse(); } foreach ($msgInfo['vals'] as $msgKey => $msgVal) { $messages[$msgKey] = $msgVal; } // Version information $language = Language::factory($context->getLanguage()); $hash = $this->getGitHeadHash(); $id = $hash ? substr($this->getGitHeadHash(), 0, 7) : false; $url = $this->gitInfo->getHeadViewUrl(); $date = $this->gitInfo->getHeadCommitDate(); $dateString = $date ? $language->timeanddate($date, true) : ''; return 've.init.platform.addParsedMessages(' . FormatJson::encode($parsedMessages, ResourceLoader::inDebugMode()) . ');' . 've.init.platform.addMessages(' . FormatJson::encode($messages, ResourceLoader::inDebugMode()) . ');' . 've.version = ' . FormatJson::encode(array('id' => $id, 'url' => $url, 'timestamp' => $date, 'dateString' => $dateString), ResourceLoader::inDebugMode()) . ';'; }
/** * @param ResourceLoaderContext $context * @return string */ public function getScript(ResourceLoaderContext $context) { return Xml::encodeJsCall('mw.user.options.set', [$context->getUserObj()->getOptions(User::GETOPTIONS_EXCLUDE_DEFAULTS)], ResourceLoader::inDebugMode()); }
/** * @param ResourceLoaderContext $context * @return string JavaScript code */ public function getScript(ResourceLoaderContext $context) { return Xml::encodeJsCall('mw.language.setData', array($context->getLanguage(), $this->getData($context)), ResourceLoader::inDebugMode()); }
/** * Returns JS code which will set the MediaWiki configuration array to * the given value. * * @param array $configuration List of configuration values keyed by variable name * @return string */ public static function makeConfigSetScript(array $configuration) { return Xml::encodeJsCall('mw.config.set', [$configuration], ResourceLoader::inDebugMode()); }
/** * @param ResourceLoaderContext $context * @return string JavaScript code */ public function getScript(ResourceLoaderContext $context) { return Xml::encodeJsCall('mw.language.setSpecialCharacters', array($this->getData()), ResourceLoader::inDebugMode()); }
/** * Returns JS code which will set the MediaWiki configuration array to * the given value. * * @param array $configuration List of configuration values keyed by variable name * @return string */ public static function makeConfigSetScript(array $configuration) { return Xml::encodeJsCall('mw.config.set', array($configuration), ResourceLoader::inDebugMode()) . ResourceLoader::FILTER_NOMIN; }
/** * @param ResourceLoaderContext $context * @return string */ public function getScript(ResourceLoaderContext $context) { global $IP; if ($context->getOnly() !== 'scripts') { return '/* Requires only=script */'; } $out = file_get_contents("{$IP}/resources/src/startup.js"); $pairs = array_map(function ($value) { $value = FormatJson::encode($value, ResourceLoader::inDebugMode(), FormatJson::ALL_OK); // Fix indentation $value = str_replace("\n", "\n\t", $value); return $value; }, ['$VARS.wgLegacyJavaScriptGlobals' => $this->getConfig()->get('LegacyJavaScriptGlobals'), '$VARS.configuration' => $this->getConfigSettings($context), '$VARS.baseModulesUri' => self::getStartupModulesUrl($context)]); $pairs['$CODE.registrations()'] = str_replace("\n", "\n\t", trim($this->getModuleRegistrations($context))); return strtr($out, $pairs); }
/** * @param ResourceLoaderContext $context * @return string */ public function getScript(ResourceLoaderContext $context) { global $wgUser; return Xml::encodeJsCall('mw.user.options.set', array($wgUser->getOptions()), ResourceLoader::inDebugMode()); }
private function getRlClientContext() { if (!$this->rlClientContext) { $query = ResourceLoader::makeLoaderQuery([], $this->getLanguage()->getCode(), $this->getSkin()->getSkinName(), $this->getUser()->isLoggedIn() ? $this->getUser()->getName() : null, null, ResourceLoader::inDebugMode(), null, $this->isPrintable(), $this->getRequest()->getBool('handheld')); $this->rlClientContext = new ResourceLoaderContext($this->getResourceLoader(), new FauxRequest($query)); } return $this->rlClientContext; }
/** * Returns JS code which will set the MediaWiki configuration array to * the given value. * * @param array $configuration List of configuration values keyed by variable name * @param bool $pretty Pretty-print with extra whitespace * @return string */ public static function makeConfigSetScript(array $configuration, $pretty = null) { return Xml::encodeJsCall('mw.config.set', [$configuration], $pretty === null ? ResourceLoader::inDebugMode() : $pretty); }
/** * TODO: Document * @param $modules Array/string with the module name(s) * @param $only String ResourceLoaderModule TYPE_ class constant * @param $useESI boolean * @param $extraQuery Array with extra query parameters to add to each request. array( param => value ) * @param $loadCall boolean If true, output an (asynchronous) mw.loader.load() call rather than a <script src="..."> tag * @return string html <script> and <style> tags */ protected function makeResourceLoaderLink($modules, $only, $useESI = false, array $extraQuery = array(), $loadCall = false) { global $wgResourceLoaderUseESI; if (!count($modules)) { return ''; } if (count($modules) > 1) { // Remove duplicate module requests $modules = array_unique((array) $modules); // Sort module names so requests are more uniform sort($modules); if (ResourceLoader::inDebugMode()) { // Recursively call us for every item $links = ''; foreach ($modules as $name) { $links .= $this->makeResourceLoaderLink($name, $only, $useESI); } return $links; } } // Create keyed-by-group list of module objects from modules list $groups = array(); $resourceLoader = $this->getResourceLoader(); foreach ((array) $modules as $name) { $module = $resourceLoader->getModule($name); # Check that we're allowed to include this module on this page if (!$module || $module->getOrigin() > $this->getAllowedModules(ResourceLoaderModule::TYPE_SCRIPTS) && $only == ResourceLoaderModule::TYPE_SCRIPTS || $module->getOrigin() > $this->getAllowedModules(ResourceLoaderModule::TYPE_STYLES) && $only == ResourceLoaderModule::TYPE_STYLES) { continue; } $group = $module->getGroup(); if (!isset($groups[$group])) { $groups[$group] = array(); } $groups[$group][$name] = $module; } $links = ''; foreach ($groups as $group => $modules) { // Special handling for user-specific groups $user = null; if (($group === 'user' || $group === 'private') && $this->getUser()->isLoggedIn()) { $user = $this->getUser()->getName(); } // Create a fake request based on the one we are about to make so modules return // correct timestamp and emptiness data $query = ResourceLoader::makeLoaderQuery(array(), $this->getLanguage()->getCode(), $this->getSkin()->getSkinName(), $user, null, ResourceLoader::inDebugMode(), $only === ResourceLoaderModule::TYPE_COMBINED ? null : $only, $this->isPrintable(), $this->getRequest()->getBool('handheld'), $extraQuery); $context = new ResourceLoaderContext($resourceLoader, new FauxRequest($query)); // Drop modules that know they're empty foreach ($modules as $key => $module) { if ($module->isKnownEmpty($context)) { unset($modules[$key]); } } // If there are no modules left, skip this group if ($modules === array()) { continue; } // Inline private modules. These can't be loaded through load.php for security // reasons, see bug 34907. Note that these modules should be loaded from // getHeadScripts() before the first loader call. Otherwise other modules can't // properly use them as dependencies (bug 30914) if ($group === 'private') { if ($only == ResourceLoaderModule::TYPE_STYLES) { $links .= Html::inlineStyle($resourceLoader->makeModuleResponse($context, $modules)); } else { $links .= Html::inlineScript(ResourceLoader::makeLoaderConditionalScript($resourceLoader->makeModuleResponse($context, $modules))); } $links .= "\n"; continue; } // Special handling for the user group; because users might change their stuff // on-wiki like user pages, or user preferences; we need to find the highest // timestamp of these user-changable modules so we can ensure cache misses on change // This should NOT be done for the site group (bug 27564) because anons get that too // and we shouldn't be putting timestamps in Squid-cached HTML $version = null; if ($group === 'user') { // Get the maximum timestamp $timestamp = 1; foreach ($modules as $module) { $timestamp = max($timestamp, $module->getModifiedTime($context)); } // Add a version parameter so cache will break when things change $version = wfTimestamp(TS_ISO_8601_BASIC, $timestamp); } $url = ResourceLoader::makeLoaderURL(array_keys($modules), $this->getLanguage()->getCode(), $this->getSkin()->getSkinName(), $user, $version, ResourceLoader::inDebugMode(), $only === ResourceLoaderModule::TYPE_COMBINED ? null : $only, $this->isPrintable(), $this->getRequest()->getBool('handheld'), $extraQuery); if ($useESI && $wgResourceLoaderUseESI) { $esi = Xml::element('esi:include', array('src' => $url)); if ($only == ResourceLoaderModule::TYPE_STYLES) { $link = Html::inlineStyle($esi); } else { $link = Html::inlineScript($esi); } } else { // Automatically select style/script elements if ($only === ResourceLoaderModule::TYPE_STYLES) { $link = Html::linkedStyle($url); } else { if ($loadCall) { $link = Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(Xml::encodeJsCall('mw.loader.load', array($url, 'text/javascript', true)))); } else { $link = Html::linkedScript($url); } } } if ($group == 'noscript') { $links .= Html::rawElement('noscript', array(), $link) . "\n"; } else { $links .= $link . "\n"; } } return $links; }
/** * @param ResourceLoaderContext $context * @return string */ public function getScript(ResourceLoaderContext $context) { global $IP; $out = file_get_contents("{$IP}/resources/src/startup.js"); if ($context->getOnly() === 'scripts') { // Startup function $configuration = $this->getConfigSettings($context); $registrations = $this->getModuleRegistrations($context); // Fix indentation $registrations = str_replace("\n", "\n\t", trim($registrations)); $mwMapJsCall = Xml::encodeJsCall('mw.Map', array($this->getConfig()->get('LegacyJavaScriptGlobals'))); $mwConfigSetJsCall = Xml::encodeJsCall('mw.config.set', array($configuration), ResourceLoader::inDebugMode()); $out .= "var startUp = function () {\n" . "\tmw.config = new " . $mwMapJsCall . "\n" . "\t{$registrations}\n" . "\t" . $mwConfigSetJsCall . "};\n"; // Conditional script injection $scriptTag = Html::linkedScript(self::getStartupModulesUrl($context)); $out .= "if ( isCompatible() ) {\n" . "\t" . Xml::encodeJsCall('document.write', array($scriptTag)) . "\n}"; } return $out; }
/** * Get registration code for all modules. * * @param ResourceLoaderContext $context * @return string JavaScript code for registering all modules with the client loader */ public function getModuleRegistrations(ResourceLoaderContext $context) { wfProfileIn(__METHOD__); $resourceLoader = $context->getResourceLoader(); $target = $context->getRequest()->getVal('target', 'desktop'); $out = ''; $registryData = array(); // Get registry data foreach ($resourceLoader->getModuleNames() as $name) { $module = $resourceLoader->getModule($name); $moduleTargets = $module->getTargets(); if (!in_array($target, $moduleTargets)) { continue; } if ($module->isRaw()) { // Don't register "raw" modules (like 'jquery' and 'mediawiki') client-side because // depending on them is illegal anyway and would only lead to them being reloaded // causing any state to be lost (like jQuery plugins, mw.config etc.) continue; } // getModifiedTime() is supposed to return a UNIX timestamp, but it doesn't always // seem to do that, and custom implementations might forget. Coerce it to TS_UNIX $moduleMtime = wfTimestamp(TS_UNIX, $module->getModifiedTime($context)); $mtime = max($moduleMtime, wfTimestamp(TS_UNIX, $this->getConfig()->get('CacheEpoch'))); // FIXME: Convert to numbers, wfTimestamp always gives us stings, even for TS_UNIX $skipFunction = $module->getSkipFunction(); if ($skipFunction !== null && !ResourceLoader::inDebugMode()) { $skipFunction = $resourceLoader->filter('minify-js', $skipFunction, false); } $registryData[$name] = array('version' => $mtime, 'dependencies' => $module->getDependencies(), 'group' => $module->getGroup(), 'source' => $module->getSource(), 'loader' => $module->getLoaderScript(), 'skip' => $skipFunction); } self::compileUnresolvedDependencies($registryData); // Register sources $out .= ResourceLoader::makeLoaderSourcesScript($resourceLoader->getSources()); // Concatenate module loader scripts and figure out the different call // signatures for mw.loader.register $registrations = array(); foreach ($registryData as $name => $data) { if ($data['loader'] !== false) { $out .= ResourceLoader::makeCustomLoaderScript($name, wfTimestamp(TS_ISO_8601_BASIC, $data['version']), $data['dependencies'], $data['group'], $data['source'], $data['loader']); continue; } if (!count($data['dependencies']) && $data['group'] === null && $data['source'] === 'local' && $data['skip'] === null) { // Modules with no dependencies, group, foreign source or skip function; // call mw.loader.register(name, timestamp) $registrations[] = array($name, $data['version']); } elseif ($data['group'] === null && $data['source'] === 'local' && $data['skip'] === null) { // Modules with dependencies but no group, foreign source or skip function; // call mw.loader.register(name, timestamp, dependencies) $registrations[] = array($name, $data['version'], $data['dependencies']); } elseif ($data['source'] === 'local' && $data['skip'] === null) { // Modules with a group but no foreign source or skip function; // call mw.loader.register(name, timestamp, dependencies, group) $registrations[] = array($name, $data['version'], $data['dependencies'], $data['group']); } elseif ($data['skip'] === null) { // Modules with a foreign source but no skip function; // call mw.loader.register(name, timestamp, dependencies, group, source) $registrations[] = array($name, $data['version'], $data['dependencies'], $data['group'], $data['source']); } else { // Modules with a skip function; // call mw.loader.register(name, timestamp, dependencies, group, source, skip) $registrations[] = array($name, $data['version'], $data['dependencies'], $data['group'], $data['source'], $data['skip']); } } // Register modules $out .= ResourceLoader::makeLoaderRegisterScript($registrations); wfProfileOut(__METHOD__); return $out; }
/** * Generate the JavaScript content of this module. * * Add FILTER_NOMIN annotation to prevent needless minification and caching (T84960). * * @param ResourceLoaderContext $context * @return string */ public function getScript(ResourceLoaderContext $context) { return Xml::encodeJsCall('mw.user.tokens.set', [$this->contextUserTokens($context)], ResourceLoader::inDebugMode()) . ResourceLoader::FILTER_NOMIN; }
private function plainQUnit() { $out = $this->getOutput(); $out->disable(); $styles = $out->makeResourceLoaderLink('jquery.qunit', ResourceLoaderModule::TYPE_STYLES); // Use 'raw' because QUnit loads before ResourceLoader initialises (omit mw.loader.state call) // Use 'test' to ensure OutputPage doesn't use the "async" attribute because QUnit must // load before qunit/export. $scripts = $out->makeResourceLoaderLink('jquery.qunit', ResourceLoaderModule::TYPE_SCRIPTS, array('raw' => true, 'sync' => true)); $head = implode("\n", array_merge($styles['html'], $scripts['html'])); $summary = $this->getSummaryHtml(); $html = <<<HTML <!DOCTYPE html> <title>QUnit</title> {$head} {$summary} <div id="qunit"></div> HTML; $url = $this->getPageTitle('qunit/export')->getFullURL(array('debug' => ResourceLoader::inDebugMode() ? 'true' : 'false')); $html .= "\n" . Html::linkedScript($url); header('Content-Type: text/html; charset=utf-8'); echo $html; }
/** * TODO: Document * @param $skin Skin * @param $modules Array/string with the module name * @param $only String ResourceLoaderModule TYPE_ class constant * @param $useESI boolean * @return string html <script> and <style> tags */ protected function makeResourceLoaderLink(Skin $skin, $modules, $only, $useESI = false) { global $wgLoadScript, $wgResourceLoaderUseESI; // Lazy-load ResourceLoader // TODO: Should this be a static function of ResourceLoader instead? $baseQuery = array('lang' => $this->getContext()->getLang()->getCode(), 'debug' => ResourceLoader::inDebugMode() ? 'true' : 'false', 'skin' => $skin->getSkinName(), 'only' => $only); // Propagate printable and handheld parameters if present if ($this->isPrintable()) { $baseQuery['printable'] = 1; } if ($this->getRequest()->getBool('handheld')) { $baseQuery['handheld'] = 1; } if (!count($modules)) { return ''; } if (count($modules) > 1) { // Remove duplicate module requests $modules = array_unique((array) $modules); // Sort module names so requests are more uniform sort($modules); if (ResourceLoader::inDebugMode()) { // Recursively call us for every item $links = ''; foreach ($modules as $name) { $links .= $this->makeResourceLoaderLink($skin, $name, $only, $useESI); } return $links; } } // Create keyed-by-group list of module objects from modules list $groups = array(); $resourceLoader = $this->getResourceLoader(); foreach ((array) $modules as $name) { $module = $resourceLoader->getModule($name); # Check that we're allowed to include this module on this page if (!$module || $module->getOrigin() > $this->getAllowedModules(ResourceLoaderModule::TYPE_SCRIPTS) && $only == ResourceLoaderModule::TYPE_SCRIPTS || $module->getOrigin() > $this->getAllowedModules(ResourceLoaderModule::TYPE_STYLES) && $only == ResourceLoaderModule::TYPE_STYLES) { continue; } $group = $module->getGroup(); if (!isset($groups[$group])) { $groups[$group] = array(); } $groups[$group][$name] = $module; } $links = ''; foreach ($groups as $group => $modules) { $query = $baseQuery; // Special handling for user-specific groups if (($group === 'user' || $group === 'private') && $this->getUser()->isLoggedIn()) { $query['user'] = $this->getUser()->getName(); } // Create a fake request based on the one we are about to make so modules return // correct timestamp and emptiness data $context = new ResourceLoaderContext($resourceLoader, new FauxRequest($query)); // Drop modules that know they're empty foreach ($modules as $key => $module) { if ($module->isKnownEmpty($context)) { unset($modules[$key]); } } // If there are no modules left, skip this group if ($modules === array()) { continue; } $query['modules'] = ResourceLoader::makePackedModulesString(array_keys($modules)); // Inline private modules. These can't be loaded through load.php for security // reasons, see bug 34907. Note that these modules should be loaded from // getHeadScripts() before the first loader call. Otherwise other modules can't // properly use them as dependencies (bug 30914) if ($group === 'private') { if ($only == ResourceLoaderModule::TYPE_STYLES) { $links .= Html::inlineStyle($resourceLoader->makeModuleResponse($context, $modules)); } else { $links .= Html::inlineScript(ResourceLoader::makeLoaderConditionalScript($resourceLoader->makeModuleResponse($context, $modules))); } continue; } // Special handling for the user group; because users might change their stuff // on-wiki like user pages, or user preferences; we need to find the highest // timestamp of these user-changable modules so we can ensure cache misses on change // This should NOT be done for the site group (bug 27564) because anons get that too // and we shouldn't be putting timestamps in Squid-cached HTML if ($group === 'user') { // Get the maximum timestamp $timestamp = 1; foreach ($modules as $module) { $timestamp = max($timestamp, $module->getModifiedTime($context)); } // Add a version parameter so cache will break when things change $query['version'] = wfTimestamp(TS_ISO_8601_BASIC, $timestamp); } // Make queries uniform in order ksort($query); $url = wfAppendQuery($wgLoadScript, $query); // Prevent the IE6 extension check from being triggered (bug 28840) // by appending a character that's invalid in Windows extensions ('*') $url .= '&*'; if ($useESI && $wgResourceLoaderUseESI) { $esi = Xml::element('esi:include', array('src' => $url)); if ($only == ResourceLoaderModule::TYPE_STYLES) { $link = Html::inlineStyle($esi); } else { $link = Html::inlineScript($esi); } } else { // Automatically select style/script elements if ($only === ResourceLoaderModule::TYPE_STYLES) { $link = Html::linkedStyle($url); } else { $link = Html::linkedScript($url); } } if ($group == 'noscript') { $links .= Html::rawElement('noscript', array(), $link) . "\n"; } else { $links .= $link . "\n"; } } return $links; }
function headScriptsStartupScript($outputPage, $scripts) { $resourceLoader = $outputPage->getResourceLoader(); $module = $resourceLoader->getModule('startup'); $query = ResourceLoader::makeLoaderQuery(array(), $outputPage->getLanguage()->getCode(), $outputPage->getSkin()->getSkinName(), null, null, ResourceLoader::inDebugMode(), "scripts", $outputPage->isPrintable(), $outputPage->getRequest()->getBool('handheld'), array()); $context = new ResourceLoaderContext($resourceLoader, new FauxRequest($query)); $scripts = Html::inlineScript($resourceLoader->makeModuleResponse($context, array($module))); return true; }
/** * Build a load.php URL using OutputPage instance to get most of the required information * * @param OutputPage $out * @param string|array $modules Module names * @param string $only * @param bool|string $user User name (true to get it from OutputPage) * @param string $version * @param array $extraQuery * @return string */ public static function makeCustomURL(OutputPage $out, $modules, $only = ResourceLoaderModule::TYPE_COMBINED, $user = null, $version = null, $extraQuery = array()) { if ($user === true) { $user = $out->getUser()->getName(); } else { if ($user === false || $user === null) { $user = null; } else { $user = (string) $user; } } $url = ResourceLoader::makeLoaderURL($modules, $out->getLanguage()->getCode(), $out->getSkin()->getSkinName(), $user, $version, ResourceLoader::inDebugMode(), $only === ResourceLoaderModule::TYPE_COMBINED ? null : $only, $out->isPrintable(), $out->getRequest()->getBool('handheld'), $extraQuery); return $url; }
/** * Shows a bulletin board style toolbar for common editing functions. * It can be disabled in the user preferences. * * @param $title Title object for the page being edited (optional) * @return string */ static function getEditToolbar($title = null) { global $wgContLang, $wgOut; global $wgEnableUploads, $wgForeignFileRepos; $imagesAvailable = $wgEnableUploads || count($wgForeignFileRepos); $showSignature = true; if ($title) { $showSignature = MWNamespace::wantSignatures($title->getNamespace()); } /** * $toolarray is an array of arrays each of which includes the * opening tag, the closing tag, optionally a sample text that is * inserted between the two when no selection is highlighted * and. The tip text is shown when the user moves the mouse * over the button. * * Images are defined in ResourceLoaderEditToolbarModule. */ $toolarray = array(array('id' => 'mw-editbutton-bold', 'open' => '\'\'\'', 'close' => '\'\'\'', 'sample' => wfMessage('bold_sample')->text(), 'tip' => wfMessage('bold_tip')->text()), array('id' => 'mw-editbutton-italic', 'open' => '\'\'', 'close' => '\'\'', 'sample' => wfMessage('italic_sample')->text(), 'tip' => wfMessage('italic_tip')->text()), array('id' => 'mw-editbutton-link', 'open' => '[[', 'close' => ']]', 'sample' => wfMessage('link_sample')->text(), 'tip' => wfMessage('link_tip')->text()), array('id' => 'mw-editbutton-extlink', 'open' => '[', 'close' => ']', 'sample' => wfMessage('extlink_sample')->text(), 'tip' => wfMessage('extlink_tip')->text()), array('id' => 'mw-editbutton-headline', 'open' => "\n== ", 'close' => " ==\n", 'sample' => wfMessage('headline_sample')->text(), 'tip' => wfMessage('headline_tip')->text()), $imagesAvailable ? array('id' => 'mw-editbutton-image', 'open' => '[[' . $wgContLang->getNsText(NS_FILE) . ':', 'close' => ']]', 'sample' => wfMessage('image_sample')->text(), 'tip' => wfMessage('image_tip')->text()) : false, $imagesAvailable ? array('id' => 'mw-editbutton-media', 'open' => '[[' . $wgContLang->getNsText(NS_MEDIA) . ':', 'close' => ']]', 'sample' => wfMessage('media_sample')->text(), 'tip' => wfMessage('media_tip')->text()) : false, array('id' => 'mw-editbutton-nowiki', 'open' => "<nowiki>", 'close' => "</nowiki>", 'sample' => wfMessage('nowiki_sample')->text(), 'tip' => wfMessage('nowiki_tip')->text()), $showSignature ? array('id' => 'mw-editbutton-signature', 'open' => '--~~~~', 'close' => '', 'sample' => '', 'tip' => wfMessage('sig_tip')->text()) : false, array('id' => 'mw-editbutton-hr', 'open' => "\n----\n", 'close' => '', 'sample' => '', 'tip' => wfMessage('hr_tip')->text())); $script = 'mw.loader.using("mediawiki.toolbar", function () {'; foreach ($toolarray as $tool) { if (!$tool) { continue; } $params = array(false, $tool['tip'], $tool['open'], $tool['close'], $tool['sample'], $tool['id']); $script .= Xml::encodeJsCall('mw.toolbar.addButton', $params, ResourceLoader::inDebugMode()); } $script .= '});'; $wgOut->addScript(ResourceLoader::makeInlineScript($script)); $toolbar = '<div id="toolbar"></div>'; Hooks::run('EditPageBeforeEditToolbar', array(&$toolbar)); return $toolbar; }
/** * Returns JS code which will set the MediaWiki configuration array to * the given value. * * @param array $configuration List of configuration values keyed by variable name * @return string */ public static function makeConfigSetScript(array $configuration) { if (ResourceLoader::inDebugMode()) { return Xml::encodeJsCall('mw.config.set', array($configuration), true); } $config = RequestContext::getMain()->getConfig(); $js = Xml::encodeJsCall('mw.config.set', array($configuration), false); return self::applyFilter('minify-js', $js, $config); }
private function plainQUnit() { $out = $this->getOutput(); $out->disable(); $url = $this->getPageTitle('qunit/export')->getFullURL(array('debug' => ResourceLoader::inDebugMode() ? 'true' : 'false')); $styles = $out->makeResourceLoaderLink('jquery.qunit', ResourceLoaderModule::TYPE_STYLES, false); // Use 'raw' since this is a plain HTML page without ResourceLoader $scripts = $out->makeResourceLoaderLink('jquery.qunit', ResourceLoaderModule::TYPE_SCRIPTS, false, array('raw' => 'true')); $head = trim($styles['html'] . $scripts['html']); $html = <<<HTML <!DOCTYPE html> <title>QUnit</title> {$head} <div id="qunit"></div> HTML; $html .= "\n" . Html::linkedScript($url); header('Content-Type: text/html; charset=utf-8'); echo $html; }
/** * @todo Document * @param array|string $modules One or more module names * @param string $only ResourceLoaderModule TYPE_ class constant * @param bool $useESI * @param array $extraQuery Array with extra query parameters to add to each * request. array( param => value ). * @param bool $loadCall If true, output an (asynchronous) mw.loader.load() * call rather than a "<script src='...'>" tag. * @return string The html "<script>", "<link>" and "<style>" tags */ public function makeResourceLoaderLink($modules, $only, $useESI = false, array $extraQuery = array(), $loadCall = false) { $modules = (array) $modules; $links = array('html' => '', 'states' => array()); if (!count($modules)) { return $links; } if (count($modules) > 1) { // Remove duplicate module requests $modules = array_unique($modules); // Sort module names so requests are more uniform sort($modules); if (ResourceLoader::inDebugMode()) { // Recursively call us for every item foreach ($modules as $name) { $link = $this->makeResourceLoaderLink($name, $only, $useESI); $links['html'] .= $link['html']; $links['states'] += $link['states']; } return $links; } } if (!is_null($this->mTarget)) { $extraQuery['target'] = $this->mTarget; } // Create keyed-by-source and then keyed-by-group list of module objects from modules list $sortedModules = array(); $resourceLoader = $this->getResourceLoader(); $resourceLoaderUseESI = $this->getConfig()->get('ResourceLoaderUseESI'); foreach ($modules as $name) { $module = $resourceLoader->getModule($name); # Check that we're allowed to include this module on this page if (!$module || $module->getOrigin() > $this->getAllowedModules(ResourceLoaderModule::TYPE_SCRIPTS) && $only == ResourceLoaderModule::TYPE_SCRIPTS || $module->getOrigin() > $this->getAllowedModules(ResourceLoaderModule::TYPE_STYLES) && $only == ResourceLoaderModule::TYPE_STYLES || $module->getOrigin() > $this->getAllowedModules(ResourceLoaderModule::TYPE_COMBINED) && $only == ResourceLoaderModule::TYPE_COMBINED || $this->mTarget && !in_array($this->mTarget, $module->getTargets())) { continue; } $sortedModules[$module->getSource()][$module->getGroup()][$name] = $module; } foreach ($sortedModules as $source => $groups) { foreach ($groups as $group => $grpModules) { // Special handling for user-specific groups $user = null; if (($group === 'user' || $group === 'private') && $this->getUser()->isLoggedIn()) { $user = $this->getUser()->getName(); } // Create a fake request based on the one we are about to make so modules return // correct timestamp and emptiness data $query = ResourceLoader::makeLoaderQuery(array(), $this->getLanguage()->getCode(), $this->getSkin()->getSkinName(), $user, null, ResourceLoader::inDebugMode(), $only === ResourceLoaderModule::TYPE_COMBINED ? null : $only, $this->isPrintable(), $this->getRequest()->getBool('handheld'), $extraQuery); $context = new ResourceLoaderContext($resourceLoader, new FauxRequest($query)); // Extract modules that know they're empty and see if we have one or more // raw modules $isRaw = false; foreach ($grpModules as $key => $module) { // Inline empty modules: since they're empty, just mark them as 'ready' (bug 46857) // If we're only getting the styles, we don't need to do anything for empty modules. if ($module->isKnownEmpty($context)) { unset($grpModules[$key]); if ($only !== ResourceLoaderModule::TYPE_STYLES) { $links['states'][$key] = 'ready'; } } $isRaw |= $module->isRaw(); } // If there are no non-empty modules, skip this group if (count($grpModules) === 0) { continue; } // Inline private modules. These can't be loaded through load.php for security // reasons, see bug 34907. Note that these modules should be loaded from // getHeadScripts() before the first loader call. Otherwise other modules can't // properly use them as dependencies (bug 30914) if ($group === 'private') { if ($only == ResourceLoaderModule::TYPE_STYLES) { $links['html'] .= Html::inlineStyle($resourceLoader->makeModuleResponse($context, $grpModules)); } else { $links['html'] .= ResourceLoader::makeInlineScript($resourceLoader->makeModuleResponse($context, $grpModules)); } $links['html'] .= "\n"; continue; } // Special handling for the user group; because users might change their stuff // on-wiki like user pages, or user preferences; we need to find the highest // timestamp of these user-changeable modules so we can ensure cache misses on change // This should NOT be done for the site group (bug 27564) because anons get that too // and we shouldn't be putting timestamps in Squid-cached HTML $version = null; if ($group === 'user') { $query['version'] = $resourceLoader->getCombinedVersion($context, array_keys($grpModules)); } $query['modules'] = ResourceLoader::makePackedModulesString(array_keys($grpModules)); $moduleContext = new ResourceLoaderContext($resourceLoader, new FauxRequest($query)); $url = $resourceLoader->createLoaderURL($source, $moduleContext, $extraQuery); if ($useESI && $resourceLoaderUseESI) { $esi = Xml::element('esi:include', array('src' => $url)); if ($only == ResourceLoaderModule::TYPE_STYLES) { $link = Html::inlineStyle($esi); } else { $link = Html::inlineScript($esi); } } else { // Automatically select style/script elements if ($only === ResourceLoaderModule::TYPE_STYLES) { $link = Html::linkedStyle($url); } elseif ($loadCall) { $link = ResourceLoader::makeInlineScript(Xml::encodeJsCall('mw.loader.load', array($url, 'text/javascript', true))); } else { $link = Html::linkedScript($url); if (!$context->getRaw() && !$isRaw) { // Wrap only=script / only=combined requests in a conditional as // browsers not supported by the startup module would unconditionally // execute this module. Otherwise users will get "ReferenceError: mw is // undefined" or "jQuery is undefined" from e.g. a "site" module. $link = ResourceLoader::makeInlineScript(Xml::encodeJsCall('document.write', array($link))); } // For modules requested directly in the html via <link> or <script>, // tell mw.loader they are being loading to prevent duplicate requests. foreach ($grpModules as $key => $module) { // Don't output state=loading for the startup module.. if ($key !== 'startup') { $links['states'][$key] = 'loading'; } } } } if ($group == 'noscript') { $links['html'] .= Html::rawElement('noscript', array(), $link) . "\n"; } else { $links['html'] .= $link . "\n"; } } } return $links; }
/** * @param ResourceLoaderContext $context * @return string */ public function getScript(ResourceLoaderContext $context) { return Xml::encodeJsCall('mw.user.options.set', array(User::getDefaultOptions()), ResourceLoader::inDebugMode()); }
/** * @param $context ResourceLoaderContext * @return string */ public function getScript(ResourceLoaderContext $context) { return Xml::encodeJsCall('mw.user.tokens.set', array($this->contextUserTokens()), ResourceLoader::inDebugMode()); }
/** * @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()); }