lepu-test-platform-web/node_modules/csso/lib/compressor/restructure/utils.js

142 lines
3.8 KiB
JavaScript

var hasOwnProperty = Object.prototype.hasOwnProperty;
function isEqualLists(a, b) {
var cursor1 = a.head;
var cursor2 = b.head;
while (cursor1 !== null && cursor2 !== null && cursor1.data.id === cursor2.data.id) {
cursor1 = cursor1.next;
cursor2 = cursor2.next;
}
return cursor1 === null && cursor2 === null;
}
function isEqualDeclarations(a, b) {
var cursor1 = a.head;
var cursor2 = b.head;
while (cursor1 !== null && cursor2 !== null && cursor1.data.id === cursor2.data.id) {
cursor1 = cursor1.next;
cursor2 = cursor2.next;
}
return cursor1 === null && cursor2 === null;
}
function compareDeclarations(declarations1, declarations2) {
var result = {
eq: [],
ne1: [],
ne2: [],
ne2overrided: []
};
var fingerprints = Object.create(null);
var declarations2hash = Object.create(null);
for (var cursor = declarations2.head; cursor; cursor = cursor.next) {
declarations2hash[cursor.data.id] = true;
}
for (var cursor = declarations1.head; cursor; cursor = cursor.next) {
var data = cursor.data;
if (data.fingerprint) {
fingerprints[data.fingerprint] = data.value.important;
}
if (declarations2hash[data.id]) {
declarations2hash[data.id] = false;
result.eq.push(data);
} else {
result.ne1.push(data);
}
}
for (var cursor = declarations2.head; cursor; cursor = cursor.next) {
var data = cursor.data;
if (declarations2hash[data.id]) {
// if declarations1 has overriding declaration, this is not a difference
// but take in account !important - prev should be equal or greater than follow
if (hasOwnProperty.call(fingerprints, data.fingerprint) &&
Number(fingerprints[data.fingerprint]) >= Number(data.value.important)) {
result.ne2overrided.push(data);
} else {
result.ne2.push(data);
}
}
}
return result;
}
function addSelectors(dest, source) {
source.each(function(sourceData) {
var newStr = sourceData.id;
var cursor = dest.head;
while (cursor) {
var nextStr = cursor.data.id;
if (nextStr === newStr) {
return;
}
if (nextStr > newStr) {
break;
}
cursor = cursor.next;
}
dest.insert(dest.createItem(sourceData), cursor);
});
return dest;
}
// check if simpleselectors has no equal specificity and element selector
function hasSimilarSelectors(selectors1, selectors2) {
return selectors1.some(function(a) {
return selectors2.some(function(b) {
return a.compareMarker === b.compareMarker;
});
});
}
// test node can't to be skipped
function unsafeToSkipNode(node) {
switch (node.type) {
case 'Ruleset':
// unsafe skip ruleset with selector similarities
return hasSimilarSelectors(node.selector.selectors, this);
case 'Atrule':
// can skip at-rules with blocks
if (node.block) {
// non-stylesheet blocks are safe to skip since have no selectors
if (node.block.type !== 'StyleSheet') {
return false;
}
// unsafe skip at-rule if block contains something unsafe to skip
return node.block.rules.some(unsafeToSkipNode, this);
}
break;
}
// unsafe by default
return true;
}
module.exports = {
isEqualLists: isEqualLists,
isEqualDeclarations: isEqualDeclarations,
compareDeclarations: compareDeclarations,
addSelectors: addSelectors,
hasSimilarSelectors: hasSimilarSelectors,
unsafeToSkipNode: unsafeToSkipNode
};