/** @var bool */
protected static $debugMode = null;
+ /** @var array */
+ private static $lessVars = null;
+
/**
* Module name/ResourceLoaderModule object pairs
* @var array
*/
protected $errors = array();
+ /**
+ * @var MessageBlobStore
+ */
+ protected $blobStore;
+
/**
* Load information stored in the database about modules.
*
$this->registerTestModules();
}
+ $this->setMessageBlobStore( new MessageBlobStore() );
}
/**
return $this->config;
}
+ /**
+ * @param MessageBlobStore $blobStore
+ * @since 1.25
+ */
+ public function setMessageBlobStore( MessageBlobStore $blobStore ) {
+ $this->blobStore = $blobStore;
+ }
+
/**
* Register a module with the ResourceLoader system.
*
}
}
+ /**
+ * Check whether a ResourceLoader module is registered
+ *
+ * @since 1.25
+ * @param string $name
+ * @return bool
+ */
+ public function isModuleRegistered( $name ) {
+ return isset( $this->moduleInfos[$name] );
+ }
+
/**
* Get the ResourceLoaderModule object for a given module name.
*
$states = array();
if ( !count( $modules ) && !count( $missing ) ) {
- return "/* This file is the Web entry point for MediaWiki's ResourceLoader:
+ return <<<MESSAGE
+/* This file is the Web entry point for MediaWiki's ResourceLoader:
<https://www.mediawiki.org/wiki/ResourceLoader>. In this request,
- no modules were requested. Max made me put this here. */";
+ no modules were requested. Max made me put this here. */
+MESSAGE;
}
$image = $context->getImageObj();
// Pre-fetch blobs
if ( $context->shouldIncludeMessages() ) {
try {
- $blobs = MessageBlobStore::getInstance()->get( $this, $modules, $context->getLanguage() );
+ $blobs = $this->blobStore->get( $this, $modules, $context->getLanguage() );
} catch ( Exception $e ) {
MWExceptionHandler::logException( $e );
wfDebugLog(
} elseif ( !is_array( $scripts ) ) {
throw new MWException( 'Invalid scripts error. Array of URLs or string of code expected.' );
}
-
- return Xml::encodeJsCall(
- 'mw.loader.implement',
- array(
- $name,
- $scripts,
- // Force objects. mw.loader.implement requires them to be javascript objects.
- // Although these variables are associative arrays, which become javascript
- // objects through json_encode. In many cases they will be empty arrays, and
- // PHP/json_encode() consider empty arrays to be numerical arrays and
- // output javascript "[]" instead of "{}". This fixes that.
- (object)$styles,
- (object)$messages,
- (object)$templates,
- ),
- ResourceLoader::inDebugMode()
+ // mw.loader.implement requires 'styles', 'messages' and 'templates' to be objects (not
+ // arrays). json_encode considers empty arrays to be numerical and outputs "[]" instead
+ // of "{}". Force them to objects.
+ $module = array(
+ $name,
+ $scripts,
+ (object) $styles,
+ (object) $messages,
+ (object) $templates,
);
+ self::trimArray( $module );
+
+ return Xml::encodeJsCall( 'mw.loader.implement', $module, ResourceLoader::inDebugMode() );
}
/**
);
}
+ private static function isEmptyObject( stdClass $obj ) {
+ foreach ( $obj as $key => &$value ) {
+ return false;
+ }
+ return true;
+ }
+
/**
* Remove empty values from the end of an array.
*
* Values considered empty:
*
* - null
- * - empty array
+ * - array()
+ * - new XmlJsCode( '{}' )
+ * - new stdClass() // (object) array()
*
* @param Array $array
*/
private static function trimArray( Array &$array ) {
$i = count( $array );
while ( $i-- ) {
- if ( $array[$i] === null || $array[$i] === array() ) {
+ if ( $array[$i] === null
+ || $array[$i] === array()
+ || ( $array[$i] instanceof XmlJsCode && $array[$i]->value === '{}' )
+ || ( $array[$i] instanceof stdClass && self::isEmptyObject( $array[$i] ) )
+ ) {
unset( $array[$i] );
} else {
break;
* @return array Map of variable names to string CSS values.
*/
public static function getLessVars( Config $config ) {
- $lessVars = $config->get( 'ResourceLoaderLESSVars' );
- // Sort by key to ensure consistent hashing for cache lookups.
- ksort( $lessVars );
- return $lessVars;
+ if ( !self::$lessVars ) {
+ $lessVars = $config->get( 'ResourceLoaderLESSVars' );
+ Hooks::run( 'ResourceLoaderGetLessVars', array( &$lessVars ) );
+ // Sort by key to ensure consistent hashing for cache lookups.
+ ksort( $lessVars );
+ self::$lessVars = $lessVars;
+ }
+ return self::$lessVars;
}
}