Anomie has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/347444 )
Change subject: Deduplicate embedded style rules
......................................................................
Deduplicate embedded style rules
Use the facility added in core to deduplicate the embedded style rules.
Change-Id: I512c3c27d3689a8163595e204e740779448ceead
Depends-On: I088acfd1e461be6204d1fc62b85a0eb2b8d49be7
---
M TemplateStylesHooks.php
A TemplateStylesResourceLoaderModule.php
M extension.json
M i18n/en.json
M i18n/qqq.json
5 files changed, 147 insertions(+), 38 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/TemplateStyles
refs/changes/44/347444/1
diff --git a/TemplateStylesHooks.php b/TemplateStylesHooks.php
index 8e563c0..6658b9e 100644
--- a/TemplateStylesHooks.php
+++ b/TemplateStylesHooks.php
@@ -234,41 +234,9 @@
'</strong>';
}
- // For the moment just output the styles inline.
- // @todo: If T160563 happens, it would be good to convert this
to use that.
-
- $status = $content->sanitize( [
- 'flip' => $parser->getTargetLanguage()->getDir() !==
$wgContLang->getDir(),
- 'minify' => !ResourceLoader::inDebugMode(),
- ] );
- $style = $status->isOk() ? $status->getValue() : '/* Fatal
error, no CSS will be output */';
-
- // Prepend errors. This should normally never happen, but might
if an
- // update or configuration change causes something that was
formerly
- // valid to become invalid.
- if ( !$status->isGood() ) {
- $comment = wfMessage(
- 'templatestyles-errorcomment',
- $title->getPrefixedText(),
- $rev->getId(),
- $status->getWikiText( null, 'rawmessage' )
- )->text();
- $comment = trim( strtr( $comment, [
- // Use some lookalike unicode characters to
avoid things that might
- // otherwise confuse browsers.
- '*' => '•', '-' => '‐', '<' => '⧼', '>' => '⧽',
- ] ) );
- $style = "/*\n$comment\n*/\n$style";
- }
-
- // Hide the CSS from Parser::doBlockLevels
- $marker = Parser::MARKER_PREFIX . '-templatestyles-' .
- sprintf( '%08X', $parser->mMarkerIndex++ ) .
Parser::MARKER_SUFFIX;
- $parser->mStripState->addNoWiki( $marker, $style );
-
- // Return the inline <style>, which the Parser will wrap in a
'general'
- // strip marker.
- return Html::inlineStyle( $marker );
+ return $parser->getEmbeddedStyleModuleStripItem(
+
TemplateStylesResourceLoaderModule::moduleNameForRevision( $rev )
+ );
}
}
diff --git a/TemplateStylesResourceLoaderModule.php
b/TemplateStylesResourceLoaderModule.php
new file mode 100644
index 0000000..fb9243a
--- /dev/null
+++ b/TemplateStylesResourceLoaderModule.php
@@ -0,0 +1,132 @@
+<?php
+
+/**
+ * @file
+ * @license https://opensource.org/licenses/GPL-2.0 GPL-2.0+
+ */
+
+use Wikimedia\CSS\Objects\QualifiedRule;
+use Wikimedia\CSS\Objects\Token;
+
+class TemplateStylesResourceLoaderModule extends ResourceLoaderModule {
+
+ /** @var Content[] */
+ protected static $tempContent = [];
+
+ /**
+ * Get the module name for a Revision
+ * @param Revision $rev
+ * @return string|null
+ */
+ public static function moduleNameForRevision( Revision $rev ) {
+ if ( $rev->getId() ) {
+ return 'ext.templatestyles.rev.' . $rev->getId();
+ }
+
+ $content = $rev->getContent();
+ if ( $content ) {
+ $id = substr( sha1( $content->serialize() ), 0, 32 );
+ self::$tempContent[$id] = $content;
+ return 'ext.templatestyles.temp.' . $id;
+ }
+
+ return null;
+ }
+
+ public function getGroup() {
+ return $this->supportsURLLoading() ? 'templatestyles' :
'private';
+ }
+
+ public function shouldEmbedModule( ResourceLoaderContext $context ) {
+ return true;
+ }
+
+ /**
+ * Get the stylesheet text
+ * @param ResourceLoaderContext $context
+ * @return string
+ */
+ public function getStylesheet( ResourceLoaderContext $context ) {
+ $name = $this->getName();
+ if ( preg_match( '/^ext\.templatestyles\.rev\.(\d+)$/', $name,
$m ) ) {
+ $rev = Revision::newFromId( $m[1] );
+ $content = $rev ? $rev->getContent() : null;
+ } elseif ( preg_match(
'/^ext\.templatestyles\.temp\.([0-9a-f]+)$/', $name, $m ) ) {
+ if ( !isset( self::$tempContent[$m[1]] ) ) {
+ throw new UnexpectedValueException( "Hash
{$m[1]} is not set" );
+ }
+ $content = self::$tempContent[$m[1]];
+ } else {
+ throw new UnexpectedValueException( 'Invalid module
name' );
+ }
+
+ if ( !$content instanceof TemplateStylesContent ) {
+ throw new UnexpectedValueException( 'Not a
TemplateStylesContent' );
+ }
+
+ $status = $content->sanitize( [
+ 'flip' => $this->getFlip( $context ),
+ 'minify' => !$context->getDebug(),
+ ] );
+ $style = $status->isOk() ? $status->getValue() : '';
+
+ // Prepend errors. This should normally never happen, but might
if an
+ // update or configuration change causes something that was
formerly
+ // valid to become invalid.
+ if ( !$status->isGood() ) {
+ // ResourceLoader strongly insists on eating comments,
so output
+ // the errors as a content rule for a dummy
pseudoelement instead.
+ $rule = new QualifiedRule();
+ $rule->getPrelude()->add( [
+ new Token( Token::T_COLON ),
+ new Token( Token::T_COLON ),
+ new Token( Token::T_IDENT, '-mw-errors' ),
+ new Token( Token::T_WHITESPACE ),
+ ] );
+ $value = $rule->getBlock()->getValue();
+ $value->add( [
+ new Token( Token::T_IDENT, 'content' ),
+ new Token( Token::T_COLON ),
+ new Token( Token::T_WHITESPACE ),
+ new Token( Token::T_STRING, $context->msg(
'templatestyles-rl-module-errors' )->text() ),
+ ] );
+ foreach ( $status->getErrors() as $error ) {
+ $value->add( [
+ new Token( Token::T_WHITESPACE ),
+ new Token( Token::T_STRING,
+ $context->msg( array_merge( [
$error['message'] ], $error['params'] ) )->text()
+ )
+ ] );
+ }
+ $value->add( new Token( Token::T_SEMICOLON ) );
+
+ $style = $rule->__toString() . "\n" . $style;
+ }
+
+ return $style;
+ }
+
+ public function getStyles( ResourceLoaderContext $context ) {
+ $style = $this->getStylesheet( $context );
+
+ // If css-sanitizer used comments to separate tokens, RL's use
of
+ // CSSMin is going to screw it up. Turn them into spaces.
+ $style = str_replace( '/**/', ' ', $style );
+
+ return [
+ 'all' => [ $style ],
+ ];
+ }
+
+ public function supportsURLLoading() {
+ return substr( $this->getName(), 0, 23 ) ===
'ext.templatestyles.rev.';
+ }
+
+ public function enableModuleContentVersion() {
+ return false;
+ }
+
+ public function getType() {
+ return self::LOAD_STYLES;
+ }
+}
diff --git a/extension.json b/extension.json
index 1708579..e5c438a 100644
--- a/extension.json
+++ b/extension.json
@@ -21,11 +21,20 @@
"TemplateStylesContentHandler":
"TemplateStylesContentHandler.php",
"TemplateStylesContent": "TemplateStylesContent.php",
"TemplateStylesHooks": "TemplateStylesHooks.php",
- "TemplateStylesMatcherFactory":
"TemplateStylesMatcherFactory.php"
+ "TemplateStylesMatcherFactory":
"TemplateStylesMatcherFactory.php",
+ "TemplateStylesResourceLoaderModule":
"TemplateStylesResourceLoaderModule.php"
},
"ContentHandlers": {
"sanitized-css": "TemplateStylesContentHandler"
},
+ "ResourceModules": {
+ "ext.templatestyles.rev.*": {
+ "class": "TemplateStylesResourceLoaderModule"
+ },
+ "ext.templatestyles.temp.*": {
+ "class": "TemplateStylesResourceLoaderModule"
+ }
+ },
"SyntaxHighlightModels": {
"sanitized-css": "css"
},
diff --git a/i18n/en.json b/i18n/en.json
index f02d2d1..a882151 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -11,8 +11,8 @@
"templatestyles-invalid-src": "Invalid title for TemplateStyles
<code>src</code>.",
"templatestyles-bad-src-missing": "Page [[:$1|$2]] has no content.",
"templatestyles-bad-src": "Page [[:$1|$2]] must have content model
\"{{int:content-model-sanitized-css}}\" for TemplateStyles (current model is
\"$3\").",
- "templatestyles-errorcomment": "Errors processing stylesheet [[:$1]]
(rev $2):\n$3",
"templatestyles-size-exceeded": "The stylesheet is larger than the
maximum size of $2.",
+ "templatestyles-rl-module-errors": "Errors encountered while processing
stylesheet:",
"content-model-sanitized-css": "Sanitized CSS",
"templatestyles-error-at-rule-block-not-allowed": "Block not allowed
for <code>@$3</code> at line $1 character $2.",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index a6d999c..c6ee709 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -11,7 +11,7 @@
"templatestyles-invalid-src": "Error message displayed when the
<code>src</code> attribute is not a valid title.",
"templatestyles-bad-src-missing": "Error message displayed when the
title specified has no content. Parameters:\n* $1 - The title specified.\n* $2
- The title with wikitext escaped.",
"templatestyles-bad-src": "Error message displayed when the title
specified is not a usable stylesheet. Parameters:\n* $1 - The title
specified.\n* $2 - The title with wikitext escaped.\n* $3 - Current content
model of the page in question.",
- "templatestyles-errorcomment": "Formatting for the comment used to
display TemplateStyles errors encountered during the parse. Parameters:\n* $1 -
Source stylesheet.\n* $2 - Revision of the stylesheet.* $3 - Errors.",
+ "templatestyles-rl-module-errors": "Error message when the
ResourceLoader module encounters errors during the parse.",
"templatestyles-size-exceeded": "Error returned when the stylesheet is
more than $wgTemplateStylesMaxStylesheetSize bytes. Parameters:\n* $1 - Maximum
size in bytes\n* $2 - Maximum size in \"human units\" (i.e. KB, MB, GB, etc).",
"content-model-sanitized-css": "Name for TemplateStyles sanitized-css
content model.",
--
To view, visit https://gerrit.wikimedia.org/r/347444
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I512c3c27d3689a8163595e204e740779448ceead
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/TemplateStyles
Gerrit-Branch: master
Gerrit-Owner: Anomie <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits