Socket
Socket
Sign inDemoInstall

specificity

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

specificity - npm Package Compare versions

Comparing version 0.1.6 to 0.2.0

2

package.json
{
"name": "specificity",
"version": "0.1.6",
"version": "0.2.0",
"description": "Calculate the specificity of a CSS selector",

@@ -5,0 +5,0 @@ "keywords": [

# Specificity Calculator
A JavaScript module for calculating the [specificity of CSS selectors](http://www.w3.org/TR/css3-selectors/#specificity). The module is used on the [Specificity Calculator](http://specificity.keegan.st/) website.
A JavaScript module for calculating and comparing the [specificity of CSS selectors](http://www.w3.org/TR/css3-selectors/#specificity). The module is used on the [Specificity Calculator](http://specificity.keegan.st/) website.

@@ -34,3 +34,4 @@ Specificity Calculator is built for CSS Selectors Level 3. Specificity Calculator isn’t a CSS validator. If you enter invalid selectors it will return incorrect results. For example, the [negation pseudo-class](http://www.w3.org/TR/css3-selectors/#negation) may only take a simple selector as an argument. Using a psuedo-element or combinator as an argument for `:not()` is invalid CSS3 so Specificity Calculator will return incorrect results.

* `selector`: the input
* `specificity`: the result e.g. `0,1,0,0`
* `specificity`: the result as a string e.g. `0,1,0,0`
* `specificityArray`: the result as an array of numbers e.g. `[0, 1, 0, 0]`
* `parts`: array with details about each part of the selector that counts towards the specificity

@@ -50,2 +51,3 @@

specificity: '0,1,1,3',
specificityArray: [0, 1, 1, 3],
parts: [

@@ -62,2 +64,24 @@ { selector: 'ul', type: 'c', index: 0, length: 2 },

## Comparing two selectors
Specificity Calculator also exposes a `compare` function. This function accepts two CSS selectors, `a` and `b`.
* It returns `-1` if `a` has a lower specificity than `b`
* It returns `1` if `a` has a higher specificity than `b`
* It returns `0` if `a` has the same specificity than `b`
```js
SPECIFICITY.compare('div', '.active'); // -1
SPECIFICITY.compare('#main', 'div'); // 1
SPECIFICITY.compare('span', 'div'); // 0
```
## Ordering an array of selectors by specificity
You can pass the `SPECIFICITY.compare` function to `Array.prototype.sort` to sort an array of CSS selectors by specificity.
```js
['#main', 'p', '.active'].sort(SPECIFICITY.compare); // ['p', '.active', '#main']
```
## Testing

@@ -64,0 +88,0 @@

@@ -1,14 +0,7 @@

/**
* Calculates the specificity of CSS selectors
* http://www.w3.org/TR/css3-selectors/#specificity
*
* Returns an array of objects with the following properties:
* - selector: the input
* - specificity: e.g. 0,1,0,0
* - parts: array with details about each part of the selector that counts towards the specificity
*/
var SPECIFICITY = (function() {
var calculate,
calculateSingle;
calculateSingle,
compare;
// Calculate the specificity for a selector by dividing it into simple selectors and counting them
calculate = function(input) {

@@ -34,3 +27,12 @@ var selectors,

// Calculate the specificity for a selector by dividing it into simple selectors and counting them
/**
* Calculates the specificity of CSS selectors
* http://www.w3.org/TR/css3-selectors/#specificity
*
* Returns an object with the following properties:
* - selector: the input
* - specificity: e.g. 0,1,0,0
* - parts: array with details about each part of the selector that counts towards the specificity
* - specificityArray: e.g. [0, 1, 0, 0]
*/
calculateSingle = function(input) {

@@ -160,2 +162,3 @@ var selector = input,

specificity: '0,' + typeCount.a.toString() + ',' + typeCount.b.toString() + ',' + typeCount.c.toString(),
specificityArray: [0, typeCount.a, typeCount.b, typeCount.c],
parts: parts

@@ -165,4 +168,39 @@ };

/**
* Compares two CSS selectors for specificity
*
* - it returns -1 if a has a lower specificity than b
* - it returns 1 if a has a higher specificity than b
* - it returns 0 if a has the same specificity than b
*/
compare = function(a, b) {
var aSpecificity,
bSpecificity,
i;
if (a.indexOf(',') !== -1) {
throw a + ' is not a valid CSS selector';
}
if (b.indexOf(',') !== -1) {
throw b + ' is not a valid CSS selector';
}
aSpecificity = calculateSingle(a)['specificityArray'];
bSpecificity = calculateSingle(b)['specificityArray'];
for (i = 0; i < 4; i += 1) {
if (aSpecificity[i] < bSpecificity[i]) {
return -1;
} else if (aSpecificity[i] > bSpecificity[i]) {
return 1;
}
}
return 0;
};
return {
calculate: calculate
calculate: calculate,
compare: compare
};

@@ -174,2 +212,3 @@ }());

exports.calculate = SPECIFICITY.calculate;
exports.compare = SPECIFICITY.compare;
}
var specificity = require('../'),
assert = require('assert'),
tests,
testSelector;
testSelector,
comparisonTests,
testCompare;

@@ -64,8 +66,62 @@ tests = [

comparisonTests = [
{ a: 'div', b: 'span', expected: 0 },
{ a: '.active', b: ':focus', expected: 0 },
{ a: '#header', b: '#main', expected: 0 },
{ a: 'div', b: '.active', expected: -1 },
{ a: 'div', b: '#header', expected: -1 },
{ a: '.active', b: '#header', expected: -1 },
{ a: '.active', b: 'div', expected: 1 },
{ a: '#main', b: 'div', expected: 1 },
{ a: '#main', b: ':focus', expected: 1 },
{ a: 'div p', b: 'span a', expected: 0 },
{ a: '#main p .active', b: '#main span :focus', expected: 0 },
{ a: ':focus', b: 'span a', expected: 1 },
{ a: '#main', b: 'span a:hover', expected: 1 },
{ a: 'ul > li > a > span:before', b: '.active', expected: -1 },
{ a: 'a.active:hover', b: '#main', expected: -1 }
];
testCompare = function(test) {
it('compare("' + test.a + '", "' + test.b + '") should return ' + test.expected, function() {
var result = specificity.compare(test.a, test.b);
assert.equal(result, test.expected);
});
};
describe('specificity', function() {
var i, len, test;
for (i = 0, len = tests.length; i < len; i += 1) {
test = tests[i];
testSelector(test);
}
describe('calculate', function() {
var i, len, test;
for (i = 0, len = tests.length; i < len; i += 1) {
test = tests[i];
testSelector(test);
}
});
describe('compare', function() {
var i, len, test;
for (i = 0, len = comparisonTests.length; i < len; i += 1) {
test = comparisonTests[i];
testCompare(test);
}
});
describe('sorting with compare', function() {
var a = 'div',
b = 'p a',
c = '.active',
d = 'p.active',
e = '.active:focus',
f = '#main',
original = [c, f, a, e, b, d],
sorted = [a, b, c, d, e, f];
it('array.sort(specificity.compare) should sort the array by specificity', function() {
var result = original.sort(specificity.compare);
assert.equal(result.join('|'), sorted.join('|'));
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc