* Copyright (C) 2016 JakubPawlowicz.com
*/
-var ImportInliner = require('./imports/inliner');
-var rebaseUrls = require('./urls/rebase');
-
-var tokenize = require('./tokenizer/tokenize');
-var simpleOptimize = require('./selectors/simple');
-var advancedOptimize = require('./selectors/advanced');
-
-var simpleStringify = require('./stringifier/simple');
-var sourceMapStringify = require('./stringifier/source-maps');
-
-var CommentsProcessor = require('./text/comments-processor');
-var ExpressionsProcessor = require('./text/expressions-processor');
-var FreeTextProcessor = require('./text/free-text-processor');
-var UrlsProcessor = require('./text/urls-processor');
-
-var Compatibility = require('./utils/compatibility');
-var InputSourceMapTracker = require('./utils/input-source-map-tracker');
-var SourceTracker = require('./utils/source-tracker');
-var SourceReader = require('./utils/source-reader');
-var Validator = require('./properties/validator');
-
var fs = require('fs');
var path = require('path');
var url = require('url');
-var override = require('./utils/object').override;
-
+var compatibility = require('./utils/compatibility');
+var Validator = require('./properties/validator');
+var override = require('./utils/override');
var DEFAULT_TIMEOUT = 5000;
+var readSources = require('./utils/read-sources');
+var basicOptimize = require('./optimizer/basic');
+var advancedOptimize = require('./optimizer/advanced');
+var simpleStringify = require('./stringifier/simple');
+var sourceMapStringify = require('./stringifier/source-maps');
+
var CleanCSS = module.exports = function CleanCSS(options) {
options = options || {};
advanced: undefined === options.advanced ? true : !!options.advanced,
aggressiveMerging: undefined === options.aggressiveMerging ? true : !!options.aggressiveMerging,
benchmark: options.benchmark,
- compatibility: new Compatibility(options.compatibility).toOptions(),
+ compatibility: compatibility(options.compatibility),
debug: options.debug,
explicitRoot: !!options.root,
explicitTarget: !!options.target,
{};
}
-CleanCSS.prototype.minify = function (data, callback) {
+CleanCSS.prototype.minify = function (input, callback) {
var context = {
stats: {},
errors: [],
warnings: [],
options: this.options,
- debug: this.options.debug,
localOnly: !callback,
- sourceTracker: new SourceTracker(),
validator: new Validator(this.options.compatibility)
};
- if (context.options.sourceMap)
- context.inputSourceMapTracker = new InputSourceMapTracker(context);
+ return runner(context.localOnly)(function () {
+ return readSources(input, context, function (tokens) {
+ var stringify = context.options.sourceMap ?
+ sourceMapStringify :
+ simpleStringify;
- context.sourceReader = new SourceReader(context, data);
- data = context.sourceReader.toString();
+ var optimizedTokens = optimize(tokens, context);
+ var optimizedStyles = stringify(optimizedTokens, context);
+ var output = withMetadata(optimizedStyles, context);
- if (context.options.processImport || data.indexOf('@shallow') > 0) {
- // inline all imports
- var runner = callback ?
- process.nextTick :
- function (callback) { return callback(); };
-
- return runner(function () {
- return new ImportInliner(context).process(data, {
- localOnly: context.localOnly,
- imports: context.options.processImportFrom,
- whenDone: runMinifier(callback, context)
- });
+ return callback ?
+ callback(context.errors.length > 0 ? context.errors : null, output) :
+ output;
});
- } else {
- return runMinifier(callback, context)(data);
- }
+ });
};
-function runMinifier(callback, context) {
- function whenSourceMapReady (data) {
- data = context.options.debug ?
- minifyWithDebug(context, data) :
- minify(context, data);
- data = withMetadata(context, data);
-
- return callback ?
- callback.call(null, context.errors.length > 0 ? context.errors : null, data) :
- data;
- }
-
- return function (data) {
- if (context.options.sourceMap) {
- return context.inputSourceMapTracker.track(data, function () {
- if (context.options.sourceMapInlineSources) {
- return context.inputSourceMapTracker.resolveSources(function () {
- return whenSourceMapReady(data);
- });
- } else {
- return whenSourceMapReady(data);
- }
- });
- } else {
- return whenSourceMapReady(data);
- }
- };
-}
-
-function withMetadata(context, data) {
- data.stats = context.stats;
- data.errors = context.errors;
- data.warnings = context.warnings;
- return data;
+function runner(localOnly) {
+ // to always execute code asynchronously when a callback is given
+ // more at blog.izs.me/post/59142742143/designing-apis-for-asynchrony
+ return localOnly ?
+ function (callback) { return callback(); } :
+ process.nextTick;
}
-function minifyWithDebug(context, data) {
- var startedAt = process.hrtime();
- context.stats.originalSize = context.sourceTracker.removeAll(data).length;
-
- data = minify(context, data);
+function optimize(tokens, context) {
+ var optimized;
- var elapsed = process.hrtime(startedAt);
- context.stats.timeSpent = ~~(elapsed[0] * 1e3 + elapsed[1] / 1e6);
- context.stats.efficiency = 1 - data.styles.length / context.stats.originalSize;
- context.stats.minifiedSize = data.styles.length;
+ optimized = basicOptimize(tokens, context);
+ optimized = context.options.advanced ?
+ advancedOptimize(tokens, context, true) :
+ optimized;
- return data;
+ return optimized;
}
-function benchmark(runner) {
- return function (processor, action) {
- var name = processor.constructor.name + '#' + action;
- var start = process.hrtime();
- runner(processor, action);
- var itTook = process.hrtime(start);
- console.log('%d ms: ' + name, 1000 * itTook[0] + itTook[1] / 1000000);
- };
+function withMetadata(output, context) {
+ output.stats = context.stats;
+ output.errors = context.errors;
+ output.warnings = context.warnings;
+ return output;
}
-function minify(context, data) {
- var options = context.options;
+// function minifyWithDebug(context, data) {
+// var startedAt = process.hrtime();
+// context.stats.originalSize = context.sourceTracker.removeAll(data).length;
- var commentsProcessor = new CommentsProcessor(context, options.keepSpecialComments, options.keepBreaks, options.sourceMap);
- var expressionsProcessor = new ExpressionsProcessor(options.sourceMap);
- var freeTextProcessor = new FreeTextProcessor(options.sourceMap);
- var urlsProcessor = new UrlsProcessor(context, options.sourceMap, options.compatibility.properties.urlQuotes);
+// data = minify(context, data);
- var stringify = options.sourceMap ? sourceMapStringify : simpleStringify;
+// var elapsed = process.hrtime(startedAt);
+// context.stats.timeSpent = ~~(elapsed[0] * 1e3 + elapsed[1] / 1e6);
+// context.stats.efficiency = 1 - data.styles.length / context.stats.originalSize;
+// context.stats.minifiedSize = data.styles.length;
- var run = function (processor, action) {
- data = typeof processor == 'function' ?
- processor(data) :
- processor[action](data);
- };
-
- if (options.benchmark)
- run = benchmark(run);
-
- run(commentsProcessor, 'escape');
- run(expressionsProcessor, 'escape');
- run(urlsProcessor, 'escape');
- run(freeTextProcessor, 'escape');
+// return data;
+// }
- function restoreEscapes(data, prefixContent) {
- data = freeTextProcessor.restore(data, prefixContent);
- data = urlsProcessor.restore(data);
- data = options.rebase ? rebaseUrls(data, context) : data;
- data = expressionsProcessor.restore(data);
- return commentsProcessor.restore(data);
- }
+// function minify(context, data) {
+ // var options = context.options;
+ // var stringify = options.sourceMap ?
+ // sourceMapStringify :
+ // simpleStringify;
- var tokens = tokenize(data, context);
+ // var tokens = tokenize(data, context);
+ // var allTokens = inline()
+ // var optimizedTokens = optimize(tokens, context);
+ // var output = stringify(optimizedTokens, context);
- simpleOptimize(tokens, options, context);
-
- if (options.advanced)
- advancedOptimize(tokens, options, context, true);
-
- return stringify(tokens, options, restoreEscapes, context.inputSourceMapTracker);
-}
+ // return output;
+// }
var removeDuplicateMediaQueries = require('./remove-duplicate-media-queries');
var mergeMediaQueries = require('./merge-media-queries');
+var Token = require('../tokenizer/token');
+
function removeEmpty(tokens) {
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
var isEmpty = false;
switch (token[0]) {
- case 'selector':
+ case Token.RULE:
isEmpty = token[1].length === 0 || token[2].length === 0;
break;
- case 'block':
+ case Token.BLOCK:
removeEmpty(token[2]);
isEmpty = token[2].length === 0;
}
}
}
-function recursivelyOptimizeBlocks(tokens, options, context) {
+function recursivelyOptimizeBlocks(tokens, context) {
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, context, !isKeyframes);
+ if (token[0] == Token.BLOCK) {
+ var isKeyframes = /@(-moz-|-o-|-webkit-)?keyframes/.test(token[1][0][0]);
+ optimize(token[2], context, !isKeyframes);
}
}
}
-function recursivelyOptimizeProperties(tokens, options, context) {
+function recursivelyOptimizeProperties(tokens, context) {
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
switch (token[0]) {
- case 'selector':
- optimizeProperties(token[1], token[2], false, true, options, context);
+ case Token.RULE:
+ optimizeProperties(token[1], token[2], false, true, context);
break;
- case 'block':
- recursivelyOptimizeProperties(token[2], options, context);
+ case Token.BLOCK:
+ recursivelyOptimizeProperties(token[2], context);
}
}
}
-function optimize(tokens, options, context, withRestructuring) {
- recursivelyOptimizeBlocks(tokens, options, context);
- recursivelyOptimizeProperties(tokens, options, context);
+function optimize(tokens, context, withRestructuring) {
+ recursivelyOptimizeBlocks(tokens, context);
+ recursivelyOptimizeProperties(tokens, context);
- removeDuplicates(tokens);
- mergeAdjacent(tokens, options, context);
- reduceNonAdjacent(tokens, options, context);
+ removeDuplicates(tokens, context);
+ mergeAdjacent(tokens, context);
+ reduceNonAdjacent(tokens, context);
- mergeNonAdjacentBySelector(tokens, options, context);
- mergeNonAdjacentByBody(tokens, options);
+ mergeNonAdjacentBySelector(tokens, context);
+ mergeNonAdjacentByBody(tokens, context);
- if (options.restructuring && withRestructuring) {
- restructure(tokens, options);
- mergeAdjacent(tokens, options, context);
+ if (context.options.restructuring && withRestructuring) {
+ restructure(tokens, context);
+ mergeAdjacent(tokens, context);
}
- if (options.mediaMerging) {
- removeDuplicateMediaQueries(tokens);
- var reduced = mergeMediaQueries(tokens);
+ if (context.options.mediaMerging) {
+ removeDuplicateMediaQueries(tokens, context);
+ var reduced = mergeMediaQueries(tokens, context);
for (var i = reduced.length - 1; i >= 0; i--) {
- optimize(reduced[i][2], options, context, false);
+ optimize(reduced[i][2], context, false);
}
}
removeEmpty(tokens);
+
+ return tokens;
}
module.exports = optimize;
-var cleanUpSelectors = require('./clean-up').selectors;
-var cleanUpBlock = require('./clean-up').block;
-var cleanUpAtRule = require('./clean-up').atRule;
+var tidyRules = require('./tidy-rules');
+var tidyBlock = require('./tidy-block');
+var tidyAtRule = require('./tidy-at-rule');
var split = require('../utils/split');
+var Token = require('../tokenizer/token');
+var Marker = require('../tokenizer/marker');
+
var RGB = require('../colors/rgb');
var HSL = require('../colors/hsl');
var HexNameShortener = require('../colors/hex-name-shortener');
+var Hack = require('../properties/hack');
+
var wrapForOptimizing = require('../properties/wrap-for-optimizing').all;
var restoreFromOptimizing = require('../properties/restore-from-optimizing');
var removeUnused = require('../properties/remove-unused');
+var rebaseConfig = require('../urls/rebase-config');
+var rewriteUrl = require('../urls/rewrite-url');
+
var DEFAULT_ROUNDING_PRECISION = 2;
var CHARSET_TOKEN = '@charset';
var CHARSET_REGEXP = new RegExp('^' + CHARSET_TOKEN, 'i');
-var IMPORT_REGEXP = /^@import["'\s]/i;
var FONT_NUMERAL_WEIGHTS = ['100', '200', '300', '400', '500', '600', '700', '800', '900'];
var FONT_NAME_WEIGHTS = ['normal', 'bold', 'bolder', 'lighter'];
var WHOLE_PIXEL_VALUE = /(?:^|\s|\()(-?\d+)px/;
var TIME_VALUE = /^(\-?[\d\.]+)(m?s)$/;
+var QUOTED_PATTERN = /^('.*'|".*")$/;
+var QUOTED_BUT_SAFE_PATTERN = /^['"][a-zA-Z][a-zA-Z\d\-_]+['"]$/;
+var URL_PREFIX_PATTERN = /^url\(/i;
+
var valueMinifiers = {
'background': function (value, index, total) {
return index === 0 && total == 1 && (value == 'none' || value == 'transparent') ? '0 0' : value;
}
};
-function isNegative(property, idx) {
- return property.value[idx] && property.value[idx][0][0] == '-' && parseFloat(property.value[idx][0]) < 0;
+function isNegative(value) {
+ return value && value[1][0] == '-' && parseFloat(value[1]) < 0;
}
function zeroMinifier(name, value) {
}
function whitespaceMinifier(name, value) {
- if (name.indexOf('filter') > -1 || value.indexOf(' ') == -1)
+ if (name.indexOf('filter') > -1 || value.indexOf(' ') == -1 || value.indexOf('expression') === 0)
+ return value;
+
+ if (value.indexOf(Marker.SINGLE_QUOTE) > -1 || value.indexOf(Marker.DOUBLE_QUOTE) > -1)
return value;
value = value.replace(/\s+/g, ' ');
var values = property.value;
var spliceAt;
- if (values.length == 4 && values[0][0] === '0' && values[1][0] === '0' && values[2][0] === '0' && values[3][0] === '0') {
- if (property.name.indexOf('box-shadow') > -1)
+ if (values.length == 4 && values[0][1] === '0' && values[1][1] === '0' && values[2][1] === '0' && values[3][1] === '0') {
+ if (property.name.indexOf('box-shadow') > -1) {
spliceAt = 2;
- else
+ } else {
spliceAt = 1;
+ }
}
if (spliceAt) {
var values = property.value;
var spliceAt;
- if (values.length == 3 && values[1][0] == '/' && values[0][0] == values[2][0])
+ if (values.length == 3 && values[1][1] == '/' && values[0][1] == values[2][1])
spliceAt = 1;
- else if (values.length == 5 && values[2][0] == '/' && values[0][0] == values[3][0] && values[1][0] == values[4][0])
+ else if (values.length == 5 && values[2][1] == '/' && values[0][1] == values[3][1] && values[1][1] == values[4][1])
spliceAt = 2;
- else if (values.length == 7 && values[3][0] == '/' && values[0][0] == values[4][0] && values[1][0] == values[5][0] && values[2][0] == values[6][0])
+ else if (values.length == 7 && values[3][1] == '/' && values[0][1] == values[4][1] && values[1][1] == values[5][1] && values[2][1] == values[6][1])
spliceAt = 3;
- else if (values.length == 9 && values[4][0] == '/' && values[0][0] == values[5][0] && values[1][0] == values[6][0] && values[2][0] == values[7][0] && values[3][0] == values[8][0])
+ else if (values.length == 9 && values[4][1] == '/' && values[0][1] == values[5][1] && values[1][1] == values[6][1] && values[2][1] == values[7][1] && values[3][1] == values[8][1])
spliceAt = 4;
if (spliceAt) {
function minifyFilter(property) {
if (property.value.length == 1) {
- property.value[0][0] = property.value[0][0].replace(/progid:DXImageTransform\.Microsoft\.(Alpha|Chroma)(\W)/, function (match, filter, suffix) {
+ property.value[0][1] = property.value[0][1].replace(/progid:DXImageTransform\.Microsoft\.(Alpha|Chroma)(\W)/, function (match, filter, suffix) {
return filter.toLowerCase() + suffix;
});
}
- property.value[0][0] = property.value[0][0]
+ property.value[0][1] = property.value[0][1]
.replace(/,(\S)/g, ', $1')
.replace(/ ?= ?/g, '=');
}
function minifyFont(property) {
var values = property.value;
- var hasNumeral = FONT_NUMERAL_WEIGHTS.indexOf(values[0][0]) > -1 ||
- values[1] && FONT_NUMERAL_WEIGHTS.indexOf(values[1][0]) > -1 ||
- values[2] && FONT_NUMERAL_WEIGHTS.indexOf(values[2][0]) > -1;
+ var hasNumeral = FONT_NUMERAL_WEIGHTS.indexOf(values[0][1]) > -1 ||
+ values[1] && FONT_NUMERAL_WEIGHTS.indexOf(values[1][1]) > -1 ||
+ values[2] && FONT_NUMERAL_WEIGHTS.indexOf(values[2][1]) > -1;
if (hasNumeral)
return;
- if (values[1] == '/')
+ if (values[1] && values[1][1] == '/')
return;
var normalCount = 0;
- if (values[0][0] == 'normal')
+ if (values[0][1] == 'normal')
normalCount++;
- if (values[1] && values[1][0] == 'normal')
+ if (values[1] && values[1][1] == 'normal')
normalCount++;
- if (values[2] && values[2][0] == 'normal')
+ if (values[2] && values[2][1] == 'normal')
normalCount++;
if (normalCount > 1)
return;
var toOptimize;
- if (FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[0][0]) > -1)
+ if (FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[0][1]) > -1)
toOptimize = 0;
- else if (values[1] && FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[1][0]) > -1)
+ else if (values[1] && FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[1][1]) > -1)
toOptimize = 1;
- else if (values[2] && FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[2][0]) > -1)
+ else if (values[2] && FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[2][1]) > -1)
toOptimize = 2;
- else if (FONT_NAME_WEIGHTS.indexOf(values[0][0]) > -1)
+ else if (FONT_NAME_WEIGHTS.indexOf(values[0][1]) > -1)
toOptimize = 0;
- else if (values[1] && FONT_NAME_WEIGHTS.indexOf(values[1][0]) > -1)
+ else if (values[1] && FONT_NAME_WEIGHTS.indexOf(values[1][1]) > -1)
toOptimize = 1;
- else if (values[2] && FONT_NAME_WEIGHTS.indexOf(values[2][0]) > -1)
+ else if (values[2] && FONT_NAME_WEIGHTS.indexOf(values[2][1]) > -1)
toOptimize = 2;
if (toOptimize !== undefined) {
- property.value[toOptimize][0] = valueMinifiers['font-weight'](values[toOptimize][0]);
+ property.value[toOptimize][1] = valueMinifiers['font-weight'](values[toOptimize][1]);
property.dirty = true;
}
}
-function optimizeBody(properties, options) {
+function normalizeUrl(value) {
+ return value
+ .replace(URL_PREFIX_PATTERN, 'url(')
+ .replace(/\\?\n|\\?\r\n/g, '');
+}
+
+function removeUrlQuotes(value) {
+ return /^url\(['"].+['"]\)$/.test(value) && !/^url\(['"].*[\*\s\(\)'"].*['"]\)$/.test(value) && !/^url\(['"]data:[^;]+;charset/.test(value) ?
+ value.replace(/["']/g, '') :
+ value;
+}
+
+function isQuoted(value) {
+ return QUOTED_PATTERN.test(value);
+}
+
+function removeQuotes(name, value) {
+ if (name == 'content') {
+ return value;
+ }
+
+ return QUOTED_BUT_SAFE_PATTERN.test(value) ?
+ value.substring(1, value.length - 1) :
+ value;
+}
+
+function optimizeBody(properties, context) {
+ var options = context.options;
var property, name, value;
+ var valueIsUrl;
var _properties = wrapForOptimizing(properties);
for (var i = 0, l = _properties.length; i < l; i++) {
property = _properties[i];
name = property.name;
+ if (property.value.length === 0) {
+ property.unused = true;
+ }
+
if (property.hack && (
- (property.hack == 'star' || property.hack == 'underscore') && !options.compatibility.properties.iePrefixHack ||
- property.hack == 'backslash' && !options.compatibility.properties.ieSuffixHack ||
- property.hack == 'bang' && !options.compatibility.properties.ieBangHack))
+ (property.hack == Hack.STAR || property.hack == Hack.UNDERSCORE) && !options.compatibility.properties.iePrefixHack ||
+ property.hack == Hack.BACKSLASH && !options.compatibility.properties.ieSuffixHack ||
+ property.hack == Hack.BANG && !options.compatibility.properties.ieBangHack)) {
property.unused = true;
+ }
- if (name.indexOf('padding') === 0 && (isNegative(property, 0) || isNegative(property, 1) || isNegative(property, 2) || isNegative(property, 3)))
+ if (name.indexOf('padding') === 0 && (isNegative(property.value[0]) || isNegative(property.value[1]) || isNegative(property.value[2]) || isNegative(property.value[3])))
property.unused = true;
if (property.unused)
continue;
- if (property.variable) {
- if (property.block)
- optimizeBody(property.value[0], options);
+ if (property.block) {
+ optimizeBody(property.value[0][1], context);
continue;
}
for (var j = 0, m = property.value.length; j < m; j++) {
- value = property.value[j][0];
+ value = property.value[j][1];
+ valueIsUrl = isUrl(value);
+
+ if (valueIsUrl && !context.validator.isValidUrl(value)) {
+ property.unused = true;
+ break;
+ }
if (valueMinifiers[name])
value = valueMinifiers[name](value, j, m);
- value = whitespaceMinifier(name, value);
- value = precisionMinifier(name, value, options.precision);
- value = pixelLengthMinifier(name, value, options.compatibility);
- value = timeUnitMinifier(name, value);
- value = zeroMinifier(name, value);
- if (options.compatibility.properties.zeroUnits) {
- value = zeroDegMinifier(name, value);
- value = unitMinifier(name, value, options.unitsRegexp);
+ if (valueIsUrl) {
+ value = normalizeUrl(value);
+ value = options.compatibility.properties.urlQuotes ?
+ value :
+ removeUrlQuotes(value);
+ value = options.rebase && context.validator.isValidUrl(value) ?
+ rewriteUrl(value, options.rebaseConfig) :
+ value;
+ } else if (isQuoted(value)) {
+ value = removeQuotes(name, value);
+ } else {
+ value = whitespaceMinifier(name, value);
+ value = precisionMinifier(name, value, options.precision);
+ value = pixelLengthMinifier(name, value, options.compatibility);
+ value = timeUnitMinifier(name, value);
+ value = zeroMinifier(name, value);
+ if (options.compatibility.properties.zeroUnits) {
+ value = zeroDegMinifier(name, value);
+ value = unitMinifier(name, value, options.unitsRegexp);
+ }
+ if (options.compatibility.properties.colors)
+ value = colorMininifier(name, value, options.compatibility);
}
- if (options.compatibility.properties.colors)
- value = colorMininifier(name, value, options.compatibility);
- property.value[j][0] = value;
+ property.value[j][1] = value;
}
multipleZerosMinifier(property);
restoreFromOptimizing(_properties, true);
removeUnused(_properties);
+
+ if (_properties.length != properties.length) {
+ removeComments(properties, options);
+ }
+}
+
+function isUrl(value) {
+ return URL_PREFIX_PATTERN.test(value);
+}
+
+function removeComments(tokens, options) {
+ var token;
+ var i;
+
+ for (i = 0; i < tokens.length; i++) {
+ token = tokens[i];
+
+ if (token[0] != Token.COMMENT) {
+ continue;
+ }
+
+ optimizeComment(token, options);
+
+ if (token[1].length === 0) {
+ tokens.splice(i, 1);
+ i--;
+ }
+ }
+}
+
+function optimizeComment(token, options) {
+ if (token[1][0][2] == Marker.EXCLAMATION && (options.keepSpecialComments == '*' || options.commentsKept < options.keepSpecialComments)) {
+ options.commentsKept++;
+ return;
+ }
+
+ token[1] = [];
}
function cleanupCharsets(tokens) {
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
- if (token[0] != 'at-rule')
+ if (token[0] != Token.AT_RULE)
continue;
- if (!CHARSET_REGEXP.test(token[1][0]))
+ if (!CHARSET_REGEXP.test(token[1]))
continue;
- if (hasCharset || token[1][0].indexOf(CHARSET_TOKEN) == -1) {
+ if (hasCharset || token[1].indexOf(CHARSET_TOKEN) == -1) {
tokens.splice(i, 1);
i--;
l--;
} else {
hasCharset = true;
tokens.splice(i, 1);
- tokens.unshift(['at-rule', [token[1][0].replace(CHARSET_REGEXP, CHARSET_TOKEN)]]);
+ tokens.unshift([Token.AT_RULE, token[1].replace(CHARSET_REGEXP, CHARSET_TOKEN)]);
}
}
}
return precision;
}
-function optimize(tokens, options, context) {
+function basicOptimize(tokens, context) {
+ var options = context.options;
var ie7Hack = options.compatibility.selectors.ie7Hack;
var adjacentSpace = options.compatibility.selectors.adjacentSpace;
var spaceAfterClosingBrace = options.compatibility.properties.spaceAfterClosingBrace;
var mayHaveCharset = false;
- var afterContent = false;
- options.unitsRegexp = buildUnitRegexp(options);
- options.precision = buildPrecision(options);
+ options.unitsRegexp = options.unitsRegexp || buildUnitRegexp(options);
+ options.precision = options.precision || buildPrecision(options);
+ options.commentsKept = options.commentsKept || 0;
+ options.rebaseConfig = options.rebaseConfig || rebaseConfig(context);
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
switch (token[0]) {
- case 'selector':
- token[1] = cleanUpSelectors(token[1], !ie7Hack, adjacentSpace);
- optimizeBody(token[2], options);
- afterContent = true;
+ case Token.AT_RULE:
+ token[1] = tidyAtRule(token[1]);
+ mayHaveCharset = true;
break;
- case 'block':
- cleanUpBlock(token[1], spaceAfterClosingBrace);
- optimize(token[2], options, context);
- afterContent = true;
+ case Token.AT_RULE_BLOCK:
+ optimizeBody(token[2], context);
break;
- case 'flat-block':
- cleanUpBlock(token[1], spaceAfterClosingBrace);
- optimizeBody(token[2], options);
- afterContent = true;
+ case Token.BLOCK:
+ token[1] = tidyBlock(token[1], spaceAfterClosingBrace);
+ basicOptimize(token[2], context);
+ break;
+ case Token.COMMENT:
+ optimizeComment(token, options);
+ break;
+ case Token.RULE:
+ token[1] = tidyRules(token[1], !ie7Hack, adjacentSpace);
+ optimizeBody(token[2], context);
break;
- case 'at-rule':
- cleanUpAtRule(token[1]);
- mayHaveCharset = true;
- }
-
- if (token[0] == 'at-rule' && IMPORT_REGEXP.test(token[1]) && afterContent) {
- context.warnings.push('Ignoring @import rule "' + token[1] + '" as it appears after rules thus browsers will ignore them.');
- token[1] = '';
}
if (token[1].length === 0 || (token[2] && token[2].length === 0)) {
}
}
- if (mayHaveCharset)
+ if (mayHaveCharset) {
cleanupCharsets(tokens);
+ }
+
+ return tokens;
}
-module.exports = optimize;
+module.exports = basicOptimize;
// IMPORTANT: Mind Token class and this code is not related!
// Properties will be tokenized in one step, see #429
-var stringifySelectors = require('../stringifier/one-time').selectors;
+var stringifyRules = require('../stringifier/one-time').rules;
var stringifyValue = require('../stringifier/one-time').value;
+var Token = require('../tokenizer/token');
-var AT_RULE = 'at-rule';
-
-function extract(token) {
+function extractProperties(token) {
var properties = [];
+ var inSpecificSelector;
+ var property;
+ var name;
+ var value;
+ var i, l;
- if (token[0] == 'selector') {
- var inSpecificSelector = !/[\.\+>~]/.test(stringifySelectors(token[1]));
- for (var i = 0, l = token[2].length; i < l; i++) {
- var property = token[2][i];
+ if (token[0] == Token.RULE) {
+ inSpecificSelector = !/[\.\+>~]/.test(stringifyRules(token[1]));
- if (property.indexOf('__ESCAPED') === 0)
- continue;
+ for (i = 0, l = token[2].length; i < l; i++) {
+ property = token[2][i];
- if (property[0] == AT_RULE)
+ if (property[0] != Token.PROPERTY)
continue;
- var name = token[2][i][0][0];
+ name = property[1][1];
if (name.length === 0)
continue;
if (name.indexOf('--') === 0)
continue;
- var value = stringifyValue(token[2], i);
+ value = stringifyValue(property, i);
properties.push([
name,
inSpecificSelector
]);
}
- } else if (token[0] == 'block') {
- for (var j = 0, k = token[2].length; j < k; j++) {
- properties = properties.concat(extract(token[2][j]));
+ } else if (token[0] == Token.BLOCK) {
+ for (i = 0, l = token[2].length; i < l; i++) {
+ properties = properties.concat(extractProperties(token[2][i]));
}
}
return name.replace(/^\-\w+\-/, '').match(/([a-zA-Z]+)/)[0].toLowerCase();
}
-module.exports = extract;
+module.exports = extractProperties;
--- /dev/null
+var optimizeProperties = require('../properties/optimizer');
+
+var stringifyBody = require('../stringifier/one-time').body;
+var stringifyRules = require('../stringifier/one-time').rules;
+var tidyRules = require('./tidy-rules');
+var isSpecial = require('./is-special');
+
+var Token = require('../tokenizer/token');
+
+function mergeAdjacent(tokens, context) {
+ var lastToken = [null, [], []];
+ var options = context.options;
+ var adjacentSpace = options.compatibility.selectors.adjacentSpace;
+
+ for (var i = 0, l = tokens.length; i < l; i++) {
+ var token = tokens[i];
+
+ if (token[0] != Token.RULE) {
+ lastToken = [null, [], []];
+ continue;
+ }
+
+ if (lastToken[0] == Token.RULE && stringifyRules(token[1]) == stringifyRules(lastToken[1])) {
+ var joinAt = [lastToken[2].length];
+ Array.prototype.push.apply(lastToken[2], token[2]);
+ optimizeProperties(token[1], lastToken[2], joinAt, true, context);
+ token[2] = [];
+ } else if (lastToken[0] == Token.RULE && stringifyBody(token[2]) == stringifyBody(lastToken[2]) &&
+ !isSpecial(options, stringifyRules(token[1])) && !isSpecial(options, stringifyRules(lastToken[1]))) {
+ lastToken[1] = tidyRules(lastToken[1].concat(token[1]), false, adjacentSpace);
+ token[2] = [];
+ } else {
+ lastToken = token;
+ }
+ }
+}
+
+module.exports = mergeAdjacent;
var canReorder = require('./reorderable').canReorder;
-var extractProperties = require('./extractor');
+var extractProperties = require('./extract-properties');
+
+var stringifyRules = require('../stringifier/one-time').rules;
+var Token = require('../tokenizer/token');
function mergeMediaQueries(tokens) {
var candidates = {};
for (var i = tokens.length - 1; i >= 0; i--) {
var token = tokens[i];
- if (token[0] != 'block')
+ if (token[0] != Token.BLOCK) {
continue;
+ }
- var candidate = candidates[token[1][0]];
+ var key = stringifyRules(token[1]);
+ var candidate = candidates[key];
if (!candidate) {
candidate = [];
- candidates[token[1][0]] = candidate;
+ candidates[key] = candidate;
}
candidate.push(i);
var stringifyBody = require('../stringifier/one-time').body;
-var stringifySelectors = require('../stringifier/one-time').selectors;
-var cleanUpSelectors = require('./clean-up').selectors;
+var stringifyRules = require('../stringifier/one-time').rules;
+var tidyRules = require('./tidy-rules');
var isSpecial = require('./is-special');
+var Token = require('../tokenizer/token');
+
function unsafeSelector(value) {
return /\.|\*| :/.test(value);
}
function isBemElement(token) {
- var asString = stringifySelectors(token[1]);
+ var asString = stringifyRules(token[1]);
return asString.indexOf('__') > -1 || asString.indexOf('--') > -1;
}
}
function removeAnyUnsafeElements(left, candidates) {
- var leftSelector = withoutModifier(stringifySelectors(left[1]));
+ var leftSelector = withoutModifier(stringifyRules(left[1]));
for (var body in candidates) {
var right = candidates[body];
- var rightSelector = withoutModifier(stringifySelectors(right[1]));
+ var rightSelector = withoutModifier(stringifyRules(right[1]));
if (rightSelector.indexOf(leftSelector) > -1 || leftSelector.indexOf(rightSelector) > -1)
delete candidates[body];
}
}
-function mergeNonAdjacentByBody(tokens, options) {
- var candidates = {};
+function mergeNonAdjacentByBody(tokens, context) {
+ var options = context.options;
var adjacentSpace = options.compatibility.selectors.adjacentSpace;
+ var candidates = {};
for (var i = tokens.length - 1; i >= 0; i--) {
var token = tokens[i];
- if (token[0] != 'selector')
+ if (token[0] != Token.RULE)
continue;
- if (token[2].length > 0 && (!options.semanticMerging && unsafeSelector(stringifySelectors(token[1]))))
+ if (token[2].length > 0 && (!options.semanticMerging && unsafeSelector(stringifyRules(token[1]))))
candidates = {};
if (token[2].length > 0 && options.semanticMerging && isBemElement(token))
var candidateBody = stringifyBody(token[2]);
var oldToken = candidates[candidateBody];
- if (oldToken && !isSpecial(options, stringifySelectors(token[1])) && !isSpecial(options, stringifySelectors(oldToken[1]))) {
+ if (oldToken && !isSpecial(options, stringifyRules(token[1])) && !isSpecial(options, stringifyRules(oldToken[1]))) {
token[1] = token[2].length > 0 ?
- cleanUpSelectors(oldToken[1].concat(token[1]), false, adjacentSpace) :
+ tidyRules(oldToken[1].concat(token[1]), false, adjacentSpace) :
oldToken[1].concat(token[1]);
oldToken[2] = [];
var optimizeProperties = require('../properties/optimizer');
-var stringifySelectors = require('../stringifier/one-time').selectors;
-var extractProperties = require('./extractor');
+var stringifyRules = require('../stringifier/one-time').rules;
+var extractProperties = require('./extract-properties');
var canReorder = require('./reorderable').canReorder;
-function mergeNonAdjacentBySelector(tokens, options, context) {
+var Token = require('../tokenizer/token');
+
+function mergeNonAdjacentBySelector(tokens, context) {
var allSelectors = {};
var repeatedSelectors = [];
var i;
for (i = tokens.length - 1; i >= 0; i--) {
- if (tokens[i][0] != 'selector')
+ if (tokens[i][0] != Token.RULE)
continue;
if (tokens[i][2].length === 0)
continue;
- var selector = stringifySelectors(tokens[i][1]);
+ var selector = stringifyRules(tokens[i][1]);
allSelectors[selector] = [i].concat(allSelectors[selector] || []);
if (allSelectors[selector].length == 2)
Array.prototype.push.apply(target[2], moved[2]);
}
- optimizeProperties(target[1], target[2], joinAt, true, options, context);
+ optimizeProperties(target[1], target[2], joinAt, true, context);
moved[2] = [];
}
}
var optimizeProperties = require('../properties/optimizer');
var stringifyBody = require('../stringifier/one-time').body;
-var stringifySelectors = require('../stringifier/one-time').selectors;
+var stringifyRules = require('../stringifier/one-time').rules;
var isSpecial = require('./is-special');
var cloneArray = require('../utils/clone-array');
-function reduceNonAdjacent(tokens, options, context) {
+var Token = require('../tokenizer/token');
+
+function reduceNonAdjacent(tokens, context) {
+ var options = context.options;
var candidates = {};
var repeated = [];
for (var i = tokens.length - 1; i >= 0; i--) {
var token = tokens[i];
- if (token[0] != 'selector')
+ if (token[0] != Token.RULE) {
continue;
- if (token[2].length === 0)
+ } else if (token[2].length === 0) {
continue;
+ }
- var selectorAsString = stringifySelectors(token[1]);
+ var selectorAsString = stringifyRules(token[1]);
var isComplexAndNotSpecial = token[1].length > 1 && !isSpecial(options, selectorAsString);
- var wrappedSelectors = options.sourceMap ? wrappedSelectorsFrom(token[1]) : token[1];
+ var wrappedSelectors = wrappedSelectorsFrom(token[1]);
var selectors = isComplexAndNotSpecial ?
[selectorAsString].concat(wrappedSelectors) :
[selectorAsString];
joinsAt.push((joinsAt.length > 0 ? joinsAt[joinsAt.length - 1] : 0) + bodiesAsList[j].length);
}
- optimizeProperties(selector, bodies, joinsAt, false, options, outerContext);
+ optimizeProperties(selector, bodies, joinsAt, false, outerContext);
var processedCount = processedTokens.length;
var propertyIdx = bodies.length - 1;
--- /dev/null
+var stringifyAll = require('../stringifier/one-time').all;
+var stringifyRules = require('../stringifier/one-time').rules;
+
+var Token = require('../tokenizer/token');
+
+function removeDuplicateMediaQueries(tokens) {
+ var candidates = {};
+ var candidate;
+ var token;
+ var key;
+ var i, l;
+
+ for (i = 0, l = tokens.length; i < l; i++) {
+ token = tokens[i];
+ if (token[0] != Token.BLOCK) {
+ continue;
+ }
+
+ key = stringifyRules(token[1]) + '%' + stringifyAll(token[2]);
+ candidate = candidates[key];
+
+ if (candidate) {
+ candidate[2] = [];
+ }
+
+ candidates[key] = token;
+ }
+}
+
+module.exports = removeDuplicateMediaQueries;
var stringifyBody = require('../stringifier/one-time').body;
-var stringifySelectors = require('../stringifier/one-time').selectors;
+var stringifyRules = require('../stringifier/one-time').rules;
+
+var Token = require('../tokenizer/token');
function removeDuplicates(tokens) {
var matched = {};
for (var i = 0, l = tokens.length; i < l; i++) {
token = tokens[i];
- if (token[0] != 'selector')
+ if (token[0] != Token.RULE)
continue;
- id = stringifySelectors(token[1]);
+ id = stringifyRules(token[1]);
if (matched[id] && matched[id].length == 1)
moreThanOnce.push(id);
-var extractProperties = require('./extractor');
+var extractProperties = require('./extract-properties');
var canReorderSingle = require('./reorderable').canReorderSingle;
var stringifyBody = require('../stringifier/one-time').body;
-var stringifySelectors = require('../stringifier/one-time').selectors;
-var cleanUpSelectorDuplicates = require('./clean-up').selectorDuplicates;
+var stringifyRules = require('../stringifier/one-time').rules;
+var tidyRuleDuplicates = require('./tidy-rule-duplicates');
var isSpecial = require('./is-special');
var cloneArray = require('../utils/clone-array');
+var Token = require('../tokenizer/token');
+
function naturalSorter(a, b) {
return a > b;
}
return cloned;
}
-function restructure(tokens, options) {
+function restructure(tokens, context) {
+ var options = context.options;
var movableTokens = {};
var movedProperties = [];
var multiPropertyMoveCache = {};
function cacheId(cachedTokens) {
var id = [];
for (var i = 0, l = cachedTokens.length; i < l; i++) {
- id.push(stringifySelectors(cachedTokens[i][1]));
+ id.push(stringifyRules(cachedTokens[i][1]));
}
return id.join(ID_JOIN_CHARACTER);
}
var mergeableTokens = [];
for (var i = sourceTokens.length - 1; i >= 0; i--) {
- if (isSpecial(options, stringifySelectors(sourceTokens[i][1])))
+ if (isSpecial(options, stringifyRules(sourceTokens[i][1])))
continue;
mergeableTokens.unshift(sourceTokens[i]);
qualifiedTokens.unshift(bestFit[0][i]);
}
- allSelectors = cleanUpSelectorDuplicates(allSelectors);
+ allSelectors = tidyRuleDuplicates(allSelectors);
dropAsNewTokenAt(position, [movedProperty], allSelectors, qualifiedTokens);
}
function sizeDifference(tokensVariant, propertySize, propertiesCount) {
var allSelectorsSize = 0;
for (var i = tokensVariant.length - 1; i >= 0; i--) {
- allSelectorsSize += tokensVariant[i][2].length > propertiesCount ? stringifySelectors(tokensVariant[i][1]).length : -1;
+ allSelectorsSize += tokensVariant[i][2].length > propertiesCount ? stringifyRules(tokensVariant[i][1]).length : -1;
}
return allSelectorsSize - (tokensVariant.length - 1) * propertySize + 1;
}
for (k = 0, m = properties.length; k < m; k++) {
var property = properties[k];
- var mergeablePropertyName = mergeableProperty[0][0];
+ var mergeablePropertyName = mergeableProperty[1][1];
var propertyName = property[0];
var propertyBody = property[4];
if (mergeablePropertyName == propertyName && stringifyBody([mergeableProperty]) == propertyBody) {
allProperties.unshift(properties[i][3]);
}
- var newToken = ['selector', allSelectors, allProperties];
+ var newToken = [Token.RULE, allSelectors, allProperties];
tokens.splice(position, 0, newToken);
}
qualifiedTokens.unshift(bestFit[0][i]);
}
- allSelectors = cleanUpSelectorDuplicates(allSelectors);
+ allSelectors = tidyRuleDuplicates(allSelectors);
dropAsNewTokenAt(position, properties, allSelectors, qualifiedTokens);
for (i = properties.length - 1; i >= 0; i--) {
for (var i = tokens.length - 1; i >= 0; i--) {
var token = tokens[i];
- var isSelector;
+ var isRule;
var j, k, m;
var samePropertyAt;
- if (token[0] == 'selector') {
- isSelector = true;
- } else if (token[0] == 'block') {
- isSelector = false;
+ if (token[0] == Token.RULE) {
+ isRule = true;
+ } else if (token[0] == Token.BLOCK) {
+ isRule = false;
} else {
continue;
}
}
}
- if (!isSelector || unmovableInCurrentToken.indexOf(j) > -1)
+ if (!isRule || unmovableInCurrentToken.indexOf(j) > -1)
continue;
var key = property[4];
}
}
- var position = tokens[0] && tokens[0][0] == 'at-rule' && tokens[0][1][0].indexOf('@charset') === 0 ? 1 : 0;
+ var position = tokens[0] && tokens[0][0] == Token.AT_RULE && tokens[0][1].indexOf('@charset') === 0 ? 1 : 0;
for (; position < tokens.length - 1; position++) {
- var isImportRule = tokens[position][0] === 'at-rule' && tokens[position][1][0].indexOf('@import') === 0;
- var isEscapedCommentSpecial = tokens[position][0] === 'text' && tokens[position][1][0].indexOf('__ESCAPED_COMMENT_SPECIAL') === 0;
- if (!(isImportRule || isEscapedCommentSpecial))
+ var isImportRule = tokens[position][0] === Token.AT_RULE && tokens[position][1].indexOf('@import') === 0;
+ var isComment = tokens[position][0] === Token.COMMENT;
+ if (!(isImportRule || isComment))
break;
}
--- /dev/null
+function tidyAtRule(value) {
+ return value
+ .replace(/\s+/g, ' ')
+ .trim();
+}
+
+module.exports = tidyAtRule;
--- /dev/null
+function tidyBlock(values, spaceAfterClosingBrace) {
+ var i;
+
+ for (i = values.length - 1; i >= 0; i--) {
+ values[i][0] = values[i][0]
+ .replace(/\n|\r\n/g, ' ')
+ .replace(/\s+/g, ' ')
+ .replace(/(,|:|\() /g, '$1')
+ .replace(/ \)/g, ')')
+ .replace(/'([a-zA-Z][a-zA-Z\d\-_]+)'/, '$1')
+ .replace(/"([a-zA-Z][a-zA-Z\d\-_]+)"/, '$1')
+ .replace(spaceAfterClosingBrace ? null : /\) /g, ')');
+ }
+
+ return values;
+}
+
+module.exports = tidyBlock;
--- /dev/null
+function ruleSorter(s1, s2) {
+ return s1[0] > s2[0] ? 1 : -1;
+}
+
+function tidyRuleDuplicates(rules) {
+ var list = [];
+ var repeated = [];
+
+ for (var i = 0, l = rules.length; i < l; i++) {
+ var rule = rules[i];
+
+ if (repeated.indexOf(rule[0]) == -1) {
+ repeated.push(rule[0]);
+ list.push(rule);
+ }
+ }
+
+ return list.sort(ruleSorter);
+}
+
+module.exports = tidyRuleDuplicates;
--- /dev/null
+var Marker = require('../tokenizer/marker');
+
+var RELATION_PATTERN = /[>\+~]/;
+var WHITESPACE_PATTERN = /\s/;
+
+var STAR_PLUS_HTML_HACK = '*+html ';
+var STAR_FIRST_CHILD_PLUS_HTML_HACK = '*:first-child+html ';
+
+function removeWhitespace(value) {
+ var stripped = [];
+ var character;
+ var isNewLineNix;
+ var isNewLineWin;
+ var isEscaped;
+ var wasEscaped;
+ var isQuote;
+ var isAttribute;
+ var isRelation;
+ var isWhitespace;
+ var roundBracketLevel = 0;
+ var wasRelation = false;
+ var wasWhitespace = false;
+ var i, l;
+
+ for (i = 0, l = value.length; i < l; i++) {
+ character = value[i];
+
+ isNewLineNix = character == Marker.NEW_LINE_NIX;
+ isNewLineWin = character == Marker.NEW_LINE_NIX && value[i - 1] == Marker.NEW_LINE_WIN;
+ isRelation = !isEscaped && RELATION_PATTERN.test(character);
+ isWhitespace = WHITESPACE_PATTERN.test(character);
+
+ if (wasEscaped && isQuote && isNewLineWin) {
+ // swallow escaped new windows lines in comments
+ stripped.pop();
+ stripped.pop();
+ } else if (isEscaped && isQuote && isNewLineNix) {
+ // swallow escaped new *nix lines in comments
+ stripped.pop();
+ } else if (isEscaped) {
+ stripped.push(character);
+ } else if (character == Marker.OPEN_SQUARE_BRACKET && !isQuote) {
+ stripped.push(character);
+ isAttribute = true;
+ } else if (character == Marker.CLOSE_SQUARE_BRACKET && !isQuote) {
+ stripped.push(character);
+ isAttribute = false;
+ } else if (character == Marker.OPEN_ROUND_BRACKET && !isQuote) {
+ stripped.push(character);
+ roundBracketLevel++;
+ } else if (character == Marker.CLOSE_ROUND_BRACKET && !isQuote) {
+ stripped.push(character);
+ roundBracketLevel--;
+ } else if ((character == Marker.SINGLE_QUOTE || character == Marker.DOUBLE_QUOTE) && !isQuote) {
+ stripped.push(character);
+ isQuote = true;
+ } else if (character == Marker.SINGLE_QUOTE || character == Marker.DOUBLE_QUOTE) {
+ stripped.push(character);
+ isQuote = false;
+ } else if (isWhitespace && wasRelation) {
+ continue;
+ } else if (isWhitespace && (isAttribute || roundBracketLevel > 0) && !isQuote) {
+ // skip space
+ } else if (isWhitespace && wasWhitespace && !isQuote) {
+ // skip extra space
+ } else if ((isNewLineWin || isNewLineNix) && (isAttribute || roundBracketLevel > 0) && isQuote) {
+ // skip newline
+ } else if (isRelation && wasWhitespace) {
+ stripped.pop();
+ stripped.push(character);
+ } else if (isWhitespace) {
+ stripped.push(Marker.SPACE);
+ } else {
+ stripped.push(character);
+ }
+
+ wasEscaped = isEscaped;
+ isEscaped = character == Marker.BACK_SLASH;
+ wasRelation = isRelation;
+ wasWhitespace = isWhitespace;
+ }
+
+ return stripped.join('');
+}
+
+function removeQuotes(value) {
+ return value
+ .replace(/([^\[])'([a-zA-Z][a-zA-Z\d\-_]+)([^\]])'/g, '$1$2$3')
+ .replace(/([^\[])"([a-zA-Z][a-zA-Z\d\-_]+)([^\]])"/g, '$1$2$3');
+}
+
+function ruleSorter(s1, s2) {
+ return s1[0] > s2[0] ? 1 : -1;
+}
+
+function tidyRules(rules, removeUnsupported, adjacentSpace) {
+ var list = [];
+ var repeated = [];
+
+ for (var i = 0, l = rules.length; i < l; i++) {
+ var rule = rules[i];
+ var reduced = rule[0];
+
+ reduced = removeWhitespace(reduced);
+ reduced = removeQuotes(reduced);
+
+ if (adjacentSpace && reduced.indexOf('nav') > 0) {
+ reduced = reduced.replace(/\+nav(\S|$)/, '+ nav$1');
+ }
+
+ if (removeUnsupported && reduced.indexOf(STAR_PLUS_HTML_HACK) > -1) {
+ continue;
+ }
+
+ if (removeUnsupported && reduced.indexOf(STAR_FIRST_CHILD_PLUS_HTML_HACK) > -1) {
+ continue;
+ }
+
+ if (reduced.indexOf('*') > -1) {
+ reduced = reduced
+ .replace(/\*([:#\.\[])/g, '$1')
+ .replace(/^(\:first\-child)?\+html/, '*$1+html');
+ }
+
+ if (repeated.indexOf(reduced) > -1) {
+ continue;
+ }
+
+ rule[0] = reduced;
+ repeated.push(reduced);
+ list.push(rule);
+ }
+
+ return list.sort(ruleSorter);
+}
+
+module.exports = tidyRules;
var wrapSingle = require('./wrap-for-optimizing').single;
var InvalidPropertyError = require('./invalid-property-error');
-var split = require('../utils/split');
+var Token = require('../tokenizer/token');
+
var MULTIPLEX_SEPARATOR = ',';
function _colorFilter(validator) {
return function (value) {
- return value[0] == 'invert' || validator.isValidColor(value[0]);
+ return value[1] == 'invert' || validator.isValidColor(value[1]);
};
}
function _styleFilter(validator) {
return function (value) {
- return value[0] != 'inherit' && validator.isValidStyle(value[0]) && !validator.isValidColorValue(value[0]);
+ return value[1] != 'inherit' && validator.isValidStyle(value[1]) && !validator.isValidColorValue(value[1]);
};
}
function _wrapDefault(name, property, compactable) {
var descriptor = compactable[name];
- if (descriptor.doubleValues && descriptor.defaultValue.length == 2)
- return wrapSingle([[name, property.important], [descriptor.defaultValue[0]], [descriptor.defaultValue[1]]]);
- else if (descriptor.doubleValues && descriptor.defaultValue.length == 1)
- return wrapSingle([[name, property.important], [descriptor.defaultValue[0]]]);
- else
- return wrapSingle([[name, property.important], [descriptor.defaultValue]]);
+ if (descriptor.doubleValues && descriptor.defaultValue.length == 2) {
+ return wrapSingle([
+ Token.PROPERTY,
+ [Token.PROPERTY_NAME, name],
+ [Token.PROPERTY_VALUE, descriptor.defaultValue[0]],
+ [Token.PROPERTY_VALUE, descriptor.defaultValue[1]]
+ ]);
+ } else if (descriptor.doubleValues && descriptor.defaultValue.length == 1) {
+ return wrapSingle([
+ Token.PROPERTY,
+ [Token.PROPERTY_NAME, name],
+ [Token.PROPERTY_VALUE, descriptor.defaultValue[0]]
+ ]);
+ } else {
+ return wrapSingle([
+ Token.PROPERTY,
+ [Token.PROPERTY_NAME, name],
+ [Token.PROPERTY_VALUE, descriptor.defaultValue]
+ ]);
+ }
}
function _widthFilter(validator) {
return function (value) {
- return value[0] != 'inherit' && validator.isValidWidth(value[0]) && !validator.isValidStyleKeyword(value[0]) && !validator.isValidColorValue(value[0]);
+ return value[1] != 'inherit' && validator.isValidWidth(value[1]) && !validator.isValidStyleKeyword(value[1]) && !validator.isValidColorValue(value[1]);
};
}
var originSet = false;
var repeatSet = false;
- if (property.value.length == 1 && property.value[0][0] == 'inherit') {
+ var anyValueSet = false;
+
+ if (property.value.length == 1 && property.value[0][1] == 'inherit') {
// NOTE: 'inherit' is not a valid value for background-attachment
color.value = image.value = repeat.value = position.value = size.value = origin.value = clip.value = property.value;
return components;
}
+ if (property.value.length == 1 && property.value[0][1] == '0 0') {
+ return components;
+ }
+
for (var i = values.length - 1; i >= 0; i--) {
var value = values[i];
- if (validator.isValidBackgroundAttachment(value[0])) {
+ if (validator.isValidBackgroundAttachment(value[1])) {
attachment.value = [value];
- } else if (validator.isValidBackgroundBox(value[0])) {
+ anyValueSet = true;
+ } else if (validator.isValidBackgroundBox(value[1])) {
if (clipSet) {
origin.value = [value];
originSet = true;
clip.value = [value];
clipSet = true;
}
- } else if (validator.isValidBackgroundRepeat(value[0])) {
+ anyValueSet = true;
+ } else if (validator.isValidBackgroundRepeat(value[1])) {
if (repeatSet) {
repeat.value.unshift(value);
} else {
repeat.value = [value];
repeatSet = true;
}
- } else if (validator.isValidBackgroundPositionPart(value[0]) || validator.isValidBackgroundSizePart(value[0])) {
+ anyValueSet = true;
+ } else if (validator.isValidBackgroundPositionPart(value[1]) || validator.isValidBackgroundSizePart(value[1])) {
if (i > 0) {
var previousValue = values[i - 1];
- if (previousValue[0].indexOf('/') > 0) {
- var twoParts = split(previousValue[0], '/');
- // NOTE: we do this slicing as value may contain metadata too, like for source maps
- size.value = [[twoParts.pop()].concat(previousValue.slice(1)), value];
- values[i - 1] = [twoParts.pop()].concat(previousValue.slice(1));
- } else if (i > 1 && values[i - 2][0] == '/') {
+ if (previousValue[1] == '/') {
+ size.value = [value];
+ } else if (i > 1 && values[i - 2][1] == '/') {
size.value = [previousValue, value];
i -= 2;
- } else if (previousValue[0] == '/') {
- size.value = [value];
} else {
if (!positionSet)
position.value = [];
position.value.unshift(value);
positionSet = true;
}
- } else if (validator.isValidBackgroundPositionAndSize(value[0])) {
- var sizeValue = split(value[0], '/');
- // NOTE: we do this slicing as value may contain metadata too, like for source maps
- size.value = [[sizeValue.pop()].concat(value.slice(1))];
- position.value = [[sizeValue.pop()].concat(value.slice(1))];
- } else if ((color.value[0][0] == compactable[color.name].defaultValue || color.value[0][0] == 'none') && validator.isValidColor(value[0])) {
+ anyValueSet = true;
+ } else if ((color.value[0][1] == compactable[color.name].defaultValue || color.value[0][1] == 'none') && validator.isValidColor(value[1])) {
color.value = [value];
- } else if (validator.isValidUrl(value[0]) || validator.isValidFunction(value[0])) {
+ anyValueSet = true;
+ } else if (validator.isValidUrl(value[1]) || validator.isValidFunction(value[1])) {
image.value = [value];
+ anyValueSet = true;
}
}
if (clipSet && !originSet)
origin.value = clip.value.slice(0);
+ if (!anyValueSet) {
+ throw new InvalidPropertyError('Invalid background value.');
+ }
+
return components;
}
var splitAt = -1;
for (var i = 0, l = values.length; i < l; i++) {
- if (values[i][0] == '/') {
+ if (values[i][1] == '/') {
splitAt = i;
break;
}
value[3] = value[1].slice(0);
for (var i = componentNames.length - 1; i >= 0; i--) {
- var component = wrapSingle([[componentNames[i], property.important]]);
+ var component = wrapSingle([
+ Token.PROPERTY,
+ [Token.PROPERTY_NAME, componentNames[i]]
+ ]);
component.value = [value[i]];
components.unshift(component);
}
// find split commas
for (i = 0, l = values.length; i < l; i++) {
- if (values[i][0] == ',')
+ if (values[i][1] == ',')
splitsAt.push(i);
}
components[i].multiplex = true;
for (j = 1, m = splitComponents.length; j < m; j++) {
- components[i].value.push([MULTIPLEX_SEPARATOR]);
+ components[i].value.push([Token.PROPERTY_VALUE, MULTIPLEX_SEPARATOR]);
Array.prototype.push.apply(components[i].value, splitComponents[j][i].value);
}
}
var image = _wrapDefault('list-style-image', property, compactable);
var components = [type, position, image];
- if (property.value.length == 1 && property.value[0][0] == 'inherit') {
+ if (property.value.length == 1 && property.value[0][1] == 'inherit') {
type.value = position.value = image.value = [property.value[0]];
return components;
}
// `image` first...
for (index = 0, total = values.length; index < total; index++) {
- if (validator.isValidUrl(values[index][0]) || values[index][0] == '0') {
+ if (validator.isValidUrl(values[index][1]) || values[index][1] == '0') {
image.value = [values[index]];
values.splice(index, 1);
break;
// ... then `type`...
for (index = 0, total = values.length; index < total; index++) {
- if (validator.isValidListStyleType(values[index][0])) {
+ if (validator.isValidListStyleType(values[index][1])) {
type.value = [values[index]];
values.splice(index, 1);
break;
}
// ... and what's left is a `position`
- if (values.length > 0 && validator.isValidListStylePosition(values[0][0]))
+ if (values.length > 0 && validator.isValidListStylePosition(values[0][1]))
position.value = [values[0]];
return components;
width = component;
}
- if ((property.value.length == 1 && property.value[0][0] == 'inherit') ||
- (property.value.length == 3 && property.value[0][0] == 'inherit' && property.value[1][0] == 'inherit' && property.value[2][0] == 'inherit')) {
+ if ((property.value.length == 1 && property.value[0][1] == 'inherit') ||
+ (property.value.length == 3 && property.value[0][1] == 'inherit' && property.value[1][1] == 'inherit' && property.value[2][1] == 'inherit')) {
color.value = style.value = width.value = [property.value[0]];
return components;
}
if (values.length > 0) {
matches = values.filter(_widthFilter(validator));
- match = matches.length > 1 && (matches[0][0] == 'none' || matches[0][0] == 'auto') ? matches[1] : matches[0];
+ match = matches.length > 1 && (matches[0][1] == 'none' || matches[0][1] == 'auto') ? matches[1] : matches[0];
if (match) {
width.value = [match];
values.splice(values.indexOf(match), 1);
}
function alwaysButIntoFunction(property1, property2, validator) {
- var value1 = property1.value[0][0];
- var value2 = property2.value[0][0];
+ var value1 = property1.value[0][1];
+ var value2 = property2.value[0][1];
var validFunction1 = validator.isValidFunction(value1);
var validFunction2 = validator.isValidFunction(value2);
// Understandability: (none | url | inherit) > (same function) > (same value)
// (none | url)
- var image1 = property1.value[0][0];
- var image2 = property2.value[0][0];
+ var image1 = property1.value[0][1];
+ var image2 = property2.value[0][1];
if (image2 == 'none' || image2 == 'inherit' || validator.isValidUrl(image2))
return true;
// Understandability: (hex | named) > (rgba | hsla) > (same function name) > anything else
// NOTE: at this point rgb and hsl are replaced by hex values by clean-css
- var color1 = property1.value[0][0];
- var color2 = property2.value[0][0];
+ var color1 = property1.value[0][1];
+ var color2 = property2.value[0][1];
if (!validator.colorOpacity && (validator.isValidRgbaColor(color1) || validator.isValidHslaColor(color1)))
return false;
}
function twoOptionalFunctions(property1, property2, validator) {
- var value1 = property1.value[0][0];
- var value2 = property2.value[0][0];
+ var value1 = property1.value[0][1];
+ var value2 = property2.value[0][1];
return !(validator.isValidFunction(value1) ^ validator.isValidFunction(value2));
}
function sameValue(property1, property2) {
- var value1 = property1.value[0][0];
- var value2 = property2.value[0][0];
+ var value1 = property1.value[0][1];
+ var value2 = property2.value[0][1];
return value1 === value2;
}
function sameFunctionOrValue(property1, property2, validator) {
- var value1 = property1.value[0][0];
- var value2 = property2.value[0][0];
+ var value1 = property1.value[0][1];
+ var value2 = property2.value[0][1];
// Functions with the same name can override each other
if (validator.areSameFunction(value1, value2))
// NOTE: there is no point in having different vendor-specific functions override each other or standard functions,
// or having standard functions override vendor-specific functions, but standard functions can override each other
// NOTE: vendor-specific property values are not taken into consideration here at the moment
- var value1 = property1.value[0][0];
- var value2 = property2.value[0][0];
+ var value1 = property1.value[0][1];
+ var value2 = property2.value[0][1];
if (validator.isValidAndCompatibleUnitWithoutFunction(value1) && !validator.isValidAndCompatibleUnitWithoutFunction(value2))
return false;
var wrapSingle = require('./wrap-for-optimizing').single;
+var Token = require('../tokenizer/token');
function deep(property) {
var cloned = shallow(property);
}
function shallow(property) {
- var cloned = wrapSingle([[property.name, property.important, property.hack]]);
+ var cloned = wrapSingle([
+ Token.PROPERTY,
+ [Token.PROPERTY_NAME, property.name]
+ ]);
+ cloned.important = property.important;
+ cloned.hack = property.hack;
cloned.unused = false;
return cloned;
}
var shallowClone = require('./clone').shallow;
-var MULTIPLEX_SEPARATOR = ',';
+var Marker = require('../tokenizer/marker');
function everyCombination(fn, left, right, validator) {
var samePositon = !left.shorthand && !right.shorthand && !left.multiplex && !right.multiplex;
for (var i = 0, l = left.value.length; i < l; i++) {
for (var j = 0, m = right.value.length; j < m; j++) {
- if (left.value[i][0] == MULTIPLEX_SEPARATOR || right.value[j][0] == MULTIPLEX_SEPARATOR)
+ if (left.value[i][1] == Marker.COMMA || right.value[j][1] == Marker.COMMA)
continue;
if (samePositon && i != j)
--- /dev/null
+var Hack = {
+ BANG: 'bang',
+ BACKSLASH: 'backslash',
+ STAR: 'star',
+ UNDERSCORE: 'underscore'
+};
+
+module.exports = Hack;
function hasInherit(property) {
for (var i = property.value.length - 1; i >= 0; i--) {
- if (property.value[i][0] == 'inherit')
+ if (property.value[i][1] == 'inherit')
return true;
}
}
}
-function optimize(selector, properties, mergeAdjacent, withCompacting, options, context) {
+function optimize(selector, properties, mergeAdjacent, withCompacting, context) {
var validator = context.validator;
var warnings = context.warnings;
var _properties = wrapForOptimizing(properties);
populateComponents(_properties, validator, warnings);
- _optimize(_properties, mergeAdjacent, options.aggressiveMerging, validator);
+ _optimize(_properties, mergeAdjacent, context.options.aggressiveMerging, validator);
for (var i = 0, l = _properties.length; i < l; i++) {
var _property = _properties[i];
- if (_property.variable && _property.block)
- optimize(selector, _property.value[0], mergeAdjacent, withCompacting, options, context);
+ if (_property.block) {
+ optimize(selector, _property.value[0][1], mergeAdjacent, withCompacting, context);
+ }
}
- if (withCompacting && options.shorthandCompacting) {
- compactOverrides(_properties, options.compatibility, validator);
- compactShorthands(_properties, options.sourceMap, validator);
+ if (withCompacting && context.options.shorthandCompacting) {
+ compactOverrides(_properties, context.options.compatibility, validator);
+ compactShorthands(_properties, validator);
}
restoreFromOptimizing(_properties);
var stringifyProperty = require('../stringifier/one-time').property;
-var MULTIPLEX_SEPARATOR = ',';
+var Token = require('../tokenizer/token');
+var Marker = require('../tokenizer/marker');
// Used when searching for a component that matches property
function nameMatchFilter(to) {
var canOverride = descriptor && descriptor.canOverride || canOverride.sameValue;
var _component = shallowClone(component);
- _component.value = [[descriptor.defaultValue]];
+ _component.value = [[Token.PROPERTY_VALUE, descriptor.defaultValue]];
if (!canOverride(_component, component, validator))
return true;
var value = component.value.slice(0);
for (var j = 1; j < size; j++) {
- component.value.push([MULTIPLEX_SEPARATOR]);
+ component.value.push([Token.PROPERTY_VALUE, Marker.COMMA]);
Array.prototype.push.apply(component.value, value);
}
}
var size = 0;
for (var i = 0, l = component.value.length; i < l; i++) {
- if (component.value[i][0] == MULTIPLEX_SEPARATOR)
+ if (component.value[i][1] == Marker.COMMA)
size++;
}
}
function lengthOf(property) {
- var fakeAsArray = [[property.name]].concat(property.value);
+ var fakeAsArray = [
+ Token.PROPERTY,
+ [Token.PROPERTY_NAME, property.name]
+ ].concat(property.value);
return stringifyProperty([fakeAsArray], 0).length;
}
function anyValue(fn, property) {
for (var i = 0, l = property.value.length; i < l; i++) {
- if (property.value[i][0] == MULTIPLEX_SEPARATOR)
+ if (property.value[i][1] == Marker.COMMA)
continue;
- if (fn(property.value[i][0]))
+ if (fn(property.value[i][1]))
return true;
}
var lengthAfter = lengthOf(simpleClone);
- return lengthBefore < lengthAfter;
+ return lengthBefore <= lengthAfter;
}
function isCompactable(property) {
var layers = intoLayers(values);
for (var i = 0, l = layers.length; i < l; i++) {
- if (layers[i].length == 1 && layers[i][0][0] == 'none')
+ if (layers[i].length == 1 && layers[i][0][1] == 'none')
return true;
}
for (var i = 0, layer = [], l = values.length; i < l; i++) {
var value = values[i];
- if (value[0] == MULTIPLEX_SEPARATOR) {
+ if (value[1] == Marker.COMMA) {
layers.push(layer);
layer = [];
} else {
if (!isCompactable(right))
continue;
- if (right.variable)
+ if (right.block)
continue;
mayOverride = compactable[right.name].canOverride || canOverride.sameValue;
if (!isCompactable(left))
continue;
- if (left.variable)
+ if (left.block)
continue;
if (left.unused || right.unused)
!compatibility.properties.backgroundClipMerging && component.name.indexOf('background-clip') > -1 ||
!compatibility.properties.backgroundOriginMerging && component.name.indexOf('background-origin') > -1 ||
!compatibility.properties.backgroundSizeMerging && component.name.indexOf('background-size') > -1;
- var nonMergeableValue = compactable[right.name].nonMergeableValue === right.value[0][0];
+ var nonMergeableValue = compactable[right.name].nonMergeableValue === right.value[0][1];
if (disabledBackgroundMerging || nonMergeableValue)
continue;
if (!compatibility.properties.merging && wouldBreakCompatibility(left, validator))
continue;
- if (component.value[0][0] != right.value[0][0] && (hasInherit(left) || hasInherit(right)))
+ if (component.value[0][1] != right.value[0][1] && (hasInherit(left) || hasInherit(right)))
continue;
if (wouldResultInLongerValue(left, right))
for (var i = properties.length - 1; i >= 0; i--) {
var property = properties[i];
- if (property.unused)
+ if (property.unused) {
property.all.splice(property.position, 1);
+ }
}
}
+var Hack = require('./hack');
+var Marker = require('../tokenizer/marker');
var compactable = require('./compactable');
var BACKSLASH_HACK = '\\9';
var UNDERSCORE_HACK = '_';
var BANG_HACK = '!ie';
-function restoreImportant(property) {
- property.value[property.value.length - 1][0] += IMPORTANT_TOKEN;
-}
-
-function restoreHack(property) {
- if (property.hack == 'underscore')
- property.name = UNDERSCORE_HACK + property.name;
- else if (property.hack == 'star')
- property.name = STAR_HACK + property.name;
- else if (property.hack == 'backslash')
- property.value[property.value.length - 1][0] += BACKSLASH_HACK;
- else if (property.hack == 'bang')
- property.value[property.value.length - 1][0] += ' ' + BANG_HACK;
-}
-
function restoreFromOptimizing(properties, simpleMode) {
- for (var i = properties.length - 1; i >= 0; i--) {
- var property = properties[i];
- var descriptor = compactable[property.name];
- var restored;
+ var property;
+ var descriptor;
+ var restored;
+ var current;
+ var i;
+
+ for (i = properties.length - 1; i >= 0; i--) {
+ property = properties[i];
+ descriptor = compactable[property.name];
- if (property.unused)
+ if (property.unused) {
continue;
+ }
- if (!property.dirty && !property.important && !property.hack)
+ if (!property.dirty && !property.important && !property.hack) {
continue;
+ }
if (!simpleMode && descriptor && descriptor.shorthand) {
restored = descriptor.restore(property, compactable);
restored = property.value;
}
- if (property.important)
+ if (property.important) {
restoreImportant(property);
+ }
- if (property.hack)
+ if (property.hack) {
restoreHack(property);
+ }
- if (!('all' in property))
- continue;
+ if ('all' in property) {
+ current = property.all[property.position];
+ current[1][1] = property.name;
- var current = property.all[property.position];
- current[0][0] = property.name;
+ current.splice(2, current.length - 1);
+ Array.prototype.push.apply(current, restored);
+ }
+ }
+}
- current.splice(1, current.length - 1);
- Array.prototype.push.apply(current, restored);
+function restoreImportant(property) {
+ property.value[property.value.length - 1][1] += IMPORTANT_TOKEN;
+}
+
+function restoreHack(property) {
+ if (property.hack == Hack.UNDERSCORE) {
+ property.name = UNDERSCORE_HACK + property.name;
+ } else if (property.hack == Hack.STAR) {
+ property.name = STAR_HACK + property.name;
+ } else if (property.hack == Hack.BACKSLASH) {
+ property.value[property.value.length - 1][1] += BACKSLASH_HACK;
+ } else if (property.hack == Hack.BANG) {
+ property.value[property.value.length - 1][1] += Marker.SPACE + BANG_HACK;
}
}
var shallowClone = require('./clone').shallow;
-var MULTIPLEX_SEPARATOR = ',';
-var SIZE_POSITION_SEPARATOR = '/';
+var Token = require('../tokenizer/token');
+var Marker = require('../tokenizer/marker');
function isInheritOnly(values) {
for (var i = 0, l = values.length; i < l; i++) {
- var value = values[i][0];
+ var value = values[i][1];
- if (value != 'inherit' && value != MULTIPLEX_SEPARATOR && value != SIZE_POSITION_SEPARATOR)
+ if (value != 'inherit' && value != Marker.COMMA && value != Marker.FORWARD_SLASH)
return false;
}
function isDefaultValue(component) {
var descriptor = compactable[component.name];
- if (descriptor.doubleValues) {
- if (descriptor.defaultValue.length == 1)
- return component.value[0][0] == descriptor.defaultValue[0] && (component.value[1] ? component.value[1][0] == descriptor.defaultValue[0] : true);
- else
- return component.value[0][0] == descriptor.defaultValue[0] && (component.value[1] ? component.value[1][0] : component.value[0][0]) == descriptor.defaultValue[1];
+
+ if (descriptor.doubleValues && descriptor.defaultValue.length == 1) {
+ return component.value[0][1] == descriptor.defaultValue[0] && (component.value[1] ? component.value[1][1] == descriptor.defaultValue[0] : true);
+ } else if (descriptor.doubleValues && descriptor.defaultValue.length != 1) {
+ return component.value[0][1] == descriptor.defaultValue[0] && (component.value[1] ? component.value[1][1] : component.value[0][1]) == descriptor.defaultValue[1];
} else {
- return component.value[0][0] == descriptor.defaultValue;
+ return component.value[0][1] == descriptor.defaultValue;
}
}
var originComponent = components[i - 1];
var isOriginDefault = isDefaultValue(originComponent);
- needsOne = component.value[0][0] == originComponent.value[0][0];
+ needsOne = component.value[0][1] == originComponent.value[0][1];
needsBoth = !needsOne && (
(isOriginDefault && !isDefault) ||
(!isOriginDefault && !isDefault) ||
- (!isOriginDefault && isDefault && component.value[0][0] != originComponent.value[0][0]));
+ (!isOriginDefault && isDefault && component.value[0][1] != originComponent.value[0][1]));
if (needsOne) {
restoreValue(originComponent);
restoreValue(positionComponent);
} else if (needsBoth) {
restoreValue(component);
- restored.unshift([SIZE_POSITION_SEPARATOR]);
+ restored.unshift([Token.PROPERTY_VALUE, Marker.FORWARD_SLASH]);
restoreValue(positionComponent);
} else if (positionComponent.value.length == 1) {
restoreValue(positionComponent);
}
}
- if (restored.length === 0 && property.value.length == 1 && property.value[0][0] == '0')
+ if (restored.length === 0 && property.value.length == 1 && property.value[0][1] == '0')
restored.push(property.value[0]);
if (restored.length === 0)
- restored.push([compactable[property.name].defaultValue]);
+ restored.push([Token.PROPERTY_VALUE, compactable[property.name].defaultValue]);
if (isInheritOnly(restored))
return [restored[0]];
var verticalValues = fourValues(vertical, compactable);
if (horizontalValues.length == verticalValues.length &&
- horizontalValues[0][0] == verticalValues[0][0] &&
- (horizontalValues.length > 1 ? horizontalValues[1][0] == verticalValues[1][0] : true) &&
- (horizontalValues.length > 2 ? horizontalValues[2][0] == verticalValues[2][0] : true) &&
- (horizontalValues.length > 3 ? horizontalValues[3][0] == verticalValues[3][0] : true)) {
+ horizontalValues[0][1] == verticalValues[0][1] &&
+ (horizontalValues.length > 1 ? horizontalValues[1][1] == verticalValues[1][1] : true) &&
+ (horizontalValues.length > 2 ? horizontalValues[2][1] == verticalValues[2][1] : true) &&
+ (horizontalValues.length > 3 ? horizontalValues[3][1] == verticalValues[3][1] : true)) {
return horizontalValues;
} else {
- return horizontalValues.concat([['/']]).concat(verticalValues);
+ return horizontalValues.concat([[Token.PROPERTY_VALUE, Marker.FORWARD_SLASH]]).concat(verticalValues);
}
} else {
return fourValues(property, compactable);
var value3 = components[2].value[0];
var value4 = components[3].value[0];
- if (value1[0] == value2[0] && value1[0] == value3[0] && value1[0] == value4[0]) {
+ if (value1[1] == value2[1] && value1[1] == value3[1] && value1[1] == value4[1]) {
return [value1];
- } else if (value1[0] == value3[0] && value2[0] == value4[0]) {
+ } else if (value1[1] == value3[1] && value2[1] == value4[1]) {
return [value1, value2];
- } else if (value2[0] == value4[0]) {
+ } else if (value2[1] == value4[1]) {
return [value1, value2, value3];
} else {
return [value1, value2, value3, value4];
// At this point we don't know what's the multiplex size, e.g. how many background layers are there
for (i = 0, l = property.components[0].value.length; i < l; i++) {
- if (property.components[0].value[i][0] == MULTIPLEX_SEPARATOR)
+ if (property.components[0].value[i][1] == Marker.COMMA)
multiplexSize++;
}
// The trick is some properties has more than one value, so we iterate over values looking for
// a multiplex separator - a comma
for (var k = componentMultiplexSoFar[_component.name] || 0, n = componentToClone.value.length; k < n; k++) {
- if (componentToClone.value[k][0] == MULTIPLEX_SEPARATOR) {
+ if (componentToClone.value[k][1] == Marker.COMMA) {
componentMultiplexSoFar[_component.name] = k + 1;
break;
}
Array.prototype.push.apply(restored, _restored);
if (i < multiplexSize)
- restored.push([',']);
+ restored.push([Token.PROPERTY_VALUE, Marker.COMMA]);
}
return restored;
var component = components[i];
var descriptor = compactable[component.name];
- if (component.value[0][0] != descriptor.defaultValue)
+ if (component.value[0][1] != descriptor.defaultValue)
restored.unshift(component.value[0]);
}
if (restored.length === 0)
- restored.push([compactable[property.name].defaultValue]);
+ restored.push([Token.PROPERTY_VALUE, compactable[property.name].defaultValue]);
if (isInheritOnly(restored))
return [restored[0]];
var wrapSingle = require('./wrap-for-optimizing').single;
var everyCombination = require('./every-combination');
+var Token = require('../tokenizer/token');
+
function mixedImportance(components) {
var important;
return sourceMapping;
}
-function replaceWithShorthand(properties, candidateComponents, name, sourceMaps, validator) {
+function replaceWithShorthand(properties, candidateComponents, name, validator) {
var descriptor = compactable[name];
- var newValuePlaceholder = [[name], [descriptor.defaultValue]];
+ var newValuePlaceholder = [
+ Token.PROPERTY,
+ [Token.PROPERTY_NAME, name],
+ [Token.PROPERTY_VALUE, descriptor.defaultValue]
+ ];
var all;
var newProperty = wrapSingle(newValuePlaceholder);
candidateComponents[componentName].unused = true;
}
- if (sourceMaps) {
- var sourceMapping = componentSourceMaps(candidateComponents);
- if (sourceMapping.length > 0)
- newValuePlaceholder[0].push(sourceMapping);
- }
+ // var sourceMapping = componentSourceMaps(candidateComponents);
+ // if (sourceMapping.length > 0)
+ // newValuePlaceholder[0].push(sourceMapping);
+ // }
newProperty.position = all.length;
newProperty.all = all;
properties.push(newProperty);
}
-function invalidateOrCompact(properties, position, candidates, sourceMaps, validator) {
+function invalidateOrCompact(properties, position, candidates, validator) {
var property = properties[position];
for (var name in candidates) {
if (mixedImportance(candidateComponents))
continue;
- replaceWithShorthand(properties, candidateComponents, name, sourceMaps, validator);
+ replaceWithShorthand(properties, candidateComponents, name, validator);
}
}
-function compactShortands(properties, sourceMaps, validator) {
+function compactShortands(properties, validator) {
var candidates = {};
if (properties.length < 3)
if (property.hack)
continue;
- if (property.variable)
+ if (property.block)
continue;
var descriptor = compactable[property.name];
continue;
if (property.shorthand) {
- invalidateOrCompact(properties, i, candidates, sourceMaps, validator);
+ invalidateOrCompact(properties, i, candidates, validator);
} else {
var componentOf = descriptor.componentOf;
candidates[componentOf] = candidates[componentOf] || {};
}
}
- invalidateOrCompact(properties, i, candidates, sourceMaps, validator);
+ invalidateOrCompact(properties, i, candidates, validator);
}
module.exports = compactShortands;
// Validates various CSS property values
-var split = require('../utils/split');
-
var widthKeywords = ['thin', 'thick', 'medium', 'inherit', 'initial'];
var allUnits = ['px', '%', 'em', 'in', 'cm', 'mm', 'ex', 'pt', 'pc', 'ch', 'rem', 'vh', 'vm', 'vmin', 'vmax', 'vw'];
var cssUnitRegexStr = '(\\-?\\.?\\d+\\.?\\d*(' + allUnits.join('|') + '|)|auto|inherit)';
var cssUnitOrCalcRegex = new RegExp('^' + cssUnitOrCalcRegexStr + '$', 'i');
var cssUnitAnyRegex = new RegExp('^' + cssUnitAnyRegexStr + '$', 'i');
+var urlRegex = /^url\([\s\S]+\)$/i;
+
var backgroundRepeatKeywords = ['repeat', 'no-repeat', 'repeat-x', 'repeat-y', 'inherit'];
var backgroundAttachmentKeywords = ['inherit', 'scroll', 'fixed', 'local'];
var backgroundPositionKeywords = ['center', 'top', 'bottom', 'left', 'right'];
};
Validator.prototype.isValidUrl = function (s) {
- // NOTE: at this point all URLs are replaced with placeholders by clean-css, so we check for those placeholders
- return s.indexOf('__ESCAPED_URL_CLEAN_CSS') === 0;
+ return urlRegex.test(s);
};
Validator.prototype.isValidUnit = function (s) {
};
Validator.prototype.isValidFunctionWithoutVendorPrefix = function (s) {
- return cssFunctionNoVendorRegex.test(s);
+ return !urlRegex.test(s) && cssFunctionNoVendorRegex.test(s);
};
Validator.prototype.isValidFunctionWithVendorPrefix = function (s) {
- return cssFunctionVendorRegex.test(s);
+ return !urlRegex.test(s) && cssFunctionVendorRegex.test(s);
};
Validator.prototype.isValidFunction = function (s) {
- return cssFunctionAnyRegex.test(s);
+ return !urlRegex.test(s) && cssFunctionAnyRegex.test(s);
};
Validator.prototype.isValidBackgroundRepeat = function (s) {
return backgroundSizeKeywords.indexOf(s) >= 0 || cssUnitRegex.test(s) || this.isValidVariable(s);
};
-Validator.prototype.isValidBackgroundPositionAndSize = function (s) {
- if (s.indexOf('/') < 0)
- return false;
-
- var twoParts = split(s, '/');
- return this.isValidBackgroundSizePart(twoParts.pop()) && this.isValidBackgroundPositionPart(twoParts.pop());
-};
-
Validator.prototype.isValidListStyleType = function (s) {
return listStyleTypeKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
};
-var BACKSLASH_HACK = '\\';
-var IMPORTANT_WORD = 'important';
-var IMPORTANT_TOKEN = '!'+IMPORTANT_WORD;
-var IMPORTANT_WORD_MATCH = new RegExp(IMPORTANT_WORD+'$', 'i');
-var IMPORTANT_TOKEN_MATCH = new RegExp(IMPORTANT_TOKEN+'$', 'i');
-var STAR_HACK = '*';
-var UNDERSCORE_HACK = '_';
-var BANG_HACK = '!';
+var Hack = require('./hack');
+var Marker = require('../tokenizer/marker');
+var Token = require('../tokenizer/token');
+
+var Match = {
+ BACKSLASH: '\\',
+ BANG: '!',
+ BANG_SUFFIX_PATTERN: /!\w+$/,
+ IMPORTANT_TOKEN: '!important',
+ IMPORTANT_TOKEN_PATTERN: new RegExp('!important$', 'i'),
+ IMPORTANT_WORD: 'important',
+ IMPORTANT_WORD_PATTERN: new RegExp('important$', 'i'),
+ STAR: '*',
+ SUFFIX_BANG_PATTERN: /!$/,
+ UNDERSCORE: '_'
+};
function wrapAll(properties) {
var wrapped = [];
+ var single;
+ var i;
- for (var i = properties.length - 1; i >= 0; i--) {
- if (typeof properties[i][0] == 'string')
+ for (i = properties.length - 1; i >= 0; i--) {
+ if (properties[i][0] != Token.PROPERTY) {
continue;
+ }
- var single = wrapSingle(properties[i]);
+ single = wrapSingle(properties[i]);
single.all = properties;
single.position = i;
wrapped.unshift(single);
}
function isMultiplex(property) {
- for (var i = 1, l = property.length; i < l; i++) {
- if (property[i][0] == ',' || property[i][0] == '/')
+ var value;
+ var i, l;
+
+ for (i = 3, l = property.length; i < l; i++) {
+ value = property[i];
+
+ if (value[0] == Token.PROPERTY_VALUE && (value[1] == Marker.COMMA || value[1] == Marker.FORWARD_SLASH)) {
return true;
+ }
}
return false;
function hackType(property) {
var type = false;
- var name = property[0][0];
+ var name = property[1][1];
var lastValue = property[property.length - 1];
- if (name[0] == UNDERSCORE_HACK) {
- type = 'underscore';
- } else if (name[0] == STAR_HACK) {
- type = 'star';
- } else if (lastValue[0][0] == BANG_HACK && !lastValue[0].match(IMPORTANT_WORD_MATCH)) {
- type = 'bang';
- } else if (lastValue[0].indexOf(BANG_HACK) > 0 && !lastValue[0].match(IMPORTANT_WORD_MATCH)) {
- type = 'bang';
- } else if (lastValue[0].indexOf(BACKSLASH_HACK) > 0 && lastValue[0].indexOf(BACKSLASH_HACK) == lastValue[0].length - BACKSLASH_HACK.length - 1) {
- type = 'backslash';
- } else if (lastValue[0].indexOf(BACKSLASH_HACK) === 0 && lastValue[0].length == 2) {
- type = 'backslash';
+ if (name[0] == Match.UNDERSCORE) {
+ type = Hack.UNDERSCORE;
+ } else if (name[0] == Match.STAR) {
+ type = Hack.STAR;
+ } else if (lastValue[1][0] == Match.BANG && !lastValue[1].match(Match.IMPORTANT_WORD_PATTERN)) {
+ type = Hack.BANG;
+ } else if (lastValue[1].indexOf(Match.BANG) > 0 && !lastValue[1].match(Match.IMPORTANT_WORD_PATTERN) && Match.BANG_SUFFIX_PATTERN.test(lastValue[1])) {
+ type = Hack.BANG;
+ } else if (lastValue[1].indexOf(Match.BACKSLASH) > 0 && lastValue[1].indexOf(Match.BACKSLASH) == lastValue[1].length - Match.BACKSLASH.length - 1) {
+ type = Hack.BACKSLASH;
+ } else if (lastValue[1].indexOf(Match.BACKSLASH) === 0 && lastValue[1].length == 2) {
+ type = Hack.BACKSLASH;
}
return type;
}
function isImportant(property) {
- if (property.length > 1) {
- var p = property[property.length - 1][0];
- if (typeof(p) === 'string') {
- return IMPORTANT_TOKEN_MATCH.test(p);
- }
+ if (property.length < 3)
+ return false;
+
+ var lastValue = property[property.length - 1];
+ if (Match.IMPORTANT_TOKEN_PATTERN.test(lastValue[1])) {
+ return true;
+ } else if (Match.IMPORTANT_WORD_PATTERN.test(lastValue[1]) && Match.SUFFIX_BANG_PATTERN.test(property[property.length - 2][1])) {
+ return true;
}
+
return false;
}
function stripImportant(property) {
- if (property.length > 0)
- property[property.length - 1][0] = property[property.length - 1][0].replace(IMPORTANT_TOKEN_MATCH, '');
+ var lastValue = property[property.length - 1];
+ var oneButLastValue = property[property.length - 2];
+
+ if (Match.IMPORTANT_TOKEN_PATTERN.test(lastValue[1])) {
+ lastValue[1] = lastValue[1].replace(Match.IMPORTANT_TOKEN_PATTERN, '');
+ } else {
+ lastValue[1] = lastValue[1].replace(Match.IMPORTANT_WORD_PATTERN, '');
+ oneButLastValue[1] = oneButLastValue[1].replace(Match.SUFFIX_BANG_PATTERN, '');
+ }
+
+ if (lastValue[1].length === 0) {
+ property.pop();
+ }
+
+ if (oneButLastValue[1].length === 0) {
+ property.pop();
+ }
}
function stripPrefixHack(property) {
- property[0][0] = property[0][0].substring(1);
+ property[1][1] = property[1][1].substring(1);
}
function stripSuffixHack(property, hackType) {
var lastValue = property[property.length - 1];
- lastValue[0] = lastValue[0]
- .substring(0, lastValue[0].indexOf(hackType == 'backslash' ? BACKSLASH_HACK : BANG_HACK))
+ lastValue[1] = lastValue[1]
+ .substring(0, lastValue[1].indexOf(hackType == Hack.BACKSLASH ? Match.BACKSLASH : Match.BANG))
.trim();
- if (lastValue[0].length === 0)
+ if (lastValue[1].length === 0) {
property.pop();
+ }
}
function wrapSingle(property) {
- var _isImportant = isImportant(property);
- if (_isImportant)
+ var importantProperty = isImportant(property);
+ if (importantProperty) {
stripImportant(property);
+ }
- var _hackType = hackType(property);
- if (_hackType == 'star' || _hackType == 'underscore')
+ var hackProperty = hackType(property);
+ if (hackProperty == Hack.STAR || hackProperty == Hack.UNDERSCORE) {
stripPrefixHack(property);
- else if (_hackType == 'backslash' || _hackType == 'bang')
- stripSuffixHack(property, _hackType);
-
- var isVariable = property[0][0].indexOf('--') === 0;
+ } else if (hackProperty == Hack.BACKSLASH || hackProperty == Hack.BANG) {
+ stripSuffixHack(property, hackProperty);
+ }
return {
- block: isVariable && property[1] && Array.isArray(property[1][0][0]),
+ block: property[2] && property[2][0] == Token.PROPERTY_BLOCK,
components: [],
dirty: false,
- hack: _hackType,
- important: _isImportant,
- name: property[0][0],
- multiplex: property.length > 2 ? isMultiplex(property) : false,
+ hack: hackProperty,
+ important: importantProperty,
+ name: property[1][1],
+ multiplex: property.length > 3 ? isMultiplex(property) : false,
position: 0,
shorthand: false,
- unused: property.length < 2,
- value: property.slice(1),
- variable: isVariable
+ unused: false,
+ value: property.slice(2)
};
}
+++ /dev/null
-function removeWhitespace(match, value) {
- return '[' + value.replace(/ /g, '') + ']';
-}
-
-function selectorSorter(s1, s2) {
- return s1[0] > s2[0] ? 1 : -1;
-}
-
-function whitespaceReplacements(_, p1, p2, p3) {
- if (p1 && p2 && p3.length)
- return p1 + p2 + ' ';
- else if (p1 && p2)
- return p1 + p2;
- else
- return p2;
-}
-
-var CleanUp = {
- selectors: function (selectors, removeUnsupported, adjacentSpace) {
- var list = [];
- var repeated = [];
-
- for (var i = 0, l = selectors.length; i < l; i++) {
- var selector = selectors[i];
- var reduced = selector[0]
- .replace(/\s+/g, ' ')
- .replace(/ ?, ?/g, ',')
- .replace(/\s*(\\)?([>+~])(\s*)/g, whitespaceReplacements)
- .trim();
-
- if (adjacentSpace && reduced.indexOf('nav') > 0)
- reduced = reduced.replace(/\+nav(\S|$)/, '+ nav$1');
-
- if (removeUnsupported && (reduced.indexOf('*+html ') != -1 || reduced.indexOf('*:first-child+html ') != -1))
- continue;
-
- if (reduced.indexOf('*') > -1) {
- reduced = reduced
- .replace(/\*([:#\.\[])/g, '$1')
- .replace(/^(\:first\-child)?\+html/, '*$1+html');
- }
-
- if (reduced.indexOf('[') > -1)
- reduced = reduced.replace(/\[([^\]]+)\]/g, removeWhitespace);
-
- if (repeated.indexOf(reduced) == -1) {
- selector[0] = reduced;
- repeated.push(reduced);
- list.push(selector);
- }
- }
-
- return list.sort(selectorSorter);
- },
-
- selectorDuplicates: function (selectors) {
- var list = [];
- var repeated = [];
-
- for (var i = 0, l = selectors.length; i < l; i++) {
- var selector = selectors[i];
-
- if (repeated.indexOf(selector[0]) == -1) {
- repeated.push(selector[0]);
- list.push(selector);
- }
- }
-
- return list.sort(selectorSorter);
- },
-
- block: function (values, spaceAfterClosingBrace) {
- values[0] = values[0]
- .replace(/\s+/g, ' ')
- .replace(/(,|:|\() /g, '$1')
- .replace(/ \)/g, ')');
-
- if (!spaceAfterClosingBrace)
- values[0] = values[0].replace(/\) /g, ')');
- },
-
- atRule: function (values) {
- values[0] = values[0]
- .replace(/\s+/g, ' ')
- .trim();
- }
-};
-
-module.exports = CleanUp;
+++ /dev/null
-var optimizeProperties = require('../properties/optimizer');
-
-var stringifyBody = require('../stringifier/one-time').body;
-var stringifySelectors = require('../stringifier/one-time').selectors;
-var cleanUpSelectors = require('./clean-up').selectors;
-var isSpecial = require('./is-special');
-
-function mergeAdjacent(tokens, options, context) {
- var lastToken = [null, [], []];
- var adjacentSpace = options.compatibility.selectors.adjacentSpace;
-
- for (var i = 0, l = tokens.length; i < l; i++) {
- var token = tokens[i];
-
- if (token[0] != 'selector') {
- lastToken = [null, [], []];
- continue;
- }
-
- if (lastToken[0] == 'selector' && stringifySelectors(token[1]) == stringifySelectors(lastToken[1])) {
- var joinAt = [lastToken[2].length];
- Array.prototype.push.apply(lastToken[2], token[2]);
- optimizeProperties(token[1], lastToken[2], joinAt, true, options, context);
- token[2] = [];
- } else if (lastToken[0] == 'selector' && stringifyBody(token[2]) == stringifyBody(lastToken[2]) &&
- !isSpecial(options, stringifySelectors(token[1])) && !isSpecial(options, stringifySelectors(lastToken[1]))) {
- lastToken[1] = cleanUpSelectors(lastToken[1].concat(token[1]), false, adjacentSpace);
- token[2] = [];
- } else {
- lastToken = token;
- }
- }
-}
-
-module.exports = mergeAdjacent;
+++ /dev/null
-var stringifyAll = require('../stringifier/one-time').all;
-
-function removeDuplicateMediaQueries(tokens) {
- var candidates = {};
-
- for (var i = 0, l = tokens.length; i < l; i++) {
- var token = tokens[i];
- if (token[0] != 'block')
- continue;
-
- var key = token[1][0] + '%' + stringifyAll(token[2]);
- var candidate = candidates[key];
-
- if (candidate)
- candidate[2] = [];
-
- candidates[key] = token;
- }
-}
-
-module.exports = removeDuplicateMediaQueries;
var lineBreak = require('os').EOL;
+var emptyCharacter = '';
-var AT_RULE = 'at-rule';
-var PROPERTY_SEPARATOR = ';';
-
-function hasMoreProperties(tokens, index) {
- for (var i = index, l = tokens.length; i < l; i++) {
- if (typeof tokens[i] != 'string')
- return true;
- }
-
- return false;
-}
+var Marker = require('../tokenizer/marker');
+var Token = require('../tokenizer/token');
function supportsAfterClosingBrace(token) {
- return token[0][0] == 'background' || token[0][0] == 'transform' || token[0][0] == 'src';
+ return token[1][1] == 'background' || token[1][1] == 'transform' || token[1][1] == 'src';
}
function afterClosingBrace(token, valueIndex) {
- return token[valueIndex][0][token[valueIndex][0].length - 1] == ')' || token[valueIndex][0].indexOf('__ESCAPED_URL_CLEAN_CSS') === 0;
+ return token[valueIndex][1][token[valueIndex][1].length - 1] == Marker.CLOSE_ROUND_BRACKET;
}
function afterComma(token, valueIndex) {
- return token[valueIndex][0] == ',';
+ return token[valueIndex][1] == Marker.COMMA;
}
function afterSlash(token, valueIndex) {
- return token[valueIndex][0] == '/';
+ return token[valueIndex][1] == Marker.FORWARD_SLASH;
}
function beforeComma(token, valueIndex) {
- return token[valueIndex + 1] && token[valueIndex + 1][0] == ',';
+ return token[valueIndex + 1] && token[valueIndex + 1][1] == Marker.COMMA;
}
function beforeSlash(token, valueIndex) {
- return token[valueIndex + 1] && token[valueIndex + 1][0] == '/';
+ return token[valueIndex + 1] && token[valueIndex + 1][1] == Marker.FORWARD_SLASH;
}
function inFilter(token) {
- return token[0][0] == 'filter' || token[0][0] == '-ms-filter';
+ return token[1][1] == 'filter' || token[1][1] == '-ms-filter';
}
function inSpecialContext(token, valueIndex, context) {
afterComma(token, valueIndex);
}
-function selectors(tokens, context) {
+function rules(tokens, context) {
var store = context.store;
for (var i = 0, l = tokens.length; i < l; i++) {
store(tokens[i], context);
- if (i < l - 1)
- store(',', context);
+ if (i < l - 1) {
+ store(Marker.COMMA, context);
+ }
}
}
function body(tokens, context) {
+ var lastPropertyAt = lastPropertyIndex(tokens);
+
for (var i = 0, l = tokens.length; i < l; i++) {
- property(tokens, i, i == l - 1, context);
+ property(tokens, i, lastPropertyAt, context);
}
}
-function property(tokens, position, isLast, context) {
- var store = context.store;
- var token = tokens[position];
+function lastPropertyIndex(tokens) {
+ var index = tokens.length - 1;
- if (typeof token == 'string') {
- store(token, context);
- } else if (token[0] == AT_RULE) {
- propertyAtRule(token[1], isLast, context);
- } else {
- store(token[0], context);
- store(':', context);
- value(tokens, position, isLast, context);
+ for (; index >= 0; index--) {
+ if (tokens[index][0] != Token.COMMENT) {
+ break;
+ }
}
+
+ return index;
}
-function propertyAtRule(value, isLast, context) {
+function property(tokens, position, lastPropertyAt, context) {
var store = context.store;
+ var token = tokens[position];
- store(value, context);
- if (!isLast)
- store(PROPERTY_SEPARATOR, context);
+ switch (token[0]) {
+ case Token.AT_RULE:
+ // slicing here is a bit inconvenient but necessary since otherwise source map info
+ // would not be passed in. We should consider changing parsing to output an array as
+ // 2nd element. Unfortunately this also refers to properties... :-/
+ store(token.slice(1), context);
+ store(position < lastPropertyAt ? Marker.SEMICOLON : '', context);
+ break;
+ case Token.COMMENT:
+ store(token[1][0], context);
+ break;
+ case Token.PROPERTY:
+ store(token[1][1], context);
+ store(Marker.COLON, context);
+ value(token, context);
+ store(position < lastPropertyAt || token[2][0] == Token.PROPERTY_BLOCK ? Marker.SEMICOLON : '', context);
+ }
}
-function value(tokens, position, isLast, context) {
+function value(token, context) {
var store = context.store;
- var token = tokens[position];
- var isVariableDeclaration = token[0][0].indexOf('--') === 0;
- var isBlockVariable = isVariableDeclaration && Array.isArray(token[1][0]);
-
- if (isVariableDeclaration && isBlockVariable && atRulesOrProperties(token[1])) {
- store('{', context);
- body(token[1], context);
- store('};', context);
- return;
- }
+ var j, m;
- for (var j = 1, m = token.length; j < m; j++) {
- store(token[j], context);
+ if (token[2][0] == Token.PROPERTY_BLOCK) {
+ store(Marker.OPEN_BRACE, context);
+ body(token[2][1], context);
+ store(Marker.CLOSE_BRACE, context);
+ } else {
+ for (j = 2, m = token.length; j < m; j++) {
+ store(token[j][1], context);
- if (j < m - 1 && (inFilter(token) || !inSpecialContext(token, j, context))) {
- store(' ', context);
- } else if (j == m - 1 && !isLast && hasMoreProperties(tokens, position + 1)) {
- store(PROPERTY_SEPARATOR, context);
+ if (j < m - 1 && (inFilter(token) || !inSpecialContext(token, j, context))) {
+ store(Marker.SPACE, context);
+ }
}
}
}
-function atRulesOrProperties(values) {
- for (var i = 0, l = values.length; i < l; i++) {
- if (values[i][0] == AT_RULE || Array.isArray(values[i][0]))
- return true;
- }
-
- return false;
-}
-
function all(tokens, context) {
- var joinCharacter = context.keepBreaks ? lineBreak : '';
+ var joinCharacter = context.keepBreaks ? lineBreak : emptyCharacter;
var store = context.store;
+ var token;
+ var i, l;
- for (var i = 0, l = tokens.length; i < l; i++) {
- var token = tokens[i];
+ for (i = 0, l = tokens.length; i < l; i++) {
+ token = tokens[i];
switch (token[0]) {
- case 'at-rule':
- case 'text':
- store(token[1][0], context);
+ case Token.AT_RULE:
+ store(token[1], context);
+ store(Marker.SEMICOLON, context);
+ break;
+ case Token.AT_RULE_BLOCK:
+ rules(token[1], context);
store(joinCharacter, context);
+ store(Marker.OPEN_BRACE, context);
+ body(token[2], context);
+ store(Marker.CLOSE_BRACE, context);
break;
- case 'block':
- selectors([token[1]], context);
- store('{', context);
+ case Token.BLOCK:
+ rules(token[1], context);
+ store(Marker.OPEN_BRACE, context);
all(token[2], context);
- store('}', context);
- store(joinCharacter, context);
+ store(Marker.CLOSE_BRACE, context);
break;
- case 'flat-block':
- selectors([token[1]], context);
- store('{', context);
- body(token[2], context);
- store('}', context);
- store(joinCharacter, context);
+ case Token.COMMENT:
+ store(token[1], context);
break;
- default:
- selectors(token[1], context);
- store('{', context);
+ case Token.RULE:
+ rules(token[1], context);
+ store(Marker.OPEN_BRACE, context);
body(token[2], context);
- store('}', context);
- store(joinCharacter, context);
+ store(Marker.CLOSE_BRACE, context);
+ break;
+ }
+
+ if (i < l - 1) {
+ store(joinCharacter, context);
}
}
}
all: all,
body: body,
property: property,
- selectors: selectors,
+ rules: rules,
value: value
};
return fakeContext.output.join('');
}
-function selectors(tokens) {
+function rules(tokens) {
var fakeContext = context();
- helpers.selectors(tokens, fakeContext);
+ helpers.rules(tokens, fakeContext);
return fakeContext.output.join('');
}
-function value(tokens, position) {
+function value(tokens) {
var fakeContext = context();
- helpers.value(tokens, position, true, fakeContext);
+ helpers.value(tokens, fakeContext);
return fakeContext.output.join('');
}
all: all,
body: body,
property: property,
- selectors: selectors,
+ rules: rules,
value: value
};
var all = require('./helpers').all;
-function store(token, context) {
- context.output.push(typeof token == 'string' ? token : token[0]);
+function store(token, stringifyContext) {
+ stringifyContext.output.push(typeof token == 'string' ? token : token[0]);
}
-function stringify(tokens, options, restoreCallback) {
- var context = {
- keepBreaks: options.keepBreaks,
+function stringify(tokens, context) {
+ var stringifyContext = {
+ keepBreaks: context.options.keepBreaks,
output: [],
- spaceAfterClosingBrace: options.compatibility.properties.spaceAfterClosingBrace,
+ spaceAfterClosingBrace: context.options.compatibility.properties.spaceAfterClosingBrace,
store: store
};
- all(tokens, context, false);
+ all(tokens, stringifyContext, false);
return {
- styles: restoreCallback(context.output.join('')).trim()
+ styles: stringifyContext.output.join('')
};
}
context.outputMap.setSourceContent(source, mapping[3][mapping[2]]);
}
-function stringify(tokens, options, restoreCallback, inputMapTracker) {
- var context = {
+function stringify(tokens, context) {
+ var stringifyContext = {
column: 0,
- inputMapTracker: inputMapTracker,
- keepBreaks: options.keepBreaks,
+ inputMapTracker: context.inputMapTracker,
+ keepBreaks: context.options.keepBreaks,
line: 1,
output: [],
outputMap: new SourceMapGenerator(),
- restore: restoreCallback,
- sourceMapInlineSources: options.sourceMapInlineSources,
- spaceAfterClosingBrace: options.compatibility.properties.spaceAfterClosingBrace,
+ sourceMapInlineSources: context.options.sourceMapInlineSources,
+ spaceAfterClosingBrace: context.options.compatibility.properties.spaceAfterClosingBrace,
store: store
};
- all(tokens, context, false);
+ all(tokens, stringifyContext, false);
return {
- sourceMap: context.outputMap,
- styles: context.output.join('').trim()
+ sourceMap: stringifyContext.outputMap,
+ styles: stringifyContext.output.join('')
};
}
BACK_SLASH: '\\',
CLOSE_BRACE: '}',
CLOSE_ROUND_BRACKET: ')',
+ CLOSE_SQUARE_BRACKET: ']',
COLON: ':',
COMMA: ',',
DOUBLE_QUOTE: '"',
NEW_LINE_WIN: '\r',
OPEN_BRACE: '{',
OPEN_ROUND_BRACKET: '(',
+ OPEN_SQUARE_BRACKET: '[',
SEMICOLON: ';',
SINGLE_QUOTE: '\'',
SPACE: ' ',
--- /dev/null
+var path = require('path');
+
+function rebaseConfig(context) {
+ var config = {
+ absolute: context.options.explicitRoot,
+ relative: !context.options.explicitRoot && context.options.explicitTarget,
+ fromBase: context.options.relativeTo
+ };
+
+ if (!config.absolute && !config.relative) {
+ return null;
+ }
+
+ if (config.absolute && context.options.explicitTarget) {
+ context.warnings.push('Both \'root\' and output file given so rebasing URLs as absolute paths');
+ }
+
+ if (config.absolute) {
+ config.toBase = path.resolve(context.options.root);
+ }
+
+ if (config.relative) {
+ config.toBase = path.resolve(context.options.target);
+ }
+
+ return config.fromBase && config.toBase ?
+ config :
+ null;
+}
+
+module.exports = rebaseConfig;
+++ /dev/null
-var path = require('path');
-
-var rewriteUrls = require('./rewrite');
-
-function rebaseUrls(data, context) {
- var rebaseOpts = {
- absolute: context.options.explicitRoot,
- relative: !context.options.explicitRoot && context.options.explicitTarget,
- fromBase: context.options.relativeTo
- };
-
- if (!rebaseOpts.absolute && !rebaseOpts.relative)
- return data;
-
- if (rebaseOpts.absolute && context.options.explicitTarget)
- context.warnings.push('Both \'root\' and output file given so rebasing URLs as absolute paths');
-
- if (rebaseOpts.absolute)
- rebaseOpts.toBase = path.resolve(context.options.root);
-
- if (rebaseOpts.relative)
- rebaseOpts.toBase = path.resolve(context.options.target);
-
- if (!rebaseOpts.fromBase || !rebaseOpts.toBase)
- return data;
-
- return rewriteUrls(data, rebaseOpts, context);
-}
-
-module.exports = rebaseUrls;
+++ /dev/null
-var split = require('../utils/split');
-
-var URL_PREFIX = 'url(';
-var UPPERCASE_URL_PREFIX = 'URL(';
-var URL_SUFFIX = ')';
-var SINGLE_QUOTE_URL_SUFFIX = '\')';
-var DOUBLE_QUOTE_URL_SUFFIX = '")';
-
-var DATA_URI_PREFIX_PATTERN = /^\s*['"]?\s*data:/;
-var DATA_URI_TRAILER_PATTERN = /[\s\};,\/!]/;
-
-var IMPORT_URL_PREFIX = '@import';
-var UPPERCASE_IMPORT_URL_PREFIX = '@IMPORT';
-
-var COMMENT_END_MARKER = /\*\//;
-
-function byUrl(data, context, callback) {
- var nextStart = 0;
- var nextStartUpperCase = 0;
- var nextEnd = 0;
- var firstMatch;
- var isDataURI = false;
- var cursor = 0;
- var tempData = [];
- var hasUppercaseUrl = data.indexOf(UPPERCASE_URL_PREFIX) > -1;
-
- for (; nextEnd < data.length;) {
- nextStart = data.indexOf(URL_PREFIX, nextEnd);
- nextStartUpperCase = hasUppercaseUrl ? data.indexOf(UPPERCASE_URL_PREFIX, nextEnd) : -1;
- if (nextStart == -1 && nextStartUpperCase == -1)
- break;
-
- if (nextStart == -1 && nextStartUpperCase > -1)
- nextStart = nextStartUpperCase;
-
- if (data[nextStart + URL_PREFIX.length] == '"') {
- nextEnd = data.indexOf(DOUBLE_QUOTE_URL_SUFFIX, nextStart);
- } else if (data[nextStart + URL_PREFIX.length] == '\'') {
- nextEnd = data.indexOf(SINGLE_QUOTE_URL_SUFFIX, nextStart);
- } else {
- isDataURI = DATA_URI_PREFIX_PATTERN.test(data.substring(nextStart + URL_PREFIX.length));
-
- if (isDataURI) {
- firstMatch = split(data.substring(nextStart), DATA_URI_TRAILER_PATTERN, false, '(', ')', true).pop();
-
- if (firstMatch && firstMatch[firstMatch.length - 1] == URL_SUFFIX) {
- nextEnd = nextStart + firstMatch.length - URL_SUFFIX.length;
- } else {
- nextEnd = -1;
- }
- } else {
- nextEnd = data.indexOf(URL_SUFFIX, nextStart);
- }
- }
-
-
- // Following lines are a safety mechanism to ensure
- // incorrectly terminated urls are processed correctly.
- if (nextEnd == -1) {
- nextEnd = data.indexOf('}', nextStart);
-
- if (nextEnd == -1)
- nextEnd = data.length;
- else
- nextEnd--;
-
- context.warnings.push('Broken URL declaration: \'' + data.substring(nextStart, nextEnd + 1) + '\'.');
- } else {
- if (data[nextEnd] != URL_SUFFIX)
- nextEnd = data.indexOf(URL_SUFFIX, nextEnd);
- }
-
- tempData.push(data.substring(cursor, nextStart));
-
- var url = data.substring(nextStart, nextEnd + 1);
- callback(url, tempData);
-
- cursor = nextEnd + 1;
- }
-
- return tempData.length > 0 ?
- tempData.join('') + data.substring(cursor, data.length) :
- data;
-}
-
-function byImport(data, context, callback) {
- var nextImport = 0;
- var nextImportUpperCase = 0;
- var nextStart = 0;
- var nextEnd = 0;
- var cursor = 0;
- var tempData = [];
- var nextSingleQuote = 0;
- var nextDoubleQuote = 0;
- var untilNextQuote;
- var withQuote;
- var SINGLE_QUOTE = '\'';
- var DOUBLE_QUOTE = '"';
-
- for (; nextEnd < data.length;) {
- nextImport = data.indexOf(IMPORT_URL_PREFIX, nextEnd);
- nextImportUpperCase = data.indexOf(UPPERCASE_IMPORT_URL_PREFIX, nextEnd);
- if (nextImport == -1 && nextImportUpperCase == -1)
- break;
-
- if (nextImport > -1 && nextImportUpperCase > -1 && nextImportUpperCase < nextImport)
- nextImport = nextImportUpperCase;
-
- nextSingleQuote = data.indexOf(SINGLE_QUOTE, nextImport);
- nextDoubleQuote = data.indexOf(DOUBLE_QUOTE, nextImport);
-
- if (nextSingleQuote > -1 && nextDoubleQuote > -1 && nextSingleQuote < nextDoubleQuote) {
- nextStart = nextSingleQuote;
- withQuote = SINGLE_QUOTE;
- } else if (nextSingleQuote > -1 && nextDoubleQuote > -1 && nextSingleQuote > nextDoubleQuote) {
- nextStart = nextDoubleQuote;
- withQuote = DOUBLE_QUOTE;
- } else if (nextSingleQuote > -1) {
- nextStart = nextSingleQuote;
- withQuote = SINGLE_QUOTE;
- } else if (nextDoubleQuote > -1) {
- nextStart = nextDoubleQuote;
- withQuote = DOUBLE_QUOTE;
- } else {
- break;
- }
-
- tempData.push(data.substring(cursor, nextStart));
- nextEnd = data.indexOf(withQuote, nextStart + 1);
-
- untilNextQuote = data.substring(nextImport, nextEnd);
- if (nextEnd == -1 || /^@import\s+(url\(|__ESCAPED)/i.test(untilNextQuote) || COMMENT_END_MARKER.test(untilNextQuote)) {
- cursor = nextStart;
- break;
- }
-
- var url = data.substring(nextStart, nextEnd + 1);
- callback(url, tempData);
-
- cursor = nextEnd + 1;
- }
-
- return tempData.length > 0 ?
- tempData.join('') + data.substring(cursor, data.length) :
- data;
-}
-
-function reduceAll(data, context, callback) {
- data = byUrl(data, context, callback);
- data = byImport(data, context, callback);
- return data;
-}
-
-module.exports = reduceAll;
--- /dev/null
+var path = require('path');
+var url = require('url');
+
+var DOUBLE_QUOTE = '"';
+var SINGLE_QUOTE = '\'';
+var URL_PREFIX = 'url(';
+var URL_SUFFIX = ')';
+
+var QUOTE_PREFIX_PATTERN = /^["']/;
+var QUOTE_SUFFIX_PATTERN = /["']$/;
+var ROUND_BRACKETS_PATTERN = /[\(\)]/;
+var URL_PREFIX_PATTERN = /^url\(/;
+var URL_SUFFIX_PATTERN = /\)$/;
+var WHITESPACE_PATTERN = /\s/;
+
+var isWindows = process.platform == 'win32';
+
+function rebase(uri, rebaseConfig) {
+ if (!rebaseConfig) {
+ return uri;
+ }
+
+ if (isAbsolute(uri) || isSVGMarker(uri) || isInternal(uri)) {
+ return uri;
+ }
+
+ if (isData(uri)) {
+ return '\'' + uri + '\'';
+ }
+
+ if (isRemote(uri) && !isRemote(rebaseConfig.toBase)) {
+ return uri;
+ }
+
+ if (isRemote(uri) && !isSameOrigin(uri, rebaseConfig.toBase)) {
+ return uri;
+ }
+
+ if (!isRemote(uri) && isRemote(rebaseConfig.toBase)) {
+ return url.resolve(rebaseConfig.toBase, uri);
+ }
+
+ return rebaseConfig.absolute ?
+ normalize(absolute(uri, rebaseConfig)) :
+ normalize(relative(uri, rebaseConfig));
+}
+
+function isAbsolute(uri) {
+ return uri[0] == '/';
+}
+
+function isSVGMarker(uri) {
+ return uri[0] == '#';
+}
+
+function isInternal(uri) {
+ return /^\w+:\w+/.test(uri);
+}
+
+function isRemote(uri) {
+ return /^[^:]+?:\/\//.test(uri) || uri.indexOf('//') === 0;
+}
+
+function isSameOrigin(uri1, uri2) {
+ return url.parse(uri1).protocol == url.parse(uri2).protocol &&
+ url.parse(uri1).host == url.parse(uri2).host;
+}
+
+function isData(uri) {
+ return uri.indexOf('data:') === 0;
+}
+
+function absolute(uri, rebaseConfig) {
+ return path
+ .resolve(path.join(rebaseConfig.fromBase || '', uri))
+ .replace(rebaseConfig.toBase, '');
+}
+
+function relative(uri, rebaseConfig) {
+ return path.relative(rebaseConfig.toBase, path.join(rebaseConfig.fromBase || '', uri));
+}
+
+function normalize(uri) {
+ return isWindows ? uri.replace(/\\/g, '/') : uri;
+}
+
+function quoteFor(unquotedUrl) {
+ if (unquotedUrl.indexOf(SINGLE_QUOTE) > -1) {
+ return DOUBLE_QUOTE;
+ } else if (unquotedUrl.indexOf(DOUBLE_QUOTE) > -1) {
+ return SINGLE_QUOTE;
+ } else if (hasWhitespace(unquotedUrl) || hasRoundBrackets(unquotedUrl)) {
+ return SINGLE_QUOTE;
+ } else {
+ return '';
+ }
+}
+
+function hasWhitespace(url) {
+ return WHITESPACE_PATTERN.test(url);
+}
+
+function hasRoundBrackets(url) {
+ return ROUND_BRACKETS_PATTERN.test(url);
+}
+
+function rewriteUrl(originalUrl, rebaseConfig) {
+ var strippedUrl = originalUrl
+ .replace(URL_PREFIX_PATTERN, '')
+ .replace(URL_SUFFIX_PATTERN, '')
+ .trim();
+
+ var unquotedUrl = strippedUrl
+ .replace(QUOTE_PREFIX_PATTERN, '')
+ .replace(QUOTE_SUFFIX_PATTERN, '');
+
+ var quote = strippedUrl[0] == SINGLE_QUOTE || strippedUrl[0] == DOUBLE_QUOTE ?
+ strippedUrl[0] :
+ quoteFor(unquotedUrl);
+
+ return URL_PREFIX + quote + rebase(unquotedUrl, rebaseConfig) + quote + URL_SUFFIX;
+}
+
+module.exports = rewriteUrl;
+++ /dev/null
-var path = require('path');
-var url = require('url');
-
-var reduceUrls = require('./reduce');
-
-var isWindows = process.platform == 'win32';
-
-function isAbsolute(uri) {
- return uri[0] == '/';
-}
-
-function isSVGMarker(uri) {
- return uri[0] == '#';
-}
-
-function isEscaped(uri) {
- return uri.indexOf('__ESCAPED_URL_CLEAN_CSS__') === 0;
-}
-
-function isInternal(uri) {
- return /^\w+:\w+/.test(uri);
-}
-
-function isRemote(uri) {
- return /^[^:]+?:\/\//.test(uri) || uri.indexOf('//') === 0;
-}
-
-function isSameOrigin(uri1, uri2) {
- return url.parse(uri1).protocol == url.parse(uri2).protocol &&
- url.parse(uri1).host == url.parse(uri2).host;
-}
-
-function isImport(uri) {
- return uri.lastIndexOf('.css') === uri.length - 4;
-}
-
-function isData(uri) {
- return uri.indexOf('data:') === 0;
-}
-
-function absolute(uri, options) {
- return path
- .resolve(path.join(options.fromBase || '', uri))
- .replace(options.toBase, '');
-}
-
-function relative(uri, options) {
- return path.relative(options.toBase, path.join(options.fromBase || '', uri));
-}
-
-function normalize(uri) {
- return isWindows ? uri.replace(/\\/g, '/') : uri;
-}
-
-function rebase(uri, options) {
- if (isAbsolute(uri) || isSVGMarker(uri) || isEscaped(uri) || isInternal(uri))
- return uri;
-
- if (options.rebase === false && !isImport(uri))
- return uri;
-
- if (!options.imports && isImport(uri))
- return uri;
-
- if (isData(uri))
- return '\'' + uri + '\'';
-
- if (isRemote(uri) && !isRemote(options.toBase))
- return uri;
-
- if (isRemote(uri) && !isSameOrigin(uri, options.toBase))
- return uri;
-
- if (!isRemote(uri) && isRemote(options.toBase))
- return url.resolve(options.toBase, uri);
-
- return options.absolute ?
- normalize(absolute(uri, options)) :
- normalize(relative(uri, options));
-}
-
-function quoteFor(url) {
- if (url.indexOf('\'') > -1)
- return '"';
- else if (url.indexOf('"') > -1)
- return '\'';
- else if (/\s/.test(url) || /[\(\)]/.test(url))
- return '\'';
- else
- return '';
-}
-
-function rewriteUrls(data, options, context) {
- return reduceUrls(data, context, function (originUrl, tempData) {
- var url = originUrl.replace(/^(url\()?\s*['"]?|['"]?\s*\)?$/g, '');
- var match = originUrl.match(/^(url\()?\s*(['"]).*?(['"])\s*\)?$/);
- var quote;
- if (!!options.urlQuotes && match && match[2] === match[3]) {
- quote = match[2];
- } else {
- quote = quoteFor(url);
- }
- tempData.push('url(' + quote + rebase(url, options) + quote + ')');
- });
-}
-
-module.exports = rewriteUrls;
}
};
-function Compatibility(source) {
- this.source = source || {};
+function compatibility(source) {
+ return merge(DEFAULTS['*'], calculateSource(source));
}
function merge(source, target) {
return merge(template, source);
}
-Compatibility.prototype.toOptions = function () {
- return merge(DEFAULTS['*'], calculateSource(this.source));
-};
-
-module.exports = Compatibility;
+module.exports = compatibility;
+++ /dev/null
-module.exports = {
- override: function (source1, source2) {
- var target = {};
- for (var key1 in source1)
- target[key1] = source1[key1];
- for (var key2 in source2)
- target[key2] = source2[key2];
-
- return target;
- }
-};
--- /dev/null
+function override(source1, source2) {
+ var target = {};
+
+ for (var key1 in source1) {
+ target[key1] = source1[key1];
+ }
+ for (var key2 in source2) {
+ target[key2] = source2[key2];
+ }
+
+ return target;
+}
+
+module.exports = override;
+++ /dev/null
-var COMMENT_START_MARK = '/*';
-
-function QuoteScanner(data) {
- this.data = data;
-}
-
-var findQuoteEnd = function (data, matched, cursor, oldCursor) {
- var commentEndMark = '*/';
- var escapeMark = '\\';
- var blockEndMark = '}';
- var dataPrefix = data.substring(oldCursor, cursor);
- var commentEndedAt = dataPrefix.lastIndexOf(commentEndMark, cursor);
- var commentStartedAt = findLastCommentStartedAt(dataPrefix, cursor);
- var commentStarted = false;
-
- if (commentEndedAt >= cursor && commentStartedAt > -1)
- commentStarted = true;
- if (commentStartedAt < cursor && commentStartedAt > commentEndedAt)
- commentStarted = true;
-
- if (commentStarted) {
- var commentEndsAt = data.indexOf(commentEndMark, cursor);
- if (commentEndsAt > -1)
- return commentEndsAt;
-
- commentEndsAt = data.indexOf(blockEndMark, cursor);
- return commentEndsAt > -1 ? commentEndsAt - 1 : data.length;
- }
-
- while (true) {
- if (data[cursor] === undefined)
- break;
- if (data[cursor] == matched && (data[cursor - 1] != escapeMark || data[cursor - 2] == escapeMark))
- break;
-
- cursor++;
- }
-
- return cursor;
-};
-
-function findLastCommentStartedAt(data, cursor) {
- var position = cursor;
-
- while (position > -1) {
- position = data.lastIndexOf(COMMENT_START_MARK, position);
-
- if (position > -1 && data[position - 1] != '*') {
- break;
- } else {
- position--;
- }
- }
-
- return position;
-}
-
-function findNext(data, mark, startAt) {
- var escapeMark = '\\';
- var candidate = startAt;
-
- while (true) {
- candidate = data.indexOf(mark, candidate + 1);
- if (candidate == -1)
- return -1;
- if (data[candidate - 1] != escapeMark)
- return candidate;
- }
-}
-
-QuoteScanner.prototype.each = function (callback) {
- var data = this.data;
- var tempData = [];
- var nextStart = 0;
- var nextEnd = 0;
- var cursor = 0;
- var matchedMark = null;
- var singleMark = '\'';
- var doubleMark = '"';
- var dataLength = data.length;
-
- for (; nextEnd < data.length;) {
- var nextStartSingle = findNext(data, singleMark, nextEnd);
- var nextStartDouble = findNext(data, doubleMark, nextEnd);
-
- if (nextStartSingle == -1)
- nextStartSingle = dataLength;
- if (nextStartDouble == -1)
- nextStartDouble = dataLength;
-
- if (nextStartSingle < nextStartDouble) {
- nextStart = nextStartSingle;
- matchedMark = singleMark;
- } else {
- nextStart = nextStartDouble;
- matchedMark = doubleMark;
- }
-
- if (nextStart == -1)
- break;
-
- nextEnd = findQuoteEnd(data, matchedMark, nextStart + 1, cursor);
- if (nextEnd == -1)
- break;
-
- var text = data.substring(nextStart, nextEnd + 1);
- tempData.push(data.substring(cursor, nextStart));
- if (text.length > 0)
- callback(text, tempData, nextStart);
-
- cursor = nextEnd + 1;
- }
-
- return tempData.length > 0 ?
- tempData.join('') + data.substring(cursor, data.length) :
- data;
-};
-
-module.exports = QuoteScanner;
--- /dev/null
+var path = require('path');
+
+var tokenize = require('../tokenizer/tokenize');
+var Token = require('../tokenizer/token');
+
+var rewriteUrl = require('../urls/rewrite-url');
+
+function readSources(input, context, callback) {
+ var tokens;
+
+ if (typeof input == 'string') {
+ tokens = tokenize(input, context);
+ } else if (typeof input == 'object') {
+ tokens = fromHash(input, context);
+ }
+
+ return callback(tokens);
+}
+
+function fromHash(input, context) {
+ var tokens = [];
+ var sourcePath;
+ var source;
+ var baseRelativeTo = context.options.relativeTo || context.options.root;
+ var relativeTo;
+ var fullPath;
+ var config;
+
+ for (sourcePath in input) {
+ source = input[sourcePath];
+ relativeTo = sourcePath[0] == '/' ?
+ context.options.root :
+ baseRelativeTo;
+ fullPath = path.resolve(
+ path.join(
+ relativeTo,
+ sourcePath
+ )
+ );
+
+ config = {
+ relative: true,
+ fromBase: path.dirname(fullPath),
+ toBase: baseRelativeTo
+ };
+
+ tokens = tokens.concat(
+ rebase(
+ tokenize(source.styles, context),
+ context.validator,
+ config
+ )
+ );
+ }
+
+ return tokens;
+}
+
+function rebase(tokens, validator, config) {
+ var token;
+ var i, l;
+
+ for (i = 0, l = tokens.length; i < l; i++) {
+ token = tokens[i];
+
+ switch (token[0]) {
+ case Token.AT_RULE:
+ //
+ break;
+ case Token.AT_RULE_BLOCK:
+ //
+ break;
+ case Token.BLOCK:
+ rebase(token[2], validator, config);
+ break;
+ case Token.PROPERTY:
+ //
+ break;
+ case Token.RULE:
+ rebaseProperties(token[2], validator, config);
+ break;
+ }
+ }
+
+ return tokens;
+}
+
+function rebaseProperties(properties, validator, config) {
+ var property;
+ var value;
+ var i, l;
+ var j, m;
+
+ for (i = 0, l = properties.length; i < l; i++) {
+ property = properties[i];
+
+ for (j = 2 /* 0 is Token.PROPERTY, 1 is name */, m = property.length; j < m; j++) {
+ value = property[j][1];
+
+ if (validator.isValidUrl(value)) {
+ property[j][1] = rewriteUrl(value, config);
+ }
+ }
+ }
+}
+
+module.exports = readSources;
+++ /dev/null
-var path = require('path');
-var rewriteUrls = require('../urls/rewrite');
-
-var REMOTE_RESOURCE = /^(https?:)?\/\//;
-
-function SourceReader(context, data) {
- this.outerContext = context;
- this.data = data;
- this.sources = {};
-}
-
-SourceReader.prototype.sourceAt = function (path) {
- return this.sources[path];
-};
-
-SourceReader.prototype.trackSource = function (path, source) {
- this.sources[path] = {};
- this.sources[path][path] = source;
-};
-
-SourceReader.prototype.toString = function () {
- if (typeof this.data == 'string')
- return fromString(this);
- if (Buffer.isBuffer(this.data))
- return fromBuffer(this);
- if (Array.isArray(this.data))
- return fromArray(this);
-
- return fromHash(this);
-};
-
-function fromString(self) {
- var data = self.data;
- self.trackSource(undefined, data);
- return data;
-}
-
-function fromBuffer(self) {
- var data = self.data.toString();
- self.trackSource(undefined, data);
- return data;
-}
-
-function fromArray(self) {
- return self.data
- .map(function (source) {
- return self.outerContext.options.processImport === false ?
- source + '@shallow' :
- source;
- })
- .map(function (source) {
- return !self.outerContext.options.relativeTo || /^https?:\/\//.test(source) ?
- source :
- path.relative(self.outerContext.options.relativeTo, source);
- })
- .map(function (source) { return '@import url(' + source + ');'; })
- .join('');
-}
-
-function fromHash(self) {
- var data = [];
- var toBase = path.resolve(self.outerContext.options.target || self.outerContext.options.root);
-
- for (var source in self.data) {
- var styles = self.data[source].styles;
- var inputSourceMap = self.data[source].sourceMap;
- var isRemote = REMOTE_RESOURCE.test(source);
- var absoluteSource = isRemote ? source : path.resolve(source);
- var absoluteSourcePath = path.dirname(absoluteSource);
-
- var rewriteOptions = {
- absolute: self.outerContext.options.explicitRoot,
- relative: !self.outerContext.options.explicitRoot,
- imports: true,
- rebase: self.outerContext.options.rebase,
- fromBase: absoluteSourcePath,
- toBase: isRemote ? absoluteSourcePath : toBase,
- urlQuotes: self.outerContext.options.compatibility.properties.urlQuotes
- };
- styles = rewriteUrls(styles, rewriteOptions, self.outerContext);
-
- self.trackSource(source, styles);
-
- styles = self.outerContext.sourceTracker.store(source, styles);
-
- // here we assume source map lies in the same directory as `source` does
- if (self.outerContext.options.sourceMap && inputSourceMap)
- self.outerContext.inputSourceMapTracker.trackLoaded(source, source, inputSourceMap);
-
- data.push(styles);
- }
-
- return data.join('');
-}
-
-module.exports = SourceReader;
+++ /dev/null
-function SourceTracker() {
- this.sources = [];
-}
-
-SourceTracker.prototype.store = function (filename, data) {
- this.sources.push(filename);
-
- return '__ESCAPED_SOURCE_CLEAN_CSS' + (this.sources.length - 1) + '__' +
- data +
- '__ESCAPED_SOURCE_END_CLEAN_CSS__';
-};
-
-SourceTracker.prototype.nextStart = function (data) {
- var next = /__ESCAPED_SOURCE_CLEAN_CSS(\d+)__/.exec(data);
-
- return next ?
- { index: next.index, filename: this.sources[~~next[1]] } :
- null;
-};
-
-SourceTracker.prototype.nextEnd = function (data) {
- return /__ESCAPED_SOURCE_END_CLEAN_CSS__/g.exec(data);
-};
-
-SourceTracker.prototype.removeAll = function (data) {
- return data
- .replace(/__ESCAPED_SOURCE_CLEAN_CSS\d+__/g, '')
- .replace(/__ESCAPED_SOURCE_END_CLEAN_CSS__/g, '');
-};
-
-module.exports = SourceTracker;
var lineBreak = require('os').EOL;
+if (process.platform == 'win32')
+ return;
+
var batchContexts = function () {
var context = {};
var dir = path.join(__dirname, 'fixtures');
.bord_double_gris_blanc{line-height:25px;font-size:12px;display:inline-block;border:solid #d2d6db;border-width:1px 0}
.bord_double_gris_blanc span{display:inline-block;border:solid #fff;border-width:1px 0}
.bloc_abo{border-top:3px solid #ffd500}
-img[width="642"],img[width="312"]{margin-bottom:6px}
+img[width="312"],img[width="642"]{margin-bottom:6px}
img[width="202"]{margin-bottom:4px}
.btn,.btn_abo,.btn_fonce,.btn_petit{display:inline-block;padding:4px 10px;margin-bottom:0;color:#000b15;text-align:center;font-weight:700;vertical-align:middle;background-color:#f5f5f5;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-ms-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(top,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);cursor:pointer}
.bt_fonce a,.btn_fonce{color:#fff;background-color:#000b15;background-image:-moz-linear-gradient(top,#5d666d,#000b15);background-image:-ms-linear-gradient(top,#5d666d,#000b15);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5d666d),to(#000b15));background-image:-webkit-linear-gradient(top,#5d666d,#000b15);background-image:-o-linear-gradient(top,#5d666d,#000b15);background-image:linear-gradient(top,#5d666d,#000b15);background-repeat:repeat-x;border-color:#000b15;border-color:rgba(0,0,0,.1)}
#page-mailfriend .content input[type=checkbox]{float:right;margin-top:5px}
#page-mailfriend .content label{float:left;display:block;width:80%;font-weight:700}
#page-paywall{width:520px;font-size:12px}
-#page-paywall .content .arguments .arg .price,#page-paywall .content .arguments .arg h4,#page-paywall .content .video h5{font-family:Georgia,"Times New Roman",Times,serif}
#page-paywall .content{position:relative;padding:20px 0}
#page-paywall .content a.close{display:block;float:right}
#page-paywall .content a.close span{background:url(http://s0.libe.com/libe/img/common/_sprites_icons/icons.png?9914d0d70a49) -20px -98px no-repeat;display:block;margin:auto;width:15px;height:15px}
#page-paywall .content a.close strong{text-transform:uppercase;font-size:8px}
#page-paywall .content .video{margin-bottom:20px;width:437px}
-#page-paywall .content .video h5{margin-bottom:15px;padding:3px 0 5px;border-top:1px dotted;border-bottom:1px dotted;float:right;font-size:16px;font-style:italic;font-weight:400}
+#page-paywall .content .video h5{margin-bottom:15px;padding:3px 0 5px;border-top:1px dotted;border-bottom:1px dotted;float:right;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;font-style:italic;font-weight:400}
#page-paywall .content .arguments,#page-paywall .content .video h4{margin-bottom:20px;clear:both}
#page-paywall .content .video h4 span{float:right;padding:0 0 0 10px;text-transform:uppercase;line-height:13px;font-size:16px;font-weight:400}
#page-paywall .content .video .player{width:354px;height:200px;float:right}
#page-paywall .content .arguments .arg .visual1{height:71px}
#page-paywall .content .arguments .arg .visual2{height:76px}
#page-paywall .content .arguments .arg h5{margin-bottom:10px;text-transform:uppercase;line-height:13px;font-size:14px;font-weight:400}
-#page-paywall .content .arguments .arg h4{margin-bottom:10px;font-size:13px;font-style:italic;font-weight:400}
-#page-paywall .content .arguments .arg .price{float:right;width:120px;font-size:13px;margin-bottom:15px}
+#page-paywall .content .arguments .arg h4{margin-bottom:10px;font-family:Georgia,"Times New Roman",Times,serif;font-size:13px;font-style:italic;font-weight:400}
+#page-paywall .content .arguments .arg .price{float:right;width:120px;font-family:Georgia,"Times New Roman",Times,serif;font-size:13px;margin-bottom:15px}
#page-paywall .content .arguments .arg .price strong{display:block;float:left;margin-right:10px;line-height:25px;font-family:Verdana,sans-serif;font-size:30px;letter-spacing:-3px}
#page-paywall .content .arguments .arg .price strong .currency,#page-paywall .content .arguments .arg .price strong .decimals{font-size:20px}
#page-paywall .content .arguments .arg .price strong .currency{padding-left:3px}
img{vertical-align:middle}
svg:not(:root){overflow:hidden}
hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}
+*,:after,:before,input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box}
pre,textarea{overflow:auto}
code,kbd,pre,samp{font-size:1em}
button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}
button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}
-input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}
+input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}
input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}
input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}
table{border-spacing:0;border-collapse:collapse}
a,a:visited{text-decoration:underline}
a[href]:after{content:" (" attr(href) ")"}
abbr[title]:after{content:" (" attr(title) ")"}
-a[href^="javascript:"]:after,a[href^="#"]:after{content:""}
+a[href^="#"]:after,a[href^=javascript:]:after{content:""}
blockquote,pre{border:1px solid #999}
thead{display:table-header-group}
img{max-width:100%!important}
.glyphicon-menu-right:before{content:"\e258"}
.glyphicon-menu-down:before{content:"\e259"}
.glyphicon-menu-up:before{content:"\e260"}
-*,:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
+*,:after,:before{box-sizing:border-box}
html{font-size:10px;-webkit-tap-highlight-color:transparent}
body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333}
button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}
input[type=file]{display:block}
input[type=range]{display:block;width:100%}
select[multiple],select[size]{height:auto}
-input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}
+input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}
output{padding-top:7px}
.form-control{width:100%;height:34px;padding:6px 12px;background-color:#fff;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}
.form-group-sm .form-control,.input-sm{font-size:12px;border-radius:3px;padding:5px 10px}
.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .form-control-feedback,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}
.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}
textarea.form-control{height:auto}
-@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}
-.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}
-.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}
+@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=datetime-local],input[type=month],input[type=time]{line-height:34px}
+.input-group-sm input[type=date],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],.input-group-sm input[type=time],input[type=date].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,input[type=time].input-sm{line-height:30px}
+.input-group-lg input[type=date],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],.input-group-lg input[type=time],input[type=date].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,input[type=time].input-lg{line-height:46px}
}
.form-group{margin-bottom:15px}
.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}
.popover>.arrow:after{content:"";border-width:10px}
.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}
.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}
-.popover.left>.arrow:after,.popover.right>.arrow:after{bottom:-10px;content:" "}
.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}
-.popover.right>.arrow:after{left:1px;border-right-color:#fff;border-left-width:0}
+.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}
.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}
.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}
.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}
-.popover.left>.arrow:after{right:1px;border-right-width:0;border-left-color:#fff}
+.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}
.carousel-inner{width:100%;overflow:hidden}
.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}
.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}
* Twitter: http://twitter.com/davegandy
* Work: Lead Product Designer @ Kyruus - http://kyruus.com
*/
-.icon-large{font-size:1.3333333333333333em;margin-top:-4px;padding-top:3px;margin-bottom:-4px;padding-bottom:3px;vertical-align:middle}
-.nav [class*=" icon-"],.nav [class^=icon-]{vertical-align:inherit;margin-top:-4px;padding-top:3px;margin-bottom:-4px;padding-bottom:3px}
+.icon-large,.nav [class*=" icon-"],.nav [class^=icon-]{margin-top:-4px;padding-top:3px;margin-bottom:-4px;padding-bottom:3px}
+.icon-large{font-size:1.3333333333333333em;vertical-align:middle}
+.nav [class*=" icon-"],.nav [class^=icon-]{vertical-align:inherit}
.nav [class*=" icon-"].icon-large,.nav [class^=icon-].icon-large{vertical-align:-25%}
.nav-pills [class*=" icon-"].icon-large,.nav-pills [class^=icon-].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-tabs [class^=icon-].icon-large{line-height:.75em;margin-top:-7px;padding-top:5px;margin-bottom:-5px;padding-bottom:4px}
.btn [class*=" icon-"].pull-left,.btn [class*=" icon-"].pull-right,.btn [class^=icon-].pull-left,.btn [class^=icon-].pull-right{vertical-align:inherit}
-p{background-image:url(/*)}
+p{background-image:url('/*')}
\ No newline at end of file
],
'inside url': [
'p{background-image:url(\'/*\')}/* */',
- 'p{background-image:url(/*)}'
+ 'p{background-image:url(\'/*\')}'
],
'inside url twice': [
'p{background-image:url(\'/* */\" /*\')}/* */',
],
'inside url with more quotation': [
'p{background-image:url(\'/*\');content:""/* */}',
- 'p{background-image:url(/*);content:""}'
+ 'p{background-image:url(\'/*\');content:""}'
],
'with quote marks': [
'/*"*//* */',
],
'open ended (broken)': [
'a{width:expression(this.parentNode.innerText == }',
- 'a{width:expression(this.parentNode.innerText == }'
+ 'a{width:expression(this.parentNode.innerText ==}'
],
'function call & advanced': [
'a{zoom:expression(function (el){el.style.zoom="1"}(this))}',
'a{background:url(/images/blank.png)}',
'a{background:url(/images/blank.png)}'
],
- 'keep non-encoded data URI unchanged': [
- '.icon-logo{background-image:url(\'data:image/svg+xml;charset=US-ASCII\')}',
- '.icon-logo{background-image:url(\'data:image/svg+xml;charset=US-ASCII\')}'
- ],
'strip quotes from base64 encoded PNG data URI': [
'.icon-logo{background-image:url(\'data:image/png;base64,iVBORw0\')}',
'.icon-logo{background-image:url(data:image/png;base64,iVBORw0)}'
],
'cut off url content on selector level': [
'a{background:url(image/}',
- 'a{background:url(image/}'
+ ''
],
'cut off url content on block level': [
'@font-face{src:url(data:application/x-font-woff;base64,d09GRk9UVE8AAENAAA0AAAAA}',
- '@font-face{src:url(data:application/x-font-woff;base64,d09GRk9UVE8AAENAAA0AAAAA}'
+ ''
],
'cut off url content on top level': [
'@font-face{src:url(data:application/x-font-woff;base64,d09GRk9UVE8AAENAAA0AAAAA',
],
'keep quoting if whitespace': [
'a{background:url("/images/blank image.png")}',
- 'a{background:url(\'/images/blank image.png\')}'
+ 'a{background:url("/images/blank image.png")}'
],
'keep quoting if whitespace inside @font-face': [
'@font-face{src:url("/Helvetica Neue.eot")}',
- '@font-face{src:url(\'/Helvetica Neue.eot\')}'
+ '@font-face{src:url("/Helvetica Neue.eot")}'
],
'keep SVG data URI unchanged': [
'div{background:url(data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2018%2018%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Crect%20width%3D%2214%22%20height%3D%2214%22%2Fsvg%3E)}',
'a[href="/version-0.01.html"]{display:block}',
'a[href="/version-0.01.html"]{display:block}'
],
- 'should strip new lines inside attributes': [
- '.test[title="my very long ' + lineBreak + 'title"]{display:block}',
+ 'should strip escaped new lines inside attributes': [
+ '.test[title="my very long \\' + lineBreak + 'title"]{display:block}',
'.test[title="my very long title"]{display:block}'
],
- 'should strip new lines inside attributes which can be unquoted': [
- '.test[title="my_very_long_' + lineBreak + 'title"]{display:block}',
+ 'should strip escaped new lines inside attributes which can be unquoted': [
+ '.test[title="my_very_long_\\' + lineBreak + 'title"]{display:block}',
'.test[title=my_very_long_title]{display:block}'
],
'should strip whitespace between square brackets': [
'a{--my-toolbar: { margin:10px; margin-top:10px };}',
'a{--my-toolbar:{margin:10px};}'
],
- 'Polymer mixins - not fitting into a single chunk of 128 bytes': [
- ':host{--live-head-theme: { line-height: 40px !important; vertical-align: middle; background: transparent; height: 40px; z-index: 999; }; }',
- ':host{--live-head-theme:{line-height:40px!important;vertical-align:middle;background:0 0;height:40px;z-index:999};}'
- ],
'Polymer mixins - inlined variables': [
'.spinner{-webkit-animation:container-rotate var(--paper-spinner-container-rotation-duration) linear infinite}',
'.spinner{-webkit-animation:container-rotate var(--paper-spinner-container-rotation-duration) linear infinite}'
'should give right output': function (minified) {
assert.equal(minified.styles, '@import url(one.css);@import url(extra/three.css);@import url(./extra/four.css);.two{color:#fff}');
}
- },
- 'off - many files': {
- 'topic': function () {
- return new CleanCSS({ processImport: false }).minify(['./test/fixtures/partials/remote.css', './test/fixtures/partials-absolute/base.css']);
- },
- 'should give right output': function (minified) {
- assert.equal(minified.styles, '@import url(http://jakubpawlowicz.com/styles.css);@import url(./extra/sub.css);.base{margin:0}');
- }
- },
- 'off - many files with content': {
- 'topic': function () {
- return new CleanCSS({ processImport: false }).minify(['./test/fixtures/partials/two.css', './test/fixtures/partials-absolute/base.css']);
- },
- 'should give right output': function (minified) {
- assert.equal(minified.styles, '@import url(one.css);@import url(extra/three.css);@import url(./extra/four.css);.two{color:#fff}.base{margin:0}');
- }
}
}
},
var vows = require('vows');
-var selectorContext = require('../test-helper').selectorContext;
-var propertyContext = require('../test-helper').propertyContext;
+var optimizerContext = require('../test-helper').optimizerContext;
vows.describe('simple optimizations')
.addBatch(
- selectorContext('default', {
+ optimizerContext('selectors', {
'optimized': [
'a{}',
- null
+ ''
],
'whitespace': [
' div > span{color:red}',
- [['div>span']]
+ 'div>span{color:red}'
],
'line breaks': [
' div >\n\r\n span{color:red}',
- [['div>span']]
+ 'div>span{color:red}'
],
'more line breaks': [
'\r\ndiv\n{color:red}',
- [['div']]
+ 'div{color:red}'
],
'+html': [
- '*+html .foo{display:inline}',
- null
+ '*+html .foo{color:red}',
+ ''
],
'adjacent nav': [
'div + nav{color:red}',
- [['div+nav']]
+ 'div+nav{color:red}'
],
'heading & trailing': [
' a {color:red}',
- [['a']]
+ 'a{color:red}'
],
'descendant selector': [
'div > a{color:red}',
- [['div>a']]
+ 'div>a{color:red}'
],
'next selector': [
'div + a{color:red}',
- [['div+a']]
+ 'div+a{color:red}'
],
'sibling selector': [
'div ~ a{color:red}',
- [['div~a']]
+ 'div~a{color:red}'
],
'pseudo classes': [
'div :first-child{color:red}',
- [['div :first-child']]
+ 'div :first-child{color:red}'
],
'tabs': [
'div\t\t{color:red}',
- [['div']]
+ 'div{color:red}'
],
'universal selector - id, class, and property': [
'* > *#id > *.class > *[property]{color:red}',
- [['*>#id>.class>[property]']]
+ '*>#id>.class>[property]{color:red}'
],
'universal selector - pseudo': [
'*:first-child{color:red}',
- [[':first-child']]
+ ':first-child{color:red}'
],
'universal selector - standalone': [
'label ~ * + span{color:red}',
- [['label~*+span']]
+ 'label~*+span{color:red}'
],
'order': [
'b,div,a{color:red}',
- [['a'], ['b'], ['div']]
+ 'a,b,div{color:red}'
],
'duplicates': [
'a,div,.class,.class,a ,div > a{color:red}',
- [['.class'], ['a'], ['div'], ['div>a']]
+ '.class,a,div,div>a{color:red}',
],
'mixed': [
' label ~ \n* + span , div>*.class, section\n\n{color:red}',
- [['div>.class'], ['label~*+span'], ['section']]
+ 'div>.class,label~*+span,section{color:red}'
],
'escaped joining character #1': [
- '.class\\~ div{color: red}',
- [['.class\\~ div']]
+ '.class\\~ div{color:red}',
+ '.class\\~ div{color:red}'
],
'escaped joining character #2': [
- '.class\\+\\+ div{color: red}',
- [['.class\\+\\+ div']]
+ '.class\\+\\+ div{color:red}',
+ '.class\\+\\+ div{color:red}'
],
'escaped joining character #3': [
- '.class\\> \\~div{color: red}',
- [['.class\\> \\~div']]
+ '.class\\> \\~div{color:red}',
+ '.class\\> \\~div{color:red}'
],
'escaped characters': [
- '.a\\+\\+b{color: red}',
- [['.a\\+\\+b']]
+ '.a\\+\\+b{color:red}',
+ '.a\\+\\+b{color:red}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- selectorContext('ie8', {
+ optimizerContext('selectors - ie8', {
'+html': [
- '*+html .foo{display:inline}',
- null
+ '*+html .foo{color:red}',
+ ''
],
'+first-child html': [
- '*:first-child+html .foo{display:inline}',
- null
+ '*:first-child+html .foo{color:red}',
+ ''
],
'+html - complex': [
- '*+html .foo,.bar{display:inline}',
- [['.bar']]
+ '*+html .foo,.bar{color:red}',
+ '.bar{color:red}'
]
- }, { compatibility: 'ie8' })
+ }, { advanced: false, compatibility: 'ie8' })
)
.addBatch(
- selectorContext('ie7', {
+ optimizerContext('selectors - ie7', {
'+html': [
- '*+html .foo{display:inline}',
- [['*+html .foo']]
+ '*+html .foo{color:red}',
+ '*+html .foo{color:red}'
],
'+html - complex': [
- '*+html .foo,.bar{display:inline}',
- [['*+html .foo'], ['.bar']]
+ '*+html .foo,.bar{color:red}',
+ '*+html .foo,.bar{color:red}'
]
- }, { compatibility: 'ie7' })
+ }, { advanced: false, compatibility: 'ie7' })
)
.addBatch(
- selectorContext('+adjacentSpace', {
+ optimizerContext('selectors - adjacent space', {
'with whitespace': [
'div + nav{color:red}',
- [['div+ nav']]
+ 'div+ nav{color:red}'
],
'without whitespace': [
'div+nav{color:red}',
- [['div+ nav']]
+ 'div+ nav{color:red}'
]
- }, { compatibility: { selectors: { adjacentSpace: true } } })
+ }, { advanced: false, compatibility: { selectors: { adjacentSpace: true } } })
)
.addBatch(
- propertyContext('@background', {
+ optimizerContext('background', {
'none to 0 0': [
'a{background:none}',
- [['background', '0 0']]
+ 'a{background:0 0}'
],
'transparent to 0 0': [
'a{background:transparent}',
- [['background', '0 0']]
+ 'a{background:0 0}'
],
'any other': [
'a{background:red}',
- [['background', 'red']]
+ 'a{background:red}'
],
'none to other': [
'a{background:transparent no-repeat}',
- [['background', 'transparent', 'no-repeat']]
+ 'a{background:transparent no-repeat}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('@border-*-radius', {
+ optimizerContext('border-*-radius', {
'spaces around /': [
'a{border-radius:2em / 1em}',
- [['border-radius', '2em', '/', '1em']]
+ 'a{border-radius:2em/1em}'
],
'symmetric expanded to shorthand': [
'a{border-radius:1em 2em 3em 4em / 1em 2em 3em 4em}',
- [['border-radius', '1em', '2em', '3em', '4em']]
+ 'a{border-radius:1em 2em 3em 4em}'
],
'asymmetric kept as is': [
'a{border-top-left-radius:1em 2em}',
- [['border-top-left-radius', '1em', '2em']]
+ 'a{border-top-left-radius:1em 2em}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('@box-shadow', {
+ optimizerContext('box-shadow', {
'four zeros': [
'a{box-shadow:0 0 0 0}',
- [['box-shadow', '0', '0']]
+ 'a{box-shadow:0 0}'
],
'four zeros in vendor prefixed': [
'a{-webkit-box-shadow:0 0 0 0}',
- [['-webkit-box-shadow', '0', '0']]
+ 'a{-webkit-box-shadow:0 0}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('colors', {
+ optimizerContext('colors', {
'rgb to hex': [
'a{color:rgb(255,254,253)}',
- [['color', '#fffefd']]
+ 'a{color:#fffefd}'
],
'rgba not to hex': [
'a{color:rgba(255,254,253,.5)}',
- [['color', 'rgba(255,254,253,.5)']]
+ 'a{color:rgba(255,254,253,.5)}'
],
'hsl to hex': [
'a{color:hsl(240,100%,50%)}',
- [['color', '#00f']]
+ 'a{color:#00f}'
],
'hsla not to hex': [
'a{color:hsla(240,100%,50%,.5)}',
- [['color', 'hsla(240,100%,50%,.5)']]
+ 'a{color:hsla(240,100%,50%,.5)}'
],
'long hex to short hex': [
'a{color:#ff00ff}',
- [['color', '#f0f']]
+ 'a{color:#f0f}'
],
'hex to name': [
'a{color:#f00}',
- [['color', 'red']]
+ 'a{color:red}'
],
'name to hex': [
'a{color:white}',
- [['color', '#fff']]
+ 'a{color:#fff}'
],
'transparent black rgba to transparent': [
'a{color:rgba(0,0,0,0)}',
- [['color', 'transparent']]
+ 'a{color:transparent}'
],
'transparent non-black rgba': [
'a{color:rgba(255,0,0,0)}',
- [['color', 'rgba(255,0,0,0)']]
+ 'a{color:rgba(255,0,0,0)}'
],
'transparent black hsla to transparent': [
'a{color:hsla(0,0%,0%,0)}',
- [['color', 'transparent']]
+ 'a{color:transparent}'
],
'transparent non-black hsla': [
'a{color:rgba(240,0,0,0)}',
- [['color', 'rgba(240,0,0,0)']]
+ 'a{color:rgba(240,0,0,0)}'
],
'partial hex to name': [
'a{color:#f00000}',
- [['color', '#f00000']]
+ 'a{color:#f00000}'
],
'partial hex further down to name': [
'a{background:url(test.png) #f00000}',
- [['background', 'url(test.png)', '#f00000']]
+ 'a{background:url(test.png) #f00000}'
],
'partial name to hex': [
'a{color:greyish}',
- [['color', 'greyish']]
+ 'a{color:greyish}'
],
'partial name further down to hex': [
'a{background:url(test.png) blueish}',
- [['background', 'url(test.png)', 'blueish']]
+ 'a{background:url(test.png) blueish}'
],
'partial name as a suffix': [
'a{font-family:alrightsanslp-black}',
- [['font-family', 'alrightsanslp-black']]
+ 'a{font-family:alrightsanslp-black}'
],
'invalid rgba declaration - color': [
'a{color:rgba(255 0 0)}',
- [['color', 'rgba(255 0 0)']]
+ 'a{color:rgba(255 0 0)}'
],
'invalid rgba declaration - background': [
'a{background:rgba(255 0 0)}',
- [['background', 'rgba(255 0 0)']]
+ 'a{background:rgba(255 0 0)}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('colors - ie8 compatibility', {
+ optimizerContext('colors - ie8 compatibility', {
'transparent black rgba': [
'a{color:rgba(0,0,0,0)}',
- [['color', 'rgba(0,0,0,0)']]
+ 'a{color:rgba(0,0,0,0)}'
],
'transparent non-black rgba': [
'a{color:rgba(255,0,0,0)}',
- [['color', 'rgba(255,0,0,0)']]
+ 'a{color:rgba(255,0,0,0)}'
],
'transparent black hsla': [
'a{color:hsla(0,0%,0%,0)}',
- [['color', 'hsla(0,0%,0%,0)']]
+ 'a{color:hsla(0,0%,0%,0)}'
],
'transparent non-black hsla': [
'a{color:rgba(240,0,0,0)}',
- [['color', 'rgba(240,0,0,0)']]
+ 'a{color:rgba(240,0,0,0)}'
]
- }, { compatibility: 'ie8' })
+ }, { advanced: false, compatibility: 'ie8' })
)
.addBatch(
- propertyContext('colors - no optimizations', {
+ optimizerContext('colors - no optimizations', {
'long hex into short': [
'a{color:#ff00ff}',
- [['color', '#ff00ff']]
+ 'a{color:#ff00ff}'
],
'short hex into name': [
'a{color:#f00}',
- [['color', '#f00']]
+ 'a{color:#f00}'
],
'name into hex': [
'a{color:white}',
- [['color', 'white']]
+ 'a{color:white}'
]
- }, { compatibility: { properties: { colors: false } } })
+ }, { advanced: false, compatibility: { properties: { colors: false } } })
)
.addBatch(
- propertyContext('@filter', {
+ optimizerContext('filter', {
'spaces after comma': [
'a{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#cccccc\',endColorstr=\'#000000\', enabled=true)}',
- [['filter', 'progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#cccccc\', endColorstr=\'#000000\', enabled=true)']]
+ 'a{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#cccccc\', endColorstr=\'#000000\', enabled=true)}'
],
'single Alpha filter': [
'a{filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80)}',
- [['filter', 'alpha(Opacity=80)']]
+ 'a{filter:alpha(Opacity=80)}'
],
'single Chroma filter': [
'a{filter:progid:DXImageTransform.Microsoft.Chroma(color=#919191)}',
- [['filter', 'chroma(color=#919191)']]
+ 'a{filter:chroma(color=#919191)}'
],
'multiple filters': [
'a{filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80) progid:DXImageTransform.Microsoft.Chroma(color=#919191)}',
- [['filter', 'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)', 'progid:DXImageTransform.Microsoft.Chroma(color=#919191)']]
+ 'a{filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80) progid:DXImageTransform.Microsoft.Chroma(color=#919191)}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('@font', {
+ optimizerContext('font', {
'in shorthand': [
'a{font:normal 13px/20px sans-serif}',
- [['font', '400', '13px', '/', '20px', 'sans-serif']]
+ 'a{font:400 13px/20px sans-serif}'
],
'in shorthand with fractions': [
'a{font:bold .9em sans-serif}',
- [['font', '700', '.9em', 'sans-serif']]
+ 'a{font:700 .9em sans-serif}'
],
'with font wariant and style': [
'a{font:normal normal normal 13px/20px sans-serif}',
- [['font', 'normal', 'normal', 'normal', '13px', '/', '20px', 'sans-serif']]
+ 'a{font:normal normal normal 13px/20px sans-serif}'
],
'with mixed order of variant and style': [
'a{font:normal 300 normal 13px/20px sans-serif}',
- [['font', 'normal', '300', 'normal', '13px', '/', '20px', 'sans-serif']]
+ 'a{font:normal 300 normal 13px/20px sans-serif}'
],
'with mixed normal and weight': [
- 'a{font: normal small-caps 400 medium Georgia, sans-serif;}',
- [['font', 'normal', 'small-caps', '400', 'medium', 'Georgia', ',', 'sans-serif']]
+ 'a{font:normal small-caps 400 medium Georgia,sans-serif}',
+ 'a{font:normal small-caps 400 medium Georgia,sans-serif}'
],
'with line height': [
- 'a{font: 11px/normal sans-serif}',
- [['font', '11px', '/', 'normal', 'sans-serif']]
+ 'a{font:11px/normal sans-serif}',
+ 'a{font:11px/normal sans-serif}'
],
'with mixed bold weight and variant #1': [
'a{font:normal bold 17px sans-serif}',
- [['font', 'normal', '700', '17px', 'sans-serif']]
+ 'a{font:normal 700 17px sans-serif}'
],
'with mixed bold weight and variant #2': [
'a{font:bold normal 17px sans-serif}',
- [['font', '700', 'normal', '17px', 'sans-serif']]
+ 'a{font:700 normal 17px sans-serif}'
],
'with mixed bold weight and variant #3': [
'a{font:bold normal normal 17px sans-serif}',
- [['font', 'bold', 'normal', 'normal', '17px', 'sans-serif']] // pending #254
+ 'a{font:bold normal normal 17px sans-serif}' // pending #254
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('@font-weight', {
+ optimizerContext('font-weight', {
'normal to 400': [
'a{font-weight:normal}',
- [['font-weight', '400']]
+ 'a{font-weight:400}'
],
'bold to 700': [
'a{font-weight:bold}',
- [['font-weight', '700']]
+ 'a{font-weight:700}'
],
'any other': [
'a{font-weight:bolder}',
- [['font-weight', 'bolder']]
+ 'a{font-weight:bolder}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('ie hacks', {
+ optimizerContext('ie hacks', {
'underscore': [
'a{_width:101px}',
- null
+ ''
],
'star': [
'a{*width:101px}',
- null
+ ''
],
'backslash': [
'a{width:101px\\9}',
- [['width', '101px\\9']]
+ 'a{width:101px\\9}'
],
'bang': [
'a{color:red !ie}',
- null
+ ''
],
'before content': [
'a{*width:101px;color:red!important}',
- [['color', 'red!important']]
+ 'a{color:red!important}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('ie hacks in IE8 mode', {
+ optimizerContext('ie hacks in IE8 mode', {
'underscore': [
'a{_width:101px}',
- [['_width', '101px']]
+ 'a{_width:101px}'
],
'star': [
'a{*width:101px}',
- [['*width', '101px']]
+ 'a{*width:101px}'
],
'backslash': [
'a{width:101px\\9}',
- [['width', '101px\\9']]
+ 'a{width:101px\\9}'
],
'bang': [
'a{color:red !ie}',
- null
+ ''
]
- }, { compatibility: 'ie8' })
+ }, { advanced: false, compatibility: 'ie8' })
)
.addBatch(
- propertyContext('ie hacks in IE7 mode', {
+ optimizerContext('ie hacks in IE7 mode', {
'underscore': [
'a{_width:101px}',
- [['_width', '101px']]
+ 'a{_width:101px}'
],
'star': [
'a{*width:101px}',
- [['*width', '101px']]
+ 'a{*width:101px}'
],
'backslash': [
'a{width:101px\\9}',
- [['width', '101px\\9']]
+ 'a{width:101px\\9}'
],
'bang': [
'a{color:red !ie}',
- [['color', 'red !ie']]
+ 'a{color:red !ie}'
]
- }, { compatibility: 'ie7' })
+ }, { advanced: false, compatibility: 'ie7' })
)
.addBatch(
- propertyContext('important', {
+ optimizerContext('important', {
'minified': [
'a{color:red!important}',
- [['color', 'red!important']]
+ 'a{color:red!important}'
],
'space before !': [
'a{color:red !important}',
- [['color', 'red!important']]
+ 'a{color:red!important}',
],
'space after !': [
'a{color:red! important}',
- [['color', 'red!important']]
+ 'a{color:red!important}'
]
- }, { compatibility: 'ie8' })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('@outline', {
+ optimizerContext('outline', {
'none to 0': [
'a{outline:none}',
- [['outline', '0']]
+ 'a{outline:0}'
],
'any other': [
'a{outline:10px}',
- [['outline', '10px']]
+ 'a{outline:10px}'
],
'none and any other': [
'a{outline:none solid 1px}',
- [['outline', 'none', 'solid', '1px']]
+ 'a{outline:none solid 1px}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('rounding', {
+ optimizerContext('rounding', {
'pixels': [
'a{transform:translateY(123.31135px)}',
- [['transform', 'translateY(123.311px)']]
+ 'a{transform:translateY(123.311px)}'
],
'percents': [
'a{left:20.1231%}',
- [['left', '20.1231%']]
+ 'a{left:20.1231%}'
],
'ems': [
'a{left:1.1231em}',
- [['left', '1.1231em']]
+ 'a{left:1.1231em}'
]
- }, { roundingPrecision: 3 })
+ }, { advanced: false, roundingPrecision: 3 })
)
.addBatch(
- propertyContext('rounding disabled', {
+ optimizerContext('rounding disabled', {
'pixels': [
'a{transform:translateY(123.31135px)}',
- [['transform', 'translateY(123.31135px)']]
+ 'a{transform:translateY(123.31135px)}'
],
'percents': [
'a{left:20.1231%}',
- [['left', '20.1231%']]
+ 'a{left:20.1231%}'
],
'ems': [
'a{left:1.1231em}',
- [['left', '1.1231em']]
+ 'a{left:1.1231em}'
]
- }, { roundingPrecision: -1 })
+ }, { advanced: false, roundingPrecision: -1 })
)
.addBatch(
- propertyContext('rounding disabled when option value not castable to int', {
+ optimizerContext('rounding disabled when option value not castable to int', {
'pixels': [
'a{transform:translateY(123.31135px)}',
- [['transform', 'translateY(123.31135px)']]
+ 'a{transform:translateY(123.31135px)}'
],
'percents': [
'a{left:20.1231%}',
- [['left', '20.1231%']]
+ 'a{left:20.1231%}'
],
'ems': [
'a{left:1.1231em}',
- [['left', '1.1231em']]
+ 'a{left:1.1231em}'
]
- }, { roundingPrecision: '\'-1\'' })
+ }, { advanced: false, roundingPrecision: '\'-1\'' })
)
.addBatch(
- propertyContext('units', {
+ optimizerContext('units', {
'pixels': [
'a{width:0px}',
- [['width', '0']]
+ 'a{width:0}'
],
'degrees': [
'div{background:linear-gradient(0deg,red,#fff)}',
- [['background', 'linear-gradient(0deg,red,#fff)']]
+ 'div{background:linear-gradient(0deg,red,#fff)}'
],
'degrees when not mixed': [
'div{transform:rotate(0deg) skew(0deg)}',
- [['transform', 'rotate(0)', 'skew(0)']]
+ 'div{transform:rotate(0) skew(0)}'
],
'non-zero degrees when not mixed': [
'div{transform:rotate(10deg) skew(.5deg)}',
- [['transform', 'rotate(10deg)', 'skew(.5deg)']]
+ 'div{transform:rotate(10deg) skew(.5deg)}'
],
'ch': [
'div{width:0ch;height:0ch}',
- [['width', '0'], ['height', '0']]
+ 'div{width:0;height:0}'
],
'rem': [
'div{width:0rem;height:0rem}',
- [['width', '0'], ['height', '0']]
+ 'div{width:0;height:0}'
],
'vh': [
'div{width:0vh;height:0vh}',
- [['width', '0'], ['height', '0']]
+ 'div{width:0;height:0}'
],
'vm': [
'div{width:0vm;height:0vm}',
- [['width', '0'], ['height', '0']]
+ 'div{width:0;height:0}'
],
'vmax': [
'div{width:0vmax;height:0vmax}',
- [['width', '0'], ['height', '0']]
+ 'div{width:0;height:0}'
],
'vmin': [
'div{width:0vmin;height:0vmin}',
- [['width', '0'], ['height', '0']]
+ 'div{width:0;height:0}'
],
'vw': [
'div{width:0vw;height:0vw}',
- [['width', '0'], ['height', '0']]
+ 'div{width:0;height:0}'
],
'mixed units': [
'a{margin:0em 0rem 0px 0pt}',
- [['margin', '0']]
+ 'a{margin:0}'
],
'mixed values #1': [
'a{padding:10px 0em 30% 0rem}',
- [['padding', '10px', '0', '30%', '0']]
+ 'a{padding:10px 0 30% 0}'
],
'mixed values #2': [
'a{padding:10ch 0vm 30vmin 0vw}',
- [['padding', '10ch', '0', '30vmin', '0']]
+ 'a{padding:10ch 0 30vmin 0}'
],
'inside calc': [
'a{font-size:calc(100% + 0px)}',
- [['font-size', 'calc(100% + 0px)']]
+ 'a{font-size:calc(100% + 0px)}'
],
'flex': [
- 'a{flex: 1 0 0%}',
- [['flex', '1', '0', '0%']]
+ 'a{flex:1 0 0%}',
+ 'a{flex:1 0 0%}'
],
'flex–basis': [
'a{flex-basis:0%}',
- [['flex-basis', '0%']]
+ 'a{flex-basis:0%}'
],
'prefixed flex': [
- 'a{-ms-flex:1 0 0px;-webkit-flex:1 0 0px;}',
- [['-ms-flex', '1', '0', '0px'], ['-webkit-flex', '1', '0', '0px']]
+ 'a{-ms-flex:1 0 0px;-webkit-flex:1 0 0px}',
+ 'a{-ms-flex:1 0 0px;-webkit-flex:1 0 0px}'
],
'prefixed flex–basis': [
'a{-webkit-flex-basis:0px}',
- [['-webkit-flex-basis', '0px']]
+ 'a{-webkit-flex-basis:0px}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('units in compatibility mode', {
+ optimizerContext('units in compatibility mode', {
'pixels': [
'a{width:0px}',
- [['width', '0']]
+ 'a{width:0}'
],
'mixed units': [
'a{margin:0em 0rem 0px 0pt}',
- [['margin', '0', '0rem', '0', '0']]
+ 'a{margin:0 0rem 0 0}'
],
'mixed values #1': [
'a{padding:10px 0em 30% 0rem}',
- [['padding', '10px', '0', '30%', '0rem']]
+ 'a{padding:10px 0 30% 0rem}'
],
'mixed values #2': [
'a{padding:10ch 0vm 30vmin 0vw}',
- [['padding', '10ch', '0vm', '30vmin', '0vw']]
+ 'a{padding:10ch 0vm 30vmin 0vw}'
]
- }, { compatibility: 'ie8' })
+ }, { advanced: false, compatibility: 'ie8' })
)
.addBatch(
- propertyContext('zeros', {
+ optimizerContext('zeros', {
'-0 to 0': [
'a{margin:-0}',
- [['margin', '0']]
+ 'a{margin:0}'
],
'-0px to 0': [
'a{margin:-0px}',
- [['margin', '0']]
+ 'a{margin:0}'
],
'-0% to 0': [
'a{width:-0%}',
- [['width', '0']]
+ 'a{width:0}'
],
'missing': [
'a{opacity:1.}',
- [['opacity', '1']]
+ 'a{opacity:1}'
],
'multiple': [
'a{margin:-0 -0 -0 -0}',
- [['margin', '0']]
+ 'a{margin:0}'
],
'keeps negative non-zero': [
'a{margin:-0.5em}',
- [['margin', '-.5em']]
+ 'a{margin:-.5em}'
],
'inside names #1': [
'div{animation-name:test-0-bounce}',
- [['animation-name', 'test-0-bounce']]
+ 'div{animation-name:test-0-bounce}'
],
'inside names #2': [
'div{animation-name:test-0bounce}',
- [['animation-name', 'test-0bounce']]
+ 'div{animation-name:test-0bounce}'
],
'inside names #3': [
'div{animation-name:test-0px}',
- [['animation-name', 'test-0px']]
+ 'div{animation-name:test-0px}'
],
'strips leading from value': [
'a{padding:010px 0015px}',
- [['padding', '10px', '15px']]
+ 'a{padding:10px 15px}'
],
'strips leading from fractions': [
'a{margin:-0.5em}',
- [['margin', '-.5em']]
+ 'a{margin:-.5em}'
],
'strips trailing from opacity': [
'a{opacity:1.0}',
- [['opacity', '1']]
+ 'a{opacity:1}'
],
'.0 to 0': [
'a{margin:.0 .0 .0 .0}',
- [['margin', '0']]
+ 'a{margin:0}'
],
'fraction zeros': [
'a{margin:10.0em 15.50em 10.01em 0.0em}',
- [['margin', '10em', '15.5em', '10.01em', '0']]
+ 'a{margin:10em 15.5em 10.01em 0}'
],
'fraction zeros after rounding': [
'a{margin:10.0010px}',
- [['margin', '10px']]
+ 'a{margin:10px}'
],
'four zeros into one': [
'a{margin:0 0 0 0}',
- [['margin', '0']]
+ 'a{margin:0}'
],
'rect zeros': [
'a{clip:rect(0px 0px 0px 0px)}',
- [['clip', 'rect(0 0 0 0)']]
+ 'a{clip:rect(0 0 0 0)}'
],
'rect zeros with non-zero value': [
'a{clip:rect(0.5% 0px 0px 0px)}',
- [['clip', 'rect(.5% 0 0 0)']]
+ 'a{clip:rect(.5% 0 0 0)}'
],
'rect zeros with commas': [
'a{clip:rect(0px, 0px, 0px, 0px)}',
- [['clip', 'rect(0,0,0,0)']]
+ 'a{clip:rect(0,0,0,0)}'
],
'height': [
'a{height:0%}',
- [['height', '0%']]
+ 'a{height:0%}'
],
'min-height': [
'a{min-height:0%}',
- [['min-height', '0']]
+ 'a{min-height:0}'
],
'max-height': [
'a{max-height:0%}',
- [['max-height', '0%']]
+ 'a{max-height:0%}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('zeros with disabled zeroUnits', {
+ optimizerContext('zeros with disabled zeroUnits', {
'10.0em': [
'a{margin:10.0em}',
- [['margin', '10em']]
+ 'a{margin:10em}'
],
'0px': [
'a{margin:0px}',
- [['margin', '0px']]
+ 'a{margin:0px}'
],
'0px 0px': [
'a{margin:0px 0px}',
- [['margin', '0px', '0px']]
+ 'a{margin:0px 0px}'
],
'0deg': [
'div{transform:rotate(0deg) skew(0deg)}',
- [['transform', 'rotate(0deg)', 'skew(0deg)']]
+ 'div{transform:rotate(0deg) skew(0deg)}'
],
'0%': [
'a{height:0%}',
- [['height', '0%']]
+ 'a{height:0%}'
],
'10%': [
'a{width:10%}',
- [['width', '10%']]
+ 'a{width:10%}'
]
- }, { compatibility: { properties: { zeroUnits: false } } })
+ }, { advanced: false, compatibility: { properties: { zeroUnits: false } } })
)
.addBatch(
- propertyContext('comments', {
+ optimizerContext('comments', {
'comment': [
- 'a{__ESCAPED_COMMENT_SPECIAL_CLEAN_CSS0__color:red__ESCAPED_COMMENT_SPECIAL_CLEAN_CSS1__}',
- ['__ESCAPED_COMMENT_SPECIAL_CLEAN_CSS0__', '__ESCAPED_COMMENT_SPECIAL_CLEAN_CSS1__', ['color', 'red']]
+ 'a{/*! comment 1 */color:red/*! comment 2 */}',
+ 'a{/*! comment 1 */color:red/*! comment 2 */}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('whitespace', {
+ optimizerContext('whitespace', {
'stripped spaces': [
'div{text-shadow:rgba(255,1,1,.5) 1px}',
- [['text-shadow', 'rgba(255,1,1,.5)', '1px']]
+ 'div{text-shadow:rgba(255,1,1,.5) 1px}'
],
'calc': [
'a{width:-moz-calc(100% - 1em);width:calc(100% - 1em)}',
- [['width', '-moz-calc(100% - 1em)'], ['width', 'calc(100% - 1em)']]
+ 'a{width:-moz-calc(100% - 1em);width:calc(100% - 1em)}'
],
'empty body': [
'a{}',
- null
+ ''
],
'in a body': [
'a{ \n }',
- null
+ ''
],
'after calc()': [
'div{margin:calc(100% - 21px) 1px}',
- [['margin', 'calc(100% - 21px)', '1px']]
+ 'div{margin:calc(100% - 21px) 1px}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('time units', {
+ optimizerContext('time units', {
'positive miliseconds to seconds': [
'div{transition-duration:500ms}',
- [['transition-duration', '.5s']]
+ 'div{transition-duration:.5s}'
],
'negative miliseconds to seconds': [
'div{transition-duration:-500ms}',
- [['transition-duration', '-.5s']]
+ 'div{transition-duration:-.5s}'
],
'miliseconds to seconds when results in a too long value': [
'div{transition-duration:1515ms}',
- [['transition-duration', '1515ms']]
+ 'div{transition-duration:1515ms}'
],
'zero miliseconds to seconds': [
'div{transition-duration:0ms}',
- [['transition-duration', '0s']]
+ 'div{transition-duration:0s}'
],
'positive seconds to miliseconds': [
'div{transition-duration:0.005s}',
- [['transition-duration', '5ms']]
+ 'div{transition-duration:5ms}'
],
'negative seconds to miliseconds': [
'div{transition-duration:-0.005s}',
- [['transition-duration', '-5ms']]
+ 'div{transition-duration:-5ms}'
],
'seconds to miliseconds when results in a too long value': [
'div{transition-duration:1.2s}',
- [['transition-duration', '1.2s']]
+ 'div{transition-duration:1.2s}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('length units', {
+ optimizerContext('length units', {
'px to in': [
'div{left:480px}',
- [['left', '480px']]
+ 'div{left:480px}'
],
'px to pc': [
'div{left:32px}',
- [['left', '32px']]
+ 'div{left:32px}'
],
'px to pt': [
'div{left:120px}',
- [['left', '120px']]
+ 'div{left:120px}'
]
- })
+ }, { advanced: false })
)
.addBatch(
- propertyContext('length units in compatibility mode', {
+ optimizerContext('length units in compatibility mode', {
'px to in': [
'div{left:480px}',
- [['left', '480px']]
+ 'div{left:480px}'
],
'px to pc': [
'div{left:32px}',
- [['left', '32px']]
+ 'div{left:32px}'
],
'px to pt': [
'div{left:120px}',
- [['left', '120px']]
+ 'div{left:120px}'
]
- }, { compatibility: 'ie8' })
+ }, { advanced: false, compatibility: 'ie8' })
)
.addBatch(
- propertyContext('length units when turned on', {
+ optimizerContext('length units when turned on', {
'positive px to in': [
'div{left:480px}',
- [['left', '5in']]
+ 'div{left:5in}'
],
'negative px to in': [
'div{left:-96px}',
- [['left', '-1in']]
+ 'div{left:-1in}'
],
'positive px to pc': [
'div{left:32px}',
- [['left', '2pc']]
+ 'div{left:2pc}'
],
'negative px to pc': [
'div{left:-160px}',
- [['left', '-10pc']]
+ 'div{left:-10pc}'
],
'positive px to pt': [
'div{left:120px}',
- [['left', '90pt']]
+ 'div{left:90pt}'
],
'negative px to pt': [
'div{left:-120px}',
- [['left', '-90pt']]
+ 'div{left:-90pt}'
],
'in calc': [
'div{left:calc(100% - 480px)}',
- [['left', 'calc(100% - 5in)']]
+ 'div{left:calc(100% - 5in)}'
],
'in transform': [
'div{transform:translateY(32px)}',
- [['transform', 'translateY(2pc)']]
+ 'div{transform:translateY(2pc)}'
]
- }, { compatibility: { properties: { shorterLengthUnits: true } } })
+ }, { advanced: false, compatibility: { properties: { shorterLengthUnits: true } } })
)
.addBatch(
- propertyContext('length units when turned on selectively', {
+ optimizerContext('length units when turned on selectively', {
'px to in': [
'div{left:480px}',
- [['left', '30pc']]
+ 'div{left:30pc}'
],
'px to pc': [
'div{left:32px}',
- [['left', '2pc']]
+ 'div{left:2pc}'
],
'px to pt': [
'div{left:120px}',
- [['left', '120px']]
+ 'div{left:120px}'
]
- }, { compatibility: { properties: { shorterLengthUnits: true }, units: { in: false, pt: false } } })
+ }, { advanced: false, compatibility: { properties: { shorterLengthUnits: true }, units: { in: false, pt: false } } })
)
.export(module);
--- /dev/null
+var vows = require('vows');
+var assert = require('assert');
+var tokenize = require('../../lib/tokenizer/tokenize');
+var extractProperties = require('../../lib/optimizer/extract-properties');
+
+vows.describe(extractProperties)
+ .addBatch({
+ 'no properties': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, []);
+ }
+ },
+ 'no valid properties': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{:red}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, []);
+ }
+ },
+ 'one property': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{color:red}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'color',
+ 'red',
+ 'color',
+ ['property', ['property-name', 'color', [[1, 2, undefined]]], ['property-value', 'red', [[1, 8, undefined]]]],
+ 'color:red',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ },
+ 'one important property': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{color:red!important}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'color',
+ 'red!important',
+ 'color',
+ ['property', ['property-name', 'color', [[1, 2, undefined]]], ['property-value', 'red!important', [[1, 8, undefined]]]],
+ 'color:red!important',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ },
+ 'one property - simple selector': {
+ 'topic': function () {
+ return extractProperties(tokenize('#one span{color:red}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'color',
+ 'red',
+ 'color',
+ ['property', ['property-name', 'color', [[1, 10, undefined]]], ['property-value', 'red', [[1, 16, undefined]]]],
+ 'color:red',
+ [['#one span', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ },
+ 'one property - variable': {
+ 'topic': function () {
+ return extractProperties(tokenize('#one span{--color:red}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, []);
+ }
+ },
+ 'one property - block variable': {
+ 'topic': function () {
+ return extractProperties(tokenize('#one span{--color:{color:red;display:block};}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, []);
+ }
+ },
+ 'one property - complex selector': {
+ 'topic': function () {
+ return extractProperties(tokenize('.one{color:red}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'color',
+ 'red',
+ 'color',
+ ['property', ['property-name', 'color', [[1, 5, undefined]]], ['property-value', 'red', [[1, 11, undefined]]]],
+ 'color:red',
+ [['.one', [[1, 0, undefined]]]],
+ false
+ ]
+ ]);
+ }
+ },
+ 'two properties': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{color:red;display:block}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'color',
+ 'red',
+ 'color',
+ ['property', ['property-name', 'color', [[1, 2, undefined]]], ['property-value', 'red', [[1, 8, undefined]]]],
+ 'color:red',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ],
+ [
+ 'display',
+ 'block',
+ 'display',
+ ['property', ['property-name', 'display', [[1, 12, undefined]]], ['property-value', 'block', [[1, 20, undefined]]]],
+ 'display:block',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ },
+ 'from @media': {
+ 'topic': function () {
+ return extractProperties(tokenize('@media{a{color:red;display:block}p{color:red}}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'color',
+ 'red',
+ 'color',
+ ['property', ['property-name', 'color', [[1, 9, undefined]]], ['property-value', 'red', [[1, 15, undefined]]]],
+ 'color:red',
+ [['a', [[1, 7, undefined]]]],
+ true
+ ],
+ [
+ 'display',
+ 'block',
+ 'display',
+ ['property', ['property-name', 'display', [[1, 19, undefined]]], ['property-value', 'block', [[1, 27, undefined]]]],
+ 'display:block',
+ [['a', [[1, 7, undefined]]]],
+ true
+ ],
+ [
+ 'color',
+ 'red',
+ 'color',
+ ['property', ['property-name', 'color', [[1, 35, undefined]]], ['property-value', 'red', [[1, 41, undefined]]]],
+ 'color:red',
+ [['p', [[1, 33, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ }
+ })
+ .addBatch({
+ 'name root special cases': {
+ 'vendor prefix': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{-moz-transform:none}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ '-moz-transform',
+ 'none',
+ 'transform',
+ ['property', ['property-name', '-moz-transform', [[1, 2, undefined]]], ['property-value', 'none', [[1, 17, undefined]]]],
+ '-moz-transform:none',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ },
+ 'list-style': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{list-style:none}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'list-style',
+ 'none',
+ 'list-style',
+ ['property', ['property-name', 'list-style', [[1, 2, undefined]]], ['property-value', 'none', [[1, 13, undefined]]]],
+ 'list-style:none',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ },
+ 'border-radius': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{border-top-left-radius:none}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'border-top-left-radius',
+ 'none',
+ 'border-radius',
+ ['property', ['property-name', 'border-top-left-radius', [[1, 2, undefined]]], ['property-value', 'none', [[1, 25, undefined]]]],
+ 'border-top-left-radius:none',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ },
+ 'vendor prefixed border-radius': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{-webkit-border-top-left-radius:none}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ '-webkit-border-top-left-radius',
+ 'none',
+ 'border-radius',
+ ['property', ['property-name', '-webkit-border-top-left-radius', [[1, 2, undefined]]], ['property-value', 'none', [[1, 33, undefined]]]],
+ '-webkit-border-top-left-radius:none',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ },
+ 'border-image-width': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{border-image-width:2px}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'border-image-width',
+ '2px',
+ 'border-image',
+ ['property', ['property-name', 'border-image-width', [[1, 2, undefined]]], ['property-value', '2px', [[1, 21, undefined]]]],
+ 'border-image-width:2px',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ },
+ 'border-color': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{border-color:red}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'border-color',
+ 'red',
+ 'border',
+ ['property', ['property-name', 'border-color', [[1, 2, undefined]]], ['property-value', 'red', [[1, 15, undefined]]]],
+ 'border-color:red',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ },
+ 'border-top-style': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{border-top-style:none}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'border-top-style',
+ 'none',
+ 'border-top',
+ ['property', ['property-name', 'border-top-style', [[1, 2, undefined]]], ['property-value', 'none', [[1, 19, undefined]]]],
+ 'border-top-style:none',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ },
+ 'border-top': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{border-top:none}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'border-top',
+ 'none',
+ 'border',
+ ['property', ['property-name', 'border-top', [[1, 2, undefined]]], ['property-value', 'none', [[1, 13, undefined]]]],
+ 'border-top:none',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ },
+ 'border-collapse': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{border-collapse:collapse}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'border-collapse',
+ 'collapse',
+ 'border-collapse',
+ ['property', ['property-name', 'border-collapse', [[1, 2, undefined]]], ['property-value', 'collapse', [[1, 18, undefined]]]],
+ 'border-collapse:collapse',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ },
+ 'text-shadow': {
+ 'topic': function () {
+ return extractProperties(tokenize('a{text-shadow:none}', {})[0]);
+ },
+ 'has no properties': function (tokens) {
+ assert.deepEqual(tokens, [
+ [
+ 'text-shadow',
+ 'none',
+ 'text-shadow',
+ ['property', ['property-name', 'text-shadow', [[1, 2, undefined]]], ['property-value', 'none', [[1, 14, undefined]]]],
+ 'text-shadow:none',
+ [['a', [[1, 0, undefined]]]],
+ true
+ ]
+ ]);
+ }
+ }
+ }
+ })
+ .export(module);
var assert = require('assert');
var tokenize = require('../../lib/tokenizer/tokenize');
-var extractProperties = require('../../lib/selectors/extractor');
-var canReorder = require('../../lib/selectors/reorderable').canReorder;
-var canReorderSingle = require('../../lib/selectors/reorderable').canReorderSingle;
+var extractProperties = require('../../lib/optimizer/extract-properties');
+var canReorder = require('../../lib/optimizer/reorderable').canReorder;
+var canReorderSingle = require('../../lib/optimizer/reorderable').canReorderSingle;
function propertiesIn(source) {
return extractProperties(tokenize(source, { options: {} })[0]);
var wrapForOptimizing = require('../../lib/properties/wrap-for-optimizing').all;
var populateComponents = require('../../lib/properties/populate-components');
var Validator = require('../../lib/properties/validator');
-var Compatibility = require('../../lib/utils/compatibility');
+var compatibility = require('../../lib/utils/compatibility');
var breakUp = require('../../lib/properties/break-up');
function _breakUp(properties) {
- var validator = new Validator(new Compatibility().toOptions());
+ var validator = new Validator(compatibility());
var wrapped = wrapForOptimizing(properties);
populateComponents(wrapped, validator, []);
'background': {
'inherit': {
'topic': function () {
- return _breakUp([[['background'], ['inherit']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'inherit']
+ ]
+ ]);
},
'has 8 components': function (components) {
assert.lengthOf(components, 8);
},
'has background-image': function (components) {
assert.deepEqual(components[0].name, 'background-image');
- assert.deepEqual(components[0].value, [['inherit']]);
+ assert.deepEqual(components[0].value, [['property-value', 'inherit']]);
},
'has background-position': function (components) {
assert.deepEqual(components[1].name, 'background-position');
- assert.deepEqual(components[1].value, [['inherit']]);
+ assert.deepEqual(components[1].value, [['property-value', 'inherit']]);
},
'has background-size': function (components) {
assert.deepEqual(components[2].name, 'background-size');
- assert.deepEqual(components[2].value, [['inherit']]);
+ assert.deepEqual(components[2].value, [['property-value', 'inherit']]);
},
'has background-repeat': function (components) {
assert.deepEqual(components[3].name, 'background-repeat');
- assert.deepEqual(components[3].value, [['inherit']]);
+ assert.deepEqual(components[3].value, [['property-value', 'inherit']]);
},
'has background-attachment': function (components) {
assert.deepEqual(components[4].name, 'background-attachment');
- assert.deepEqual(components[4].value, [['scroll']]);
+ assert.deepEqual(components[4].value, [['property-value', 'scroll']]);
},
'has background-origin': function (components) {
assert.deepEqual(components[5].name, 'background-origin');
- assert.deepEqual(components[5].value, [['inherit']]);
+ assert.deepEqual(components[5].value, [['property-value', 'inherit']]);
},
'has background-clip': function (components) {
assert.deepEqual(components[6].name, 'background-clip');
- assert.deepEqual(components[6].value, [['inherit']]);
+ assert.deepEqual(components[6].value, [['property-value', 'inherit']]);
},
'has background-color': function (components) {
assert.deepEqual(components[7].name, 'background-color');
- assert.deepEqual(components[7].value, [['inherit']]);
+ assert.deepEqual(components[7].value, [['property-value', 'inherit']]);
}
},
'all': {
'topic': function () {
- return _breakUp([[['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['repeat'], ['no-repeat'], ['2px'], ['3px'], ['/'], ['50%'], ['60%'], ['fixed'], ['padding-box'], ['border-box'], ['red']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', 'repeat'],
+ ['property-value', 'no-repeat'],
+ ['property-value', '2px'],
+ ['property-value', '3px'],
+ ['property-value', '/'],
+ ['property-value', '50%'],
+ ['property-value', '60%'],
+ ['property-value', 'fixed'],
+ ['property-value', 'padding-box'],
+ ['property-value', 'border-box'],
+ ['property-value', 'red']
+ ]
+ ]);
},
'has 8 components': function (components) {
assert.lengthOf(components, 8);
},
'has background-image': function (components) {
assert.deepEqual(components[0].name, 'background-image');
- assert.deepEqual(components[0].value, [['__ESCAPED_URL_CLEAN_CSS0__']]);
+ assert.deepEqual(components[0].value, [['property-value', 'url(image.png)']]);
},
'has background-position': function (components) {
assert.deepEqual(components[1].name, 'background-position');
- assert.deepEqual(components[1].value, [['2px'], ['3px']]);
+ assert.deepEqual(components[1].value, [['property-value', '2px'], ['property-value', '3px']]);
},
'has background-size': function (components) {
assert.deepEqual(components[2].name, 'background-size');
- assert.deepEqual(components[2].value, [['50%'], ['60%']]);
+ assert.deepEqual(components[2].value, [['property-value', '50%'], ['property-value', '60%']]);
},
'has background-repeat': function (components) {
assert.deepEqual(components[3].name, 'background-repeat');
- assert.deepEqual(components[3].value, [['repeat'], ['no-repeat']]);
+ assert.deepEqual(components[3].value, [['property-value', 'repeat'], ['property-value', 'no-repeat']]);
},
'has background-attachment': function (components) {
assert.deepEqual(components[4].name, 'background-attachment');
- assert.deepEqual(components[4].value, [['fixed']]);
+ assert.deepEqual(components[4].value, [['property-value', 'fixed']]);
},
'has background-origin': function (components) {
assert.deepEqual(components[5].name, 'background-origin');
- assert.deepEqual(components[5].value, [['padding-box']]);
+ assert.deepEqual(components[5].value, [['property-value', 'padding-box']]);
},
'has background-clip': function (components) {
assert.deepEqual(components[6].name, 'background-clip');
- assert.deepEqual(components[6].value, [['border-box']]);
+ assert.deepEqual(components[6].value, [['property-value', 'border-box']]);
},
'has background-color': function (components) {
assert.deepEqual(components[7].name, 'background-color');
- assert.deepEqual(components[7].value, [['red']]);
+ assert.deepEqual(components[7].value, [['property-value', 'red']]);
}
},
'no size': {
'topic': function () {
- return _breakUp([[['background'], ['bottom']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'bottom']
+ ]
+ ]);
},
'has 8 components': function (components) {
assert.lengthOf(components, 8);
},
'has background-position': function (components) {
assert.deepEqual(components[1].name, 'background-position');
- assert.deepEqual(components[1].value, [['bottom']]);
+ assert.deepEqual(components[1].value, [['property-value', 'bottom']]);
},
'has background-size': function (components) {
assert.deepEqual(components[2].name, 'background-size');
- assert.deepEqual(components[2].value, [['auto']]);
+ assert.deepEqual(components[2].value, [['property-value', 'auto']]);
}
},
'shorthand size & position': {
'topic': function () {
- return _breakUp([[['background'], ['2px'], ['/'], ['50px']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', '2px'],
+ ['property-value', '/'],
+ ['property-value', '50px']
+ ]
+ ]);
},
'has 8 components': function (components) {
assert.lengthOf(components, 8);
},
'has background-position': function (components) {
assert.deepEqual(components[1].name, 'background-position');
- assert.deepEqual(components[1].value, [['2px']]);
+ assert.deepEqual(components[1].value, [['property-value', '2px']]);
},
'has background-size': function (components) {
assert.deepEqual(components[2].name, 'background-size');
- assert.deepEqual(components[2].value, [['50px']]);
+ assert.deepEqual(components[2].value, [['property-value', '50px']]);
}
},
'size & position joined together': {
'topic': function () {
- return _breakUp([[['background'], ['2px/50px']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', '2px'],
+ ['property-value', '/'],
+ ['property-value', '50px']
+ ]
+ ]);
},
'has 8 components': function (components) {
assert.lengthOf(components, 8);
},
'has background-position': function (components) {
assert.deepEqual(components[1].name, 'background-position');
- assert.deepEqual(components[1].value, [['2px']]);
+ assert.deepEqual(components[1].value, [['property-value', '2px']]);
},
'has background-size': function (components) {
assert.deepEqual(components[2].name, 'background-size');
- assert.deepEqual(components[2].value, [['50px']]);
+ assert.deepEqual(components[2].value, [['property-value', '50px']]);
}
},
'size & position joined together with 4 values': {
'topic': function () {
- return _breakUp([[['background'], ['5px'], ['2px/50px'], ['30px']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', '5px'],
+ ['property-value', '2px'],
+ ['property-value', '/'],
+ ['property-value', '50px'],
+ ['property-value', '30px']
+ ]
+ ]);
},
'has 8 components': function (components) {
assert.lengthOf(components, 8);
},
'has background-position': function (components) {
assert.deepEqual(components[1].name, 'background-position');
- assert.deepEqual(components[1].value, [['5px'], ['2px']]);
+ assert.deepEqual(components[1].value, [['property-value', '5px'], ['property-value', '2px']]);
},
'has background-size': function (components) {
assert.deepEqual(components[2].name, 'background-size');
- assert.deepEqual(components[2].value, [['50px'], ['30px']]);
+ assert.deepEqual(components[2].value, [['property-value', '50px'], ['property-value', '30px']]);
}
},
'clip to origin': {
'topic': function () {
- return _breakUp([[['background'], ['padding-box']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'padding-box']
+ ]
+ ]);
},
'has 8 components': function (components) {
assert.lengthOf(components, 8);
},
'has background-origin': function (components) {
assert.deepEqual(components[5].name, 'background-origin');
- assert.deepEqual(components[5].value, [['padding-box']]);
+ assert.deepEqual(components[5].value, [['property-value', 'padding-box']]);
},
'has background-clip': function (components) {
assert.deepEqual(components[6].name, 'background-clip');
- assert.deepEqual(components[6].value, [['padding-box']]);
+ assert.deepEqual(components[6].value, [['property-value', 'padding-box']]);
}
}
},
'border': {
'inherit': {
'topic': function () {
- return _breakUp([[['border'], ['inherit']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'border'],
+ ['property-value', 'inherit']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has border-width': function (components) {
assert.deepEqual(components[0].name, 'border-width');
- assert.deepEqual(components[0].value, [['inherit']]);
+ assert.deepEqual(components[0].value, [['property-value', 'inherit']]);
},
'has border-style': function (components) {
assert.deepEqual(components[1].name, 'border-style');
- assert.deepEqual(components[1].value, [['inherit']]);
+ assert.deepEqual(components[1].value, [['property-value', 'inherit']]);
},
'has border-color': function (components) {
assert.deepEqual(components[2].name, 'border-color');
- assert.deepEqual(components[2].value, [['inherit']]);
+ assert.deepEqual(components[2].value, [['property-value', 'inherit']]);
}
},
'3 inherits': {
'topic': function () {
- return _breakUp([[['border'], ['inherit'], ['inherit'], ['inherit']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'border'],
+ ['property-value', 'inherit'],
+ ['property-value', 'inherit'],
+ ['property-value', 'inherit']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has border-width': function (components) {
assert.deepEqual(components[0].name, 'border-width');
- assert.deepEqual(components[0].value, [['inherit']]);
+ assert.deepEqual(components[0].value, [['property-value', 'inherit']]);
},
'has border-style': function (components) {
assert.deepEqual(components[1].name, 'border-style');
- assert.deepEqual(components[1].value, [['inherit']]);
+ assert.deepEqual(components[1].value, [['property-value', 'inherit']]);
},
'has border-color': function (components) {
assert.deepEqual(components[2].name, 'border-color');
- assert.deepEqual(components[2].value, [['inherit']]);
+ assert.deepEqual(components[2].value, [['property-value', 'inherit']]);
}
},
'all values in correct order': {
'topic': function () {
- return _breakUp([[['border'], ['1px'], ['solid'], ['red']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'border'],
+ ['property-value', '1px'],
+ ['property-value', 'solid'],
+ ['property-value', 'red']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has border-width': function (components) {
assert.deepEqual(components[0].name, 'border-width');
- assert.deepEqual(components[0].value, [['1px']]);
+ assert.deepEqual(components[0].value, [['property-value', '1px']]);
},
'has border-style': function (components) {
assert.deepEqual(components[1].name, 'border-style');
- assert.deepEqual(components[1].value, [['solid']]);
+ assert.deepEqual(components[1].value, [['property-value', 'solid']]);
},
'has border-color': function (components) {
assert.deepEqual(components[2].name, 'border-color');
- assert.deepEqual(components[2].value, [['red']]);
+ assert.deepEqual(components[2].value, [['property-value', 'red']]);
}
},
'all values in wrong order': {
'topic': function () {
- return _breakUp([[['border'], ['red'], ['solid'], ['1px']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'border'],
+ ['property-value', 'red'],
+ ['property-value', 'solid'],
+ ['property-value', '1px']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has border-width': function (components) {
assert.deepEqual(components[0].name, 'border-width');
- assert.deepEqual(components[0].value, [['1px']]);
+ assert.deepEqual(components[0].value, [['property-value', '1px']]);
},
'has border-style': function (components) {
assert.deepEqual(components[1].name, 'border-style');
- assert.deepEqual(components[1].value, [['solid']]);
+ assert.deepEqual(components[1].value, [['property-value', 'solid']]);
},
'has border-color': function (components) {
assert.deepEqual(components[2].name, 'border-color');
- assert.deepEqual(components[2].value, [['red']]);
+ assert.deepEqual(components[2].value, [['property-value', 'red']]);
}
},
'missing values': {
'topic': function () {
- return _breakUp([[['border'], ['red']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'border'],
+ ['property-value', 'red']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has border-width': function (components) {
assert.deepEqual(components[0].name, 'border-width');
- assert.deepEqual(components[0].value, [['medium']]);
+ assert.deepEqual(components[0].value, [['property-value', 'medium']]);
},
'has border-style': function (components) {
assert.deepEqual(components[1].name, 'border-style');
- assert.deepEqual(components[1].value, [['none']]);
+ assert.deepEqual(components[1].value, [['property-value', 'none']]);
},
'has border-color': function (components) {
assert.deepEqual(components[2].name, 'border-color');
- assert.deepEqual(components[2].value, [['red']]);
+ assert.deepEqual(components[2].value, [['property-value', 'red']]);
}
},
'missing width': {
'topic': function () {
- return _breakUp([[['border'], ['solid'], ['rgba(0,0,0,0)']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'border'],
+ ['property-value', 'solid'],
+ ['property-value', 'rgba(0,0,0,0)']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has border-width': function (components) {
assert.deepEqual(components[0].name, 'border-width');
- assert.deepEqual(components[0].value, [['medium']]);
+ assert.deepEqual(components[0].value, [['property-value', 'medium']]);
},
'has border-style': function (components) {
assert.deepEqual(components[1].name, 'border-style');
- assert.deepEqual(components[1].value, [['solid']]);
+ assert.deepEqual(components[1].value, [['property-value', 'solid']]);
},
'has border-color': function (components) {
assert.deepEqual(components[2].name, 'border-color');
- assert.deepEqual(components[2].value, [['rgba(0,0,0,0)']]);
+ assert.deepEqual(components[2].value, [['property-value', 'rgba(0,0,0,0)']]);
}
}
},
'border radius': {
'no horizontal vertical split': {
'topic': function () {
- return _breakUp([[['border-radius'], ['0px'], ['1px'], ['2px'], ['3px']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px']
+ ]
+ ]);
},
'has 4 components': function (components) {
assert.lengthOf(components, 4);
},
'has border-top-left-radius': function (components) {
assert.equal(components[0].name, 'border-top-left-radius');
- assert.deepEqual(components[0].value, [['0px'], ['0px']]);
+ assert.deepEqual(components[0].value, [['property-value', '0px'], ['property-value', '0px']]);
},
'has border-top-right-radius': function (components) {
assert.equal(components[1].name, 'border-top-right-radius');
- assert.deepEqual(components[1].value, [['1px'], ['1px']]);
+ assert.deepEqual(components[1].value, [['property-value', '1px'], ['property-value', '1px']]);
},
'has border-bottom-right-radius': function (components) {
assert.equal(components[2].name, 'border-bottom-right-radius');
- assert.deepEqual(components[2].value, [['2px'], ['2px']]);
+ assert.deepEqual(components[2].value, [['property-value', '2px'], ['property-value', '2px']]);
},
'has border-bottom-left': function (components) {
assert.equal(components[3].name, 'border-bottom-left-radius');
- assert.deepEqual(components[3].value, [['3px'], ['3px']]);
+ assert.deepEqual(components[3].value, [['property-value', '3px'], ['property-value', '3px']]);
}
},
'horizontal vertical split': {
'topic': function () {
- return _breakUp([[['border-radius'], ['0px'], ['1px'], ['2px'], ['3px'], ['/'], ['1px'], ['2px'], ['3px'], ['4px']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px'],
+ ['property-value', '/'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px'],
+ ['property-value', '4px']
+ ]
+ ]);
},
'has 4 components': function (components) {
assert.lengthOf(components, 4);
},
'has border-top-left-radius': function (components) {
assert.equal(components[0].name, 'border-top-left-radius');
- assert.deepEqual(components[0].value, [['0px'], ['1px']]);
+ assert.deepEqual(components[0].value, [['property-value', '0px'], ['property-value', '1px']]);
},
'has border-top-right-radius': function (components) {
assert.equal(components[1].name, 'border-top-right-radius');
- assert.deepEqual(components[1].value, [['1px'], ['2px']]);
+ assert.deepEqual(components[1].value, [['property-value', '1px'], ['property-value', '2px']]);
},
'has border-bottom-right-radius': function (components) {
assert.equal(components[2].name, 'border-bottom-right-radius');
- assert.deepEqual(components[2].value, [['2px'], ['3px']]);
+ assert.deepEqual(components[2].value, [['property-value', '2px'], ['property-value', '3px']]);
},
'has border-bottom-left': function (components) {
assert.equal(components[3].name, 'border-bottom-left-radius');
- assert.deepEqual(components[3].value, [['3px'], ['4px']]);
+ assert.deepEqual(components[3].value, [['property-value', '3px'], ['property-value', '4px']]);
}
},
'vendor prefix asymmetrical horizontal vertical split': {
'topic': function () {
- return _breakUp([[['-webkit-border-radius'], ['0px'], ['1px'], ['2px'], ['/'], ['1px'], ['4px']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', '-webkit-border-radius'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '/'],
+ ['property-value', '1px'],
+ ['property-value', '4px']
+ ]
+ ]);
},
'has 4 components': function (components) {
assert.lengthOf(components, 4);
},
'has border-top-left-radius': function (components) {
assert.equal(components[0].name, '-webkit-border-top-left-radius');
- assert.deepEqual(components[0].value, [['0px'], ['1px']]);
+ assert.deepEqual(components[0].value, [['property-value', '0px'], ['property-value', '1px']]);
},
'has border-top-right-radius': function (components) {
assert.equal(components[1].name, '-webkit-border-top-right-radius');
- assert.deepEqual(components[1].value, [['1px'], ['4px']]);
+ assert.deepEqual(components[1].value, [['property-value', '1px'], ['property-value', '4px']]);
},
'has border-bottom-right-radius': function (components) {
assert.equal(components[2].name, '-webkit-border-bottom-right-radius');
- assert.deepEqual(components[2].value, [['2px'], ['1px']]);
+ assert.deepEqual(components[2].value, [['property-value', '2px'], ['property-value', '1px']]);
},
'has border-bottom-left': function (components) {
assert.equal(components[3].name, '-webkit-border-bottom-left-radius');
- assert.deepEqual(components[3].value, [['1px'], ['4px']]);
+ assert.deepEqual(components[3].value, [['property-value', '1px'], ['property-value', '4px']]);
}
},
'with missing vertical value': {
'topic': function () {
- return _breakUp([[['border-radius'], ['0px'], ['/']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '0px'],
+ ['property-value', '/']
+ ]
+ ]);
},
'has no components': function (components) {
assert.lengthOf(components, 0);
},
'with missing horizontal value': {
'topic': function () {
- return _breakUp([[['border-radius'], ['/'], ['0px']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '/'],
+ ['property-value', '0px']
+ ]
+ ]);
},
'has no components': function (components) {
assert.lengthOf(components, 0);
'four values': {
'four given': {
'topic': function () {
- return _breakUp([[['margin'], ['0px'], ['1px'], ['2px'], ['3px']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px']
+ ]
+ ]);
},
'has 4 components': function (components) {
assert.lengthOf(components, 4);
},
'has margin-top': function (components) {
assert.equal(components[0].name, 'margin-top');
- assert.deepEqual(components[0].value, [['0px']]);
+ assert.deepEqual(components[0].value, [['property-value', '0px']]);
},
'has margin-right': function (components) {
assert.equal(components[1].name, 'margin-right');
- assert.deepEqual(components[1].value, [['1px']]);
+ assert.deepEqual(components[1].value, [['property-value', '1px']]);
},
'has margin-bottom': function (components) {
assert.equal(components[2].name, 'margin-bottom');
- assert.deepEqual(components[2].value, [['2px']]);
+ assert.deepEqual(components[2].value, [['property-value', '2px']]);
},
'has margin-left': function (components) {
assert.equal(components[3].name, 'margin-left');
- assert.deepEqual(components[3].value, [['3px']]);
+ assert.deepEqual(components[3].value, [['property-value', '3px']]);
}
},
'three given': {
'topic': function () {
- return _breakUp([[['padding'], ['0px'], ['1px'], ['2px']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'padding'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px']
+ ]
+ ]);
},
'has 4 components': function (components) {
assert.lengthOf(components, 4);
},
'has padding-top': function (components) {
assert.equal(components[0].name, 'padding-top');
- assert.deepEqual(components[0].value, [['0px']]);
+ assert.deepEqual(components[0].value, [['property-value', '0px']]);
},
'has padding-right': function (components) {
assert.equal(components[1].name, 'padding-right');
- assert.deepEqual(components[1].value, [['1px']]);
+ assert.deepEqual(components[1].value, [['property-value', '1px']]);
},
'has padding-bottom': function (components) {
assert.equal(components[2].name, 'padding-bottom');
- assert.deepEqual(components[2].value, [['2px']]);
+ assert.deepEqual(components[2].value, [['property-value', '2px']]);
},
'has padding-left': function (components) {
assert.equal(components[3].name, 'padding-left');
- assert.deepEqual(components[3].value, [['1px']]);
+ assert.deepEqual(components[3].value, [['property-value', '1px']]);
}
},
'two given': {
'topic': function () {
- return _breakUp([[['border-color'], ['red'], ['blue']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'border-color'],
+ ['property-value', 'red'],
+ ['property-value', 'blue']
+ ]
+ ]);
},
'has 4 components': function (components) {
assert.lengthOf(components, 4);
},
'has border-top-color': function (components) {
assert.equal(components[0].name, 'border-top-color');
- assert.deepEqual(components[0].value, [['red']]);
+ assert.deepEqual(components[0].value, [['property-value', 'red']]);
},
'has border-right-color': function (components) {
assert.equal(components[1].name, 'border-right-color');
- assert.deepEqual(components[1].value, [['blue']]);
+ assert.deepEqual(components[1].value, [['property-value', 'blue']]);
},
'has border-bottom-color': function (components) {
assert.equal(components[2].name, 'border-bottom-color');
- assert.deepEqual(components[2].value, [['red']]);
+ assert.deepEqual(components[2].value, [['property-value', 'red']]);
},
'has border-left-color': function (components) {
assert.equal(components[3].name, 'border-left-color');
- assert.deepEqual(components[3].value, [['blue']]);
+ assert.deepEqual(components[3].value, [['property-value', 'blue']]);
}
},
'one given': {
'topic': function () {
- return _breakUp([[['border-style'], ['solid']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'border-style'],
+ ['property-value', 'solid']
+ ]
+ ]);
},
'has 4 components': function (components) {
assert.lengthOf(components, 4);
},
'has border-top-style': function (components) {
assert.equal(components[0].name, 'border-top-style');
- assert.deepEqual(components[0].value, [['solid']]);
+ assert.deepEqual(components[0].value, [['property-value', 'solid']]);
},
'has border-right-style': function (components) {
assert.equal(components[1].name, 'border-right-style');
- assert.deepEqual(components[1].value, [['solid']]);
+ assert.deepEqual(components[1].value, [['property-value', 'solid']]);
},
'has border-bottom-style': function (components) {
assert.equal(components[2].name, 'border-bottom-style');
- assert.deepEqual(components[2].value, [['solid']]);
+ assert.deepEqual(components[2].value, [['property-value', 'solid']]);
},
'has border-left-style': function (components) {
assert.equal(components[3].name, 'border-left-style');
- assert.deepEqual(components[3].value, [['solid']]);
+ assert.deepEqual(components[3].value, [['property-value', 'solid']]);
}
},
'none given': {
'topic': function () {
- return _breakUp([[['border-style']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'border-style']
+ ]
+ ]);
},
'has 0 components': function (components) {
assert.lengthOf(components, 0);
'list style': {
'inherit': {
'topic': function () {
- return _breakUp([[['list-style'], ['inherit']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'list-style'],
+ ['property-value', 'inherit']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has border-top-style': function (components) {
assert.equal(components[0].name, 'list-style-type');
- assert.deepEqual(components[0].value, [['inherit']]);
+ assert.deepEqual(components[0].value, [['property-value', 'inherit']]);
},
'has border-right-style': function (components) {
assert.equal(components[1].name, 'list-style-position');
- assert.deepEqual(components[1].value, [['inherit']]);
+ assert.deepEqual(components[1].value, [['property-value', 'inherit']]);
},
'has border-bottom-style': function (components) {
assert.equal(components[2].name, 'list-style-image');
- assert.deepEqual(components[2].value, [['inherit']]);
+ assert.deepEqual(components[2].value, [['property-value', 'inherit']]);
}
},
'all values': {
'topic': function () {
- return _breakUp([[['list-style'], ['circle'], ['inside'], ['__ESCAPED_URL_CLEAN_CSS0__']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'list-style'],
+ ['property-value', 'circle'],
+ ['property-value', 'inside'],
+ ['property-value', 'url(image.png)']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has border-top-style': function (components) {
assert.equal(components[0].name, 'list-style-type');
- assert.deepEqual(components[0].value, [['circle']]);
+ assert.deepEqual(components[0].value, [['property-value', 'circle']]);
},
'has border-right-style': function (components) {
assert.equal(components[1].name, 'list-style-position');
- assert.deepEqual(components[1].value, [['inside']]);
+ assert.deepEqual(components[1].value, [['property-value', 'inside']]);
},
'has border-bottom-style': function (components) {
assert.equal(components[2].name, 'list-style-image');
- assert.deepEqual(components[2].value, [['__ESCAPED_URL_CLEAN_CSS0__']]);
+ assert.deepEqual(components[2].value, [['property-value', 'url(image.png)']]);
}
},
'some missing': {
'topic': function () {
- return _breakUp([[['list-style'], ['inside']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'list-style'],
+ ['property-value', 'inside']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has border-top-style': function (components) {
assert.equal(components[0].name, 'list-style-type');
- assert.deepEqual(components[0].value, [['__hack']]);
+ assert.deepEqual(components[0].value, [['property-value', '__hack']]);
},
'has border-right-style': function (components) {
assert.equal(components[1].name, 'list-style-position');
- assert.deepEqual(components[1].value, [['inside']]);
+ assert.deepEqual(components[1].value, [['property-value', 'inside']]);
},
'has border-bottom-style': function (components) {
assert.equal(components[2].name, 'list-style-image');
- assert.deepEqual(components[2].value, [['none']]);
+ assert.deepEqual(components[2].value, [['property-value', 'none']]);
}
},
'fuzzy matching': {
'topic': function () {
- return _breakUp([[['list-style'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['outside'], ['none']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'list-style'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', 'outside'],
+ ['property-value', 'none']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has list-style-type': function (components) {
assert.equal(components[0].name, 'list-style-type');
- assert.deepEqual(components[0].value, [['none']]);
+ assert.deepEqual(components[0].value, [['property-value', 'none']]);
},
'has list-style-position': function (components) {
assert.equal(components[1].name, 'list-style-position');
- assert.deepEqual(components[1].value, [['outside']]);
+ assert.deepEqual(components[1].value, [['property-value', 'outside']]);
},
'has list-style-image': function (components) {
assert.equal(components[2].name, 'list-style-image');
- assert.deepEqual(components[2].value, [['__ESCAPED_URL_CLEAN_CSS0__']]);
+ assert.deepEqual(components[2].value, [['property-value', 'url(image.png)']]);
}
}
},
- 'multiple values': {
+ 'multiple values 123': {
'background': {
'topic': function () {
- return _breakUp([[['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['#fff'], [','], ['url(image2.png)'], ['repeat'], ['no-repeat'], ['2px'], ['3px'], ['/'], ['50%'], ['60%'], ['fixed'], ['content-box'], ['content-box'], ['red']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', '#fff'],
+ ['property-value', ','],
+ ['property-value', 'url(image2.png)'],
+ ['property-value', 'repeat'],
+ ['property-value', 'no-repeat'],
+ ['property-value', '2px'],
+ ['property-value', '3px'],
+ ['property-value', '/'],
+ ['property-value', '50%'],
+ ['property-value', '60%'],
+ ['property-value', 'fixed'],
+ ['property-value', 'content-box'],
+ ['property-value', 'content-box'],
+ ['property-value', 'red']
+ ]
+ ]);
},
'has 8 components': function (components) {
assert.lengthOf(components, 8);
},
'has background-image': function (components) {
assert.deepEqual(components[0].name, 'background-image');
- assert.deepEqual(components[0].value, [['__ESCAPED_URL_CLEAN_CSS0__'], [','], ['url(image2.png)']]);
+ assert.deepEqual(components[0].value, [['property-value', 'url(image.png)'], ['property-value', ','], ['property-value', 'url(image2.png)']]);
assert.isTrue(components[0].multiplex);
},
'has background-position': function (components) {
assert.deepEqual(components[1].name, 'background-position');
- assert.deepEqual(components[1].value, [['0'], ['0'], [','], ['2px'], ['3px']]);
+ assert.deepEqual(components[1].value, [['property-value', '0'], ['property-value', '0'], ['property-value', ','], ['property-value', '2px'], ['property-value', '3px']]);
assert.isTrue(components[0].multiplex);
},
'has background-size': function (components) {
assert.deepEqual(components[2].name, 'background-size');
- assert.deepEqual(components[2].value, [['auto'], [','], ['50%'], ['60%']]);
+ assert.deepEqual(components[2].value, [['property-value', 'auto'], ['property-value', ','], ['property-value', '50%'], ['property-value', '60%']]);
assert.isTrue(components[0].multiplex);
},
'has background-repeat': function (components) {
assert.deepEqual(components[3].name, 'background-repeat');
- assert.deepEqual(components[3].value, [['repeat'], [','], ['repeat'], ['no-repeat']]);
+ assert.deepEqual(components[3].value, [['property-value', 'repeat'], ['property-value', ','], ['property-value', 'repeat'], ['property-value', 'no-repeat']]);
assert.isTrue(components[0].multiplex);
},
'has background-attachment': function (components) {
assert.deepEqual(components[4].name, 'background-attachment');
- assert.deepEqual(components[4].value, [['scroll'], [','], ['fixed']]);
+ assert.deepEqual(components[4].value, [['property-value', 'scroll'], ['property-value', ','], ['property-value', 'fixed']]);
assert.isTrue(components[0].multiplex);
},
'has background-origin': function (components) {
assert.deepEqual(components[5].name, 'background-origin');
- assert.deepEqual(components[5].value, [['padding-box'], [','], ['content-box']]);
+ assert.deepEqual(components[5].value, [['property-value', 'padding-box'], ['property-value', ','], ['property-value', 'content-box']]);
assert.isTrue(components[0].multiplex);
},
'has background-clip': function (components) {
assert.deepEqual(components[6].name, 'background-clip');
- assert.deepEqual(components[6].value, [['border-box'], [','], ['content-box']]);
+ assert.deepEqual(components[6].value, [['property-value', 'border-box'], ['property-value', ','], ['property-value', 'content-box']]);
assert.isTrue(components[0].multiplex);
},
'has background-color': function (components) {
assert.deepEqual(components[7].name, 'background-color');
- assert.deepEqual(components[7].value, [['#fff'], [','], ['red']]);
+ assert.deepEqual(components[7].value, [['property-value', '#fff'], ['property-value', ','], ['property-value', 'red']]);
assert.isTrue(components[0].multiplex);
}
},
'background - clip & origin': {
'topic': function () {
- return _breakUp([[['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat'], ['padding-box'], [','], ['repeat'], ['red']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', 'no-repeat'],
+ ['property-value', 'padding-box'],
+ ['property-value', ','],
+ ['property-value', 'repeat'],
+ ['property-value', 'red']
+ ]
+ ]);
},
'has background-origin': function (components) {
- assert.deepEqual(components[5].value, [['padding-box'], [','], ['padding-box']]);
+ assert.deepEqual(components[5].value, [['property-value', 'padding-box'], ['property-value', ','], ['property-value', 'padding-box']]);
},
'has background-clip': function (components) {
- assert.deepEqual(components[6].value, [['padding-box'], [','], ['border-box']]);
+ assert.deepEqual(components[6].value, [['property-value', 'padding-box'], ['property-value', ','], ['property-value', 'border-box']]);
}
}
},
'outline': {
'inherit': {
'topic': function () {
- return _breakUp([[['outline'], ['inherit']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'outline'],
+ ['property-value', 'inherit']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has outline-color': function (components) {
assert.deepEqual(components[0].name, 'outline-color');
- assert.deepEqual(components[0].value, [['inherit']]);
+ assert.deepEqual(components[0].value, [['property-value', 'inherit']]);
},
'has outline-style': function (components) {
assert.deepEqual(components[1].name, 'outline-style');
- assert.deepEqual(components[1].value, [['inherit']]);
+ assert.deepEqual(components[1].value, [['property-value', 'inherit']]);
},
'has outline-width': function (components) {
assert.deepEqual(components[2].name, 'outline-width');
- assert.deepEqual(components[2].value, [['inherit']]);
+ assert.deepEqual(components[2].value, [['property-value', 'inherit']]);
}
},
'3 inherits': {
'topic': function () {
- return _breakUp([[['outline'], ['inherit'], ['inherit'], ['inherit']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'outline'],
+ ['property-value', 'inherit'],
+ ['property-value', 'inherit'],
+ ['property-value', 'inherit']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has outline-color': function (components) {
assert.deepEqual(components[0].name, 'outline-color');
- assert.deepEqual(components[0].value, [['inherit']]);
+ assert.deepEqual(components[0].value, [['property-value', 'inherit']]);
},
'has outline-style': function (components) {
assert.deepEqual(components[1].name, 'outline-style');
- assert.deepEqual(components[1].value, [['inherit']]);
+ assert.deepEqual(components[1].value, [['property-value', 'inherit']]);
},
'has outline-width': function (components) {
assert.deepEqual(components[2].name, 'outline-width');
- assert.deepEqual(components[2].value, [['inherit']]);
+ assert.deepEqual(components[2].value, [['property-value', 'inherit']]);
}
},
'all values in correct order': {
'topic': function () {
- return _breakUp([[['outline'], ['red'], ['solid'], ['1px']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'outline'],
+ ['property-value', 'red'],
+ ['property-value', 'solid'],
+ ['property-value', '1px']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has outline-color': function (components) {
assert.deepEqual(components[0].name, 'outline-color');
- assert.deepEqual(components[0].value, [['red']]);
+ assert.deepEqual(components[0].value, [['property-value', 'red']]);
},
'has outline-style': function (components) {
assert.deepEqual(components[1].name, 'outline-style');
- assert.deepEqual(components[1].value, [['solid']]);
+ assert.deepEqual(components[1].value, [['property-value', 'solid']]);
},
'has outline-width': function (components) {
assert.deepEqual(components[2].name, 'outline-width');
- assert.deepEqual(components[2].value, [['1px']]);
+ assert.deepEqual(components[2].value, [['property-value', '1px']]);
}
},
'all values in wrong order': {
'topic': function () {
- return _breakUp([[['outline'], ['1px'], ['dotted'], ['#fff']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'outline'],
+ ['property-value', '1px'],
+ ['property-value', 'dotted'],
+ ['property-value', '#fff']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has outline-color': function (components) {
assert.deepEqual(components[0].name, 'outline-color');
- assert.deepEqual(components[0].value, [['#fff']]);
+ assert.deepEqual(components[0].value, [['property-value', '#fff']]);
},
'has outline-style': function (components) {
assert.deepEqual(components[1].name, 'outline-style');
- assert.deepEqual(components[1].value, [['dotted']]);
+ assert.deepEqual(components[1].value, [['property-value', 'dotted']]);
},
'has outline-width': function (components) {
assert.deepEqual(components[2].name, 'outline-width');
- assert.deepEqual(components[2].value, [['1px']]);
+ assert.deepEqual(components[2].value, [['property-value', '1px']]);
}
},
'with auto style': {
'topic': function () {
- return _breakUp([[['outline'], ['#fff'], ['auto'], ['1px']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'outline'],
+ ['property-value', '#fff'],
+ ['property-value', 'auto'],
+ ['property-value', '1px']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has outline-color': function (components) {
assert.deepEqual(components[0].name, 'outline-color');
- assert.deepEqual(components[0].value, [['#fff']]);
+ assert.deepEqual(components[0].value, [['property-value', '#fff']]);
},
'has outline-style': function (components) {
assert.deepEqual(components[1].name, 'outline-style');
- assert.deepEqual(components[1].value, [['auto']]);
+ assert.deepEqual(components[1].value, [['property-value', 'auto']]);
},
'has outline-width': function (components) {
assert.deepEqual(components[2].name, 'outline-width');
- assert.deepEqual(components[2].value, [['1px']]);
+ assert.deepEqual(components[2].value, [['property-value', '1px']]);
}
},
'missing values': {
'topic': function () {
- return _breakUp([[['outline'], ['solid']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'outline'],
+ ['property-value', 'solid']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has outline-color': function (components) {
assert.deepEqual(components[0].name, 'outline-color');
- assert.deepEqual(components[0].value, [['invert']]);
+ assert.deepEqual(components[0].value, [['property-value', 'invert']]);
},
'has outline-style': function (components) {
assert.deepEqual(components[1].name, 'outline-style');
- assert.deepEqual(components[1].value, [['solid']]);
+ assert.deepEqual(components[1].value, [['property-value', 'solid']]);
},
'has outline-width': function (components) {
assert.deepEqual(components[2].name, 'outline-width');
- assert.deepEqual(components[2].value, [['medium']]);
+ assert.deepEqual(components[2].value, [['property-value', 'medium']]);
}
},
'default values': {
'topic': function () {
- return _breakUp([[['outline'], ['invert'], ['none'], ['medium']]]);
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'outline'],
+ ['property-value', 'invert'],
+ ['property-value', 'none'],
+ ['property-value', 'medium']
+ ]
+ ]);
},
'has 3 components': function (components) {
assert.lengthOf(components, 3);
},
'has outline-color': function (components) {
assert.deepEqual(components[0].name, 'outline-color');
- assert.deepEqual(components[0].value, [['invert']]);
+ assert.deepEqual(components[0].value, [['property-value', 'invert']]);
},
'has outline-style': function (components) {
assert.deepEqual(components[1].name, 'outline-style');
- assert.deepEqual(components[1].value, [['none']]);
+ assert.deepEqual(components[1].value, [['property-value', 'none']]);
},
'has outline-width': function (components) {
assert.deepEqual(components[2].name, 'outline-width');
- assert.deepEqual(components[2].value, [['medium']]);
+ assert.deepEqual(components[2].value, [['property-value', 'medium']]);
}
}
}
var optimize = require('../../lib/properties/optimizer');
var tokenize = require('../../lib/tokenizer/tokenize');
-var SourceTracker = require('../../lib/utils/source-tracker');
-var Compatibility = require('../../lib/utils/compatibility');
+var compatibility = require('../../lib/utils/compatibility');
var Validator = require('../../lib/properties/validator');
function _optimize(source) {
var tokens = tokenize(source, {
options: {},
- sourceTracker: new SourceTracker(),
warnings: []
});
- var compatibility = new Compatibility().toOptions();
- var validator = new Validator(compatibility);
- optimize(tokens[0][1], tokens[0][2], false, true, { compatibility: compatibility, aggressiveMerging: true, shorthandCompacting: true }, { validator: validator });
+ var compat = compatibility();
+ var validator = new Validator(compat);
+ optimize(tokens[0][1], tokens[0][2], false, true, { options: { compatibility: compat, aggressiveMerging: true, shorthandCompacting: true }, validator: validator });
return tokens[0][2];
}
'topic': function () {
return _optimize('a{' + prefixedLonghand + ':inherit;' + prefixedShorthand + ':' + zeroValue + '}');
},
- 'has one token': function (body) {
- assert.lengthOf(body, 1);
+ 'has one token': function (properties) {
+ assert.lengthOf(properties, 1);
},
- 'has zero value only': function (body) {
- assert.deepEqual(body[0][0], [prefixedShorthand]);
- assert.deepEqual(body[0][1], [zeroValue]);
+ 'has zero value only': function (properties) {
+ assert.deepEqual(properties[0][1][1], prefixedShorthand);
+ assert.deepEqual(properties[0][2][1], zeroValue);
}
};
}
'topic': function () {
return _optimize('a{' + prefixedShorthand + ':' + zeroValue + ';' + prefixedLonghand + ':inherit}');
},
- 'has two tokens': function (body) {
- assert.lengthOf(body, 2);
+ 'has two tokens': function (properties) {
+ assert.lengthOf(properties, 2);
},
- 'first is shorthand': function (body) {
- assert.deepEqual(body[0][0], [prefixedShorthand]);
- assert.deepEqual(body[0][1], [zeroValue]);
+ 'first is shorthand': function (properties) {
+ assert.deepEqual(properties[0][1][1], prefixedShorthand);
+ assert.deepEqual(properties[0][2][1], zeroValue);
},
- 'second is longhand': function (body) {
- assert.deepEqual(body[1][0], [prefixedLonghand]);
- assert.deepEqual(body[1][1], ['inherit']);
+ 'second is longhand': function (properties) {
+ assert.deepEqual(properties[1][1][1], prefixedLonghand);
+ assert.deepEqual(properties[1][2][1], 'inherit');
}
};
}
var optimize = require('../../lib/properties/optimizer');
var tokenize = require('../../lib/tokenizer/tokenize');
-var SourceTracker = require('../../lib/utils/source-tracker');
-var Compatibility = require('../../lib/utils/compatibility');
+var compatibility = require('../../lib/utils/compatibility');
var Validator = require('../../lib/properties/validator');
function _optimize(source, mergeAdjacent, aggressiveMerging, compatibilityOptions) {
- var compatibility = new Compatibility(compatibilityOptions).toOptions();
- var validator = new Validator(compatibility);
+ var compat = compatibility(compatibilityOptions);
+ var validator = new Validator(compat);
var tokens = tokenize(source, {
options: {},
- sourceTracker: new SourceTracker(),
warnings: []
});
- optimize(tokens[0][1], tokens[0][2], mergeAdjacent, true, { compatibility: compatibility, aggressiveMerging: aggressiveMerging }, { validator: validator });
+ optimize(tokens[0][1], tokens[0][2], mergeAdjacent, true, { options: { compatibility: compat, aggressiveMerging: aggressiveMerging }, validator: validator });
return tokens[0][2];
}
vows.describe(optimize)
.addBatch({
'of two adjacent properties': {
- 'topic': 'a{display:-moz-inline-box;display:inline-block}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['display'], ['-moz-inline-box']],
- [['display'], ['inline-block']]
+ 'topic': function () {
+ return _optimize('a{display:-moz-inline-box;display:inline-block}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'display', [[1, 2, undefined]]],
+ ['property-value', '-moz-inline-box', [[1, 10, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 26, undefined]]],
+ ['property-value', 'inline-block', [[1, 34, undefined]]]
+ ]
]);
}
},
'of two properties ': {
- 'topic': 'a{display:inline-block;color:red;display:block}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['color'], ['red']],
- [['display'], ['block']]
+ 'topic': function () {
+ return _optimize('a{display:inline-block;color:red;display:block}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 23, undefined]]],
+ ['property-value', 'red', [[1, 29, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 33, undefined]]],
+ ['property-value', 'block', [[1, 41, undefined]]]
+ ]
]);
}
},
'of two same properties with same value where latter is a hack': {
- 'topic': 'a{margin:0;_margin:0}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['margin'], ['0']],
- [['_margin'], ['0']]
+ 'topic': function () {
+ return _optimize('a{margin:0;_margin:0}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'margin', [[1, 2, undefined]]],
+ ['property-value', '0', [[1, 9, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', '_margin', [[1, 11, undefined]]],
+ ['property-value', '0', [[1, 19, undefined]]]
+ ]
]);
}
},
'of two same properties with same value where latter is !important': {
- 'topic': 'a{margin:0;margin:0 !important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['margin'], ['0']],
- [['margin'], ['0!important']]
+ 'topic': function () {
+ return _optimize('a{margin:0;margin:0 !important}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'margin', [[1, 2, undefined]]],
+ ['property-value', '0', [[1, 9, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'margin', [[1, 11, undefined]]],
+ ['property-value', '0!important', [[1, 18, undefined]]]
+ ]
]);
}
},
'of two properties where former is !important': {
- 'topic': 'a{display:inline-block!important;color:red;display:block}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['display'], ['inline-block!important']],
- [['color'], ['red']]
+ 'topic': function () {
+ return _optimize('a{display:inline-block!important;color:red;display:block}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'display', [[1, 2, undefined]]],
+ ['property-value', 'inline-block!important', [[1, 10, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'color', [[1, 33, undefined]]],
+ ['property-value', 'red', [[1, 39, undefined]]]
+ ]
]);
}
},
'of two properties where latter is !important': {
- 'topic': 'a{display:inline-block;color:red;display:block!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['color'], ['red']],
- [['display'], ['block!important']]
+ 'topic': function () {
+ return _optimize('a{display:inline-block;color:red;display:block!important}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 23, undefined]]],
+ ['property-value', 'red', [[1, 29, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 33, undefined]]],
+ ['property-value', 'block!important', [[1, 41, undefined]]]
+ ]
]);
}
},
'of two properties where both are !important': {
- 'topic': 'a{display:inline-block!important;color:red;display:block!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['color'], ['red']],
- [['display'], ['block!important']]
+ 'topic': function () {
+ return _optimize('a{display:inline-block!important;color:red;display:block!important}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 33, undefined]]],
+ ['property-value', 'red', [[1, 39, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 43, undefined]]],
+ ['property-value', 'block!important', [[1, 51, undefined]]]
+ ]
]);
}
},
'of many properties': {
- 'topic': 'a{display:inline-block;color:red;font-weight:bolder;font-weight:700;display:block!important;color:#fff}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['font-weight'], ['bolder']],
- [['font-weight'], ['700']],
- [['display'], ['block!important']],
- [['color'], ['#fff']]
+ 'topic': function () {
+ return _optimize('a{display:inline-block;color:red;font-weight:bolder;font-weight:700;display:block!important;color:#fff}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'font-weight', [[1, 33, undefined]]],
+ ['property-value', 'bolder', [[1, 45, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'font-weight', [[1, 52, undefined]]],
+ ['property-value', '700', [[1, 64, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 68, undefined]]],
+ ['property-value', 'block!important', [[1, 76, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'color', [[1, 92, undefined]]],
+ ['property-value', '#fff', [[1, 98, undefined]]]
+ ]
]);
}
},
'both redefined': {
- 'topic': 'p{display:block;display:-moz-inline-box;color:red;display:table-cell}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['color'], ['red']],
- [['display'], ['table-cell']]
+ 'topic': function () {
+ return _optimize('p{display:block;display:-moz-inline-box;color:red;display:table-cell}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 40, undefined]]],
+ ['property-value', 'red', [[1, 46, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 50, undefined]]],
+ ['property-value', 'table-cell', [[1, 58, undefined]]]
+ ]
]);
}
},
'filter treated as background': {
- 'topic': 'p{background:-moz-linear-gradient();background:-webkit-linear-gradient();filter:"progid:DXImageTransform";background:linear-gradient()}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['background'], ['-moz-linear-gradient()']],
- [['background'], ['-webkit-linear-gradient()']],
- [['filter'], ['"progid:DXImageTransform"']],
- [['background'], ['linear-gradient()']]
+ 'topic': function () {
+ return _optimize('p{background:-moz-linear-gradient();background:-webkit-linear-gradient();filter:"progid:DXImageTransform";background:linear-gradient()}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', '-moz-linear-gradient()', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 36, undefined]]],
+ ['property-value', '-webkit-linear-gradient()', [[1, 47, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'filter', [[1, 73, undefined]]],
+ ['property-value', '"progid:DXImageTransform"', [[1, 80, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 106, undefined]]],
+ ['property-value', 'linear-gradient()', [[1, 117, undefined]]]
+ ]
]);
}
},
'filter treated as background-image': {
- 'topic': 'p{background-image:-moz-linear-gradient();background-image:-webkit-linear-gradient();filter:"progid:DXImageTransform";background-image:linear-gradient()}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['background-image'], ['-moz-linear-gradient()']],
- [['background-image'], ['-webkit-linear-gradient()']],
- [['filter'], ['"progid:DXImageTransform"']],
- [['background-image'], ['linear-gradient()']]
+ 'topic': function () {
+ return _optimize('p{background-image:-moz-linear-gradient();background-image:-webkit-linear-gradient();filter:"progid:DXImageTransform";background-image:linear-gradient()}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 2, undefined]]],
+ ['property-value', '-moz-linear-gradient()', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 42, undefined]]],
+ ['property-value', '-webkit-linear-gradient()', [[1, 59, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'filter', [[1, 85, undefined]]],
+ ['property-value', '"progid:DXImageTransform"', [[1, 92, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 118, undefined]]],
+ ['property-value', 'linear-gradient()', [[1, 135, undefined]]]
+ ]
]);
}
},
'-ms-filter treated as background': {
- 'topic': 'p{background:-moz-linear-gradient();background:-webkit-linear-gradient();-ms-filter:"progid:DXImageTransform";background:linear-gradient()}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['background'], ['-moz-linear-gradient()']],
- [['background'], ['-webkit-linear-gradient()']],
- [['-ms-filter'], ['"progid:DXImageTransform"']],
- [['background'], ['linear-gradient()']]
+ 'topic': function () {
+ return _optimize('p{background:-moz-linear-gradient();background:-webkit-linear-gradient();-ms-filter:"progid:DXImageTransform";background:linear-gradient()}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', '-moz-linear-gradient()', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 36, undefined]]],
+ ['property-value', '-webkit-linear-gradient()', [[1, 47, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', '-ms-filter', [[1, 73, undefined]]],
+ ['property-value', '"progid:DXImageTransform"', [[1, 84, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 110, undefined]]],
+ ['property-value', 'linear-gradient()', [[1, 121, undefined]]]
+ ]
]);
}
},
'-ms-filter treated as background-image': {
- 'topic': 'p{background-image:-moz-linear-gradient();background-image:-webkit-linear-gradient();-ms-filter:"progid:DXImageTransform";background-image:linear-gradient()}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['background-image'], ['-moz-linear-gradient()']],
- [['background-image'], ['-webkit-linear-gradient()']],
- [['-ms-filter'], ['"progid:DXImageTransform"']],
- [['background-image'], ['linear-gradient()']]
+ 'topic': function () {
+ return _optimize('p{background-image:-moz-linear-gradient();background-image:-webkit-linear-gradient();-ms-filter:"progid:DXImageTransform";background-image:linear-gradient()}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 2, undefined]]],
+ ['property-value', '-moz-linear-gradient()', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 42, undefined]]],
+ ['property-value', '-webkit-linear-gradient()', [[1, 59, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', '-ms-filter', [[1, 85, undefined]]],
+ ['property-value', '"progid:DXImageTransform"', [[1, 96, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 122, undefined]]],
+ ['property-value', 'linear-gradient()', [[1, 139, undefined]]]
+ ]
]);
}
},
'longhand then shorthand': {
- 'topic': 'p{border-left-style:solid;border:1px dotted red}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['border'], ['1px'], ['dotted'], ['red']]
+ 'topic': function () {
+ return _optimize('p{border-left-style:solid;border:1px dotted red}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border', [[1, 26, undefined]]],
+ ['property-value', '1px', [[1, 33, undefined]]],
+ ['property-value', 'dotted', [[1, 37, undefined]]],
+ ['property-value', 'red', [[1, 44, undefined]]]
+ ]
]);
}
},
'longhand then shorthand with important': {
- 'topic': 'p{border-left-style:solid!important;border:1px dotted red}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['border-left-style'], ['solid!important']],
- [['border'], ['1px'], ['dotted'], ['red']]
+ 'topic': function () {
+ return _optimize('p{border-left-style:solid!important;border:1px dotted red}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-left-style', [[1, 2, undefined]]],
+ ['property-value', 'solid!important', [[1, 20, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'border', [[1, 36, undefined]]],
+ ['property-value', '1px', [[1, 43, undefined]]],
+ ['property-value', 'dotted', [[1, 47, undefined]]],
+ ['property-value', 'red', [[1, 54, undefined]]]
+ ]
]);
}
},
'shorthand then longhand': {
- 'topic': 'p{background:url(image.png);background-image:#fff}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['background'], ['url(image.png)']],
- [['background-image'], ['#fff']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png);background-image:#fff}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 28, undefined]]],
+ ['property-value', '#fff', [[1, 45, undefined]]]
+ ]
]);
}
}
})
.addBatch({
'list-style fuzzy matching': {
- 'topic': 'p{list-style:inside none}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['list-style'], ['none'], ['inside']]
+ 'topic': function () {
+ return _optimize('p{list-style:inside none}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'list-style', [[1, 2, undefined]]],
+ ['property-value', 'none', [[1, 20, undefined]]],
+ ['property-value', 'inside', [[1, 13, undefined]]]
+ ]
]);
}
}
})
.addBatch({
'ie hacks - normal before hack': {
- 'topic': 'p{color:red;display:none;color:#fff\\9}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['color'], ['red']],
- [['display'], ['none']],
- [['color'], ['#fff\\9']]
+ 'topic': function () {
+ return _optimize('p{color:red;display:none;color:#fff\\9}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 2, undefined]]],
+ ['property-value', 'red', [[1, 8, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 12, undefined]]],
+ ['property-value', 'none', [[1, 20, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'color', [[1, 25, undefined]]],
+ ['property-value', '#fff\\9', [[1, 31, undefined]]]
+ ]
]);
}
},
'ie hacks - normal after hack': {
- 'topic': 'p{color:red\\9;display:none;color:#fff}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['color'], ['red\\9']],
- [['display'], ['none']],
- [['color'], ['#fff']]
+ 'topic': function () {
+ return _optimize('p{color:red\\9;display:none;color:#fff}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 2, undefined]]],
+ ['property-value', 'red\\9', [[1, 8, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 14, undefined]]],
+ ['property-value', 'none', [[1, 22, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'color', [[1, 27, undefined]]],
+ ['property-value', '#fff', [[1, 33, undefined]]]
+ ]
]);
}
},
'ie hacks - hack after hack': {
- 'topic': 'p{color:red\\9;display:none;color:#fff\\9}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['display'], ['none']],
- [['color'], ['#fff\\9']]
+ 'topic': function () {
+ return _optimize('p{color:red\\9;display:none;color:#fff\\9}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'display', [[1, 14, undefined]]],
+ ['property-value', 'none', [[1, 22, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'color', [[1, 27, undefined]]],
+ ['property-value', '#fff\\9', [[1, 33, undefined]]]
+ ]
]);
}
}
})
.addBatch({
'mergeAdjacent is true': {
- 'topic': 'p{display:block;display:inline-block}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, true, true), [
- [['display'], ['inline-block']]
+ 'topic': function () {
+ return _optimize('p{display:block;display:inline-block}', true, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'display', [[1, 16, undefined]]],
+ ['property-value', 'inline-block', [[1, 24, undefined]]]
+ ]
]);
}
},
'mergeAdjacent is false': {
- 'topic': 'p{display:block;display:inline-block}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['display'], ['block']],
- [['display'], ['inline-block']]
+ 'topic': function () {
+ return _optimize('p{display:block;display:inline-block}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'display', [[1, 2, undefined]]],
+ ['property-value', 'block', [[1, 10, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 16, undefined]]],
+ ['property-value', 'inline-block', [[1, 24, undefined]]]
+ ]
]);
}
},
'mergeAdjacent is an array with irrelevant join positions': {
- 'topic': 'p{display:block;display:inline-block;color:red}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, [2], true), [
- [['display'], ['block']],
- [['display'], ['inline-block']],
- [['color'], ['red']]
+ 'topic': function () {
+ return _optimize('p{display:block;display:inline-block;color:red}', [2], true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'display', [[1, 2, undefined]]],
+ ['property-value', 'block', [[1, 10, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 16, undefined]]],
+ ['property-value', 'inline-block', [[1, 24, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'color', [[1, 37, undefined]]],
+ ['property-value', 'red', [[1, 43, undefined]]]
+ ]
]);
}
},
'mergeAdjacent is an array with relevant join positions': {
- 'topic': 'p{display:block;display:inline-block;color:red}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, [1], true), [
- [['display'], ['inline-block']],
- [['color'], ['red']]
+ 'topic': function () {
+ return _optimize('p{display:block;display:inline-block;color:red}', [1], true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'display', [[1, 16, undefined]]],
+ ['property-value', 'inline-block', [[1, 24, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'color', [[1, 37, undefined]]],
+ ['property-value', 'red', [[1, 43, undefined]]]
+ ]
]);
}
}
})
.addBatch({
'aggressive off - (yet) not overriddable': {
- 'topic': 'a{display:inline-block;color:red;display:-moz-block}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false), [
- [['display'], ['inline-block']],
- [['color'], ['red']],
- [['display'], ['-moz-block']]
+ 'topic': function () {
+ return _optimize('a{display:inline-block;color:red;display:-moz-block}', false);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'display', [[1, 2, undefined]]],
+ ['property-value', 'inline-block', [[1, 10, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'color', [[1, 23, undefined]]],
+ ['property-value', 'red', [[1, 29, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 33, undefined]]],
+ ['property-value', '-moz-block', [[1, 41, undefined]]]
+ ]
]);
}
}
})
.addBatch({
'understandable - 2 properties, both !important, 2nd less understandable': {
- 'topic': 'a{color:red!important;display:block;color:rgba(0,255,0,.5)!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['color'], ['red!important']],
- [['display'], ['block']],
- [['color'], ['rgba(0,255,0,.5)!important']]
+ 'topic': function () {
+ return _optimize('a{color:red!important;display:block;color:rgba(0,255,0,.5)!important}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 2, undefined]]],
+ ['property-value', 'red!important', [[1, 8, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 22, undefined]]],
+ ['property-value', 'block', [[1, 30, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'color', [[1, 36, undefined]]],
+ ['property-value', 'rgba(0,255,0,.5)!important', [[1, 42, undefined]]]
+ ]
]);
}
},
'understandable - 2 properties, both !important, 2nd more understandable': {
- 'topic': 'a{color:rgba(0,255,0,.5)!important;display:block;color:red!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['display'], ['block']],
- [['color'], ['red!important']]
+ 'topic': function () {
+ return _optimize('a{color:rgba(0,255,0,.5)!important;display:block;color:red!important}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'display', [[1, 35, undefined]]],
+ ['property-value', 'block', [[1, 43, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'color', [[1, 49, undefined]]],
+ ['property-value', 'red!important', [[1, 55, undefined]]]
+ ]
]);
}
},
'understandable - 2 adjacent properties, both !important, 2nd less understandable': {
- 'topic': 'a{background:red!important;background:rgba(0,255,0,.5)!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['background'], ['red!important']],
- [['background'], ['rgba(0,255,0,.5)!important']]
+ 'topic': function () {
+ return _optimize('a{background:red!important;background:rgba(0,255,0,.5)!important}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'red!important', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 27, undefined]]],
+ ['property-value', 'rgba(0,255,0,.5)!important', [[1, 38, undefined]]]
+ ]
]);
}
},
'understandable - 2 adjacent properties, both !important, 2nd more understandable': {
- 'topic': 'a{background:rgba(0,255,0,.5)!important;background:red!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['background'], ['rgba(0,255,0,.5)!important']],
- [['background'], ['red!important']]
+ 'topic': function () {
+ return _optimize('a{background:rgba(0,255,0,.5)!important;background:red!important}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'rgba(0,255,0,.5)!important', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 40, undefined]]],
+ ['property-value', 'red!important', [[1, 51, undefined]]]
+ ]
]);
}
},
'understandable - 2 adjacent -ms-transform with different values': {
- 'topic': 'div{-ms-transform:translate(0,0);-ms-transform:translate3d(0,0,0)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['-ms-transform'], ['translate(0,0)']],
- [['-ms-transform'], ['translate3d(0,0,0)']]
+ 'topic': function () {
+ return _optimize('div{-ms-transform:translate(0,0);-ms-transform:translate3d(0,0,0)}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', '-ms-transform', [[1, 4, undefined]]],
+ ['property-value', 'translate(0,0)', [[1, 18, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', '-ms-transform', [[1, 33, undefined]]],
+ ['property-value', 'translate3d(0,0,0)', [[1, 47, undefined]]]
+ ]
]);
}
},
'understandable - 2 non-adjacent -ms-transform with different values': {
- 'topic': 'div{-ms-transform:translate(0,0);-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['-ms-transform'], ['translate(0,0)']],
- [['-webkit-transform'], ['translate3d(0,0,0)']],
- [['-ms-transform'], ['translate3d(0,0,0)']]
+ 'topic': function () {
+ return _optimize('div{-ms-transform:translate(0,0);-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0)}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', '-ms-transform', [[1, 4, undefined]]],
+ ['property-value', 'translate(0,0)', [[1, 18, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', '-webkit-transform', [[1, 33, undefined]]],
+ ['property-value', 'translate3d(0,0,0)', [[1, 51, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', '-ms-transform', [[1, 70, undefined]]],
+ ['property-value', 'translate3d(0,0,0)', [[1, 84, undefined]]]
+ ]
]);
}
},
'understandable - 2 adjacent transform with different values': {
- 'topic': 'div{transform:translate(0,0);transform:translate3d(0,0,0)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['transform'], ['translate(0,0)']],
- [['transform'], ['translate3d(0,0,0)']]
+ 'topic': function () {
+ return _optimize('div{transform:translate(0,0);transform:translate3d(0,0,0)}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'transform', [[1, 4, undefined]]],
+ ['property-value', 'translate(0,0)', [[1, 14, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'transform', [[1, 29, undefined]]],
+ ['property-value', 'translate3d(0,0,0)', [[1, 39, undefined]]]
+ ]
]);
}
},
'understandable - 2 non-adjacent transform with different values': {
- 'topic': 'div{transform:translate(0,0);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['transform'], ['translate(0,0)']],
- [['-webkit-transform'], ['translate3d(0,0,0)']],
- [['transform'], ['translate3d(0,0,0)']]
+ 'topic': function () {
+ return _optimize('div{transform:translate(0,0);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'transform', [[1, 4, undefined]]],
+ ['property-value', 'translate(0,0)', [[1, 14, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', '-webkit-transform', [[1, 29, undefined]]],
+ ['property-value', 'translate3d(0,0,0)', [[1, 47, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'transform', [[1, 66, undefined]]],
+ ['property-value', 'translate3d(0,0,0)', [[1, 76, undefined]]]
+ ]
]);
}
},
'understandable - border(hex) with border(rgba)': {
- 'topic': 'a{border:1px solid #fff;border:1px solid rgba(1,0,0,.5)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['border'], ['1px'], ['solid'], ['#fff']],
- [['border'], ['1px'], ['solid'], ['rgba(1,0,0,.5)']]
+ 'topic': function () {
+ return _optimize('a{border:1px solid #fff;border:1px solid rgba(1,0,0,.5)}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border', [[1, 2, undefined]]],
+ ['property-value', '1px', [[1, 9, undefined]]],
+ ['property-value', 'solid', [[1, 13, undefined]]],
+ ['property-value', '#fff', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'border', [[1, 24, undefined]]],
+ ['property-value', '1px', [[1, 31, undefined]]],
+ ['property-value', 'solid', [[1, 35, undefined]]],
+ ['property-value', 'rgba(1,0,0,.5)', [[1, 41, undefined]]]
+ ]
]);
}
},
'understandable - border(hex) with border(rgba !important)': {
- 'topic': 'a{border:1px solid #fff;border:1px solid rgba(1,0,0,.5)!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['border'], ['1px'], ['solid'], ['#fff']],
- [['border'], ['1px'], ['solid'], ['rgba(1,0,0,.5)!important']]
+ 'topic': function () {
+ return _optimize('a{border:1px solid #fff;border:1px solid rgba(1,0,0,.5)!important}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border', [[1, 2, undefined]]],
+ ['property-value', '1px', [[1, 9, undefined]]],
+ ['property-value', 'solid', [[1, 13, undefined]]],
+ ['property-value', '#fff', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'border', [[1, 24, undefined]]],
+ ['property-value', '1px', [[1, 31, undefined]]],
+ ['property-value', 'solid', [[1, 35, undefined]]],
+ ['property-value', 'rgba(1,0,0,.5)!important', [[1, 41, undefined]]]
+ ]
]);
}
},
'understandable - border(hex !important) with border(hex)': {
- 'topic': 'a{border:1px solid #fff!important;display:block;border:1px solid #fff}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['border'], ['1px'], ['solid'], ['#fff!important']],
- [['display'], ['block']]
+ 'topic': function () {
+ return _optimize('a{border:1px solid #fff!important;display:block;border:1px solid #fff}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border', [[1, 2, undefined]]],
+ ['property-value', '1px', [[1, 9, undefined]]],
+ ['property-value', 'solid', [[1, 13, undefined]]],
+ ['property-value', '#fff!important', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 34, undefined]]],
+ ['property-value', 'block', [[1, 42, undefined]]]
+ ]
]);
}
},
'understandable - border(hex) with border(hex !important)': {
- 'topic': 'a{border:1px solid #fff;display:block;border:1px solid #fff!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['display'], ['block']],
- [['border'], ['1px'], ['solid'], ['#fff!important']]
+ 'topic': function () {
+ return _optimize('a{border:1px solid #fff;display:block;border:1px solid #fff!important}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'display', [[1, 24, undefined]]],
+ ['property-value', 'block', [[1, 32, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'border', [[1, 38, undefined]]],
+ ['property-value', '1px', [[1, 45, undefined]]],
+ ['property-value', 'solid', [[1, 49, undefined]]],
+ ['property-value', '#fff!important', [[1, 55, undefined]]]
+ ]
]);
}
},
'understandable - unit with function with unit without one': {
- 'topic': 'a{border-top-width:calc(100%);display:block;border-top-width:1px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['display'], ['block']],
- [['border-top-width'], ['1px']]
+ 'topic': function () {
+ return _optimize('a{border-top-width:calc(100%);display:block;border-top-width:1px}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'display', [[1, 30, undefined]]],
+ ['property-value', 'block', [[1, 38, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'border-top-width', [[1, 44, undefined]]],
+ ['property-value', '1px', [[1, 61, undefined]]]
+ ]
]);
}
},
'understandable - unit without function with unit with one': {
- 'topic': 'a{border-top-width:1px;display:block;border-top-width:calc(100%)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['border-top-width'], ['1px']],
- [['display'], ['block']],
- [['border-top-width'], ['calc(100%)']]
+ 'topic': function () {
+ return _optimize('a{border-top-width:1px;display:block;border-top-width:calc(100%)}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-top-width', [[1, 2, undefined]]],
+ ['property-value', '1px', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 23, undefined]]],
+ ['property-value', 'block', [[1, 31, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'border-top-width', [[1, 37, undefined]]],
+ ['property-value', 'calc(100%)', [[1, 54, undefined]]]
+ ]
]);
}
},
'understandable - non adjacent units': {
- 'topic': 'a{margin-top:100px;padding-top:30px;margin-top:10vmin}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true), [
- [['padding-top'], ['30px']],
- [['margin-top'], ['10vmin']]
+ 'topic': function () {
+ return _optimize('a{margin-top:80px;padding-top:30px;margin-top:10vmin}', false, true);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'padding-top', [[1, 18, undefined]]],
+ ['property-value', '30px', [[1, 30, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'margin-top', [[1, 35, undefined]]],
+ ['property-value', '10vmin', [[1, 46, undefined]]]
+ ]
]);
}
}
})
.addBatch({
'understandable - non adjacent units in IE8 mode': {
- 'topic': 'a{margin-top:80px;padding-top:30px;margin-top:10vmin}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, false, true, 'ie8'), [
- [['margin-top'], ['80px']],
- [['padding-top'], ['30px']],
- [['margin-top'], ['10vmin']]
+ 'topic': function () {
+ return _optimize('a{margin-top:80px;padding-top:30px;margin-top:10vmin}', false, true, 'ie8');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'margin-top', [[1, 2, undefined]]],
+ ['property-value', '80px', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-top', [[1, 18, undefined]]],
+ ['property-value', '30px', [[1, 30, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'margin-top', [[1, 35, undefined]]],
+ ['property-value', '10vmin', [[1, 46, undefined]]]
+ ]
]);
}
}
var optimize = require('../../lib/properties/optimizer');
var tokenize = require('../../lib/tokenizer/tokenize');
-var SourceTracker = require('../../lib/utils/source-tracker');
-var Compatibility = require('../../lib/utils/compatibility');
+var compatibility = require('../../lib/utils/compatibility');
var Validator = require('../../lib/properties/validator');
-function _optimize(source, compatibility, aggressiveMerging) {
+function _optimize(source, compat, aggressiveMerging) {
var tokens = tokenize(source, {
options: {},
- sourceTracker: new SourceTracker(),
warnings: []
});
- compatibility = new Compatibility(compatibility).toOptions();
+ compat = compatibility(compat);
- var validator = new Validator(compatibility);
+ var validator = new Validator(compat);
var options = {
aggressiveMerging: undefined === aggressiveMerging ? true : aggressiveMerging,
- compatibility: compatibility,
+ compatibility: compat,
shorthandCompacting: true
};
- optimize(tokens[0][1], tokens[0][2], false, true, options, { validator: validator });
+ optimize(tokens[0][1], tokens[0][2], false, true, { options: options, validator: validator });
return tokens[0][2];
}
vows.describe(optimize)
.addBatch({
'longhand then longhand - background colors as functions': {
- 'topic': 'p{background-color:-ms-linear-gradient(top,red,#000);background-color:linear-gradient(top,red,#000)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background-color'], ['-ms-linear-gradient(top,red,#000)']],
- [['background-color'], ['linear-gradient(top,red,#000)']]
+ 'topic': function () {
+ return _optimize('p{background-color:-ms-linear-gradient(top,red,#000);background-color:linear-gradient(top,red,#000)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-color', [[1, 2, undefined]]],
+ ['property-value', '-ms-linear-gradient(top,red,#000)', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-color', [[1, 53, undefined]]],
+ ['property-value', 'linear-gradient(top,red,#000)', [[1, 70, undefined]]]
+ ]
]);
}
},
'longhand then longhand - background position as function': {
- 'topic': 'p{background-position:-moz-calc(100% - 1em) 0;background-position:calc(100% - 1em) 0}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background-position'], ['-moz-calc(100% - 1em)'], ['0']],
- [['background-position'], ['calc(100% - 1em)'], ['0']]
+ 'topic': function () {
+ return _optimize('p{background-position:-moz-calc(100% - 1em) 0;background-position:calc(100% - 1em) 0}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-position', [[1, 2, undefined]]],
+ ['property-value', '-moz-calc(100% - 1em)', [[1, 22, undefined]]],
+ ['property-value', '0', [[1, 44, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-position', [[1, 46, undefined]]],
+ ['property-value', 'calc(100% - 1em)', [[1, 66, undefined]]],
+ ['property-value', '0', [[1, 83, undefined]]]
+ ]
]);
}
},
'longhand then longhand - background position as same function': {
- 'topic': 'p{background-position:calc(100% - 1em) 0;background-position:calc(100% - 1em) 1em}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background-position'], ['calc(100% - 1em)'], ['1em']]
+ 'topic': function () {
+ return _optimize('p{background-position:calc(100% - 1em) 0;background-position:calc(100% - 1em) 1em}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-position', [[1, 41, undefined]]],
+ ['property-value', 'calc(100% - 1em)', [[1, 61, undefined]]],
+ ['property-value', '1em', [[1, 78, undefined]]]
+ ]
]);
}
},
'longhand then longhand - background position as function by value': {
- 'topic': 'p{background-position:calc(100% - 1em) 0;background-position:1em 1em}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background-position'], ['1em'], ['1em']]
+ 'topic': function () {
+ return _optimize('p{background-position:calc(100% - 1em) 0;background-position:1em 1em}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-position', [[1, 41, undefined]]],
+ ['property-value', '1em', [[1, 61, undefined]]],
+ ['property-value', '1em', [[1, 65, undefined]]]
+ ]
]);
}
},
'longhand then longhand - background position as value by function': {
- 'topic': 'p{background-position:1em 0;background-position:calc(100% - 1em) 1em}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background-position'], ['1em'], ['0']],
- [['background-position'], ['calc(100% - 1em)'], ['1em']]
+ 'topic': function () {
+ return _optimize('p{background-position:1em 0;background-position:calc(100% - 1em) 1em}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-position', [[1, 2, undefined]]],
+ ['property-value', '1em', [[1, 22, undefined]]],
+ ['property-value', '0', [[1, 26, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-position', [[1, 28, undefined]]],
+ ['property-value', 'calc(100% - 1em)', [[1, 48, undefined]]],
+ ['property-value', '1em', [[1, 65, undefined]]]
+ ]
]);
}
},
'longhand then longhand - background size as function': {
- 'topic': 'p{background-size:-moz-calc(100% - 1em) 0;background-size:calc(100% - 1em) 0}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background-size'], ['-moz-calc(100% - 1em)'], ['0']],
- [['background-size'], ['calc(100% - 1em)'], ['0']]
+ 'topic': function () {
+ return _optimize('p{background-size:-moz-calc(100% - 1em) 0;background-size:calc(100% - 1em) 0}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-size', [[1, 2, undefined]]],
+ ['property-value', '-moz-calc(100% - 1em)', [[1, 18, undefined]]],
+ ['property-value', '0', [[1, 40, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-size', [[1, 42, undefined]]],
+ ['property-value', 'calc(100% - 1em)', [[1, 58, undefined]]],
+ ['property-value', '0', [[1, 75, undefined]]]
+ ]
]);
}
},
'longhand then shorthand': {
- 'topic': 'p{background-image:none;background:__ESCAPED_URL_CLEAN_CSS0__}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']]
+ 'topic': function () {
+ return _optimize('p{background-image:none;background:url(image.png)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 24, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 35, undefined]]]
+ ]
]);
}
},
'longhand then shorthand - important then non-important': {
- 'topic': 'p{background-image:none!important;background:__ESCAPED_URL_CLEAN_CSS0__}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background-image'], ['none!important']],
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']]
+ 'topic': function () {
+ return _optimize('p{background-image:none!important;background:url(image.png)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 2, undefined]]],
+ ['property-value', 'none!important', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 34, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 45, undefined]]]
+ ]
]);
}
},
'longhand then shorthand - with vendor prefixed function': {
- 'topic': 'p{background-color:red;background:-ms-linear-gradient(top,red,#000)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background-color'], ['red']],
- [['background'], ['-ms-linear-gradient(top,red,#000)']],
+ 'topic': function () {
+ return _optimize('p{background-color:red;background:-ms-linear-gradient(top,red,#000)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-color', [[1, 2, undefined]]],
+ ['property-value', 'red', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 23, undefined]]],
+ ['property-value', '-ms-linear-gradient(top,red,#000)', [[1, 34, undefined]]]
+ ]
]);
}
},
'longhand then shorthand - with same vendor prefixed function': {
- 'topic': 'p{background-image:-ms-linear-gradient(bottom,black,white);background:-ms-linear-gradient(top,red,#000)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['-ms-linear-gradient(top,red,#000)']],
+ 'topic': function () {
+ return _optimize('p{background-image:-ms-linear-gradient(bottom,black,white);background:-ms-linear-gradient(top,red,#000)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 59, undefined]]],
+ ['property-value', '-ms-linear-gradient(top,red,#000)', [[1, 70, undefined]]]
+ ]
]);
}
},
'longhand then shorthand - with different vendor prefixed function': {
- 'topic': 'p{background-image:linear-gradient(bottom,black,white);background:-ms-linear-gradient(top,red,#000)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background-image'], ['linear-gradient(bottom,black,white)']],
- [['background'], ['-ms-linear-gradient(top,red,#000)']],
+ 'topic': function () {
+ return _optimize('p{background-image:linear-gradient(bottom,black,white);background:-ms-linear-gradient(top,red,#000)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 2, undefined]]],
+ ['property-value', 'linear-gradient(bottom,black,white)', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 55, undefined]]],
+ ['property-value', '-ms-linear-gradient(top,red,#000)', [[1, 66, undefined]]]
+ ]
]);
}
},
'longhand then shorthand - with unprefixed function': {
- 'topic': 'p{background-color:red;background:linear-gradient(red,blue)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background-color'], ['red']],
- [['background'], ['linear-gradient(red,blue)']]
+ 'topic': function () {
+ return _optimize('p{background-color:red;background:linear-gradient(red,blue)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-color', [[1, 2, undefined]]],
+ ['property-value', 'red', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 23, undefined]]],
+ ['property-value', 'linear-gradient(red,blue)', [[1, 34, undefined]]]
+ ]
]);
}
},
'shorthand then longhand': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__ repeat;background-repeat:no-repeat}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png) repeat;background-repeat:no-repeat}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]],
+ ['property-value', 'no-repeat', [[1, 53, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - important then non-important': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__ repeat-x!important;background-repeat:no-repeat}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['repeat-x!important']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png) repeat-x!important;background-repeat:no-repeat}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]],
+ ['property-value', 'repeat-x!important', [[1, 28, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - non-important then important': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__ repeat;background-repeat:no-repeat!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
- [['background-repeat'], ['no-repeat!important']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png) repeat;background-repeat:no-repeat!important}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-repeat', [[1, 35, undefined]]],
+ ['property-value', 'no-repeat!important', [[1, 53, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - disabled background size merging': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-size:50%}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, { properties: { backgroundSizeMerging: false } }), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
- [['background-size'], ['50%']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png);background-size:50%}', { properties: { backgroundSizeMerging: false } });
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-size', [[1, 28, undefined]]],
+ ['property-value', '50%', [[1, 44, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - disabled background clip merging': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-clip:padding-box}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, { properties: { backgroundClipMerging: false } }), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
- [['background-clip'], ['padding-box']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png);background-clip:padding-box}', { properties: { backgroundClipMerging: false } });
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-clip', [[1, 28, undefined]]],
+ ['property-value', 'padding-box', [[1, 44, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - enabled background clip merging': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-clip:padding-box}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, { properties: { backgroundClipMerging: true } }), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['padding-box']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png);background-clip:padding-box}', { properties: { backgroundClipMerging: true } });
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]],
+ ['property-value', 'padding-box']
+ ]
]);
}
},
'shorthand then longhand - disabled background origin merging': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-origin:border-box}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, { properties: { backgroundOriginMerging: false } }), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
- [['background-origin'], ['border-box']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png);background-origin:border-box}', { properties: { backgroundOriginMerging: false } });
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-origin', [[1, 28, undefined]]],
+ ['property-value', 'border-box', [[1, 46, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - enabled background origin merging': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-origin:border-box}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, { properties: { backgroundOriginMerging: true } }), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['border-box']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png);background-origin:border-box}', { properties: { backgroundOriginMerging: true } });
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]],
+ ['property-value', 'border-box', [[1, 46, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - non mergeable value': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-color:none}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
- [['background-color'], ['none']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png);background-color:none}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-color', [[1, 28, undefined]]],
+ ['property-value', 'none', [[1, 45, undefined]]]
+ ]
]);
}
},
'shorthand then multiplex longhand - non mergeable value': {
- 'topic': 'p{background:#fff;background-image:__ESCAPED_URL_CLEAN_CSS0__,linear-gradient()}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['#fff']],
- [['background-image'], ['__ESCAPED_URL_CLEAN_CSS0__'], [','], ['linear-gradient()']]
+ 'topic': function () {
+ return _optimize('p{background:#fff;background-image:url(image.png),linear-gradient()}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', '#fff', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 18, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 35, undefined]]],
+ ['property-value', ',', [[1, 49, undefined]]],
+ ['property-value', 'linear-gradient()', [[1, 50, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - border with rgba() and color opacity on': {
- 'topic': 'p{border:solid rgba(0,0,0,0);border-color:transparent}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, { colors: { opacity: true } }), [
- [['border'], ['solid'], ['transparent']]
+ 'topic': function () {
+ return _optimize('p{border:solid rgba(0,0,0,0);border-color:transparent}', { colors: { opacity: true } });
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border', [[1, 2, undefined]]],
+ ['property-value', 'solid', [[1, 9, undefined]]],
+ ['property-value', 'transparent', [[1, 42, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - border with rgba() and color opacity off': {
- 'topic': 'p{border:solid rgba(0,0,0,0);border-color:transparent}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, { colors: { opacity: false } }), [
- [['border'], ['solid'], ['rgba(0,0,0,0)']],
- [['border-color'], ['transparent']]
+ 'topic': function () {
+ return _optimize('p{border:solid rgba(0,0,0,0);border-color:transparent}', { colors: { opacity: false } });
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border', [[1, 2, undefined]]],
+ ['property-value', 'solid', [[1, 9, undefined]]],
+ ['property-value', 'rgba(0,0,0,0)', [[1, 15, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'border-color', [[1, 29, undefined]]],
+ ['property-value', 'transparent', [[1, 42, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - color into a color - with merging off': {
- 'topic': 'p{background:white;background-color:red}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, { properties: { merging: false } }), [
- [['background'], ['red']]
+ 'topic': function () {
+ return _optimize('p{background:white;background-color:red}', { properties: { merging: false } });
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'red', [[1, 36, undefined]]]
+ ],
]);
}
},
'shorthand then longhand - color into a function - with merging off': {
- 'topic': 'p{background:linear-gradient();background-color:red}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, { properties: { merging: false } }), [
- [['background'], ['linear-gradient()']],
- [['background-color'], ['red']]
+ 'topic': function () {
+ return _optimize('p{background:linear-gradient();background-color:red}', { properties: { merging: false } });
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'linear-gradient()', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-color', [[1, 31, undefined]]],
+ ['property-value', 'red', [[1, 48, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - two shorthands - pending #527': {
- 'topic': 'p{background:-webkit-linear-gradient();background:linear-gradient();background-repeat:repeat-x}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['-webkit-linear-gradient()']],
- [['background'], ['linear-gradient()']],
- [['background-repeat'], ['repeat-x']]
+ 'topic': function () {
+ return _optimize('p{background:-webkit-linear-gradient();background:linear-gradient();background-repeat:repeat-x}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', '-webkit-linear-gradient()', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 39, undefined]]],
+ ['property-value', 'linear-gradient()', [[1, 50, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-repeat', [[1, 68, undefined]]],
+ ['property-value', 'repeat-x', [[1, 86, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - two shorthands and default - pending #527': {
- 'topic': 'p{background:-webkit-linear-gradient();background:linear-gradient();background-repeat:repeat}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['-webkit-linear-gradient()']],
- [['background'], ['linear-gradient()']],
- [['background-repeat'], ['repeat']]
+ 'topic': function () {
+ return _optimize('p{background:-webkit-linear-gradient();background:linear-gradient();background-repeat:repeat}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', '-webkit-linear-gradient()', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 39, undefined]]],
+ ['property-value', 'linear-gradient()', [[1, 50, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-repeat', [[1, 68, undefined]]],
+ ['property-value', 'repeat', [[1, 86, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - two mergeable shorthands and default - pending #527': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background:__ESCAPED_URL_CLEAN_CSS1__;background-repeat:repeat-x}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS1__']],
- [['background-repeat'], ['repeat-x']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png);background:url(image.jpg);background-repeat:repeat-x}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.jpg)', [[1, 39, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-repeat', [[1, 54, undefined]]],
+ ['property-value', 'repeat-x', [[1, 72, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - non-function into a function': {
- 'topic': 'p{background:linear-gradient();background-color:red}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['linear-gradient()']],
- [['background-color'], ['red']]
+ 'topic': function () {
+ return _optimize('p{background:linear-gradient();background-color:red}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'linear-gradient()', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-color', [[1, 31, undefined]]],
+ ['property-value', 'red', [[1, 48, undefined]]]
+ ]
]);
}
},
'shorthand then longhand - function into a non-function': {
- 'topic': 'p{background:repeat-x;background-image:-webkit-linear-gradient()}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['repeat-x']],
- [['background-image'], ['-webkit-linear-gradient()']]
+ 'topic': function () {
+ return _optimize('p{background:repeat-x;background-image:-webkit-linear-gradient()}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'repeat-x', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 22, undefined]]],
+ ['property-value', '-webkit-linear-gradient()', [[1, 39, undefined]]]
+ ]
]);
}
},
'shorthand then shorthand - same values': {
- 'topic': 'p{background:red;background:red}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['red']]
+ 'topic': function () {
+ return _optimize('p{background:red;background:red}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'red', [[1, 28, undefined]]]
+ ]
]);
}
},
'shorthand then shorthand - same values with defaults': {
- 'topic': 'p{background:repeat red;background:red}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['red']]
+ 'topic': function () {
+ return _optimize('p{background:repeat red;background:red}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'red', [[1, 35, undefined]]]
+ ]
]);
}
},
'shorthand then shorthand - with different functions': {
- 'topic': 'p{background:linear-gradient();background:-webkit-gradient()}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['linear-gradient()']],
- [['background'], ['-webkit-gradient()']]
+ 'topic': function () {
+ return _optimize('p{background:linear-gradient();background:-webkit-gradient()}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'linear-gradient()', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 31, undefined]]],
+ ['property-value', '-webkit-gradient()', [[1, 42, undefined]]]
+ ]
]);
}
},
'shorthand then shorthand - with function then url': {
- 'topic': 'p{background:linear-gradient();background:__ESCAPED_URL_CLEAN_CSS0__}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']]
+ 'topic': function () {
+ return _optimize('p{background:linear-gradient();background:url(image.png)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 42, undefined]]]
+ ]
]);
}
},
'shorthand then shorthand - with url then function': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background:linear-gradient()}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
- [['background'], ['linear-gradient()']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png);background:linear-gradient()}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 28, undefined]]],
+ ['property-value', 'linear-gradient()', [[1, 39, undefined]]]
+ ]
]);
}
},
'shorthand then shorthand - important then non-important': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__ no-repeat!important;background:__ESCAPED_URL_CLEAN_CSS1__ repeat red}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat!important']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png) no-repeat!important;background:url(image.jpg) repeat red}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]],
+ ['property-value', 'no-repeat!important', [[1, 28, undefined]]]
+ ]
]);
}
},
'shorthand then shorthand - non-important then important': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__ no-repeat;background:__ESCAPED_URL_CLEAN_CSS1__ repeat red!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS1__'], ['red!important']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png) no-repeat;background:url(image.jpg) repeat red!important}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 38, undefined]]],
+ ['property-value', 'url(image.jpg)', [[1, 49, undefined]]],
+ ['property-value', 'red!important', [[1, 71, undefined]]]
+ ]
]);
}
},
'shorthand then shorthand - same value and latter important': {
- 'topic': 'a{margin:0;margin:0 !important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['margin'], ['0!important']]
+ 'topic': function () {
+ return _optimize('a{margin:0;margin:0 !important}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'margin', [[1, 11, undefined]]],
+ ['property-value', '0!important', [[1, 18, undefined]]]
+ ]
]);
}
},
'with aggressive off': {
- 'topic': 'a{background:white;color:red;background:red}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic, null, false), [
- [['background'], ['red']],
- [['color'], ['red']]
+ 'topic': function () {
+ return _optimize('a{background:white;color:red;background:red}', undefined, false);
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'red', [[1, 40, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'color', [[1, 19, undefined]]],
+ ['property-value', 'red', [[1, 25, undefined]]]
+ ]
]);
}
}
})
.addBatch({
'border': {
- 'topic': 'a{border:1px solid red;border-style:dotted}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border'], ['1px'], ['dotted'], ['red']]
+ 'topic': function () {
+ return _optimize('a{border:1px solid red;border-style:dotted}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border', [[1, 2, undefined]]],
+ ['property-value', '1px', [[1, 9, undefined]]],
+ ['property-value', 'dotted', [[1, 36, undefined]]],
+ ['property-value', 'red', [[1, 19, undefined]]]
+ ]
]);
}
},
'border - multivalue righthand': {
- 'topic': 'a{border:1px solid red;border-style:dotted solid}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border'], ['1px'], ['solid'], ['red']],
- [['border-style'], ['dotted'], ['solid']]
+ 'topic': function () {
+ return _optimize('a{border:1px solid red;border-style:dotted solid}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border', [[1, 2, undefined]]],
+ ['property-value', '1px', [[1, 9, undefined]]],
+ ['property-value', 'solid', [[1, 13, undefined]]],
+ ['property-value', 'red', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'border-style', [[1, 23, undefined]]],
+ ['property-value', 'dotted', [[1, 36, undefined]]],
+ ['property-value', 'solid', [[1, 43, undefined]]]
+ ]
]);
}
},
'border - important righthand': {
- 'topic': 'a{border:1px solid red;border-style:dotted!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border'], ['1px'], ['solid'], ['red']],
- [['border-style'], ['dotted!important']]
+ 'topic': function () {
+ return _optimize('a{border:1px solid red;border-style:dotted!important}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border', [[1, 2, undefined]]],
+ ['property-value', '1px', [[1, 9, undefined]]],
+ ['property-value', 'solid', [[1, 13, undefined]]],
+ ['property-value', 'red', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'border-style', [[1, 23, undefined]]],
+ ['property-value', 'dotted!important', [[1, 36, undefined]]],
+ ]
]);
}
},
'border - important lefthand': {
- 'topic': 'a{border:1px solid red!important;border-style:dotted}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border'], ['1px'], ['solid'], ['red!important']]
+ 'topic': function () {
+ return _optimize('a{border:1px solid red!important;border-style:dotted}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border', [[1, 2, undefined]]],
+ ['property-value', '1px', [[1, 9, undefined]]],
+ ['property-value', 'solid', [[1, 13, undefined]]],
+ ['property-value', 'red!important', [[1, 19, undefined]]]
+ ]
]);
}
},
'border - both important': {
- 'topic': 'a{border:1px solid red!important;border-style:dotted!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border'], ['1px'], ['dotted'], ['red!important']]
+ 'topic': function () {
+ return _optimize('a{border:1px solid red!important;border-style:dotted!important}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border', [[1, 2, undefined]]],
+ ['property-value', '1px', [[1, 9, undefined]]],
+ ['property-value', 'dotted', [[1, 46, undefined]]],
+ ['property-value', 'red!important', [[1, 19, undefined]]]
+ ]
]);
}
},
'border - hex and rgb colors': {
- 'topic': 'a{border:1px solid #000;border-color:rgba(255,0,0,.5)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border'], ['1px'], ['solid'], ['#000']],
- [['border-color'], ['rgba(255,0,0,.5)']]
+ 'topic': function () {
+ return _optimize('a{border:1px solid #000;border-color:rgba(255,0,0,.5)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border', [[1, 2, undefined]]],
+ ['property-value', '1px', [[1, 9, undefined]]],
+ ['property-value', 'solid', [[1, 13, undefined]]],
+ ['property-value', '#000', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'border-color', [[1, 24, undefined]]],
+ ['property-value', 'rgba(255,0,0,.5)', [[1, 37, undefined]]],
+ ]
]);
}
},
'border-color - hex then rgb': {
- 'topic': 'a{border-color:#000;border-color:rgba(255,0,0,.5)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border-color'], ['#000']],
- [['border-color'], ['rgba(255,0,0,.5)']]
+ 'topic': function () {
+ return _optimize('a{border-color:#000;border-color:rgba(255,0,0,.5)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-color', [[1, 2, undefined]]],
+ ['property-value', '#000', [[1, 15, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'border-color', [[1, 20, undefined]]],
+ ['property-value', 'rgba(255,0,0,.5)', [[1, 33, undefined]]],
+ ]
]);
}
},
'border-color - rgb then hex': {
- 'topic': 'a{border-color:rgba(255,0,0,.5);border-color:#000}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border-color'], ['#000']]
+ 'topic': function () {
+ return _optimize('a{border-color:rgba(255,0,0,.5);border-color:#000}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-color', [[1, 2, undefined]]],
+ ['property-value', '#000', [[1, 45, undefined]]]
+ ]
]);
}
},
'border-color - hex then rgb with multiple values': {
- 'topic': 'a{border-color:red;border-color:#000 rgba(255,0,0,.5)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border-color'], ['red']],
- [['border-color'], ['#000'], ['rgba(255,0,0,.5)']]
+ 'topic': function () {
+ return _optimize('a{border-color:red;border-color:#000 rgba(255,0,0,.5)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-color', [[1, 2, undefined]]],
+ ['property-value', 'red', [[1, 15, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'border-color', [[1, 19, undefined]]],
+ ['property-value', '#000', [[1, 32, undefined]]],
+ ['property-value', 'rgba(255,0,0,.5)', [[1, 37, undefined]]],
+ ]
]);
}
}
})
.addBatch({
'border radius': {
- 'topic': 'a{-moz-border-radius:2px;-moz-border-top-left-radius:3px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['-moz-border-radius'], ['3px'], ['2px'], ['2px']]
+ 'topic': function () {
+ return _optimize('a{-moz-border-radius:2px;-moz-border-top-left-radius:3px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', '-moz-border-radius', [[1, 2, undefined]]],
+ ['property-value', '3px', [[1, 53, undefined]]],
+ ['property-value', '2px', [[1, 21, undefined]]],
+ ['property-value', '2px', [[1, 21, undefined]]]
+ ]
]);
}
},
'border radius prefixed and unprefixed': {
- 'topic': 'a{-moz-border-radius:2px;border-top-left-radius:3px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['-moz-border-radius'], ['2px']],
- [['border-top-left-radius'], ['3px']]
+ 'topic': function () {
+ return _optimize('a{-moz-border-radius:2px;border-top-left-radius:3px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', '-moz-border-radius', [[1, 2, undefined]]],
+ ['property-value', '2px', [[1, 21, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'border-top-left-radius', [[1, 25, undefined]]],
+ ['property-value', '3px', [[1, 48, undefined]]]
+ ]
]);
}
},
'border width': {
- 'topic': 'a{border-width:2px 3px 2px 1px;border-left-width:3px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border-width'], ['2px'], ['3px']]
+ 'topic': function () {
+ return _optimize('a{border-width:2px 3px 2px 1px;border-left-width:3px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-width', [[1, 2, undefined]]],
+ ['property-value', '2px', [[1, 15, undefined]]],
+ ['property-value', '3px', [[1, 19, undefined]]]
+ ]
]);
}
},
'list style': {
- 'topic': 'a{list-style:circle inside;list-style-image:__ESCAPED_URL_CLEAN_CSS0__}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['list-style'], ['circle'], ['inside'], ['__ESCAPED_URL_CLEAN_CSS0__']]
+ 'topic': function () {
+ return _optimize('a{list-style:circle inside;list-style-image:url(image.png)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'list-style', [[1, 2, undefined]]],
+ ['property-value', 'circle', [[1, 13, undefined]]],
+ ['property-value', 'inside', [[1, 20, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 44, undefined]]]
+ ]
]);
}
},
'margin': {
- 'topic': 'a{margin:10px 20px;margin-left:25px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['margin'], ['10px'], ['20px'], ['10px'], ['25px']]
+ 'topic': function () {
+ return _optimize('a{margin:10px 20px;margin-left:25px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'margin', [[1, 2, undefined]]],
+ ['property-value', '10px', [[1, 9, undefined]]],
+ ['property-value', '20px', [[1, 14, undefined]]],
+ ['property-value', '10px', [[1, 9, undefined]]],
+ ['property-value', '25px', [[1, 31, undefined]]]
+ ]
]);
}
},
'outline': {
- 'topic': 'a{outline:red solid 1px;outline-width:3px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['outline'], ['red'], ['solid'], ['3px']]
+ 'topic': function () {
+ return _optimize('a{outline:red solid 1px;outline-width:3px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'outline', [[1, 2, undefined]]],
+ ['property-value', 'red', [[1, 10, undefined]]],
+ ['property-value', 'solid', [[1, 14, undefined]]],
+ ['property-value', '3px', [[1, 38, undefined]]]
+ ]
]);
}
},
'padding': {
- 'topic': 'a{padding:10px;padding-right:20px;padding-left:20px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['padding'], ['10px'], ['20px']]
+ 'topic': function () {
+ return _optimize('a{padding:10px;padding-right:20px;padding-left:20px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'padding', [[1, 2, undefined]]],
+ ['property-value', '10px', [[1, 10, undefined]]],
+ ['property-value', '20px', [[1, 29, undefined]]],
+ ]
]);
}
}
})
.addBatch({
'colors with same understandability': {
- 'topic': 'a{color:red;color:#fff;color:blue}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['color'], ['blue']]
+ 'topic': function () {
+ return _optimize('a{color:red;color:#fff;color:blue}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 23, undefined]]],
+ ['property-value', 'blue', [[1, 29, undefined]]],
+ ]
]);
}
},
'colors with different understandability': {
- 'topic': 'a{color:red;color:#fff;color:blue;color:rgba(1,2,3,.4)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['color'], ['blue']],
- [['color'], ['rgba(1,2,3,.4)']]
+ 'topic': function () {
+ return _optimize('a{color:red;color:#fff;color:blue;color:rgba(1,2,3,.4)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 23, undefined]]],
+ ['property-value', 'blue', [[1, 29, undefined]]],
+ ],
+ [
+ 'property',
+ ['property-name', 'color', [[1, 34, undefined]]],
+ ['property-value', 'rgba(1,2,3,.4)', [[1, 40, undefined]]],
+ ]
]);
}
},
'colors with different understandability overridden by high understandability': {
- 'topic': 'a{color:red;color:#fff;color:blue;color:rgba(1,2,3,.4);color:red}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['color'], ['red']]
+ 'topic': function () {
+ return _optimize('a{color:red;color:#fff;color:blue;color:rgba(1,2,3,.4);color:red}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 55, undefined]]],
+ ['property-value', 'red', [[1, 61, undefined]]],
+ ]
]);
}
},
'colors with different understandability and importance #1': {
- 'topic': 'a{color:#fff!important;color:rgba(1,2,3,.4)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['color'], ['#fff!important']]
+ 'topic': function () {
+ return _optimize('a{color:#fff!important;color:rgba(1,2,3,.4)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 2, undefined]]],
+ ['property-value', '#fff!important', [[1, 8, undefined]]],
+ ]
]);
}
},
'colors with different understandability and importance #2': {
- 'topic': 'a{color:#fff;color:rgba(1,2,3,.4)!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['color'], ['#fff']],
- [['color'], ['rgba(1,2,3,.4)!important']]
+ 'topic': function () {
+ return _optimize('a{color:#fff;color:rgba(1,2,3,.4)!important}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 2, undefined]]],
+ ['property-value', '#fff', [[1, 8, undefined]]],
+ ],
+ [
+ 'property',
+ ['property-name', 'color', [[1, 13, undefined]]],
+ ['property-value', 'rgba(1,2,3,.4)!important', [[1, 19, undefined]]],
+ ]
]);
}
}
})
.addBatch({
'shorthand then shorthand multiplex': {
- 'topic': 'p{background:url(one.png);background:url(two.png) center 1px,url(three.png) center 2px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['url(one.png)']],
- [['background'], ['url(two.png)'], ['center'], ['1px'], [','], ['url(three.png)'], ['center'], ['2px']]
+ 'topic': function () {
+ return _optimize('p{background:url(one.png);background:url(two.png) center 1px,url(three.png) center 2px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(one.png)', [[1, 13, undefined]]],
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 26, undefined]]],
+ ['property-value', 'url(two.png)', [[1, 37, undefined]]],
+ ['property-value', 'center', [[1, 50, undefined]]],
+ ['property-value', '1px', [[1, 57, undefined]]],
+ ['property-value', ','],
+ ['property-value', 'url(three.png)', [[1, 61, undefined]]],
+ ['property-value', 'center', [[1, 76, undefined]]],
+ ['property-value', '2px', [[1, 83, undefined]]]
+ ]
]);
}
},
'shorthand then longhand multiplex': {
- 'topic': 'p{background:top left;background-repeat:no-repeat,no-repeat}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['top'], ['left'], ['no-repeat'], [','], ['top'], ['left'], ['no-repeat']]
+ 'topic': function () {
+ return _optimize('p{background:top left;background-repeat:no-repeat,no-repeat}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'top', [[1, 13, undefined]]],
+ ['property-value', 'left', [[1, 17, undefined]]],
+ ['property-value', 'no-repeat', [[1, 40, undefined]]],
+ ['property-value', ','],
+ ['property-value', 'top', [[1, 13, undefined]]],
+ ['property-value', 'left', [[1, 17, undefined]]],
+ ['property-value', 'no-repeat', [[1, 50, undefined]]]
+ ]
]);
}
},
'shorthand multiplex then longhand': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__,__ESCAPED_URL_CLEAN_CSS1__;background-repeat:no-repeat}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat'], [','], ['__ESCAPED_URL_CLEAN_CSS1__'], ['no-repeat']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png),url(image.jpg);background-repeat:no-repeat}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]],
+ ['property-value', 'no-repeat', [[1, 61, undefined]]],
+ ['property-value', ','],
+ ['property-value', 'url(image.jpg)', [[1, 28, undefined]]],
+ ['property-value', 'no-repeat', [[1, 61, undefined]]]
+ ]
]);
}
},
'longhand then shorthand multiplex': {
- 'topic': 'p{background-repeat:no-repeat;background:__ESCAPED_URL_CLEAN_CSS0__,__ESCAPED_URL_CLEAN_CSS1__}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], [','], ['__ESCAPED_URL_CLEAN_CSS1__']]
+ 'topic': function () {
+ return _optimize('p{background-repeat:no-repeat;background:url(image.png),url(image.jpg)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 30, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 41, undefined]]],
+ ['property-value', ','],
+ ['property-value', 'url(image.jpg)', [[1, 56, undefined]]],
+ ]
]);
}
},
'longhand multiplex then shorthand': {
- 'topic': 'p{background-repeat:no-repeat,no-repeat;background:__ESCAPED_URL_CLEAN_CSS0__}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']]
+ 'topic': function () {
+ return _optimize('p{background-repeat:no-repeat,no-repeat;background:url(image.png)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 40, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 51, undefined]]],
+ ]
]);
}
},
'multiplex longhand into multiplex shorthand': {
- 'topic': 'p{background:no-repeat,no-repeat;background-position:top left,bottom left}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['top'], ['left'], ['no-repeat'], [','], ['bottom'], ['left'], ['no-repeat']]
+ 'topic': function () {
+ return _optimize('p{background:no-repeat,no-repeat;background-position:top left,bottom left}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'top', [[1, 53, undefined]]],
+ ['property-value', 'left', [[1, 57, undefined]]],
+ ['property-value', 'no-repeat', [[1, 13, undefined]]],
+ ['property-value', ','],
+ ['property-value', 'bottom', [[1, 62, undefined]]],
+ ['property-value', 'left', [[1, 69, undefined]]],
+ ['property-value', 'no-repeat', [[1, 23, undefined]]]
+ ]
]);
}
},
'two multiplex shorthands with vendor specific functions': {
- 'topic': 'p{background:url(1.png),-webkit-linear-gradient();background:url(1.png),linear-gradient()}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['url(1.png)'], [','], ['-webkit-linear-gradient()']],
- [['background'], ['url(1.png)'], [','], ['linear-gradient()']]
+ 'topic': function () {
+ return _optimize('p{background:url(1.png),-webkit-linear-gradient();background:url(1.png),linear-gradient()}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(1.png)', [[1, 13, undefined]]],
+ ['property-value', ','],
+ ['property-value', '-webkit-linear-gradient()', [[1, 24, undefined]]],
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 50, undefined]]],
+ ['property-value', 'url(1.png)', [[1, 61, undefined]]],
+ ['property-value', ','],
+ ['property-value', 'linear-gradient()', [[1, 72, undefined]]],
+ ]
]);
}
},
'not too long into multiplex #1': {
- 'topic': 'p{background:top left;background-repeat:no-repeat,no-repeat}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['top'], ['left'], ['no-repeat'], [','], ['top'], ['left'], ['no-repeat']]
+ 'topic': function () {
+ return _optimize('p{background:top left;background-repeat:no-repeat,no-repeat}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'top', [[1, 13, undefined]]],
+ ['property-value', 'left', [[1, 17, undefined]]],
+ ['property-value', 'no-repeat', [[1, 40, undefined]]],
+ ['property-value', ','],
+ ['property-value', 'top', [[1, 13, undefined]]],
+ ['property-value', 'left', [[1, 17, undefined]]],
+ ['property-value', 'no-repeat', [[1, 50, undefined]]]
+ ]
]);
}
},
'not too long into multiplex #2': {
- 'topic': 'p{background:repeat content-box;background-repeat:no-repeat,no-repeat}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['no-repeat'], ['content-box'], [','], ['no-repeat'], ['content-box']]
+ 'topic': function () {
+ return _optimize('p{background:repeat content-box;background-repeat:no-repeat,no-repeat}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'no-repeat', [[1, 50, undefined]]],
+ ['property-value', 'content-box', [[1, 20, undefined]]],
+ ['property-value', ','],
+ ['property-value', 'no-repeat', [[1, 60, undefined]]],
+ ['property-value', 'content-box', [[1, 20, undefined]]]
+ ]
]);
}
},
'not too long into multiplex - twice': {
- 'topic': 'p{background:top left;background-repeat:no-repeat,no-repeat;background-image:__ESCAPED_URL_CLEAN_CSS0__,__ESCAPED_URL_CLEAN_CSS1__}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['top'], ['left'], ['no-repeat'], [','], ['__ESCAPED_URL_CLEAN_CSS1__'], ['top'], ['left'], ['no-repeat']]
+ 'topic': function () {
+ return _optimize('p{background:top left;background-repeat:no-repeat,no-repeat;background-image:url(image.png),url(image.jpg)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 77, undefined]]],
+ ['property-value', 'top', [[1, 13, undefined]]],
+ ['property-value', 'left', [[1, 17, undefined]]],
+ ['property-value', 'no-repeat', [[1, 40, undefined]]],
+ ['property-value', ','],
+ ['property-value', 'url(image.jpg)', [[1, 92, undefined]]],
+ ['property-value', 'top', [[1, 13, undefined]]],
+ ['property-value', 'left', [[1, 17, undefined]]],
+ ['property-value', 'no-repeat', [[1, 50, undefined]]]
+ ]
]);
}
},
'not too long into multiplex - over a property': {
- 'topic': 'p{background:top left;background-repeat:no-repeat,no-repeat;background-image:__ESCAPED_URL_CLEAN_CSS0__}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['top'], ['left']],
- [['background-repeat'], ['no-repeat'], [','], ['no-repeat']]
+ 'topic': function () {
+ return _optimize('p{background:top left;background-repeat:no-repeat,no-repeat;background-image:url(image.png)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 77, undefined]]],
+ ['property-value', 'top', [[1, 13, undefined]]],
+ ['property-value', 'left', [[1, 17, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-repeat', [[1, 22, undefined]]],
+ ['property-value', 'no-repeat', [[1, 40, undefined]]],
+ ['property-value', ',', [[1, 49, undefined]]],
+ ['property-value', 'no-repeat', [[1, 50, undefined]]]
+ ]
]);
}
},
'too long into multiplex #1': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-repeat:no-repeat,no-repeat}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
- [['background-repeat'], ['no-repeat'], [','], ['no-repeat']]
+ 'topic': function () {
+ return _optimize('p{background:url(/long/image/path.png);background-repeat:no-repeat,no-repeat}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(/long/image/path.png)', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-repeat', [[1, 39, undefined]]],
+ ['property-value', 'no-repeat', [[1, 57, undefined]]],
+ ['property-value', ',', [[1, 66, undefined]]],
+ ['property-value', 'no-repeat', [[1, 67, undefined]]]
+ ]
]);
}
},
'too long into multiplex #2': {
- 'topic': 'p{background:content-box padding-box;background-repeat:no-repeat,no-repeat}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['content-box'], ['padding-box']],
- [['background-repeat'], ['no-repeat'], [','], ['no-repeat']]
- ]);
- }
- },
- 'too long into multiplex #3': {
- 'topic': 'p{background:top left / 20px 20px;background-repeat:no-repeat,no-repeat}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['top'], ['left'], ['/'], ['20px'], ['20px']],
- [['background-repeat'], ['no-repeat'], [','], ['no-repeat']]
+ 'topic': function () {
+ return _optimize('p{background:content-box padding-box;background-repeat:no-repeat,no-repeat}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'content-box', [[1, 13, undefined]]],
+ ['property-value', 'padding-box', [[1, 25, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-repeat', [[1, 37, undefined]]],
+ ['property-value', 'no-repeat', [[1, 55, undefined]]],
+ ['property-value', ',', [[1, 64, undefined]]],
+ ['property-value', 'no-repeat', [[1, 65, undefined]]]
+ ]
+ ]);
+ }
+ },
+ 'too long into multiplex #3 - equal size': {
+ 'topic': function () {
+ return _optimize('p{background:top left / 20px 20px;background-repeat:no-repeat,no-repeat}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'top', [[1, 13, undefined]]],
+ ['property-value', 'left', [[1, 17, undefined]]],
+ ['property-value', '/'],
+ ['property-value', '20px', [[1, 24, undefined]]],
+ ['property-value', '20px', [[1, 29, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-repeat', [[1, 34, undefined]]],
+ ['property-value', 'no-repeat', [[1, 52, undefined]]],
+ ['property-value', ',', [[1, 61, undefined]]],
+ ['property-value', 'no-repeat', [[1, 62, undefined]]]
+ ]
]);
}
},
'background color into background': {
- 'topic': 'p{background:red;background-repeat:__ESCAPED_URL_CLEAN_CSS0__,__ESCAPED_URL_CLEAN_CSS1__}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], [','], ['__ESCAPED_URL_CLEAN_CSS1__'], ['red']],
+ 'topic': function () {
+ return _optimize('p{background:red;background-image:url(image.png),url(image.jpg)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 34, undefined]]],
+ ['property-value', ','],
+ ['property-value', 'url(image.jpg)', [[1, 49, undefined]]],
+ ['property-value', 'red', [[1, 13, undefined]]]
+ ]
]);
}
},
'background then background - svg hack': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background:__ESCAPED_URL_CLEAN_CSS1__,none}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
- [['background'], ['__ESCAPED_URL_CLEAN_CSS1__'], [','], ['none']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png);background:url(image.svg),none}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 28, undefined]]],
+ ['property-value', 'url(image.svg)', [[1, 39, undefined]]],
+ ['property-value', ','],
+ ['property-value', 'none', [[1, 54, undefined]]]
+ ]
]);
}
},
'background then background - inverted svg hack': {
- 'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background:none,__ESCAPED_URL_CLEAN_CSS1__}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
- [['background'], ['0 0'], [','], ['__ESCAPED_URL_CLEAN_CSS1__']]
+ 'topic': function () {
+ return _optimize('p{background:url(image.png);background:none,url(image.svg)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 13, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background', [[1, 28, undefined]]],
+ ['property-value', '0 0'],
+ ['property-value', ','],
+ ['property-value', 'url(image.svg)', [[1, 44, undefined]]]
+ ]
]);
}
},
'background-image then background-image - svg hack': {
- 'topic': 'p{background-image:__ESCAPED_URL_CLEAN_CSS0__;background-image: __ESCAPED_URL_CLEAN_CSS1__,none}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background-image'], ['__ESCAPED_URL_CLEAN_CSS0__']],
- [['background-image'], ['__ESCAPED_URL_CLEAN_CSS1__'], [','], ['none']]
+ 'topic': function () {
+ return _optimize('p{background-image:url(image.png);background-image:url(image.svg),none}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 2, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 34, undefined]]],
+ ['property-value', 'url(image.svg)', [[1, 51, undefined]]],
+ ['property-value', ',', [[1, 65, undefined]]],
+ ['property-value', 'none', [[1, 66, undefined]]]
+ ]
]);
}
}
})
.addBatch({
'padding !important then not !important': {
- 'topic': 'a{padding:0!important;padding-left:3px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['padding'], ['0!important']]
+ 'topic': function () {
+ return _optimize('a{padding:0!important;padding-left:3px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'padding', [[1, 2, undefined]]],
+ ['property-value', '0!important', [[1, 10, undefined]]]
+ ]
]);
}
}
})
.addBatch({
'overriding !important by a star hack': {
- 'topic': 'a{color:red!important;display:block;*color:#fff}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['color'], ['red!important']],
- [['display'], ['block']],
- [['*color'], ['#fff']]
+ 'topic': function () {
+ return _optimize('a{color:red!important;display:block;*color:#fff}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 2, undefined]]],
+ ['property-value', 'red!important', [[1, 8, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 22, undefined]]],
+ ['property-value', 'block', [[1, 30, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', '*color', [[1, 36, undefined]]],
+ ['property-value', '#fff', [[1, 43, undefined]]]
+ ]
]);
}
},
'overriding !important by an underscore hack': {
- 'topic': 'a{color:red!important;display:block;_color:#fff}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['color'], ['red!important']],
- [['display'], ['block']],
- [['_color'], ['#fff']]
+ 'topic': function () {
+ return _optimize('a{color:red!important;display:block;_color:#fff}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 2, undefined]]],
+ ['property-value', 'red!important', [[1, 8, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 22, undefined]]],
+ ['property-value', 'block', [[1, 30, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', '_color', [[1, 36, undefined]]],
+ ['property-value', '#fff', [[1, 43, undefined]]]
+ ]
]);
}
},
'overriding !important by an backslash hack': {
- 'topic': 'a{color:red!important;display:block;color:#fff\\0}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['color'], ['red!important']],
- [['display'], ['block']]
+ 'topic': function () {
+ return _optimize('a{color:red!important;display:block;color:#fff\\0}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 2, undefined]]],
+ ['property-value', 'red!important', [[1, 8, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'display', [[1, 22, undefined]]],
+ ['property-value', 'block', [[1, 30, undefined]]]
+ ]
]);
}
}
.addBatch({
'shorthand': {
'topic': function () {
- var wrapped = wrapForOptimizing([[['margin'], ['0px'], ['1px'], ['2px'], ['3px']]]);
+ var wrapped = wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px']
+ ]
+ ]);
populateComponents(wrapped);
return wrapped;
},
'gets a margin-top': function (wrapped) {
assert.deepEqual(wrapped[0].components[0].name, 'margin-top');
- assert.deepEqual(wrapped[0].components[0].value, [['0px']]);
+ assert.deepEqual(wrapped[0].components[0].value, [['property-value', '0px']]);
},
'gets a margin-right': function (wrapped) {
assert.deepEqual(wrapped[0].components[1].name, 'margin-right');
- assert.deepEqual(wrapped[0].components[1].value, [['1px']]);
+ assert.deepEqual(wrapped[0].components[1].value, [['property-value', '1px']]);
},
'gets a margin-bottom': function (wrapped) {
assert.deepEqual(wrapped[0].components[2].name, 'margin-bottom');
- assert.deepEqual(wrapped[0].components[2].value, [['2px']]);
+ assert.deepEqual(wrapped[0].components[2].value, [['property-value', '2px']]);
},
'gets a margin-left': function (wrapped) {
assert.deepEqual(wrapped[0].components[3].name, 'margin-left');
- assert.deepEqual(wrapped[0].components[3].value, [['3px']]);
+ assert.deepEqual(wrapped[0].components[3].value, [['property-value', '3px']]);
}
},
'longhand': {
'topic': function () {
- var wrapped = wrapForOptimizing([[['margin-top'], ['0px']]]);
+ var wrapped = wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin-top'],
+ ['property-value', '0px']
+ ]
+ ]);
populateComponents(wrapped);
return wrapped;
},
'no value': {
'topic': function () {
- var wrapped = wrapForOptimizing([[['margin']]]);
+ var wrapped = wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin']
+ ]
+ ]);
populateComponents(wrapped);
return wrapped;
'it removes unused only': {
'topic': function () {
var properties = [
- [['background'], ['none']],
- [['color'], ['red']]
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'none']
+ ],
+ [
+ 'property',
+ ['property-name', 'color'],
+ ['property-value', 'red']
+ ]
];
var _properties = wrapForOptimizing(properties);
_properties[0].unused = true;
},
'it has one property left': function (properties) {
assert.lengthOf(properties, 1);
- assert.equal(properties[0][0], 'color');
+ assert.equal(properties[0][1][1], 'color');
}
},
'it respects comments': {
'topic': function () {
var properties = [
- [['background'], ['none']],
- '__ESCAPED_COMMENT_CLEAN_CSS0__',
- [['color'], ['red']]
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'none']
+ ],
+ [
+ 'comment',
+ ['/* comment */']
+ ],
+ [
+ 'property',
+ ['property-name', 'color'],
+ ['property-value', 'red']
+ ]
];
var _properties = wrapForOptimizing(properties);
_properties[1].unused = true;
},
'it has one property left': function (properties) {
assert.lengthOf(properties, 2);
- assert.equal(properties[0][0], 'background');
- assert.equal(properties[1], '__ESCAPED_COMMENT_CLEAN_CSS0__');
+ assert.equal(properties[0][1][1], 'background');
+ assert.equal(properties[1][1][0], '/* comment */');
}
}
})
var restoreFromOptimizing = require('../../lib/properties/restore-from-optimizing');
-var Compatibility = require('../../lib/utils/compatibility');
+var compatibility = require('../../lib/utils/compatibility');
var Validator = require('../../lib/properties/validator');
-var validator = new Validator(new Compatibility().toOptions());
+var validator = new Validator(compatibility());
vows.describe(restoreFromOptimizing)
.addBatch({
'without descriptor': {
'topic': function () {
- var properties = [[['margin-top'], ['0']]];
- var _properties = wrapForOptimizing(properties);
- restoreFromOptimizing(_properties);
+ var properties = [
+ [
+ 'property',
+ ['property-name', 'margin-top'],
+ ['property-value', '0']
+ ]
+ ];
+ var wrapped = wrapForOptimizing(properties);
+ restoreFromOptimizing(wrapped);
return properties;
},
'is same as source': function (properties) {
- assert.deepEqual(properties, [[['margin-top'], ['0']]]);
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'margin-top'],
+ ['property-value', '0']
+ ]
+ ]);
}
},
'with changed value but without descriptor': {
'topic': function () {
- var properties = [[['margin-top'], ['0']]];
- var _properties = wrapForOptimizing(properties);
- _properties[0].value = [['1px']];
- _properties[0].dirty = true;
- restoreFromOptimizing(_properties);
+ var properties = [
+ [
+ 'property',
+ ['property-name', 'margin-top'],
+ ['property-value', '0']
+ ]
+ ];
+ var wrapped = wrapForOptimizing(properties);
+ wrapped[0].value = [['property-value', '1px']];
+ wrapped[0].dirty = true;
+ restoreFromOptimizing(wrapped);
return properties;
},
'has right output': function (properties) {
- assert.deepEqual(properties, [[['margin-top'], ['1px']]]);
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'margin-top'],
+ ['property-value', '1px']
+ ]
+ ]);
}
},
- 'longhands': {
+ 'with comment': {
'topic': function () {
- var properties = ['/*comment */', [['margin-top'], ['0']]];
- var _properties = wrapForOptimizing(properties);
- populateComponents(_properties, validator);
- restoreFromOptimizing(_properties);
+ var properties = [
+ [
+ 'comment',
+ '/* comment */'
+ ],
+ [
+ 'property',
+ ['property-name', 'margin-top'],
+ ['property-value', '0']
+ ]
+ ];
+ var wrapped = wrapForOptimizing(properties);
+ populateComponents(wrapped, validator);
+ restoreFromOptimizing(wrapped);
return properties;
},
'is same as source': function (properties) {
- assert.deepEqual(properties, ['/*comment */', [['margin-top'], ['0']]]);
+ assert.deepEqual(properties, [
+ [
+ 'comment',
+ '/* comment */'
+ ],
+ [
+ 'property',
+ ['property-name', 'margin-top'],
+ ['property-value', '0']
+ ]
+ ]);
}
},
'shorthands': {
'topic': function () {
- var properties = ['/*comment */', [['background'], ['url(image.png)']]];
- var _properties = wrapForOptimizing(properties);
- populateComponents(_properties, validator);
+ var properties = [
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)']
+ ]
+ ];
+ var wrapped = wrapForOptimizing(properties);
+ populateComponents(wrapped, validator);
- properties[1].pop();
- _properties[0].dirty = true;
+ wrapped[0].dirty = true;
- restoreFromOptimizing(_properties);
+ restoreFromOptimizing(wrapped);
return properties;
},
'is same as source': function (properties) {
- assert.deepEqual(properties, ['/*comment */', [['background'], ['url(image.png)']]]);
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)']
+ ]
+ ]);
}
},
'shorthands in simple mode': {
'topic': function () {
- var properties = [[['margin'], ['1px'], ['2px']]];
- var _properties = wrapForOptimizing(properties);
+ var properties = [
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '1px'],
+ ['property-value', '2px']
+ ]
+ ];
+ var wrapped = wrapForOptimizing(properties);
- _properties[0].dirty = true;
+ wrapped[0].dirty = true;
- restoreFromOptimizing(_properties, true);
+ restoreFromOptimizing(wrapped, true);
return properties;
},
'is same as source': function (properties) {
- assert.deepEqual(properties, [[['margin'], ['1px'], ['2px']]]);
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '1px'],
+ ['property-value', '2px']
+ ]
+ ]);
}
},
'values': {
'topic': function () {
- var properties = [[['background'], ['url(image.png)']]];
- var _properties = wrapForOptimizing(properties);
- populateComponents(_properties, validator);
+ var properties = [
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)']
+ ]
+ ];
+ var wrapped = wrapForOptimizing(properties);
+ populateComponents(wrapped, validator);
- _properties[0].value = [];
- _properties[0].dirty = true;
+ wrapped[0].value = [];
+ wrapped[0].dirty = true;
- restoreFromOptimizing(_properties);
- return _properties;
+ restoreFromOptimizing(wrapped);
+ return properties;
},
- 'updates value': function (_properties) {
- assert.deepEqual(_properties[0].value, [['url(image.png)']]);
+ 'updates value': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)']
+ ]
+ ]);
}
},
'in cloned without reference to `all`': {
'topic': function () {
- var properties = [[['background'], ['url(image.png)']]];
- var _properties = wrapForOptimizing(properties);
- populateComponents(_properties, validator);
+ var properties = [
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)']
+ ]
+ ];
+ var wrapped = wrapForOptimizing(properties);
+ populateComponents(wrapped, validator);
- var cloned = shallowClone(_properties[0]);
- cloned.components = _properties[0].components;
+ var cloned = shallowClone(wrapped[0]);
+ cloned.components = wrapped[0].components;
cloned.dirty = true;
restoreFromOptimizing([cloned]);
return cloned;
},
'does not fail': function (cloned) {
- assert.deepEqual(cloned.value, [['url(image.png)']]);
+ assert.deepEqual(cloned.value, [['property-value', 'url(image.png)']]);
}
}
})
.addBatch({
'important': {
'topic': function () {
- var properties = [[['color'], ['red!important']]];
- var _properties = wrapForOptimizing(properties);
+ var properties = [
+ [
+ 'property',
+ ['property-name', 'color'],
+ ['property-value', 'red!important']
+ ]
+ ];
+ var wrapped = wrapForOptimizing(properties);
- restoreFromOptimizing(_properties, true);
+ restoreFromOptimizing(wrapped, true);
return properties;
},
'restores important': function (properties) {
- assert.deepEqual(properties, [[['color'], ['red!important']]]);
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color'],
+ ['property-value', 'red!important']
+ ]
+ ]);
}
},
'underscore hack': {
'topic': function () {
- var properties = [[['_color'], ['red']]];
- var _properties = wrapForOptimizing(properties);
+ var properties = [
+ [
+ 'property',
+ ['property-name', '_color'],
+ ['property-value', 'red']
+ ]
+ ];
+ var wrapped = wrapForOptimizing(properties);
- restoreFromOptimizing(_properties, true);
+ restoreFromOptimizing(wrapped, true);
return properties;
},
'restores hack': function (properties) {
- assert.deepEqual(properties, [[['_color'], ['red']]]);
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', '_color'],
+ ['property-value', 'red']
+ ]
+ ]);
}
},
'star hack': {
'topic': function () {
- var properties = [[['*color'], ['red']]];
- var _properties = wrapForOptimizing(properties);
+ var properties = [
+ [
+ 'property',
+ ['property-name', '*color'],
+ ['property-value', 'red']
+ ]
+ ];
+ var wrapped = wrapForOptimizing(properties);
- restoreFromOptimizing(_properties, true);
+ restoreFromOptimizing(wrapped, true);
return properties;
},
'restores hack': function (properties) {
- assert.deepEqual(properties, [[['*color'], ['red']]]);
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', '*color'],
+ ['property-value', 'red']
+ ]
+ ]);
}
},
'suffix hack': {
'topic': function () {
- var properties = [[['color'], ['red\\9']]];
- var _properties = wrapForOptimizing(properties);
+ var properties = [
+ [
+ 'property',
+ ['property-name', 'color'],
+ ['property-value', 'red\\9']
+ ]
+ ];
+ var wrapped = wrapForOptimizing(properties);
- restoreFromOptimizing(_properties, true);
+ restoreFromOptimizing(wrapped, true);
return properties;
},
'restores hack': function (properties) {
- assert.deepEqual(properties, [[['color'], ['red\\9']]]);
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color'],
+ ['property-value', 'red\\9']
+ ]
+ ]);
}
}
})
var wrapForOptimizing = require('../../lib/properties/wrap-for-optimizing').single;
var compactable = require('../../lib/properties/compactable');
-var Compatibility = require('../../lib/utils/compatibility');
+var compatibility = require('../../lib/utils/compatibility');
var Validator = require('../../lib/properties/validator');
var restore = require('../../lib/properties/restore');
function _breakUp(property) {
- var validator = new Validator(new Compatibility().toOptions());
- var descriptor = compactable[property[0][0]];
+ var validator = new Validator(compatibility());
+ var descriptor = compactable[property[1][1]];
var _property = wrapForOptimizing(property);
_property.components = descriptor.breakUp(_property, compactable, validator);
_property.multiplex = _property.components[0].multiplex;
'background': {
'background with some values': {
'topic': function () {
- return _restore(_breakUp([['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat'], ['padding-box']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', 'no-repeat'],
+ ['property-value', 'padding-box']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat'], ['padding-box']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'url(image.png)'],
+ ['property-value', 'no-repeat'],
+ ['property-value', 'padding-box']
+ ]);
}
},
'background with some default values': {
'topic': function () {
- return _restore(_breakUp([['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['repeat'], ['padding-box'], ['border-box']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', 'repeat'],
+ ['property-value', 'padding-box'],
+ ['property-value', 'border-box']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['__ESCAPED_URL_CLEAN_CSS0__']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'url(image.png)']
+ ]);
}
},
'background with all default values': {
'topic': function () {
- return _restore(_breakUp([['background'], ['transparent'], ['none'], ['repeat'], ['scroll'], ['0'], ['0'], ['padding-box'], ['border-box']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'transparent'],
+ ['property-value', 'none'],
+ ['property-value', 'repeat'],
+ ['property-value', 'scroll'],
+ ['property-value', '0'],
+ ['property-value', '0'],
+ ['property-value', 'padding-box'],
+ ['property-value', 'border-box']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0 0']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0 0']
+ ]);
}
},
'background with some double values': {
'topic': function () {
- return _restore(_breakUp([['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['repeat'], ['no-repeat'], ['2px'], ['3px'], ['/'], ['auto'], ['padding-box']]));
- },
- 'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['__ESCAPED_URL_CLEAN_CSS0__'], ['2px'], ['3px'], ['repeat'], ['no-repeat'], ['padding-box']]);
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', 'repeat'],
+ ['property-value', 'no-repeat'],
+ ['property-value', '2px'],
+ ['property-value', '3px'],
+ ['property-value', '/'],
+ ['property-value', 'auto'],
+ ['property-value', 'padding-box']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'url(image.png)'],
+ ['property-value', '2px'],
+ ['property-value', '3px'],
+ ['property-value', 'repeat'],
+ ['property-value', 'no-repeat'],
+ ['property-value', 'padding-box']
+ ]);
}
},
'background with default background origin and background clip': {
'topic': function () {
- return _restore(_breakUp([['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['padding-box'], ['border-box']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', 'padding-box'],
+ ['property-value', 'border-box']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['__ESCAPED_URL_CLEAN_CSS0__']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'url(image.png)']
+ ]);
}
},
'background with same background origin and background clip': {
'topic': function () {
- return _restore(_breakUp([['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['padding-box'], ['padding-box']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', 'padding-box'],
+ ['property-value', 'padding-box']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['__ESCAPED_URL_CLEAN_CSS0__'], ['padding-box']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'url(image.png)'],
+ ['property-value', 'padding-box']
+ ]);
}
},
'background with default background position and background size': {
'topic': function () {
- return _restore(_breakUp([['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['0'], ['0'], ['/'], ['50%'], ['25%']]));
- },
- 'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['__ESCAPED_URL_CLEAN_CSS0__'], ['0'], ['0'], ['/'], ['50%'], ['25%']]);
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', '0'],
+ ['property-value', '0'],
+ ['property-value', '/'],
+ ['property-value', '50%'],
+ ['property-value', '25%']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'url(image.png)'],
+ ['property-value', '0'],
+ ['property-value', '0'],
+ ['property-value', '/'],
+ ['property-value', '50%'],
+ ['property-value', '25%']
+ ]);
}
},
'background with default background position and single background size': {
'topic': function () {
- return _restore(_breakUp([['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['0'], ['0'], ['/'], ['50%']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', '0'],
+ ['property-value', '0'],
+ ['property-value', '/'],
+ ['property-value', '50%']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['__ESCAPED_URL_CLEAN_CSS0__'], ['0'], ['0'], ['/'], ['50%']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'url(image.png)'],
+ ['property-value', '0'],
+ ['property-value', '0'],
+ ['property-value', '/'],
+ ['property-value', '50%']
+ ]);
}
},
'background with default background position and background size differing by 2nd value': {
'topic': function () {
- return _restore(_breakUp([['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['0'], ['50px'], ['/'], ['0'], ['30px']]));
- },
- 'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['__ESCAPED_URL_CLEAN_CSS0__'], ['0'], ['50px'], ['/'], ['0'], ['30px']]);
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', '0'],
+ ['property-value', '50px'],
+ ['property-value', '/'],
+ ['property-value', '0'],
+ ['property-value', '30px']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'url(image.png)'],
+ ['property-value', '0'],
+ ['property-value', '50px'],
+ ['property-value', '/'],
+ ['property-value', '0'],
+ ['property-value', '30px']
+ ]);
}
},
'background 0 to background 0': {
'topic': function () {
- return _restore(_breakUp([['background'], ['0']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', '0']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0']
+ ]);
}
},
'background color in multiplex': {
'topic': function () {
- return _restore(_breakUp([['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['blue'], [','], ['__ESCAPED_URL_CLEAN_CSS1__'], ['red']]));
- },
- 'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['__ESCAPED_URL_CLEAN_CSS0__'], [','], ['__ESCAPED_URL_CLEAN_CSS1__'], ['red']]);
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', 'blue'],
+ ['property-value', ','],
+ ['property-value', 'url(image.jpg)'],
+ ['property-value', 'red']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'url(image.png)'],
+ ['property-value', ','],
+ ['property-value', 'url(image.jpg)'],
+ ['property-value', 'red']
+ ]);
}
}
},
'border radius': {
'4 values': {
'topic': function () {
- return _restore(_breakUp([['border-radius'], ['0px'], ['1px'], ['2px'], ['3px']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0px'], ['1px'], ['2px'], ['3px']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px']
+ ]);
}
},
'3 values': {
'topic': function () {
- return _restore(_breakUp([['border-radius'], ['0px'], ['1px'], ['2px'], ['1px']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '1px']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0px'], ['1px'], ['2px']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px']
+ ]);
}
},
'2 values': {
'topic': function () {
- return _restore(_breakUp([['border-radius'], ['0px'], ['1px'], ['0px'], ['1px']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '0px'],
+ ['property-value', '1px']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0px'], ['1px']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0px'],
+ ['property-value', '1px']
+ ]);
}
},
'1 value': {
'topic': function () {
- return _restore(_breakUp([['border-radius'], ['0px'], ['0px'], ['0px'], ['0px']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '0px'],
+ ['property-value', '0px'],
+ ['property-value', '0px'],
+ ['property-value', '0px']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0px']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0px']
+ ]);
}
},
'horizontal + vertical - different values': {
'topic': function () {
- return _restore(_breakUp([['border-radius'], ['0px'], ['1px'], ['2px'], ['3px'], ['/'], ['2px'], ['1px'], ['2px'], ['1px']]));
- },
- 'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0px'], ['1px'], ['2px'], ['3px'], ['/'], ['2px'], ['1px']]);
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px'],
+ ['property-value', '/'],
+ ['property-value', '2px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '1px']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px'],
+ ['property-value', '/'],
+ ['property-value', '2px'],
+ ['property-value', '1px']
+ ]);
}
},
'horizontal + vertical - same values': {
'topic': function () {
- return _restore(_breakUp([['border-radius'], ['0px'], ['1px'], ['2px'], ['3px'], ['/'], ['0px'], ['1px'], ['2px'], ['3px']]));
- },
- 'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0px'], ['1px'], ['2px'], ['3px']]);
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px'],
+ ['property-value', '/'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px']
+ ]);
}
},
'horizontal + vertical - asymetrical': {
'topic': function () {
- return _restore(_breakUp([['border-radius'], ['0px'], ['1px'], ['2px'], ['3px'], ['/'], ['0px'], ['1px']]));
- },
- 'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0px'], ['1px'], ['2px'], ['3px'], ['/'], ['0px'], ['1px']]);
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px'],
+ ['property-value', '/'],
+ ['property-value', '0px'],
+ ['property-value', '1px']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px'],
+ ['property-value', '/'],
+ ['property-value', '0px'],
+ ['property-value', '1px']
+ ]);
}
},
'inherit': {
'topic': function () {
- return _restore(_breakUp([['border-radius'], ['inherit']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', 'inherit']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['inherit']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'inherit']
+ ]);
}
}
},
'four values': {
'4 different': {
'topic': function () {
- return _restore(_breakUp([['padding'], ['0px'], ['1px'], ['2px'], ['3px']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'padding'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0px'], ['1px'], ['2px'], ['3px']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '3px']
+ ]);
}
},
'3 different': {
'topic': function () {
- return _restore(_breakUp([['padding'], ['0px'], ['1px'], ['2px'], ['1px']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'padding'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px'],
+ ['property-value', '1px']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0px'], ['1px'], ['2px']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '2px']
+ ]);
}
},
'2 different': {
'topic': function () {
- return _restore(_breakUp([['padding'], ['0px'], ['1px'], ['0px'], ['1px']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'padding'],
+ ['property-value', '0px'],
+ ['property-value', '1px'],
+ ['property-value', '0px'],
+ ['property-value', '1px']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0px'], ['1px']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0px'],
+ ['property-value', '1px']
+ ]);
}
},
'all same': {
'topic': function () {
- return _restore(_breakUp([['padding'], ['0px'], ['0px'], ['0px'], ['0px']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'padding'],
+ ['property-value', '0px'],
+ ['property-value', '0px'],
+ ['property-value', '0px'],
+ ['property-value', '0px']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0px']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0px']
+ ]);
}
},
'inherit': {
'topic': function () {
- return _restore(_breakUp([['padding'], ['inherit']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'padding'],
+ ['property-value', 'inherit']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['inherit']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'inherit']
+ ]);
}
}
},
'repeated values': {
'background with some values': {
'topic': function () {
- return _restore(_breakUp([['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat'], ['padding-box'], [','], ['repeat'], ['red']]));
- },
- 'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat'], ['padding-box'], [','], ['red']]);
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)'],
+ ['property-value', 'no-repeat'],
+ ['property-value', 'padding-box'],
+ ['property-value', ','],
+ ['property-value', 'repeat'],
+ ['property-value', 'red']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'url(image.png)'],
+ ['property-value', 'no-repeat'],
+ ['property-value', 'padding-box'],
+ ['property-value', ','],
+ ['property-value', 'red']
+ ]);
}
},
'background with background origin and size': {
'topic': function () {
- return _restore(_breakUp([['background'], ['no-repeat'], ['padding-box'], [','], ['repeat'], ['10px'], ['10px'], ['/'], ['auto'], ['red'], [','], ['top'], ['left'], ['/'], ['30%']]));
- },
- 'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['no-repeat'], ['padding-box'], [','], ['10px'], ['10px'], [','], ['top'], ['left'], ['/'], ['30%']]);
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'no-repeat'],
+ ['property-value', 'padding-box'],
+ ['property-value', ','],
+ ['property-value', 'repeat'],
+ ['property-value', '10px'],
+ ['property-value', '10px'],
+ ['property-value', '/'],
+ ['property-value', 'auto'],
+ ['property-value', 'red'],
+ ['property-value', ','],
+ ['property-value', 'top'],
+ ['property-value', 'left'],
+ ['property-value', '/'],
+ ['property-value', '30%']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'no-repeat'],
+ ['property-value', 'padding-box'],
+ ['property-value', ','],
+ ['property-value', '10px'],
+ ['property-value', '10px'],
+ ['property-value', ','],
+ ['property-value', 'top'],
+ ['property-value', 'left'],
+ ['property-value', '/'],
+ ['property-value', '30%']
+ ]);
}
}
},
'without defaults': {
'border with some values': {
'topic': function () {
- return _restore(_breakUp([['border'], ['solid']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'border'],
+ ['property-value', 'solid']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['solid']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'solid']
+ ]);
}
},
'border with all values': {
'topic': function () {
- return _restore(_breakUp([['border'], ['1px'], ['solid'], ['red']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'border'],
+ ['property-value', '1px'],
+ ['property-value', 'solid'],
+ ['property-value', 'red']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['1px'], ['solid'], ['red']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', '1px'],
+ ['property-value', 'solid'],
+ ['property-value', 'red']
+ ]);
}
},
'border with all defaults': {
'topic': function () {
- return _restore(_breakUp([['border'], ['medium'], ['none'], ['none']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'border'],
+ ['property-value', 'medium'],
+ ['property-value', 'none'],
+ ['property-value', 'none']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['none']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'none']
+ ]);
}
},
'border with inherit': {
'topic': function () {
- return _restore(_breakUp([['border'], ['inherit']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'border'],
+ ['property-value', 'inherit']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['inherit']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'inherit']
+ ]);
}
},
'list with some values': {
'topic': function () {
- return _restore(_breakUp([['list-style'], ['circle']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'list-style'],
+ ['property-value', 'circle']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['circle']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'circle']
+ ]);
}
},
'list with all values': {
'topic': function () {
- return _restore(_breakUp([['list-style'], ['circle'], ['inside'], ['__ESCAPED_URL_CLEAN_CSS1__']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'list-style'],
+ ['property-value', 'circle'],
+ ['property-value', 'inside'],
+ ['property-value', 'url(image.png)']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['circle'], ['inside'], ['__ESCAPED_URL_CLEAN_CSS1__']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'circle'],
+ ['property-value', 'inside'],
+ ['property-value', 'url(image.png)']
+ ]);
}
},
'list with some defaults': {
'topic': function () {
- return _restore(_breakUp([['list-style'], ['circle'], ['outside'], ['__ESCAPED_URL_CLEAN_CSS0__']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'list-style'],
+ ['property-value', 'circle'],
+ ['property-value', 'outside'],
+ ['property-value', 'url(image.png)']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['circle'], ['__ESCAPED_URL_CLEAN_CSS0__']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'circle'],
+ ['property-value', 'url(image.png)']
+ ]);
}
},
'list with inherit': {
'topic': function () {
- return _restore(_breakUp([['list-style'], ['inherit']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'list-style'],
+ ['property-value', 'inherit']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['inherit']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'inherit']
+ ]);
}
},
'outline with some values': {
'topic': function () {
- return _restore(_breakUp([['outline'], ['dotted']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'outline'],
+ ['property-value', 'dotted']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['dotted']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'dotted']
+ ]);
}
},
'outline with all values': {
'topic': function () {
- return _restore(_breakUp([['outline'], ['#fff'], ['dotted'], ['1px']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'outline'],
+ ['property-value', '#fff'],
+ ['property-value', 'dotted'],
+ ['property-value', '1px']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['#fff'], ['dotted'], ['1px']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', '#fff'],
+ ['property-value', 'dotted'],
+ ['property-value', '1px']
+ ]);
}
},
'outline with all defaults': {
'topic': function () {
- return _restore(_breakUp([['outline'], ['invert'], ['none'], ['medium']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'outline'],
+ ['property-value', 'invert'],
+ ['property-value', 'none'],
+ ['property-value', 'medium']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['0']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', '0']
+ ]);
}
},
'outline with inherit': {
'topic': function () {
- return _restore(_breakUp([['outline'], ['inherit']]));
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'outline'],
+ ['property-value', 'inherit']
+ ])
+ );
},
'gives right value back': function (restoredValue) {
- assert.deepEqual(restoredValue, [['inherit']]);
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'inherit']
+ ]);
}
}
}
+++ /dev/null
-var vows = require('vows');
-var assert = require('assert');
-
-var optimize = require('../../lib/properties/optimizer');
-
-var tokenize = require('../../lib/tokenizer/tokenize');
-var SourceTracker = require('../../lib/utils/source-tracker');
-var SourceReader = require('../../lib/utils/source-reader');
-var InputSourceMapTracker = require('../../lib/utils/input-source-map-tracker');
-
-var Compatibility = require('../../lib/utils/compatibility');
-var Validator = require('../../lib/properties/validator');
-
-function _optimize(source) {
- var inputSourceMapTracker = new InputSourceMapTracker({
- options: { inliner: {} },
- errors: {},
- sourceTracker: new SourceTracker()
- });
- var tokens = tokenize(source, {
- options: { sourceMap: true },
- inputSourceMapTracker: inputSourceMapTracker,
- sourceReader: new SourceReader(),
- sourceTracker: new SourceTracker(),
- warnings: []
- });
-
- var compatibility = new Compatibility().toOptions();
- var validator = new Validator(compatibility);
- var options = {
- aggressiveMerging: true,
- compatibility: compatibility,
- sourceMap: true,
- shorthandCompacting: true
- };
- optimize(tokens[0][1], tokens[0][2], false, true, options, { validator: validator });
-
- return tokens[0][2];
-}
-
-vows.describe(optimize)
- .addBatch({
- 'with source map': {
- topic: 'a{margin-top:10px;margin-bottom:4px;margin-left:5px;margin-right:5px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [
- ['margin', [[1, 2, undefined], [1, 18, undefined], [1, 36, undefined], [1, 52, undefined]]],
- [ '10px', [[1, 13, undefined]]],
- [ '5px', [[1, 65, undefined]]],
- [ '4px', [[1, 32, undefined]]]
- ]
- ]);
- }
- }
- })
- .export(module);
var optimize = require('../../lib/properties/optimizer');
var tokenize = require('../../lib/tokenizer/tokenize');
-var SourceTracker = require('../../lib/utils/source-tracker');
-var Compatibility = require('../../lib/utils/compatibility');
+var compatibility = require('../../lib/utils/compatibility');
var Validator = require('../../lib/properties/validator');
function _optimize(source) {
var tokens = tokenize(source, {
options: {},
- sourceTracker: new SourceTracker(),
warnings: []
});
- var compatibility = new Compatibility(compatibility).toOptions();
- var validator = new Validator(compatibility);
+ var compat = compatibility(compat);
+ var validator = new Validator(compat);
var options = {
aggressiveMerging: true,
- compatibility: compatibility,
+ compatibility: compat,
shorthandCompacting: true
};
- optimize(tokens[0][1], tokens[0][2], false, true, options, { validator: validator });
+ optimize(tokens[0][1], tokens[0][2], false, true, { options: options, validator: validator });
return tokens[0][2];
}
vows.describe(optimize)
.addBatch({
'shorthand background #1': {
- 'topic': 'p{background-color:#111;background-image:__ESCAPED_URL_CLEAN_CSS0__;background-repeat:repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-origin:padding-box;background-clip:border-box}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['#111']]
+ 'topic': function () {
+ return _optimize('p{background-color:#111;background-image:url(image.png);background-repeat:repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-origin:padding-box;background-clip:border-box}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)', [[1, 41, undefined]]],
+ ['property-value', '#111', [[1, 19, undefined]]]
+ ]
]);
}
},
'shorthand background #2': {
- 'topic': 'p{background-color:#111;background-image:__ESCAPED_URL_CLEAN_CSS0__;background-repeat:no-repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-origin:padding-box;background-clip:border-box}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat'], ['#111']]
+ 'topic': function () {
+ return _optimize('p{background-color:#111;background-image:url(image.png);background-repeat:no-repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-origin:padding-box;background-clip:border-box}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)', [[1, 41, undefined]]],
+ ['property-value', 'no-repeat', [[1, 74, undefined]]],
+ ['property-value', '#111', [[1, 19, undefined]]]
+ ]
]);
}
},
'shorthand important background': {
- 'topic': 'p{background-color:#111!important;background-image:__ESCAPED_URL_CLEAN_CSS0__!important;background-repeat:repeat!important;background-position:0 0!important;background-attachment:scroll!important;background-size:auto!important;background-origin:padding-box!important;background-clip:border-box!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['#111!important']]
+ 'topic': function () {
+ return _optimize('p{background-color:#111!important;background-image:url(image.png)!important;background-repeat:repeat!important;background-position:0 0!important;background-attachment:scroll!important;background-size:auto!important;background-origin:padding-box!important;background-clip:border-box!important}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background'],
+ ['property-value', 'url(image.png)', [[1, 51, undefined]]],
+ ['property-value', '#111!important', [[1, 19, undefined]]]
+ ]
]);
}
},
'shorthand border-width': {
- 'topic': 'p{border-top-width:7px;border-bottom-width:7px;border-left-width:4px;border-right-width:4px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border-width'], ['7px'], ['4px']]
+ 'topic': function () {
+ return _optimize('p{border-top-width:7px;border-bottom-width:7px;border-left-width:4px;border-right-width:4px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-width'],
+ ['property-value', '7px', [[1, 19, undefined]]],
+ ['property-value', '4px', [[1, 88, undefined]]]
+ ]
]);
}
},
'shorthand border-color #1': {
- 'topic': 'p{border-top-color:#9fce00;border-bottom-color:#9fce00;border-left-color:#9fce00;border-right-color:#9fce00}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border-color'], ['#9fce00']]
+ 'topic': function () {
+ return _optimize('p{border-top-color:#9fce00;border-bottom-color:#9fce00;border-left-color:#9fce00;border-right-color:#9fce00}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-color'],
+ ['property-value', '#9fce00', [[1, 19, undefined]]]
+ ]
]);
}
},
'shorthand border-color #2': {
- 'topic': 'p{border-right-color:#002;border-bottom-color:#003;border-top-color:#001;border-left-color:#004}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border-color'], ['#001'], ['#002'], ['#003'], ['#004']]
+ 'topic': function () {
+ return _optimize('p{border-right-color:#002;border-bottom-color:#003;border-top-color:#001;border-left-color:#004}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-color'],
+ ['property-value', '#001', [[1, 68, undefined]]],
+ ['property-value', '#002', [[1, 21, undefined]]],
+ ['property-value', '#003', [[1, 46, undefined]]],
+ ['property-value', '#004', [[1, 91, undefined]]]
+ ]
]);
}
},
'shorthand border-radius': {
- 'topic': 'p{border-top-left-radius:7px;border-bottom-right-radius:6px;border-bottom-left-radius:5px;border-top-right-radius:3px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border-radius'], ['7px'], ['3px'], ['6px'], ['5px']]
+ 'topic': function () {
+ return _optimize('p{border-top-left-radius:7px;border-bottom-right-radius:6px;border-bottom-left-radius:5px;border-top-right-radius:3px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '7px', [[1, 25, undefined]]],
+ ['property-value', '3px', [[1, 114, undefined]]],
+ ['property-value', '6px', [[1, 56, undefined]]],
+ ['property-value', '5px', [[1, 86, undefined]]]
+ ]
]);
}
},
'shorthand multiplexed border-radius': {
- 'topic': 'p{border-radius:7px/3px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border-radius'], ['7px'], ['/'], ['3px']]
+ 'topic': function () {
+ return _optimize('p{border-radius:7px/3px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-radius', [[1, 2, undefined]]],
+ ['property-value', '7px', [[1, 16, undefined]]],
+ ['property-value', '/'],
+ ['property-value', '3px', [[1, 20, undefined]]]
+ ]
]);
}
},
'shorthand asymmetric border-radius with same values': {
- 'topic': 'p{border-top-left-radius:7px 3px;border-top-right-radius:7px 3px;border-bottom-right-radius:7px 3px;border-bottom-left-radius:7px 3px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border-radius'], ['7px'], ['/'], ['3px']]
+ 'topic': function () {
+ return _optimize('p{border-top-left-radius:7px 3px;border-top-right-radius:7px 3px;border-bottom-right-radius:7px 3px;border-bottom-left-radius:7px 3px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '7px', [[1, 25, undefined]]],
+ ['property-value', '/'],
+ ['property-value', '3px', [[1, 29, undefined]]]
+ ]
]);
}
},
'shorthand asymmetric border-radius': {
- 'topic': 'p{border-top-left-radius:7px 3px;border-top-right-radius:6px 2px;border-bottom-right-radius:5px 1px;border-bottom-left-radius:4px 0}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border-radius'], ['7px'], ['6px'], ['5px'], ['4px'], ['/'], ['3px'], ['2px'], ['1px'], ['0']]
+ 'topic': function () {
+ return _optimize('p{border-top-left-radius:7px 3px;border-top-right-radius:6px 2px;border-bottom-right-radius:5px 1px;border-bottom-left-radius:4px 0}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-radius'],
+ ['property-value', '7px', [[1, 25, undefined]]],
+ ['property-value', '6px', [[1, 57, undefined]]],
+ ['property-value', '5px', [[1, 92, undefined]]],
+ ['property-value', '4px', [[1, 126, undefined]]],
+ ['property-value', '/'],
+ ['property-value', '3px', [[1, 29, undefined]]],
+ ['property-value', '2px', [[1, 61, undefined]]],
+ ['property-value', '1px', [[1, 96, undefined]]],
+ ['property-value', '0', [[1, 130, undefined]]]
+ ]
]);
}
},
'shorthand multiple !important': {
- 'topic': 'a{border-color:#123 !important;border-top-color: #456 !important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['border-color'], ['#456'], ['#123'], ['#123!important']]
+ 'topic': function () {
+ return _optimize('a{border-color:#123 !important;border-top-color: #456 !important}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'border-color', [[1, 2, undefined]]],
+ ['property-value', '#456', [[1, 49, undefined]]],
+ ['property-value', '#123', [[1, 15, undefined]]],
+ ['property-value', '#123!important', [[1, 15, undefined]]]
+ ]
]);
}
},
'shorthand list-style #1': {
- 'topic': 'a{list-style-type:circle;list-style-position:outside;list-style-image:__ESCAPED_URL_CLEAN_CSS0__}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['list-style'], ['circle'], ['__ESCAPED_URL_CLEAN_CSS0__']]
+ 'topic': function () {
+ return _optimize('a{list-style-type:circle;list-style-position:outside;list-style-image:url(image.png)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'list-style'],
+ ['property-value', 'circle', [[1, 18, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 70, undefined]]]
+ ]
]);
}
},
'shorthand list-style #2': {
- 'topic': 'a{list-style-image:__ESCAPED_URL_CLEAN_CSS0__;list-style-type:circle;list-style-position:inside}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['list-style'], ['circle'], ['inside'], ['__ESCAPED_URL_CLEAN_CSS0__']]
+ 'topic': function () {
+ return _optimize('a{list-style-image:url(image.png);list-style-type:circle;list-style-position:inside}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'list-style'],
+ ['property-value', 'circle', [[1, 50, undefined]]],
+ ['property-value', 'inside', [[1, 77, undefined]]],
+ ['property-value', 'url(image.png)', [[1, 19, undefined]]]
+ ]
]);
}
},
'shorthand margin': {
- 'topic': 'a{margin-top:10px;margin-right:5px;margin-bottom:3px;margin-left:2px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['margin'], ['10px'], ['5px'], ['3px'], ['2px']]
+ 'topic': function () {
+ return _optimize('a{margin-top:10px;margin-right:5px;margin-bottom:3px;margin-left:2px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '10px', [[1, 13, undefined]]],
+ ['property-value', '5px', [[1, 31, undefined]]],
+ ['property-value', '3px', [[1, 49, undefined]]],
+ ['property-value', '2px', [[1, 65, undefined]]]
+ ]
]);
}
},
'shorthand padding': {
- 'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px;padding-right:2px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['padding'], ['10px'], ['2px'], ['3px'], ['5px']]
+ 'topic': function () {
+ return _optimize('a{padding-top:10px;padding-left:5px;padding-bottom:3px;padding-right:2px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'padding'],
+ ['property-value', '10px', [[1, 14, undefined]]],
+ ['property-value', '2px', [[1, 69, undefined]]],
+ ['property-value', '3px', [[1, 51, undefined]]],
+ ['property-value', '5px', [[1, 32, undefined]]]
+ ]
]);
}
},
'mixed': {
- 'topic': 'a{padding-top:10px;margin-top:3px;padding-left:5px;margin-left:3px;padding-bottom:3px;margin-bottom:3px;padding-right:2px;margin-right:3px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['padding'], ['10px'], ['2px'], ['3px'], ['5px']],
- [['margin'], ['3px']]
+ 'topic': function () {
+ return _optimize('a{padding-top:10px;margin-top:3px;padding-left:5px;margin-left:3px;padding-bottom:3px;margin-bottom:3px;padding-right:2px;margin-right:3px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'padding'],
+ ['property-value', '10px', [[1, 14, undefined]]],
+ ['property-value', '2px', [[1, 118, undefined]]],
+ ['property-value', '3px', [[1, 82, undefined]]],
+ ['property-value', '5px', [[1, 47, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '3px', [[1, 30, undefined]]]
+ ]
]);
}
},
'with other properties': {
- 'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px;color:red;padding-right:2px;width:100px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['color'], ['red']],
- [['width'], ['100px']],
- [['padding'], ['10px'], ['2px'], ['3px'], ['5px']]
+ 'topic': function () {
+ return _optimize('a{padding-top:10px;padding-left:5px;padding-bottom:3px;color:red;padding-right:2px;width:100px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'color', [[1, 55, undefined]]],
+ ['property-value', 'red', [[1, 61, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'width', [[1, 83, undefined]]],
+ ['property-value', '100px', [[1, 89, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding'],
+ ['property-value', '10px', [[1, 14, undefined]]],
+ ['property-value', '2px', [[1, 79, undefined]]],
+ ['property-value', '3px', [[1, 51, undefined]]],
+ ['property-value', '5px', [[1, 32, undefined]]]
+ ]
]);
}
},
'with hacks': {
- 'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px;_padding-right:2px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['padding-top'], ['10px']],
- [['padding-left'], ['5px']],
- [['padding-bottom'], ['3px']],
- [['_padding-right'], ['2px']]
+ 'topic': function () {
+ return _optimize('a{padding-top:10px;padding-left:5px;padding-bottom:3px;_padding-right:2px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'padding-top', [[1, 2, undefined]]],
+ ['property-value', '10px', [[1, 14, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-left', [[1, 19, undefined]]],
+ ['property-value', '5px', [[1, 32, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-bottom', [[1, 36, undefined]]],
+ ['property-value', '3px', [[1, 51, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', '_padding-right', [[1, 55, undefined]]],
+ ['property-value', '2px', [[1, 70, undefined]]]
+ ]
]);
}
},
'just inherit': {
- 'topic': 'a{background:inherit}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background'], ['inherit']]
+ 'topic': function () {
+ return _optimize('a{background:inherit}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background', [[1, 2, undefined]]],
+ ['property-value', 'inherit', [[1, 13, undefined]]]
+ ]
]);
}
}
})
.addBatch({
'not enough components': {
- 'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['padding-top'], ['10px']],
- [['padding-left'], ['5px']],
- [['padding-bottom'], ['3px']]
+ 'topic': function () {
+ return _optimize('a{padding-top:10px;padding-left:5px;padding-bottom:3px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'padding-top', [[1, 2, undefined]]],
+ ['property-value', '10px', [[1, 14, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-left', [[1, 19, undefined]]],
+ ['property-value', '5px', [[1, 32, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-bottom', [[1, 36, undefined]]],
+ ['property-value', '3px', [[1, 51, undefined]]]
+ ]
]);
}
},
'with inherit - pending #525': {
- 'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px;padding-right:inherit}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['padding-top'], ['10px']],
- [['padding-left'], ['5px']],
- [['padding-bottom'], ['3px']],
- [['padding-right'], ['inherit']]
+ 'topic': function () {
+ return _optimize('a{padding-top:10px;padding-left:5px;padding-bottom:3px;padding-right:inherit}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'padding-top', [[1, 2, undefined]]],
+ ['property-value', '10px', [[1, 14, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-left', [[1, 19, undefined]]],
+ ['property-value', '5px', [[1, 32, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-bottom', [[1, 36, undefined]]],
+ ['property-value', '3px', [[1, 51, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-right', [[1, 55, undefined]]],
+ ['property-value', 'inherit', [[1, 69, undefined]]]
+ ]
]);
}
},
'mixed importance': {
- 'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px;padding-right:2px!important}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['padding-top'], ['10px']],
- [['padding-left'], ['5px']],
- [['padding-bottom'], ['3px']],
- [['padding-right'], ['2px!important']]
+ 'topic': function () {
+ return _optimize('a{padding-top:10px;padding-left:5px;padding-bottom:3px;padding-right:2px!important}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'padding-top', [[1, 2, undefined]]],
+ ['property-value', '10px', [[1, 14, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-left', [[1, 19, undefined]]],
+ ['property-value', '5px', [[1, 32, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-bottom', [[1, 36, undefined]]],
+ ['property-value', '3px', [[1, 51, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-right', [[1, 55, undefined]]],
+ ['property-value', '2px!important', [[1, 69, undefined]]]
+ ]
]);
}
},
'mixed understandability of units': {
- 'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px;padding-right:calc(100% - 20px)}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['padding-top'], ['10px']],
- [['padding-left'], ['5px']],
- [['padding-bottom'], ['3px']],
- [['padding-right'], ['calc(100% - 20px)']]
+ 'topic': function () {
+ return _optimize('a{padding-top:10px;padding-left:5px;padding-bottom:3px;padding-right:calc(100% - 20px)}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'padding-top', [[1, 2, undefined]]],
+ ['property-value', '10px', [[1, 14, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-left', [[1, 19, undefined]]],
+ ['property-value', '5px', [[1, 32, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-bottom', [[1, 36, undefined]]],
+ ['property-value', '3px', [[1, 51, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'padding-right', [[1, 55, undefined]]],
+ ['property-value', 'calc(100% - 20px)', [[1, 69, undefined]]]
+ ]
]);
}
},
'mixed understandability of images': {
- 'topic': 'p{background-color:#111;background-image:linear-gradient(sth);background-repeat:repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-origin:padding-box;background-clip:border-box}',
- 'into': function (topic) {
- assert.deepEqual(_optimize(topic), [
- [['background-color'], ['#111']],
- [['background-image'], ['linear-gradient(sth)']],
- [['background-repeat'], ['repeat']],
- [['background-position'], ['0'], ['0']],
- [['background-attachment'], ['scroll']],
- [['background-size'], ['auto']],
- [['background-origin'], ['padding-box']],
- [['background-clip'], ['border-box']]
+ 'topic': function () {
+ return _optimize('p{background-color:#111;background-image:linear-gradient(sth);background-repeat:repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-origin:padding-box;background-clip:border-box}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'background-color', [[1, 2, undefined]]],
+ ['property-value', '#111', [[1, 19, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-image', [[1, 24, undefined]]],
+ ['property-value', 'linear-gradient(sth)', [[1, 41, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-repeat', [[1, 62, undefined]]],
+ ['property-value', 'repeat', [[1, 80, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-position', [[1, 87, undefined]]],
+ ['property-value', '0', [[1, 107, undefined]]],
+ ['property-value', '0', [[1, 109, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-attachment', [[1, 111, undefined]]],
+ ['property-value', 'scroll', [[1, 133, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-size', [[1, 140, undefined]]],
+ ['property-value', 'auto', [[1, 156, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-origin', [[1, 161, undefined]]],
+ ['property-value', 'padding-box', [[1, 179, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'background-clip', [[1, 191, undefined]]],
+ ['property-value', 'border-box', [[1, 207, undefined]]]
+ ]
]);
}
- }
+ }
})
.export(module);
.addBatch({
'one': {
'topic': function () {
- return wrapForOptimizing([[['margin'], ['0'], ['0']]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0'],
+ ['property-value', '0']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
assert.deepEqual(wrapped[0].name, 'margin');
},
'has value': function (wrapped) {
- assert.deepEqual(wrapped[0].value, [['0'], ['0']]);
+ assert.deepEqual(wrapped[0].value, [['property-value', '0'], ['property-value', '0']]);
},
'is not a block': function (wrapped) {
assert.isFalse(wrapped[0].block);
},
'two': {
'topic': function () {
- return wrapForOptimizing([[['margin'], ['0'], ['0']], [['color'], ['red']]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0'],
+ ['property-value', '0']
+ ],
+ [
+ 'property',
+ ['property-name', 'color'],
+ ['property-value', 'red']
+ ]
+ ]);
},
'has two wraps': function (wrapped) {
assert.lengthOf(wrapped, 2);
},
'with comments': {
'topic': function () {
- return wrapForOptimizing([['/* comment */'], [['color'], ['red']]]);
+ return wrapForOptimizing([
+ [
+ 'comment',
+ ['/* comment */']
+ ],
+ [
+ 'property',
+ ['property-name', 'color'],
+ ['property-value', 'red']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
},
'longhand': {
'topic': function () {
- return wrapForOptimizing([[['border-radius-top-left'], ['1px'], ['/'], ['2px']]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'border-radius-top-left'],
+ ['property-value', '1px'],
+ ['property-value', '/'],
+ ['property-value', '2px']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
assert.deepEqual(wrapped[0].name, 'border-radius-top-left');
},
'has value': function (wrapped) {
- assert.deepEqual(wrapped[0].value, [['1px'], ['/'], ['2px']]);
+ assert.deepEqual(wrapped[0].value, [['property-value', '1px'], ['property-value', '/'], ['property-value', '2px']]);
},
'is multiplex': function (wrapped) {
assert.isTrue(wrapped[0].multiplex);
},
'variable': {
'topic': function () {
- return wrapForOptimizing([[['--color'], ['red']]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', '--color'],
+ ['property-value', 'red']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
'has name': function (wrapped) {
assert.deepEqual(wrapped[0].name, '--color');
},
- 'has value': function (wrapped) {
- assert.deepEqual(wrapped[0].value, [['red']]);
- },
'is not a block': function (wrapped) {
assert.isFalse(wrapped[0].block);
- },
- 'is variable': function (wrapped) {
- assert.isTrue(wrapped[0].variable);
}
},
'variable block': {
'topic': function () {
- return wrapForOptimizing([[['--color'], [ [['color'], ['red']], [['text-color'], ['red']] ]]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', '--color'],
+ [
+ 'property-block',
+ [
+ [
+ 'property',
+ ['property-name', 'color'],
+ ['property-value', 'red']
+ ],
+ [
+ 'property',
+ ['property-name', 'text-color'],
+ ['property-value', 'red']
+ ]
+ ]
+ ]
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
assert.deepEqual(wrapped[0].name, '--color');
},
'has value': function (wrapped) {
- assert.deepEqual(wrapped[0].value, [[ [['color'], ['red']], [['text-color'], ['red']] ]]);
- },
- 'is not a block': function (wrapped) {
+ assert.deepEqual(wrapped[0].value, [
+ [
+ 'property-block',
+ [
+ [
+ 'property',
+ ['property-name', 'color'],
+ ['property-value', 'red']
+ ],
+ [
+ 'property',
+ ['property-name', 'text-color'],
+ ['property-value', 'red']
+ ]
+ ]
+ ]
+ ]);
+ },
+ 'is a block': function (wrapped) {
assert.isTrue(wrapped[0].block);
- },
- 'is variable': function (wrapped) {
- assert.isTrue(wrapped[0].variable);
}
},
'without value': {
'topic': function () {
- return wrapForOptimizing([[['margin']]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
},
- 'is unused': function (wrapped) {
- assert.isTrue(wrapped[0].unused);
+ 'has value': function (wrapped) {
+ assert.isUndefined(wrapped.value);
+ },
+ 'unused is not set': function (wrapped) {
+ assert.isFalse(wrapped[0].unused);
}
},
'important': {
'topic': function () {
- return wrapForOptimizing([[['margin'], ['0!important']]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0!important']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
},
'has right value': function (wrapped) {
- assert.deepEqual(wrapped[0].value, [['0']]);
+ assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
},
- 'is important': function (wrapped) {
+ 'has important set': function (wrapped) {
+ assert.isTrue(wrapped[0].important);
+ }
+ },
+ 'important with prefix space': {
+ 'topic': function () {
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0'],
+ ['property-value', '!important']
+ ]
+ ]);
+ },
+ 'has one wrap': function (wrapped) {
+ assert.lengthOf(wrapped, 1);
+ },
+ 'has right value': function (wrapped) {
+ assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
+ },
+ 'has important set': function (wrapped) {
assert.isTrue(wrapped[0].important);
}
},
+ 'important with suffix space': {
+ 'topic': function () {
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0!'],
+ ['property-value', 'important']
+ ]
+ ]);
+ },
+ 'has one wrap': function (wrapped) {
+ assert.lengthOf(wrapped, 1);
+ },
+ 'has right value': function (wrapped) {
+ assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
+ },
+ 'has important set': function (wrapped) {
+ assert.isTrue(wrapped[0].important);
+ }
+ },
+ 'important with two spaces': {
+ 'topic': function () {
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0'],
+ ['property-value', '!'],
+ ['property-value', 'important']
+ ]
+ ]);
+ },
+ 'has one wrap': function (wrapped) {
+ assert.lengthOf(wrapped, 1);
+ },
+ 'has right value': function (wrapped) {
+ assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
+ },
+ 'has important set': function (wrapped) {
+ assert.isTrue(wrapped[0].important);
+ },
+ 'is not a bang hack': function (wrapped) {
+ assert.isFalse(wrapped[0].hack);
+ }
+ },
'underscore hack': {
'topic': function () {
- return wrapForOptimizing([[['_color'], ['red']]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', '_color'],
+ ['property-value', 'red']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
},
'star hack': {
'topic': function () {
- return wrapForOptimizing([[['*color'], ['red']]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', '*color'],
+ ['property-value', 'red']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
},
'backslash hack': {
'topic': function () {
- return wrapForOptimizing([[['margin'], ['0\\9']]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0\\9']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
},
'has right value': function (wrapped) {
- assert.deepEqual(wrapped[0].value, [['0']]);
+ assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
},
'is a hack': function (wrapped) {
assert.equal(wrapped[0].hack, 'backslash');
},
'backslash hack - single value': {
'topic': function () {
- return wrapForOptimizing([[['margin'], ['0']]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
},
'has right value': function (wrapped) {
- assert.deepEqual(wrapped[0].value, [['0']]);
+ assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
},
'is a hack': function (wrapped) {
assert.isFalse(wrapped[0].hack);
},
'backslash hack - space between values': {
'topic': function () {
- return wrapForOptimizing([[['margin'], ['0'], ['\\9']]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0'],
+ ['property-value', '\\9']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
},
'has right value': function (wrapped) {
- assert.deepEqual(wrapped[0].value, [['0']]);
+ assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
},
'is a hack': function (wrapped) {
assert.equal(wrapped[0].hack, 'backslash');
},
'bang hack': {
'topic': function () {
- return wrapForOptimizing([[['margin'], ['0'], ['!ie']]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0!ie']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
},
'has right value': function (wrapped) {
- assert.deepEqual(wrapped[0].value, [['0']]);
+ assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
+ },
+ 'is a hack': function (wrapped) {
+ assert.equal(wrapped[0].hack, 'bang');
+ },
+ 'is not important': function (wrapped) {
+ assert.isFalse(wrapped[0].important);
+ }
+ },
+ 'bang hack with space': {
+ 'topic': function () {
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0 !ie']
+ ]
+ ]);
+ },
+ 'has one wrap': function (wrapped) {
+ assert.lengthOf(wrapped, 1);
+ },
+ 'has right value': function (wrapped) {
+ assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
},
'is a hack': function (wrapped) {
assert.equal(wrapped[0].hack, 'bang');
},
'bang hack - space between values': {
'topic': function () {
- return wrapForOptimizing([[['margin'], ['0 !ie']]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'margin'],
+ ['property-value', '0'],
+ ['property-value', '!ie']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
},
'has right value': function (wrapped) {
- assert.deepEqual(wrapped[0].value, [['0']]);
+ assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
},
'is a hack': function (wrapped) {
assert.equal(wrapped[0].hack, 'bang');
assert.isFalse(wrapped[0].important);
}
},
- 'source map': {
+ 'two hacks': {
'topic': function () {
- return wrapForOptimizing([[['color', 1, 2, undefined], ['red\\9!important', 1, 2, undefined]]]);
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'color'],
+ ['property-value', 'red\\9!important']
+ ]
+ ]);
},
'has one wrap': function (wrapped) {
assert.lengthOf(wrapped, 1);
},
'has right value': function (wrapped) {
- assert.deepEqual(wrapped[0].value, [['red', 1, 2, undefined]]);
+ assert.deepEqual(wrapped[0].value, [['property-value', 'red']]);
},
'is important': function (wrapped) {
assert.isTrue(wrapped[0].important);
'is a hack': function (wrapped) {
assert.equal(wrapped[0].hack, 'backslash');
}
+ },
+ 'source map': {
+ 'topic': function () {
+ return wrapForOptimizing([
+ [
+ 'property',
+ ['property-name', 'color', [[1, 2, undefined]]],
+ ['property-value', 'red', [[1, 2, undefined]]]
+ ]
+ ]);
+ },
+ 'has one wrap': function (wrapped) {
+ assert.lengthOf(wrapped, 1);
+ },
+ 'has right value': function (wrapped) {
+ assert.deepEqual(wrapped[0].value, [['property-value', 'red', [[1, 2, undefined]]]]);
+ }
}
})
.export(module);
+++ /dev/null
-var vows = require('vows');
-var assert = require('assert');
-var tokenize = require('../../lib/tokenizer/tokenize');
-var extractor = require('../../lib/selectors/extractor');
-
-function buildToken(source) {
- return tokenize(source, { options: {} })[0];
-}
-
-vows.describe(extractor)
- .addBatch({
- 'no properties': {
- 'topic': extractor(buildToken('a{}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, []);
- }
- },
- 'no valid properties': {
- 'topic': extractor(buildToken('a{:red}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, []);
- }
- },
- 'one property': {
- 'topic': extractor(buildToken('a{color:red}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['color', 'red', 'color', [['color'], ['red']], 'color:red', [['a']], true]]);
- }
- },
- 'one important property': {
- 'topic': extractor(buildToken('a{color:red!important}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['color', 'red!important', 'color', [['color'], ['red!important']], 'color:red!important', [['a']], true]]);
- }
- },
- 'one property - simple selector': {
- 'topic': extractor(buildToken('#one span{color:red}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['color', 'red', 'color', [['color'], ['red']], 'color:red', [['#one span']], true]]);
- }
- },
- 'one property - variable': {
- 'topic': extractor(buildToken('#one span{--color:red}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, []);
- }
- },
- 'one property - block variable': {
- 'topic': extractor(buildToken('#one span{--color:{color:red;display:block};}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, []);
- }
- },
- 'one property - complex selector': {
- 'topic': extractor(buildToken('.one{color:red}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['color', 'red', 'color', [['color'], ['red']], 'color:red', [['.one']], false]]);
- }
- },
- 'two properties': {
- 'topic': extractor(buildToken('a{color:red;display:block}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [
- ['color', 'red', 'color', [['color'], ['red']], 'color:red', [['a']], true],
- ['display', 'block', 'display', [['display'], ['block']], 'display:block', [['a']], true]
- ]);
- }
- },
- 'from @media': {
- 'topic': extractor(buildToken('@media{a{color:red;display:block}p{color:red}}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [
- ['color', 'red', 'color', [['color'], ['red']], 'color:red', [['a']], true],
- ['display', 'block', 'display', [['display'], ['block']], 'display:block', [['a']], true],
- ['color', 'red', 'color', [['color'], ['red']], 'color:red', [['p']], true]
- ]);
- }
- },
- 'with source map info': {
- 'topic': extractor(['selector', [['a', 1, 0, undefined]], [[['color', 1, 3, undefined], ['red', 1, 9, undefined]]]]),
- 'has one property': function (tokens) {
- assert.deepEqual(tokens, [
- ['color', 'red', 'color', [['color', 1, 3, undefined], ['red', 1, 9, undefined]], 'color:red', [['a', 1, 0, undefined]], true],
- ]);
- }
- }
- })
- .addBatch({
- 'name root special cases': {
- 'vendor prefix': {
- 'topic': extractor(buildToken('a{-moz-transform:none}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['-moz-transform', 'none', 'transform', [['-moz-transform'], ['none']], '-moz-transform:none', [['a']], true]]);
- }
- },
- 'list-style': {
- 'topic': extractor(buildToken('a{list-style:none}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['list-style', 'none', 'list-style', [['list-style'], ['none']], 'list-style:none', [['a']], true]]);
- }
- },
- 'border-radius': {
- 'topic': extractor(buildToken('a{border-top-left-radius:none}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['border-top-left-radius', 'none', 'border-radius', [['border-top-left-radius'], ['none']], 'border-top-left-radius:none', [['a']], true]]);
- }
- },
- 'vendor prefixed border-radius': {
- 'topic': extractor(buildToken('a{-webkit-border-top-left-radius:none}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['-webkit-border-top-left-radius', 'none', 'border-radius', [['-webkit-border-top-left-radius'], ['none']], '-webkit-border-top-left-radius:none', [['a']], true]]);
- }
- },
- 'border-image-width': {
- 'topic': extractor(buildToken('a{border-image-width:2px}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['border-image-width', '2px', 'border-image', [['border-image-width'], ['2px']], 'border-image-width:2px', [['a']], true]]);
- }
- },
- 'border-color': {
- 'topic': extractor(buildToken('a{border-color:red}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['border-color', 'red', 'border', [['border-color'], ['red']], 'border-color:red', [['a']], true]]);
- }
- },
- 'border-top-style': {
- 'topic': extractor(buildToken('a{border-top-style:none}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['border-top-style', 'none', 'border-top', [['border-top-style'], ['none']], 'border-top-style:none', [['a']], true]]);
- }
- },
- 'border-top': {
- 'topic': extractor(buildToken('a{border-top:none}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['border-top', 'none', 'border', [['border-top'], ['none']], 'border-top:none', [['a']], true]]);
- }
- },
- 'border-collapse': {
- 'topic': extractor(buildToken('a{border-collapse:collapse}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['border-collapse', 'collapse', 'border-collapse', [['border-collapse'], ['collapse']], 'border-collapse:collapse', [['a']], true]]);
- }
- },
- 'text-shadow': {
- 'topic': extractor(buildToken('a{text-shadow:none}')),
- 'has no properties': function (tokens) {
- assert.deepEqual(tokens, [['text-shadow', 'none', 'text-shadow', [['text-shadow'], ['none']], 'text-shadow:none', [['a']], true]]);
- }
- }
- }
- })
- .export(module);
var assert = require('assert');
var CleanCSS = require('../lib/clean');
-var tokenize = require('../lib/tokenizer/tokenize');
-var simpleOptimize = require('../lib/selectors/simple');
-var Compatibility = require('../lib/utils/compatibility');
function optimizerContext(group, specs, options) {
var context = {};
return context;
}
-function selectorContext(group, specs, options) {
- var context = {};
- options = options || {};
- options.compatibility = new Compatibility(options.compatibility).toOptions();
-
- function optimized(selectors) {
- return function (source) {
- var tokens = tokenize(source, { options: {} });
- simpleOptimize(tokens, options, {});
-
- assert.deepEqual(tokens[0] ? tokens[0][1] : null, selectors);
- };
- }
-
- for (var name in specs) {
- context['selector - ' + group + ' - ' + name] = {
- topic: specs[name][0],
- optimized: optimized(specs[name][1])
- };
- }
-
- return context;
-}
-
-function propertyContext(group, specs, options) {
- var context = {};
- options = options || {};
- options.compatibility = new Compatibility(options.compatibility).toOptions();
-
- function optimized(selectors) {
- return function (source) {
- var tokens = tokenize(source, { options: {} });
- simpleOptimize(tokens, options, {});
-
- var value = tokens[0] ?
- tokens[0][2].map(function (property) {
- return typeof property == 'string' ?
- property :
- property.map(function (t) { return t[0]; });
- }) :
- null;
-
- assert.deepEqual(value, selectors);
- };
- }
-
- for (var name in specs) {
- context['property - ' + group + ' - ' + name] = {
- topic: specs[name][0],
- optimized: optimized(specs[name][1])
- };
- }
-
- return context;
-}
-
module.exports = {
- optimizerContext: optimizerContext,
- selectorContext: selectorContext,
- propertyContext: propertyContext
+ optimizerContext: optimizerContext
};
var vows = require('vows');
var assert = require('assert');
-var Compatibility = require('../../lib/utils/compatibility');
+var compatibility = require('../../lib/utils/compatibility');
-vows.describe(Compatibility)
+vows.describe(compatibility)
.addBatch({
'as an empty hash': {
'topic': function () {
- return new Compatibility({}).toOptions();
+ return compatibility({});
},
- 'gets default options': function (options) {
- assert.isTrue(options.colors.opacity);
- assert.isTrue(options.properties.colors);
- assert.isFalse(options.properties.backgroundClipMerging);
- assert.isFalse(options.properties.backgroundOriginMerging);
- assert.isFalse(options.properties.backgroundSizeMerging);
- assert.isFalse(options.properties.ieBangHack);
- assert.isFalse(options.properties.iePrefixHack);
- assert.isTrue(options.properties.ieSuffixHack);
- assert.isTrue(options.properties.merging);
- assert.isFalse(options.properties.shorterLengthUnits);
- assert.isTrue(options.properties.spaceAfterClosingBrace);
- assert.isFalse(options.properties.urlQuotes);
- assert.isTrue(options.properties.zeroUnits);
- assert.isFalse(options.selectors.adjacentSpace);
- assert.isFalse(options.selectors.ie7Hack);
- assert.isTrue(options.units.ch);
- assert.isTrue(options.units.in);
- assert.isTrue(options.units.pc);
- assert.isTrue(options.units.pt);
- assert.isTrue(options.units.rem);
- assert.isTrue(options.units.vh);
- assert.isTrue(options.units.vm);
- assert.isTrue(options.units.vmax);
- assert.isTrue(options.units.vmin);
- assert.isTrue(options.units.vw);
+ 'gets default compatibility': function (compat) {
+ assert.isTrue(compat.colors.opacity);
+ assert.isTrue(compat.properties.colors);
+ assert.isFalse(compat.properties.backgroundClipMerging);
+ assert.isFalse(compat.properties.backgroundOriginMerging);
+ assert.isFalse(compat.properties.backgroundSizeMerging);
+ assert.isFalse(compat.properties.ieBangHack);
+ assert.isFalse(compat.properties.iePrefixHack);
+ assert.isTrue(compat.properties.ieSuffixHack);
+ assert.isTrue(compat.properties.merging);
+ assert.isFalse(compat.properties.shorterLengthUnits);
+ assert.isTrue(compat.properties.spaceAfterClosingBrace);
+ assert.isFalse(compat.properties.urlQuotes);
+ assert.isTrue(compat.properties.zeroUnits);
+ assert.isFalse(compat.selectors.adjacentSpace);
+ assert.isFalse(compat.selectors.ie7Hack);
+ assert.isTrue(compat.units.ch);
+ assert.isTrue(compat.units.in);
+ assert.isTrue(compat.units.pc);
+ assert.isTrue(compat.units.pt);
+ assert.isTrue(compat.units.rem);
+ assert.isTrue(compat.units.vh);
+ assert.isTrue(compat.units.vm);
+ assert.isTrue(compat.units.vmax);
+ assert.isTrue(compat.units.vmin);
+ assert.isTrue(compat.units.vw);
}
},
'not given': {
'topic': function () {
- return new Compatibility().toOptions();
+ return compatibility();
},
- 'gets default options': function (options) {
- assert.deepEqual(options, new Compatibility({}).toOptions());
+ 'gets default compatibility': function (compat) {
+ assert.deepEqual(compat, compatibility({}));
}
},
'as a populated hash': {
'topic': function () {
- return new Compatibility({ units: { rem: false, vmax: false }, properties: { prefix: true } }).toOptions();
+ return compatibility({ units: { rem: false, vmax: false }, properties: { prefix: true } });
},
- 'gets merged options': function (options) {
- assert.isTrue(options.colors.opacity);
- assert.isFalse(options.properties.backgroundClipMerging);
- assert.isFalse(options.properties.backgroundOriginMerging);
- assert.isFalse(options.properties.backgroundSizeMerging);
- assert.isTrue(options.properties.colors);
- assert.isFalse(options.properties.ieBangHack);
- assert.isFalse(options.properties.iePrefixHack);
- assert.isTrue(options.properties.ieSuffixHack);
- assert.isTrue(options.properties.merging);
- assert.isFalse(options.properties.shorterLengthUnits);
- assert.isTrue(options.properties.spaceAfterClosingBrace);
- assert.isTrue(options.properties.zeroUnits);
- assert.isFalse(options.selectors.adjacentSpace);
- assert.isFalse(options.selectors.ie7Hack);
- assert.isTrue(options.units.ch);
- assert.isTrue(options.units.in);
- assert.isTrue(options.units.pc);
- assert.isTrue(options.units.pt);
- assert.isFalse(options.units.rem);
- assert.isTrue(options.units.vh);
- assert.isTrue(options.units.vm);
- assert.isFalse(options.units.vmax);
- assert.isTrue(options.units.vmin);
- assert.isTrue(options.units.vw);
+ 'gets merged compatibility': function (compat) {
+ assert.isTrue(compat.colors.opacity);
+ assert.isFalse(compat.properties.backgroundClipMerging);
+ assert.isFalse(compat.properties.backgroundOriginMerging);
+ assert.isFalse(compat.properties.backgroundSizeMerging);
+ assert.isTrue(compat.properties.colors);
+ assert.isFalse(compat.properties.ieBangHack);
+ assert.isFalse(compat.properties.iePrefixHack);
+ assert.isTrue(compat.properties.ieSuffixHack);
+ assert.isTrue(compat.properties.merging);
+ assert.isFalse(compat.properties.shorterLengthUnits);
+ assert.isTrue(compat.properties.spaceAfterClosingBrace);
+ assert.isTrue(compat.properties.zeroUnits);
+ assert.isFalse(compat.selectors.adjacentSpace);
+ assert.isFalse(compat.selectors.ie7Hack);
+ assert.isTrue(compat.units.ch);
+ assert.isTrue(compat.units.in);
+ assert.isTrue(compat.units.pc);
+ assert.isTrue(compat.units.pt);
+ assert.isFalse(compat.units.rem);
+ assert.isTrue(compat.units.vh);
+ assert.isTrue(compat.units.vm);
+ assert.isFalse(compat.units.vmax);
+ assert.isTrue(compat.units.vmin);
+ assert.isTrue(compat.units.vw);
}
}
})
.addBatch({
'as an ie8 template': {
'topic': function () {
- return new Compatibility('ie8').toOptions();
+ return compatibility('ie8');
},
- 'gets template options': function (options) {
- assert.isFalse(options.colors.opacity);
- assert.isFalse(options.properties.backgroundClipMerging);
- assert.isFalse(options.properties.backgroundOriginMerging);
- assert.isFalse(options.properties.backgroundSizeMerging);
- assert.isTrue(options.properties.colors);
- assert.isFalse(options.properties.ieBangHack);
- assert.isTrue(options.properties.iePrefixHack);
- assert.isTrue(options.properties.ieSuffixHack);
- assert.isFalse(options.properties.merging);
- assert.isFalse(options.properties.shorterLengthUnits);
- assert.isTrue(options.properties.spaceAfterClosingBrace);
- assert.isFalse(options.properties.urlQuotes);
- assert.isTrue(options.properties.zeroUnits);
- assert.isFalse(options.selectors.adjacentSpace);
- assert.isFalse(options.selectors.ie7Hack);
- assert.isFalse(options.units.ch);
- assert.isTrue(options.units.in);
- assert.isTrue(options.units.pc);
- assert.isTrue(options.units.pt);
- assert.isFalse(options.units.rem);
- assert.isFalse(options.units.vh);
- assert.isFalse(options.units.vm);
- assert.isFalse(options.units.vmax);
- assert.isFalse(options.units.vmin);
- assert.isFalse(options.units.vw);
+ 'gets template compatibility': function (compat) {
+ assert.isFalse(compat.colors.opacity);
+ assert.isFalse(compat.properties.backgroundClipMerging);
+ assert.isFalse(compat.properties.backgroundOriginMerging);
+ assert.isFalse(compat.properties.backgroundSizeMerging);
+ assert.isTrue(compat.properties.colors);
+ assert.isFalse(compat.properties.ieBangHack);
+ assert.isTrue(compat.properties.iePrefixHack);
+ assert.isTrue(compat.properties.ieSuffixHack);
+ assert.isFalse(compat.properties.merging);
+ assert.isFalse(compat.properties.shorterLengthUnits);
+ assert.isTrue(compat.properties.spaceAfterClosingBrace);
+ assert.isFalse(compat.properties.urlQuotes);
+ assert.isTrue(compat.properties.zeroUnits);
+ assert.isFalse(compat.selectors.adjacentSpace);
+ assert.isFalse(compat.selectors.ie7Hack);
+ assert.isFalse(compat.units.ch);
+ assert.isTrue(compat.units.in);
+ assert.isTrue(compat.units.pc);
+ assert.isTrue(compat.units.pt);
+ assert.isFalse(compat.units.rem);
+ assert.isFalse(compat.units.vh);
+ assert.isFalse(compat.units.vm);
+ assert.isFalse(compat.units.vmax);
+ assert.isFalse(compat.units.vmin);
+ assert.isFalse(compat.units.vw);
}
},
'as an ie7 template': {
'topic': function () {
- return new Compatibility('ie7').toOptions();
+ return compatibility('ie7');
},
- 'gets template options': function (options) {
- assert.isFalse(options.colors.opacity);
- assert.isFalse(options.properties.backgroundClipMerging);
- assert.isFalse(options.properties.backgroundOriginMerging);
- assert.isFalse(options.properties.backgroundSizeMerging);
- assert.isTrue(options.properties.colors);
- assert.isTrue(options.properties.ieBangHack);
- assert.isTrue(options.properties.iePrefixHack);
- assert.isTrue(options.properties.ieSuffixHack);
- assert.isFalse(options.properties.merging);
- assert.isFalse(options.properties.shorterLengthUnits);
- assert.isTrue(options.properties.spaceAfterClosingBrace);
- assert.isFalse(options.properties.urlQuotes);
- assert.isTrue(options.properties.zeroUnits);
- assert.isFalse(options.selectors.adjacentSpace);
- assert.isTrue(options.selectors.ie7Hack);
- assert.isFalse(options.units.ch);
- assert.isTrue(options.units.in);
- assert.isTrue(options.units.pc);
- assert.isTrue(options.units.pt);
- assert.isFalse(options.units.rem);
- assert.isFalse(options.units.vh);
- assert.isFalse(options.units.vm);
- assert.isFalse(options.units.vmax);
- assert.isFalse(options.units.vmin);
- assert.isFalse(options.units.vw);
+ 'gets template compatibility': function (compat) {
+ assert.isFalse(compat.colors.opacity);
+ assert.isFalse(compat.properties.backgroundClipMerging);
+ assert.isFalse(compat.properties.backgroundOriginMerging);
+ assert.isFalse(compat.properties.backgroundSizeMerging);
+ assert.isTrue(compat.properties.colors);
+ assert.isTrue(compat.properties.ieBangHack);
+ assert.isTrue(compat.properties.iePrefixHack);
+ assert.isTrue(compat.properties.ieSuffixHack);
+ assert.isFalse(compat.properties.merging);
+ assert.isFalse(compat.properties.shorterLengthUnits);
+ assert.isTrue(compat.properties.spaceAfterClosingBrace);
+ assert.isFalse(compat.properties.urlQuotes);
+ assert.isTrue(compat.properties.zeroUnits);
+ assert.isFalse(compat.selectors.adjacentSpace);
+ assert.isTrue(compat.selectors.ie7Hack);
+ assert.isFalse(compat.units.ch);
+ assert.isTrue(compat.units.in);
+ assert.isTrue(compat.units.pc);
+ assert.isTrue(compat.units.pt);
+ assert.isFalse(compat.units.rem);
+ assert.isFalse(compat.units.vh);
+ assert.isFalse(compat.units.vm);
+ assert.isFalse(compat.units.vmax);
+ assert.isFalse(compat.units.vmin);
+ assert.isFalse(compat.units.vw);
}
},
'as an unknown template': {
'topic': function () {
- return new Compatibility('').toOptions();
+ return compatibility('');
},
- 'gets default options': function (options) {
- assert.deepEqual(options, new Compatibility({}).toOptions());
+ 'gets default compatibility': function (compat) {
+ assert.deepEqual(compat, compatibility({}));
}
}
})
.addBatch({
'as a complex string value with group': {
'topic': function () {
- return new Compatibility('ie8,-properties.iePrefixHack,+colors.opacity').toOptions();
+ return compatibility('ie8,-properties.iePrefixHack,+colors.opacity');
},
- 'gets calculated options': function (options) {
- assert.isTrue(options.colors.opacity);
- assert.isFalse(options.properties.backgroundClipMerging);
- assert.isFalse(options.properties.backgroundOriginMerging);
- assert.isFalse(options.properties.backgroundSizeMerging);
- assert.isTrue(options.properties.colors);
- assert.isFalse(options.properties.ieBangHack);
- assert.isFalse(options.properties.iePrefixHack);
- assert.isTrue(options.properties.ieSuffixHack);
- assert.isFalse(options.properties.merging);
- assert.isFalse(options.properties.shorterLengthUnits);
- assert.isTrue(options.properties.spaceAfterClosingBrace);
- assert.isFalse(options.properties.urlQuotes);
- assert.isTrue(options.properties.zeroUnits);
- assert.isFalse(options.selectors.adjacentSpace);
- assert.isFalse(options.selectors.ie7Hack);
- assert.isFalse(options.units.ch);
- assert.isTrue(options.units.in);
- assert.isTrue(options.units.pc);
- assert.isTrue(options.units.pt);
- assert.isFalse(options.units.rem);
- assert.isFalse(options.units.vh);
- assert.isFalse(options.units.vm);
- assert.isFalse(options.units.vmax);
- assert.isFalse(options.units.vmin);
- assert.isFalse(options.units.vw);
+ 'gets calculated compatibility': function (compat) {
+ assert.isTrue(compat.colors.opacity);
+ assert.isFalse(compat.properties.backgroundClipMerging);
+ assert.isFalse(compat.properties.backgroundOriginMerging);
+ assert.isFalse(compat.properties.backgroundSizeMerging);
+ assert.isTrue(compat.properties.colors);
+ assert.isFalse(compat.properties.ieBangHack);
+ assert.isFalse(compat.properties.iePrefixHack);
+ assert.isTrue(compat.properties.ieSuffixHack);
+ assert.isFalse(compat.properties.merging);
+ assert.isFalse(compat.properties.shorterLengthUnits);
+ assert.isTrue(compat.properties.spaceAfterClosingBrace);
+ assert.isFalse(compat.properties.urlQuotes);
+ assert.isTrue(compat.properties.zeroUnits);
+ assert.isFalse(compat.selectors.adjacentSpace);
+ assert.isFalse(compat.selectors.ie7Hack);
+ assert.isFalse(compat.units.ch);
+ assert.isTrue(compat.units.in);
+ assert.isTrue(compat.units.pc);
+ assert.isTrue(compat.units.pt);
+ assert.isFalse(compat.units.rem);
+ assert.isFalse(compat.units.vh);
+ assert.isFalse(compat.units.vm);
+ assert.isFalse(compat.units.vmax);
+ assert.isFalse(compat.units.vmin);
+ assert.isFalse(compat.units.vw);
}
},
'as a single string value without group': {
'topic': function () {
- return new Compatibility('+properties.iePrefixHack').toOptions();
+ return compatibility('+properties.iePrefixHack');
},
- 'gets calculated options': function (options) {
- assert.isTrue(options.colors.opacity);
- assert.isTrue(options.properties.colors);
- assert.isFalse(options.properties.backgroundClipMerging);
- assert.isFalse(options.properties.backgroundOriginMerging);
- assert.isFalse(options.properties.backgroundSizeMerging);
- assert.isFalse(options.properties.ieBangHack);
- assert.isTrue(options.properties.iePrefixHack);
- assert.isTrue(options.properties.ieSuffixHack);
- assert.isTrue(options.properties.merging);
- assert.isFalse(options.properties.shorterLengthUnits);
- assert.isTrue(options.properties.spaceAfterClosingBrace);
- assert.isFalse(options.properties.urlQuotes);
- assert.isTrue(options.properties.zeroUnits);
- assert.isFalse(options.selectors.adjacentSpace);
- assert.isFalse(options.selectors.ie7Hack);
- assert.isTrue(options.units.ch);
- assert.isTrue(options.units.in);
- assert.isTrue(options.units.pc);
- assert.isTrue(options.units.pt);
- assert.isTrue(options.units.rem);
- assert.isTrue(options.units.vh);
- assert.isTrue(options.units.vm);
- assert.isTrue(options.units.vmax);
- assert.isTrue(options.units.vmin);
- assert.isTrue(options.units.vw);
+ 'gets calculated compatibility': function (compat) {
+ assert.isTrue(compat.colors.opacity);
+ assert.isTrue(compat.properties.colors);
+ assert.isFalse(compat.properties.backgroundClipMerging);
+ assert.isFalse(compat.properties.backgroundOriginMerging);
+ assert.isFalse(compat.properties.backgroundSizeMerging);
+ assert.isFalse(compat.properties.ieBangHack);
+ assert.isTrue(compat.properties.iePrefixHack);
+ assert.isTrue(compat.properties.ieSuffixHack);
+ assert.isTrue(compat.properties.merging);
+ assert.isFalse(compat.properties.shorterLengthUnits);
+ assert.isTrue(compat.properties.spaceAfterClosingBrace);
+ assert.isFalse(compat.properties.urlQuotes);
+ assert.isTrue(compat.properties.zeroUnits);
+ assert.isFalse(compat.selectors.adjacentSpace);
+ assert.isFalse(compat.selectors.ie7Hack);
+ assert.isTrue(compat.units.ch);
+ assert.isTrue(compat.units.in);
+ assert.isTrue(compat.units.pc);
+ assert.isTrue(compat.units.pt);
+ assert.isTrue(compat.units.rem);
+ assert.isTrue(compat.units.vh);
+ assert.isTrue(compat.units.vm);
+ assert.isTrue(compat.units.vmax);
+ assert.isTrue(compat.units.vmin);
+ assert.isTrue(compat.units.vw);
}
},
'as a complex string value without group': {
'topic': function () {
- return new Compatibility('+properties.iePrefixHack,-units.rem').toOptions();
+ return compatibility('+properties.iePrefixHack,-units.rem');
},
- 'gets calculated options': function (options) {
- assert.isTrue(options.colors.opacity);
- assert.isTrue(options.properties.colors);
- assert.isFalse(options.properties.backgroundClipMerging);
- assert.isFalse(options.properties.backgroundOriginMerging);
- assert.isFalse(options.properties.backgroundSizeMerging);
- assert.isFalse(options.properties.ieBangHack);
- assert.isTrue(options.properties.iePrefixHack);
- assert.isTrue(options.properties.ieSuffixHack);
- assert.isTrue(options.properties.merging);
- assert.isFalse(options.properties.shorterLengthUnits);
- assert.isTrue(options.properties.spaceAfterClosingBrace);
- assert.isFalse(options.properties.urlQuotes);
- assert.isTrue(options.properties.zeroUnits);
- assert.isFalse(options.selectors.adjacentSpace);
- assert.isFalse(options.selectors.ie7Hack);
- assert.isTrue(options.units.ch);
- assert.isTrue(options.units.in);
- assert.isTrue(options.units.pc);
- assert.isTrue(options.units.pt);
- assert.isFalse(options.units.rem);
- assert.isTrue(options.units.vh);
- assert.isTrue(options.units.vm);
- assert.isTrue(options.units.vmax);
- assert.isTrue(options.units.vmin);
- assert.isTrue(options.units.vw);
+ 'gets calculated compatibility': function (compat) {
+ assert.isTrue(compat.colors.opacity);
+ assert.isTrue(compat.properties.colors);
+ assert.isFalse(compat.properties.backgroundClipMerging);
+ assert.isFalse(compat.properties.backgroundOriginMerging);
+ assert.isFalse(compat.properties.backgroundSizeMerging);
+ assert.isFalse(compat.properties.ieBangHack);
+ assert.isTrue(compat.properties.iePrefixHack);
+ assert.isTrue(compat.properties.ieSuffixHack);
+ assert.isTrue(compat.properties.merging);
+ assert.isFalse(compat.properties.shorterLengthUnits);
+ assert.isTrue(compat.properties.spaceAfterClosingBrace);
+ assert.isFalse(compat.properties.urlQuotes);
+ assert.isTrue(compat.properties.zeroUnits);
+ assert.isFalse(compat.selectors.adjacentSpace);
+ assert.isFalse(compat.selectors.ie7Hack);
+ assert.isTrue(compat.units.ch);
+ assert.isTrue(compat.units.in);
+ assert.isTrue(compat.units.pc);
+ assert.isTrue(compat.units.pt);
+ assert.isFalse(compat.units.rem);
+ assert.isTrue(compat.units.vh);
+ assert.isTrue(compat.units.vm);
+ assert.isTrue(compat.units.vmax);
+ assert.isTrue(compat.units.vmin);
+ assert.isTrue(compat.units.vw);
}
}
})
+++ /dev/null
-var vows = require('vows');
-var assert = require('assert');
-var QuoteScanner = require('../../lib/utils/quote-scanner');
-
-vows.describe(QuoteScanner)
- .addBatch({
- 'no quotes': {
- topic: 'text without quotes',
- iterator: function (topic) {
- var index = 0;
- new QuoteScanner(topic).each(function iterator() { index++; });
-
- assert.equal(index, 0);
- }
- },
- 'one single quote': {
- topic: 'text with \'one quote\'!',
- iterator: function (topic) {
- var index = 0;
- new QuoteScanner(topic).each(function iterator(match, tokensSoFar, nextStart) {
- index++;
-
- assert.equal(match, '\'one quote\'');
- assert.deepEqual(tokensSoFar, ['text with ']);
- assert.equal(nextStart, 10);
- });
-
- assert.equal(index, 1);
- }
- },
- 'one double quote': {
- topic: 'text with "one quote"!',
- iterator: function (topic) {
- var index = 0;
- new QuoteScanner(topic).each(function iterator(match, tokensSoFar, nextStart) {
- index++;
-
- assert.equal(match, '"one quote"');
- assert.deepEqual(tokensSoFar, ['text with ']);
- assert.equal(nextStart, 10);
- });
-
- assert.equal(index, 1);
- }
- },
- 'mixed quotes': {
- topic: 'text with "one \'quote\'"!',
- iterator: function (topic) {
- var index = 0;
- new QuoteScanner(topic).each(function iterator(match, tokensSoFar, nextStart) {
- index++;
-
- assert.equal(match, '"one \'quote\'"');
- assert.deepEqual(tokensSoFar, ['text with ']);
- assert.equal(nextStart, 10);
- });
-
- assert.equal(index, 1);
- }
- },
- 'escaped quotes': {
- topic: 'text with "one \\"quote"!',
- iterator: function (topic) {
- var index = 0;
- new QuoteScanner(topic).each(function iterator(match, tokensSoFar, nextStart) {
- index++;
-
- assert.equal(match, '"one \\"quote"');
- assert.deepEqual(tokensSoFar, ['text with ']);
- assert.equal(nextStart, 10);
- });
-
- assert.equal(index, 1);
- }
- },
- 'one open-ended quote': {
- topic: '.this-class\\\'s-got-an-apostrophe {}',
- iterator: function (topic) {
- var index = 0;
- new QuoteScanner(topic).each(function iterator() {
- index++;
- });
-
- assert.equal(index, 0);
- }
- },
- 'many open-ended quotes': {
- topic: '.this-class\\\'s-got-many\\\"-apostrophes\\\' {}',
- iterator: function (topic) {
- var index = 0;
- new QuoteScanner(topic).each(function iterator() {
- index++;
- });
-
- assert.equal(index, 0);
- }
- },
- 'two quotes': {
- topic: 'text with "one \\"quote" and \'another one\'!',
- iterator: function (topic) {
- var index = 0;
- new QuoteScanner(topic).each(function iterator(match, tokensSoFar, nextStart) {
- index++;
-
- if (index == 1) {
- assert.equal(match, '"one \\"quote"');
- assert.deepEqual(tokensSoFar, ['text with ']);
- assert.equal(nextStart, 10);
- } else {
- assert.equal(match, '\'another one\'');
- assert.deepEqual(tokensSoFar, ['text with ', ' and ']);
- assert.equal(nextStart, 28);
- }
- });
-
- assert.equal(index, 2);
- }
- },
- 'between comments': {
- topic: '/*! comment */*{box-sizing:border-box}div:before{content:" "}/*! @comment */',
- iterator: function (topic) {
- var index = 0;
- new QuoteScanner(topic).each(function iterator(match) {
- index++;
-
- assert.equal(match, '" "');
- });
-
- assert.equal(index, 1);
- }
- },
- })
- .export(module);