WIP - add extractor, generate snippet_data
This commit is contained in:
1
node_modules/css-selector-parser/.idea/.name
generated
vendored
Normal file
1
node_modules/css-selector-parser/.idea/.name
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
node-css-selector-parser
|
||||
2
node_modules/css-selector-parser/.npmignore
generated
vendored
Normal file
2
node_modules/css-selector-parser/.npmignore
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
test
|
||||
benchmark
|
||||
5
node_modules/css-selector-parser/.travis.yml
generated
vendored
Normal file
5
node_modules/css-selector-parser/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.12"
|
||||
19
node_modules/css-selector-parser/LICENSE
generated
vendored
Normal file
19
node_modules/css-selector-parser/LICENSE
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2013 Dulin Marat
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
82
node_modules/css-selector-parser/README.md
generated
vendored
Normal file
82
node_modules/css-selector-parser/README.md
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
node-css-selector-parser [](https://travis-ci.org/mdevils/node-css-selector-parser)
|
||||
========================
|
||||
|
||||
Fast and low memory CSS selector parser.
|
||||
|
||||
Parses CSS selector into object-model.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
```
|
||||
npm install css-selector-parser
|
||||
```
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
```javascript
|
||||
var CssSelectorParser = require('css-selector-parser').CssSelectorParser,
|
||||
|
||||
parser = new CssSelectorParser();
|
||||
|
||||
parser.registerSelectorPseudos('has');
|
||||
parser.registerNestingOperators('>', '+', '~');
|
||||
parser.registerAttrEqualityMods('^', '$', '*', '~');
|
||||
parser.enableSubstitutes();
|
||||
|
||||
var util = require('util');
|
||||
|
||||
console.log(util.inspect(parser.parse('a[href^=/], .container:has(nav) > a[href]:lt($var)'), false, null));
|
||||
```
|
||||
|
||||
Produces:
|
||||
|
||||
```javascript
|
||||
{ type: 'selectors',
|
||||
selectors:
|
||||
[ { type: 'ruleSet',
|
||||
rule:
|
||||
{ tagName: 'a',
|
||||
attrs: [ { name: 'href', operator: '^=', valueType: 'string', value: '/' } ],
|
||||
type: 'rule' } },
|
||||
{ type: 'ruleSet',
|
||||
rule:
|
||||
{ classNames: [ 'container' ],
|
||||
pseudos:
|
||||
[ { name: 'has',
|
||||
valueType: 'selector',
|
||||
value: { type: 'ruleSet', rule: { tagName: 'nav', type: 'rule' } } } ],
|
||||
type: 'rule',
|
||||
rule:
|
||||
{ tagName: 'a',
|
||||
attrs: [ { name: 'href' } ],
|
||||
pseudos: [ { name: 'lt', valueType: 'substitute', value: 'var' } ],
|
||||
nestingOperator: '>',
|
||||
type: 'rule' } } } ] }
|
||||
```
|
||||
|
||||
Token description
|
||||
-----------------
|
||||
|
||||
*type* may be one of:
|
||||
|
||||
* *selectors* — list of selectors, token contains *selectors* array of *ruleSet* tokens (based on "," operator).
|
||||
* *ruleSet* — selector, token contains *rule* field with *rule*-type object.
|
||||
* *rule* — single rule.
|
||||
|
||||
Fields for *rule* type.
|
||||
|
||||
* *tagName* — tag name for the rule (e.g. "div"), may be '*'.
|
||||
* *classNames* — list of CSS class names for the rule.
|
||||
* *attrs* — list of attribute rules; rule may contain fields:
|
||||
* *name* — attribute name, required field.
|
||||
* *valueType* — type of comparison value ("string" or "substitute").
|
||||
* *operator* — attribute value comparison operator.
|
||||
* *value* — comparison attribute value.
|
||||
* *pseudos* — list of pseudo class rules; rule may contain fields:
|
||||
* *name* — pseudo name, required field.
|
||||
* *valueType* — argument type ("string", "selector" or "substitute").
|
||||
* *value* — pseudo argument.
|
||||
* *nestingOperator* — the operator used to nest this rule (e.g. in selector "tag1 > tag2", tag2 will have nestingOperator=">")
|
||||
* *rule* — nested rule.
|
||||
3
node_modules/css-selector-parser/index.js
generated
vendored
Normal file
3
node_modules/css-selector-parser/index.js
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
CssSelectorParser: require('./lib/css-selector-parser.js').CssSelectorParser
|
||||
};
|
||||
596
node_modules/css-selector-parser/lib/css-selector-parser.js
generated
vendored
Normal file
596
node_modules/css-selector-parser/lib/css-selector-parser.js
generated
vendored
Normal file
@ -0,0 +1,596 @@
|
||||
function CssSelectorParser() {
|
||||
this.pseudos = {};
|
||||
this.attrEqualityMods = {};
|
||||
this.ruleNestingOperators = {};
|
||||
this.substitutesEnabled = false;
|
||||
}
|
||||
|
||||
CssSelectorParser.prototype.registerSelectorPseudos = function(name) {
|
||||
for (var j = 0, len = arguments.length; j < len; j++) {
|
||||
name = arguments[j];
|
||||
this.pseudos[name] = 'selector';
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
CssSelectorParser.prototype.unregisterSelectorPseudos = function(name) {
|
||||
for (var j = 0, len = arguments.length; j < len; j++) {
|
||||
name = arguments[j];
|
||||
delete this.pseudos[name];
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
CssSelectorParser.prototype.registerNumericPseudos = function(name) {
|
||||
for (var j = 0, len = arguments.length; j < len; j++) {
|
||||
name = arguments[j];
|
||||
this.pseudos[name] = 'numeric';
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
CssSelectorParser.prototype.unregisterNumericPseudos = function(name) {
|
||||
for (var j = 0, len = arguments.length; j < len; j++) {
|
||||
name = arguments[j];
|
||||
delete this.pseudos[name];
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
CssSelectorParser.prototype.registerNestingOperators = function(operator) {
|
||||
for (var j = 0, len = arguments.length; j < len; j++) {
|
||||
operator = arguments[j];
|
||||
this.ruleNestingOperators[operator] = true;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
CssSelectorParser.prototype.unregisterNestingOperators = function(operator) {
|
||||
for (var j = 0, len = arguments.length; j < len; j++) {
|
||||
operator = arguments[j];
|
||||
delete this.ruleNestingOperators[operator];
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
CssSelectorParser.prototype.registerAttrEqualityMods = function(mod) {
|
||||
for (var j = 0, len = arguments.length; j < len; j++) {
|
||||
mod = arguments[j];
|
||||
this.attrEqualityMods[mod] = true;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
CssSelectorParser.prototype.unregisterAttrEqualityMods = function(mod) {
|
||||
for (var j = 0, len = arguments.length; j < len; j++) {
|
||||
mod = arguments[j];
|
||||
delete this.attrEqualityMods[mod];
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
CssSelectorParser.prototype.enableSubstitutes = function() {
|
||||
this.substitutesEnabled = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
CssSelectorParser.prototype.disableSubstitutes = function() {
|
||||
this.substitutesEnabled = false;
|
||||
return this;
|
||||
};
|
||||
|
||||
function isIdentStart(c) {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c === '-') || (c === '_');
|
||||
}
|
||||
|
||||
function isIdent(c) {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c === '-' || c === '_';
|
||||
}
|
||||
|
||||
function isHex(c) {
|
||||
return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9');
|
||||
}
|
||||
|
||||
function isDecimal(c) {
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
function isAttrMatchOperator(chr) {
|
||||
return chr === '=' || chr === '^' || chr === '$' || chr === '*' || chr === '~';
|
||||
}
|
||||
|
||||
var identSpecialChars = {
|
||||
'!': true,
|
||||
'"': true,
|
||||
'#': true,
|
||||
'$': true,
|
||||
'%': true,
|
||||
'&': true,
|
||||
'\'': true,
|
||||
'(': true,
|
||||
')': true,
|
||||
'*': true,
|
||||
'+': true,
|
||||
',': true,
|
||||
'.': true,
|
||||
'/': true,
|
||||
';': true,
|
||||
'<': true,
|
||||
'=': true,
|
||||
'>': true,
|
||||
'?': true,
|
||||
'@': true,
|
||||
'[': true,
|
||||
'\\': true,
|
||||
']': true,
|
||||
'^': true,
|
||||
'`': true,
|
||||
'{': true,
|
||||
'|': true,
|
||||
'}': true,
|
||||
'~': true
|
||||
};
|
||||
|
||||
var strReplacementsRev = {
|
||||
'\n': '\\n',
|
||||
'\r': '\\r',
|
||||
'\t': '\\t',
|
||||
'\f': '\\f',
|
||||
'\v': '\\v'
|
||||
};
|
||||
|
||||
var singleQuoteEscapeChars = {
|
||||
n: '\n',
|
||||
r: '\r',
|
||||
t: '\t',
|
||||
f: '\f',
|
||||
'\\': '\\',
|
||||
'\'': '\''
|
||||
};
|
||||
|
||||
var doubleQuotesEscapeChars = {
|
||||
n: '\n',
|
||||
r: '\r',
|
||||
t: '\t',
|
||||
f: '\f',
|
||||
'\\': '\\',
|
||||
'"': '"'
|
||||
};
|
||||
|
||||
function ParseContext(str, pos, pseudos, attrEqualityMods, ruleNestingOperators, substitutesEnabled) {
|
||||
var chr, getIdent, getStr, l, skipWhitespace;
|
||||
l = str.length;
|
||||
chr = null;
|
||||
getStr = function(quote, escapeTable) {
|
||||
var esc, hex, result;
|
||||
result = '';
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
while (pos < l) {
|
||||
if (chr === quote) {
|
||||
pos++;
|
||||
return result;
|
||||
} else if (chr === '\\') {
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
if (chr === quote) {
|
||||
result += quote;
|
||||
} else if (esc = escapeTable[chr]) {
|
||||
result += esc;
|
||||
} else if (isHex(chr)) {
|
||||
hex = chr;
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
while (isHex(chr)) {
|
||||
hex += chr;
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
}
|
||||
if (chr === ' ') {
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
}
|
||||
result += String.fromCharCode(parseInt(hex, 16));
|
||||
continue;
|
||||
} else {
|
||||
result += chr;
|
||||
}
|
||||
} else {
|
||||
result += chr;
|
||||
}
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
getIdent = function() {
|
||||
var result = '';
|
||||
chr = str.charAt(pos);
|
||||
while (pos < l) {
|
||||
if (isIdent(chr)) {
|
||||
result += chr;
|
||||
} else if (chr === '\\') {
|
||||
pos++;
|
||||
if (pos >= l) {
|
||||
throw Error('Expected symbol but end of file reached.');
|
||||
}
|
||||
chr = str.charAt(pos);
|
||||
if (identSpecialChars[chr]) {
|
||||
result += chr;
|
||||
} else if (isHex(chr)) {
|
||||
var hex = chr;
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
while (isHex(chr)) {
|
||||
hex += chr;
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
}
|
||||
if (chr === ' ') {
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
}
|
||||
result += String.fromCharCode(parseInt(hex, 16));
|
||||
continue;
|
||||
} else {
|
||||
result += chr;
|
||||
}
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
skipWhitespace = function() {
|
||||
chr = str.charAt(pos);
|
||||
var result = false;
|
||||
while (chr === ' ' || chr === "\t" || chr === "\n" || chr === "\r" || chr === "\f") {
|
||||
result = true;
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
this.parse = function() {
|
||||
var res = this.parseSelector();
|
||||
if (pos < l) {
|
||||
throw Error('Rule expected but "' + str.charAt(pos) + '" found.');
|
||||
}
|
||||
return res;
|
||||
};
|
||||
this.parseSelector = function() {
|
||||
var res;
|
||||
var selector = res = this.parseSingleSelector();
|
||||
chr = str.charAt(pos);
|
||||
while (chr === ',') {
|
||||
pos++;
|
||||
skipWhitespace();
|
||||
if (res.type !== 'selectors') {
|
||||
res = {
|
||||
type: 'selectors',
|
||||
selectors: [selector]
|
||||
};
|
||||
}
|
||||
selector = this.parseSingleSelector();
|
||||
if (!selector) {
|
||||
throw Error('Rule expected after ",".');
|
||||
}
|
||||
res.selectors.push(selector);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
this.parseSingleSelector = function() {
|
||||
skipWhitespace();
|
||||
var selector = {
|
||||
type: 'ruleSet'
|
||||
};
|
||||
var rule = this.parseRule();
|
||||
if (!rule) {
|
||||
return null;
|
||||
}
|
||||
var currentRule = selector;
|
||||
while (rule) {
|
||||
rule.type = 'rule';
|
||||
currentRule.rule = rule;
|
||||
currentRule = rule;
|
||||
skipWhitespace();
|
||||
chr = str.charAt(pos);
|
||||
if (pos >= l || chr === ',' || chr === ')') {
|
||||
break;
|
||||
}
|
||||
if (ruleNestingOperators[chr]) {
|
||||
var op = chr;
|
||||
pos++;
|
||||
skipWhitespace();
|
||||
rule = this.parseRule();
|
||||
if (!rule) {
|
||||
throw Error('Rule expected after "' + op + '".');
|
||||
}
|
||||
rule.nestingOperator = op;
|
||||
} else {
|
||||
rule = this.parseRule();
|
||||
if (rule) {
|
||||
rule.nestingOperator = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return selector;
|
||||
};
|
||||
|
||||
this.parseRule = function() {
|
||||
var rule = null;
|
||||
while (pos < l) {
|
||||
chr = str.charAt(pos);
|
||||
if (chr === '*') {
|
||||
pos++;
|
||||
(rule = rule || {}).tagName = '*';
|
||||
} else if (isIdentStart(chr) || chr === '\\') {
|
||||
(rule = rule || {}).tagName = getIdent();
|
||||
} else if (chr === '.') {
|
||||
pos++;
|
||||
rule = rule || {};
|
||||
(rule.classNames = rule.classNames || []).push(getIdent());
|
||||
} else if (chr === '#') {
|
||||
pos++;
|
||||
(rule = rule || {}).id = getIdent();
|
||||
} else if (chr === '[') {
|
||||
pos++;
|
||||
skipWhitespace();
|
||||
var attr = {
|
||||
name: getIdent()
|
||||
};
|
||||
skipWhitespace();
|
||||
if (chr === ']') {
|
||||
pos++;
|
||||
} else {
|
||||
var operator = '';
|
||||
if (attrEqualityMods[chr]) {
|
||||
operator = chr;
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
}
|
||||
if (pos >= l) {
|
||||
throw Error('Expected "=" but end of file reached.');
|
||||
}
|
||||
if (chr !== '=') {
|
||||
throw Error('Expected "=" but "' + chr + '" found.');
|
||||
}
|
||||
attr.operator = operator + '=';
|
||||
pos++;
|
||||
skipWhitespace();
|
||||
var attrValue = '';
|
||||
attr.valueType = 'string';
|
||||
if (chr === '"') {
|
||||
attrValue = getStr('"', doubleQuotesEscapeChars);
|
||||
} else if (chr === '\'') {
|
||||
attrValue = getStr('\'', singleQuoteEscapeChars);
|
||||
} else if (substitutesEnabled && chr === '$') {
|
||||
pos++;
|
||||
attrValue = getIdent();
|
||||
attr.valueType = 'substitute';
|
||||
} else {
|
||||
while (pos < l) {
|
||||
if (chr === ']') {
|
||||
break;
|
||||
}
|
||||
attrValue += chr;
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
}
|
||||
attrValue = attrValue.trim();
|
||||
}
|
||||
skipWhitespace();
|
||||
if (pos >= l) {
|
||||
throw Error('Expected "]" but end of file reached.');
|
||||
}
|
||||
if (chr !== ']') {
|
||||
throw Error('Expected "]" but "' + chr + '" found.');
|
||||
}
|
||||
pos++;
|
||||
attr.value = attrValue;
|
||||
}
|
||||
rule = rule || {};
|
||||
(rule.attrs = rule.attrs || []).push(attr);
|
||||
} else if (chr === ':') {
|
||||
pos++;
|
||||
var pseudoName = getIdent();
|
||||
var pseudo = {
|
||||
name: pseudoName
|
||||
};
|
||||
if (chr === '(') {
|
||||
pos++;
|
||||
var value = '';
|
||||
skipWhitespace();
|
||||
if (pseudos[pseudoName] === 'selector') {
|
||||
pseudo.valueType = 'selector';
|
||||
value = this.parseSelector();
|
||||
} else {
|
||||
pseudo.valueType = pseudos[pseudoName] || 'string';
|
||||
if (chr === '"') {
|
||||
value = getStr('"', doubleQuotesEscapeChars);
|
||||
} else if (chr === '\'') {
|
||||
value = getStr('\'', singleQuoteEscapeChars);
|
||||
} else if (substitutesEnabled && chr === '$') {
|
||||
pos++;
|
||||
value = getIdent();
|
||||
pseudo.valueType = 'substitute';
|
||||
} else {
|
||||
while (pos < l) {
|
||||
if (chr === ')') {
|
||||
break;
|
||||
}
|
||||
value += chr;
|
||||
pos++;
|
||||
chr = str.charAt(pos);
|
||||
}
|
||||
value = value.trim();
|
||||
}
|
||||
skipWhitespace();
|
||||
}
|
||||
if (pos >= l) {
|
||||
throw Error('Expected ")" but end of file reached.');
|
||||
}
|
||||
if (chr !== ')') {
|
||||
throw Error('Expected ")" but "' + chr + '" found.');
|
||||
}
|
||||
pos++;
|
||||
pseudo.value = value;
|
||||
}
|
||||
rule = rule || {};
|
||||
(rule.pseudos = rule.pseudos || []).push(pseudo);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rule;
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
CssSelectorParser.prototype.parse = function(str) {
|
||||
var context = new ParseContext(
|
||||
str,
|
||||
0,
|
||||
this.pseudos,
|
||||
this.attrEqualityMods,
|
||||
this.ruleNestingOperators,
|
||||
this.substitutesEnabled
|
||||
);
|
||||
return context.parse();
|
||||
};
|
||||
|
||||
CssSelectorParser.prototype.escapeIdentifier = function(s) {
|
||||
var result = '';
|
||||
var i = 0;
|
||||
var len = s.length;
|
||||
while (i < len) {
|
||||
var chr = s.charAt(i);
|
||||
if (identSpecialChars[chr]) {
|
||||
result += '\\' + chr;
|
||||
} else {
|
||||
if (
|
||||
!(
|
||||
chr === '_' || chr === '-' ||
|
||||
(chr >= 'A' && chr <= 'Z') ||
|
||||
(chr >= 'a' && chr <= 'z') ||
|
||||
(i !== 0 && chr >= '0' && chr <= '9')
|
||||
)
|
||||
) {
|
||||
var charCode = chr.charCodeAt(0);
|
||||
if ((charCode & 0xF800) === 0xD800) {
|
||||
var extraCharCode = s.charCodeAt(i++);
|
||||
if ((charCode & 0xFC00) !== 0xD800 || (extraCharCode & 0xFC00) !== 0xDC00) {
|
||||
throw Error('UCS-2(decode): illegal sequence');
|
||||
}
|
||||
charCode = ((charCode & 0x3FF) << 10) + (extraCharCode & 0x3FF) + 0x10000;
|
||||
}
|
||||
result += '\\' + charCode.toString(16) + ' ';
|
||||
} else {
|
||||
result += chr;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
CssSelectorParser.prototype.escapeStr = function(s) {
|
||||
var result = '';
|
||||
var i = 0;
|
||||
var len = s.length;
|
||||
var chr, replacement;
|
||||
while (i < len) {
|
||||
chr = s.charAt(i);
|
||||
if (chr === '"') {
|
||||
chr = '\\"';
|
||||
} else if (chr === '\\') {
|
||||
chr = '\\\\';
|
||||
} else if (replacement = strReplacementsRev[chr]) {
|
||||
chr = replacement;
|
||||
}
|
||||
result += chr;
|
||||
i++;
|
||||
}
|
||||
return "\"" + result + "\"";
|
||||
};
|
||||
|
||||
CssSelectorParser.prototype.render = function(path) {
|
||||
return this._renderEntity(path).trim();
|
||||
};
|
||||
|
||||
CssSelectorParser.prototype._renderEntity = function(entity) {
|
||||
var currentEntity, parts, res;
|
||||
res = '';
|
||||
switch (entity.type) {
|
||||
case 'ruleSet':
|
||||
currentEntity = entity.rule;
|
||||
parts = [];
|
||||
while (currentEntity) {
|
||||
if (currentEntity.nestingOperator) {
|
||||
parts.push(currentEntity.nestingOperator);
|
||||
}
|
||||
parts.push(this._renderEntity(currentEntity));
|
||||
currentEntity = currentEntity.rule;
|
||||
}
|
||||
res = parts.join(' ');
|
||||
break;
|
||||
case 'selectors':
|
||||
res = entity.selectors.map(this._renderEntity, this).join(', ');
|
||||
break;
|
||||
case 'rule':
|
||||
if (entity.tagName) {
|
||||
if (entity.tagName === '*') {
|
||||
res = '*';
|
||||
} else {
|
||||
res = this.escapeIdentifier(entity.tagName);
|
||||
}
|
||||
}
|
||||
if (entity.id) {
|
||||
res += "#" + this.escapeIdentifier(entity.id);
|
||||
}
|
||||
if (entity.classNames) {
|
||||
res += entity.classNames.map(function(cn) {
|
||||
return "." + (this.escapeIdentifier(cn));
|
||||
}, this).join('');
|
||||
}
|
||||
if (entity.attrs) {
|
||||
res += entity.attrs.map(function(attr) {
|
||||
if (attr.operator) {
|
||||
if (attr.valueType === 'substitute') {
|
||||
return "[" + this.escapeIdentifier(attr.name) + attr.operator + "$" + attr.value + "]";
|
||||
} else {
|
||||
return "[" + this.escapeIdentifier(attr.name) + attr.operator + this.escapeStr(attr.value) + "]";
|
||||
}
|
||||
} else {
|
||||
return "[" + this.escapeIdentifier(attr.name) + "]";
|
||||
}
|
||||
}, this).join('');
|
||||
}
|
||||
if (entity.pseudos) {
|
||||
res += entity.pseudos.map(function(pseudo) {
|
||||
if (pseudo.valueType) {
|
||||
if (pseudo.valueType === 'selector') {
|
||||
return ":" + this.escapeIdentifier(pseudo.name) + "(" + this._renderEntity(pseudo.value) + ")";
|
||||
} else if (pseudo.valueType === 'substitute') {
|
||||
return ":" + this.escapeIdentifier(pseudo.name) + "($" + pseudo.value + ")";
|
||||
} else if (pseudo.valueType === 'numeric') {
|
||||
return ":" + this.escapeIdentifier(pseudo.name) + "(" + pseudo.value + ")";
|
||||
} else {
|
||||
return ":" + this.escapeIdentifier(pseudo.name) + "(" + this.escapeIdentifier(pseudo.value) + ")";
|
||||
}
|
||||
} else {
|
||||
return ":" + this.escapeIdentifier(pseudo.name);
|
||||
}
|
||||
}, this).join('');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw Error('Unknown entity type: "' + entity.type(+'".'));
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
exports.CssSelectorParser = CssSelectorParser;
|
||||
61
node_modules/css-selector-parser/package.json
generated
vendored
Normal file
61
node_modules/css-selector-parser/package.json
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"_from": "css-selector-parser@^1.1.0",
|
||||
"_id": "css-selector-parser@1.3.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-XxrUPi2O77/cME/NOaUhZklD4+s=",
|
||||
"_location": "/css-selector-parser",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "css-selector-parser@^1.1.0",
|
||||
"name": "css-selector-parser",
|
||||
"escapedName": "css-selector-parser",
|
||||
"rawSpec": "^1.1.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^1.1.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/unist-util-select"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.3.0.tgz",
|
||||
"_shasum": "5f1ad43e2d8eefbfdc304fcd39a521664943e3eb",
|
||||
"_spec": "css-selector-parser@^1.1.0",
|
||||
"_where": "/Users/stefanfejes/Projects/30-seconds-of-python-code/node_modules/unist-util-select",
|
||||
"author": {
|
||||
"name": "Marat Dulin",
|
||||
"email": "mdevils@yandex.ru"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/mdevils/node-css-selector-parser/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {},
|
||||
"deprecated": false,
|
||||
"description": "Just a CSS selector parser.",
|
||||
"devDependencies": {
|
||||
"coffee-script": "^1.9.3",
|
||||
"colors": "*"
|
||||
},
|
||||
"engines": [
|
||||
"node >= 0.4.0"
|
||||
],
|
||||
"homepage": "https://github.com/mdevils/node-css-selector-parser#readme",
|
||||
"keywords": [
|
||||
"css",
|
||||
"css selector",
|
||||
"css selector parser"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index",
|
||||
"name": "css-selector-parser",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/mdevils/node-css-selector-parser.git"
|
||||
},
|
||||
"scripts": {
|
||||
"benchmark": "node benchmark/benchmark.js",
|
||||
"test": "node test/test.js"
|
||||
},
|
||||
"version": "1.3.0"
|
||||
}
|
||||
Reference in New Issue
Block a user