367 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			367 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/*
 | 
						|
	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 getElement = (function (fn) {
 | 
						|
	var memo = {};
 | 
						|
 | 
						|
	return function(selector) {
 | 
						|
		if (typeof memo[selector] === "undefined") {
 | 
						|
			var styleTarget = fn.call(this, selector);
 | 
						|
			// Special case to return head of iframe instead of iframe itself
 | 
						|
			if (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[selector] = styleTarget;
 | 
						|
		}
 | 
						|
		return memo[selector]
 | 
						|
	};
 | 
						|
})(function (target) {
 | 
						|
	return document.querySelector(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) 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.insertInto + " " + options.insertAt.before);
 | 
						|
		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");
 | 
						|
 | 
						|
	options.attrs.type = "text/css";
 | 
						|
 | 
						|
	addAttrs(style, options.attrs);
 | 
						|
	insertStyleElement(options, style);
 | 
						|
 | 
						|
	return style;
 | 
						|
}
 | 
						|
 | 
						|
function createLinkElement (options) {
 | 
						|
	var link = document.createElement("link");
 | 
						|
 | 
						|
	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 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 = options.transform(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);
 | 
						|
}
 |