Skip to content

Commit dffc7af

Browse files
committed
Add specificity information
1 parent 19e3558 commit dffc7af

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

selector-grammar.ne

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,27 +51,40 @@ selectors_group -> _ selector (_ "," _ selector):* _
5151
} %}
5252

5353
selector -> simple_selector_sequence (combinator simple_selector_sequence):*
54-
{% (d) => { return {type: 'selector', nodes: collectObjects(d)} } %}
54+
{% (d) => {
55+
var nodes = collectObjects(d)
56+
, specificity = {a: 0, b: 0, c: 0, d: 0}
57+
;
58+
59+
// calculate the specificity @see: https://www.w3.org/TR/2009/CR-CSS2-20090908/cascade.html#specificity
60+
for (var i = 0; i < nodes.length; i++) {
61+
if (nodes[i].specificityType) {
62+
specificity[nodes[i].specificityType]++;
63+
}
64+
}
65+
66+
return {type: 'selector', nodes, specificity};
67+
} %}
5568

5669
combinator -> ( _ [+>~] _ | __ )
57-
{% (d, location) => { return {type: combinatorTypes[d[0][1] || ' '], location, raw: collapseRaw(d)} } %}
70+
{% (d, location) => { return {type: combinatorTypes[d[0][1] || ' '], location, raw: collapseRaw(d), specificityType: null} } %}
5871

5972
simple_selector_sequence -> ( type_selector | universal ) simple_selector:* | simple_selector:+
6073

6174
simple_selector -> hash | class | attrib | pseudo | negation
6275

6376
# selectors
6477
universal -> namespace_prefix:? "*"
65-
{% (d, location) => { return {type: 'universalSelector', namespace: d[0] ? d[0].name : d[0], location, raw: collapseRaw(d)} } %}
78+
{% (d, location) => { return {type: 'universalSelector', namespace: d[0] ? d[0].name : d[0], location, raw: collapseRaw(d), specificityType: null} } %}
6679
type_selector -> namespace_prefix:? ident
67-
{% (d, location) => { return {type: 'typeSelector', namespace: d[0] ? d[0].name : d[0], name: collapse(d[1]), location, raw: collapseRaw(d)} } %}
80+
{% (d, location) => { return {type: 'typeSelector', namespace: d[0] ? d[0].name : d[0], name: collapse(d[1]), location, raw: collapseRaw(d), specificityType: 'd'} } %}
6881
hash -> "#" name
69-
{% (d, location) => { return {type: 'idSelector', name: collapse(d[1]), location, raw: collapseRaw(d)} } %}
82+
{% (d, location) => { return {type: 'idSelector', name: collapse(d[1]), location, raw: collapseRaw(d), specificityType: 'b'} } %}
7083
class -> "." ident
71-
{% (d, location) => { return {type: 'classSelector', name: collapse(d[1]), location, raw: collapseRaw(d)} } %}
84+
{% (d, location) => { return {type: 'classSelector', name: collapse(d[1]), location, raw: collapseRaw(d), specificityType: 'c'} } %}
7285
attrib -> "[" _ namespace_prefix:? ident _ ( [~|^$*]:? "=" _ ( ident | string ) ):? "]"
7386
{% (d, location) => {
74-
var obj = {namespace: d[2] ? d[2].name : d[2], name: collapse(d[3]), location, raw: collapseRaw(d)};
87+
var obj = {namespace: d[2] ? d[2].name : d[2], name: collapse(d[3]), location, raw: collapseRaw(d), specificityType: 'c'};
7588
if (d[5] && d[5].length) {
7689
obj.type = 'attributeValueSelector';
7790
obj.operator = (d[5][0] || '') + '=';
@@ -95,15 +108,17 @@ pseudo -> ":" ":":? ( ident | functional_pseudo )
95108
return reject;
96109
}
97110
obj.type = 'pseudoElementSelector';
111+
obj.specificityType = 'd';
98112
} else {
99113
obj.type = 'pseudoClassSelector';
114+
obj.specificityType = 'c';
100115
obj.expression = d[2][0].expression || null;
101116
obj.expressionRaw = d[2][0].expressionRaw || null;
102117
}
103118
return obj;
104119
} %}
105120
negation -> ":" [nN] [oO] [tT] "(" _ negation_arg _ ")"
106-
{% (d, location) => { return {type: 'negationSelector', selectors: d[6], location, raw: collapseRaw(d)} } %}
121+
{% (d, location) => { return {type: 'negationSelector', selectors: d[6], location, raw: collapseRaw(d), specificityType: null} } %}
107122

108123
# selector helpers
109124
namespace_prefix -> ( ident | "*" ):? "|"

0 commit comments

Comments
 (0)