1 |
|
2 |
|
3 |
|
4 |
|
5 | var stylesInDom = {},
|
6 | memoize = function(fn) {
|
7 | var memo;
|
8 | return function () {
|
9 | if (typeof memo === "undefined") memo = fn.apply(this, arguments);
|
10 | return memo;
|
11 | };
|
12 | },
|
13 | isOldIE = memoize(function() {
|
14 | return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
|
15 | }),
|
16 | getHeadElement = memoize(function () {
|
17 | return document.head || document.getElementsByTagName("head")[0];
|
18 | }),
|
19 | singletonElement = null,
|
20 | singletonCounter = 0;
|
21 |
|
22 | module.exports = function(list, options) {
|
23 | if(typeof DEBUG !== "undefined" && DEBUG) {
|
24 | if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
|
25 | }
|
26 |
|
27 | options = options || {};
|
28 |
|
29 |
|
30 | if (typeof options.singleton === "undefined") options.singleton = isOldIE();
|
31 |
|
32 | var styles = listToStyles(list);
|
33 | addStylesToDom(styles, options);
|
34 |
|
35 | return function update(newList) {
|
36 | var mayRemove = [];
|
37 | for(var i = 0; i < styles.length; i++) {
|
38 | var item = styles[i];
|
39 | var domStyle = stylesInDom[item.id];
|
40 | domStyle.refs--;
|
41 | mayRemove.push(domStyle);
|
42 | }
|
43 | if(newList) {
|
44 | var newStyles = listToStyles(newList);
|
45 | addStylesToDom(newStyles, options);
|
46 | }
|
47 | for(var i = 0; i < mayRemove.length; i++) {
|
48 | var domStyle = mayRemove[i];
|
49 | if(domStyle.refs === 0) {
|
50 | for(var j = 0; j < domStyle.parts.length; j++)
|
51 | domStyle.parts[j]();
|
52 | delete stylesInDom[domStyle.id];
|
53 | }
|
54 | }
|
55 | };
|
56 | }
|
57 |
|
58 | function addStylesToDom(styles, options) {
|
59 | for(var i = 0; i < styles.length; i++) {
|
60 | var item = styles[i];
|
61 | var domStyle = stylesInDom[item.id];
|
62 | if(domStyle) {
|
63 | domStyle.refs++;
|
64 | for(var j = 0; j < domStyle.parts.length; j++) {
|
65 | domStyle.parts[j](item.parts[j]);
|
66 | }
|
67 | for(; j < item.parts.length; j++) {
|
68 | domStyle.parts.push(addStyle(item.parts[j], options));
|
69 | }
|
70 | } else {
|
71 | var parts = [];
|
72 | for(var j = 0; j < item.parts.length; j++) {
|
73 | parts.push(addStyle(item.parts[j], options));
|
74 | }
|
75 | stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
|
76 | }
|
77 | }
|
78 | }
|
79 |
|
80 | function listToStyles(list) {
|
81 | var styles = [];
|
82 | var newStyles = {};
|
83 | for(var i = 0; i < list.length; i++) {
|
84 | var item = list[i];
|
85 | var id = item[0];
|
86 | var css = item[1];
|
87 | var media = item[2];
|
88 | var sourceMap = item[3];
|
89 | var part = {css: css, media: media, sourceMap: sourceMap};
|
90 | if(!newStyles[id])
|
91 | styles.push(newStyles[id] = {id: id, parts: [part]});
|
92 | else
|
93 | newStyles[id].parts.push(part);
|
94 | }
|
95 | return styles;
|
96 | }
|
97 |
|
98 | function createStyleElement() {
|
99 | var styleElement = document.createElement("style");
|
100 | var head = getHeadElement();
|
101 | styleElement.type = "text/css";
|
102 | head.appendChild(styleElement);
|
103 | return styleElement;
|
104 | }
|
105 |
|
106 | function createLinkElement() {
|
107 | var linkElement = document.createElement("link");
|
108 | var head = getHeadElement();
|
109 | linkElement.rel = "stylesheet";
|
110 | head.appendChild(linkElement);
|
111 | return linkElement;
|
112 | }
|
113 |
|
114 | function addStyle(obj, options) {
|
115 | var styleElement, update, remove;
|
116 |
|
117 | if (options.singleton) {
|
118 | var styleIndex = singletonCounter++;
|
119 | styleElement = singletonElement || (singletonElement = createStyleElement());
|
120 | update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
|
121 | remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
|
122 | } else if(obj.sourceMap &&
|
123 | typeof URL === "function" &&
|
124 | typeof URL.createObjectURL === "function" &&
|
125 | typeof URL.revokeObjectURL === "function" &&
|
126 | typeof Blob === "function" &&
|
127 | typeof btoa === "function") {
|
128 | styleElement = createLinkElement();
|
129 | update = updateLink.bind(null, styleElement);
|
130 | remove = function() {
|
131 | styleElement.parentNode.removeChild(styleElement);
|
132 | if(styleElement.href)
|
133 | URL.revokeObjectURL(styleElement.href);
|
134 | };
|
135 | } else {
|
136 | styleElement = createStyleElement();
|
137 | update = applyToTag.bind(null, styleElement);
|
138 | remove = function() {
|
139 | styleElement.parentNode.removeChild(styleElement);
|
140 | };
|
141 | }
|
142 |
|
143 | update(obj);
|
144 |
|
145 | return function updateStyle(newObj) {
|
146 | if(newObj) {
|
147 | if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
|
148 | return;
|
149 | update(obj = newObj);
|
150 | } else {
|
151 | remove();
|
152 | }
|
153 | };
|
154 | }
|
155 |
|
156 | var replaceText = (function () {
|
157 | var textStore = [];
|
158 |
|
159 | return function (index, replacement) {
|
160 | textStore[index] = replacement;
|
161 | return textStore.filter(Boolean).join('\n');
|
162 | };
|
163 | })();
|
164 |
|
165 | function applyToSingletonTag(styleElement, index, remove, obj) {
|
166 | var css = remove ? "" : obj.css;
|
167 |
|
168 | if (styleElement.styleSheet) {
|
169 | styleElement.styleSheet.cssText = replaceText(index, css);
|
170 | } else {
|
171 | var cssNode = document.createTextNode(css);
|
172 | var childNodes = styleElement.childNodes;
|
173 | if (childNodes[index]) styleElement.removeChild(childNodes[index]);
|
174 | if (childNodes.length) {
|
175 | styleElement.insertBefore(cssNode, childNodes[index]);
|
176 | } else {
|
177 | styleElement.appendChild(cssNode);
|
178 | }
|
179 | }
|
180 | }
|
181 |
|
182 | function applyToTag(styleElement, obj) {
|
183 | var css = obj.css;
|
184 | var media = obj.media;
|
185 | var sourceMap = obj.sourceMap;
|
186 |
|
187 | if(media) {
|
188 | styleElement.setAttribute("media", media)
|
189 | }
|
190 |
|
191 | if(styleElement.styleSheet) {
|
192 | styleElement.styleSheet.cssText = css;
|
193 | } else {
|
194 | while(styleElement.firstChild) {
|
195 | styleElement.removeChild(styleElement.firstChild);
|
196 | }
|
197 | styleElement.appendChild(document.createTextNode(css));
|
198 | }
|
199 | }
|
200 |
|
201 | function updateLink(linkElement, obj) {
|
202 | var css = obj.css;
|
203 | var media = obj.media;
|
204 | var sourceMap = obj.sourceMap;
|
205 |
|
206 | if(sourceMap) {
|
207 | css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(JSON.stringify(sourceMap)) + " */";
|
208 | }
|
209 |
|
210 | var blob = new Blob([css], { type: "text/css" });
|
211 |
|
212 | var oldSrc = linkElement.href;
|
213 |
|
214 | linkElement.href = URL.createObjectURL(blob);
|
215 |
|
216 | if(oldSrc)
|
217 | URL.revokeObjectURL(oldSrc);
|
218 | }
|