*
* @param string $script JavaScript code
* @param string $nonce [optional] Content-Security-Policy nonce (from OutputPage::getCSPNonce)
- * @return WrappedString HTML
+ * @return string|WrappedString HTML
*/
public static function makeInlineScript( $script, $nonce = null ) {
$js = self::makeLoaderConditionalScript( $script );
* Returns LESS compiler set up for use with MediaWiki
*
* @since 1.27
- * @param array $extraVars Associative array of extra (i.e., other than the
- * globally-configured ones) that should be used for compilation.
+ * @param array $vars Associative array of variables that should be used
+ * for compilation. Since 1.32, this method no longer automatically includes
+ * global LESS vars from ResourceLoader::getLessVars (T191937).
* @throws MWException
* @return Less_Parser
*/
- public function getLessCompiler( $extraVars = [] ) {
+ public function getLessCompiler( $vars = [] ) {
// When called from the installer, it is possible that a required PHP extension
// is missing (at least for now; see T49564). If this is the case, throw an
// exception (caught by the installer) to prevent a fatal error later on.
}
$parser = new Less_Parser;
- $parser->ModifyVars( array_merge( $this->getLessVars(), $extraVars ) );
+ $parser->ModifyVars( $vars );
$parser->SetImportDirs(
array_fill_keys( $this->config->get( 'ResourceLoaderLESSImportPaths' ), '' )
);
*/
public function testLessImportDirs() {
$rl = new EmptyResourceLoader();
- $lc = $rl->getLessCompiler();
+ $lc = $rl->getLessCompiler( $rl->getLessVars() );
$basePath = dirname( dirname( __DIR__ ) ) . '/data/less';
$lc->SetImportDirs( [
"$basePath/common" => '',
}
}
- protected function getFailFerryMock() {
+ protected function getFailFerryMock( $getter = 'getScript' ) {
$mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
- ->setMethods( [ 'getScript' ] )
+ ->setMethods( [ $getter ] )
->getMock();
- $mock->method( 'getScript' )->will( $this->throwException(
+ $mock->method( $getter )->will( $this->throwException(
new Exception( 'Ferry not found' )
) );
return $mock;
return $mock;
}
+ protected function getSimpleStyleModuleMock( $styles = '' ) {
+ $mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
+ ->setMethods( [ 'getStyles' ] )
+ ->getMock();
+ $mock->method( 'getStyles' )->willReturn( [ '' => $styles ] );
+ return $mock;
+ }
+
/**
* @covers ResourceLoader::getCombinedVersion
*/
);
}
+ /**
+ * Verify that exceptions in PHP for one module will not break others
+ * (stylesheet response).
+ *
+ * @covers ResourceLoader::makeModuleResponse
+ */
+ public function testMakeModuleResponseErrorCSS() {
+ $modules = [
+ 'foo' => self::getSimpleStyleModuleMock( '.foo{}' ),
+ 'ferry' => self::getFailFerryMock( 'getStyles' ),
+ 'bar' => self::getSimpleStyleModuleMock( '.bar{}' ),
+ ];
+ $rl = new EmptyResourceLoader();
+ $rl->register( $modules );
+ $context = $this->getResourceLoaderContext(
+ [
+ 'modules' => 'foo|ferry|bar',
+ 'only' => 'styles',
+ 'debug' => 'false',
+ ],
+ $rl
+ );
+
+ // Disable log from makeModuleResponse via outputErrorAndLog
+ $this->setLogger( 'exception', new Psr\Log\NullLogger() );
+
+ $response = $rl->makeModuleResponse( $context, $modules );
+ $errors = $rl->getErrors();
+
+ $this->assertCount( 2, $errors );
+ $this->assertRegExp( '/Ferry not found/', $errors[0] );
+ $this->assertRegExp( '/Problem.+\n\s*"ferry":\s*"error"/m', $errors[1] );
+ $this->assertEquals(
+ '.foo{}.bar{}',
+ $response
+ );
+ }
/**
* Verify that when building the startup module response,
* an exception from one module class will not break the entire