r110988 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r110987‎ | r110988 | r110989 >
Date:00:10, 9 February 2012
Author:catrope
Status:fixme (Comments)
Tags:
Comment:
(bug 31676) Group dynamically inserted CSS into a single <style> tag, because IE limits the number of styles it'll apply to 32 (seriously?!?). 3rd party users were complaining about IE not applying some modules' CSS when many modules were loaded; this wasn't a problem on WMF wikis as far as I know
Modified paths:
  • /trunk/phase3/RELEASE-NOTES-1.19 (modified) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.js (modified) (history)

Diff [purge]

Index: trunk/phase3/resources/mediawiki/mediawiki.js
@@ -375,7 +375,7 @@
376376
377377 /* Private methods */
378378
379 - function getMarker(){
 379+ function getMarker() {
380380 // Cached ?
381381 if ( $marker ) {
382382 return $marker;
@@ -389,6 +389,27 @@
390390 return $marker;
391391 }
392392 }
 393+
 394+ function addInlineCSS( css, media ) {
 395+ var $style = getMarker().prev();
 396+ if ( $style.is( 'style' ) && $style.data( 'ResourceLoaderDynamicStyleTag' ) === true ) {
 397+ // There's already a dynamic <style> tag present, append to it
 398+ // This recycling of <style> tags is for bug 31676 (can't have
 399+ // more than 32 <style> tags in IE)
 400+
 401+ // Do cdata sanitization on the provided CSS, and prepend a double newline
 402+ css = $( mw.html.element( 'style', {}, new mw.html.Cdata( "\n\n" + css ) ) ).html();
 403+ $style.append( css );
 404+ } else {
 405+ // Create a new <style> tag and insert it
 406+ $style = $( mw.html.element( 'style', {
 407+ 'type': 'text/css',
 408+ 'media': media
 409+ }, new mw.html.Cdata( css ) ) );
 410+ $style.data( 'ResourceLoaderDynamicStyleTag', true );
 411+ getMarker().before( $style );
 412+ }
 413+ }
393414
394415 function compare( a, b ) {
395416 var i;
@@ -686,10 +707,7 @@
687708 } ) );
688709 }
689710 } else if ( typeof style === 'string' ) {
690 - getMarker().before( mw.html.element( 'style', {
691 - 'type': 'text/css',
692 - 'media': media
693 - }, new mw.html.Cdata( style ) ) );
 711+ addInlineCSS( style, media );
694712 }
695713 }
696714 }
Index: trunk/phase3/RELEASE-NOTES-1.19
@@ -245,6 +245,8 @@
246246 * It is now possible to delete images that have no corresponding description pages.
247247 * (bug 33165) GlobalFunctions.php line 1312: Call to a member function
248248 getText() on a non-object
 249+* (bug 31676) Group dynamically inserted CSS into a single <style> tag, to work
 250+ around a bug where not all styles were applied in Internet Explorer
249251
250252 === API changes in 1.19 ===
251253 * Made action=edit less likely to return "unknownerror", by returning the actual error

Sign-offs

UserFlagDate
Nikerabbitinspected07:22, 9 February 2012

Follow-up revisions

RevisionCommit summaryAuthorDate
r111067Followup r110988: IE8 throws JS errors if you try to call .append() on a <sty...catrope19:02, 9 February 2012
r112368[JSTesting] Add more mw.loader tests...krinkle23:13, 24 February 2012
r112370[mw.loader] Refactor addInlineCSS's logic, fixing various bugs...krinkle23:22, 24 February 2012
r112371[mw.loader] Remove 'media' type support in addInlineCSS...krinkle23:32, 24 February 2012

Comments

#Comment by Krinkle (talk | contribs)   00:33, 24 February 2012

Marking fixme for needing to:

  • check media attribute in the .is() check. You'll need a style tag for each media type
  • account for bug 33305 (was fixed in mw.util.addCSS, should use that as base function perhaps)
  • @import doesn't work when not on top of a stylesheet
#Comment by Krinkle (talk | contribs)   01:40, 24 February 2012

Also, aside from checking the media-attribute. Just checking it isn't enough. Doing so would still create various style-tags when there are different media-types used.

it's using getMarker().prev() as attempt to get the "right" one. If it's right, use it. If not, create one. But if there are more than 2 style tags in use, it would have to look back further.

Aside from that, separating by media-type and concatenating them into one tag don't play well together since media-types are not exclusive. For example "all" includes "screen". Taking the following as use case:

  • module A (media type: screen)
  • module B (media type: print)
  • module B (media type: all)
  • module C (media type: screen)

The 'screen' style would be appended to the earlier created and recycled "screen" media type style tag, thus messing with the cascading order (A:screen > C:screen > B:all, instead of A:screen > B:all, C:screen)

While discussing this on IRC, we came up with an easy work around though. ResourceLoader is already taking care of this by wrapping code in @media-type groups. The only media type that ever makes it to implement() is "all". We can drop this check.

#Comment by Krinkle (talk | contribs)   23:24, 24 February 2012

r112370 fixes accountiong for bug 33305. It also improves IE performance by using appending there as well. appending to cssText works in IE. The try-catch and fallback to re-creation of the style tag for each module is now removed and no longer needed gladly.

  • media attribute: Still an issue, although it appears (see comment above) that we can factor this out entirely. Will do soon.
  • @import: Still an issue
#Comment by Krinkle (talk | contribs)   23:33, 24 February 2012

r112371 takes care of the media attribute. This leaves us with @import ..

Status & tagging log