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.
|
|
var Marker = require('../../tokenizer/marker');
var Selector = { ADJACENT_SIBLING: '+', DESCENDANT: '>', DOT: '.', HASH: '#', NON_ADJACENT_SIBLING: '~', PSEUDO: ':' };
var LETTER_PATTERN = /[a-zA-Z]/; var NOT_PREFIX = ':not('; var SEPARATOR_PATTERN = /[\s,\(>~\+]/;
function specificity(selector) { var result = [0, 0, 0]; var character; var isEscaped; var isSingleQuoted; var isDoubleQuoted; var roundBracketLevel = 0; var couldIntroduceNewTypeSelector; var withinNotPseudoClass = false; var wasPseudoClass = false; var i, l;
for (i = 0, l = selector.length; i < l; i++) { character = selector[i];
if (isEscaped) { // noop
} else if (character == Marker.SINGLE_QUOTE && !isDoubleQuoted && !isSingleQuoted) { isSingleQuoted = true; } else if (character == Marker.SINGLE_QUOTE && !isDoubleQuoted && isSingleQuoted) { isSingleQuoted = false; } else if (character == Marker.DOUBLE_QUOTE && !isDoubleQuoted && !isSingleQuoted) { isDoubleQuoted = true; } else if (character == Marker.DOUBLE_QUOTE && isDoubleQuoted && !isSingleQuoted) { isDoubleQuoted = false; } else if (isSingleQuoted || isDoubleQuoted) { continue; } else if (roundBracketLevel > 0 && !withinNotPseudoClass) { // noop
} else if (character == Marker.OPEN_ROUND_BRACKET) { roundBracketLevel++; } else if (character == Marker.CLOSE_ROUND_BRACKET && roundBracketLevel == 1) { roundBracketLevel--; withinNotPseudoClass = false; } else if (character == Marker.CLOSE_ROUND_BRACKET) { roundBracketLevel--; } else if (character == Selector.HASH) { result[0]++; } else if (character == Selector.DOT || character == Marker.OPEN_SQUARE_BRACKET) { result[1]++; } else if (character == Selector.PSEUDO && !wasPseudoClass && !isNotPseudoClass(selector, i)) { result[1]++; withinNotPseudoClass = false; } else if (character == Selector.PSEUDO) { withinNotPseudoClass = true; } else if ((i === 0 || couldIntroduceNewTypeSelector) && LETTER_PATTERN.test(character)) { result[2]++; }
isEscaped = character == Marker.BACK_SLASH; wasPseudoClass = character == Selector.PSEUDO; couldIntroduceNewTypeSelector = !isEscaped && SEPARATOR_PATTERN.test(character); }
return result; }
function isNotPseudoClass(selector, index) { return selector.indexOf(NOT_PREFIX, index) === index; }
module.exports = specificity;
|