You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

137 lines
3.8 KiB

var trim = require('./trim');
var each = require('./each');
var identity = require('./identity');
var map = require('./map');
var whitespace = '[\\x20\\t\\r\\n\\f]';
var identifier = '(?:\\\\[\\da-fA-F]{1,6}'.concat(
whitespace,
'?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+'
);
var attributes = '\\['
.concat(whitespace, '*(')
.concat(identifier, ')(?:')
.concat(whitespace, '*([*^$|!~]?=)')
.concat(
whitespace,
'*(?:\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)"|('
)
.concat(identifier, '))|)')
.concat(whitespace, '*\\]');
var pseudos = '::?('
.concat(
identifier,
')(?:\\(((\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)")|((?:\\\\.|[^\\\\()[\\]]|'
)
.concat(attributes, ')*)|.*)\\)|)');
var regComma = new RegExp('^'.concat(whitespace, '*,').concat(whitespace, '*'));
var regCombinators = new RegExp(
'^'
.concat(whitespace, '*([>+~]|')
.concat(whitespace, ')')
.concat(whitespace, '*')
);
var matchExpr = {
id: {
reg: new RegExp('^#('.concat(identifier, ')')),
value: function(raw) {
return raw.slice(1);
},
toStr: function(value) {
return '#'.concat(value);
}
},
class: {
reg: new RegExp('^\\.('.concat(identifier, ')')),
value: function(raw) {
return raw.slice(1);
},
toStr: function(value) {
return '.'.concat(value);
}
},
tag: {
reg: new RegExp('^('.concat(identifier, '|[*])')),
value: identity
},
attribute: {
reg: new RegExp('^'.concat(attributes)),
value: function(raw) {
return raw.slice(1, raw.length - 1);
},
toStr: function(value) {
return '['.concat(value, ']');
}
},
pseudo: {
reg: new RegExp('^'.concat(pseudos)),
value: identity
}
};
each(matchExpr, function(item) {
if (!item.value) item.value = identity;
if (!item.toStr) item.toStr = identity;
});
function parse(selector) {
selector = trim(selector);
var groups = [];
var tokens;
var match;
var matched;
while (selector) {
if (!matched || (match = regComma.exec(selector))) {
if (match) {
selector = selector.slice(match[0].length);
}
tokens = [];
groups.push(tokens);
}
matched = false;
if ((match = regCombinators.exec(selector))) {
matched = match.shift();
selector = selector.slice(matched.length);
matched = trim(matched);
if (!matched) matched = ' ';
tokens.push({
value: matched,
type: 'combinator'
});
}
each(matchExpr, function(_ref, type) {
var reg = _ref.reg,
value = _ref.value;
if ((match = reg.exec(selector))) {
matched = match.shift();
selector = selector.slice(matched.length);
matched = trim(matched);
tokens.push({
value: value(matched),
type: type
});
}
});
if (!matched) {
break;
}
}
return groups;
}
function stringify(groups) {
return map(groups, function(group) {
group = map(group, function(_ref2) {
var type = _ref2.type,
value = _ref2.value;
if (type === 'combinator') {
return value === ' ' ? value : ' '.concat(value, ' ');
}
return matchExpr[type].toStr(value);
});
return group.join('');
}).join(', ');
}
exports = {
parse: parse,
stringify: stringify
};
module.exports = exports;