Last active
December 6, 2016 07:31
-
-
Save dkypooh/ad96c52aa7ebe9254d08d97f710fa104 to your computer and use it in GitHub Desktop.
How to add Style On Dom
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module.exports = function(list, options) { | |
| if(false) { | |
| if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment"); | |
| } | |
| options = options || {}; | |
| // Force single-tag solution on IE6-9, which has a hard limit on the # of <style> | |
| // tags it will allow on a page | |
| if (typeof options.singleton === "undefined") options.singleton = isOldIE(); | |
| // By default, add <style> tags to the bottom of <head>. | |
| if (typeof options.insertAt === "undefined") options.insertAt = "bottom"; | |
| var styles = listToStyles(list); | |
| 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); | |
| 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) { | |
| var styles = []; | |
| var newStyles = {}; | |
| for(var i = 0; i < list.length; i++) { | |
| var item = list[i]; | |
| var id = 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, styleElement) { | |
| var head = getHeadElement(); | |
| var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1]; | |
| if (options.insertAt === "top") { | |
| if(!lastStyleElementInsertedAtTop) { | |
| head.insertBefore(styleElement, head.firstChild); | |
| } else if(lastStyleElementInsertedAtTop.nextSibling) { | |
| head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling); | |
| } else { | |
| head.appendChild(styleElement); | |
| } | |
| styleElementsInsertedAtTop.push(styleElement); | |
| } else if (options.insertAt === "bottom") { | |
| head.appendChild(styleElement); | |
| } else { | |
| throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'."); | |
| } | |
| } | |
| function removeStyleElement(styleElement) { | |
| styleElement.parentNode.removeChild(styleElement); | |
| var idx = styleElementsInsertedAtTop.indexOf(styleElement); | |
| if(idx >= 0) { | |
| styleElementsInsertedAtTop.splice(idx, 1); | |
| } | |
| } | |
| function createStyleElement(options) { | |
| var styleElement = document.createElement("style"); | |
| styleElement.type = "text/css"; | |
| insertStyleElement(options, styleElement); | |
| return styleElement; | |
| } | |
| function createLinkElement(options) { | |
| var linkElement = document.createElement("link"); | |
| linkElement.rel = "stylesheet"; | |
| insertStyleElement(options, linkElement); | |
| return linkElement; | |
| } | |
| function addStyle(obj, options) { | |
| var styleElement, update, remove; | |
| if (options.singleton) { | |
| var styleIndex = singletonCounter++; | |
| styleElement = singletonElement || (singletonElement = createStyleElement(options)); | |
| update = applyToSingletonTag.bind(null, styleElement, styleIndex, false); | |
| remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true); | |
| } else if(obj.sourceMap && | |
| typeof URL === "function" && | |
| typeof URL.createObjectURL === "function" && | |
| typeof URL.revokeObjectURL === "function" && | |
| typeof Blob === "function" && | |
| typeof btoa === "function") { | |
| styleElement = createLinkElement(options); | |
| update = updateLink.bind(null, styleElement); | |
| remove = function() { | |
| removeStyleElement(styleElement); | |
| if(styleElement.href) | |
| URL.revokeObjectURL(styleElement.href); | |
| }; | |
| } else { | |
| styleElement = createStyleElement(options); | |
| update = applyToTag.bind(null, styleElement); | |
| remove = function() { | |
| removeStyleElement(styleElement); | |
| }; | |
| } | |
| 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(styleElement, index, remove, obj) { | |
| var css = remove ? "" : obj.css; | |
| if (styleElement.styleSheet) { | |
| styleElement.styleSheet.cssText = replaceText(index, css); | |
| } else { | |
| var cssNode = document.createTextNode(css); | |
| var childNodes = styleElement.childNodes; | |
| if (childNodes[index]) styleElement.removeChild(childNodes[index]); | |
| if (childNodes.length) { | |
| styleElement.insertBefore(cssNode, childNodes[index]); | |
| } else { | |
| styleElement.appendChild(cssNode); | |
| } | |
| } | |
| } | |
| function applyToTag(styleElement, obj) { | |
| var css = obj.css; | |
| var media = obj.media; | |
| if(media) { | |
| styleElement.setAttribute("media", media) | |
| } | |
| if(styleElement.styleSheet) { | |
| styleElement.styleSheet.cssText = css; | |
| } else { | |
| while(styleElement.firstChild) { | |
| styleElement.removeChild(styleElement.firstChild); | |
| } | |
| styleElement.appendChild(document.createTextNode(css)); | |
| } | |
| } | |
| function updateLink(linkElement, obj) { | |
| var css = obj.css; | |
| var sourceMap = obj.sourceMap; | |
| 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 = linkElement.href; | |
| linkElement.href = URL.createObjectURL(blob); | |
| if(oldSrc) | |
| URL.revokeObjectURL(oldSrc); | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
reference form webpack