コード例 #1
0
 /**
  * JS stuff to put at the 'bottom', which goes at the bottom of the `<body>`.
  * These are modules marked with position 'bottom', legacy scripts ($this->mScripts),
  * site JS, and user JS.
  *
  * @param bool $unused Previously used to let this method change its output based
  *  on whether it was called by getExternalHeadScripts() or getBottomScripts().
  * @return string
  */
 function getScriptsForBottomQueue($unused = null)
 {
     // Scripts "only" requests marked for bottom inclusion
     // If we're in the <head>, use load() calls rather than <script src="..."> tags
     $links = array();
     $links[] = $this->makeResourceLoaderLink($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) {
         $links[] = ResourceLoader::makeInlineScript(Xml::encodeJsCall('mw.loader.load', array($modules)));
     }
     // Legacy Scripts
     $links[] = $this->mScripts;
     // Add user JS if enabled
     // This must use TYPE_COMBINED instead of only=scripts so that its request is handled by
     // mw.loader.implement() which ensures that execution is scheduled after the "site" module.
     if ($this->getConfig()->get('AllowUserJs') && $this->getUser()->isLoggedIn() && $this->getTitle() && $this->getTitle()->isJsSubpage() && $this->userCanPreview()) {
         // We're on a preview of a JS subpage. Exclude this page from the user module (T28283)
         // and include the draft contents as a raw script instead.
         $links[] = $this->makeResourceLoaderLink('user', ResourceLoaderModule::TYPE_COMBINED, array('excludepage' => $this->getTitle()->getPrefixedDBkey()));
         // Load the previewed JS
         $links[] = ResourceLoader::makeInlineScript(Xml::encodeJsCall('mw.loader.using', array(array('user', 'site'), new XmlJsCode('function () {' . Xml::encodeJsCall('$.globalEval', array($this->getRequest()->getText('wpTextbox1'))) . '}'))));
         // 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.
         // Similarly, when previewing ./common.js and the user module does arrive first,
         // it will arrive without common.js and the inline script runs after.
         // Thus running common after the excluded subpage.
     } else {
         // Include the user module normally, i.e., raw to avoid it being wrapped in a closure.
         $links[] = $this->makeResourceLoaderLink('user', ResourceLoaderModule::TYPE_COMBINED);
     }
     // Group JS is only enabled if site JS is enabled.
     $links[] = $this->makeResourceLoaderLink('user.groups', ResourceLoaderModule::TYPE_COMBINED);
     return self::getHtmlFromLoaderLinks($links);
 }
コード例 #2
0
 /**
  * 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)
 {
     // Scripts "only" requests marked for bottom inclusion
     // If we're in the <head>, use load() calls rather than <script src="..."> tags
     $links = array();
     $links[] = $this->makeResourceLoaderLink($this->getModuleScripts(true, 'bottom'), ResourceLoaderModule::TYPE_SCRIPTS, false, array(), $inHead);
     $links[] = $this->makeResourceLoaderLink($this->getModuleStyles(true, 'bottom'), ResourceLoaderModule::TYPE_STYLES, 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[] = ResourceLoader::makeInlineScript(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 ($this->getConfig()->get('AllowUserJs') && $this->getUser()->isLoggedIn() && $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);
 }
コード例 #3
0
ファイル: MWDebug.php プロジェクト: MediaWiki-stable/1.26.1
 /**
  * Returns the HTML to add to the page for the toolbar
  *
  * @since 1.19
  * @param IContextSource $context
  * @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 = ResourceLoader::makeInlineScript(ResourceLoader::makeConfigSetScript(array('debugInfo' => $debugInfo)));
     }
     if ($wgDebugComments) {
         $html .= "<!-- Debug output:\n" . htmlspecialchars(implode("\n", self::$debug)) . "\n\n-->";
     }
     return $html;
 }
コード例 #4
0
    function printPage($form_name, $embedded = false)
    {
        global $wgOut, $wgRequest, $sfgFormPrinter, $wgParser, $sfgRunQueryFormAtTop;
        global $wgUser;
        // Get contents of form-definition page.
        $form_title = Title::makeTitleSafe(SF_NS_FORM, $form_name);
        if (!$form_title || !$form_title->exists()) {
            if ($form_name === '') {
                $text = Html::element('p', array('class' => 'error'), wfMessage('sf_runquery_badurl')->text()) . "\n";
            } else {
                $text = Html::rawElement('p', array('class' => 'error'), wfMessage('sf_formstart_badform', SFUtils::linkText(SF_NS_FORM, $form_name))->parse()) . "\n";
            }
            $wgOut->addHTML($text);
            return;
        }
        // Initialize variables.
        $form_definition = SFUtils::getPageText($form_title);
        if ($embedded) {
            $run_query = false;
            $content = null;
            $raw = false;
        } else {
            $run_query = $wgRequest->getCheck('wpRunQuery');
            $content = $wgRequest->getVal('wpTextbox1');
            $raw = $wgRequest->getBool('raw', false);
        }
        $form_submitted = $run_query;
        if ($raw) {
            $wgOut->setArticleBodyOnly(true);
        }
        // If user already made some action, ignore the edited
        // page and just get data from the query string.
        if (!$embedded && $wgRequest->getVal('query') == 'true') {
            $edit_content = null;
            $is_text_source = false;
        } elseif ($content != null) {
            $edit_content = $content;
            $is_text_source = true;
        } else {
            $edit_content = null;
            $is_text_source = true;
        }
        list($form_text, $javascript_text, $data_text, $form_page_title) = $sfgFormPrinter->formHTML($form_definition, $form_submitted, $is_text_source, $form_title->getArticleID(), $edit_content, null, null, true, $embedded);
        $text = "";
        // Get the text of the results.
        $resultsText = '';
        if ($form_submitted) {
            // @TODO - fix RunQuery's parsing so that this check
            // isn't needed.
            if ($wgParser->getOutput() == null) {
                $headItems = array();
            } else {
                $headItems = $wgParser->getOutput()->getHeadItems();
            }
            foreach ($headItems as $key => $item) {
                $wgOut->addHeadItem($key, "\t\t" . $item . "\n");
            }
            $wgParser->mOptions = ParserOptions::newFromUser($wgUser);
            $resultsText = $wgParser->parse($data_text, $this->getTitle(), $wgParser->mOptions)->getText();
        }
        // Get the full text of the form.
        $fullFormText = '';
        $additionalQueryHeader = '';
        $dividerText = '';
        if (!$raw) {
            // Create the "additional query" header, and the
            // divider text - one of these (depending on whether
            // the query form is at the top or bottom) is displayed
            // if the form has already been submitted.
            if ($form_submitted) {
                $additionalQueryHeader = "\n" . Html::element('h2', null, wfMessage('sf_runquery_additionalquery')->text()) . "\n";
                $dividerText = "\n<hr style=\"margin: 15px 0;\" />\n";
            }
            $action = htmlspecialchars($this->getTitle($form_name)->getLocalURL());
            $fullFormText .= <<<END
\t<form id="sfForm" name="createbox" action="{$action}" method="post" class="createbox">

END;
            $fullFormText .= Html::hidden('query', 'true');
            $fullFormText .= $form_text;
        }
        // Either don't display a query form at all, or display the
        // query form at the top, and the results at the bottom, or the
        // other way around, depending on the settings.
        if ($wgRequest->getVal('additionalquery') == 'false') {
            $text .= $resultsText;
        } elseif ($sfgRunQueryFormAtTop) {
            $text .= Html::openElement('div', array('class' => 'sf-runquery-formcontent'));
            $text .= $fullFormText;
            $text .= $dividerText;
            $text .= Html::closeElement('div');
            $text .= $resultsText;
        } else {
            $text .= $resultsText;
            $text .= Html::openElement('div', array('class' => 'sf-runquery-formcontent'));
            $text .= $additionalQueryHeader;
            $text .= $fullFormText;
            $text .= Html::closeElement('div');
        }
        if ($embedded) {
            $text = "<div class='runQueryEmbedded'>{$text}</div>";
        }
        // Armor against doBlockLevels()
        $text = preg_replace('/^ +/m', '', $text);
        // Now write everything to the screen.
        $wgOut->addHTML($text);
        SFUtils::addFormRLModules($embedded ? $wgParser : null);
        $script = "\t\t" . '<script type="text/javascript">' . "\n" . $javascript_text . '</script>' . "\n";
        if ($embedded) {
            if (method_exists('ResourceLoader', 'makeInlineScript')) {
                // MW 1.25+
                $wgParser->getOutput()->addHeadItem(ResourceLoader::makeInlineScript($javascript_text));
            } else {
                $wgParser->getOutput()->addHeadItem($script);
            }
        } else {
            if (method_exists('ResourceLoader', 'makeInlineScript')) {
                // MW 1.25+
                $wgOut->addScript(ResourceLoader::makeInlineScript($javascript_text));
            } else {
                $wgOut->addScript($script);
            }
            $po = $wgParser->getOutput();
            if ($po) {
                // addParserOutputMetadata was introduced in 1.24 when addParserOutputNoText was deprecated
                if (method_exists($wgOut, 'addParserOutputMetadata')) {
                    $wgOut->addParserOutputMetadata($po);
                } else {
                    $wgOut->addParserOutputNoText($po);
                }
            }
        }
        // Finally, set the page title - previously, this had to be
        // called after addParserOutputNoText() for it to take effect;
        // now the order doesn't matter.
        if (!$embedded) {
            if ($form_page_title != null) {
                $wgOut->setPageTitle($form_page_title);
            } else {
                $s = wfMessage('sf_runquery_title', $form_title->getText())->text();
                $wgOut->setPageTitle($s);
            }
        }
    }
コード例 #5
0
    /**
     * 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(ResourceLoader::makeInlineScript(Xml::encodeJsCall('mw.loader.using', array(array('jquery.qunit', 'jquery.qunit.completenessTest'), new XmlJsCode('function () {' . Xml::encodeJsCall('mw.loader.load', array($modules)) . '}')))));
    }
コード例 #6
0
ファイル: Skin.php プロジェクト: junjiemars/mediawiki
 /**
  * @param array $data
  * @return string
  */
 static function makeVariablesScript($data)
 {
     if ($data) {
         return ResourceLoader::makeInlineScript(ResourceLoader::makeConfigSetScript($data));
     } else {
         return '';
     }
 }
コード例 #7
0
ファイル: EditPage.php プロジェクト: OrBin/mediawiki
 /**
  * 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;
 }
コード例 #8
0
ファイル: OutputPage.php プロジェクト: paladox/mediawiki
 /**
  * JS stuff to put at the bottom of the `<body>`. These are modules with position 'bottom',
  * legacy scripts ($this->mScripts), and user JS.
  *
  * @return string|WrappedStringList HTML
  */
 public function getBottomScripts()
 {
     $chunks = [];
     $chunks[] = $this->getRlClient()->getBodyHtml();
     // Legacy non-ResourceLoader scripts
     $chunks[] = $this->mScripts;
     // Exempt 'user' module
     // - May need excludepages for live preview. (T28283)
     // - Must use TYPE_COMBINED so its response is handled by mw.loader.implement() which
     //   ensures execution is scheduled after the "site" module.
     // - Don't load if module state is already resolved as "ready".
     if ($this->rlUserModuleState === 'loading') {
         if ($this->isUserJsPreview()) {
             $chunks[] = $this->makeResourceLoaderLink('user', ResourceLoaderModule::TYPE_COMBINED, ['excludepage' => $this->getTitle()->getPrefixedDBkey()]);
             $chunks[] = ResourceLoader::makeInlineScript(Xml::encodeJsCall('mw.loader.using', [['user', 'site'], new XmlJsCode('function () {' . Xml::encodeJsCall('$.globalEval', [$this->getRequest()->getText('wpTextbox1')]) . '}')]));
             // 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.
             // Similarly, when previewing ./common.js and the user module does arrive first,
             // it will arrive without common.js and the inline script runs after.
             // Thus running common after the excluded subpage.
         } else {
             // Load normally
             $chunks[] = $this->makeResourceLoaderLink('user', ResourceLoaderModule::TYPE_COMBINED);
         }
     }
     if ($this->limitReportData) {
         $chunks[] = ResourceLoader::makeInlineScript(ResourceLoader::makeConfigSetScript(['wgPageParseReport' => $this->limitReportData], true));
     }
     return self::combineWrappedStrings($chunks);
 }
コード例 #9
0
 function printForm($form_name, $targetName, $alt_forms = array())
 {
     $out = $this->getOutput();
     $req = $this->getRequest();
     $module = new SFAutoeditAPI(new ApiMain(), 'sfautoedit');
     $module->setOption('form', $form_name);
     $module->setOption('target', $targetName);
     if ($req->getCheck('wpSave') || $req->getCheck('wpPreview') || $req->getCheck('wpDiff')) {
         // If the page was submitted, form data should be
         // complete => do not preload (unless it's a partial
         // form).
         if ($req->getCheck('partial')) {
             $module->setOption('preload', true);
         } else {
             $module->setOption('preload', false);
         }
     } else {
         if (!empty($targetName) && Title::newFromText($targetName)->exists()) {
             // If target page exists, do not overwrite it with
             // preload data; just preload the page's data.
             $module->setOption('preload', true);
         } else {
             if ($req->getCheck('preload')) {
                 // if page does not exist and preload parameter is set, pass that on
                 $module->setOption('preload', $req->getText('preload'));
             } else {
                 // nothing set, so do not set preload
             }
         }
     }
     $module->execute();
     $text = '';
     // if action was successful and action was a Save, return
     if ($module->getStatus() === 200) {
         if ($module->getAction() === SFAutoeditAPI::ACTION_SAVE) {
             return;
         }
     } else {
         $resultData = $module->getResultData();
         if (array_key_exists('errors', $resultData)) {
             foreach ($resultData['errors'] as $error) {
                 // FIXME: This should probably not be hard-coded to WARNING but put into a setting
                 if ($error['level'] <= SFAutoeditAPI::WARNING) {
                     $text .= Html::rawElement('p', array('class' => 'error'), $error['message']) . "\n";
                 }
             }
         }
     }
     // Override the default title for this page if a title was
     // specified in the form.
     $result = $module->getOptions();
     $targetTitle = Title::newFromText($result['target']);
     // Set page title depending on whether an explicit title was
     // specified in the form definition.
     if (array_key_exists('formtitle', $result)) {
         // set page title depending on whether the target page exists
         if (empty($targetName)) {
             $pageTitle = $result['formtitle'];
         } else {
             $pageTitle = $result['formtitle'] . ': ' . $targetName;
         }
     } elseif ($result['form'] !== '') {
         // Set page title depending on whether the target page
         // exists.
         if (empty($targetName)) {
             $pageTitle = wfMessage('sf_formedit_createtitlenotarget', $result['form'])->text();
         } elseif ($targetTitle->exists()) {
             $pageTitle = wfMessage('sf_formedit_edittitle', $result['form'], $targetName)->text();
         } else {
             $pageTitle = wfMessage('sf_formedit_createtitle', $result['form'], $targetName)->text();
         }
     } elseif (count($alt_forms) > 0) {
         // We use the 'creating' message here, instead of
         // 'sf_formedit_createtitlenotarget', to differentiate
         // between a page with no (default) form, and one with
         // no target; in English they'll show up as
         // "Creating ..." and "Create ...", respectively.
         // Does this make any difference? Who knows.
         $pageTitle = wfMessage('creating', $targetName)->text();
     } elseif ($result['form'] == '') {
         //FIXME: This looks weird; a simple else should be enough, right?
         // display error message if the form is not specified in the URL
         $pageTitle = wfMessage('formedit')->text();
         $text .= Html::element('p', array('class' => 'error'), wfMessage('sf_formedit_badurl')->text()) . "\n";
         $out->addHTML($text);
     }
     $out->setPageTitle($pageTitle);
     if (count($alt_forms) > 0) {
         $text .= '<div class="infoMessage">';
         if ($result['form'] != '') {
             $text .= wfMessage('sf_formedit_altforms')->escaped();
         } else {
             $text .= wfMessage('sf_formedit_altformsonly')->escaped();
         }
         $text .= ' ' . $this->printAltFormsList($alt_forms, $targetName);
         $text .= "</div>\n";
     }
     $text .= '<form name="createbox" id="sfForm" method="post" class="createbox">';
     $pre_form_html = '';
     Hooks::run('sfHTMLBeforeForm', array(&$targetTitle, &$pre_form_html));
     $text .= $pre_form_html;
     if (isset($result['formHTML'])) {
         $text .= $result['formHTML'];
     }
     SFUtils::addFormRLModules();
     if (isset($result['formJS'])) {
         if (method_exists('ResourceLoader', 'makeInlineScript')) {
             // MW 1.25+
             $out->addScript(ResourceLoader::makeInlineScript($result['formJS']));
         } else {
             $out->addScript('		<script type="text/javascript">' . "\n{$result['formJS']}\n" . '</script>' . "\n");
         }
     }
     $out->addHTML($text);
     return null;
 }
コード例 #10
0
 private static function makeLegacyWarning($id)
 {
     $special = SpecialPage::getTitleFor('Gadgets');
     return ResourceLoader::makeInlineScript(Xml::encodeJsCall('mw.log.warn', array("Gadget \"{$id}\" was not loaded. Please migrate it to use ResourceLoader. " . ' See <' . $special->getCanonicalURL() . '>.')));
 }
コード例 #11
0
 /**
  * Explicily load or embed modules on a page.
  *
  * @param ResourceLoaderContext $mainContext
  * @param array $modules One or more module names
  * @param string $only ResourceLoaderModule TYPE_ class constant
  * @param array $extraQuery [optional] Array with extra query parameters for the request
  * @return string|WrappedStringList HTML
  */
 public static function makeLoad(ResourceLoaderContext $mainContext, array $modules, $only, array $extraQuery = [])
 {
     $rl = $mainContext->getResourceLoader();
     $chunks = [];
     if ($mainContext->getDebug() && count($modules) > 1) {
         $chunks = [];
         // Recursively call us for every item
         foreach ($modules as $name) {
             $chunks[] = self::makeLoad($mainContext, [$name], $only, $extraQuery);
         }
         return new WrappedStringList("\n", $chunks);
     }
     // Sort module names so requests are more uniform
     sort($modules);
     // Create keyed-by-source and then keyed-by-group list of module objects from modules list
     $sortedModules = [];
     foreach ($modules as $name) {
         $module = $rl->getModule($name);
         if (!$module) {
             $rl->getLogger()->warning('Unknown module "{module}"', ['module' => $name]);
             continue;
         }
         $sortedModules[$module->getSource()][$module->getGroup()][$name] = $module;
     }
     foreach ($sortedModules as $source => $groups) {
         foreach ($groups as $group => $grpModules) {
             $context = self::makeContext($mainContext, $group, $only, $extraQuery);
             $context->setModules(array_keys($grpModules));
             if ($group === 'private') {
                 // Decide whether to use style or script element
                 if ($only == ResourceLoaderModule::TYPE_STYLES) {
                     $chunks[] = Html::inlineStyle($rl->makeModuleResponse($context, $grpModules));
                 } else {
                     $chunks[] = ResourceLoader::makeInlineScript($rl->makeModuleResponse($context, $grpModules));
                 }
                 continue;
             }
             // See if we have one or more raw modules
             $isRaw = false;
             foreach ($grpModules as $key => $module) {
                 $isRaw |= $module->isRaw();
             }
             // 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 CDN-cached HTML
             if ($group === 'user') {
                 // Must setModules() before makeVersionQuery()
                 $context->setVersion($rl->makeVersionQuery($context));
             }
             $url = $rl->createLoaderURL($source, $context, $extraQuery);
             // Decide whether to use 'style' or 'script' element
             if ($only === ResourceLoaderModule::TYPE_STYLES) {
                 $chunk = Html::linkedStyle($url);
             } else {
                 if ($context->getRaw() || $isRaw) {
                     $chunk = Html::element('script', ['async' => !isset($extraQuery['sync']), 'src' => $url]);
                 } else {
                     $chunk = ResourceLoader::makeInlineScript(Xml::encodeJsCall('mw.loader.load', [$url]));
                 }
             }
             if ($group == 'noscript') {
                 $chunks[] = Html::rawElement('noscript', [], $chunk);
             } else {
                 $chunks[] = $chunk;
             }
         }
     }
     return new WrappedStringList("\n", $chunks);
 }