| 1 |
// phpcs:disable |
| 2 |
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */ |
| 3 |
(function(w){ |
| 4 |
"use strict"; |
| 5 |
/* exported loadCSS */ |
| 6 |
var loadCSS = function( href, before, media, attributes ){ |
| 7 |
// Arguments explained: |
| 8 |
// `href` [REQUIRED] is the URL for your CSS file. |
| 9 |
// `before` [OPTIONAL] is the element the script should use as a reference for injecting our stylesheet <link> before |
| 10 |
// By default, loadCSS attempts to inject the link after the last stylesheet or script in the DOM. However, you might desire a more specific location in your document. |
| 11 |
// `media` [OPTIONAL] is the media type or query of the stylesheet. By default it will be 'all' |
| 12 |
// `attributes` [OPTIONAL] is the Object of attribute name/attribute value pairs to set on the stylesheet's DOM Element. |
| 13 |
var doc = w.document; |
| 14 |
var ss = doc.createElement( "link" ); |
| 15 |
var ref; |
| 16 |
if( before ){ |
| 17 |
ref = before; |
| 18 |
} |
| 19 |
else { |
| 20 |
var refs = ( doc.body || doc.getElementsByTagName( "head" )[ 0 ] ).childNodes; |
| 21 |
ref = refs[ refs.length - 1]; |
| 22 |
} |
| 23 |
|
| 24 |
var sheets = doc.styleSheets; |
| 25 |
// Set any of the provided attributes to the stylesheet DOM Element. |
| 26 |
if( attributes ){ |
| 27 |
for( var attributeName in attributes ){ |
| 28 |
if( attributes.hasOwnProperty( attributeName ) ){ |
| 29 |
ss.setAttribute( attributeName, attributes[attributeName] ); |
| 30 |
} |
| 31 |
} |
| 32 |
} |
| 33 |
ss.rel = "stylesheet"; |
| 34 |
ss.href = href; |
| 35 |
// temporarily set media to something inapplicable to ensure it'll fetch without blocking render |
| 36 |
ss.media = "only x"; |
| 37 |
|
| 38 |
// wait until body is defined before injecting link. This ensures a non-blocking load in IE11. |
| 39 |
function ready( cb ){ |
| 40 |
if( doc.body ){ |
| 41 |
return cb(); |
| 42 |
} |
| 43 |
setTimeout(function(){ |
| 44 |
ready( cb ); |
| 45 |
}); |
| 46 |
} |
| 47 |
// Inject link |
| 48 |
// Note: the ternary preserves the existing behavior of "before" argument, but we could choose to change the argument to "after" in a later release and standardize on ref.nextSibling for all refs |
| 49 |
// Note: `insertBefore` is used instead of `appendChild`, for safety re: http://www.paulirish.com/2011/surefire-dom-element-insertion/ |
| 50 |
ready( function(){ |
| 51 |
ref.parentNode.insertBefore( ss, ( before ? ref : ref.nextSibling ) ); |
| 52 |
}); |
| 53 |
// A method (exposed on return object for external use) that mimics onload by polling document.styleSheets until it includes the new sheet. |
| 54 |
var onloadcssdefined = function( cb ){ |
| 55 |
var resolvedHref = ss.href; |
| 56 |
var i = sheets.length; |
| 57 |
while( i-- ){ |
| 58 |
if( sheets[ i ].href === resolvedHref ){ |
| 59 |
return cb(); |
| 60 |
} |
| 61 |
} |
| 62 |
setTimeout(function() { |
| 63 |
onloadcssdefined( cb ); |
| 64 |
}); |
| 65 |
}; |
| 66 |
|
| 67 |
function loadCB(){ |
| 68 |
if( ss.addEventListener ){ |
| 69 |
ss.removeEventListener( "load", loadCB ); |
| 70 |
} |
| 71 |
ss.media = media || "all"; |
| 72 |
} |
| 73 |
|
| 74 |
// once loaded, set link's media back to `all` so that the stylesheet applies once it loads |
| 75 |
if( ss.addEventListener ){ |
| 76 |
ss.addEventListener( "load", loadCB); |
| 77 |
} |
| 78 |
ss.onloadcssdefined = onloadcssdefined; |
| 79 |
onloadcssdefined( loadCB ); |
| 80 |
return ss; |
| 81 |
}; |
| 82 |
// commonjs |
| 83 |
if( typeof exports !== "undefined" ){ |
| 84 |
exports.loadCSS = loadCSS; |
| 85 |
} |
| 86 |
else { |
| 87 |
w.loadCSS = loadCSS; |
| 88 |
} |
| 89 |
}( typeof global !== "undefined" ? global : this )); |