|
1 | | -import { MasterCSS, config as defaultConfig, Rule } from '@master/css' |
| 1 | +import { MasterCSS, config as defaultConfig, Rule, VariableRule, AnimationRule } from '@master/css' |
2 | 2 | import { type Config } from '@master/css' |
3 | 3 | import registerGlobal from './register-global' |
4 | 4 | import { HydrateResult } from './types' |
@@ -88,7 +88,7 @@ export default class CSSRuntime extends MasterCSS { |
88 | 88 | this.style.id = 'master' |
89 | 89 | this.container.append(this.style) |
90 | 90 | this.style.sheet!.insertRule(this.layerStatementRule.text) |
91 | | - this.layerStatementRule.nodes[0].native = this.style!.sheet!.cssRules.item(0) as CSSLayerStatementRule |
| 91 | + this.layerStatementRule.native = this.style!.sheet!.cssRules.item(0) as CSSLayerStatementRule |
92 | 92 | for (const eachConnectedName of connectedNames) { |
93 | 93 | this.add(eachConnectedName) |
94 | 94 | } |
@@ -230,37 +230,49 @@ export default class CSSRuntime extends MasterCSS { |
230 | 230 | const eachCSSLayerRule = eachNativeCSSRule as CSSLayerBlockRule |
231 | 231 | if ((eachNativeCSSRule as CSSLayerBlockRule).name === 'theme') { |
232 | 232 | this.themeLayer.native = eachCSSLayerRule |
233 | | - let variableRule: Rule | undefined |
234 | | - let lastVariableName: string | undefined |
235 | | - for (let j = 0; j < eachCSSLayerRule.cssRules.length; j++) { |
236 | | - const cssRule = eachCSSLayerRule.cssRules[j] |
| 233 | + let variableRule: VariableRule | undefined |
| 234 | + const unresolvedCSSRules = new Map<string, CSSRule>() |
| 235 | + for (const rule of eachCSSLayerRule.cssRules) { |
| 236 | + // trim() for fix the firefox bug that the cssText ends with \n\n |
| 237 | + unresolvedCSSRules.set(rule.cssText.trim(), rule) |
| 238 | + } |
| 239 | + for (const cssRule of eachCSSLayerRule.cssRules) { |
| 240 | + if (!unresolvedCSSRules.has(cssRule.cssText)) continue |
237 | 241 | const variableCSSRule = (cssRule.constructor.name === 'CSSMediaRule' |
238 | 242 | ? (cssRule as CSSMediaRule).cssRules[0] |
239 | 243 | : cssRule) as CSSStyleRule |
240 | 244 | const variableName = variableCSSRule.style[0].slice(2) |
241 | | - if (variableName !== lastVariableName) { |
242 | | - lastVariableName = variableName |
243 | | - variableRule = new Rule(variableName) |
244 | | - this.themeLayer.rules.push(variableRule) |
245 | | - this.themeLayer.tokenCounts.set(variableRule.name, 0) |
246 | | - } |
247 | | - variableRule?.nodes.push({ |
248 | | - native: cssRule, |
249 | | - text: cssRule.cssText |
| 245 | + const variable = this.variables.get(variableName) |
| 246 | + if (!variable) continue |
| 247 | + variableRule = new VariableRule(variableName, variable, this) |
| 248 | + this.themeLayer.rules.push(variableRule) |
| 249 | + this.themeLayer.tokenCounts.set(variableRule.name, 0) |
| 250 | + variableRule.nodes.forEach((node) => { |
| 251 | + const checkRuleIndex = checkSheet.insertRule(node.text) |
| 252 | + const checkNodeNativeRule = checkSheet.cssRules.item(checkRuleIndex) |
| 253 | + if (checkNodeNativeRule) { |
| 254 | + const checkNodeNativeRuleText = checkNodeNativeRule.cssText.trim() |
| 255 | + const match = unresolvedCSSRules.get(checkNodeNativeRuleText) |
| 256 | + if (match) { |
| 257 | + node.native = match |
| 258 | + unresolvedCSSRules.delete(checkNodeNativeRuleText) |
| 259 | + return |
| 260 | + } |
| 261 | + } |
250 | 262 | }) |
251 | 263 | } |
252 | 264 | if (this.themeLayer.rules.length) this.rules.push(this.themeLayer) |
253 | 265 | } else { |
254 | 266 | cssLayerRules.push(eachCSSLayerRule) |
255 | 267 | } |
256 | 268 | } else if (eachNativeCSSRule.constructor.name === 'CSSLayerStatementRule') { |
257 | | - this.layerStatementRule.nodes[0].native = eachNativeCSSRule as CSSLayerStatementRule |
| 269 | + this.layerStatementRule.native = eachNativeCSSRule as CSSLayerStatementRule |
258 | 270 | } else if (eachNativeCSSRule.constructor.name === 'CSSKeyframesRule') { |
259 | | - const keyframsRule = eachNativeCSSRule as CSSKeyframesRule |
260 | | - const animationRule = new Rule(keyframsRule.name, [{ |
261 | | - native: keyframsRule, |
262 | | - text: keyframsRule.cssText |
263 | | - }]) |
| 271 | + const nativeKeyframsRule = eachNativeCSSRule as CSSKeyframesRule |
| 272 | + const keyframes = this.animations.get(nativeKeyframsRule.name) |
| 273 | + if (!keyframes) continue |
| 274 | + const animationRule = new AnimationRule(nativeKeyframsRule.name, keyframes, this) |
| 275 | + animationRule.native = nativeKeyframsRule as unknown as CSSKeyframeRule |
264 | 276 | this.animationsNonLayer.rules.push(animationRule) |
265 | 277 | this.rules.push(animationRule) |
266 | 278 | this.animationsNonLayer.tokenCounts.set(animationRule.name, 0) |
@@ -306,26 +318,24 @@ export default class CSSRuntime extends MasterCSS { |
306 | 318 | layer.insertVariables(createdRule) |
307 | 319 | layer.insertAnimations(createdRule) |
308 | 320 | result.allSyntaxRules.push(createdRule) |
309 | | - createdRule.nodes.forEach((node) => { |
310 | | - try { |
311 | | - const checkRuleIndex = checkSheet.insertRule(node.text) |
312 | | - const checkNodeNativeRule = checkSheet.cssRules.item(checkRuleIndex) |
313 | | - if (checkNodeNativeRule) { |
314 | | - const checkNodeNativeRuleText = checkNodeNativeRule.cssText.trim() |
315 | | - const match = unresolvedCSSRules.get(checkNodeNativeRuleText) |
316 | | - if (match) { |
317 | | - node.native = match |
318 | | - unresolvedCSSRules.delete(checkNodeNativeRuleText) |
319 | | - return |
320 | | - } |
321 | | - } |
322 | | - console.error(`Cannot retrieve CSS rule for \`${node.text}\`. (${layer.name}) (https://rc.css.master.co/messages/hydration-errors)`) |
323 | | - } catch (error) { |
324 | | - if (process.env.NODE_ENV === 'development') { |
325 | | - console.debug(`Cannot insert CSS rule for \`${node.text}\`. (${layer.name}) (https://rc.css.master.co/messages/hydration-errors)`) |
| 321 | + try { |
| 322 | + const checkRuleIndex = checkSheet.insertRule(createdRule.text) |
| 323 | + const checkNodeNativeRule = checkSheet.cssRules.item(checkRuleIndex) |
| 324 | + if (checkNodeNativeRule) { |
| 325 | + const checkNodeNativeRuleText = checkNodeNativeRule.cssText.trim() |
| 326 | + const match = unresolvedCSSRules.get(checkNodeNativeRuleText) |
| 327 | + if (match) { |
| 328 | + createdRule.native = match |
| 329 | + unresolvedCSSRules.delete(checkNodeNativeRuleText) |
| 330 | + continue |
326 | 331 | } |
327 | 332 | } |
328 | | - }) |
| 333 | + console.error(`Cannot retrieve CSS rule for \`${createdRule.text}\`. (${layer.name}) (https://rc.css.master.co/messages/hydration-errors)`) |
| 334 | + } catch (error) { |
| 335 | + if (process.env.NODE_ENV === 'development') { |
| 336 | + console.debug(`Cannot insert CSS rule for \`${createdRule.text}\`. (${layer.name}) (https://rc.css.master.co/messages/hydration-errors)`) |
| 337 | + } |
| 338 | + } |
329 | 339 | } |
330 | 340 | } else { |
331 | 341 | console.error(`Cannot recognize \`${eachNativeLayerRule.cssText}\`. (${layer.name}) (https://rc.css.master.co/messages/hydration-errors)`) |
|
0 commit comments