Remove global variable, add ID to style elements so server- and client-rendered match each other
parent
e5aaab0300
commit
7d48da227e
44
addStyles.js
44
addStyles.js
|
@ -1,7 +1,8 @@
|
||||||
/*
|
/**
|
||||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
* MIT License http://www.opensource.org/licenses/mit-license.php
|
||||||
Author Tobias Koppers @sokra
|
* Tobias Koppers @sokra
|
||||||
*/
|
* Vitaliy Filippov vitalif@yourcmc.ru
|
||||||
|
*/
|
||||||
var stylesInDom = {},
|
var stylesInDom = {},
|
||||||
memoize = function(fn) {
|
memoize = function(fn) {
|
||||||
var memo;
|
var memo;
|
||||||
|
@ -42,15 +43,17 @@ module.exports = function(list, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
options.attrs = typeof options.attrs === "object" ? options.attrs : {};
|
options.attrs = typeof options.attrs === "object" ? options.attrs : {};
|
||||||
|
|
||||||
// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
|
// By default, use "__universalLoaderStyles" as the ID of style element
|
||||||
// tags it will allow on a page
|
if (!options.elementId) options.elementId = "__universalLoaderStyles";
|
||||||
if (typeof options.singleton === "undefined") options.singleton = isOldIE();
|
|
||||||
|
// Use single-tag solution by default
|
||||||
|
if (options.singleton == undefined) options.singleton = true;
|
||||||
|
|
||||||
// By default, add <style> tags to the <head> element
|
// By default, add <style> tags to the <head> element
|
||||||
if (typeof options.insertInto === "undefined") options.insertInto = "head";
|
if (options.insertInto == undefined) options.insertInto = "head";
|
||||||
|
|
||||||
// By default, add <style> tags to the bottom of the target
|
// By default, add <style> tags to the bottom of the target
|
||||||
if (typeof options.insertAt === "undefined") options.insertAt = "bottom";
|
if (options.insertAt == undefined) options.insertAt = "bottom";
|
||||||
|
|
||||||
var styles = listToStyles(list);
|
var styles = listToStyles(list);
|
||||||
addStylesToDom(styles, options);
|
addStylesToDom(styles, options);
|
||||||
|
@ -103,6 +106,7 @@ function addStylesToDom(styles, options) {
|
||||||
function listToStyles(list) {
|
function listToStyles(list) {
|
||||||
var styles = [];
|
var styles = [];
|
||||||
var newStyles = {};
|
var newStyles = {};
|
||||||
|
list = list.default || list;
|
||||||
for(var i = 0; i < list.length; i++) {
|
for(var i = 0; i < list.length; i++) {
|
||||||
var item = list[i];
|
var item = list[i];
|
||||||
var id = item[0];
|
var id = item[0];
|
||||||
|
@ -148,12 +152,15 @@ function removeStyleElement(styleElement) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createStyleElement(options) {
|
function createStyleElement(options, id) {
|
||||||
var styleElement = document.createElement("style");
|
var styleElement = document.getElementById(id);
|
||||||
options.attrs.type = "text/css";
|
options.attrs.type = "text/css";
|
||||||
|
if (!styleElement) {
|
||||||
attachTagAttrs(styleElement, options.attrs);
|
styleElement = document.createElement("style");
|
||||||
insertStyleElement(options, styleElement);
|
attachTagAttrs(styleElement, options.attrs);
|
||||||
|
styleElement.setAttribute('id', id);
|
||||||
|
insertStyleElement(options, styleElement);
|
||||||
|
}
|
||||||
return styleElement;
|
return styleElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,9 +183,9 @@ function attachTagAttrs(element, attrs) {
|
||||||
function addStyle(obj, options) {
|
function addStyle(obj, options) {
|
||||||
var styleElement, update, remove;
|
var styleElement, update, remove;
|
||||||
|
|
||||||
|
var styleIndex = singletonCounter++;
|
||||||
if (options.singleton) {
|
if (options.singleton) {
|
||||||
var styleIndex = singletonCounter++;
|
styleElement = singletonElement || (singletonElement = createStyleElement(options, options.elementId));
|
||||||
styleElement = singletonElement || (singletonElement = createStyleElement(options));
|
|
||||||
update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
|
update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
|
||||||
remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
|
remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
|
||||||
} else if(obj.sourceMap &&
|
} else if(obj.sourceMap &&
|
||||||
|
@ -195,7 +202,7 @@ function addStyle(obj, options) {
|
||||||
URL.revokeObjectURL(styleElement.href);
|
URL.revokeObjectURL(styleElement.href);
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
styleElement = createStyleElement(options);
|
styleElement = createStyleElement(options, options.elementId+styleIndex);
|
||||||
update = applyToTag.bind(null, styleElement);
|
update = applyToTag.bind(null, styleElement);
|
||||||
remove = function() {
|
remove = function() {
|
||||||
removeStyleElement(styleElement);
|
removeStyleElement(styleElement);
|
||||||
|
@ -232,7 +239,8 @@ function applyToSingletonTag(styleElement, index, remove, obj) {
|
||||||
} else {
|
} else {
|
||||||
var cssNode = document.createTextNode(css);
|
var cssNode = document.createTextNode(css);
|
||||||
var childNodes = styleElement.childNodes;
|
var childNodes = styleElement.childNodes;
|
||||||
if (childNodes[index]) styleElement.removeChild(childNodes[index]);
|
if (childNodes[index])
|
||||||
|
styleElement.removeChild(childNodes[index]);
|
||||||
if (childNodes.length) {
|
if (childNodes.length) {
|
||||||
styleElement.insertBefore(cssNode, childNodes[index]);
|
styleElement.insertBefore(cssNode, childNodes[index]);
|
||||||
} else {
|
} else {
|
||||||
|
|
83
universal.js
83
universal.js
|
@ -1,39 +1,76 @@
|
||||||
/*
|
/**
|
||||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
* MIT License http://www.opensource.org/licenses/mit-license.php
|
||||||
Istvan Jano janoist1@gmail.com
|
* Istvan Jano janoist1@gmail.com
|
||||||
|
* Vitaliy Filippov vitalif@yourcmc.ru
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var collectedStyleElementId = "__universalLoaderStyles";
|
||||||
|
var collectedStyleSingleton = true;
|
||||||
|
var collectedStyles = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add styles - used by the loader
|
* Add styles - used by the loader
|
||||||
*
|
*
|
||||||
* @param list
|
* @param list
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
module.exports.addStyles = function (list, options) {
|
function addStyles(list, options)
|
||||||
global.__styles__ = global.__styles__ || []
|
{
|
||||||
var newStyles = {}
|
// By default, use "__universalLoaderStyles" as the ID of style element
|
||||||
|
collectedStyleElementId = options && options.elementId || "__universalLoaderStyles";
|
||||||
for (var i = 0; i < list.length; i++) {
|
collectedStyleSingleton = !options || options.singleton == undefined ? true : options.singleton;
|
||||||
var item = list[i]
|
var newStyles = {};
|
||||||
var id = item[0]
|
// default is for ES6 CSS modules
|
||||||
var css = item[1]
|
list = list.default || list;
|
||||||
var media = item[2]
|
for (var i = 0; i < list.length; i++)
|
||||||
var sourceMap = item[3]
|
{
|
||||||
var part = {css: css, media: media, sourceMap: sourceMap}
|
var item = list[i];
|
||||||
|
var id = item[0];
|
||||||
if (!newStyles[id]){
|
var css = item[1];
|
||||||
global.__styles__.push(newStyles[id] = {id: id, parts: [part]})
|
var media = item[2];
|
||||||
} else {
|
var sourceMap = item[3];
|
||||||
|
var part = { css: css, media: media, sourceMap: sourceMap };
|
||||||
|
if (!newStyles[id])
|
||||||
|
collectedStyles.push(newStyles[id] = { id: id, parts: [ part ]})
|
||||||
|
else
|
||||||
newStyles[id].parts.push(part)
|
newStyles[id].parts.push(part)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the styles that have been collected so far
|
* Return the styles that have been collected so far as array
|
||||||
*
|
*
|
||||||
* @returns {*}
|
* @returns object[]
|
||||||
*/
|
*/
|
||||||
module.exports.getStyles = function () {
|
function getStyleList()
|
||||||
return global.__styles__
|
{
|
||||||
|
return collectedStyles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the styles that have been collected so far as a <style>
|
||||||
|
* element code ready for insertion into <head>
|
||||||
|
*
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
|
function getStyles()
|
||||||
|
{
|
||||||
|
if (collectedStyleSingleton)
|
||||||
|
{
|
||||||
|
return "<style type=\"text/css\" id=\""+collectedStyleElementId+"\">"+
|
||||||
|
collectedStyles.map(style => style.parts.map(part => part.css + "\n").join('')).join('')+
|
||||||
|
"</style>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return collectedStyles.map((style, idx) =>
|
||||||
|
"<style type=\"text/css\" id=\""+collectedStyleElementId+idx+"\">"+
|
||||||
|
style.parts.map(part => part.css + "\n").join('')+
|
||||||
|
"</style>"
|
||||||
|
).join('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.addStyles = addStyles;
|
||||||
|
module.exports.getStyleList = getStyleList;
|
||||||
|
module.exports.getStyles = getStyles;
|
||||||
|
|
Loading…
Reference in New Issue