Comparing version 0.1.0 to 0.2.0
48
index.js
@@ -36,24 +36,25 @@ var traverse = require("traverse"), | ||
path.reverse(); | ||
path.push(""); | ||
if (!matchesPart(parts.shift(), path.shift())) { | ||
// last part of selector should match node | ||
return false; | ||
} | ||
// walk up the ancestors | ||
var must = true; | ||
while(parts.length && path.length) { | ||
var part = parts[0], | ||
key = path[0]; | ||
if (part == ">") { | ||
if (!matchesPart(parts[1], key)) { | ||
return false; | ||
} | ||
parts.shift(); | ||
must = true; | ||
continue; | ||
} | ||
else { | ||
if (matchesPart(part, key)) { | ||
parts.shift(); | ||
} | ||
path.shift(); | ||
if (matchesKey(part, key)) { | ||
parts.shift(); | ||
} | ||
else if(must) { | ||
return false; | ||
} | ||
path.shift(); | ||
must = false; | ||
} | ||
@@ -63,5 +64,20 @@ return parts.length == 0; | ||
function matchesPart(part, key) { | ||
return traverse.deepEqual(part, {}) | ||
|| (part.id && part.id == key); | ||
function matchesKey(part, key) { | ||
if (part.id && part.id != key) { | ||
return false; | ||
} | ||
if (part.pf == ":nth-child") { | ||
if (part.a == 0 | ||
&& (parseInt(key) + 1) !== part.b) { | ||
return false; | ||
} | ||
else if (part.a == 2 | ||
&& (parseInt(key) % 2) != part.b) { | ||
return false ; | ||
} | ||
} | ||
if (part.pc == ":root" && key != "") { | ||
return false; | ||
} | ||
return true; | ||
} |
{ | ||
"name": "js-select", | ||
"description": "Traverse and modify JavaScript objects with JSONSelect selectors", | ||
"version": "0.1.0", | ||
"description": "Traverse and modify objects with JSONSelect selectors", | ||
"version": "0.2.0", | ||
"author": "Heather Arthur <fayearthur@gmail.com>", | ||
@@ -6,0 +6,0 @@ "repository": { |
# js-select | ||
js-select is a little mashup of [js-traverse](https://github.com/substack/js-traverse) and a subset of [JSONSelect](http://jsonselect.org/). | ||
js-select uses [js-traverse](https://github.com/substack/js-traverse) to traverse and modify JavaScript object nodes that match [JSONSelect](http://jsonselect.org/) selectors: | ||
It lets you traverse and modify JavaScript object nodes that match JSONSelect selectors: | ||
```javascript | ||
@@ -12,8 +10,8 @@ var select = require("js-select"); | ||
george: { | ||
age : 35, | ||
movie: "Repo Man" | ||
age : 35, | ||
movie: "Repo Man" | ||
}, | ||
mary: { | ||
age: 15, | ||
movie: "Twilight" | ||
age: 15, | ||
movie: "Twilight" | ||
} | ||
@@ -23,4 +21,3 @@ } | ||
select(people, ".age").forEach(function(age) { | ||
// make everyone look younger! | ||
this.update(age - 5); | ||
this.update(age - 5); | ||
}) | ||
@@ -31,9 +28,9 @@ | ||
See [js-traverse](https://github.com/substack/js-traverse) for all the things you can do to modify the node. The `forEach()` callback will get the same context (`this`) as the `forEach()` callback in [js-traverse](https://github.com/substack/js-traverse), plus a `this.matches()` which will test if the node matches a selector: | ||
See [js-traverse](https://github.com/substack/js-traverse) for all the things you can do to modify the node. The `forEach()` callback will get the same `this` context as the `forEach()` callback from [js-traverse](https://github.com/substack/js-traverse), plus a `this.matches()` which will test if the node matches a selector: | ||
```javascript | ||
select(obj).forEach(function(node) { | ||
if(this.matches(".movie")) { | ||
this.update(node.toLowerCase()); | ||
} | ||
if (this.matches(".mary > .movie")) { | ||
this.update(node.toLowerCase()); | ||
} | ||
} | ||
@@ -51,2 +48,7 @@ ``` | ||
".parent > .key" | ||
":root" | ||
":nth-child(n)" | ||
":nth-child(even)" | ||
":nth-child(odd)" | ||
":first-child" | ||
``` | ||
@@ -53,0 +55,0 @@ |
@@ -6,9 +6,12 @@ var select = require("./index"); | ||
age: 15, | ||
movie: { | ||
movies: [{ | ||
name: "Twilight", | ||
stars: 3 | ||
} | ||
}, | ||
{ name: "Clueless", | ||
stars: 5 | ||
}] | ||
} | ||
}; | ||
console.log(select(people, ".movie > .stars").nodes()) | ||
console.log(select(people, ":root").nodes()) |
@@ -19,2 +19,10 @@ var assert = require("assert"), | ||
stars: 3 | ||
}, | ||
{ | ||
name: "Trudy", | ||
stars: 2 | ||
}, | ||
{ | ||
name: "The Fighter", | ||
stars: 4 | ||
}] | ||
@@ -25,12 +33,17 @@ } | ||
assert.deepEqual(select(people, "*").nodes(), [{"george":{"age":35,"movies":[{"name":"Repo Man","stars":5}]},"mary":{"age":15,"movies":[{"name":"Twilight","stars":3}]}},{"age":35,"movies":[{"name":"Repo Man","stars":5}]},35,[{"name":"Repo Man","stars":5}],{"name":"Repo Man","stars":5},"Repo Man",5,{"age":15,"movies":[{"name":"Twilight","stars":3}]},15,[{"name":"Twilight","stars":3}],{"name":"Twilight","stars":3},"Twilight",3]); | ||
assert.deepEqual(select(people, "*").nodes(), [{"george":{"age":35,"movies":[{"name":"Repo Man","stars":5}]},"mary":{"age":15,"movies":[{"name":"Twilight","stars":3},{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4}]}},{"age":35,"movies":[{"name":"Repo Man","stars":5}]},35,[{"name":"Repo Man","stars":5}],{"name":"Repo Man","stars":5},"Repo Man",5,{"age":15,"movies":[{"name":"Twilight","stars":3},{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4}]},15,[{"name":"Twilight","stars":3},{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4}],{"name":"Twilight","stars":3},"Twilight",3,{"name":"Trudy","stars":2},"Trudy",2,{"name":"The Fighter","stars":4},"The Fighter",4]); | ||
assert.deepEqual(select(people, ".george").nodes(), [{"age":35,"movies":[{"name":"Repo Man","stars":5}]}]); | ||
assert.deepEqual(select(people, ".george .age").nodes(), [35]); | ||
assert.deepEqual(select(people, ".george .name").nodes(), ["Repo Man"]); | ||
assert.deepEqual(select(people, ".mary *").nodes(), [15,[{"name":"Twilight","stars":3}],{"name":"Twilight","stars":3},"Twilight",3]) | ||
assert.deepEqual(select(people, ".george *").nodes(), [35,[{"name":"Repo Man","stars":5}],{"name":"Repo Man","stars":5},"Repo Man",5]) | ||
assert.deepEqual(select(people, ".mary > *").nodes(), [15,[{"name":"Twilight","stars":3}]]); | ||
assert.deepEqual(select(people, ".george > *").nodes(), [35,[{"name":"Repo Man","stars":5}]]); | ||
assert.deepEqual(select(people, ".george > .name").nodes(), []); | ||
assert.deepEqual(select(people, ":nth-child(2)").nodes(), [{"name":"Trudy","stars":2}]); | ||
assert.deepEqual(select(people, ":nth-child(even)").nodes(), [{"name":"Repo Man","stars":5},{"name":"Twilight","stars":3},{"name":"The Fighter","stars":4}]); | ||
assert.deepEqual(select(people, ":nth-child(odd)").nodes(), [{"name":"Trudy","stars":2}]); | ||
assert.deepEqual(select(people, ":root").nodes(), [{"george":{"age":35,"movies":[{"name":"Repo Man","stars":5}]},"mary":{"age":15,"movies":[{"name":"Twilight","stars":3},{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4}]}}]); | ||
// invalid | ||
@@ -61,8 +74,6 @@ assert.deepEqual(select(people, ".hmmm").nodes(), []); | ||
var t1 = Date.now(); | ||
console.time("big") | ||
assert.deepEqual(select(timeline, ".bug .id").nodes().length, 126); | ||
assert.deepEqual(select(timeline, ".id").nodes().length, 141); | ||
assert.deepEqual(select(timeline, ".comments .id").nodes().length, 115); | ||
var t2 = Date.now() - t1; | ||
console.log(t2); | ||
console.timeEnd("big") |
86336
8
151
61