-
-
Notifications
You must be signed in to change notification settings - Fork 470
/
injectStylesIntoStyleTag.js
115 lines (88 loc) · 2.45 KB
/
injectStylesIntoStyleTag.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
const stylesInDOM = [];
function getIndexByIdentifier(identifier) {
let result = -1;
for (let i = 0; i < stylesInDOM.length; i++) {
if (stylesInDOM[i].identifier === identifier) {
result = i;
break;
}
}
return result;
}
function modulesToDom(list, options) {
const idCountMap = {};
const identifiers = [];
for (let i = 0; i < list.length; i++) {
const item = list[i];
const id = options.base ? item[0] + options.base : item[0];
const count = idCountMap[id] || 0;
const identifier = `${id} ${count}`;
idCountMap[id] = count + 1;
const indexByIdentifier = getIndexByIdentifier(identifier);
const obj = {
css: item[1],
media: item[2],
sourceMap: item[3],
supports: item[4],
layer: item[5],
};
if (indexByIdentifier !== -1) {
stylesInDOM[indexByIdentifier].references++;
stylesInDOM[indexByIdentifier].updater(obj);
} else {
const updater = addElementStyle(obj, options);
options.byIndex = i;
stylesInDOM.splice(i, 0, {
identifier,
updater,
references: 1,
});
}
identifiers.push(identifier);
}
return identifiers;
}
function addElementStyle(obj, options) {
const api = options.domAPI(options);
api.update(obj);
const updater = (newObj) => {
if (newObj) {
if (
newObj.css === obj.css &&
newObj.media === obj.media &&
newObj.sourceMap === obj.sourceMap &&
newObj.supports === obj.supports &&
newObj.layer === obj.layer
) {
return;
}
api.update((obj = newObj));
} else {
api.remove();
}
};
return updater;
}
module.exports = (list, options) => {
options = options || {};
list = list || [];
let lastIdentifiers = modulesToDom(list, options);
return function update(newList) {
newList = newList || [];
for (let i = 0; i < lastIdentifiers.length; i++) {
const identifier = lastIdentifiers[i];
const index = getIndexByIdentifier(identifier);
stylesInDOM[index].references--;
}
const newLastIdentifiers = modulesToDom(newList, options);
for (let i = 0; i < lastIdentifiers.length; i++) {
const identifier = lastIdentifiers[i];
const index = getIndexByIdentifier(identifier);
if (stylesInDOM[index].references === 0) {
stylesInDOM[index].updater();
stylesInDOM.splice(index, 1);
}
}
lastIdentifiers = newLastIdentifiers;
};
};