12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- 'use strict';
- var parser = require('slick/parser');
- module.exports = exports = Selector;
- /**
- * CSS selector constructor.
- *
- * @param {String} selector text
- * @param {Array} optionally, precalculated specificity
- * @api public
- */
- function Selector(text, styleAttribute) {
- this.text = text;
- this.spec = undefined;
- this.styleAttribute = styleAttribute || false;
- }
- /**
- * Get parsed selector.
- *
- * @api public
- */
- Selector.prototype.parsed = function() {
- if (!this.tokens) { this.tokens = parse(this.text); }
- return this.tokens;
- };
- /**
- * Lazy specificity getter
- *
- * @api public
- */
- Selector.prototype.specificity = function() {
- var styleAttribute = this.styleAttribute;
- if (!this.spec) { this.spec = specificity(this.text, this.parsed()); }
- return this.spec;
- function specificity(text, parsed) {
- var expressions = parsed || parse(text);
- var spec = [styleAttribute ? 1 : 0, 0, 0, 0];
- var nots = [];
- for (var i = 0; i < expressions.length; i++) {
- var expression = expressions[i];
- var pseudos = expression.pseudos;
- // id awards a point in the second column
- if (expression.id) { spec[1]++; }
- // classes and attributes award a point each in the third column
- if (expression.attributes) { spec[2] += expression.attributes.length; }
- if (expression.classList) { spec[2] += expression.classList.length; }
- // tag awards a point in the fourth column
- if (expression.tag && expression.tag !== '*') { spec[3]++; }
- // pseudos award a point each in the fourth column
- if (pseudos) {
- spec[3] += pseudos.length;
- for (var p = 0; p < pseudos.length; p++) {
- if (pseudos[p].name === 'not') {
- nots.push(pseudos[p].value);
- spec[3]--;
- }
- }
- }
- }
- for (var ii = nots.length; ii--;) {
- var not = specificity(nots[ii]);
- for (var jj = 4; jj--;) { spec[jj] += not[jj]; }
- }
- return spec;
- }
- };
- /**
- * Parses a selector and returns the tokens.
- *
- * @param {String} selector
- * @api private.
- */
- function parse(text) {
- try {
- return parser(text)[0];
- } catch (e) {
- return [];
- }
- }
|