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.
94 lines
2.9 KiB
94 lines
2.9 KiB
var generate = require('css-tree').generate; |
|
var specificity = require('./specificity'); |
|
|
|
var nonFreezePseudoElements = { |
|
'first-letter': true, |
|
'first-line': true, |
|
'after': true, |
|
'before': true |
|
}; |
|
var nonFreezePseudoClasses = { |
|
'link': true, |
|
'visited': true, |
|
'hover': true, |
|
'active': true, |
|
'first-letter': true, |
|
'first-line': true, |
|
'after': true, |
|
'before': true |
|
}; |
|
|
|
module.exports = function freeze(node, usageData) { |
|
var pseudos = Object.create(null); |
|
var hasPseudo = false; |
|
|
|
node.prelude.children.each(function(simpleSelector) { |
|
var tagName = '*'; |
|
var scope = 0; |
|
|
|
simpleSelector.children.each(function(node) { |
|
switch (node.type) { |
|
case 'ClassSelector': |
|
if (usageData && usageData.scopes) { |
|
var classScope = usageData.scopes[node.name] || 0; |
|
|
|
if (scope !== 0 && classScope !== scope) { |
|
throw new Error('Selector can\'t has classes from different scopes: ' + generate(simpleSelector)); |
|
} |
|
|
|
scope = classScope; |
|
} |
|
break; |
|
|
|
case 'PseudoClassSelector': |
|
var name = node.name.toLowerCase(); |
|
|
|
if (!nonFreezePseudoClasses.hasOwnProperty(name)) { |
|
pseudos[':' + name] = true; |
|
hasPseudo = true; |
|
} |
|
break; |
|
|
|
case 'PseudoElementSelector': |
|
var name = node.name.toLowerCase(); |
|
|
|
if (!nonFreezePseudoElements.hasOwnProperty(name)) { |
|
pseudos['::' + name] = true; |
|
hasPseudo = true; |
|
} |
|
break; |
|
|
|
case 'TypeSelector': |
|
tagName = node.name.toLowerCase(); |
|
break; |
|
|
|
case 'AttributeSelector': |
|
if (node.flags) { |
|
pseudos['[' + node.flags.toLowerCase() + ']'] = true; |
|
hasPseudo = true; |
|
} |
|
break; |
|
|
|
case 'WhiteSpace': |
|
case 'Combinator': |
|
tagName = '*'; |
|
break; |
|
} |
|
}); |
|
|
|
simpleSelector.compareMarker = specificity(simpleSelector).toString(); |
|
simpleSelector.id = null; // pre-init property to avoid multiple hidden class |
|
simpleSelector.id = generate(simpleSelector); |
|
|
|
if (scope) { |
|
simpleSelector.compareMarker += ':' + scope; |
|
} |
|
|
|
if (tagName !== '*') { |
|
simpleSelector.compareMarker += ',' + tagName; |
|
} |
|
}); |
|
|
|
// add property to all rule nodes to avoid multiple hidden class |
|
node.pseudoSignature = hasPseudo && Object.keys(pseudos).sort().join(','); |
|
};
|
|
|