コード例 #1
0
 /**
  * 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)
 {
     $resourceLoader = $context->getResourceLoader();
     $target = $context->getRequest()->getVal('target', 'desktop');
     // Bypass target filter if this request is Special:JavaScriptTest.
     // To prevent misuse in production, this is only allowed if testing is enabled server-side.
     $byPassTargetFilter = $this->getConfig()->get('EnableJavaScriptTest') && $target === 'test';
     $out = '';
     $registryData = [];
     // Get registry data
     foreach ($resourceLoader->getModuleNames() as $name) {
         $module = $resourceLoader->getModule($name);
         $moduleTargets = $module->getTargets();
         if (!$byPassTargetFilter && !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;
         }
         $versionHash = $module->getVersionHash($context);
         if (strlen($versionHash) !== 8) {
             $context->getLogger()->warning("Module '{module}' produced an invalid version hash: '{version}'.", ['module' => $name, 'version' => $versionHash]);
             // Module implementation either broken or deviated from ResourceLoader::makeHash
             // Asserted by tests/phpunit/structure/ResourcesTest.
             $versionHash = ResourceLoader::makeHash($versionHash);
         }
         $skipFunction = $module->getSkipFunction();
         if ($skipFunction !== null && !ResourceLoader::inDebugMode()) {
             $skipFunction = ResourceLoader::filter('minify-js', $skipFunction);
         }
         $registryData[$name] = ['version' => $versionHash, 'dependencies' => $module->getDependencies($context), 'group' => $module->getGroup(), 'source' => $module->getSource(), 'skip' => $skipFunction];
     }
     self::compileUnresolvedDependencies($registryData);
     // Register sources
     $out .= ResourceLoader::makeLoaderSourcesScript($resourceLoader->getSources());
     // Figure out the different call signatures for mw.loader.register
     $registrations = [];
     foreach ($registryData as $name => $data) {
         // Call mw.loader.register(name, version, dependencies, group, source, skip)
         $registrations[] = [$name, $data['version'], $data['dependencies'], $data['group'], $data['source'] === 'local' ? null : $data['source'], $data['skip']];
     }
     // Register modules
     $out .= "\n" . ResourceLoader::makeLoaderRegisterScript($registrations);
     return $out;
 }
コード例 #2
0
 /**
  * Bundle all resources attached to this module into an array.
  *
  * @since 1.26
  * @param ResourceLoaderContext $context
  * @return array
  */
 protected final function buildContent(ResourceLoaderContext $context)
 {
     $rl = $context->getResourceLoader();
     $stats = RequestContext::getMain()->getStats();
     $statStart = microtime(true);
     // Only include properties that are relevant to this context (e.g. only=scripts)
     // and that are non-empty (e.g. don't include "templates" for modules without
     // templates). This helps prevent invalidating cache for all modules when new
     // optional properties are introduced.
     $content = array();
     // Scripts
     if ($context->shouldIncludeScripts()) {
         // If we are in debug mode, we'll want to return an array of URLs if possible
         // However, we can't do this if the module doesn't support it
         // We also can't do this if there is an only= parameter, because we have to give
         // the module a way to return a load.php URL without causing an infinite loop
         if ($context->getDebug() && !$context->getOnly() && $this->supportsURLLoading()) {
             $scripts = $this->getScriptURLsForDebug($context);
         } else {
             $scripts = $this->getScript($context);
             // rtrim() because there are usually a few line breaks
             // after the last ';'. A new line at EOF, a new line
             // added by ResourceLoaderFileModule::readScriptFiles, etc.
             if (is_string($scripts) && strlen($scripts) && substr(rtrim($scripts), -1) !== ';') {
                 // Append semicolon to prevent weird bugs caused by files not
                 // terminating their statements right (bug 27054)
                 $scripts .= ";\n";
             }
         }
         $content['scripts'] = $scripts;
     }
     // Styles
     if ($context->shouldIncludeStyles()) {
         $styles = array();
         // Don't create empty stylesheets like array( '' => '' ) for modules
         // that don't *have* any stylesheets (bug 38024).
         $stylePairs = $this->getStyles($context);
         if (count($stylePairs)) {
             // If we are in debug mode without &only= set, we'll want to return an array of URLs
             // See comment near shouldIncludeScripts() for more details
             if ($context->getDebug() && !$context->getOnly() && $this->supportsURLLoading()) {
                 $styles = array('url' => $this->getStyleURLsForDebug($context));
             } else {
                 // Minify CSS before embedding in mw.loader.implement call
                 // (unless in debug mode)
                 if (!$context->getDebug()) {
                     foreach ($stylePairs as $media => $style) {
                         // Can be either a string or an array of strings.
                         if (is_array($style)) {
                             $stylePairs[$media] = array();
                             foreach ($style as $cssText) {
                                 if (is_string($cssText)) {
                                     $stylePairs[$media][] = ResourceLoader::filter('minify-css', $cssText);
                                 }
                             }
                         } elseif (is_string($style)) {
                             $stylePairs[$media] = ResourceLoader::filter('minify-css', $style);
                         }
                     }
                 }
                 // Wrap styles into @media groups as needed and flatten into a numerical array
                 $styles = array('css' => $rl->makeCombinedStyles($stylePairs));
             }
         }
         $content['styles'] = $styles;
     }
     // Messages
     $blobs = $rl->getMessageBlobStore()->get($rl, array($this->getName() => $this), $context->getLanguage());
     if (isset($blobs[$this->getName()])) {
         $content['messagesBlob'] = $blobs[$this->getName()];
     }
     $templates = $this->getTemplates();
     if ($templates) {
         $content['templates'] = $templates;
     }
     $statTiming = microtime(true) - $statStart;
     $statName = strtr($this->getName(), '.', '_');
     $stats->timing("resourceloader_build.all", 1000 * $statTiming);
     $stats->timing("resourceloader_build.{$statName}", 1000 * $statTiming);
     return $content;
 }