diff -Nru node-css-select-1.2.0/browser_functions.js node-css-select-1.3.0~rc0/browser_functions.js --- node-css-select-1.2.0/browser_functions.js 2015-11-24 00:18:35.000000000 +0000 +++ node-css-select-1.3.0~rc0/browser_functions.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -function isTag(elem){ - return elem.nodeType === 1; -} -function getChildren(elem){ - return Array.prototype.slice.call(elem.childNodes, 0); -} -function getParent(elem){ - return elem.parentElement; -} - -module.exports = { - isTag: isTag, - getSiblings: function(elem){ - var parent = getParent(elem); - return parent && getChildren(parent); - }, - getChildren: getChildren, - getParent: getParent, - getAttributeValue: function(elem, name){ - return elem.attributes[name].value; - }, - hasAttrib: function(elem, name){ - return name in elem.attributes; - }, - getName: function(elem){ - return elem.tagName.toLowerCase(); - }, - findOne: function findOne(test, arr){ - var elem = null; - - for(var i = 0, l = arr.length; i < l && !elem; i++){ - if(test(arr[i])){ - elem = arr[i]; - } else { - var childs = getChildren(arr[i]); - if(childs && childs.length > 0){ - elem = findOne(test, childs); - } - } - } - - return elem; - }, - findAll: function findAll(test, elems){ - var result = []; - for(var i = 0, j = elems.length; i < j; i++){ - if(!isTag(elems[i])) continue; - if(test(elems[i])) result.push(elems[i]); - var childs = getChildren(elems[i]); - if(childs) result = result.concat(findAll(test, childs)); - } - return result; - }, - //https://github.com/ded/qwery/blob/master/pseudos/qwery-pseudos.js#L47-54 - getText: function getText(elem) { - var str = "", - childs = getChildren(elem); - - if(!childs) return str; - - for(var i = 0; i < childs.length; i++){ - if(isTag(childs[i])) str += elem.textContent || elem.innerText || getText(childs[i]); - } - - return str; - } -}; diff -Nru node-css-select-1.2.0/debian/changelog node-css-select-1.3.0~rc0/debian/changelog --- node-css-select-1.2.0/debian/changelog 2016-12-23 08:03:16.000000000 +0000 +++ node-css-select-1.3.0~rc0/debian/changelog 2018-01-15 18:11:47.000000000 +0000 @@ -1,3 +1,10 @@ +node-css-select (1.3.0~rc0-1) unstable; urgency=medium + + * Team upload + * New upstream release + + -- Pirate Praveen Mon, 15 Jan 2018 23:41:47 +0530 + node-css-select (1.2.0-1) unstable; urgency=low * Initial release (Closes: #848353) diff -Nru node-css-select-1.2.0/debian/compat node-css-select-1.3.0~rc0/debian/compat --- node-css-select-1.2.0/debian/compat 2016-12-23 08:03:16.000000000 +0000 +++ node-css-select-1.3.0~rc0/debian/compat 2018-01-15 18:11:47.000000000 +0000 @@ -1 +1 @@ -9 +11 diff -Nru node-css-select-1.2.0/debian/control node-css-select-1.3.0~rc0/debian/control --- node-css-select-1.2.0/debian/control 2016-12-23 08:03:16.000000000 +0000 +++ node-css-select-1.3.0~rc0/debian/control 2018-01-15 18:11:47.000000000 +0000 @@ -1,10 +1,10 @@ Source: node-css-select -Section: web +Section: javascript Priority: optional Maintainer: Debian Javascript Maintainers Uploaders: Paolo Greppi Build-Depends: - debhelper (>= 9) + debhelper (>= 11) , dh-buildinfo , node-css-what (>= 2.1) , node-boolbase (>= 1.0.0) @@ -15,7 +15,7 @@ , node-nth-check (>= 1.0.1) , mocha , nodejs -Standards-Version: 3.9.8 +Standards-Version: 4.1.3 Homepage: https://github.com/fb55/css-select#readme Vcs-Git: https://anonscm.debian.org/git/pkg-javascript/node-css-select.git Vcs-Browser: https://anonscm.debian.org/cgit/pkg-javascript/node-css-select.git diff -Nru node-css-select-1.2.0/.eslintrc node-css-select-1.3.0~rc0/.eslintrc --- node-css-select-1.2.0/.eslintrc 1970-01-01 00:00:00.000000000 +0000 +++ node-css-select-1.3.0~rc0/.eslintrc 2017-01-19 11:01:38.000000000 +0000 @@ -0,0 +1,95 @@ +{ + "extends": "eslint:recommended", + "env": { + "node": true + }, + "globals": { + "beforeEach": true, + "describe": true, + "it": true + }, + "rules": { + "no-console": 0, + "new-cap": 0, + "space-before-blocks": [2, "never"], + "space-in-parens": [2, "never"], + "eqeqeq": [2, "allow-null"], + "no-extend-native": 2, + "no-use-before-define": [ + 2, + { + "functions": false, + "classes": false + } + ], + "no-caller": 2, + "no-irregular-whitespace": 2, + "quotes": [ + 2, + "double" + ], + "no-undef": 2, + "no-unused-vars": 2, + "no-proto": 2, + "curly": [ + 2, + "multi-line" + ], + "no-mixed-spaces-and-tabs": [ + 2, + "smart-tabs" + ], + "space-infix-ops": 2, + "keyword-spacing": [ + 2, + { + "overrides": { + "if": { + "after": false + }, + "catch": { + "after": false + }, + "for": { + "after": false + }, + "while": { + "after": false + } + } + } + ], + "comma-style": [ + 2, + "last" + ], + "dot-notation": 2, + "wrap-iife": 2, + "no-empty": 2, + "space-unary-ops": [ + 2, + { + "words": false, + "nonwords": false + } + ], + "no-with": 2, + "no-multi-str": 2, + "no-trailing-spaces": 2, + "indent": [ + 2, + "tab", + { + "SwitchCase": 1 + } + ], + "linebreak-style": [ + 2, + "unix" + ], + "consistent-this": [ + 2, + "_this" + ] + } +} diff -Nru node-css-select-1.2.0/index.js node-css-select-1.3.0~rc0/index.js --- node-css-select-1.2.0/index.js 2015-11-24 00:18:35.000000000 +0000 +++ node-css-select-1.3.0~rc0/index.js 2017-01-19 11:01:38.000000000 +0000 @@ -2,35 +2,61 @@ module.exports = CSSselect; -var Pseudos = require("./lib/pseudos.js"), - DomUtils = require("domutils"), - findOne = DomUtils.findOne, - findAll = DomUtils.findAll, - getChildren = DomUtils.getChildren, - removeSubsets = DomUtils.removeSubsets, - falseFunc = require("boolbase").falseFunc, - compile = require("./lib/compile.js"), - compileUnsafe = compile.compileUnsafe, - compileToken = compile.compileToken; +var DomUtils = require("domutils"), + falseFunc = require("boolbase").falseFunc, + compileFactory = require("./lib/compile.js"), + defaultCompile = compileFactory(DomUtils); + +function adapterCompile(adapter){ + return adapter === DomUtils ? defaultCompile : compileFactory(adapter); +} function getSelectorFunc(searchFunc){ return function select(query, elems, options){ - if(typeof query !== "function") query = compileUnsafe(query, options, elems); - if(!Array.isArray(elems)) elems = getChildren(elems); - else elems = removeSubsets(elems); - return searchFunc(query, elems); + options = options || {} + options.adapter = options.adapter || DomUtils; + var compile = adapterCompile(options.adapter); + + if(typeof query !== "function") query = compile.compileUnsafe(query, options, elems); + if(query.shouldTestNextSiblings) elems = appendNextSiblings((options && options.context) || elems, options.adapter); + if(!Array.isArray(elems)) elems = options.adapter.getChildren(elems); + else elems = options.adapter.removeSubsets(elems); + return searchFunc(query, elems, options); }; } -var selectAll = getSelectorFunc(function selectAll(query, elems){ - return (query === falseFunc || !elems || elems.length === 0) ? [] : findAll(query, elems); +function getNextSiblings(elem, adapter){ + var siblings = adapter.getSiblings(elem); + if(!Array.isArray(siblings)) return []; + siblings = siblings.slice(0); + while(siblings.shift() !== elem); + return siblings; +} + +function appendNextSiblings(elems, adapter){ + // Order matters because jQuery seems to check the children before the siblings + if(!Array.isArray(elems)) elems = [elems]; + var newElems = elems.slice(0); + + for(var i = 0, len = elems.length; i < len; i++){ + var nextSiblings = getNextSiblings(newElems[i], adapter); + newElems.push.apply(newElems, nextSiblings); + } + return newElems; +} + +var selectAll = getSelectorFunc(function selectAll(query, elems, options){ + return (query === falseFunc || !elems || elems.length === 0) ? [] : options.adapter.findAll(query, elems); }); -var selectOne = getSelectorFunc(function selectOne(query, elems){ - return (query === falseFunc || !elems || elems.length === 0) ? null : findOne(query, elems); +var selectOne = getSelectorFunc(function selectOne(query, elems, options){ + return (query === falseFunc || !elems || elems.length === 0) ? null : options.adapter.findOne(query, elems); }); function is(elem, query, options){ + options = options || {} + options.adapter = options.adapter || DomUtils; + var compile = adapterCompile(options.adapter); return (typeof query === "function" ? query : compile(query, options))(elem); } @@ -41,9 +67,9 @@ return selectAll(query, elems, options); } -CSSselect.compile = compile; -CSSselect.filters = Pseudos.filters; -CSSselect.pseudos = Pseudos.pseudos; +CSSselect.compile = defaultCompile; +CSSselect.filters = defaultCompile.Pseudos.filters; +CSSselect.pseudos = defaultCompile.Pseudos.pseudos; CSSselect.selectAll = selectAll; CSSselect.selectOne = selectOne; @@ -51,9 +77,9 @@ CSSselect.is = is; //legacy methods (might be removed) -CSSselect.parse = compile; +CSSselect.parse = defaultCompile; CSSselect.iterate = selectAll; //hooks -CSSselect._compileUnsafe = compileUnsafe; -CSSselect._compileToken = compileToken; +CSSselect._compileUnsafe = defaultCompile.compileUnsafe; +CSSselect._compileToken = defaultCompile.compileToken; diff -Nru node-css-select-1.2.0/lib/attributes.js node-css-select-1.3.0~rc0/lib/attributes.js --- node-css-select-1.2.0/lib/attributes.js 2015-11-24 00:18:35.000000000 +0000 +++ node-css-select-1.3.0~rc0/lib/attributes.js 2017-01-19 11:01:38.000000000 +0000 @@ -1,181 +1,181 @@ -var DomUtils = require("domutils"), - hasAttrib = DomUtils.hasAttrib, - getAttributeValue = DomUtils.getAttributeValue, - falseFunc = require("boolbase").falseFunc; +var falseFunc = require("boolbase").falseFunc; //https://github.com/slevithan/XRegExp/blob/master/src/xregexp.js#L469 var reChars = /[-[\]{}()*+?.,\\^$|#\s]/g; -/* - attribute selectors -*/ - -var attributeRules = { - __proto__: null, - equals: function(next, data){ - var name = data.name, - value = data.value; - - if(data.ignoreCase){ - value = value.toLowerCase(); - - return function equalsIC(elem){ - var attr = getAttributeValue(elem, name); - return attr != null && attr.toLowerCase() === value && next(elem); - }; - } - - return function equals(elem){ - return getAttributeValue(elem, name) === value && next(elem); - }; - }, - hyphen: function(next, data){ - var name = data.name, - value = data.value, - len = value.length; - - if(data.ignoreCase){ - value = value.toLowerCase(); +function factory(adapter){ + /* + attribute selectors + */ + var attributeRules = { + __proto__: null, + equals: function(next, data){ + var name = data.name, + value = data.value; + + if(data.ignoreCase){ + value = value.toLowerCase(); + + return function equalsIC(elem){ + var attr = adapter.getAttributeValue(elem, name); + return attr != null && attr.toLowerCase() === value && next(elem); + }; + } + + return function equals(elem){ + return adapter.getAttributeValue(elem, name) === value && next(elem); + }; + }, + hyphen: function(next, data){ + var name = data.name, + value = data.value, + len = value.length; + + if(data.ignoreCase){ + value = value.toLowerCase(); + + return function hyphenIC(elem){ + var attr = adapter.getAttributeValue(elem, name); + return attr != null && + (attr.length === len || attr.charAt(len) === "-") && + attr.substr(0, len).toLowerCase() === value && + next(elem); + }; + } - return function hyphenIC(elem){ - var attr = getAttributeValue(elem, name); + return function hyphen(elem){ + var attr = adapter.getAttributeValue(elem, name); return attr != null && + attr.substr(0, len) === value && (attr.length === len || attr.charAt(len) === "-") && - attr.substr(0, len).toLowerCase() === value && next(elem); }; - } - - return function hyphen(elem){ - var attr = getAttributeValue(elem, name); - return attr != null && - attr.substr(0, len) === value && - (attr.length === len || attr.charAt(len) === "-") && - next(elem); - }; - }, - element: function(next, data){ - var name = data.name, - value = data.value; - - if(/\s/.test(value)){ - return falseFunc; - } - - value = value.replace(reChars, "\\$&"); - - var pattern = "(?:^|\\s)" + value + "(?:$|\\s)", - flags = data.ignoreCase ? "i" : "", - regex = new RegExp(pattern, flags); - - return function element(elem){ - var attr = getAttributeValue(elem, name); - return attr != null && regex.test(attr) && next(elem); - }; - }, - exists: function(next, data){ - var name = data.name; - return function exists(elem){ - return hasAttrib(elem, name) && next(elem); - }; - }, - start: function(next, data){ - var name = data.name, - value = data.value, - len = value.length; - - if(len === 0){ - return falseFunc; - } - - if(data.ignoreCase){ - value = value.toLowerCase(); - - return function startIC(elem){ - var attr = getAttributeValue(elem, name); - return attr != null && attr.substr(0, len).toLowerCase() === value && next(elem); - }; - } - - return function start(elem){ - var attr = getAttributeValue(elem, name); - return attr != null && attr.substr(0, len) === value && next(elem); - }; - }, - end: function(next, data){ - var name = data.name, - value = data.value, - len = -value.length; + }, + element: function(next, data){ + var name = data.name, + value = data.value; + + if(/\s/.test(value)){ + return falseFunc; + } + + value = value.replace(reChars, "\\$&"); + + var pattern = "(?:^|\\s)" + value + "(?:$|\\s)", + flags = data.ignoreCase ? "i" : "", + regex = new RegExp(pattern, flags); - if(len === 0){ - return falseFunc; - } - - if(data.ignoreCase){ - value = value.toLowerCase(); - - return function endIC(elem){ - var attr = getAttributeValue(elem, name); - return attr != null && attr.substr(len).toLowerCase() === value && next(elem); - }; - } - - return function end(elem){ - var attr = getAttributeValue(elem, name); - return attr != null && attr.substr(len) === value && next(elem); - }; - }, - any: function(next, data){ - var name = data.name, - value = data.value; - - if(value === ""){ - return falseFunc; - } - - if(data.ignoreCase){ - var regex = new RegExp(value.replace(reChars, "\\$&"), "i"); - - return function anyIC(elem){ - var attr = getAttributeValue(elem, name); + return function element(elem){ + var attr = adapter.getAttributeValue(elem, name); return attr != null && regex.test(attr) && next(elem); }; - } - - return function any(elem){ - var attr = getAttributeValue(elem, name); - return attr != null && attr.indexOf(value) >= 0 && next(elem); - }; - }, - not: function(next, data){ - var name = data.name, - value = data.value; - - if(value === ""){ - return function notEmpty(elem){ - return !!getAttributeValue(elem, name) && next(elem); - }; - } else if(data.ignoreCase){ - value = value.toLowerCase(); - - return function notIC(elem){ - var attr = getAttributeValue(elem, name); - return attr != null && attr.toLowerCase() !== value && next(elem); - }; - } + }, + exists: function(next, data){ + var name = data.name; + return function exists(elem){ + return adapter.hasAttrib(elem, name) && next(elem); + }; + }, + start: function(next, data){ + var name = data.name, + value = data.value, + len = value.length; + + if(len === 0){ + return falseFunc; + } + + if(data.ignoreCase){ + value = value.toLowerCase(); + + return function startIC(elem){ + var attr = adapter.getAttributeValue(elem, name); + return attr != null && attr.substr(0, len).toLowerCase() === value && next(elem); + }; + } + + return function start(elem){ + var attr = adapter.getAttributeValue(elem, name); + return attr != null && attr.substr(0, len) === value && next(elem); + }; + }, + end: function(next, data){ + var name = data.name, + value = data.value, + len = -value.length; + + if(len === 0){ + return falseFunc; + } + + if(data.ignoreCase){ + value = value.toLowerCase(); + + return function endIC(elem){ + var attr = adapter.getAttributeValue(elem, name); + return attr != null && attr.substr(len).toLowerCase() === value && next(elem); + }; + } + + return function end(elem){ + var attr = adapter.getAttributeValue(elem, name); + return attr != null && attr.substr(len) === value && next(elem); + }; + }, + any: function(next, data){ + var name = data.name, + value = data.value; + + if(value === ""){ + return falseFunc; + } + + if(data.ignoreCase){ + var regex = new RegExp(value.replace(reChars, "\\$&"), "i"); + + return function anyIC(elem){ + var attr = adapter.getAttributeValue(elem, name); + return attr != null && regex.test(attr) && next(elem); + }; + } + + return function any(elem){ + var attr = adapter.getAttributeValue(elem, name); + return attr != null && attr.indexOf(value) >= 0 && next(elem); + }; + }, + not: function(next, data){ + var name = data.name, + value = data.value; + + if(value === ""){ + return function notEmpty(elem){ + return !!adapter.getAttributeValue(elem, name) && next(elem); + }; + } else if(data.ignoreCase){ + value = value.toLowerCase(); + + return function notIC(elem){ + var attr = adapter.getAttributeValue(elem, name); + return attr != null && attr.toLowerCase() !== value && next(elem); + }; + } + + return function not(elem){ + return adapter.getAttributeValue(elem, name) !== value && next(elem); + }; + } + }; + + return { + compile: function(next, data, options){ + if(options && options.strict && ( + data.ignoreCase || data.action === "not" + )) throw new Error("Unsupported attribute selector"); + return attributeRules[data.action](next, data); + }, + rules: attributeRules + }; +} - return function not(elem){ - return getAttributeValue(elem, name) !== value && next(elem); - }; - } -}; - -module.exports = { - compile: function(next, data, options){ - if(options && options.strict && ( - data.ignoreCase || data.action === "not" - )) throw SyntaxError("Unsupported attribute selector"); - return attributeRules[data.action](next, data); - }, - rules: attributeRules -}; +module.exports = factory; diff -Nru node-css-select-1.2.0/lib/compile.js node-css-select-1.3.0~rc0/lib/compile.js --- node-css-select-1.2.0/lib/compile.js 2015-11-24 00:18:35.000000000 +0000 +++ node-css-select-1.3.0~rc0/lib/compile.js 2017-01-19 11:01:38.000000000 +0000 @@ -2,191 +2,206 @@ compiles a selector to an executable function */ -module.exports = compile; -module.exports.compileUnsafe = compileUnsafe; -module.exports.compileToken = compileToken; - -var parse = require("css-what"), - DomUtils = require("domutils"), - isTag = DomUtils.isTag, - Rules = require("./general.js"), - sortRules = require("./sort.js"), - BaseFuncs = require("boolbase"), - trueFunc = BaseFuncs.trueFunc, - falseFunc = BaseFuncs.falseFunc, - procedure = require("./procedure.json"); - -function compile(selector, options, context){ - var next = compileUnsafe(selector, options, context); - return wrap(next); -} +module.exports = compileFactory; -function wrap(next){ - return function base(elem){ - return isTag(elem) && next(elem); - }; -} +var parse = require("css-what"), + BaseFuncs = require("boolbase"), + sortRules = require("./sort.js"), + procedure = require("./procedure.json"), + rulesFactory = require("./general.js"), + pseudosFactory = require("./pseudos.js"), + trueFunc = BaseFuncs.trueFunc, + falseFunc = BaseFuncs.falseFunc; + +function compileFactory(adapter){ + var Pseudos = pseudosFactory(adapter), + filters = Pseudos.filters, + Rules = rulesFactory(adapter, Pseudos); + + function compile(selector, options, context){ + var next = compileUnsafe(selector, options, context); + return wrap(next); + } -function compileUnsafe(selector, options, context){ - var token = parse(selector, options); - return compileToken(token, options, context); -} + function wrap(next){ + return function base(elem){ + return adapter.isTag(elem) && next(elem); + }; + } -function includesScopePseudo(t){ - return t.type === "pseudo" && ( - t.name === "scope" || ( - Array.isArray(t.data) && - t.data.some(function(data){ - return data.some(includesScopePseudo); - }) - ) - ); -} + function compileUnsafe(selector, options, context){ + var token = parse(selector, options); + return compileToken(token, options, context); + } -var DESCENDANT_TOKEN = {type: "descendant"}, - SCOPE_TOKEN = {type: "pseudo", name: "scope"}, - PLACEHOLDER_ELEMENT = {}, - getParent = DomUtils.getParent; - -//CSS 4 Spec (Draft): 3.3.1. Absolutizing a Scope-relative Selector -//http://www.w3.org/TR/selectors4/#absolutizing -function absolutize(token, context){ - //TODO better check if context is document - var hasContext = !!context && !!context.length && context.every(function(e){ - return e === PLACEHOLDER_ELEMENT || !!getParent(e); - }); - - - token.forEach(function(t){ - if(t.length > 0 && isTraversal(t[0]) && t[0].type !== "descendant"){ - //don't return in else branch - } else if(hasContext && !includesScopePseudo(t)){ - t.unshift(DESCENDANT_TOKEN); - } else { - return; - } + function includesScopePseudo(t){ + return t.type === "pseudo" && ( + t.name === "scope" || ( + Array.isArray(t.data) && + t.data.some(function(data){ + return data.some(includesScopePseudo); + }) + ) + ); + } - t.unshift(SCOPE_TOKEN); - }); -} + var DESCENDANT_TOKEN = {type: "descendant"}, + FLEXIBLE_DESCENDANT_TOKEN = {type: "_flexibleDescendant"}, + SCOPE_TOKEN = {type: "pseudo", name: "scope"}, + PLACEHOLDER_ELEMENT = {}; + + //CSS 4 Spec (Draft): 3.3.1. Absolutizing a Scope-relative Selector + //http://www.w3.org/TR/selectors4/#absolutizing + function absolutize(token, context){ + //TODO better check if context is document + var hasContext = !!context && !!context.length && context.every(function(e){ + return e === PLACEHOLDER_ELEMENT || !!adapter.getParent(e); + }); + + + token.forEach(function(t){ + if(t.length > 0 && isTraversal(t[0]) && t[0].type !== "descendant"){ + //don't return in else branch + } else if(hasContext && !includesScopePseudo(t)){ + t.unshift(DESCENDANT_TOKEN); + } else { + return; + } -function compileToken(token, options, context){ - token = token.filter(function(t){ return t.length > 0; }); + t.unshift(SCOPE_TOKEN); + }); + } - token.forEach(sortRules); + function compileToken(token, options, context){ + token = token.filter(function(t){ return t.length > 0; }); - var isArrayContext = Array.isArray(context); + token.forEach(sortRules); - context = (options && options.context) || context; + var isArrayContext = Array.isArray(context); - if(context && !isArrayContext) context = [context]; + context = (options && options.context) || context; - absolutize(token, context); + if(context && !isArrayContext) context = [context]; - return token - .map(function(rules){ return compileRules(rules, options, context, isArrayContext); }) - .reduce(reduceRules, falseFunc); -} + absolutize(token, context); -function isTraversal(t){ - return procedure[t.type] < 0; -} + var shouldTestNextSiblings = false; -function compileRules(rules, options, context, isArrayContext){ - var acceptSelf = (isArrayContext && rules[0].name === "scope" && rules[1].type === "descendant"); - return rules.reduce(function(func, rule, index){ - if(func === falseFunc) return func; - return Rules[rule.type](func, rule, options, context, acceptSelf && index === 1); - }, options && options.rootFunc || trueFunc); -} + var query = token + .map(function(rules){ + if(rules[0] && rules[1] && rules[0].name === "scope"){ + var ruleType = rules[1].type; + if(isArrayContext && ruleType === "descendant") rules[1] = FLEXIBLE_DESCENDANT_TOKEN; + else if(ruleType === "adjacent" || ruleType === "sibling") shouldTestNextSiblings = true; + } + return compileRules(rules, options, context); + }) + .reduce(reduceRules, falseFunc); + + query.shouldTestNextSiblings = shouldTestNextSiblings; -function reduceRules(a, b){ - if(b === falseFunc || a === trueFunc){ - return a; + return query; } - if(a === falseFunc || b === trueFunc){ - return b; + + function isTraversal(t){ + return procedure[t.type] < 0; } - return function combine(elem){ - return a(elem) || b(elem); - }; -} + function compileRules(rules, options, context){ + return rules.reduce(function(func, rule){ + if(func === falseFunc) return func; + return Rules[rule.type](func, rule, options, context); + }, options && options.rootFunc || trueFunc); + } -//:not, :has and :matches have to compile selectors -//doing this in lib/pseudos.js would lead to circular dependencies, -//so we add them here - -var Pseudos = require("./pseudos.js"), - filters = Pseudos.filters, - existsOne = DomUtils.existsOne, - isTag = DomUtils.isTag, - getChildren = DomUtils.getChildren; + function reduceRules(a, b){ + if(b === falseFunc || a === trueFunc){ + return a; + } + if(a === falseFunc || b === trueFunc){ + return b; + } + return function combine(elem){ + return a(elem) || b(elem); + }; + } -function containsTraversal(t){ - return t.some(isTraversal); -} + function containsTraversal(t){ + return t.some(isTraversal); + } -filters.not = function(next, token, options, context){ - var opts = { - xmlMode: !!(options && options.xmlMode), - strict: !!(options && options.strict) - }; - - if(opts.strict){ - if(token.length > 1 || token.some(containsTraversal)){ - throw new SyntaxError("complex selectors in :not aren't allowed in strict mode"); + //:not, :has and :matches have to compile selectors + //doing this in lib/pseudos.js would lead to circular dependencies, + //so we add them here + filters.not = function(next, token, options, context){ + var opts = { + xmlMode: !!(options && options.xmlMode), + strict: !!(options && options.strict) + }; + + if(opts.strict){ + if(token.length > 1 || token.some(containsTraversal)){ + throw new Error("complex selectors in :not aren't allowed in strict mode"); + } } - } - var func = compileToken(token, opts, context); + var func = compileToken(token, opts, context); - if(func === falseFunc) return next; - if(func === trueFunc) return falseFunc; + if(func === falseFunc) return next; + if(func === trueFunc) return falseFunc; - return function(elem){ - return !func(elem) && next(elem); + return function(elem){ + return !func(elem) && next(elem); + }; }; -}; -filters.has = function(next, token, options){ - var opts = { - xmlMode: !!(options && options.xmlMode), - strict: !!(options && options.strict) - }; + filters.has = function(next, token, options){ + var opts = { + xmlMode: !!(options && options.xmlMode), + strict: !!(options && options.strict) + }; - //FIXME: Uses an array as a pointer to the current element (side effects) - var context = token.some(containsTraversal) ? [PLACEHOLDER_ELEMENT] : null; + //FIXME: Uses an array as a pointer to the current element (side effects) + var context = token.some(containsTraversal) ? [PLACEHOLDER_ELEMENT] : null; - var func = compileToken(token, opts, context); + var func = compileToken(token, opts, context); - if(func === falseFunc) return falseFunc; - if(func === trueFunc) return function(elem){ - return getChildren(elem).some(isTag) && next(elem); - }; + if(func === falseFunc) return falseFunc; + if(func === trueFunc){ + return function(elem){ + return adapter.getChildren(elem).some(adapter.isTag) && next(elem); + }; + } - func = wrap(func); + func = wrap(func); - if(context){ - return function has(elem){ - return next(elem) && ( - (context[0] = elem), existsOne(func, getChildren(elem)) - ); - }; - } + if(context){ + return function has(elem){ + return next(elem) && ( + (context[0] = elem), adapter.existsOne(func, adapter.getChildren(elem)) + ); + }; + } - return function has(elem){ - return next(elem) && existsOne(func, getChildren(elem)); + return function has(elem){ + return next(elem) && adapter.existsOne(func, adapter.getChildren(elem)); + }; }; -}; -filters.matches = function(next, token, options, context){ - var opts = { - xmlMode: !!(options && options.xmlMode), - strict: !!(options && options.strict), - rootFunc: next + filters.matches = function(next, token, options, context){ + var opts = { + xmlMode: !!(options && options.xmlMode), + strict: !!(options && options.strict), + rootFunc: next + }; + + return compileToken(token, opts, context); }; - return compileToken(token, opts, context); -}; + compile.compileToken = compileToken; + compile.compileUnsafe = compileUnsafe; + compile.Pseudos = Pseudos; + + return compile; +} diff -Nru node-css-select-1.2.0/lib/general.js node-css-select-1.3.0~rc0/lib/general.js --- node-css-select-1.2.0/lib/general.js 2015-11-24 00:18:35.000000000 +0000 +++ node-css-select-1.3.0~rc0/lib/general.js 2017-01-19 11:01:38.000000000 +0000 @@ -1,89 +1,99 @@ -var DomUtils = require("domutils"), - isTag = DomUtils.isTag, - getParent = DomUtils.getParent, - getChildren = DomUtils.getChildren, - getSiblings = DomUtils.getSiblings, - getName = DomUtils.getName; - -/* - all available rules -*/ -module.exports = { - __proto__: null, - - attribute: require("./attributes.js").compile, - pseudo: require("./pseudos.js").compile, - - //tags - tag: function(next, data){ - var name = data.name; - return function tag(elem){ - return getName(elem) === name && next(elem); - }; - }, - - //traversal - descendant: function(next, rule, options, context, acceptSelf){ - return function descendant(elem){ +var attributeFactory = require("./attributes.js"); - if (acceptSelf && next(elem)) return true; +function generalFactory(adapter, Pseudos){ + /* + all available rules + */ + return { + __proto__: null, + + attribute: attributeFactory(adapter).compile, + pseudo: Pseudos.compile, + + //tags + tag: function(next, data){ + var name = data.name; + return function tag(elem){ + return adapter.getName(elem) === name && next(elem); + }; + }, + + //traversal + descendant: function(next){ + return function descendant(elem){ - var found = false; + var found = false; - while(!found && (elem = getParent(elem))){ - found = next(elem); - } + while(!found && (elem = adapter.getParent(elem))){ + found = next(elem); + } - return found; - }; - }, - parent: function(next, data, options){ - if(options && options.strict) throw SyntaxError("Parent selector isn't part of CSS3"); - - return function parent(elem){ - return getChildren(elem).some(test); - }; + return found; + }; + }, + _flexibleDescendant: function(next){ + // Include element itself, only used while querying an array + return function descendant(elem){ - function test(elem){ - return isTag(elem) && next(elem); - } - }, - child: function(next){ - return function child(elem){ - var parent = getParent(elem); - return !!parent && next(parent); - }; - }, - sibling: function(next){ - return function sibling(elem){ - var siblings = getSiblings(elem); - - for(var i = 0; i < siblings.length; i++){ - if(isTag(siblings[i])){ - if(siblings[i] === elem) break; - if(next(siblings[i])) return true; + var found = next(elem); + + while(!found && (elem = adapter.getParent(elem))){ + found = next(elem); } + + return found; + }; + }, + parent: function(next, data, options){ + if(options && options.strict) throw new Error("Parent selector isn't part of CSS3"); + + return function parent(elem){ + return adapter.getChildren(elem).some(test); + }; + + function test(elem){ + return adapter.isTag(elem) && next(elem); } + }, + child: function(next){ + return function child(elem){ + var parent = adapter.getParent(elem); + return !!parent && next(parent); + }; + }, + sibling: function(next){ + return function sibling(elem){ + var siblings = adapter.getSiblings(elem); + + for(var i = 0; i < siblings.length; i++){ + if(adapter.isTag(siblings[i])){ + if(siblings[i] === elem) break; + if(next(siblings[i])) return true; + } + } - return false; - }; - }, - adjacent: function(next){ - return function adjacent(elem){ - var siblings = getSiblings(elem), - lastElement; - - for(var i = 0; i < siblings.length; i++){ - if(isTag(siblings[i])){ - if(siblings[i] === elem) break; - lastElement = siblings[i]; + return false; + }; + }, + adjacent: function(next){ + return function adjacent(elem){ + var siblings = adapter.getSiblings(elem), + lastElement; + + for(var i = 0; i < siblings.length; i++){ + if(adapter.isTag(siblings[i])){ + if(siblings[i] === elem) break; + lastElement = siblings[i]; + } } - } - return !!lastElement && next(lastElement); - }; - }, - universal: function(next){ - return next; - } -}; \ No newline at end of file + return !!lastElement && next(lastElement); + }; + }, + universal: function(next){ + return next; + } + }; +} + +module.exports = generalFactory; diff -Nru node-css-select-1.2.0/lib/pseudos.js node-css-select-1.3.0~rc0/lib/pseudos.js --- node-css-select-1.2.0/lib/pseudos.js 2015-11-24 00:18:35.000000000 +0000 +++ node-css-select-1.3.0~rc0/lib/pseudos.js 2017-01-19 11:01:38.000000000 +0000 @@ -11,351 +11,359 @@ they need to return a boolean */ -var DomUtils = require("domutils"), - isTag = DomUtils.isTag, - getText = DomUtils.getText, - getParent = DomUtils.getParent, - getChildren = DomUtils.getChildren, - getSiblings = DomUtils.getSiblings, - hasAttrib = DomUtils.hasAttrib, - getName = DomUtils.getName, - getAttribute= DomUtils.getAttributeValue, - getNCheck = require("nth-check"), - checkAttrib = require("./attributes.js").rules.equals, - BaseFuncs = require("boolbase"), - trueFunc = BaseFuncs.trueFunc, - falseFunc = BaseFuncs.falseFunc; - -//helper methods -function getFirstElement(elems){ - for(var i = 0; elems && i < elems.length; i++){ - if(isTag(elems[i])) return elems[i]; - } -} - -function getAttribFunc(name, value){ - var data = {name: name, value: value}; - return function attribFunc(next){ - return checkAttrib(next, data); - }; -} +var getNCheck = require("nth-check"), + BaseFuncs = require("boolbase"), + attributesFactory = require("./attributes.js"), + trueFunc = BaseFuncs.trueFunc, + falseFunc = BaseFuncs.falseFunc; + +function filtersFactory(adapter){ + var attributes = attributesFactory(adapter), + checkAttrib = attributes.rules.equals; + + //helper methods + function equals(a, b){ + if(typeof adapter.equals === "function") return adapter.equals(a, b); -function getChildFunc(next){ - return function(elem){ - return !!getParent(elem) && next(elem); - }; -} + return a === b; + } -var filters = { - contains: function(next, text){ - return function contains(elem){ - return next(elem) && getText(elem).indexOf(text) >= 0; + function getAttribFunc(name, value){ + var data = {name: name, value: value}; + return function attribFunc(next){ + return checkAttrib(next, data); }; - }, - icontains: function(next, text){ - var itext = text.toLowerCase(); - return function icontains(elem){ - return next(elem) && - getText(elem).toLowerCase().indexOf(itext) >= 0; + } + + function getChildFunc(next){ + return function(elem){ + return !!adapter.getParent(elem) && next(elem); }; - }, + } - //location specific methods - "nth-child": function(next, rule){ - var func = getNCheck(rule); - - if(func === falseFunc) return func; - if(func === trueFunc) return getChildFunc(next); - - return function nthChild(elem){ - var siblings = getSiblings(elem); - - for(var i = 0, pos = 0; i < siblings.length; i++){ - if(isTag(siblings[i])){ - if(siblings[i] === elem) break; - else pos++; + var filters = { + contains: function(next, text){ + return function contains(elem){ + return next(elem) && adapter.getText(elem).indexOf(text) >= 0; + }; + }, + icontains: function(next, text){ + var itext = text.toLowerCase(); + return function icontains(elem){ + return next(elem) && + adapter.getText(elem).toLowerCase().indexOf(itext) >= 0; + }; + }, + + //location specific methods + "nth-child": function(next, rule){ + var func = getNCheck(rule); + + if(func === falseFunc) return func; + if(func === trueFunc) return getChildFunc(next); + + return function nthChild(elem){ + var siblings = adapter.getSiblings(elem); + + for(var i = 0, pos = 0; i < siblings.length; i++){ + if(adapter.isTag(siblings[i])){ + if(siblings[i] === elem) break; + else pos++; + } } - } - return func(pos) && next(elem); - }; - }, - "nth-last-child": function(next, rule){ - var func = getNCheck(rule); - - if(func === falseFunc) return func; - if(func === trueFunc) return getChildFunc(next); - - return function nthLastChild(elem){ - var siblings = getSiblings(elem); - - for(var pos = 0, i = siblings.length - 1; i >= 0; i--){ - if(isTag(siblings[i])){ - if(siblings[i] === elem) break; - else pos++; + return func(pos) && next(elem); + }; + }, + "nth-last-child": function(next, rule){ + var func = getNCheck(rule); + + if(func === falseFunc) return func; + if(func === trueFunc) return getChildFunc(next); + + return function nthLastChild(elem){ + var siblings = adapter.getSiblings(elem); + + for(var pos = 0, i = siblings.length - 1; i >= 0; i--){ + if(adapter.isTag(siblings[i])){ + if(siblings[i] === elem) break; + else pos++; + } } - } - return func(pos) && next(elem); - }; - }, - "nth-of-type": function(next, rule){ - var func = getNCheck(rule); - - if(func === falseFunc) return func; - if(func === trueFunc) return getChildFunc(next); - - return function nthOfType(elem){ - var siblings = getSiblings(elem); - - for(var pos = 0, i = 0; i < siblings.length; i++){ - if(isTag(siblings[i])){ - if(siblings[i] === elem) break; - if(getName(siblings[i]) === getName(elem)) pos++; + return func(pos) && next(elem); + }; + }, + "nth-of-type": function(next, rule){ + var func = getNCheck(rule); + + if(func === falseFunc) return func; + if(func === trueFunc) return getChildFunc(next); + + return function nthOfType(elem){ + var siblings = adapter.getSiblings(elem); + + for(var pos = 0, i = 0; i < siblings.length; i++){ + if(adapter.isTag(siblings[i])){ + if(siblings[i] === elem) break; + if(adapter.getName(siblings[i]) === adapter.getName(elem)) pos++; + } } - } - return func(pos) && next(elem); - }; - }, - "nth-last-of-type": function(next, rule){ - var func = getNCheck(rule); - - if(func === falseFunc) return func; - if(func === trueFunc) return getChildFunc(next); - - return function nthLastOfType(elem){ - var siblings = getSiblings(elem); - - for(var pos = 0, i = siblings.length - 1; i >= 0; i--){ - if(isTag(siblings[i])){ - if(siblings[i] === elem) break; - if(getName(siblings[i]) === getName(elem)) pos++; + return func(pos) && next(elem); + }; + }, + "nth-last-of-type": function(next, rule){ + var func = getNCheck(rule); + + if(func === falseFunc) return func; + if(func === trueFunc) return getChildFunc(next); + + return function nthLastOfType(elem){ + var siblings = adapter.getSiblings(elem); + + for(var pos = 0, i = siblings.length - 1; i >= 0; i--){ + if(adapter.isTag(siblings[i])){ + if(siblings[i] === elem) break; + if(adapter.getName(siblings[i]) === adapter.getName(elem)) pos++; + } } + + return func(pos) && next(elem); + }; + }, + + //TODO determine the actual root element + root: function(next){ + return function(elem){ + return !adapter.getParent(elem) && next(elem); + }; + }, + + scope: function(next, rule, options, context){ + if(!context || context.length === 0){ + //equivalent to :root + return filters.root(next); } - return func(pos) && next(elem); - }; - }, + if(context.length === 1){ + //NOTE: can't be unpacked, as :has uses this for side-effects + return function(elem){ + return equals(context[0], elem) && next(elem); + }; + } + + return function(elem){ + return context.indexOf(elem) >= 0 && next(elem); + }; + }, + + //jQuery extensions (others follow as pseudos) + checkbox: getAttribFunc("type", "checkbox"), + file: getAttribFunc("type", "file"), + password: getAttribFunc("type", "password"), + radio: getAttribFunc("type", "radio"), + reset: getAttribFunc("type", "reset"), + image: getAttribFunc("type", "image"), + submit: getAttribFunc("type", "submit") + }; + return filters; +} - //TODO determine the actual root element - root: function(next){ - return function(elem){ - return !getParent(elem) && next(elem); - }; - }, - - scope: function(next, rule, options, context){ - if(!context || context.length === 0){ - //equivalent to :root - return filters.root(next); - } - - if(context.length === 1){ - //NOTE: can't be unpacked, as :has uses this for side-effects - return function(elem){ - return context[0] === elem && next(elem); - }; - } - - return function(elem){ - return context.indexOf(elem) >= 0 && next(elem); - }; - }, - - //jQuery extensions (others follow as pseudos) - checkbox: getAttribFunc("type", "checkbox"), - file: getAttribFunc("type", "file"), - password: getAttribFunc("type", "password"), - radio: getAttribFunc("type", "radio"), - reset: getAttribFunc("type", "reset"), - image: getAttribFunc("type", "image"), - submit: getAttribFunc("type", "submit") -}; - -//while filters are precompiled, pseudos get called when they are needed -var pseudos = { - empty: function(elem){ - return !getChildren(elem).some(function(elem){ - return isTag(elem) || elem.type === "text"; - }); - }, - - "first-child": function(elem){ - return getFirstElement(getSiblings(elem)) === elem; - }, - "last-child": function(elem){ - var siblings = getSiblings(elem); - - for(var i = siblings.length - 1; i >= 0; i--){ - if(siblings[i] === elem) return true; - if(isTag(siblings[i])) break; +function pseudosFactory(adapter){ + //helper methods + function getFirstElement(elems){ + for(var i = 0; elems && i < elems.length; i++){ + if(adapter.isTag(elems[i])) return elems[i]; } + } - return false; - }, - "first-of-type": function(elem){ - var siblings = getSiblings(elem); + //while filters are precompiled, pseudos get called when they are needed + var pseudos = { + empty: function(elem){ + return !adapter.getChildren(elem).some(function(elem){ + return adapter.isTag(elem) || elem.type === "text"; + }); + }, + + "first-child": function(elem){ + return getFirstElement(adapter.getSiblings(elem)) === elem; + }, + "last-child": function(elem){ + var siblings = adapter.getSiblings(elem); - for(var i = 0; i < siblings.length; i++){ - if(isTag(siblings[i])){ + for(var i = siblings.length - 1; i >= 0; i--){ if(siblings[i] === elem) return true; - if(getName(siblings[i]) === getName(elem)) break; + if(adapter.isTag(siblings[i])) break; } - } - return false; - }, - "last-of-type": function(elem){ - var siblings = getSiblings(elem); + return false; + }, + "first-of-type": function(elem){ + var siblings = adapter.getSiblings(elem); + + for(var i = 0; i < siblings.length; i++){ + if(adapter.isTag(siblings[i])){ + if(siblings[i] === elem) return true; + if(adapter.getName(siblings[i]) === adapter.getName(elem)) break; + } + } - for(var i = siblings.length-1; i >= 0; i--){ - if(isTag(siblings[i])){ - if(siblings[i] === elem) return true; - if(getName(siblings[i]) === getName(elem)) break; + return false; + }, + "last-of-type": function(elem){ + var siblings = adapter.getSiblings(elem); + + for(var i = siblings.length - 1; i >= 0; i--){ + if(adapter.isTag(siblings[i])){ + if(siblings[i] === elem) return true; + if(adapter.getName(siblings[i]) === adapter.getName(elem)) break; + } } - } - return false; - }, - "only-of-type": function(elem){ - var siblings = getSiblings(elem); - - for(var i = 0, j = siblings.length; i < j; i++){ - if(isTag(siblings[i])){ - if(siblings[i] === elem) continue; - if(getName(siblings[i]) === getName(elem)) return false; + return false; + }, + "only-of-type": function(elem){ + var siblings = adapter.getSiblings(elem); + + for(var i = 0, j = siblings.length; i < j; i++){ + if(adapter.isTag(siblings[i])){ + if(siblings[i] === elem) continue; + if(adapter.getName(siblings[i]) === adapter.getName(elem)) return false; + } } - } - return true; - }, - "only-child": function(elem){ - var siblings = getSiblings(elem); + return true; + }, + "only-child": function(elem){ + var siblings = adapter.getSiblings(elem); - for(var i = 0; i < siblings.length; i++){ - if(isTag(siblings[i]) && siblings[i] !== elem) return false; - } + for(var i = 0; i < siblings.length; i++){ + if(adapter.isTag(siblings[i]) && siblings[i] !== elem) return false; + } - return true; - }, + return true; + }, - //:matches(a, area, link)[href] - link: function(elem){ - return hasAttrib(elem, "href"); - }, - visited: falseFunc, //seems to be a valid implementation - //TODO: :any-link once the name is finalized (as an alias of :link) - - //forms - //to consider: :target - - //:matches([selected], select:not([multiple]):not(> option[selected]) > option:first-of-type) - selected: function(elem){ - if(hasAttrib(elem, "selected")) return true; - else if(getName(elem) !== "option") return false; - - //the first