/** * Generate self-sufficient JavaScript payload to run the tests elsewhere. * * Includes startup module to request modules from ResourceLoader. * * Note: This modifies the registry to replace 'jquery.qunit' with an * empty module to allow external environment to preload QUnit with any * neccecary framework adapters (e.g. Karma). Loading it again would * re-define QUnit and dereference event handlers from Karma. */ private function exportQUnit() { $out = $this->getOutput(); $out->disable(); $rl = $out->getResourceLoader(); $query = array('lang' => $this->getLanguage()->getCode(), 'skin' => $this->getSkin()->getSkinName(), 'debug' => ResourceLoader::inDebugMode() ? 'true' : 'false', 'target' => 'test'); $embedContext = new ResourceLoaderContext($rl, new FauxRequest($query)); $query['only'] = 'scripts'; $startupContext = new ResourceLoaderContext($rl, new FauxRequest($query)); $query['raw'] = true; $modules = $rl->getTestModuleNames('qunit'); // Disable autostart because we load modules asynchronously. By default, QUnit would start // at domready when there are no tests loaded and also fire 'QUnit.done' which then instructs // Karma to end the run before the tests even started. $qunitConfig = 'QUnit.config.autostart = false;' . 'if (window.__karma__) {' . 'window.__karma__.loaded = function () {};' . '}'; // The below is essentially a pure-javascript version of OutputPage::getHeadScripts. $startup = $rl->makeModuleResponse($startupContext, array('startup' => $rl->getModule('startup'))); // Embed page-specific mw.config variables. // The current Special page shouldn't be relevant to tests, but various modules (which // are loaded before the test suites), reference mw.config while initialising. $code = ResourceLoader::makeConfigSetScript($out->getJSVars()); // Embed private modules as they're not allowed to be loaded dynamically $code .= $rl->makeModuleResponse($embedContext, array('user.options' => $rl->getModule('user.options'), 'user.tokens' => $rl->getModule('user.tokens'))); // Catch exceptions (such as "dependency missing" or "unknown module") so that we // always start QUnit. Re-throw so that they are caught and reported as global exceptions // by QUnit and Karma. $code .= '(function () {' . 'var start = window.__karma__ ? window.__karma__.start : QUnit.start;' . 'try {' . 'mw.loader.using( ' . Xml::encodeJsVar($modules) . ' ).always( start );' . '} catch ( e ) { start(); throw e; }' . '}());'; header('Content-Type: text/javascript; charset=utf-8'); header('Cache-Control: private, no-cache, must-revalidate'); header('Pragma: no-cache'); echo $qunitConfig; echo $startup; // The following has to be deferred via RLQ because the startup module is asynchronous. echo ResourceLoader::makeLoaderConditionalScript($code); }
function wfEditPageBeforeEditToolbar(&$toolbar) { global $wgStylePath, $wgOut, $wgLanguageCode; $params = array($image = $wgStylePath . '/owl/images/1x1_transparent.gif', $tip = 'Weave links', $open = '', $close = '', $sample = '', $cssId = 'weave_button'); $script = Xml::encodeJsCall('mw.toolbar.addButton', $params); $wgOut->addScript(Html::inlineScript(ResourceLoader::makeLoaderConditionalScript($script))); $params = array($image = $wgStylePath . '/owl/images/1x1_transparent.gif', $tip = 'Add Image', $open = '', $close = '', $sample = '', $cssId = 'easyimageupload_button', $onclick = "easyImageUpload.doEIUModal('advanced');return false;"); $script = Xml::encodeJsCall('mw.toolbar.addButton', $params); $wgOut->addScript(Html::inlineScript(ResourceLoader::makeLoaderConditionalScript($script))); $wgOut->addJScode('advj'); $wgOut->addJScode('eiuj'); if (in_array($wgLanguageCode, array('en', 'de', 'es', 'pt'))) { $popbox = PopBox::getPopBoxJSAdvanced() . PopBox::getPopBoxCSS(); $popbox_div = PopBox::getPopBoxDiv(); $wgOut->addHTML($popbox_div . $popbox); $wgOut->addHTML(Easyimageupload::getUploadBoxJS(true)); } return true; }
/** * Run the test suite on the Special page. * * Rendered by OutputPage and Skin. */ private function viewQUnit() { $out = $this->getOutput(); $testConfig = $this->getConfig()->get('JavaScriptTestConfig'); $modules = $out->getResourceLoader()->getTestModuleNames('qunit'); $summary = $this->msg('javascripttest-qunit-intro')->params($testConfig['qunit']['documentation'])->parseAsBlock(); $baseHtml = <<<HTML <div class="mw-content-ltr"> <div id="qunit"></div> </div> HTML; // Used in ./tests/qunit/data/testrunner.js, see also documentation of // $wgJavaScriptTestConfig in DefaultSettings.php $out->addJsConfigVars('QUnitTestSwarmInjectJSPath', $testConfig['qunit']['testswarm-injectjs']); $out->addHtml($this->wrapSummaryHtml($summary) . $baseHtml); // The testrunner configures QUnit and essentially depends on it. However, test suites // are reusable in environments that preload QUnit (or a compatibility interface to // another framework). Therefore we have to load it ourselves. $out->addHtml(Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(Xml::encodeJsCall('mw.loader.using', array(array('jquery.qunit', 'jquery.qunit.completenessTest'), new XmlJsCode('function () {' . Xml::encodeJsCall('mw.loader.load', array($modules)) . '}')))))); }
/** * Gets the global variables and mScripts; also adds userjs to the end if * enabled. Despite the name, these scripts are no longer put in the * <head> but at the bottom of the <body> * * @param $sk Skin object to use * @return String: HTML fragment */ function getHeadScripts(Skin $sk) { global $wgUser, $wgRequest, $wgUseSiteJs; // Startup - this will immediately load jquery and mediawiki modules $scripts = $this->makeResourceLoaderLink($sk, 'startup', 'scripts', true); // Configuration -- This could be merged together with the load and go, but // makeGlobalVariablesScript returns a whole script tag -- grumble grumble... $scripts .= Skin::makeGlobalVariablesScript($sk->getSkinName()) . "\n"; // Script and Messages "only" requests $scripts .= $this->makeResourceLoaderLink($sk, $this->getModuleScripts(), 'scripts'); $scripts .= $this->makeResourceLoaderLink($sk, $this->getModuleMessages(), 'messages'); // Modules requests - let the client calculate dependencies and batch requests as it likes if ($this->getModules()) { $scripts .= Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(Xml::encodeJsCall('mediaWiki.loader.load', array($this->getModules())) . Xml::encodeJsCall('mediaWiki.loader.go', array()))) . "\n"; } // Legacy Scripts $scripts .= "\n" . $this->mScripts; // Add site JS if enabled if ($wgUseSiteJs) { $scripts .= $this->makeResourceLoaderLink($sk, 'site', 'scripts'); } // Add user JS if enabled - trying to load user.options as a bundle if possible $userOptionsAdded = false; if ($this->isUserJsAllowed() && $wgUser->isLoggedIn()) { $action = $wgRequest->getVal('action', 'view'); if ($this->mTitle && $this->mTitle->isJsSubpage() && $sk->userCanPreview($action)) { # XXX: additional security check/prompt? $scripts .= Html::inlineScript("\n" . $wgRequest->getText('wpTextbox1') . "\n") . "\n"; } else { $scripts .= $this->makeResourceLoaderLink($sk, array('user', 'user.options'), 'scripts'); $userOptionsAdded = true; } } if (!$userOptionsAdded) { $scripts .= $this->makeResourceLoaderLink($sk, 'user.options', 'scripts'); } return $scripts; }
/** * Shows a bulletin board style toolbar for common editing functions. * It can be disabled in the user preferences. * The necessary JavaScript code can be found in skins/common/edit.js. * * @return string */ static function getEditToolbar() { global $wgStylePath, $wgContLang, $wgLang, $wgOut; global $wgUseTeX, $wgEnableUploads, $wgForeignFileRepos; $imagesAvailable = $wgEnableUploads || count($wgForeignFileRepos); /** * $toolarray is an array of arrays each of which includes the * filename of the button image (without path), 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. * * Also here: accesskeys (key), which are not used yet until * someone can figure out a way to make them work in * IE. However, we should make sure these keys are not defined * on the edit page. */ $toolarray = array(array('image' => $wgLang->getImageFile('button-bold'), 'id' => 'mw-editbutton-bold', 'open' => '\'\'\'', 'close' => '\'\'\'', 'sample' => wfMsg('bold_sample'), 'tip' => wfMsg('bold_tip'), 'key' => 'B'), array('image' => $wgLang->getImageFile('button-italic'), 'id' => 'mw-editbutton-italic', 'open' => '\'\'', 'close' => '\'\'', 'sample' => wfMsg('italic_sample'), 'tip' => wfMsg('italic_tip'), 'key' => 'I'), array('image' => $wgLang->getImageFile('button-link'), 'id' => 'mw-editbutton-link', 'open' => '[[', 'close' => ']]', 'sample' => wfMsg('link_sample'), 'tip' => wfMsg('link_tip'), 'key' => 'L'), array('image' => $wgLang->getImageFile('button-extlink'), 'id' => 'mw-editbutton-extlink', 'open' => '[', 'close' => ']', 'sample' => wfMsg('extlink_sample'), 'tip' => wfMsg('extlink_tip'), 'key' => 'X'), array('image' => $wgLang->getImageFile('button-headline'), 'id' => 'mw-editbutton-headline', 'open' => "\n== ", 'close' => " ==\n", 'sample' => wfMsg('headline_sample'), 'tip' => wfMsg('headline_tip'), 'key' => 'H'), $imagesAvailable ? array('image' => $wgLang->getImageFile('button-image'), 'id' => 'mw-editbutton-image', 'open' => '[[' . $wgContLang->getNsText(NS_FILE) . ':', 'close' => ']]', 'sample' => wfMsg('image_sample'), 'tip' => wfMsg('image_tip'), 'key' => 'D') : false, $imagesAvailable ? array('image' => $wgLang->getImageFile('button-media'), 'id' => 'mw-editbutton-media', 'open' => '[[' . $wgContLang->getNsText(NS_MEDIA) . ':', 'close' => ']]', 'sample' => wfMsg('media_sample'), 'tip' => wfMsg('media_tip'), 'key' => 'M') : false, $wgUseTeX ? array('image' => $wgLang->getImageFile('button-math'), 'id' => 'mw-editbutton-math', 'open' => "<math>", 'close' => "</math>", 'sample' => wfMsg('math_sample'), 'tip' => wfMsg('math_tip'), 'key' => 'C') : false, array('image' => $wgLang->getImageFile('button-nowiki'), 'id' => 'mw-editbutton-nowiki', 'open' => "<nowiki>", 'close' => "</nowiki>", 'sample' => wfMsg('nowiki_sample'), 'tip' => wfMsg('nowiki_tip'), 'key' => 'N'), array('image' => $wgLang->getImageFile('button-sig'), 'id' => 'mw-editbutton-signature', 'open' => '--~~~~', 'close' => '', 'sample' => '', 'tip' => wfMsg('sig_tip'), 'key' => 'Y'), array('image' => $wgLang->getImageFile('button-hr'), 'id' => 'mw-editbutton-hr', 'open' => "\n----\n", 'close' => '', 'sample' => '', 'tip' => wfMsg('hr_tip'), 'key' => 'R')); $script = 'mw.loader.using("mediawiki.action.edit", function() {'; foreach ($toolarray as $tool) { if (!$tool) { continue; } $params = array($image = $wgStylePath . '/common/images/' . $tool['image'], $tip = $tool['tip'], $open = $tool['open'], $close = $tool['close'], $sample = $tool['sample'], $cssId = $tool['id']); $script .= Xml::encodeJsCall('mw.toolbar.addButton', $params); } // This used to be called on DOMReady from mediawiki.action.edit, which // ended up causing race conditions with the setup code above. $script .= "\n" . "// Create button bar\n" . "\$(function() { mw.toolbar.init(); } );\n"; $script .= '});'; $wgOut->addScript(Html::inlineScript(ResourceLoader::makeLoaderConditionalScript($script))); $toolbar = '<div id="toolbar"></div>'; wfRunHooks('EditPageBeforeEditToolbar', array(&$toolbar)); return $toolbar; }
/** * @param $data array * @return string */ static function makeVariablesScript($data) { if ($data) { return Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(ResourceLoader::makeConfigSetScript($data))); } else { return ''; } }
/** * Output an iframe */ static function outputIframe( $title ) { global $wgEnableIframeEmbed, $wgOut, $wgUser, $wgEnableScriptLoader; if(!$wgEnableIframeEmbed){ throw new MWException( __METHOD__ .' is not enabled' ); } $skin = $wgUser->getSkin(); // Setup the render parm $file = wfFindFile( $title ); $params = array( 'width' => 400 ); $videoTransform= $file->transform( $params ); $wgOut->addModules( array( 'embedPlayerIframeStyle') ); $wgOut->sendCacheControl(); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title><?php echo $title->getText() ?></title> <?php echo Html::element( 'meta', array( 'name' => 'ResourceLoaderDynamicStyles', 'content' => '' ) ); ?> <?php echo $wgOut->getHeadLinks($skin); echo $wgOut->getHeadItems(); ?> <style type="text/css"> html, body { height: 100%; margin: 0; padding: 0; overflow:hidden; } img#bgimage { position:fixed; top:0; left:0; width:100%; height:100%; } </style> <?php echo $wgOut->getHeadScripts( $skin ); ?> <?php echo Html::inlineScript( ResourceLoader::makeLoaderConditionalScript( Xml::encodeJsCall( 'mw.loader.go', array() ) ) ); ?> </head> <body> <img src="<?php echo $videoTransform->getUrl() ?>" id="bgimage" ></img> <div id="videoContainer" style="visibility:hidden"> <?php echo $videoTransform->toHtml(); ?> </div> <script> // Set the fullscreen property inline to avoid poluting the player cache mw.setConfig('EmbedPlayer.EnableFullscreen', false ); $('#bgimage').remove(); mw.ready(function(){ var fitPlayer = function(){ $( '#<?php echo TimedMediaTransformOutput::PLAYER_ID_PREFIX . '0' ?>' ) .get(0).resizePlayer({ 'width' : $(window).width(), 'height' : $(window).height() }); } // Bind window resize to reize the player: $( window ).resize( fitPlayer ); $('#videoContainer').css({ 'visibility':'visible' }); fitPlayer(); }); </script> </body> </html> <?php }
/** * JS stuff to put at the bottom of the <body>: modules marked with position 'bottom', * legacy scripts ($this->mScripts), user preferences, site JS and user JS * * @param $sk Skin * * @return string */ function getBottomScripts(Skin $sk) { global $wgUseSiteJs, $wgAllowUserJs; // Script and Messages "only" requests marked for bottom inclusion // Messages should go first $scripts = $this->makeResourceLoaderLink($sk, $this->getModuleMessages(true, 'bottom'), ResourceLoaderModule::TYPE_MESSAGES); $scripts .= $this->makeResourceLoaderLink($sk, $this->getModuleScripts(true, 'bottom'), ResourceLoaderModule::TYPE_SCRIPTS); // Modules requests - let the client calculate dependencies and batch requests as it likes // Only load modules that have marked themselves for loading at the bottom $modules = $this->getModules(true, 'bottom'); if ($modules) { $scripts .= Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(Xml::encodeJsCall('mw.loader.load', array($modules)))); } // Legacy Scripts $scripts .= "\n" . $this->mScripts; $userScripts = array('user.options', 'user.tokens'); // Add site JS if enabled if ($wgUseSiteJs) { $scripts .= $this->makeResourceLoaderLink($sk, 'site', ResourceLoaderModule::TYPE_SCRIPTS); if ($this->getUser()->isLoggedIn()) { $userScripts[] = 'user.groups'; } } // Add user JS if enabled if ($wgAllowUserJs && $this->getUser()->isLoggedIn()) { $action = $this->getRequest()->getVal('action', 'view'); if ($this->getTitle() && $this->getTitle()->isJsSubpage() && $sk->userCanPreview($action)) { # XXX: additional security check/prompt? $scripts .= Html::inlineScript("\n" . $this->getRequest()->getText('wpTextbox1') . "\n") . "\n"; } else { # @todo FIXME: This means that User:Me/Common.js doesn't load when previewing # User:Me/Vector.js, and vice versa (bug26283) $userScripts[] = 'user'; } } $scripts .= $this->makeResourceLoaderLink($sk, $userScripts, ResourceLoaderModule::TYPE_SCRIPTS); return $scripts; }
/** * Returns the HTML to add to the page for the toolbar * * @param $context IContextSource * @return string */ public static function getDebugHTML(IContextSource $context) { if (!self::$enabled) { return ''; } global $wgVersion, $wgRequestTime; MWDebug::log('MWDebug output complete'); $request = $context->getRequest(); $debugInfo = array('mwVersion' => $wgVersion, 'phpVersion' => PHP_VERSION, 'time' => microtime(true) - $wgRequestTime, 'log' => self::$log, 'debugLog' => self::$debug, 'queries' => self::$query, 'request' => array('method' => $_SERVER['REQUEST_METHOD'], 'url' => $request->getRequestURL(), 'headers' => $request->getAllHeaders(), 'params' => $request->getValues()), 'memory' => $context->getLanguage()->formatSize(memory_get_usage()), 'memoryPeak' => $context->getLanguage()->formatSize(memory_get_peak_usage()), 'includes' => self::getFilesIncluded($context)); // Cannot use OutputPage::addJsConfigVars because those are already outputted // by the time this method is called. $html = Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(ResourceLoader::makeConfigSetScript(array('debugInfo' => $debugInfo)))); return $html; }
/** * BeforePageDisplay hook handler. * @param $out OutputPage */ public static function beforePageDisplay($out) { global $wgUser; wfProfileIn(__METHOD__); $gadgets = Gadget::loadList(); if (!$gadgets) { wfProfileOut(__METHOD__); return true; } $lb = new LinkBatch(); $lb->setCaller(__METHOD__); $pages = array(); $stylesModules = array(); foreach ($gadgets as $gadget) { if ($gadget->isEnabled($wgUser) && $gadget->isAllowed($wgUser)) { if ($gadget->hasModule()) { $out->addModules($gadget->getModuleName()); } if ($gadget->hasStylesModule()) { $stylesModules[] = $gadget->getStylesModuleName(); } foreach ($gadget->getLegacyScripts() as $page) { $lb->add(NS_MEDIAWIKI, $page); $pages[] = $page; } } } if (count($stylesModules)) { $out->addHeadItem('ext.gadget', $out->makeResourceLoaderLink($stylesModules, ResourceLoaderModule::TYPE_STYLES) . Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(ResourceLoader::makeLoaderStateScript(array_fill_keys($stylesModules, 'ready'))))); } $lb->execute(__METHOD__); $done = array(); foreach ($pages as $page) { if (isset($done[$page])) { continue; } $done[$page] = true; self::applyScript($page, $out); } wfProfileOut(__METHOD__); return true; }
/** * JS stuff to put at the 'bottom', which can either be the bottom of the "<body>" * or the bottom of the "<head>" depending on $wgResourceLoaderExperimentalAsyncLoading: * modules marked with position 'bottom', legacy scripts ($this->mScripts), * user preferences, site JS and user JS * * @param $inHead boolean If true, this HTML goes into the "<head>", if false it goes into the "<body>" * @return string */ function getScriptsForBottomQueue($inHead) { global $wgUseSiteJs, $wgAllowUserJs; // Script and Messages "only" requests marked for bottom inclusion // If we're in the <head>, use load() calls rather than <script src="..."> tags // Messages should go first $scripts = $this->makeResourceLoaderLink($this->getModuleMessages(true, 'bottom'), ResourceLoaderModule::TYPE_MESSAGES, false, array(), $inHead); $scripts .= $this->makeResourceLoaderLink($this->getModuleScripts(true, 'bottom'), ResourceLoaderModule::TYPE_SCRIPTS, false, array(), $inHead); // Modules requests - let the client calculate dependencies and batch requests as it likes // Only load modules that have marked themselves for loading at the bottom $modules = $this->getModules(true, 'bottom'); if ($modules) { $scripts .= Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(Xml::encodeJsCall('mw.loader.load', array($modules, null, true)))); } // Legacy Scripts $scripts .= "\n" . $this->mScripts; $defaultModules = array(); // Add site JS if enabled if ($wgUseSiteJs) { $scripts .= $this->makeResourceLoaderLink('site', ResourceLoaderModule::TYPE_SCRIPTS, false, array(), $inHead); $defaultModules['site'] = 'loading'; } else { // The wiki is configured to not allow a site module. $defaultModules['site'] = 'missing'; } // Add user JS if enabled if ($wgAllowUserJs) { if ($this->getUser()->isLoggedIn()) { if ($this->getTitle() && $this->getTitle()->isJsSubpage() && $this->userCanPreview()) { # XXX: additional security check/prompt? // We're on a preview of a JS subpage // Exclude this page from the user module in case it's in there (bug 26283) $scripts .= $this->makeResourceLoaderLink('user', ResourceLoaderModule::TYPE_SCRIPTS, false, array('excludepage' => $this->getTitle()->getPrefixedDBkey()), $inHead); // Load the previewed JS $scripts .= Html::inlineScript("\n" . $this->getRequest()->getText('wpTextbox1') . "\n") . "\n"; // FIXME: If the user is previewing, say, ./vector.js, his ./common.js will be loaded // asynchronously and may arrive *after* the inline script here. So the previewed code // may execute before ./common.js runs. Normally, ./common.js runs before ./vector.js... } else { // Include the user module normally, i.e., raw to avoid it being wrapped in a closure. $scripts .= $this->makeResourceLoaderLink('user', ResourceLoaderModule::TYPE_SCRIPTS, false, array(), $inHead); } $defaultModules['user'] = '******'; } else { // Non-logged-in users have no user module. Treat it as empty and 'ready' to avoid // blocking default gadgets that might depend on it. Although arguably default-enabled // gadgets should not depend on the user module, it's harmless and less error-prone to // handle this case. $defaultModules['user'] = '******'; } } else { // User JS disabled $defaultModules['user'] = '******'; } // Group JS is only enabled if site JS is enabled. if ($wgUseSiteJs) { if ($this->getUser()->isLoggedIn()) { $scripts .= $this->makeResourceLoaderLink('user.groups', ResourceLoaderModule::TYPE_COMBINED, false, array(), $inHead); $defaultModules['user.groups'] = 'loading'; } else { // Non-logged-in users have no user.groups module. Treat it as empty and 'ready' to // avoid blocking gadgets that might depend upon the module. $defaultModules['user.groups'] = 'ready'; } } else { // Site (and group JS) disabled $defaultModules['user.groups'] = 'missing'; } $loaderInit = ''; if ($inHead) { // We generate loader calls anyway, so no need to fix the client-side loader's state to 'loading'. foreach ($defaultModules as $m => $state) { if ($state == 'loading') { unset($defaultModules[$m]); } } } if (count($defaultModules) > 0) { $loaderInit = Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(ResourceLoader::makeLoaderStateScript($defaultModules))) . "\n"; } return $loaderInit . $scripts; }
function buildCleanupScript() { $options = array('tableId' => 'mwProtectSet', 'labelText' => wfMessage('protect-unchain-permissions')->plain(), 'numTypes' => count($this->mApplicableTypes), 'existingMatch' => count(array_unique($this->mExistingExpiry)) === 1); $script = Xml::encodeJsCall('ProtectionForm.init', array($options)); return Html::inlineScript(ResourceLoader::makeLoaderConditionalScript($script)); }
/** * Run the test suite on the Special page. * * Rendered by OutputPage and Skin. */ private function viewQUnit() { $out = $this->getOutput(); $modules = $out->getResourceLoader()->getTestModuleNames('qunit'); $summary = $this->msg('javascripttest-qunit-intro')->params('https://www.mediawiki.org/wiki/Manual:JavaScript_unit_testing')->parseAsBlock(); $baseHtml = <<<HTML <div class="mw-content-ltr"> <div id="qunit"></div> </div> HTML; $out->addHtml($this->wrapSummaryHtml($summary) . $baseHtml); // The testrunner configures QUnit and essentially depends on it. However, test suites // are reusable in environments that preload QUnit (or a compatibility interface to // another framework). Therefore we have to load it ourselves. $out->addHtml(Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(Xml::encodeJsCall('mw.loader.using', array(array('jquery.qunit', 'jquery.qunit.completenessTest'), new XmlJsCode('function () {' . Xml::encodeJsCall('mw.loader.load', array($modules)) . '}')))))); }
<?php // This is a stub entry point to load.php This is need to support valid paths for the stand alone // mwEmbed module html test files. // This is useful for running stand alone test of mwEmbed components in the TimedMediaHandler // extension. ( ie MwEmbedModules/EmbedPlayer/tests/*.html files ) $_GET['modules'] = 'startup'; $_GET['only'] = 'scripts'; // NOTE this won't work so well with symbolic links $loaderPath = dirname(__FILE__) . '/../../load.php'; if( is_file( $loaderPath ) ){ chdir( dirname( $loaderPath ) ); include_once( $loaderPath ); } else { print "if( console && typeof console.log == 'function' ){ console.log('Error can't find load.php for stand alone tests' ) }"; } // Bootstrap some js code to make the "loader" work in stand alone tests: // Note this has to be wrapped in a document.write to run after other document.writes $pageStartupScript = Html::inlineScript( ResourceLoader::makeLoaderConditionalScript( Xml::encodeJsCall( 'mw.loader.go', array() ) ) ); echo Xml::encodeJsCall( 'document.write', array( $pageStartupScript ) );
protected function squeezeMediawikiLoad(&$scripts, &$bottomScripts) { // parse both script chunks $scriptMatches = array(); if (preg_match_all(WikiaSkin::SCRIPT_REGEX, $scripts, $scriptMatches)) { $scriptMatches = reset($scriptMatches); } $bottomScriptMatches = array(); if (preg_match_all(WikiaSkin::SCRIPT_REGEX, $bottomScripts, $bottomScriptMatches)) { $bottomScriptMatches = reset($bottomScriptMatches); } // find mw.loader.load()s $loadTags = array(); $modules = array(); foreach (array_merge($scriptMatches, $bottomScriptMatches) as $scriptTag) { $tagModules = $this->getModuleListFromMediawikiLoad($scriptTag); if ($tagModules !== false) { $loadTags[] = $scriptTag; $modules = array_merge($modules, $tagModules); } } // we cannot optimize it if (count($loadTags) <= 1) { return; } // build new modules list $modules = array_unique($modules); // sort($modules); // create conditional mw.loader.load() script $loadScript = Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(Xml::encodeJsCall('mw.loader.load', array($modules)))); // finally do the replacement $first = true; foreach ($loadTags as $loadTag) { $replacement = $first ? $loadScript : ''; $scripts = str_replace($loadTag, $replacement, $scripts); $bottomScripts = str_replace($loadTag, $replacement, $bottomScripts); $first = false; } }
/** * Shows a bulletin board style toolbar for common editing functions. * It can be disabled in the user preferences. * * @return string */ static function getEditToolbar() { global $wgContLang, $wgOut; global $wgEnableUploads, $wgForeignFileRepos; $imagesAvailable = $wgEnableUploads || count($wgForeignFileRepos); /** * $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()), array('id' => 'mw-editbutton-signature', 'open' => '--~~~~', 'close' => '', 'sample' => '', 'tip' => wfMessage('sig_tip')->text()), array('id' => 'mw-editbutton-hr', 'open' => "\n----\n", 'close' => '', 'sample' => '', 'tip' => wfMessage('hr_tip')->text())); $script = 'mw.loader.using("mediawiki.action.edit", 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); } // This used to be called on DOMReady from mediawiki.action.edit, which // ended up causing race conditions with the setup code above. $script .= "\n" . "// Create button bar\n" . "\$(function() { mw.toolbar.init(); } );\n"; $script .= '});'; $wgOut->addScript(Html::inlineScript(ResourceLoader::makeLoaderConditionalScript($script))); $toolbar = '<div id="toolbar"></div>'; wfRunHooks('EditPageBeforeEditToolbar', array(&$toolbar)); return $toolbar; }
// Output MWEMBED_VERSION global: echo "window['MWEMBED_VERSION'] = '{$wgMwEmbedVersion}';\n"; // Bootstrap some js code to make the "loader" work in stand alone mode // not need when iframe includes starup and sets iframeStartup flag if (!isset($_GET['mwEmbedSetupDone'])) { // Bootstrap some js code to make the "loader" work in stand alone mode // Note this has to be wrapped in a document.write to run after other document.writes $pageStartupScript = Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(Xml::encodeJsCall('mw.loader.go', array()))); echo Xml::encodeJsCall('document.write', array($pageStartupScript)); ?> var waitForMwCount = 0; var waitforMw = function( callback ){ if( window['mw'] ){ // most browsers will directly execute the callback: callback(); return ; } setTimeout(function(){ waitForMwCount++; if( waitForMwCount < 1000 ){ waitforMw( callback ); } else { console.log("Error in loading mwEmbedLodaer"); } }, 10 ); }; <?php // Load the core mw.MwEmbedSupport library $pageMwEmbedScript = Html::inlineScript('waitforMw( function(){' . ResourceLoader::makeLoaderConditionalScript(Xml::encodeJsCall('mw.loader.load', array('mw.MwEmbedSupport'))) . '});'); echo Xml::encodeJsCall('document.write', array($pageMwEmbedScript)); }
/** * Returns the HTML to add to the page for the toolbar * * @since 1.19 * @param $context IContextSource * @return string */ public static function getDebugHTML(IContextSource $context) { global $wgDebugComments; $html = ''; if (self::$enabled) { MWDebug::log('MWDebug output complete'); $debugInfo = self::getDebugInfo($context); // Cannot use OutputPage::addJsConfigVars because those are already outputted // by the time this method is called. $html = Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(ResourceLoader::makeConfigSetScript(array('debugInfo' => $debugInfo)))); } if ($wgDebugComments) { $html .= "<!-- Debug output:\n" . htmlspecialchars(implode("\n", self::$debug)) . "\n\n-->"; } return $html; }
/** * JS stuff to put at the 'bottom', which can either be the bottom of the <body> * or the bottom of the <head> depending on $wgResourceLoaderExperimentalAsyncLoading: * modules marked with position 'bottom', legacy scripts ($this->mScripts), * user preferences, site JS and user JS * * @param $inHead boolean If true, this HTML goes into the <head>, if false it goes into the <body> * @return string */ function getScriptsForBottomQueue($inHead) { global $wgUseSiteJs, $wgAllowUserJs; // Script and Messages "only" requests marked for bottom inclusion // If we're in the <head>, use load() calls rather than <script src="..."> tags // Messages should go first $scripts = $this->makeResourceLoaderLink($this->getModuleMessages(true, 'bottom'), ResourceLoaderModule::TYPE_MESSAGES, false, array(), $inHead); $scripts .= $this->makeResourceLoaderLink($this->getModuleScripts(true, 'bottom'), ResourceLoaderModule::TYPE_SCRIPTS, false, array(), $inHead); // Modules requests - let the client calculate dependencies and batch requests as it likes // Only load modules that have marked themselves for loading at the bottom $modules = $this->getModules(true, 'bottom'); if ($modules) { $scripts .= Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(Xml::encodeJsCall('mw.loader.load', array($modules, null, true)))); } // Legacy Scripts $scripts .= "\n" . $this->mScripts; $userScripts = array(); // Add site JS if enabled if ($wgUseSiteJs) { $scripts .= $this->makeResourceLoaderLink('site', ResourceLoaderModule::TYPE_SCRIPTS, false, array(), $inHead); if ($this->getUser()->isLoggedIn()) { $userScripts[] = 'user.groups'; } } // Add user JS if enabled if ($wgAllowUserJs && $this->getUser()->isLoggedIn()) { if ($this->getTitle() && $this->getTitle()->isJsSubpage() && $this->userCanPreview()) { # XXX: additional security check/prompt? // We're on a preview of a JS subpage // Exclude this page from the user module in case it's in there (bug 26283) $scripts .= $this->makeResourceLoaderLink('user', ResourceLoaderModule::TYPE_SCRIPTS, false, array('excludepage' => $this->getTitle()->getPrefixedDBkey()), $inHead); // Load the previewed JS $scripts .= Html::inlineScript("\n" . $this->getRequest()->getText('wpTextbox1') . "\n") . "\n"; } else { // Include the user module normally // We can't do $userScripts[] = 'user'; because the user module would end up // being wrapped in a closure, so load it raw like 'site' $scripts .= $this->makeResourceLoaderLink('user', ResourceLoaderModule::TYPE_SCRIPTS, false, array(), $inHead); } } $scripts .= $this->makeResourceLoaderLink($userScripts, ResourceLoaderModule::TYPE_COMBINED, false, array(), $inHead); return $scripts; }
/** * More minimal version of getHeadScripts from OutputPage * * @param OutputPage $out * @return string */ protected function getHeadScripts(OutputPage $out) { $scripts = $out->makeResourceLoaderLink('startup', ResourceLoaderModule::TYPE_SCRIPTS, true, array('mobile' => true)); $scripts .= Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(ResourceLoader::makeConfigSetScript($out->getJSVars()))); return $scripts; }
/** * Get all the kaltura defined modules from player config * */ function outputKalturaModules() { $o = ''; // Init modules array, always include MwEmbedSupport $moduleList = array('mw.MwEmbedSupport'); // Check player config per plugin id mapping $kalturaSupportModules = (include 'KalturaSupport.php'); $playerConfig = $this->getUiConfResult()->getPlayerConfig(); foreach ($kalturaSupportModules as $name => $module) { if (isset($module['kalturaLoad']) && $module['kalturaLoad'] == 'always') { $moduleList[] = $name; } // Check if the module has a kalturaPluginName and load if set in playerConfig if (isset($module['kalturaPluginName'])) { if (is_array($module['kalturaPluginName'])) { foreach ($module['kalturaPluginName'] as $subModuleName) { if (isset($playerConfig['plugins'][$subModuleName])) { $moduleList[] = $name; continue; } } } else { if (isset($playerConfig['plugins'][$module['kalturaPluginName']])) { $moduleList[] = $name; } } } } // Have all the kaltura related plugins listed in a configuration var for // implicte dependency mapping before embedding embedPlayer $o .= ResourceLoader::makeConfigSetScript(array('KalturaSupport.DepModuleList' => $moduleList)); // Special cases: handle plugins that have more complex conditional load calls // always include mw.EmbedPlayer $moduleList[] = 'mw.EmbedPlayer'; // Load all the known required libraries: $o .= ResourceLoader::makeLoaderConditionalScript(Xml::encodeJsCall('mw.loader.load', array($moduleList))); return $o; }
/** * JS stuff to put at the 'bottom', which can either be the bottom of the "<body>" * or the bottom of the "<head>" depending on $wgResourceLoaderExperimentalAsyncLoading: * modules marked with position 'bottom', legacy scripts ($this->mScripts), * user preferences, site JS and user JS. * * @param bool $inHead If true, this HTML goes into the "<head>", if false it goes into the "<body>" * @return string */ function getScriptsForBottomQueue($inHead) { global $wgUseSiteJs, $wgAllowUserJs; // Scripts and messages "only" requests marked for bottom inclusion // If we're in the <head>, use load() calls rather than <script src="..."> tags // Messages should go first $links = array(); $links[] = $this->makeResourceLoaderLink($this->getModuleMessages(true, 'bottom'), ResourceLoaderModule::TYPE_MESSAGES, false, array(), $inHead); $links[] = $this->makeResourceLoaderLink($this->getModuleScripts(true, 'bottom'), ResourceLoaderModule::TYPE_SCRIPTS, false, array(), $inHead); // Modules requests - let the client calculate dependencies and batch requests as it likes // Only load modules that have marked themselves for loading at the bottom $modules = $this->getModules(true, 'bottom'); if ($modules) { $links[] = Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(Xml::encodeJsCall('mw.loader.load', array($modules, null, true)))); } // Legacy Scripts $links[] = "\n" . $this->mScripts; // Add site JS if enabled $links[] = $this->makeResourceLoaderLink('site', ResourceLoaderModule::TYPE_SCRIPTS, false, array(), $inHead); // Add user JS if enabled if ($wgAllowUserJs && $this->getTitle() && $this->getTitle()->isJsSubpage() && $this->userCanPreview()) { # XXX: additional security check/prompt? // We're on a preview of a JS subpage // Exclude this page from the user module in case it's in there (bug 26283) $links[] = $this->makeResourceLoaderLink('user', ResourceLoaderModule::TYPE_SCRIPTS, false, array('excludepage' => $this->getTitle()->getPrefixedDBkey()), $inHead); // Load the previewed JS $links[] = Html::inlineScript("\n" . $this->getRequest()->getText('wpTextbox1') . "\n") . "\n"; // FIXME: If the user is previewing, say, ./vector.js, his ./common.js will be loaded // asynchronously and may arrive *after* the inline script here. So the previewed code // may execute before ./common.js runs. Normally, ./common.js runs before ./vector.js... } else { // Include the user module normally, i.e., raw to avoid it being wrapped in a closure. $links[] = $this->makeResourceLoaderLink('user', ResourceLoaderModule::TYPE_SCRIPTS, false, array(), $inHead); } // Group JS is only enabled if site JS is enabled. $links[] = $this->makeResourceLoaderLink('user.groups', ResourceLoaderModule::TYPE_COMBINED, false, array(), $inHead); return self::getHtmlFromLoaderLinks($links); }
function buildCleanupScript() { global $wgRestrictionLevels, $wgGroupPermissions, $wgOut; $cascadeableLevels = array(); foreach ($wgRestrictionLevels as $key) { if (isset($wgGroupPermissions[$key]['protect']) && $wgGroupPermissions[$key]['protect'] || $key == 'protect') { $cascadeableLevels[] = $key; } } $options = array('tableId' => 'mwProtectSet', 'labelText' => wfMessage('protect-unchain-permissions')->plain(), 'numTypes' => count($this->mApplicableTypes), 'existingMatch' => count(array_unique($this->mExistingExpiry)) === 1); $wgOut->addJsConfigVars('wgCascadeableLevels', $cascadeableLevels); $script = Xml::encodeJsCall('ProtectionForm.init', array($options)); return Html::linkAndCreate(ResourceLoader::makeLoaderConditionalScript($script)); }
function buildCleanupScript() { global $wgCascadingRestrictionLevels, $wgOut; $cascadeableLevels = $wgCascadingRestrictionLevels; $options = array('tableId' => 'mwProtectSet', 'labelText' => wfMessage('protect-unchain-permissions')->plain(), 'numTypes' => count($this->mApplicableTypes), 'existingMatch' => count(array_unique($this->mExistingExpiry)) === 1); $wgOut->addJsConfigVars('wgCascadeableLevels', $cascadeableLevels); $script = Xml::encodeJsCall('ProtectionForm.init', array($options)); return Html::inlineScript(ResourceLoader::makeLoaderConditionalScript($script)); }