Skip to content

Commit

Permalink
add :not pseudo-class
Browse files Browse the repository at this point in the history
Close #1.
  • Loading branch information
eush77 committed Dec 19, 2015
1 parent 896d376 commit f6189ae
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ That's it!
- [x] Begins with: `[value^="prefix"]`
- [x] Containment: `[value*="substr"]`
- [x] Ends with: `[value$="suffix"]`
- [x] Negation pseudo-class: `*:not(paragraph)`

## API

Expand Down
22 changes: 18 additions & 4 deletions lib/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,14 @@ select.rule = function (selector, ast) {

// True if node matches head of selector rule.
function matches (rule, node) {
var match = true;

// Match type.
if (rule.tagName && rule.tagName != '*' && node.type != rule.tagName) {
return false;
}
match = match && (!rule.tagName || rule.tagName == '*' ||
rule.tagName == node.type);

// Match attributes.
return (rule.attrs || []).every(function (attr) {
match = match && (rule.attrs || []).every(function (attr) {
switch (attr.operator) {
case undefined:
return attr.name in node;
Expand Down Expand Up @@ -122,6 +123,19 @@ function matches (rule, node) {
throw Error('Undefined attribute operator: ' + attr.operator);
}
});

// Match pseudo classes.
match = match && (rule.pseudos || []).every(function (pseudo) {
switch (pseudo.name) {
case 'not':
return !matches(pseudo.value.rule, node);

default:
throw Error('Undefined pseudo-class: ' + pseudo.name);
}
});

return match;
}


Expand Down
1 change: 1 addition & 0 deletions lib/selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ module.exports = function SelectorParser () {
var parser = new Parser;
parser.registerNestingOperators('>', '+', '~');
parser.registerAttrEqualityMods('^', '*', '$');
parser.registerSelectorPseudos('not');
return parser.parse.bind(parser);
};
18 changes: 18 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,21 @@ test('attribute selectors', function (t) {

t.end();
});


test('negation pseudo-class', function (t) {
t.deepEqual(select(ast, 'list:not([nonexistent])'), select(ast, 'list'));
t.deepEqual(select(ast, 'list:not([start=null])'),
select(ast, 'list[start=1]'));
t.deepEqual(select(ast, 'heading text:not([value*=" "])')
.map(function (node) { return node.value }),
['Vitae', 'References', 'License']);
t.deepEqual(select(ast, [
'list:not([ordered=true])',
'*:not(listItem):not(paragraph)[children]:not(list)'
].join(' ')), [
path(ast, [4, 1, 1, 1, 0, 0]),
path(ast, [4, 1, 1, 1, 0, 0, 1])
]);
t.end();
});

0 comments on commit f6189ae

Please sign in to comment.