コード例 #1
0
 /**
  * Get a string identifying the current version of this module in a given context.
  *
  * Whenever anything happens that changes the module's response (e.g. scripts, styles, and
  * messages) this value must change. This value is used to store module responses in cache.
  * (Both client-side and server-side.)
  *
  * It is not recommended to override this directly. Use getDefinitionSummary() instead.
  * If overridden, one must call the parent getVersionHash(), append data and re-hash.
  *
  * This method should be quick because it is frequently run by ResourceLoaderStartUpModule to
  * propagate changes to the client and effectively invalidate cache.
  *
  * For backward-compatibility, the following optional data providers are automatically included:
  *
  * - getModifiedTime()
  * - getModifiedHash()
  *
  * @since 1.26
  * @param ResourceLoaderContext $context
  * @return string Hash (should use ResourceLoader::makeHash)
  */
 public function getVersionHash(ResourceLoaderContext $context)
 {
     // The startup module produces a manifest with versions representing the entire module.
     // Typically, the request for the startup module itself has only=scripts. That must apply
     // only to the startup module content, and not to the module version computed here.
     $context = new DerivativeResourceLoaderContext($context);
     $context->setModules(array());
     // Version hash must cover all resources, regardless of startup request itself.
     $context->setOnly(null);
     // Compute version hash based on content, not debug urls.
     $context->setDebug(false);
     // Cache this somewhat expensive operation. Especially because some classes
     // (e.g. startup module) iterate more than once over all modules to get versions.
     $contextHash = $context->getHash();
     if (!array_key_exists($contextHash, $this->versionHash)) {
         if ($this->enableModuleContentVersion()) {
             // Detect changes directly
             $str = json_encode($this->getModuleContent($context));
         } else {
             // Infer changes based on definition and other metrics
             $summary = $this->getDefinitionSummary($context);
             if (!isset($summary['_cacheEpoch'])) {
                 throw new LogicException('getDefinitionSummary must call parent method');
             }
             $str = json_encode($summary);
             $mtime = $this->getModifiedTime($context);
             if ($mtime !== null) {
                 // Support: MediaWiki 1.25 and earlier
                 $str .= strval($mtime);
             }
             $mhash = $this->getModifiedHash($context);
             if ($mhash !== null) {
                 // Support: MediaWiki 1.25 and earlier
                 $str .= strval($mhash);
             }
         }
         $this->versionHash[$contextHash] = ResourceLoader::makeHash($str);
     }
     return $this->versionHash[$contextHash];
 }
コード例 #2
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;
 }
コード例 #3
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');
     $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;
         }
         $versionHash = $module->getVersionHash($context);
         if (strlen($versionHash) !== 8) {
             // 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, false);
         }
         $registryData[$name] = array('version' => $versionHash, 'dependencies' => $module->getDependencies($context), '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, $data['version'], $data['dependencies'], $data['group'], $data['source'], $data['loader']);
             continue;
         }
         // Call mw.loader.register(name, version, dependencies, group, source, skip)
         $registrations[] = array($name, $data['version'], $data['dependencies'], $data['group'], $data['source'] === 'local' ? null : $data['source'], $data['skip']);
     }
     // Register modules
     $out .= "\n" . ResourceLoader::makeLoaderRegisterScript($registrations);
     return $out;
 }