Index: trunk/phase3/resources/mediawiki/mediawiki.util.js |
— | — | @@ -149,23 +149,24 @@ |
150 | 150 | }, |
151 | 151 | |
152 | 152 | /** |
153 | | - * Append a new style block to the head |
| 153 | + * Append a new style block to the head and return the CSSStyleSheet object. |
| 154 | + * Use .ownerNode to access the <style> element, or use mw.loader.addStyleTag. |
| 155 | + * This function returns the styleSheet object for convience (due to cross-browsers |
| 156 | + * difference as to where it is located). |
| 157 | + * @example |
| 158 | + * <code> |
| 159 | + * var sheet = mw.util.addCSS('.foobar { display: none; }'); |
| 160 | + * $(foo).click(function () { |
| 161 | + * // Toggle the sheet on and off |
| 162 | + * sheet.disabled = !sheet.disabled; |
| 163 | + * }); |
| 164 | + * </code> |
154 | 165 | * |
155 | 166 | * @param text string CSS to be appended |
156 | | - * @return CSSStyleSheet |
| 167 | + * @return CSSStyleSheet (use .ownerNode to get to the <style> element) |
157 | 168 | */ |
158 | 169 | addCSS: function ( text ) { |
159 | | - var s = document.createElement( 'style' ); |
160 | | - s.type = 'text/css'; |
161 | | - s.rel = 'stylesheet'; |
162 | | - // Insert into document before setting cssText (bug 33305) |
163 | | - document.getElementsByTagName('head')[0].appendChild( s ); |
164 | | - if ( s.styleSheet ) { |
165 | | - s.styleSheet.cssText = text; // IE |
166 | | - } else { |
167 | | - // Safari sometimes borks on null |
168 | | - s.appendChild( document.createTextNode( String( text ) ) ); |
169 | | - } |
| 170 | + var s = mw.loader.addStyleTag( text ); |
170 | 171 | return s.sheet || s; |
171 | 172 | }, |
172 | 173 | |
Index: trunk/phase3/resources/mediawiki/mediawiki.js |
— | — | @@ -389,41 +389,57 @@ |
390 | 390 | return $marker; |
391 | 391 | } |
392 | 392 | } |
393 | | - |
| 393 | + |
| 394 | + /** |
| 395 | + * Create a new style tag and add it to the DOM. |
| 396 | + * |
| 397 | + * @param text String: CSS text |
| 398 | + * @param $nextnode mixed: [optional] An Element or jQuery object for an element where |
| 399 | + * the style tag should be inserted before. Otherwise appended to the <head>. |
| 400 | + * @return HTMLStyleElement |
| 401 | + */ |
| 402 | + function addStyleTag( text, $nextnode ) { |
| 403 | + var s = document.createElement( 'style' ); |
| 404 | + s.type = 'text/css'; |
| 405 | + s.rel = 'stylesheet'; |
| 406 | + // Insert into document before setting cssText (bug 33305) |
| 407 | + if ( $nextnode ) { |
| 408 | + // If a raw element, create a jQuery object, otherwise use directly |
| 409 | + if ( $nextnode.nodeType ) { |
| 410 | + $nextnode = $( $nextnode ); |
| 411 | + } |
| 412 | + $nextnode.before( s ); |
| 413 | + } else { |
| 414 | + document.getElementsByTagName('head')[0].appendChild( s ); |
| 415 | + } |
| 416 | + if ( s.styleSheet ) { |
| 417 | + s.styleSheet.cssText = text; // IE |
| 418 | + } else { |
| 419 | + // Safari sometimes borks on null |
| 420 | + s.appendChild( document.createTextNode( String( text ) ) ); |
| 421 | + } |
| 422 | + return s; |
| 423 | + } |
| 424 | + |
394 | 425 | function addInlineCSS( css, media ) { |
395 | | - var $style = getMarker().prev(), |
396 | | - $newStyle, |
397 | | - attrs = { 'type': 'text/css', 'media': media }; |
| 426 | + var $style, style, $newStyle; |
| 427 | + $style = getMarker().prev(); |
398 | 428 | if ( $style.is( 'style' ) && $style.data( 'ResourceLoaderDynamicStyleTag' ) === true ) { |
399 | | - // There's already a dynamic <style> tag present, append to it |
400 | | - // This recycling of <style> tags is for bug 31676 (can't have |
401 | | - // more than 32 <style> tags in IE) |
402 | | - |
403 | | - // Also, calling .append() on a <style> tag explodes with a JS error in IE, |
404 | | - // so if the .append() fails we fall back to building a new <style> tag and |
405 | | - // replacing the existing one |
406 | | - try { |
407 | | - // Do cdata sanitization on the provided CSS, and prepend a double newline |
408 | | - css = $( mw.html.element( 'style', {}, new mw.html.Cdata( "\n\n" + css ) ) ).html(); |
409 | | - $style.append( css ); |
410 | | - } catch ( e ) { |
411 | | - // Generate a new tag with the combined CSS |
412 | | - css = $style.html() + "\n\n" + css; |
413 | | - $newStyle = $( mw.html.element( 'style', attrs, new mw.html.Cdata( css ) ) ) |
414 | | - .data( 'ResourceLoaderDynamicStyleTag', true ); |
415 | | - // Prevent a flash of unstyled content by inserting the new tag |
416 | | - // before removing the old one |
417 | | - $style.after( $newStyle ); |
418 | | - $style.remove(); |
| 429 | + // There's already a dynamic <style> tag present, append to it. This recycling of |
| 430 | + // <style> tags is for bug 31676 (can't have more than 32 <style> tags in IE) |
| 431 | + style = $style.get( 0 ); |
| 432 | + if ( style.styleSheet ) { |
| 433 | + style.styleSheet.cssText += css; // IE |
| 434 | + } else { |
| 435 | + style.appendChild( document.createTextNode( String( css ) ) ); |
419 | 436 | } |
420 | 437 | } else { |
421 | | - // Create a new <style> tag and insert it |
422 | | - $style = $( mw.html.element( 'style', attrs, new mw.html.Cdata( css ) ) ); |
423 | | - $style.data( 'ResourceLoaderDynamicStyleTag', true ); |
424 | | - getMarker().before( $style ); |
| 438 | + $newStyle = $( addStyleTag( css, getMarker() ) ) |
| 439 | + .attr( 'media', media ) |
| 440 | + .data( 'ResourceLoaderDynamicStyleTag', true ); |
425 | 441 | } |
426 | 442 | } |
427 | | - |
| 443 | + |
428 | 444 | function compare( a, b ) { |
429 | 445 | var i; |
430 | 446 | if ( a.length !== b.length ) { |
— | — | @@ -874,6 +890,8 @@ |
875 | 891 | |
876 | 892 | /* Public Methods */ |
877 | 893 | return { |
| 894 | + addStyleTag: addStyleTag, |
| 895 | + |
878 | 896 | /** |
879 | 897 | * Requests dependencies from server, loading and executing when things when ready. |
880 | 898 | */ |