We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
1 parent 2cb9c21 commit f51177dCopy full SHA for f51177d
README.md
@@ -61,7 +61,7 @@ That's it!
61
- [x] Ends with: `[value$="suffix"]`
62
- [ ] Structural pseudo-classes: `paragraph:first-of-type`
63
- [x] `:root`
64
- - [ ] `:nth-child(2n+1)`
+ - [x] `:nth-child(2n+1)`
65
- [ ] `:nth-last-child(2n+1)`
66
- [ ] `:nth-of-type(2n+1)`
67
- [ ] `:nth-last-of-type(2n+1)`
lib/match-node.js
@@ -4,10 +4,10 @@ module.exports = matchNode;
4
5
6
// Match node against a simple selector.
7
-function matchNode (rule, node, parent) {
+function matchNode (rule, node, nodeIndex, parent) {
8
return matchType(rule, node) &&
9
matchAttrs(rule, node) &&
10
- matchPseudos(rule, node, parent);
+ matchPseudos(rule, node, nodeIndex, parent);
11
}
12
13
@@ -58,14 +58,17 @@ function matchAttrs (rule, node) {
58
59
60
-function matchPseudos (rule, node, parent) {
+function matchPseudos (rule, node, nodeIndex, parent) {
return !rule.pseudos || rule.pseudos.every(function (pseudo) {
switch (pseudo.name) {
case 'root':
return parent == null;
+ case 'nth-child':
68
+ return pseudo.value(nodeIndex);
69
+
70
case 'not':
- return !matchNode(pseudo.value.rule, node, parent);
71
+ return !matchNode(pseudo.value.rule, node, nodeIndex, parent);
72
73
default:
74
throw Error('Undefined pseudo-class: ' + pseudo.name);
lib/select.js
@@ -41,7 +41,7 @@ select.rule = function (rule, ast) {
41
42
43
function match (rule, node, nodeIndex, parent) {
44
- if (matchNode(rule, node, parent)) {
+ if (matchNode(rule, node, nodeIndex, parent)) {
45
if (rule.rule) {
46
search(rule.rule, node, nodeIndex, parent);
47
lib/selector.js
@@ -1,12 +1,49 @@
1
'use strict';
2
3
-var Parser = require('css-selector-parser').CssSelectorParser;
+var Parser = require('css-selector-parser').CssSelectorParser,
+ nthCheck = require('nth-check');
module.exports = function parseSelector (selector) {
var parser = new Parser;
parser.registerNestingOperators('>', '+', '~');
parser.registerAttrEqualityMods('^', '*', '$');
parser.registerSelectorPseudos('not');
- return parser.parse(selector);
+ return compileNthChecks(parser.parse(selector));
};
14
15
16
+function compileNthChecks (ast) {
17
+ if (ast == null) {
18
+ return ast;
19
+ }
20
21
+ switch (ast.type) {
22
+ case 'selectors':
23
+ ast.selectors.forEach(compileNthChecks);
24
+ break;
25
26
+ case 'ruleSet':
27
+ compileNthChecks(ast.rule);
28
29
30
+ case 'rule':
31
+ if (ast.pseudos) {
32
+ ast.pseudos.forEach(function (pseudo) {
33
+ if (pseudo.name == 'nth-child') {
34
+ pseudo.value = nthCheck(pseudo.value);
35
+ pseudo.valueType = 'function';
36
37
+ });
38
39
+ if (ast.rule) {
40
+ default:
+ throw Error('Undefined AST node: ' + ast.type);
48
49
+}
package.json
@@ -41,7 +41,8 @@
],
"dependencies": {
"css-selector-parser": "^1.1.0",
- "debug": "^2.2.0"
+ "debug": "^2.2.0",
+ "nth-check": "^1.0.1"
},
"devDependencies": {
"tape": "^4.2.0"
test/select.js
@@ -139,6 +139,21 @@ test('structural pseudo-classes', function (t) {
139
t.end();
140
});
141
142
+ t.test(':nth-child', function (t) {
143
+ t.deepEqual(select(ast, ':root:nth-child(0)'), []);
144
+ t.deepEqual(select(ast, ':root:nth-child(n)'), [ast]);
145
+ t.deepEqual(select(ast, 'root > list:nth-child(2n+5)'),
146
+ select(ast, 'root > list'));
147
+ t.deepEqual(select(ast, 'heading:nth-child(even)'), [
148
+ path(ast, [1]),
149
+ path(ast, [7])
150
+ ]);
151
+ t.deepEqual(select(ast, ':nth-child(3n+2)[type=inlineCode]')
152
+ .map(function (node) { return node.value }),
153
+ ['integer', 'proin', 'tan']);
154
+ t.end();
155
156
157
158
159
0 commit comments