From 0ed903f04daf26ef6633342010be24b72436e62c Mon Sep 17 00:00:00 2001 From: Jakub Pawlowicz Date: Sun, 21 Jun 2015 15:18:37 +0100 Subject: [PATCH] Cleans up advanced optimizer implementation. It gets rid of AdvancedOptimizer class in favour to simpler functional style. --- lib/clean.js | 4 +- lib/selectors/advanced.js | 74 +++++++++++++++------------------ test/selectors/advanced-test.js | 56 ++++++++++++------------- 3 files changed, 64 insertions(+), 70 deletions(-) diff --git a/lib/clean.js b/lib/clean.js index b3c0a44d..87522ec5 100644 --- a/lib/clean.js +++ b/lib/clean.js @@ -10,7 +10,7 @@ var rebaseUrls = require('./urls/rebase'); var tokenize = require('./tokenizer/tokenize'); var SimpleOptimizer = require('./selectors/simple'); -var AdvancedOptimizer = require('./selectors/advanced'); +var advancedOptimize = require('./selectors/advanced'); var addOptimizationMetadata = require('./selectors/optimization-metadata'); var simpleStringify = require('./stringifier/simple'); @@ -206,7 +206,7 @@ function minify(context, data) { new SimpleOptimizer(options).optimize(tokens); if (options.advanced) - new AdvancedOptimizer(options, context).optimize(tokens); + advancedOptimize(tokens, options, context.validator, true); return stringify(tokens, options, restoreEscapes, context.inputSourceMapTracker); } diff --git a/lib/selectors/advanced.js b/lib/selectors/advanced.js index 48e55fe9..f03b11fa 100644 --- a/lib/selectors/advanced.js +++ b/lib/selectors/advanced.js @@ -9,12 +9,7 @@ var restructure = require('./restructure'); var removeDuplicateMediaQueries = require('./remove-duplicate-media-queries'); var mergeMediaQueries = require('./merge-media-queries'); -function AdvancedOptimizer(options, context) { - this.options = options; - this.validator = context.validator; -} - -AdvancedOptimizer.prototype.removeEmpty = function (tokens) { +function removeEmpty(tokens) { for (var i = 0, l = tokens.length; i < l; i++) { var token = tokens[i]; var isEmpty = false; @@ -24,7 +19,7 @@ AdvancedOptimizer.prototype.removeEmpty = function (tokens) { isEmpty = token[1].length === 0 || token[2].length === 0; break; case 'block': - this.removeEmpty(token[2]); + removeEmpty(token[2]); isEmpty = token[2].length === 0; } @@ -34,7 +29,18 @@ AdvancedOptimizer.prototype.removeEmpty = function (tokens) { l--; } } -}; +} + +function recursivelyOptimizeBlocks(tokens, options, validator) { + for (var i = 0, l = tokens.length; i < l; i++) { + var token = tokens[i]; + + if (token[0] == 'block') { + var isKeyframes = /@(-moz-|-o-|-webkit-)?keyframes/.test(token[1][0]); + optimize(token[2], options, validator, !isKeyframes); + } + } +} function recursivelyOptimizeProperties(tokens, options, validator) { for (var i = 0, l = tokens.length; i < l; i++) { @@ -50,43 +56,31 @@ function recursivelyOptimizeProperties(tokens, options, validator) { } } -AdvancedOptimizer.prototype.optimize = function (tokens) { - var self = this; - - function _optimize(tokens, withRestructuring) { - tokens.forEach(function (token) { - if (token[0] == 'block') { - var isKeyframes = /@(-moz-|-o-|-webkit-)?keyframes/.test(token[1][0]); - _optimize(token[2], !isKeyframes); - } - }); - - recursivelyOptimizeProperties(tokens, self.options, self.validator); +function optimize(tokens, options, validator, withRestructuring) { + recursivelyOptimizeBlocks(tokens, options, validator); + recursivelyOptimizeProperties(tokens, options, validator); - removeDuplicates(tokens); - mergeAdjacent(tokens, self.options, self.validator); - reduceNonAdjacent(tokens, self.options, self.validator); + removeDuplicates(tokens); + mergeAdjacent(tokens, options, validator); + reduceNonAdjacent(tokens, options, validator); - mergeNonAdjacentBySelector(tokens, self.options, self.validator); - mergeNonAdjacentByBody(tokens, self.options); + mergeNonAdjacentBySelector(tokens, options, validator); + mergeNonAdjacentByBody(tokens, options); - if (self.options.restructuring && withRestructuring) { - restructure(tokens, self.options); - mergeAdjacent(tokens, self.options, self.validator); - } + if (options.restructuring && withRestructuring) { + restructure(tokens, options); + mergeAdjacent(tokens, options, validator); + } - if (self.options.mediaMerging) { - removeDuplicateMediaQueries(tokens); - var reduced = mergeMediaQueries(tokens); - for (var i = reduced.length - 1; i >= 0; i--) { - _optimize(reduced[i][2]); - } + if (options.mediaMerging) { + removeDuplicateMediaQueries(tokens); + var reduced = mergeMediaQueries(tokens); + for (var i = reduced.length - 1; i >= 0; i--) { + optimize(reduced[i][2], options, validator, false); } - - self.removeEmpty(tokens); } - _optimize(tokens, true); -}; + removeEmpty(tokens); +} -module.exports = AdvancedOptimizer; +module.exports = optimize; diff --git a/test/selectors/advanced-test.js b/test/selectors/advanced-test.js index f5409bd3..c909652a 100644 --- a/test/selectors/advanced-test.js +++ b/test/selectors/advanced-test.js @@ -2,34 +2,6 @@ var vows = require('vows'); var optimizerContext = require('../test-helper').optimizerContext; vows.describe('advanced optimizer') - .addBatch( - optimizerContext('@media', { - 'empty': [ - '@media (min-width:980px){}', - '' - ], - 'whitespace': [ - ' @media ( min-width: 980px ){}', - '' - ], - 'body': [ - '@media (min-width:980px){\na\n{color:red}}', - '@media (min-width:980px){a{color:red}}' - ], - 'multiple': [ - '@media screen, print, (min-width:980px){a{color:red}}', - '@media screen,print,(min-width:980px){a{color:red}}' - ], - 'nested once': [ - '@media screen { @media print { a{color:red} } }', - '@media screen{@media print{a{color:red}}}' - ], - 'nested twice': [ - '@media screen { @media print { @media (min-width:980px) { a{color:red} } } }', - '@media screen{@media print{@media (min-width:980px){a{color:red}}}}' - ] - }) - ) .addBatch( optimizerContext('advanced on & aggressive merging on', { 'repeated' : [ @@ -62,6 +34,34 @@ vows.describe('advanced optimizer') ] }, { advanced: false }) ) + .addBatch( + optimizerContext('@media', { + 'empty': [ + '@media (min-width:980px){}', + '' + ], + 'whitespace': [ + ' @media ( min-width: 980px ){}', + '' + ], + 'body': [ + '@media (min-width:980px){\na\n{color:red}}', + '@media (min-width:980px){a{color:red}}' + ], + 'multiple': [ + '@media screen, print, (min-width:980px){a{color:red}}', + '@media screen,print,(min-width:980px){a{color:red}}' + ], + 'nested once': [ + '@media screen { @media print { a{color:red} } }', + '@media screen{@media print{a{color:red}}}' + ], + 'nested twice': [ + '@media screen { @media print { @media (min-width:980px) { a{color:red} } } }', + '@media screen{@media print{@media (min-width:980px){a{color:red}}}}' + ] + }) + ) .addBatch( optimizerContext('@font-face', { 'rebuilding': [ -- 2.34.1