Socket
Socket
Sign inDemoInstall

esquery

Package Overview
Dependencies
0
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.0 to 0.2.0

tests/queryField.js

184

esquery.js

@@ -7,3 +7,3 @@ (function () {

var STR = '("(?:\\"|[^"])*")';
var OP = "(\\*)";
var OP = "(\\*|\\.|#)";
var S_DOP_S = "\\s*(!=|<=|>=)\\s*";

@@ -54,3 +54,3 @@ var S_OP = "\\s*(\\]|\\)|!)";

};
} else if (/!=|<=|>=|<|>|,|~|=|!|:|\+|\[|\]|\(|\)|\s/.test(token)) {
} else if (/!=|<=|>=|<|>|,|~|=|!|:|#|\.|\+|\[|\]|\(|\)|\s/.test(token)) {
return {

@@ -109,9 +109,2 @@ type: "operator",

var operatorMap = {
" ": "descendant",
">": "child",
"~": "sibling",
"+": "adjacent"
};
function peekOp(tokens, opValue) {

@@ -148,21 +141,31 @@ if (tokens.length > 0 && peekType(tokens, "operator") &&

var operatorMap = {
" ": "descendant",
">": "child",
"~": "sibling",
"+": "adjacent"
};
function consumeComplexSelector(tokens) {
var selector;
selector = consumeCompoundSelector(tokens);
if (tokens.length > 0) {
if (peekOp(tokens, /[\s+~>]/)) {
var op = tokens.shift()
var right = consumeComplexSelector(tokens)
if (right) {
selector = {
type: operatorMap[op.value],
left: selector,
right: right
};
} else {
throw createError("Invalid right side of complex selector: ", op, tokens);
}
var result, selector;
result = consumeCompoundSelector(tokens);
while (peekOp(tokens, /[\s+~>]/)) {
op = tokens.shift();
selector = consumeCompoundSelector(tokens);
if (selector) {
result = {
type: operatorMap[op.value],
operator: op.value,
left: result,
right: selector
};
} else {
throw createError("Expected compound selector: ", op, tokens);
}
}
return selector;
return result || selector;
}

@@ -210,2 +213,11 @@

selector = consumeAttribute(tokens);
} else if (peekOp(tokens, ".")) {
selector = consumeField(tokens);
} else if (peekOp(tokens, "#")) {
tokens.shift();
selector = consumeType(tokens, /keyword|identifier/);
selector = {
type: "identifier",
value: selector.value
};
}

@@ -269,2 +281,15 @@

function consumeName(tokens) {
var name = "";
while (!name || peekOp(tokens, ".")) {
if (name) {
consumeOp(tokens, ".");
name += ".";
}
name += consumeType(tokens, /keyword|identifier/).value;
}
return name;
}
/**

@@ -275,3 +300,3 @@ * Consume an attribute selector ([])

var op = consumeOp(tokens, "[");
var id = consumeType(tokens, /keyword|identifier/);
var name = consumeName(tokens);

@@ -282,3 +307,3 @@ op = consumeType(tokens, "operator");

type: "attribute",
name: id.value
name: name
};

@@ -288,3 +313,3 @@ } else {

type: "attribute",
name: id.value,
name: name,
operator: op.value,

@@ -299,2 +324,14 @@ value: consumeValue(tokens)

/**
* Consume the various types of pseudo selectors (:*-child).
*/
function consumeField(tokens) {
var op = consumeOp(tokens, ".");
var name = consumeName(tokens, /keyword|identifier/);
return {
type: "field",
name: name
};
}
function consumeArgList(tokens) {

@@ -375,13 +412,14 @@ consumeOp(tokens, "(");

*/
function visitPre(ast, fn) {
fn(ast);
function visitPre(ast, fn, path) {
fn(ast, path);
var key;
var key, newPath;
for (key in ast) {
newPath = path ? path + "." + key : key;
if (ast[key] && ast[key].forEach) {
ast[key].forEach(function (node) {
visitPre(node, fn);
visitPre(node, fn, newPath);
});
} else if (ast[key] && ast[key].type) {
visitPre(ast[key], fn);
visitPre(ast[key], fn, newPath);
}

@@ -415,3 +453,3 @@ }

for (i = 0; i < keys.length; i++) {
if (value[keys[i]] !== undefined) {
if (value && value[keys[i]] !== undefined) {
value = value[keys[i]];

@@ -445,3 +483,3 @@ } else {

*/
function match(ast, selector) {
function match(ast, selector, cache) {
var leftResults, rightResults, subject = [], matches = [];

@@ -459,3 +497,3 @@ var results = {

case "wildcard":
visitPre(ast, function (node) {
cache.nodes.forEach(function (node) {
matches.push(node);

@@ -470,4 +508,4 @@

case "identifier":
visitPre(ast, function (node) {
if (node.type === selector.value) {
if (cache.types.hasOwnProperty(selector.value)) {
cache.types[selector.value].forEach(function (node) {
matches.push(node);

@@ -478,4 +516,4 @@

}
}
});
});
}
break;

@@ -485,3 +523,3 @@

case "nth-child":
visitPre(ast, function (node, context) {
visitPre(ast, function (node) {
var index = selector.index.value;

@@ -505,3 +543,3 @@ Object.keys(node).forEach(function (key) {

case "nth-last-child":
visitPre(ast, function (node, context) {
visitPre(ast, function (node) {
var index = selector.index.value;

@@ -579,6 +617,21 @@ Object.keys(node).forEach(function (key) {

case "field":
visitPre(ast, function (node, path) {
if (path) {
var i = path.indexOf(selector.name);
if (i > -1 && i === path.length - selector.name.length) {
matches.push(node);
if (selector.subject) {
subject.push([node]);
}
}
}
});
break;
case "matches":
selector.selectors.forEach(function (matchesSelector) {
finalMatches(match(ast, matchesSelector)).forEach(function (node) {
finalMatches(match(ast, matchesSelector, cache)).forEach(function (node) {
matches.push(node);

@@ -596,3 +649,3 @@

selector.selectors.forEach(function (selector) {
rightResults = rightResults.concat(finalMatches(match(ast, selector)));
rightResults = rightResults.concat(finalMatches(match(ast, selector, cache)));
});

@@ -614,3 +667,3 @@

selector.selectors.forEach(function (selector) {
rightResults.push(finalMatches(match(ast, selector)));
rightResults.push(finalMatches(match(ast, selector, cache)));
});

@@ -637,4 +690,4 @@

case "descendant":
leftResults = match(ast, selector.left);
rightResults = match(ast, selector.right)
leftResults = match(ast, selector.left, cache);
rightResults = match(ast, selector.right, cache);

@@ -665,4 +718,4 @@ leftResults.matches.forEach(function (leftNode, leftI) {

case "child":
leftResults = match(ast, selector.left);
rightResults = match(ast, selector.right);
leftResults = match(ast, selector.left, cache);
rightResults = match(ast, selector.right, cache);

@@ -693,4 +746,4 @@ leftResults.matches.forEach(function (leftNode, leftI) {

case "sibling":
leftResults = match(ast, selector.left);
rightResults = match(ast, selector.right);
leftResults = match(ast, selector.left, cache);
rightResults = match(ast, selector.right, cache);

@@ -732,4 +785,4 @@ visitPre(ast, function (node, context) {

case "adjacent":
leftResults = match(ast, selector.left);
rightResults = match(ast, selector.right);
leftResults = match(ast, selector.left, cache);
rightResults = match(ast, selector.right, cache);

@@ -771,2 +824,22 @@ visitPre(ast, function (node, context) {

// Holds cached info to speed up matches
function Cache(ast) {
this.ast = ast;
var nodes = [];
var types = {};
visitPre(ast, function (node) {
nodes.push(node);
if (!types.hasOwnProperty(node.type)) {
types[node.type] = [];
}
types[node.type].push(node);
});
this.nodes = nodes;
this.types = types;
}
/**

@@ -782,4 +855,4 @@ * Parse a selector string and return it's AST.

*/
function query(ast, selector) {
return finalMatches(match(ast, parse(selector)));
function query(ast, selector, cache) {
return finalMatches(match(ast, parse(selector), cache || new Cache(ast)));
}

@@ -792,2 +865,3 @@

query.finalMatches = finalMatches;
query.Cache = Cache;
return query;

@@ -794,0 +868,0 @@ }

{
"name": "esquery",
"preferGlobal": false,
"version": "0.1.0",
"version": "0.2.0",
"author": "Joel Feenstra <jrfeenst+esquery@gmail.com>",
"description": "A query library for ECMAScript AST using a CSS selector like query language.",
"main": "esquery.js",
"scripts": {
"test": "node_modules/jstestr/bin/jstestr.js path=tests"
"test": "node node_modules/jstestr/bin/jstestr.js path=tests"
},

@@ -10,0 +11,0 @@ "repository": {

@@ -27,2 +27,3 @@

var opRBracket = {type: "operator", value: "]"};
var opDot = {type: "operator", value: "."};

@@ -93,2 +94,10 @@ var num1 = {type: "number", value: 1};

"attribute with dot access": function () {
var ast = esquery.processTokens([opLBracket, idAttr, opDot, idAttr, opRBracket]);
assert.matches({
type: "attribute",
name: "attr.attr"
}, ast);
},
"descendant selector with identifiers": function () {

@@ -235,30 +244,30 @@ var ast = esquery.processTokens([idFoo, opSpace, idAsdf]);

assert.matches({
type: "adjacent",
type: "child",
left: {
type: "identifier",
value: "foo"
},
right: {
type: "descendant",
left: {
type: "nth-child",
index: {
type: "literal",
value: 1
type: "adjacent",
left: {
type: "identifier",
value: "foo"
},
right: {
type: "nth-child",
index: {
type: "literal",
value: 1
}
}
},
right: {
type: "child",
left: {
type: "attribute",
name: "attr",
operator: "=",
value: {
type: "literal",
value: 2
}
},
right: idFoo
type: "attribute",
name: "attr",
operator: "=",
value: {
type: "literal",
value: 2
}
}
}
},
right: idFoo
}, ast);

@@ -333,4 +342,8 @@ },

assert.doesThrow(Error, esquery.processTokens.bind(this, [opColon, keywordNot, opLParen, wildcard, wildcard]));
},
"invalid field": function () {
assert.doesThrow(Error, esquery.processTokens.bind(this, [opDot]));
}
});
});

@@ -22,2 +22,9 @@

"three types child": function () {
var matches = esquery(conditional, "IfStatement > BinaryExpression > Identifier");
assert.contains([
conditional.body[0].test.left
], matches);
},
"two types descendant": function () {

@@ -24,0 +31,0 @@ var matches = esquery(conditional, "IfStatement BinaryExpression");

@@ -74,2 +74,9 @@

"field subject": function () {
var matches = esquery(forLoop, '.test!');
assert.contains([
forLoop.body[0].test
], matches);
},
":matches subject": function () {

@@ -76,0 +83,0 @@ var matches = esquery(forLoop, ':matches(*)! > [name="foo"]');

@@ -101,3 +101,20 @@

},
"# type": function () {
var matches = esquery(forLoop, "#Program");
assert.contains([
forLoop
], matches);
matches = esquery(forLoop, "#ForStatement");
assert.contains([
forLoop.body[0]
], matches);
matches = esquery(forLoop, "#BinaryExpression");
assert.contains([
forLoop.body[0].test
], matches);
}
});
});

@@ -13,3 +13,7 @@

tokens = esquery.tokenize("id.name");
assert.matches([{type: "identifier", value: "id.name"}], tokens);
assert.matches([
{type: "identifier", value: "id"},
{type: "operator", value: "."},
{type: "identifier", value: "name"}
], tokens);
},

@@ -23,5 +27,11 @@

"individual operators": function () {
var tokens = esquery.tokenize(":");
var tokens = esquery.tokenize(".");
assert.matches([{type: "operator", value: "."}], tokens);
tokens = esquery.tokenize(":");
assert.matches([{type: "operator", value: ":"}], tokens);
tokens = esquery.tokenize("#");
assert.matches([{type: "operator", value: "#"}], tokens);
tokens = esquery.tokenize("[");

@@ -28,0 +38,0 @@ assert.matches([{type: "operator", value: "["}], tokens);

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc