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.
		
		
		
		
		
			
		
			
				
					
					
						
							77 lines
						
					
					
						
							2.4 KiB
						
					
					
				
			
		
		
	
	
							77 lines
						
					
					
						
							2.4 KiB
						
					
					
				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;
 | 
						|
 |