support an array of items with id
This ensures that items with the same id are only added once. i. e. multiple css file and `@import` the same base css file and it's only added once to the DOM. webpack/css-loader#17master
parent
fd51db8715
commit
289e62f0c1
|
@ -0,0 +1 @@
|
||||||
|
/node_modules
|
38
addStyle.js
38
addStyle.js
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
||||||
Author Tobias Koppers @sokra
|
|
||||||
*/
|
|
||||||
module.exports = function addStyle(cssCode) {
|
|
||||||
if(typeof DEBUG !== "undefined" && DEBUG) {
|
|
||||||
if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
|
|
||||||
}
|
|
||||||
var styleElement = document.createElement("style"),
|
|
||||||
head = document.head || document.getElementsByTagName("head")[0];
|
|
||||||
styleElement.type = "text/css";
|
|
||||||
head.appendChild(styleElement);
|
|
||||||
if (styleElement.styleSheet) {
|
|
||||||
styleElement.styleSheet.cssText = cssCode;
|
|
||||||
} else {
|
|
||||||
styleElement.appendChild(document.createTextNode(cssCode));
|
|
||||||
}
|
|
||||||
if(module.hot) {
|
|
||||||
return function(cssCode) {
|
|
||||||
if(typeof cssCode === "string") {
|
|
||||||
if (styleElement.styleSheet) {
|
|
||||||
styleElement.styleSheet.cssText = cssCode;
|
|
||||||
} else {
|
|
||||||
styleElement.childNodes[0].nodeValue = cssCode;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dispose();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// For the useable API, provide a function to remove the stylesheet.
|
|
||||||
return dispose;
|
|
||||||
}
|
|
||||||
|
|
||||||
function dispose() {
|
|
||||||
head.removeChild(styleElement);
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||||
|
Author Tobias Koppers @sokra
|
||||||
|
*/
|
||||||
|
var stylesInDom = {};
|
||||||
|
|
||||||
|
module.exports = function(list) {
|
||||||
|
if(typeof DEBUG !== "undefined" && DEBUG) {
|
||||||
|
if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
|
||||||
|
}
|
||||||
|
var styles = listToStyles(list);
|
||||||
|
addStylesToDom(styles);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
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]));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var parts = [];
|
||||||
|
for(var j = 0; j < item.parts.length; j++) {
|
||||||
|
parts.push(addStyle(item.parts[j]));
|
||||||
|
}
|
||||||
|
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 addStyle(obj) {
|
||||||
|
var styleElement = document.createElement("style");
|
||||||
|
var head = document.head || document.getElementsByTagName("head")[0];
|
||||||
|
styleElement.type = "text/css";
|
||||||
|
head.appendChild(styleElement);
|
||||||
|
applyToTag(styleElement, obj);
|
||||||
|
return function(newObj) {
|
||||||
|
if(newObj) {
|
||||||
|
if(newObj.css === obj.css && newObj.media === obj.media /*&& newObj.sourceMap === obj.sourceMap*/)
|
||||||
|
return;
|
||||||
|
applyToTag(styleElement, obj = newObj);
|
||||||
|
} else {
|
||||||
|
head.removeChild(styleElement);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function applyToTag(styleElement, obj) {
|
||||||
|
var css = obj.css;
|
||||||
|
var media = obj.media;
|
||||||
|
// var sourceMap = obj.sourceMap;
|
||||||
|
|
||||||
|
// No browser support
|
||||||
|
// if(sourceMap && typeof btoa === "function") {
|
||||||
|
// try {
|
||||||
|
// css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(JSON.stringify(sourceMap)) + " */";
|
||||||
|
// } catch(e) {}
|
||||||
|
// }
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
@import "base.css";
|
||||||
|
body {
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
@import "base.css";
|
||||||
|
.a {
|
||||||
|
background: blue;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
body {
|
||||||
|
background: green;
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
require("./b.css");
|
||||||
|
require("./a.css");
|
|
@ -0,0 +1,7 @@
|
||||||
|
module.exports = {
|
||||||
|
module: {
|
||||||
|
loaders: [
|
||||||
|
{ test: /\.css$/, loader: "style!css?sourceMap" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
21
index.js
21
index.js
|
@ -8,15 +8,22 @@ module.exports.pitch = function(remainingRequest) {
|
||||||
this.cacheable && this.cacheable();
|
this.cacheable && this.cacheable();
|
||||||
return [
|
return [
|
||||||
"// style-loader: Adds some css to the DOM by adding a <style> tag",
|
"// style-loader: Adds some css to the DOM by adding a <style> tag",
|
||||||
"var update = require(" + JSON.stringify("!" + path.join(__dirname, "addStyle.js")) + ")(",
|
"",
|
||||||
"\trequire(" + JSON.stringify("!!" + remainingRequest) + ")",
|
"// load the styles",
|
||||||
");",
|
"var content = require(" + JSON.stringify("!!" + remainingRequest) + ");",
|
||||||
|
"if(typeof content === 'string') content = [module.id, content, ''];",
|
||||||
|
"// add the styles to the DOM",
|
||||||
|
"var update = require(" + JSON.stringify("!" + path.join(__dirname, "addStyles.js")) + ")(content);",
|
||||||
"// Hot Module Replacement",
|
"// Hot Module Replacement",
|
||||||
"if(module.hot) {",
|
"if(module.hot) {",
|
||||||
"\tmodule.hot.accept(" + JSON.stringify("!!" + remainingRequest) + ", function() {",
|
" // When the styles change, update the <style> tags",
|
||||||
"\t\tupdate(require(" + JSON.stringify("!!" + remainingRequest) + "));",
|
" module.hot.accept(" + JSON.stringify("!!" + remainingRequest) + ", function() {",
|
||||||
"\t});",
|
" var newContent = require(" + JSON.stringify("!!" + remainingRequest) + ");",
|
||||||
"\tmodule.hot.dispose(function() { update(); });",
|
" if(typeof newContent === 'string') newContent = [module.id, newContent, ''];",
|
||||||
|
" update(newContent);",
|
||||||
|
" });",
|
||||||
|
" // When the module is disposed, remove the <style> tags",
|
||||||
|
" module.hot.dispose(function() { update(); });",
|
||||||
"}"
|
"}"
|
||||||
].join("\n");
|
].join("\n");
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
"version": "0.7.1",
|
"version": "0.7.1",
|
||||||
"author": "Tobias Koppers @sokra",
|
"author": "Tobias Koppers @sokra",
|
||||||
"description": "style loader module for webpack",
|
"description": "style loader module for webpack",
|
||||||
|
"devDependencies": {
|
||||||
|
"css-loader": "~0.8.0"
|
||||||
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git@github.com:webpack/style-loader.git"
|
"url": "git@github.com:webpack/style-loader.git"
|
||||||
|
|
|
@ -11,7 +11,9 @@ module.exports.pitch = function(remainingRequest) {
|
||||||
"var dispose;",
|
"var dispose;",
|
||||||
"exports.use = exports.ref = function() {",
|
"exports.use = exports.ref = function() {",
|
||||||
" if(!(refs++)) {",
|
" if(!(refs++)) {",
|
||||||
" dispose = require(" + JSON.stringify("!" + path.join(__dirname, "addStyle.js")) + ")(require(" + JSON.stringify("!!" + remainingRequest) + "));",
|
" var content = require(" + JSON.stringify("!!" + remainingRequest) + ")",
|
||||||
|
" if(typeof content === 'string') content = [module.id, content, ''];",
|
||||||
|
" dispose = require(" + JSON.stringify("!" + path.join(__dirname, "addStyles.js")) + ")(content);",
|
||||||
" }",
|
" }",
|
||||||
" return exports",
|
" return exports",
|
||||||
"};",
|
"};",
|
||||||
|
|
Loading…
Reference in New Issue