|
|
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
- */
-
- var stylesInDom = {};
-
- var memoize = function (fn) {
- var memo;
-
- return function () {
- if (typeof memo === "undefined") memo = fn.apply(this, arguments);
- return memo;
- };
- };
-
- var isOldIE = memoize(function () {
- // Test for IE <= 9 as proposed by Browserhacks
- // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
- // Tests for existence of standard globals is to allow style-loader
- // to operate correctly into non-standard environments
- // @see https://github.com/webpack-contrib/style-loader/issues/177
- return window && document && document.all && !window.atob;
- });
-
- var getTarget = function (target, parent) {
- if (parent){
- return parent.querySelector(target);
- }
- return document.querySelector(target);
- };
-
- var getElement = (function (fn) {
- var memo = {};
-
- return function(target, parent) {
- // If passing function in options, then use it for resolve "head" element.
- // Useful for Shadow Root style i.e
- // {
- // insertInto: function () { return document.querySelector("#foo").shadowRoot }
- // }
- if (typeof target === 'function') {
- return target();
- }
- if (typeof memo[target] === "undefined") {
- var styleTarget = getTarget.call(this, target, parent);
- // Special case to return head of iframe instead of iframe itself
- if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
- try {
- // This will throw an exception if access to iframe is blocked
- // due to cross-origin restrictions
- styleTarget = styleTarget.contentDocument.head;
- } catch(e) {
- styleTarget = null;
- }
- }
- memo[target] = styleTarget;
- }
- return memo[target]
- };
- })();
-
- var singleton = null;
- var singletonCounter = 0;
- var stylesInsertedAtTop = [];
-
- var fixUrls = require("./urls");
-
- module.exports = function(list, options) {
- if (typeof DEBUG !== "undefined" && DEBUG) {
- if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
- }
-
- options = options || {};
-
- options.attrs = typeof options.attrs === "object" ? options.attrs : {};
-
- // Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
- // tags it will allow on a page
- if (!options.singleton && typeof options.singleton !== "boolean") options.singleton = isOldIE();
-
- // By default, add <style> tags to the <head> element
- if (!options.insertInto) options.insertInto = "head";
-
- // By default, add <style> tags to the bottom of the target
- if (!options.insertAt) options.insertAt = "bottom";
-
- var styles = listToStyles(list, options);
-
- addStylesToDom(styles, options);
-
- return function update (newList) {
- var mayRemove = [];
-
- for (var i = 0; i < styles.length; i++) {
- var item = styles[i];
- var domStyle = stylesInDom[item.id];
-
- domStyle.refs--;
- mayRemove.push(domStyle);
- }
-
- if(newList) {
- var newStyles = listToStyles(newList, options);
- addStylesToDom(newStyles, options);
- }
-
- for (var i = 0; i < mayRemove.length; i++) {
- var domStyle = mayRemove[i];
-
- if(domStyle.refs === 0) {
- for (var j = 0; j < domStyle.parts.length; j++) domStyle.parts[j]();
-
- delete stylesInDom[domStyle.id];
- }
- }
- };
- };
-
- function addStylesToDom (styles, options) {
- for (var i = 0; i < styles.length; i++) {
- var item = styles[i];
- var domStyle = stylesInDom[item.id];
-
- if(domStyle) {
- domStyle.refs++;
-
- for(var j = 0; j < domStyle.parts.length; j++) {
- domStyle.parts[j](item.parts[j]);
- }
-
- for(; j < item.parts.length; j++) {
- domStyle.parts.push(addStyle(item.parts[j], options));
- }
- } else {
- var parts = [];
-
- for(var j = 0; j < item.parts.length; j++) {
- parts.push(addStyle(item.parts[j], options));
- }
-
- stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
- }
- }
- }
-
- function listToStyles (list, options) {
- var styles = [];
- var newStyles = {};
-
- for (var i = 0; i < list.length; i++) {
- var item = list[i];
- var id = options.base ? item[0] + options.base : item[0];
- var css = item[1];
- var media = item[2];
- var sourceMap = item[3];
- var part = {css: css, media: media, sourceMap: sourceMap};
-
- if(!newStyles[id]) styles.push(newStyles[id] = {id: id, parts: [part]});
- else newStyles[id].parts.push(part);
- }
-
- return styles;
- }
-
- function insertStyleElement (options, style) {
- var target = getElement(options.insertInto)
-
- if (!target) {
- throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.");
- }
-
- var lastStyleElementInsertedAtTop = stylesInsertedAtTop[stylesInsertedAtTop.length - 1];
-
- if (options.insertAt === "top") {
- if (!lastStyleElementInsertedAtTop) {
- target.insertBefore(style, target.firstChild);
- } else if (lastStyleElementInsertedAtTop.nextSibling) {
- target.insertBefore(style, lastStyleElementInsertedAtTop.nextSibling);
- } else {
- target.appendChild(style);
- }
- stylesInsertedAtTop.push(style);
- } else if (options.insertAt === "bottom") {
- target.appendChild(style);
- } else if (typeof options.insertAt === "object" && options.insertAt.before) {
- var nextSibling = getElement(options.insertAt.before, target);
- target.insertBefore(style, nextSibling);
- } else {
- throw new Error("[Style Loader]\n\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\n Must be 'top', 'bottom', or Object.\n (https://github.com/webpack-contrib/style-loader#insertat)\n");
- }
- }
-
- function removeStyleElement (style) {
- if (style.parentNode === null) return false;
- style.parentNode.removeChild(style);
-
- var idx = stylesInsertedAtTop.indexOf(style);
- if(idx >= 0) {
- stylesInsertedAtTop.splice(idx, 1);
- }
- }
-
- function createStyleElement (options) {
- var style = document.createElement("style");
-
- if(options.attrs.type === undefined) {
- options.attrs.type = "text/css";
- }
-
- if(options.attrs.nonce === undefined) {
- var nonce = getNonce();
- if (nonce) {
- options.attrs.nonce = nonce;
- }
- }
-
- addAttrs(style, options.attrs);
- insertStyleElement(options, style);
-
- return style;
- }
-
- function createLinkElement (options) {
- var link = document.createElement("link");
-
- if(options.attrs.type === undefined) {
- options.attrs.type = "text/css";
- }
- options.attrs.rel = "stylesheet";
-
- addAttrs(link, options.attrs);
- insertStyleElement(options, link);
-
- return link;
- }
-
- function addAttrs (el, attrs) {
- Object.keys(attrs).forEach(function (key) {
- el.setAttribute(key, attrs[key]);
- });
- }
-
- function getNonce() {
- if (typeof __webpack_nonce__ === 'undefined') {
- return null;
- }
-
- return __webpack_nonce__;
- }
-
- function addStyle (obj, options) {
- var style, update, remove, result;
-
- // If a transform function was defined, run it on the css
- if (options.transform && obj.css) {
- result = typeof options.transform === 'function'
- ? options.transform(obj.css)
- : options.transform.default(obj.css);
-
- if (result) {
- // If transform returns a value, use that instead of the original css.
- // This allows running runtime transformations on the css.
- obj.css = result;
- } else {
- // If the transform function returns a falsy value, don't add this css.
- // This allows conditional loading of css
- return function() {
- // noop
- };
- }
- }
-
- if (options.singleton) {
- var styleIndex = singletonCounter++;
-
- style = singleton || (singleton = createStyleElement(options));
-
- update = applyToSingletonTag.bind(null, style, styleIndex, false);
- remove = applyToSingletonTag.bind(null, style, styleIndex, true);
-
- } else if (
- obj.sourceMap &&
- typeof URL === "function" &&
- typeof URL.createObjectURL === "function" &&
- typeof URL.revokeObjectURL === "function" &&
- typeof Blob === "function" &&
- typeof btoa === "function"
- ) {
- style = createLinkElement(options);
- update = updateLink.bind(null, style, options);
- remove = function () {
- removeStyleElement(style);
-
- if(style.href) URL.revokeObjectURL(style.href);
- };
- } else {
- style = createStyleElement(options);
- update = applyToTag.bind(null, style);
- remove = function () {
- removeStyleElement(style);
- };
- }
-
- update(obj);
-
- return function updateStyle (newObj) {
- if (newObj) {
- if (
- newObj.css === obj.css &&
- newObj.media === obj.media &&
- newObj.sourceMap === obj.sourceMap
- ) {
- return;
- }
-
- update(obj = newObj);
- } else {
- remove();
- }
- };
- }
-
- var replaceText = (function () {
- var textStore = [];
-
- return function (index, replacement) {
- textStore[index] = replacement;
-
- return textStore.filter(Boolean).join('\n');
- };
- })();
-
- function applyToSingletonTag (style, index, remove, obj) {
- var css = remove ? "" : obj.css;
-
- if (style.styleSheet) {
- style.styleSheet.cssText = replaceText(index, css);
- } else {
- var cssNode = document.createTextNode(css);
- var childNodes = style.childNodes;
-
- if (childNodes[index]) style.removeChild(childNodes[index]);
-
- if (childNodes.length) {
- style.insertBefore(cssNode, childNodes[index]);
- } else {
- style.appendChild(cssNode);
- }
- }
- }
-
- function applyToTag (style, obj) {
- var css = obj.css;
- var media = obj.media;
-
- if(media) {
- style.setAttribute("media", media)
- }
-
- if(style.styleSheet) {
- style.styleSheet.cssText = css;
- } else {
- while(style.firstChild) {
- style.removeChild(style.firstChild);
- }
-
- style.appendChild(document.createTextNode(css));
- }
- }
-
- function updateLink (link, options, obj) {
- var css = obj.css;
- var sourceMap = obj.sourceMap;
-
- /*
- If convertToAbsoluteUrls isn't defined, but sourcemaps are enabled
- and there is no publicPath defined then lets turn convertToAbsoluteUrls
- on by default. Otherwise default to the convertToAbsoluteUrls option
- directly
- */
- var autoFixUrls = options.convertToAbsoluteUrls === undefined && sourceMap;
-
- if (options.convertToAbsoluteUrls || autoFixUrls) {
- css = fixUrls(css);
- }
-
- if (sourceMap) {
- // http://stackoverflow.com/a/26603875
- css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
- }
-
- var blob = new Blob([css], { type: "text/css" });
-
- var oldSrc = link.href;
-
- link.href = URL.createObjectURL(blob);
-
- if(oldSrc) URL.revokeObjectURL(oldSrc);
- }
|