Skip to content

Commit 42ba90e

Browse files
committed
feat: Add support for CSS feature modules in parser configuration
1 parent e5fd208 commit 42ba90e

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ export {
2121
AstWildcardNamespace,
2222
AstWildcardTag
2323
} from './ast.js';
24-
export {CssLevel, SyntaxDefinition} from './syntax-definitions.js';
24+
export {CssLevel, CssFeature, SyntaxDefinition} from './syntax-definitions.js';

src/parser.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ import {
2323
PseudoSignature
2424
} from './pseudo-signatures.js';
2525
import {
26+
CssFeature,
2627
CssLevel,
28+
cssFeatures,
2729
cssSyntaxDefinitions,
2830
extendSyntaxDefinition,
2931
getXmlOptions,
@@ -74,14 +76,30 @@ export function createParser(
7476
* Default: `true`
7577
*/
7678
strict?: boolean;
79+
/**
80+
* Additional CSS features to include in the syntax definition.
81+
* These are specific CSS modules that add new selectors or modify existing ones.
82+
* @example ['css-position-3', 'css-scoping-1']
83+
*/
84+
features?: CssFeature[];
7785
} = {}
7886
): Parser {
79-
const {syntax = 'latest', substitutes, strict = true} = options;
87+
const {syntax = 'latest', substitutes, strict = true, features} = options;
8088
let syntaxDefinition: SyntaxDefinition = typeof syntax === 'object' ? syntax : cssSyntaxDefinitions[syntax];
8189

8290
if (syntaxDefinition.baseSyntax) {
8391
syntaxDefinition = extendSyntaxDefinition(cssSyntaxDefinitions[syntaxDefinition.baseSyntax], syntaxDefinition);
8492
}
93+
94+
// Apply additional features if specified
95+
if (features && features.length > 0) {
96+
for (const feature of features) {
97+
const featureSyntax = cssFeatures[feature];
98+
if (featureSyntax) {
99+
syntaxDefinition = extendSyntaxDefinition(syntaxDefinition, featureSyntax);
100+
}
101+
}
102+
}
85103

86104
const [tagNameEnabled, tagNameWildcardEnabled] = syntaxDefinition.tag
87105
? [true, Boolean(getXmlOptions(syntaxDefinition.tag).wildcard)]

src/syntax-definitions.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ export type PseudoClassType = Exclude<'NoArgument' | AstPseudoClassArgument['typ
44
export type PseudoElementType = Exclude<'NoArgument' | AstPseudoElementArgument['type'], 'Substitution'>;
55
export type CssLevel = 'css1' | 'css2' | 'css3' | 'selectors-3' | 'selectors-4' | 'latest' | 'progressive';
66

7+
/**
8+
* CSS Feature module name.
9+
* @example 'css-position-3'
10+
* @example 'css-scoping-1'
11+
*/
12+
export type CssFeature = string;
13+
714
/**
815
* CSS Selector Syntax Definition can be used to define custom CSS selector parsing rules.
916
*/
@@ -404,3 +411,39 @@ export const cssSyntaxDefinitions: Record<CssLevel, SyntaxDefinition> = {
404411
latest: selectors4SyntaxDefinition,
405412
progressive: progressiveSyntaxDefinition
406413
};
414+
415+
/**
416+
* CSS Feature modules with their syntax definitions.
417+
* These can be used to extend the parser with specific CSS features.
418+
*
419+
* @example
420+
* // Using the css-position-3 feature
421+
* createParser({ features: ['css-position-3'] })
422+
*/
423+
export const cssFeatures: Record<string, SyntaxDefinition> = {
424+
'css-position-3': {
425+
pseudoClasses: {
426+
definitions: {
427+
NoArgument: ['sticky', 'fixed', 'absolute', 'relative', 'static']
428+
}
429+
}
430+
},
431+
'css-position-4': {
432+
pseudoClasses: {
433+
definitions: {
434+
NoArgument: ['sticky', 'fixed', 'absolute', 'relative', 'static', 'initial']
435+
}
436+
}
437+
},
438+
'css-scoping-1': {
439+
pseudoClasses: {
440+
definitions: {
441+
NoArgument: ['host', 'host-context'],
442+
Selector: ['host', 'host-context']
443+
}
444+
},
445+
pseudoElements: {
446+
definitions: ['slotted']
447+
}
448+
}
449+
};

0 commit comments

Comments
 (0)