From 36cc11354f6ecdb6e1ef23dd922b3009954c8af9 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowicz Date: Wed, 11 Jan 2017 20:20:25 +0100 Subject: [PATCH] See #773 - speeds up specificity lookup. Why: * Calculating it is slow, but, since it's done repeatedly for the same selectors, it can be cached quite effectively. --- lib/clean.js | 3 + lib/optimizer/level-2/merge-media-queries.js | 9 +- .../level-2/merge-non-adjacent-by-selector.js | 5 +- lib/optimizer/level-2/reorderable.js | 8 +- lib/optimizer/level-2/restructure.js | 5 +- .../level-2/specificities-overlap.js | 16 ++- test/optimizer/level-2/reorderable-test.js | 104 +++++++++--------- 7 files changed, 83 insertions(+), 67 deletions(-) diff --git a/lib/clean.js b/lib/clean.js index 6b1f7adf..00e0da35 100644 --- a/lib/clean.js +++ b/lib/clean.js @@ -79,6 +79,9 @@ CleanCSS.prototype.minify = function (input, callback) { startedAt: Date.now(), timeSpent: 0 }, + cache: { + specificity: {} + }, errors: [], inlinedStylesheets: [], inputSourceMapTracker: inputSourceMapTracker(), diff --git a/lib/optimizer/level-2/merge-media-queries.js b/lib/optimizer/level-2/merge-media-queries.js index 0698c56b..36d3dc2d 100644 --- a/lib/optimizer/level-2/merge-media-queries.js +++ b/lib/optimizer/level-2/merge-media-queries.js @@ -9,6 +9,7 @@ var Token = require('../../tokenizer/token'); function mergeMediaQueries(tokens, context) { var mergeSemantically = context.options.level[OptimizationLevel.Two].mergeSemantically; + var specificityCache = context.cache.specificity; var candidates = {}; var reduced = []; @@ -52,11 +53,11 @@ function mergeMediaQueries(tokens, context) { var traversedProperties = extractProperties(tokens[from]); from += delta; - if (mergeSemantically && allSameRulePropertiesCanBeReordered(movedProperties, traversedProperties)) { + if (mergeSemantically && allSameRulePropertiesCanBeReordered(movedProperties, traversedProperties, specificityCache)) { continue; } - if (!canReorder(movedProperties, traversedProperties)) + if (!canReorder(movedProperties, traversedProperties, specificityCache)) continue directionLoop; } @@ -74,7 +75,7 @@ function mergeMediaQueries(tokens, context) { return reduced; } -function allSameRulePropertiesCanBeReordered(movedProperties, traversedProperties) { +function allSameRulePropertiesCanBeReordered(movedProperties, traversedProperties, specificityCache) { var movedProperty; var movedRule; var traversedProperty; @@ -90,7 +91,7 @@ function allSameRulePropertiesCanBeReordered(movedProperties, traversedPropertie traversedProperty = traversedProperties[i]; traversedRule = traversedProperty[5]; - if (rulesOverlap(movedRule, traversedRule, true) && !canReorderSingle(movedProperty, traversedProperty)) { + if (rulesOverlap(movedRule, traversedRule, true) && !canReorderSingle(movedProperty, traversedProperty, specificityCache)) { return false; } } diff --git a/lib/optimizer/level-2/merge-non-adjacent-by-selector.js b/lib/optimizer/level-2/merge-non-adjacent-by-selector.js index 027ba361..cba12fe9 100644 --- a/lib/optimizer/level-2/merge-non-adjacent-by-selector.js +++ b/lib/optimizer/level-2/merge-non-adjacent-by-selector.js @@ -8,6 +8,7 @@ var serializeRules = require('../../writer/one-time').rules; var Token = require('../../tokenizer/token'); function mergeNonAdjacentBySelector(tokens, context) { + var specificityCache = context.cache.specificity; var allSelectors = {}; var repeatedSelectors = []; var i; @@ -52,8 +53,8 @@ function mergeNonAdjacentBySelector(tokens, context) { // traversed then moved as we move selectors towards the start var reorderable = topToBottom ? - canReorder(movedProperties, traversedProperties) : - canReorder(traversedProperties, movedProperties); + canReorder(movedProperties, traversedProperties, specificityCache) : + canReorder(traversedProperties, movedProperties, specificityCache); if (!reorderable && !topToBottom) continue selectorIterator; diff --git a/lib/optimizer/level-2/reorderable.js b/lib/optimizer/level-2/reorderable.js index 9cf8deca..4a3747a0 100644 --- a/lib/optimizer/level-2/reorderable.js +++ b/lib/optimizer/level-2/reorderable.js @@ -6,10 +6,10 @@ var specificitiesOverlap = require('./specificities-overlap'); var FLEX_PROPERTIES = /align\-items|box\-align|box\-pack|flex|justify/; var BORDER_PROPERTIES = /^border\-(top|right|bottom|left|color|style|width|radius)/; -function canReorder(left, right) { +function canReorder(left, right, cache) { for (var i = right.length - 1; i >= 0; i--) { for (var j = left.length - 1; j >= 0; j--) { - if (!canReorderSingle(left[j], right[i])) + if (!canReorderSingle(left[j], right[i], cache)) return false; } } @@ -17,7 +17,7 @@ function canReorder(left, right) { return true; } -function canReorderSingle(left, right) { +function canReorderSingle(left, right, cache) { var leftName = left[0]; var leftValue = left[1]; var leftNameRoot = left[2]; @@ -51,7 +51,7 @@ function canReorderSingle(left, right) { return true; if (rightInSpecificSelector && leftInSpecificSelector && !inheritable(leftNameRoot) && !inheritable(rightNameRoot) && !rulesOverlap(rightSelector, leftSelector, false)) return true; - if (!specificitiesOverlap(leftSelector, rightSelector)) + if (!specificitiesOverlap(leftSelector, rightSelector, cache)) return true; return false; diff --git a/lib/optimizer/level-2/restructure.js b/lib/optimizer/level-2/restructure.js index 7ecc434d..f68c572c 100644 --- a/lib/optimizer/level-2/restructure.js +++ b/lib/optimizer/level-2/restructure.js @@ -25,6 +25,7 @@ function restructure(tokens, context) { var options = context.options; var mergeablePseudoClasses = options.compatibility.selectors.mergeablePseudoClasses; var mergeablePseudoElements = options.compatibility.selectors.mergeablePseudoElements; + var specificityCache = context.cache.specificity; var movableTokens = {}; var movedProperties = []; var multiPropertyMoveCache = {}; @@ -308,7 +309,7 @@ function restructure(tokens, context) { var unmovableInCurrentToken = []; for (j = properties.length - 1; j >= 0; j--) { for (k = j - 1; k >= 0; k--) { - if (!canReorderSingle(properties[j], properties[k])) { + if (!canReorderSingle(properties[j], properties[k], specificityCache)) { unmovableInCurrentToken.push(j); break; } @@ -322,7 +323,7 @@ function restructure(tokens, context) { for (k = 0; k < movedCount; k++) { var movedProperty = movedProperties[k]; - if (movedToBeDropped.indexOf(k) == -1 && !canReorderSingle(property, movedProperty) && !boundToAnotherPropertyInCurrrentToken(property, movedProperty, token)) { + if (movedToBeDropped.indexOf(k) == -1 && !canReorderSingle(property, movedProperty, specificityCache) && !boundToAnotherPropertyInCurrrentToken(property, movedProperty, token)) { dropPropertiesAt(i + 1, movedProperty, token); if (movedToBeDropped.indexOf(k) == -1) { diff --git a/lib/optimizer/level-2/specificities-overlap.js b/lib/optimizer/level-2/specificities-overlap.js index 7015ac9b..bde03744 100644 --- a/lib/optimizer/level-2/specificities-overlap.js +++ b/lib/optimizer/level-2/specificities-overlap.js @@ -1,16 +1,16 @@ var specificity = require('./specificity'); -function specificitiesOverlap(selector1, selector2) { +function specificitiesOverlap(selector1, selector2, cache) { var specificity1; var specificity2; var i, l; var j, m; for (i = 0, l = selector1.length; i < l; i++) { - specificity1 = specificity(selector1[i][1]); + specificity1 = findSpecificity(selector1[i][1], cache); for (j = 0, m = selector2.length; j < m; j++) { - specificity2 = specificity(selector2[j][1]); + specificity2 = findSpecificity(selector2[j][1], cache); if (specificity1[0] === specificity2[0] && specificity1[1] === specificity2[1] && specificity1[2] === specificity2[2]) { return true; @@ -21,4 +21,14 @@ function specificitiesOverlap(selector1, selector2) { return false; } +function findSpecificity(selector, cache) { + var value; + + if (!(selector in cache)) { + cache[selector] = value = specificity(selector); + } + + return value || cache[selector]; +} + module.exports = specificitiesOverlap; diff --git a/test/optimizer/level-2/reorderable-test.js b/test/optimizer/level-2/reorderable-test.js index e273db11..8c2f0dbe 100644 --- a/test/optimizer/level-2/reorderable-test.js +++ b/test/optimizer/level-2/reorderable-test.js @@ -25,7 +25,7 @@ vows.describe(canReorder) .addBatch({ 'empty': { 'topic': function () { - return canReorder(propertiesIn('a{}'), propertiesIn('a{}')); + return canReorder(propertiesIn('a{}'), propertiesIn('a{}'), {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -33,7 +33,7 @@ vows.describe(canReorder) }, 'left empty': { 'topic': function () { - return canReorder(propertiesIn('a{}'), propertiesIn('a{color:red}')); + return canReorder(propertiesIn('a{}'), propertiesIn('a{color:red}'), {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -41,7 +41,7 @@ vows.describe(canReorder) }, 'right empty': { 'topic': function () { - return canReorder(propertiesIn('a{color:red}'), propertiesIn('a{}')); + return canReorder(propertiesIn('a{color:red}'), propertiesIn('a{}'), {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -49,7 +49,7 @@ vows.describe(canReorder) }, 'all reorderable': { 'topic': function () { - return canReorder(propertiesIn('a{color:red;width:100%}'), propertiesIn('a{display:block;height:20px}')); + return canReorder(propertiesIn('a{color:red;width:100%}'), propertiesIn('a{display:block;height:20px}'), {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -57,7 +57,7 @@ vows.describe(canReorder) }, 'one not reorderable on the left': { 'topic': function () { - return canReorder(propertiesIn('a{color:red;width:100%;display:inline}'), propertiesIn('a{display:block;height:20px}')); + return canReorder(propertiesIn('a{color:red;width:100%;display:inline}'), propertiesIn('a{display:block;height:20px}'), {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -65,7 +65,7 @@ vows.describe(canReorder) }, 'one not reorderable on the right': { 'topic': function () { - return canReorder(propertiesIn('a{color:red;width:100%}'), propertiesIn('a{display:block;height:20px;width:20px}')); + return canReorder(propertiesIn('a{color:red;width:100%}'), propertiesIn('a{display:block;height:20px;width:20px}'), {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -78,7 +78,7 @@ vows.describe(canReorderSingle) .addBatch({ 'different properties': { 'topic': function () { - return canReorderSingle(propertiesIn('a{color:red}')[0], propertiesIn('a{display:block}')[0]); + return canReorderSingle(propertiesIn('a{color:red}')[0], propertiesIn('a{display:block}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -86,7 +86,7 @@ vows.describe(canReorderSingle) }, 'font and line-height': { 'topic': function () { - return canReorderSingle(propertiesIn('a{font:10px}')[0], propertiesIn('a{line-height:12px}')[0]); + return canReorderSingle(propertiesIn('a{font:10px}')[0], propertiesIn('a{line-height:12px}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -94,7 +94,7 @@ vows.describe(canReorderSingle) }, 'same properties with same value': { 'topic': function () { - return canReorderSingle(propertiesIn('a{color:red}')[0], propertiesIn('a{color:red}')[0]); + return canReorderSingle(propertiesIn('a{color:red}')[0], propertiesIn('a{color:red}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -102,7 +102,7 @@ vows.describe(canReorderSingle) }, 'same properties with same value and different case': { 'topic': function () { - return canReorderSingle(propertiesIn('a{COLOR:red}')[0], propertiesIn('a{color:red}')[0]); + return canReorderSingle(propertiesIn('a{COLOR:red}')[0], propertiesIn('a{color:red}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -110,7 +110,7 @@ vows.describe(canReorderSingle) }, 'same properties with different value': { 'topic': function () { - return canReorderSingle(propertiesIn('a{color:red}')[0], propertiesIn('a{color:blue}')[0]); + return canReorderSingle(propertiesIn('a{color:red}')[0], propertiesIn('a{color:blue}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -118,7 +118,7 @@ vows.describe(canReorderSingle) }, 'same properties with different value and different case': { 'topic': function () { - return canReorderSingle(propertiesIn('a{color:red}')[0], propertiesIn('a{COLOR:blue}')[0]); + return canReorderSingle(propertiesIn('a{color:red}')[0], propertiesIn('a{COLOR:blue}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -126,7 +126,7 @@ vows.describe(canReorderSingle) }, 'different properties with same root': { 'topic': function () { - return canReorderSingle(propertiesIn('a{text-shadow:none}')[0], propertiesIn('a{text-decoration:underline}')[0]); + return canReorderSingle(propertiesIn('a{text-shadow:none}')[0], propertiesIn('a{text-decoration:underline}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -134,7 +134,7 @@ vows.describe(canReorderSingle) }, 'different properties with same root when shorthand does not reset': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border:none}')[0], propertiesIn('a{border-spacing:1px}')[0]); + return canReorderSingle(propertiesIn('a{border:none}')[0], propertiesIn('a{border-spacing:1px}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -142,7 +142,7 @@ vows.describe(canReorderSingle) }, 'different properties with same root - border #1': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border:none}')[0], propertiesIn('a{border-top-color:red}')[0]); + return canReorderSingle(propertiesIn('a{border:none}')[0], propertiesIn('a{border-top-color:red}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -150,7 +150,7 @@ vows.describe(canReorderSingle) }, 'different properties with same root - border #2': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border-top:1px solid red}')[0], propertiesIn('a{border-bottom:1px solid blue}')[0]); + return canReorderSingle(propertiesIn('a{border-top:1px solid red}')[0], propertiesIn('a{border-bottom:1px solid blue}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -158,7 +158,7 @@ vows.describe(canReorderSingle) }, 'different properties with same root - border #3': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border-top-color:red}')[0], propertiesIn('a{border-bottom:1px solid blue}')[0]); + return canReorderSingle(propertiesIn('a{border-top-color:red}')[0], propertiesIn('a{border-bottom:1px solid blue}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -166,7 +166,7 @@ vows.describe(canReorderSingle) }, 'different properties with same root - border #4': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border-bottom:none}')[0], propertiesIn('a{border-bottom:1px solid blue}')[0]); + return canReorderSingle(propertiesIn('a{border-bottom:none}')[0], propertiesIn('a{border-bottom:1px solid blue}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -174,7 +174,7 @@ vows.describe(canReorderSingle) }, 'different properties with same root - border #5': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border-bottom:none}')[0], propertiesIn('a{border-bottom:none}')[0]); + return canReorderSingle(propertiesIn('a{border-bottom:none}')[0], propertiesIn('a{border-bottom:none}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -182,7 +182,7 @@ vows.describe(canReorderSingle) }, 'different properties with same root - border #6': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border-radius:3px}')[0], propertiesIn('a{border:0}')[0]); + return canReorderSingle(propertiesIn('a{border-radius:3px}')[0], propertiesIn('a{border:0}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -190,7 +190,7 @@ vows.describe(canReorderSingle) }, 'different properties with same root - border #7': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border-radius:3px}')[0], propertiesIn('a{border-style:solid}')[0]); + return canReorderSingle(propertiesIn('a{border-radius:3px}')[0], propertiesIn('a{border-style:solid}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -198,7 +198,7 @@ vows.describe(canReorderSingle) }, 'different properties with same root - border #8': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border:1px solid red}')[0], propertiesIn('a{border-right-style:dotted}')[0]); + return canReorderSingle(propertiesIn('a{border:1px solid red}')[0], propertiesIn('a{border-right-style:dotted}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -206,7 +206,7 @@ vows.describe(canReorderSingle) }, 'different properties with same root - border #9': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border-color:red}')[0], propertiesIn('a{border-right:1px dotted}')[0]); + return canReorderSingle(propertiesIn('a{border-color:red}')[0], propertiesIn('a{border-right:1px dotted}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -214,7 +214,7 @@ vows.describe(canReorderSingle) }, 'different properties with same root - border #10': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border-color:red}')[0], propertiesIn('a{border-bottom-color:rgba(0,0,0,0.5)}')[0]); + return canReorderSingle(propertiesIn('a{border-color:red}')[0], propertiesIn('a{border-bottom-color:rgba(0,0,0,0.5)}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -222,7 +222,7 @@ vows.describe(canReorderSingle) }, 'different properties with same root - border #11': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border-color:red}')[0], propertiesIn('a{border-bottom-color:red}')[0]); + return canReorderSingle(propertiesIn('a{border-color:red}')[0], propertiesIn('a{border-bottom-color:red}')[0], {}); }, 'must be false': function (result) { assert.isTrue(result); @@ -230,7 +230,7 @@ vows.describe(canReorderSingle) }, 'shorhand and longhand with different value': { 'topic': function () { - return canReorderSingle(propertiesIn('a{margin:3px}')[0], propertiesIn('a{margin-bottom:5px}')[0]); + return canReorderSingle(propertiesIn('a{margin:3px}')[0], propertiesIn('a{margin-bottom:5px}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -238,7 +238,7 @@ vows.describe(canReorderSingle) }, 'shorhand and longhand with same value': { 'topic': function () { - return canReorderSingle(propertiesIn('a{margin:3px}')[0], propertiesIn('a{margin-bottom:3px}')[0]); + return canReorderSingle(propertiesIn('a{margin:3px}')[0], propertiesIn('a{margin-bottom:3px}')[0], {}); }, 'must be false': function (result) { assert.isTrue(result); @@ -246,7 +246,7 @@ vows.describe(canReorderSingle) }, 'two longhand with different value sharing same shorthand': { 'topic': function () { - return canReorderSingle(propertiesIn('a{margin-top:3px solid red}')[0], propertiesIn('a{margin-bottom:3px solid white}')[0]); + return canReorderSingle(propertiesIn('a{margin-top:3px solid red}')[0], propertiesIn('a{margin-bottom:3px solid white}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -254,7 +254,7 @@ vows.describe(canReorderSingle) }, 'two longhand with different value when sharing same shorthand and one is vendored': { 'topic': function () { - return canReorderSingle(propertiesIn('a{background-image:linear-gradient()}')[0], propertiesIn('a{-webkit-background-size:20px}')[0]); + return canReorderSingle(propertiesIn('a{background-image:linear-gradient()}')[0], propertiesIn('a{-webkit-background-size:20px}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -262,7 +262,7 @@ vows.describe(canReorderSingle) }, 'different, non-overlapping simple selectors': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border:none}')[0], propertiesIn('div{border:1px solid #f00}')[0]); + return canReorderSingle(propertiesIn('a{border:none}')[0], propertiesIn('div{border:1px solid #f00}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -270,7 +270,7 @@ vows.describe(canReorderSingle) }, 'different, non-overlapping simple selectors with inheritable property': { 'topic': function () { - return canReorderSingle(propertiesIn('a{font:inherit}')[0], propertiesIn('div{font-family:Helvetica}')[0]); + return canReorderSingle(propertiesIn('a{font:inherit}')[0], propertiesIn('div{font-family:Helvetica}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -278,7 +278,7 @@ vows.describe(canReorderSingle) }, 'different, non-overlapping complex selectors': { 'topic': function () { - return canReorderSingle(propertiesIn('.one{border:none}')[0], propertiesIn('div{border:1px solid #f00}')[0]); + return canReorderSingle(propertiesIn('.one{border:none}')[0], propertiesIn('div{border:1px solid #f00}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -286,7 +286,7 @@ vows.describe(canReorderSingle) }, 'different, non-overlapping complex selectors with same specificity': { 'topic': function () { - return canReorderSingle(propertiesIn('.one{border:none}')[0], propertiesIn('.two{border:1px solid #f00}')[0]); + return canReorderSingle(propertiesIn('.one{border:none}')[0], propertiesIn('.two{border:1px solid #f00}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -294,7 +294,7 @@ vows.describe(canReorderSingle) }, 'different, overlapping simple selectors': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border:none}')[0], propertiesIn('a{border:1px solid #f00}')[0]); + return canReorderSingle(propertiesIn('a{border:none}')[0], propertiesIn('a{border:1px solid #f00}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -302,7 +302,7 @@ vows.describe(canReorderSingle) }, 'align-items': { 'topic': function () { - return canReorderSingle(propertiesIn('a{border:none}')[0], propertiesIn('a{align-items:flex-start}')[0]); + return canReorderSingle(propertiesIn('a{border:none}')[0], propertiesIn('a{align-items:flex-start}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -310,7 +310,7 @@ vows.describe(canReorderSingle) }, 'same but one vendor prefixed': { 'topic': function () { - return canReorderSingle(propertiesIn('a{-moz-box-sizing:content-box}')[0], propertiesIn('a{box-sizing:content-box}')[0]); + return canReorderSingle(propertiesIn('a{-moz-box-sizing:content-box}')[0], propertiesIn('a{box-sizing:content-box}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -318,7 +318,7 @@ vows.describe(canReorderSingle) }, 'same and both vendor prefixed': { 'topic': function () { - return canReorderSingle(propertiesIn('a{-moz-box-sizing:content-box}')[0], propertiesIn('a{-moz-box-sizing:content-box}')[0]); + return canReorderSingle(propertiesIn('a{-moz-box-sizing:content-box}')[0], propertiesIn('a{-moz-box-sizing:content-box}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -326,7 +326,7 @@ vows.describe(canReorderSingle) }, 'same but value with different vendor prefixes': { 'topic': function () { - return canReorderSingle(propertiesIn('a{background:-webkit-linear-gradient()}')[0], propertiesIn('a{background:-o-linear-gradient()}')[0]); + return canReorderSingle(propertiesIn('a{background:-webkit-linear-gradient()}')[0], propertiesIn('a{background:-o-linear-gradient()}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -334,7 +334,7 @@ vows.describe(canReorderSingle) }, 'same but left vendor prefixed': { 'topic': function () { - return canReorderSingle(propertiesIn('a{background:-webkit-linear-gradient()}')[0], propertiesIn('a{background:linear-gradient()}')[0]); + return canReorderSingle(propertiesIn('a{background:-webkit-linear-gradient()}')[0], propertiesIn('a{background:linear-gradient()}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -342,7 +342,7 @@ vows.describe(canReorderSingle) }, 'same but right vendor prefixed': { 'topic': function () { - return canReorderSingle(propertiesIn('a{background:linear-gradient()}')[0], propertiesIn('a{background:-webkit-linear-gradient()}')[0]); + return canReorderSingle(propertiesIn('a{background:linear-gradient()}')[0], propertiesIn('a{background:-webkit-linear-gradient()}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -350,7 +350,7 @@ vows.describe(canReorderSingle) }, 'specificity - same #1': { 'topic': function () { - return canReorderSingle(propertiesIn('a{background:red}')[0], propertiesIn('a{background-color:blue}')[0]); + return canReorderSingle(propertiesIn('a{background:red}')[0], propertiesIn('a{background-color:blue}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -358,7 +358,7 @@ vows.describe(canReorderSingle) }, 'specificity - same #2': { 'topic': function () { - return canReorderSingle(propertiesIn('div a{background:red}')[0], propertiesIn('body > a{background-color:blue}')[0]); + return canReorderSingle(propertiesIn('div a{background:red}')[0], propertiesIn('body > a{background-color:blue}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -366,7 +366,7 @@ vows.describe(canReorderSingle) }, 'specificity - different #1': { 'topic': function () { - return canReorderSingle(propertiesIn('.block{background:red}')[0], propertiesIn('a{background-color:blue}')[0]); + return canReorderSingle(propertiesIn('.block{background:red}')[0], propertiesIn('a{background-color:blue}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -374,7 +374,7 @@ vows.describe(canReorderSingle) }, 'specificity - different #2': { 'topic': function () { - return canReorderSingle(propertiesIn('.block{background:red}')[0], propertiesIn('#id{background-color:blue}')[0]); + return canReorderSingle(propertiesIn('.block{background:red}')[0], propertiesIn('#id{background-color:blue}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -382,7 +382,7 @@ vows.describe(canReorderSingle) }, 'specificity - different #3': { 'topic': function () { - return canReorderSingle(propertiesIn('.block{background:red}')[0], propertiesIn('#id{background-color:blue}')[0]); + return canReorderSingle(propertiesIn('.block{background:red}')[0], propertiesIn('#id{background-color:blue}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -390,7 +390,7 @@ vows.describe(canReorderSingle) }, 'specificity - different #4': { 'topic': function () { - return canReorderSingle(propertiesIn('#id div.block-1{background:red}')[0], propertiesIn('#id > div.block-1.block-2{background-color:blue}')[0]); + return canReorderSingle(propertiesIn('#id div.block-1{background:red}')[0], propertiesIn('#id > div.block-1.block-2{background-color:blue}')[0], {}); }, 'must be true': function (result) { assert.isTrue(result); @@ -398,7 +398,7 @@ vows.describe(canReorderSingle) }, 'specificity - complex #1': { 'topic': function () { - return canReorderSingle(propertiesIn('div,.block{background:red}')[0], propertiesIn('.block,#id{background-color:blue}')[0]); + return canReorderSingle(propertiesIn('div,.block{background:red}')[0], propertiesIn('.block,#id{background-color:blue}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -408,7 +408,7 @@ vows.describe(canReorderSingle) .addBatch({ 'flex #1': { 'topic': function () { - return canReorderSingle(propertiesIn('a{-webkit-box-align:flex-start}')[0], propertiesIn('a{align-items:flex-start}')[0]); + return canReorderSingle(propertiesIn('a{-webkit-box-align:flex-start}')[0], propertiesIn('a{align-items:flex-start}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -416,7 +416,7 @@ vows.describe(canReorderSingle) }, 'flex #2': { 'topic': function () { - return canReorderSingle(propertiesIn('a{-ms-flex-align:start}')[0], propertiesIn('a{align-items:flex-start}')[0]); + return canReorderSingle(propertiesIn('a{-ms-flex-align:start}')[0], propertiesIn('a{align-items:flex-start}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -424,7 +424,7 @@ vows.describe(canReorderSingle) }, 'flex #3': { 'topic': function () { - return canReorderSingle(propertiesIn('a{flex:none}')[0], propertiesIn('a{align-items:flex-start}')[0]); + return canReorderSingle(propertiesIn('a{flex:none}')[0], propertiesIn('a{align-items:flex-start}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -432,7 +432,7 @@ vows.describe(canReorderSingle) }, 'flex #4': { 'topic': function () { - return canReorderSingle(propertiesIn('a{justify-content:center}')[0], propertiesIn('a{–ms-flex-pack:center}')[0]); + return canReorderSingle(propertiesIn('a{justify-content:center}')[0], propertiesIn('a{–ms-flex-pack:center}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); @@ -440,7 +440,7 @@ vows.describe(canReorderSingle) }, 'flex #5': { 'topic': function () { - return canReorderSingle(propertiesIn('a{justify-content:center}')[0], propertiesIn('a{–webkit-box-pack:center}')[0]); + return canReorderSingle(propertiesIn('a{justify-content:center}')[0], propertiesIn('a{–webkit-box-pack:center}')[0], {}); }, 'must be false': function (result) { assert.isFalse(result); -- 2.34.1