processLayerDirective method
Parses @layer ... and returns rules.
Note: layer blocks are represented as CSSLayerBlockRule (with nested
cssRules) instead of being flattened into top-level CSSStyleRules.
Supported:
@layer { ... }(anonymous layer block)@layer name { ... }(named layer block)@layer a, b;(layer order statement)@layer a.b;/@layer a.b { ... }(nested layer names)
Implementation
List<CSSRule>? processLayerDirective() {
_eat(TokenKind.DIRECTIVE_LAYER);
// `@layer { ... }`
if (_peekKind(TokenKind.LBRACE)) {
final anon = _resolveLayerPath(<String>[_createAnonymousLayerSegment()]);
final nodes = <CSSRule>[];
final prev = List<String>.from(_layerStack);
_layerStack
..clear()
..addAll(anon);
_eat(TokenKind.LBRACE);
nodes.addAll(processGroupRuleBody());
_eat(TokenKind.RBRACE);
_layerStack
..clear()
..addAll(prev);
return <CSSRule>[
CSSLayerBlockRule(
name: '',
layerNamePath: anon,
cssRules: nodes,
)
];
}
final rawNames = _processLayerNameList();
// `@layer a, b;`
if (_maybeEat(TokenKind.SEMICOLON)) {
if (rawNames.isEmpty) return null;
final resolved = rawNames.map(_resolveLayerPath).toList(growable: false);
return <CSSRule>[CSSLayerStatementRule(resolved)];
}
// `@layer name { ... }`
if (_peekKind(TokenKind.LBRACE)) {
final List<String> layerName = rawNames.isEmpty
? <String>[_createAnonymousLayerSegment()]
: rawNames.first;
final fullPath = _resolveLayerPath(layerName);
final nodes = <CSSRule>[];
final prev = List<String>.from(_layerStack);
_layerStack
..clear()
..addAll(fullPath);
_eat(TokenKind.LBRACE);
nodes.addAll(processGroupRuleBody());
_eat(TokenKind.RBRACE);
_layerStack
..clear()
..addAll(prev);
final String nameText = rawNames.isEmpty ? '' : rawNames.first.join('.');
return <CSSRule>[
CSSLayerBlockRule(
name: nameText,
layerNamePath: fullPath,
cssRules: nodes,
)
];
}
return null;
}