Калькулятор специфичности
by Евгений
HTML
<div class="main">
<h1>Specificity Calculator</h1>
<p class="intro">Калькулятор <a href="http://www.w3.org/TR/css3-selectors/#specificity" target="_blank">специфичности CSS</a> от <a href="http://specificity.keegan.st/">Keegan Street</a>. Измените или вставьте селекторы в поля ниже.</p>
<div id="items" class="items">
<div class="item is-small transition-all">
<textarea type="text" class="input">ul#nav li.active a</textarea>
<div class="selector"><span class="type-c">ul</span><span class="type-a">#nav</span> <span class="type-c">li</span><span class="type-b">.active</span> <span class="type-c">a</span></div>
<div class="specificity">
<span class="type-z">0</span>
<span class="type-a">1</span>
<span class="type-b">1</span>
<span class="type-c">3</span>
</div>
<div class="legend">
<span class="type-z">Стили в атрибуте <code>style</code></span>
<span class="type-a">ID</span>
<span class="type-b">Классы, псевдоклассы</span>
<span class="type-c">Элементы, псевдоэлементы</span>
</div>
<a href="#" class="duplicate button">Клонировать</a>
</div>
</div>
</main>
<div class="menu">
<a href="#" class="sort button">Сортировать по специфичности</a>
</div>
<div class="offscreen-container"><div id="offscreen"></div></div>
CSS
/*
* The colour theme for Specificity Calculator is from http://ethanschoonover.com/solarized
*/
body {
background: #FDF6E3;
color: #657B83;
}
h1 {
font-size: 40px;
line-height: 40px;
margin: 25px 0 5px;
color: #CB4B16;
letter-spacing: -1px;
}
p {
line-height: 1.5em;
}
a {
color: #6C71C4;
}
code {
background-color: transparentize(white,.6);
border: 1px solid #CCCCCC;
-webkit-border-radius: 3px;
border-radius: 3px;
padding: 0 5px;
}
.intro {
font-style: italic;
margin-top: 0;
}
.footer {
margin-bottom: 60px;
}
.main {
width: 680px;
margin: 0 auto;
}
/* Items */
#items {
width: 680px;
min-height: 536px;
position: relative;
}
.item {
background: #FFF;
padding: 20px 20px 10px;
width: 640px;
margin-bottom: 20px;
-webkit-box-shadow: 0px 0px 10px 0px #D5CEBB;
box-shadow: 0px 0px 10px 0px #D5CEBB;
-webkit-border-radius: 3px;
border-radius: 3px;
overflow: hidden;
position: relative;
opacity: 1;
}
.transition-all {
-webkit-transition: all 0.2s ease;
-moz-transition: all 0.2s ease;
-ms-transition: all 0.2s ease;
-o-transition: all 0.2s ease;
transition: all 0.2s ease;
}
.is-small {
-webkit-transform: scale(0.6);
-moz-transform: scale(0.6);
-ms-transform: scale(0.6);
-o-transform: scale(0.6);
transform: scale(0.6);
opacity: 0;
}
.input,
.selector {
font-size: 28px;
line-height: 36px;
font-family: monospace, serif;
_font-family: 'courier new', monospace;
}
.input {
width: 630px;
height: 36px;
position: absolute;
top: 20px;
left: 20px;
padding: 3px 5px;
border: none;
background: none;
color: #FFF;
resize: none;
outline: none;
overflow: hidden;
}
.input:focus,
.input:active {
-moz-box-shadow: 0 0 10px #00171D;
-webkit-box-shadow: 0 0 10px #00171D;
box-shadow: 0 0 10px #00171D;
}
.selector {
width: 630px;
min-height: 36px;
padding: 3px 5px;
background: #002B36;
white-space: pre-wrap;
}
.specificity {
margin: 20px 0 0;
color: #FFF;
font-size:...
JavaScript
/**
* 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;
calculate = function(input) {
var selectors,
selector,
i,
len,
results = [];
// Separate input by commas
selectors = input.split(',');
for (i = 0, len = selectors.length; i < len; i += 1) {
selector = selectors[i];
if (selector.length > 0) {
results.push(calculateSingle(selector));
}
}
return results;
};
// Calculate the specificity for a selector by dividing it into simple selectors and counting them
calculateSingle = function(input) {
var selector = input,
findMatch,
typeCount = {
'a': 0,
'b': 0,
'c': 0
},
parts = [],
// The following regular expressions assume that selectors matching the preceding regular expressions have been removed
attributeRegex = /(\[[^\]]+\])/g,
idRegex = /(#[^\s\+>~\.\[:]+)/g,
classRegex = /(\.[^\s\+>~\.\[:]+)/g,
pseudoElementRegex = /(::[^\s\+>~\.\[:]+|:first-line|:first-letter|:before|:after)/gi,
// A regex for pseudo classes with brackets - :nth-child(), :nth-last-child(), :nth-of-type(), :nth-last-type(), :lang()
pseudoClassWithBracketsRegex = /(:[\w-]+\([^\)]*\))/gi,
// A regex for other pseudo classes, which don't have brackets
pseudoClassRegex = /(:[^\s\+>~\.\[:]+)/g,
elementRegex = /([^\s\+>~\.\[:]+)/g;
// 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, len, match, index, length;
if (regex.test(selector)) {
matches =...