specificity
Advanced tools
Comparing version 0.1.1 to 0.1.2
{ | ||
"name" : "specificity", | ||
"version" : "0.1.1", | ||
"version" : "0.1.2", | ||
"description" : "Calculate the specificity of a CSS selector", | ||
@@ -5,0 +5,0 @@ "keywords" : ["CSS", "specificity"], |
@@ -32,5 +32,3 @@ # Specificity Calculator | ||
* `specificity`: the result e.g. `0,1,0,0` | ||
* `a`: array with details about the IDs contributing to the specificity | ||
* `b`: array with details about the classes, attributes and pseudo-classes contributing to the specificity | ||
* `c`: array with details about type selectors and pseudo-elements contributing to the specificity | ||
* `parts`: array with details about each part of the selector that counts towards the specificity | ||
@@ -49,8 +47,8 @@ ## Example | ||
specificity: '0,1,1,3', | ||
a: [ { selector: '#nav', index: 2, length: 4 } ], | ||
b: [ { selector: '.active', index: 8, length: 7 } ], | ||
c: [ | ||
{ selector: 'ul', index: 0, length: 2 }, | ||
{ selector: 'li', index: 5, length: 2 }, | ||
{ selector: 'a', index: 13, length: 1 } | ||
parts: [ | ||
{ selector: 'ul', type: 'c', index: 0, length: 2 }, | ||
{ selector: '#nav', type: 'a', index: 2, length: 4 }, | ||
{ selector: 'li', type: 'c', index: 5, length: 2 }, | ||
{ selector: '.active', type: 'b', index: 8, length: 7 }, | ||
{ selector: 'a', type: 'c', index: 13, length: 1 } | ||
] | ||
@@ -57,0 +55,0 @@ } ] |
@@ -14,5 +14,3 @@ if (!String.prototype.trim) { | ||
* - specificity: e.g. 0,1,0,0 | ||
* - a: array with details about each part of the selector contributing to the "a" count (IDs) | ||
* - b: array with details about each part of the selector contributing to the "b" count (classes, attributes and pseudo-classes) | ||
* - c: array with details about each part of the selector contributing to the "c" count (types and pseudo-elements) | ||
* - parts: array with details about each part of the selector that counts towards the specificity | ||
*/ | ||
@@ -25,2 +23,3 @@ var SPECIFICITY = (function() { | ||
var selectors, | ||
selector, | ||
i, | ||
@@ -30,7 +29,13 @@ len, | ||
input.replace(/(\r\n|\n|\r)/gm, ''); | ||
// Replace new lines with commas | ||
input.replace(/(\r\n|\n|\r)/gm, ','); | ||
// Separate input by commas | ||
selectors = input.split(','); | ||
for (i = 0, len = selectors.length; i < len; i += 1) { | ||
results.push(calculateSingle(selectors[i])); | ||
selector = selectors[i].trim(); | ||
if (selector.length > 0) { | ||
results.push(calculateSingle(selector)); | ||
} | ||
} | ||
@@ -45,3 +50,8 @@ | ||
findMatch, | ||
a = [], b = [], c = [], | ||
typeCount = { | ||
'a': 0, | ||
'b': 0, | ||
'c': 0 | ||
}, | ||
parts = [], | ||
// The following regular expressions assume that selectors matching the preceding regular expressions have been removed | ||
@@ -53,6 +63,7 @@ attributeRegex = /(\[[^\]]+\])/g, | ||
pseudoClassRegex = /(:[^\s\+>~\.\[:]+)/g, | ||
typeRegex = /([^\s\+>~\.\[:]+)/g; | ||
elementRegex = /([^\s\+>~\.\[:]+)/g; | ||
// Find matches for a regular expression in a string and push their details to output | ||
findMatch = function(regex, output) { | ||
// Find matches for a regular expression in a string and push their details to parts | ||
// Type is "a" for IDs, "b" for classes, attributes and pseudo-classes and "c" for elements and pseudo-elements | ||
findMatch = function(regex, type) { | ||
var matches, i, match, index, length; | ||
@@ -63,9 +74,11 @@ if (regex.test(selector)) { | ||
if (matches.hasOwnProperty(i)) { | ||
typeCount[type] += 1; | ||
match = matches[i]; | ||
index = selector.indexOf(match); | ||
length = match.length; | ||
output.push({ | ||
parts.push({ | ||
selector: match, | ||
type: type, | ||
index: index, | ||
length: length, | ||
selector: match | ||
length: length | ||
}); | ||
@@ -87,16 +100,16 @@ // Replace this simple selector with whitespace so it won't be counted in further simple selectors | ||
// Add attribute selectors to b collection | ||
findMatch(attributeRegex, b); | ||
// Add attribute selectors to parts collection (type b) | ||
findMatch(attributeRegex, 'b'); | ||
// Add ID selectors to a collection | ||
findMatch(idRegex, a); | ||
// Add ID selectors to parts collection (type a) | ||
findMatch(idRegex, 'a'); | ||
// Add class selectors to b collection | ||
findMatch(classRegex, b); | ||
// Add class selectors to parts collection (type b) | ||
findMatch(classRegex, 'b'); | ||
// Add pseudo-element selectors to c collection | ||
findMatch(pseudoElementRegex, c); | ||
// Add pseudo-element selectors to parts collection (type c) | ||
findMatch(pseudoElementRegex, 'c'); | ||
// Add pseudo-class selectors to b collection | ||
findMatch(pseudoClassRegex, b); | ||
// Add pseudo-class selectors to parts collection (type b) | ||
findMatch(pseudoClassRegex, 'b'); | ||
@@ -106,11 +119,15 @@ // Remove universal selector and separator characters | ||
// The only things left should be type selectors | ||
findMatch(typeRegex, c); | ||
// The only things left should be element selectors (type c) | ||
findMatch(elementRegex, 'c'); | ||
// Order the parts in the order they appear in the original selector | ||
// This is neater for external apps to deal with | ||
parts.sort(function(a, b) { | ||
return a.index - b.index; | ||
}); | ||
return { | ||
selector: input, | ||
specificity: '0,' + a.length.toString() + ',' + b.length.toString() + ',' + c.length.toString(), | ||
a: a, | ||
b: b, | ||
c: c, | ||
specificity: '0,' + typeCount.a.toString() + ',' + typeCount.b.toString() + ',' + typeCount.c.toString(), | ||
parts: parts | ||
}; | ||
@@ -117,0 +134,0 @@ }; |
7344
146
55