aboutsummaryrefslogtreecommitdiffstats
path: root/resources/mediawiki
diff options
context:
space:
mode:
authorKrinkle <krinkle@users.mediawiki.org>2012-02-24 23:22:30 +0000
committerKrinkle <krinkle@users.mediawiki.org>2012-02-24 23:22:30 +0000
commit57dda2b95e0997165dcc6eba83e5aa101bd10b51 (patch)
tree31b334896d029eba81386be88be5da966fe53dee /resources/mediawiki
parent829e60f1bd6ff30e7e863bcaa851a1f52508bea3 (diff)
downloadmediawikicore-57dda2b95e0997165dcc6eba83e5aa101bd10b51.tar.gz
mediawikicore-57dda2b95e0997165dcc6eba83e5aa101bd10b51.zip
[mw.loader] Refactor addInlineCSS's logic, fixing various bugs
* Using mw.util.addCSS as base to instance of bug 33305 automatically * Expose as mw.loader.addStyleTag * Re-use the code in mw.util.addCSS * Drop the "text > Cdata > element > jQuery object > innerHTML", in favor of setting cssText or appending a text node (html escapement isn't a problem when working with text nodes directly). * Appending this way also works in IE, no need for the dispose/re-create style-tag logic in the try-catch(). * Follows-up r110988 (fixme)
Notes
Notes: http://mediawiki.org/wiki/Special:Code/MediaWiki/112370
Diffstat (limited to 'resources/mediawiki')
-rw-r--r--resources/mediawiki/mediawiki.js76
-rw-r--r--resources/mediawiki/mediawiki.util.js27
2 files changed, 61 insertions, 42 deletions
diff --git a/resources/mediawiki/mediawiki.js b/resources/mediawiki/mediawiki.js
index 2ed894e19bed..c0e2fdd4e145 100644
--- a/resources/mediawiki/mediawiki.js
+++ b/resources/mediawiki/mediawiki.js
@@ -389,41 +389,57 @@ var mw = ( function ( $, undefined ) {
return $marker;
}
}
-
+
+ /**
+ * Create a new style tag and add it to the DOM.
+ *
+ * @param text String: CSS text
+ * @param $nextnode mixed: [optional] An Element or jQuery object for an element where
+ * the style tag should be inserted before. Otherwise appended to the <head>.
+ * @return HTMLStyleElement
+ */
+ function addStyleTag( text, $nextnode ) {
+ var s = document.createElement( 'style' );
+ s.type = 'text/css';
+ s.rel = 'stylesheet';
+ // Insert into document before setting cssText (bug 33305)
+ if ( $nextnode ) {
+ // If a raw element, create a jQuery object, otherwise use directly
+ if ( $nextnode.nodeType ) {
+ $nextnode = $( $nextnode );
+ }
+ $nextnode.before( s );
+ } else {
+ document.getElementsByTagName('head')[0].appendChild( s );
+ }
+ if ( s.styleSheet ) {
+ s.styleSheet.cssText = text; // IE
+ } else {
+ // Safari sometimes borks on null
+ s.appendChild( document.createTextNode( String( text ) ) );
+ }
+ return s;
+ }
+
function addInlineCSS( css, media ) {
- var $style = getMarker().prev(),
- $newStyle,
- attrs = { 'type': 'text/css', 'media': media };
+ var $style, style, $newStyle;
+ $style = getMarker().prev();
if ( $style.is( 'style' ) && $style.data( 'ResourceLoaderDynamicStyleTag' ) === true ) {
- // There's already a dynamic <style> tag present, append to it
- // This recycling of <style> tags is for bug 31676 (can't have
- // more than 32 <style> tags in IE)
-
- // Also, calling .append() on a <style> tag explodes with a JS error in IE,
- // so if the .append() fails we fall back to building a new <style> tag and
- // replacing the existing one
- try {
- // Do cdata sanitization on the provided CSS, and prepend a double newline
- css = $( mw.html.element( 'style', {}, new mw.html.Cdata( "\n\n" + css ) ) ).html();
- $style.append( css );
- } catch ( e ) {
- // Generate a new tag with the combined CSS
- css = $style.html() + "\n\n" + css;
- $newStyle = $( mw.html.element( 'style', attrs, new mw.html.Cdata( css ) ) )
- .data( 'ResourceLoaderDynamicStyleTag', true );
- // Prevent a flash of unstyled content by inserting the new tag
- // before removing the old one
- $style.after( $newStyle );
- $style.remove();
+ // There's already a dynamic <style> tag present, append to it. This recycling of
+ // <style> tags is for bug 31676 (can't have more than 32 <style> tags in IE)
+ style = $style.get( 0 );
+ if ( style.styleSheet ) {
+ style.styleSheet.cssText += css; // IE
+ } else {
+ style.appendChild( document.createTextNode( String( css ) ) );
}
} else {
- // Create a new <style> tag and insert it
- $style = $( mw.html.element( 'style', attrs, new mw.html.Cdata( css ) ) );
- $style.data( 'ResourceLoaderDynamicStyleTag', true );
- getMarker().before( $style );
+ $newStyle = $( addStyleTag( css, getMarker() ) )
+ .attr( 'media', media )
+ .data( 'ResourceLoaderDynamicStyleTag', true );
}
}
-
+
function compare( a, b ) {
var i;
if ( a.length !== b.length ) {
@@ -874,6 +890,8 @@ var mw = ( function ( $, undefined ) {
/* Public Methods */
return {
+ addStyleTag: addStyleTag,
+
/**
* Requests dependencies from server, loading and executing when things when ready.
*/
diff --git a/resources/mediawiki/mediawiki.util.js b/resources/mediawiki/mediawiki.util.js
index 277b19457cfb..6edbe5d1d7b8 100644
--- a/resources/mediawiki/mediawiki.util.js
+++ b/resources/mediawiki/mediawiki.util.js
@@ -149,23 +149,24 @@
},
/**
- * Append a new style block to the head
+ * Append a new style block to the head and return the CSSStyleSheet object.
+ * Use .ownerNode to access the <style> element, or use mw.loader.addStyleTag.
+ * This function returns the styleSheet object for convience (due to cross-browsers
+ * difference as to where it is located).
+ * @example
+ * <code>
+ * var sheet = mw.util.addCSS('.foobar { display: none; }');
+ * $(foo).click(function () {
+ * // Toggle the sheet on and off
+ * sheet.disabled = !sheet.disabled;
+ * });
+ * </code>
*
* @param text string CSS to be appended
- * @return CSSStyleSheet
+ * @return CSSStyleSheet (use .ownerNode to get to the <style> element)
*/
addCSS: function ( text ) {
- var s = document.createElement( 'style' );
- s.type = 'text/css';
- s.rel = 'stylesheet';
- // Insert into document before setting cssText (bug 33305)
- document.getElementsByTagName('head')[0].appendChild( s );
- if ( s.styleSheet ) {
- s.styleSheet.cssText = text; // IE
- } else {
- // Safari sometimes borks on null
- s.appendChild( document.createTextNode( String( text ) ) );
- }
+ var s = mw.loader.addStyleTag( text );
return s.sheet || s;
},