@master/css-runtime 2.0.0-rc.69 → 2.0.0-rc.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -7
- package/dist/class-tracker.d.ts +12 -0
- package/dist/core.d.ts +51 -66
- package/dist/css-runtime.d.ts +17 -0
- package/dist/debuggers/log.d.ts +17 -0
- package/dist/default-manifest.json +1 -0
- package/dist/generated-rule.d.ts +26 -0
- package/dist/global.min.js +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.development.mjs +980 -268
- package/dist/index.mjs +972 -263
- package/dist/layer.d.ts +3 -2
- package/dist/native-declaration.d.ts +2 -0
- package/dist/register-global.d.ts +2 -5
- package/dist/theme-layer.d.ts +27 -0
- package/dist/types/hydrate-result.d.ts +3 -2
- package/dist/utility-layer.d.ts +13 -0
- package/dist/utils/find-native-css-rule-index.d.ts +1 -0
- package/package.json +1 -1
- package/dist/index.cjs +0 -481
- package/dist/index.development.cjs +0 -608
- package/dist/init.d.ts +0 -10
- package/dist/syntax-layer.d.ts +0 -19
|
@@ -1,608 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var css = require('@master/css');
|
|
4
|
-
var cssDevtoolsHook = require('@master/css-devtools-hook');
|
|
5
|
-
|
|
6
|
-
const createLogger = (type)=>{
|
|
7
|
-
return (message, ...args)=>{
|
|
8
|
-
if (!type) return console.log(message, ...args);
|
|
9
|
-
if (console[type]) {
|
|
10
|
-
console[type](`%c[Master CSS]%c ${message}`, 'color: gray;', 'color: inherit;', ...args);
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
};
|
|
14
|
-
const loggers = {
|
|
15
|
-
info: createLogger('info'),
|
|
16
|
-
debug: createLogger('debug'),
|
|
17
|
-
warn: console.warn,
|
|
18
|
-
error: console.error,
|
|
19
|
-
trace: console.trace,
|
|
20
|
-
table: console.table,
|
|
21
|
-
group: console.group,
|
|
22
|
-
groupCollapsed: console.group,
|
|
23
|
-
groupEnd: console.groupEnd,
|
|
24
|
-
time: console.time,
|
|
25
|
-
timeEnd: console.timeEnd
|
|
26
|
-
};
|
|
27
|
-
const log = createLogger();
|
|
28
|
-
Object.assign(log, loggers);
|
|
29
|
-
|
|
30
|
-
function registerClassCountDebugger() {
|
|
31
|
-
const hook = globalThis.__MASTER_CSS_DEVTOOLS_HOOK__;
|
|
32
|
-
hook.on('runtime:mutated', ({ records, classCounts, cssRuntime })=>{
|
|
33
|
-
const actualClassCounts = {};
|
|
34
|
-
let errored = false;
|
|
35
|
-
const resolveClass = (className)=>{
|
|
36
|
-
if (Object.prototype.hasOwnProperty.call(actualClassCounts, className)) {
|
|
37
|
-
actualClassCounts[className]++;
|
|
38
|
-
} else {
|
|
39
|
-
actualClassCounts[className] = 1;
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
(cssRuntime.root.constructor.name === 'HTMLDocument' ? cssRuntime.host : cssRuntime.container).querySelectorAll('[class]').forEach((element)=>{
|
|
43
|
-
element.classList.forEach(resolveClass);
|
|
44
|
-
});
|
|
45
|
-
cssRuntime.host.classList.forEach(resolveClass);
|
|
46
|
-
for(const className in actualClassCounts){
|
|
47
|
-
const eachCount = cssRuntime.classCounts.get(className);
|
|
48
|
-
const eachActualCount = actualClassCounts[className];
|
|
49
|
-
if (eachCount !== eachActualCount) {
|
|
50
|
-
log.error(`Class count mismatch for \`${className}\` (expected ${eachActualCount}) (received ${eachCount})`);
|
|
51
|
-
errored = true;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
cssRuntime.classCounts.forEach((eachCount, className)=>{
|
|
55
|
-
if (!Object.prototype.hasOwnProperty.call(actualClassCounts, className)) {
|
|
56
|
-
log.error(`Class count mismatch for \`${className}\` (expected ${0}) (received ${eachCount})`);
|
|
57
|
-
errored = true;
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
if (errored) {
|
|
61
|
-
log.debug('Records:', records);
|
|
62
|
-
log.debug('Serialized Records:', serializeMutations(records));
|
|
63
|
-
log.debug('Counts:', classCounts);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
function serializeMutations(mutations) {
|
|
68
|
-
return mutations.map((m)=>{
|
|
69
|
-
const target = m.target;
|
|
70
|
-
return {
|
|
71
|
-
type: m.type,
|
|
72
|
-
attributeName: m.attributeName,
|
|
73
|
-
oldValue: m.oldValue,
|
|
74
|
-
target: {
|
|
75
|
-
tagName: target.tagName,
|
|
76
|
-
id: target.id,
|
|
77
|
-
classList: Array.from(target.classList)
|
|
78
|
-
},
|
|
79
|
-
added: Array.from(m.addedNodes).filter((n)=>n.nodeType === 1).map((el)=>({
|
|
80
|
-
tagName: el.tagName,
|
|
81
|
-
id: el.id,
|
|
82
|
-
classList: Array.from(el.classList)
|
|
83
|
-
})),
|
|
84
|
-
removed: Array.from(m.removedNodes).filter((n)=>n.nodeType === 1).map((el)=>({
|
|
85
|
-
tagName: el.tagName,
|
|
86
|
-
id: el.id,
|
|
87
|
-
classList: Array.from(el.classList)
|
|
88
|
-
}))
|
|
89
|
-
};
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function registerLifecycleDebugger() {
|
|
94
|
-
const hook = globalThis.__MASTER_CSS_DEVTOOLS_HOOK__;
|
|
95
|
-
hook.on('runtime:created', ({ cssRuntime })=>{
|
|
96
|
-
log.debug('created', cssRuntime);
|
|
97
|
-
});
|
|
98
|
-
hook.on('runtime:hydrated', ({ cssRuntime })=>{
|
|
99
|
-
log.debug('hydrated', cssRuntime);
|
|
100
|
-
});
|
|
101
|
-
hook.on('runtime:observed', ({ cssRuntime })=>{
|
|
102
|
-
log.debug('observed', cssRuntime);
|
|
103
|
-
if (cssRuntime.progressive) {
|
|
104
|
-
log.info('Progressive rendering is adopted.');
|
|
105
|
-
log.debug('pre-rendered CSS', cssRuntime.style);
|
|
106
|
-
} else {
|
|
107
|
-
log.info('Runtime rendering is adopted.');
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
hook.on('runtime:refreshed', ({ cssRuntime, customConfig })=>{
|
|
111
|
-
log.debug('refreshed', cssRuntime, customConfig);
|
|
112
|
-
});
|
|
113
|
-
hook.on('runtime:disconnected', ({ cssRuntime })=>{
|
|
114
|
-
log.debug('disconnected', cssRuntime);
|
|
115
|
-
});
|
|
116
|
-
hook.on('runtime:destroyed', ({ cssRuntime })=>{
|
|
117
|
-
log.debug('destroyed', cssRuntime);
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function startDebuggers() {
|
|
122
|
-
log.info('Debug mode is enabled by default in development.');
|
|
123
|
-
registerClassCountDebugger();
|
|
124
|
-
registerLifecycleDebugger();
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function registerGlobal(CSSRuntime) {
|
|
128
|
-
if (!globalThis.CSSRuntime) globalThis.CSSRuntime = CSSRuntime;
|
|
129
|
-
cssDevtoolsHook.installHook();
|
|
130
|
-
{
|
|
131
|
-
startDebuggers();
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function findNativeCSSRuleIndex(cssRules, nativeRule) {
|
|
136
|
-
for(let i = 0; i < cssRules.length; i++){
|
|
137
|
-
if (cssRules[i] === nativeRule) {
|
|
138
|
-
return i;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return -1;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
class RuntimeLayer extends css.Layer {
|
|
145
|
-
name;
|
|
146
|
-
cssRuntime;
|
|
147
|
-
rules = [];
|
|
148
|
-
tokenCounts = new Map();
|
|
149
|
-
native = null;
|
|
150
|
-
constructor(name, cssRuntime){
|
|
151
|
-
super(name, cssRuntime), this.name = name, this.cssRuntime = cssRuntime;
|
|
152
|
-
}
|
|
153
|
-
attach() {
|
|
154
|
-
super.attach();
|
|
155
|
-
const nativeSheet = this.cssRuntime.style?.sheet;
|
|
156
|
-
if (nativeSheet && !this.native?.parentStyleSheet) {
|
|
157
|
-
const insertedIndex = nativeSheet.insertRule(this.text, nativeSheet.cssRules.length);
|
|
158
|
-
this.native = nativeSheet.cssRules.item(insertedIndex);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
insert(rule, index = this.rules.length) {
|
|
162
|
-
const insertedIndex = super.insert(rule, index);
|
|
163
|
-
if (insertedIndex === undefined || !this.native) return;
|
|
164
|
-
const insertRuleSafely = (text, position)=>{
|
|
165
|
-
// Checks if the rule is inserted in a native CSS rule with this.attach()
|
|
166
|
-
if (this.rules.length === 1) {
|
|
167
|
-
return this.native.cssRules.item(position);
|
|
168
|
-
} else {
|
|
169
|
-
try {
|
|
170
|
-
const insertedIndex = this.native.insertRule(text, position);
|
|
171
|
-
return this.native.cssRules.item(insertedIndex);
|
|
172
|
-
} catch (error) {
|
|
173
|
-
console.error(error, rule);
|
|
174
|
-
/**
|
|
175
|
-
* If the rule is invalid, remove it from the rules array.
|
|
176
|
-
* It's important to note that the rule may break the entire CSS runtime,
|
|
177
|
-
*/ this.rules.splice(insertedIndex, 1);
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
if ('nodes' in rule) {
|
|
183
|
-
let currentIndex = insertedIndex;
|
|
184
|
-
rule.nodes.forEach((node)=>{
|
|
185
|
-
node.native = insertRuleSafely(node.text, currentIndex);
|
|
186
|
-
if (node.native) currentIndex++;
|
|
187
|
-
});
|
|
188
|
-
} else {
|
|
189
|
-
rule.native = insertRuleSafely(rule.text, insertedIndex);
|
|
190
|
-
}
|
|
191
|
-
return insertedIndex;
|
|
192
|
-
}
|
|
193
|
-
detach() {
|
|
194
|
-
super.detach();
|
|
195
|
-
const nativeSheet = this.cssRuntime.style?.sheet;
|
|
196
|
-
if (nativeSheet && this.native?.parentStyleSheet) {
|
|
197
|
-
const foundIndex = findNativeCSSRuleIndex(nativeSheet.cssRules, this.native);
|
|
198
|
-
if (foundIndex !== -1) {
|
|
199
|
-
nativeSheet.deleteRule(foundIndex);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
delete(key) {
|
|
204
|
-
const deletedRule = super.delete(key);
|
|
205
|
-
if (!deletedRule || !this.native) return;
|
|
206
|
-
const deleteRuleSafely = (rule)=>{
|
|
207
|
-
if (!rule) return;
|
|
208
|
-
const foundIndex = findNativeCSSRuleIndex(this.native.cssRules, rule);
|
|
209
|
-
if (foundIndex !== -1) {
|
|
210
|
-
try {
|
|
211
|
-
this.native.deleteRule(foundIndex);
|
|
212
|
-
} catch (error) {
|
|
213
|
-
console.error(error, rule);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
};
|
|
217
|
-
if ('nodes' in deletedRule) {
|
|
218
|
-
deletedRule.nodes.forEach((node)=>deleteRuleSafely(node.native));
|
|
219
|
-
} else {
|
|
220
|
-
deleteRuleSafely(deletedRule.native);
|
|
221
|
-
}
|
|
222
|
-
return deletedRule;
|
|
223
|
-
}
|
|
224
|
-
reset() {
|
|
225
|
-
super.reset();
|
|
226
|
-
const nativeSheet = this.cssRuntime.style?.sheet;
|
|
227
|
-
if (this.native && nativeSheet) {
|
|
228
|
-
const foundIndex = findNativeCSSRuleIndex(nativeSheet.cssRules, this.native);
|
|
229
|
-
if (foundIndex !== -1) {
|
|
230
|
-
nativeSheet.deleteRule(foundIndex);
|
|
231
|
-
}
|
|
232
|
-
this.native = null;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const RuntimeSyntaxLayer = css.withSyntaxLayer(RuntimeLayer);
|
|
238
|
-
|
|
239
|
-
class CSSRuntime extends css.MasterCSS {
|
|
240
|
-
root;
|
|
241
|
-
customConfig;
|
|
242
|
-
baseConfig;
|
|
243
|
-
static instances = new WeakMap();
|
|
244
|
-
host;
|
|
245
|
-
container;
|
|
246
|
-
baseLayer = new RuntimeSyntaxLayer('base', this);
|
|
247
|
-
themeLayer = new RuntimeLayer('theme', this);
|
|
248
|
-
presetLayer = new RuntimeSyntaxLayer('preset', this);
|
|
249
|
-
componentsLayer = new RuntimeSyntaxLayer('components', this);
|
|
250
|
-
generalLayer = new RuntimeSyntaxLayer('general', this);
|
|
251
|
-
classCounts = new Map();
|
|
252
|
-
observer;
|
|
253
|
-
progressive = false;
|
|
254
|
-
observing = false;
|
|
255
|
-
constructor(root = document, customConfig = css.config, baseConfig){
|
|
256
|
-
super(customConfig, baseConfig), this.root = root, this.customConfig = customConfig, this.baseConfig = baseConfig;
|
|
257
|
-
// Do not use instanceof here, because it will not work
|
|
258
|
-
const rootConstructorName = root?.constructor.name;
|
|
259
|
-
if (rootConstructorName === 'HTMLDocument' || rootConstructorName === 'Document') {
|
|
260
|
-
this.root.defaultView.globalThis.cssRuntime = this;
|
|
261
|
-
this.container = this.root.head;
|
|
262
|
-
this.host = this.root.documentElement;
|
|
263
|
-
} else {
|
|
264
|
-
this.container = this.root;
|
|
265
|
-
this.host = this.root.host;
|
|
266
|
-
}
|
|
267
|
-
globalThis.CSSRuntime.instances.set(this.root, this);
|
|
268
|
-
__MASTER_CSS_DEVTOOLS_HOOK__?.emit('runtime:created', {
|
|
269
|
-
cssRuntime: this
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Observe the DOM for changes and update the running stylesheet. (browser only)
|
|
274
|
-
* @param options mutation observer options
|
|
275
|
-
* @returns this
|
|
276
|
-
*/ observe() {
|
|
277
|
-
if (this.observing) return this;
|
|
278
|
-
// Detect prerendered stylesheet
|
|
279
|
-
if (this.root.styleSheets) {
|
|
280
|
-
for (const sheet of this.root.styleSheets){
|
|
281
|
-
const { ownerNode } = sheet;
|
|
282
|
-
if (ownerNode instanceof HTMLStyleElement && ownerNode.id === 'master') {
|
|
283
|
-
this.style = ownerNode;
|
|
284
|
-
if (this.style.sheet?.cssRules.length) {
|
|
285
|
-
this.progressive = true;
|
|
286
|
-
}
|
|
287
|
-
break;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
// Prepare snapshot map
|
|
292
|
-
const elementClasses = new WeakMap();
|
|
293
|
-
// Initial scan and populate counts + snapshot
|
|
294
|
-
const connectedNames = new Set();
|
|
295
|
-
const increaseClassCount = (className)=>{
|
|
296
|
-
const count = this.classCounts.get(className) || 0;
|
|
297
|
-
if (!count) connectedNames.add(className);
|
|
298
|
-
this.classCounts.set(className, count + 1);
|
|
299
|
-
};
|
|
300
|
-
const elementsWithClass = this.root.querySelectorAll('[class]');
|
|
301
|
-
elementsWithClass.forEach((el)=>{
|
|
302
|
-
const clsList = el.classList;
|
|
303
|
-
if (clsList) {
|
|
304
|
-
el.classList.forEach(increaseClassCount);
|
|
305
|
-
}
|
|
306
|
-
elementClasses.set(el, new Set(clsList));
|
|
307
|
-
});
|
|
308
|
-
// Hydration or style creation
|
|
309
|
-
if (this.progressive) {
|
|
310
|
-
const hydrateResult = this.hydrate(this.style.sheet.cssRules);
|
|
311
|
-
for (const cls of connectedNames){
|
|
312
|
-
if (!hydrateResult.allSyntaxRules.find((r)=>(r.fixedClass || r.name) === cls)) {
|
|
313
|
-
this.add(cls);
|
|
314
|
-
{
|
|
315
|
-
console.debug(`Missing prerendered rule for class \`${cls}\``);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
} else {
|
|
320
|
-
this.style = document.createElement('style');
|
|
321
|
-
this.style.id = 'master';
|
|
322
|
-
this.style.setAttribute('blocking', 'render');
|
|
323
|
-
this.container.append(this.style);
|
|
324
|
-
this.style.sheet.insertRule(this.layerStatementRule.text);
|
|
325
|
-
this.layerStatementRule.native = this.style.sheet.cssRules.item(0);
|
|
326
|
-
connectedNames.forEach((cls)=>this.add(cls));
|
|
327
|
-
}
|
|
328
|
-
this.observer = new MutationObserver((records)=>{
|
|
329
|
-
const deltaCounts = new Map();
|
|
330
|
-
const nodeMap = new Map();
|
|
331
|
-
const attrRecords = new Set();
|
|
332
|
-
const visited = new WeakSet();
|
|
333
|
-
const updateDelta = (cls, delta)=>deltaCounts.set(cls, (deltaCounts.get(cls) || 0) + delta);
|
|
334
|
-
const diffAndSnapshot = (el)=>{
|
|
335
|
-
const prev = new Set(elementClasses.get(el) || []);
|
|
336
|
-
const next = new Set(el.classList);
|
|
337
|
-
for (const c of next)if (!prev.has(c)) updateDelta(c, 1);
|
|
338
|
-
for (const c of prev)if (!next.has(c)) updateDelta(c, -1);
|
|
339
|
-
elementClasses.set(el, next);
|
|
340
|
-
};
|
|
341
|
-
const removeSnapshot = (el)=>{
|
|
342
|
-
for (const c of elementClasses.get(el) || [])updateDelta(c, -1);
|
|
343
|
-
elementClasses.delete(el);
|
|
344
|
-
};
|
|
345
|
-
for (const record of records){
|
|
346
|
-
if (record.type === 'childList') {
|
|
347
|
-
for (const node of record.addedNodes)if (node instanceof Element && node.isConnected) nodeMap.set(node, (nodeMap.get(node) || 0) + 1);
|
|
348
|
-
for (const node of record.removedNodes)if (node instanceof Element && !node.isConnected) nodeMap.set(node, (nodeMap.get(node) || 0) - 1);
|
|
349
|
-
} else if (record.type === 'attributes' && record.attributeName === 'class') {
|
|
350
|
-
attrRecords.add(record.target);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
const traverseIncludingSelf = (el, fn, visited)=>{
|
|
354
|
-
if (!visited.has(el)) {
|
|
355
|
-
visited.add(el);
|
|
356
|
-
fn(el);
|
|
357
|
-
for (const child of el.children){
|
|
358
|
-
traverseIncludingSelf(child, fn, visited);
|
|
359
|
-
}
|
|
360
|
-
} else {
|
|
361
|
-
nodeMap.delete(el);
|
|
362
|
-
}
|
|
363
|
-
};
|
|
364
|
-
for (const [node, count] of nodeMap){
|
|
365
|
-
if (count > 0) {
|
|
366
|
-
traverseIncludingSelf(node, diffAndSnapshot, visited);
|
|
367
|
-
} else if (count < 0 && !node.isConnected) {
|
|
368
|
-
traverseIncludingSelf(node, removeSnapshot, visited);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
for (const el of attrRecords){
|
|
372
|
-
if (!visited.has(el)) diffAndSnapshot(el);
|
|
373
|
-
}
|
|
374
|
-
for (const [cls, change] of deltaCounts){
|
|
375
|
-
const current = this.classCounts.get(cls) || 0;
|
|
376
|
-
const next = current + change;
|
|
377
|
-
if (next > 0) {
|
|
378
|
-
this.classCounts.set(cls, next);
|
|
379
|
-
if (current === 0) this.add(cls);
|
|
380
|
-
} else {
|
|
381
|
-
this.classCounts.delete(cls);
|
|
382
|
-
this.remove(cls);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
globalThis.__MASTER_CSS_DEVTOOLS_HOOK__?.emit('runtime:mutated', {
|
|
386
|
-
records,
|
|
387
|
-
classCounts: deltaCounts,
|
|
388
|
-
cssRuntime: this
|
|
389
|
-
});
|
|
390
|
-
});
|
|
391
|
-
this.observer.observe(this.root, {
|
|
392
|
-
childList: true,
|
|
393
|
-
attributes: true,
|
|
394
|
-
attributeFilter: [
|
|
395
|
-
'class'
|
|
396
|
-
],
|
|
397
|
-
attributeOldValue: true,
|
|
398
|
-
subtree: true
|
|
399
|
-
});
|
|
400
|
-
if (!this.progressive) this.host.removeAttribute('hidden');
|
|
401
|
-
this.observing = true;
|
|
402
|
-
globalThis.__MASTER_CSS_DEVTOOLS_HOOK__?.emit('runtime:observed', {
|
|
403
|
-
cssRuntime: this
|
|
404
|
-
});
|
|
405
|
-
return this;
|
|
406
|
-
}
|
|
407
|
-
hydrate(nativeLayerRules) {
|
|
408
|
-
const cssLayerRules = [];
|
|
409
|
-
const checkSheet = new CSSStyleSheet();
|
|
410
|
-
const result = {
|
|
411
|
-
allSyntaxRules: []
|
|
412
|
-
};
|
|
413
|
-
for(let i = 0; i < nativeLayerRules.length; i++){
|
|
414
|
-
const eachNativeCSSRule = nativeLayerRules[i];
|
|
415
|
-
if (eachNativeCSSRule.constructor.name === 'CSSLayerBlockRule') {
|
|
416
|
-
const eachCSSLayerRule = eachNativeCSSRule;
|
|
417
|
-
if (eachNativeCSSRule.name === 'theme') {
|
|
418
|
-
this.themeLayer.native = eachCSSLayerRule;
|
|
419
|
-
let variableRule;
|
|
420
|
-
const unresolvedCSSRules = new Map();
|
|
421
|
-
for (const rule of eachCSSLayerRule.cssRules){
|
|
422
|
-
// trim() for fix the firefox bug that the cssText ends with \n\n
|
|
423
|
-
unresolvedCSSRules.set(rule.cssText.trim(), rule);
|
|
424
|
-
}
|
|
425
|
-
for (const cssRule of eachCSSLayerRule.cssRules){
|
|
426
|
-
if (!unresolvedCSSRules.has(cssRule.cssText)) continue;
|
|
427
|
-
const variableCSSRule = cssRule.constructor.name === 'CSSMediaRule' ? cssRule.cssRules[0] : cssRule;
|
|
428
|
-
const variableName = variableCSSRule.style[0].slice(2);
|
|
429
|
-
const variable = this.variables.get(variableName);
|
|
430
|
-
if (!variable) continue;
|
|
431
|
-
variableRule = new css.VariableRule(variableName, variable, this);
|
|
432
|
-
this.themeLayer.rules.push(variableRule);
|
|
433
|
-
this.themeLayer.tokenCounts.set(variableRule.name, 0);
|
|
434
|
-
variableRule.nodes.forEach((node)=>{
|
|
435
|
-
const checkRuleIndex = checkSheet.insertRule(node.text);
|
|
436
|
-
const checkNodeNativeRule = checkSheet.cssRules.item(checkRuleIndex);
|
|
437
|
-
if (checkNodeNativeRule) {
|
|
438
|
-
const checkNodeNativeRuleText = checkNodeNativeRule.cssText.trim();
|
|
439
|
-
const match = unresolvedCSSRules.get(checkNodeNativeRuleText);
|
|
440
|
-
if (match) {
|
|
441
|
-
node.native = match;
|
|
442
|
-
unresolvedCSSRules.delete(checkNodeNativeRuleText);
|
|
443
|
-
return;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
if (this.themeLayer.rules.length) this.rules.push(this.themeLayer);
|
|
449
|
-
} else {
|
|
450
|
-
cssLayerRules.push(eachCSSLayerRule);
|
|
451
|
-
}
|
|
452
|
-
} else if (eachNativeCSSRule.constructor.name === 'CSSLayerStatementRule') {
|
|
453
|
-
this.layerStatementRule.native = eachNativeCSSRule;
|
|
454
|
-
} else if (eachNativeCSSRule.constructor.name === 'CSSKeyframesRule') {
|
|
455
|
-
const nativeKeyframsRule = eachNativeCSSRule;
|
|
456
|
-
const keyframes = this.animations.get(nativeKeyframsRule.name);
|
|
457
|
-
if (!keyframes) continue;
|
|
458
|
-
const animationRule = new css.AnimationRule(nativeKeyframsRule.name, keyframes, this);
|
|
459
|
-
animationRule.native = nativeKeyframsRule;
|
|
460
|
-
this.animationsNonLayer.rules.push(animationRule);
|
|
461
|
-
this.rules.push(animationRule);
|
|
462
|
-
this.animationsNonLayer.tokenCounts.set(animationRule.name, 0);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
for (const eachCSSLayerRule of cssLayerRules){
|
|
466
|
-
let layer;
|
|
467
|
-
switch(eachCSSLayerRule.name){
|
|
468
|
-
case 'base':
|
|
469
|
-
layer = this.baseLayer;
|
|
470
|
-
break;
|
|
471
|
-
case 'preset':
|
|
472
|
-
layer = this.presetLayer;
|
|
473
|
-
break;
|
|
474
|
-
case 'components':
|
|
475
|
-
layer = this.componentsLayer;
|
|
476
|
-
break;
|
|
477
|
-
case 'general':
|
|
478
|
-
layer = this.generalLayer;
|
|
479
|
-
break;
|
|
480
|
-
default:
|
|
481
|
-
console.error(`Cannot recognize the layer \`${eachCSSLayerRule.name}\`. (https://rc.css.master.co/messages/hydration-errors)`);
|
|
482
|
-
continue;
|
|
483
|
-
}
|
|
484
|
-
layer.native = eachCSSLayerRule;
|
|
485
|
-
const unresolvedCSSRules = new Map();
|
|
486
|
-
for (const rule of eachCSSLayerRule.cssRules){
|
|
487
|
-
// trim() for fix the firefox bug that the cssText ends with \n\n
|
|
488
|
-
unresolvedCSSRules.set(rule.cssText.trim(), rule);
|
|
489
|
-
}
|
|
490
|
-
for (const eachNativeLayerRule of eachCSSLayerRule.cssRules){
|
|
491
|
-
if (!unresolvedCSSRules.has(eachNativeLayerRule.cssText)) continue;
|
|
492
|
-
const selectorText = this.getSelectorText(eachNativeLayerRule);
|
|
493
|
-
if (!selectorText) {
|
|
494
|
-
console.error(`Cannot get the selector text from \`${eachNativeLayerRule.cssText}\`. (${layer.name}) (https://rc.css.master.co/messages/hydration-errors)`);
|
|
495
|
-
continue;
|
|
496
|
-
}
|
|
497
|
-
const createdRules = this.createFromSelectorText(selectorText);
|
|
498
|
-
if (createdRules) {
|
|
499
|
-
for (const createdRule of createdRules){
|
|
500
|
-
layer.rules.push(createdRule);
|
|
501
|
-
layer.insertVariables(createdRule);
|
|
502
|
-
layer.insertAnimations(createdRule);
|
|
503
|
-
result.allSyntaxRules.push(createdRule);
|
|
504
|
-
try {
|
|
505
|
-
const checkRuleIndex = checkSheet.insertRule(createdRule.text);
|
|
506
|
-
const checkNodeNativeRule = checkSheet.cssRules.item(checkRuleIndex);
|
|
507
|
-
if (checkNodeNativeRule) {
|
|
508
|
-
const checkNodeNativeRuleText = checkNodeNativeRule.cssText.trim();
|
|
509
|
-
const match = unresolvedCSSRules.get(checkNodeNativeRuleText);
|
|
510
|
-
if (match) {
|
|
511
|
-
createdRule.native = match;
|
|
512
|
-
unresolvedCSSRules.delete(checkNodeNativeRuleText);
|
|
513
|
-
continue;
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
console.error(`Cannot retrieve CSS rule for \`${createdRule.text}\`. (${layer.name}) (https://rc.css.master.co/messages/hydration-errors)`);
|
|
517
|
-
} catch (error) {
|
|
518
|
-
{
|
|
519
|
-
console.debug(`Cannot insert CSS rule for \`${createdRule.text}\`. (${layer.name}) (https://rc.css.master.co/messages/hydration-errors)`);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
} else {
|
|
524
|
-
console.error(`Cannot recognize \`${eachNativeLayerRule.cssText}\`. (${layer.name}) (https://rc.css.master.co/messages/hydration-errors)`);
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
if (layer.rules.length) this.rules.push(layer);
|
|
528
|
-
}
|
|
529
|
-
globalThis.__MASTER_CSS_DEVTOOLS_HOOK__?.emit('runtime:hydrated', {
|
|
530
|
-
cssRuntime: this,
|
|
531
|
-
result
|
|
532
|
-
});
|
|
533
|
-
return result;
|
|
534
|
-
}
|
|
535
|
-
getSelectorText(cssRule) {
|
|
536
|
-
if (cssRule instanceof CSSStyleRule) {
|
|
537
|
-
return cssRule.selectorText;
|
|
538
|
-
} else if (cssRule instanceof CSSGroupingRule) {
|
|
539
|
-
return this.getSelectorText(cssRule.cssRules.item(0));
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
disconnect() {
|
|
543
|
-
if (!this.observing) return;
|
|
544
|
-
if (this.observer) {
|
|
545
|
-
this.observer.disconnect();
|
|
546
|
-
this.observer = undefined;
|
|
547
|
-
}
|
|
548
|
-
// @ts-ignore
|
|
549
|
-
this.observing = false;
|
|
550
|
-
this.reset();
|
|
551
|
-
this.classCounts.clear();
|
|
552
|
-
if (!this.progressive) {
|
|
553
|
-
this.style?.remove();
|
|
554
|
-
this.style = null;
|
|
555
|
-
}
|
|
556
|
-
globalThis.__MASTER_CSS_DEVTOOLS_HOOK__?.emit('runtime:disconnected', {
|
|
557
|
-
cssRuntime: this
|
|
558
|
-
});
|
|
559
|
-
return this;
|
|
560
|
-
}
|
|
561
|
-
refresh(customConfig = this.customConfig) {
|
|
562
|
-
if (!this.observing || !this.style.sheet) return this;
|
|
563
|
-
for(let i = 1; i <= this.style.sheet.cssRules.length - 1; i++){
|
|
564
|
-
this.style.sheet.deleteRule(i);
|
|
565
|
-
}
|
|
566
|
-
super.refresh(customConfig);
|
|
567
|
-
/**
|
|
568
|
-
* 拿當前所有的 classNames 按照最新的 colors, config.rules 匹配並生成新的 style
|
|
569
|
-
* 所以 refresh 過後 rules 可能會變多也可能會變少
|
|
570
|
-
*/ this.classCounts.forEach((_, className)=>{
|
|
571
|
-
this.add(className);
|
|
572
|
-
});
|
|
573
|
-
globalThis.__MASTER_CSS_DEVTOOLS_HOOK__?.emit('runtime:refreshed', {
|
|
574
|
-
cssRuntime: this,
|
|
575
|
-
customConfig
|
|
576
|
-
});
|
|
577
|
-
return this;
|
|
578
|
-
}
|
|
579
|
-
destroy() {
|
|
580
|
-
this.disconnect();
|
|
581
|
-
globalThis.CSSRuntime.instances.delete(this.root);
|
|
582
|
-
globalThis.__MASTER_CSS_DEVTOOLS_HOOK__?.emit('runtime:destroyed', {
|
|
583
|
-
cssRuntime: this
|
|
584
|
-
});
|
|
585
|
-
return this;
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
(function(CSSRuntime) {
|
|
589
|
-
registerGlobal(CSSRuntime);
|
|
590
|
-
})(CSSRuntime);
|
|
591
|
-
|
|
592
|
-
/**
|
|
593
|
-
* Initialize a new CSSRuntime instance and observe the target root
|
|
594
|
-
* @param config master css config
|
|
595
|
-
* @param root target root to observe
|
|
596
|
-
* @param autoObserve auto observe the target root
|
|
597
|
-
* @returns master css instance
|
|
598
|
-
*/ function initCSSRuntime(config, root = document, autoObserve = true) {
|
|
599
|
-
let cssRuntime = globalThis.CSSRuntime.instances.get(root);
|
|
600
|
-
if (cssRuntime) return cssRuntime;
|
|
601
|
-
cssRuntime = new CSSRuntime(root, config, css.config);
|
|
602
|
-
if (autoObserve) cssRuntime.observe();
|
|
603
|
-
return cssRuntime;
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
exports.CSSRuntime = CSSRuntime;
|
|
607
|
-
exports.RuntimeSyntaxLayer = RuntimeSyntaxLayer;
|
|
608
|
-
exports.initCSSRuntime = initCSSRuntime;
|
package/dist/init.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import CSSRuntime from './core';
|
|
2
|
-
import type { Config } from '@master/css';
|
|
3
|
-
/**
|
|
4
|
-
* Initialize a new CSSRuntime instance and observe the target root
|
|
5
|
-
* @param config master css config
|
|
6
|
-
* @param root target root to observe
|
|
7
|
-
* @param autoObserve auto observe the target root
|
|
8
|
-
* @returns master css instance
|
|
9
|
-
*/
|
|
10
|
-
export default function initCSSRuntime(config?: Config, root?: Document | ShadowRoot, autoObserve?: boolean): CSSRuntime;
|
package/dist/syntax-layer.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import RuntimeLayer from './layer';
|
|
2
|
-
declare const RuntimeSyntaxLayer: {
|
|
3
|
-
new (...args: any[]): {
|
|
4
|
-
rules: import("@master/css").SyntaxRule[];
|
|
5
|
-
insert(syntaxRule: import("@master/css").SyntaxRule): number | undefined;
|
|
6
|
-
delete(key: string): import("@master/css").SyntaxRule | undefined;
|
|
7
|
-
insertVariables(syntaxRule: import("@master/css").SyntaxRule): void;
|
|
8
|
-
insertAnimations(syntaxRule: import("@master/css").SyntaxRule): void;
|
|
9
|
-
readonly tokenCounts: Map<string, number>;
|
|
10
|
-
name: string;
|
|
11
|
-
css: import("@master/css").MasterCSS;
|
|
12
|
-
attach(): void;
|
|
13
|
-
detach(): void;
|
|
14
|
-
reset(): void;
|
|
15
|
-
readonly text: string;
|
|
16
|
-
};
|
|
17
|
-
} & typeof RuntimeLayer;
|
|
18
|
-
export declare type RuntimeSyntaxLayerInstance = InstanceType<typeof RuntimeSyntaxLayer>;
|
|
19
|
-
export default RuntimeSyntaxLayer;
|