forked from katiefenn/parker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TopSelectorSpecificity.js
121 lines (91 loc) · 2.97 KB
/
TopSelectorSpecificity.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*! Parker v0.0.0 - MIT license */
'use strict';
var _ = require('lodash');
module.exports = {
id: 'top-selector-specificity',
name: 'Top Selector Specificity',
type: 'selector',
aggregate: 'max',
format: 'number',
measure: function (selector) {
var identifiers = getIdentifiers(selector),
specificity = 0;
_.each(identifiers, function (identifier) {
var idIdentifiers = countIdIdentifiers(identifier),
classIdentifiers = countClassIdentifiers(identifier),
attributeIdentifiers = countAttributeIdentifiers(identifier),
pseudoClassIdentifiers = countPseudoClassIdentifiers(identifier),
typeIdentifiers = countTypeIdentifiers(identifier),
pseudoElementIdentifiers = countPseudoElementIdentifiers(identifier);
specificity += getSpecificity(idIdentifiers, classIdentifiers, attributeIdentifiers, pseudoClassIdentifiers, typeIdentifiers, pseudoElementIdentifiers);
}, this);
return specificity;
}
};
var getIdentifiers = function (selector) {
var identifiers = [],
segments = selector.split(/\s+[\s\+>]\s?|~^=/g);
_.each(segments, function (segment) {
identifiers = identifiers.concat(segment.match(/[#\.:]?[\w\-\*]+|\[[\w=\-~'"\|]+\]|:{2}[\w-]+/g));
});
return identifiers;
};
var getSpecificity = function (idIdentifiers, classIdentifiers, attributeIdentifiers, pseudoClassIdentifiers, typeIdentifiers, pseudoElementIdentifiers) {
return Number(
String(idIdentifiers) +
String(classIdentifiers + attributeIdentifiers + pseudoClassIdentifiers) +
String(typeIdentifiers + pseudoElementIdentifiers)
);
};
var countIdIdentifiers = function (identifier) {
var regex = /#/,
matches = regex.exec(identifier);
if (matches) {
return matches.length;
}
return 0;
};
var countClassIdentifiers = function (identifier) {
var regex = /\./,
matches = regex.exec(identifier);
if (matches) {
return matches.length;
}
return 0;
};
var countAttributeIdentifiers = function (identifier) {
var regex = /\[/,
matches = regex.exec(identifier);
if (matches) {
return matches.length;
}
return 0;
};
var countPseudoClassIdentifiers = function (identifier) {
var regex = /:[^:]/,
matches = regex.exec(identifier);
// :not pseudo-class identifier itself is ignored
// only selectors inside it are counted
if (identifier.match(/:not/)) {
return 0;
}
if (matches) {
return matches.length;
}
return 0;
};
var countTypeIdentifiers = function (identifier) {
var regex = /^[a-zA-Z_]/;
if (regex.exec(identifier)) {
return 1;
}
return 0;
};
var countPseudoElementIdentifiers = function (identifier) {
var regex = /::/,
matches = regex.exec(identifier);
if (matches) {
return matches.length;
}
return 0;
};