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');
options: this.options,
debug: this.options.debug,
localOnly: !callback,
- sourceTracker: new SourceTracker()
+ sourceTracker: new SourceTracker(),
+ validator: new Validator(this.options.compatibility)
};
if (context.options.sourceMap)
var wrapSingle = require('./wrap-for-optimizing').single;
-var validator = require('./validator');
var Splitter = require('../utils/splitter');
-function _colorFilter(value) {
- return value[0] == 'invert' || validator.isValidColor(value[0]);
+function _colorFilter(validator) {
+ return function (value) {
+ return value[0] == 'invert' || validator.isValidColor(value[0]);
+ };
}
-function _styleFilter(value) {
- return value[0] != 'inherit' && validator.isValidStyle(value[0]);
+function _styleFilter(validator) {
+ return function (value) {
+ return value[0] != 'inherit' && validator.isValidStyle(value[0]);
+ };
}
function _wrapDefault(name, property, compactable) {
return wrapSingle([[name, property.important], [descriptor.defaultValue]]);
}
-function _widthFilter(value) {
- return value[0] != 'inherit' && validator.isValidWidth(value[0]);
+function _widthFilter(validator) {
+ return function (value) {
+ return value[0] != 'inherit' && validator.isValidWidth(value[0]);
+ };
}
-function background(property, compactable) {
+function background(property, compactable, validator) {
var image = _wrapDefault('background-image', property, compactable);
var position = _wrapDefault('background-position', property, compactable);
var size = _wrapDefault('background-size', property, compactable);
}
function multipleValues(splitWith) {
- return function (property, compactable) {
+ return function (property, compactable, validator) {
var splitsAt = [];
var values = property.value;
var i, j, l, m;
}
if (splitsAt.length === 0)
- return splitWith(property, compactable);
+ return splitWith(property, compactable, validator);
var splitComponents = [];
var _property = _wrapDefault(property.name, property, compactable);
_property.value = values.slice(from, to);
- splitComponents.push(splitWith(_property, compactable));
+ splitComponents.push(splitWith(_property, compactable, validator));
}
var components = splitComponents[0];
};
}
-function listStyle(property, compactable) {
+function listStyle(property, compactable, validator) {
var type = _wrapDefault('list-style-type', property, compactable);
var position = _wrapDefault('list-style-position', property, compactable);
var image = _wrapDefault('list-style-image', property, compactable);
return components;
}
-function widthStyleColor(property, compactable) {
+function widthStyleColor(property, compactable, validator) {
var descriptor = compactable[property.name];
var components = [
_wrapDefault(descriptor.components[0], property, compactable),
// so we'll try to parse it caring as little about order as possible
if (values.length > 0) {
- matches = values.filter(_widthFilter);
+ matches = values.filter(_widthFilter(validator));
match = matches.length > 1 && matches[0] == 'none' ? matches[1] : matches[0];
if (match) {
width.value = [match];
}
if (values.length > 0) {
- match = values.filter(_styleFilter)[0];
+ match = values.filter(_styleFilter(validator))[0];
if (match) {
style.value = [match];
values.splice(values.indexOf(match), 1);
}
if (values.length > 0) {
- match = values.filter(_colorFilter)[0];
+ match = values.filter(_colorFilter(validator))[0];
if (match) {
color.value = [match];
values.splice(values.indexOf(match), 1);
-var validator = require('./validator');
-
// Functions that decide what value can override what.
// The main purpose is to disallow removing CSS fallbacks.
// A separate implementation is needed for every different kind of CSS property.
return true;
}
-function backgroundImage(property1, property2) {
+function backgroundImage(property1, property2, validator) {
// The idea here is that 'more understandable' values override 'less understandable' values, but not vice versa
// Understandability: (none | url | inherit) > (same function) > (same value)
return false;
// Functions with the same name can override each other; same values can override each other
- return sameFunctionOrValue(property1, property2);
+ return sameFunctionOrValue(property1, property2, validator);
}
-function border(property1, property2) {
- return color(property1.components[2], property2.components[2]);
+function border(property1, property2, validator) {
+ return color(property1.components[2], property2.components[2], validator);
}
// Use for color properties (color, background-color, border-color, etc.)
-function color(property1, property2) {
+function color(property1, property2, validator) {
// The idea here is that 'more understandable' values override 'less understandable' values, but not vice versa
// 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
return sameFunctionOrValue(property1, property2);
}
-function twoOptionalFunctions(property1, property2) {
+function twoOptionalFunctions(property1, property2, validator) {
var value1 = _valueOf(property1);
var value2 = _valueOf(property2);
return value1 === value2;
}
-function sameFunctionOrValue(property1, property2) {
+function sameFunctionOrValue(property1, property2, validator) {
var value1 = _valueOf(property1);
var value2 = _valueOf(property2);
}
// Use for properties containing CSS units (margin-top, padding-left, etc.)
-function unit(property1, property2) {
+function unit(property1, property2, validator) {
// The idea here is that 'more understandable' values override 'less understandable' values, but not vice versa
// Understandability: (unit without functions) > (same functions | standard functions) > anything else
// NOTE: there is no point in having different vendor-specific functions override each other or standard functions,
}
// Functions with the same name can override each other; same values can override each other
- return sameFunctionOrValue(property1, property2);
+ return sameFunctionOrValue(property1, property2, validator);
}
module.exports = {
'-webkit-transition-timing-function': ['-webkit-transition']
};
-function _optimize(properties, mergeAdjacent, aggressiveMerging) {
+function _optimize(properties, mergeAdjacent, aggressiveMerging, validator) {
var overrideMapping = {};
var lastName = null;
var j;
if (!wasImportant && (wasHack && !isHack || !wasHack && isHack))
continue;
- if (!wasHack && !isHack && !longhandToShorthand && canOverride && !canOverride(toRemove, property))
+ if (!wasHack && !isHack && !longhandToShorthand && canOverride && !canOverride(toRemove, property, validator))
continue;
if (wasImportant && !isImportant || wasImportant && isHack) {
}
}
-function optimize(selector, properties, mergeAdjacent, withCompacting, options) {
+function optimize(selector, properties, mergeAdjacent, withCompacting, options, validator) {
var _properties = wrapForOptimizing(properties);
- populateComponents(_properties);
- _optimize(_properties, mergeAdjacent, options.aggressiveMerging);
+ populateComponents(_properties, validator);
+ _optimize(_properties, mergeAdjacent, options.aggressiveMerging, validator);
if (withCompacting && options.shorthandCompacting && !options.sourceMap) {
- compactOverrides(_properties, options.compatibility);
+ compactOverrides(_properties, options.compatibility, validator);
// compactShorthands(_properties, false, options.compatibility);
// compactShorthands(_properties, true, options.compatibility);
}
};
}
-function wouldBreakCompatibility(property) {
+function wouldBreakCompatibility(property, validator) {
for (var i = 0; i < property.components.length; i++) {
var component = property.components[i];
var descriptor = compactable[component.name];
var _component = shallowClone(component);
_component.value = [[descriptor.defaultValue]];
- if (!canOverride(_component, component))
+ if (!canOverride(_component, component, validator))
return true;
}
return lengthBefore < lengthAfter;
}
-function compactOverrides(properties, compatibility) {
+function compactOverrides(properties, compatibility, validator) {
var mayOverride, right, left, component;
var i, j, k;
component = right.components.filter(nameMatchFilter(left))[0];
mayOverride = (compactable[left.name] && compactable[left.name].canOverride) || canOverride.sameValue;
- if (mayOverride(left, component)) {
+ if (mayOverride(left, component, validator)) {
left.unused = true;
}
} else if (left.shorthand && !right.shorthand && isComponentOf(left, right)) {
continue;
component = left.components.filter(nameMatchFilter(right))[0];
- if (mayOverride(component, right)) {
+ if (mayOverride(component, right, validator)) {
var disabledBackgroundSizeMerging = !compatibility.properties.backgroundSizeMerging && component.name.indexOf('background-size') > -1;
var nonMergeableValue = compactable[right.name].nonMergeableValue === right.value[0][0];
if (disabledBackgroundSizeMerging || nonMergeableValue)
continue;
- if (!compatibility.properties.merging && wouldBreakCompatibility(left))
+ if (!compatibility.properties.merging && wouldBreakCompatibility(left, validator))
continue;
if (component.value[0][0] != right.value[0][0] && (hasInherits(left) || hasInherits(right)))
var rightComponent = right.components[k];
mayOverride = compactable[leftComponent.name].canOverride || canOverride.sameValue;
- if (!mayOverride(leftComponent, rightComponent) || !canOverride.twoOptionalFunctions(leftComponent, rightComponent))
+ if (!mayOverride(leftComponent, rightComponent, validator) || !canOverride.twoOptionalFunctions(leftComponent, rightComponent, validator))
continue propertyLoop;
}
var compactable = require('./compactable');
-function populateComponents(properties) {
+function populateComponents(properties, validator) {
for (var i = properties.length - 1; i >= 0; i--) {
var property = properties[i];
var descriptor = compactable[property.name];
if (descriptor && descriptor.shorthand) {
property.shorthand = true;
property.dirty = true;
- property.components = descriptor.breakUp(property, compactable);
+ property.components = descriptor.breakUp(property, compactable, validator);
if (property.components.length > 0)
property.multiplex = Array.isArray(property.components[0].value[0][0]);
var listStyleTypeKeywords = ['armenian', 'circle', 'cjk-ideographic', 'decimal', 'decimal-leading-zero', 'disc', 'georgian', 'hebrew', 'hiragana', 'hiragana-iroha', 'inherit', 'katakana', 'katakana-iroha', 'lower-alpha', 'lower-greek', 'lower-latin', 'lower-roman', 'none', 'square', 'upper-alpha', 'upper-latin', 'upper-roman'];
var listStylePositionKeywords = ['inside', 'outside', 'inherit'];
-// var compatibleCssUnitRegex;
-// var compatibleCssUnitAnyRegex;
-
-// var validator = {
-// // FIXME: we need a proper OO here
-// setCompatibility: function (compatibility) {
-// if (compatibility.units.rem) {
-// compatibleCssUnitRegex = cssUnitRegex;
-// compatibleCssUnitAnyRegex = cssUnitAnyRegex;
-// return;
-// }
-
-// var validUnits = allUnits.slice(0).filter(function (value) {
-// return value != 'rem';
-// });
-
-// var compatibleCssUnitRegexStr = '(\\-?\\.?\\d+\\.?\\d*(' + validUnits.join('|') + ')|auto|inherit)';
-// compatibleCssUnitRegex = new RegExp('^' + compatibleCssUnitRegexStr + '$', 'i');
-// compatibleCssUnitAnyRegex = new RegExp('^(none|' + widthKeywords.join('|') + '|' + compatibleCssUnitRegexStr + '|' + cssVariableRegexStr + '|' + cssFunctionNoVendorRegexStr + '|' + cssFunctionVendorRegexStr + ')$', 'i');
-// }
-
-function isValidHexColor(s) {
- return (s.length === 4 || s.length === 7) && s[0] === '#';
+function Validator(compatibility) {
+ if (compatibility.units.rem) {
+ this.compatibleCssUnitRegex = cssUnitRegex;
+ this.compatibleCssUnitAnyRegex = cssUnitAnyRegex;
+ } else {
+ var validUnits = allUnits.slice(0).filter(function (value) {
+ return value != 'rem';
+ });
+
+ var compatibleCssUnitRegexStr = '(\\-?\\.?\\d+\\.?\\d*(' + validUnits.join('|') + ')|auto|inherit)';
+ this.compatibleCssUnitRegex = new RegExp('^' + compatibleCssUnitRegexStr + '$', 'i');
+ this.compatibleCssUnitAnyRegex = new RegExp('^(none|' + widthKeywords.join('|') + '|' + compatibleCssUnitRegexStr + '|' + cssVariableRegexStr + '|' + cssFunctionNoVendorRegexStr + '|' + cssFunctionVendorRegexStr + ')$', 'i');
+ }
}
-function isValidRgbaColor(s) {
+
+Validator.prototype.isValidHexColor = function (s) {
+ return (s.length === 4 || s.length === 7) && s[0] === '#';
+};
+
+Validator.prototype.isValidRgbaColor = function (s) {
s = s.split(' ').join('');
return s.length > 0 && s.indexOf('rgba(') === 0 && s.indexOf(')') === s.length - 1;
-}
-function isValidHslaColor(s) {
+};
+
+Validator.prototype.isValidHslaColor = function (s) {
s = s.split(' ').join('');
return s.length > 0 && s.indexOf('hsla(') === 0 && s.indexOf(')') === s.length - 1;
-}
-function isValidNamedColor(s) {
+};
+
+Validator.prototype.isValidNamedColor = function (s) {
// We don't really check if it's a valid color value, but allow any letters in it
return s !== 'auto' && (s === 'transparent' || s === 'inherit' || /^[a-zA-Z]+$/.test(s));
-}
-function isValidVariable(s) {
+};
+
+Validator.prototype.isValidVariable = function (s) {
return cssVariableRegex.test(s);
-}
-function isValidColor(s) {
- return isValidNamedColor(s) || isValidHexColor(s) || isValidRgbaColor(s) || isValidHslaColor(s) || isValidVariable(s) || isValidVendorPrefixedValue(s);
-}
-function isValidUrl(s) {
+};
+
+Validator.prototype.isValidColor = function (s) {
+ return this.isValidNamedColor(s) ||
+ this.isValidHexColor(s) ||
+ this.isValidRgbaColor(s) ||
+ this.isValidHslaColor(s) ||
+ this.isValidVariable(s) ||
+ this.isValidVendorPrefixedValue(s);
+};
+
+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;
-}
-function isValidUnit(s) {
- return cssUnitAnyRegex.test(s);
-}
-function isValidUnitWithoutFunction(s) {
- return cssUnitRegex.test(s);
-}
-function isValidAndCompatibleUnit(s) {
+};
+
+Validator.prototype.isValidUnit = function (s) {
return cssUnitAnyRegex.test(s);
-}
-function isValidAndCompatibleUnitWithoutFunction(s) {
+};
+
+Validator.prototype.isValidUnitWithoutFunction = function (s) {
return cssUnitRegex.test(s);
-}
-function isValidFunctionWithoutVendorPrefix(s) {
+};
+
+Validator.prototype.isValidAndCompatibleUnit = function (s) {
+ return this.compatibleCssUnitAnyRegex.test(s);
+};
+
+Validator.prototype.isValidAndCompatibleUnitWithoutFunction = function (s) {
+ return this.compatibleCssUnitRegex.test(s);
+};
+
+Validator.prototype.isValidFunctionWithoutVendorPrefix = function (s) {
return cssFunctionNoVendorRegex.test(s);
-}
-function isValidFunctionWithVendorPrefix(s) {
+};
+
+Validator.prototype.isValidFunctionWithVendorPrefix = function (s) {
return cssFunctionVendorRegex.test(s);
-}
-function isValidFunction(s) {
+};
+
+Validator.prototype.isValidFunction = function (s) {
return cssFunctionAnyRegex.test(s);
-}
-function isValidBackgroundRepeat(s) {
- return backgroundRepeatKeywords.indexOf(s) >= 0 || isValidVariable(s);
-}
-function isValidBackgroundAttachment(s) {
- return backgroundAttachmentKeywords.indexOf(s) >= 0 || isValidVariable(s);
-}
-function isValidBackgroundBox(s) {
- return backgroundBoxKeywords.indexOf(s) >= 0 || isValidVariable(s);
-}
-function isValidBackgroundPositionPart(s) {
- return backgroundPositionKeywords.indexOf(s) >= 0 || cssUnitOrCalcRegex.test(s) || isValidVariable(s);
-}
-function isValidBackgroundPosition(s) {
+};
+
+Validator.prototype.isValidBackgroundRepeat = function (s) {
+ return backgroundRepeatKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
+};
+
+Validator.prototype.isValidBackgroundAttachment = function (s) {
+ return backgroundAttachmentKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
+};
+
+Validator.prototype.isValidBackgroundBox = function (s) {
+ return backgroundBoxKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
+};
+
+Validator.prototype.isValidBackgroundPositionPart = function (s) {
+ return backgroundPositionKeywords.indexOf(s) >= 0 || cssUnitOrCalcRegex.test(s) || this.isValidVariable(s);
+};
+
+Validator.prototype.isValidBackgroundPosition = function (s) {
if (s === 'inherit')
return true;
for (var i = 0, l = parts.length; i < l; i++) {
if (parts[i] === '')
continue;
- if (isValidBackgroundPositionPart(parts[i]) || isValidVariable(parts[i]))
+ if (this.isValidBackgroundPositionPart(parts[i]) || this.isValidVariable(parts[i]))
continue;
return false;
}
return true;
-}
-function isValidBackgroundSizePart(s) {
- return backgroundSizeKeywords.indexOf(s) >= 0 || cssUnitRegex.test(s) || isValidVariable(s);
-}
-function isValidBackgroundPositionAndSize(s) {
+};
+
+Validator.prototype.isValidBackgroundSizePart = 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 = new Splitter('/').split(s);
- return isValidBackgroundSizePart(twoParts.pop()) && isValidBackgroundPositionPart(twoParts.pop());
-}
-function isValidListStyleType(s) {
- return listStyleTypeKeywords.indexOf(s) >= 0 || isValidVariable(s);
-}
-function isValidListStylePosition(s) {
- return listStylePositionKeywords.indexOf(s) >= 0 || isValidVariable(s);
-}
-function isValidStyle(s) {
- return styleKeywords.indexOf(s) >= 0 || isValidVariable(s);
-}
-function isValidWidth(s) {
- return isValidUnit(s) || widthKeywords.indexOf(s) >= 0 || isValidVariable(s);
-}
-function isValidVendorPrefixedValue(s) {
+ return this.isValidBackgroundSizePart(twoParts.pop()) && this.isValidBackgroundPositionPart(twoParts.pop());
+};
+
+Validator.prototype.isValidListStyleType = function (s) {
+ return listStyleTypeKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
+};
+
+Validator.prototype.isValidListStylePosition = function (s) {
+ return listStylePositionKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
+};
+
+Validator.prototype.isValidStyle = function (s) {
+ return styleKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
+};
+
+Validator.prototype.isValidWidth = function (s) {
+ return this.isValidUnit(s) || widthKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
+};
+
+Validator.prototype.isValidVendorPrefixedValue = function (s) {
return /^-([A-Za-z0-9]|-)*$/gi.test(s);
-}
-function areSameFunction(a, b) {
- if (!isValidFunction(a) || !isValidFunction(b))
+};
+
+Validator.prototype.areSameFunction = function (a, b) {
+ if (!this.isValidFunction(a) || !this.isValidFunction(b))
return false;
var f1name = a.substring(0, a.indexOf('('));
var f2name = b.substring(0, b.indexOf('('));
return f1name === f2name;
-}
-
-module.exports = {
- isValidHexColor: isValidHexColor,
- isValidRgbaColor: isValidRgbaColor,
- isValidHslaColor: isValidHslaColor,
- isValidNamedColor: isValidNamedColor,
- isValidVariable: isValidVariable,
- isValidColor: isValidColor,
- isValidUrl: isValidUrl,
- isValidUnit: isValidUnit,
- isValidUnitWithoutFunction: isValidUnitWithoutFunction,
- isValidAndCompatibleUnit: isValidAndCompatibleUnit,
- isValidAndCompatibleUnitWithoutFunction: isValidAndCompatibleUnitWithoutFunction,
- isValidFunctionWithoutVendorPrefix: isValidFunctionWithoutVendorPrefix,
- isValidFunctionWithVendorPrefix: isValidFunctionWithVendorPrefix,
- isValidFunction: isValidFunction,
- isValidBackgroundRepeat: isValidBackgroundRepeat,
- isValidBackgroundAttachment: isValidBackgroundAttachment,
- isValidBackgroundBox: isValidBackgroundBox,
- isValidBackgroundPositionPart: isValidBackgroundPositionPart,
- isValidBackgroundPosition: isValidBackgroundPosition,
- isValidBackgroundSizePart: isValidBackgroundSizePart,
- isValidBackgroundPositionAndSize: isValidBackgroundPositionAndSize,
- isValidListStyleType: isValidListStyleType,
- isValidListStylePosition: isValidListStylePosition,
- isValidStyle: isValidStyle,
- isValidWidth: isValidWidth,
- isValidVendorPrefixedValue: isValidVendorPrefixedValue,
- areSameFunction: areSameFunction
};
+
+module.exports = Validator;
var stringifyBody = require('../../stringifier/one-time').body;
var stringifySelectors = require('../../stringifier/one-time').selectors;
-function AdvancedOptimizer(options) {
+function AdvancedOptimizer(options, context) {
this.options = options;
+ this.validator = context.validator;
}
function unsafeSelector(value) {
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, this.options);
+ optimizeProperties(token[1], lastToken[2], joinAt, true, this.options, this.validator);
token[2] = [];
} else if (lastToken[0] == 'selector' && stringifyBody(token[2]) == stringifyBody(lastToken[2]) &&
!this.isSpecial(stringifySelectors(token[1])) && !this.isSpecial(stringifySelectors(lastToken[1]))) {
joinsAt.push((joinsAt[j - 1] || 0) + bodiesAsList[j].length);
}
- optimizeProperties(selector, bodies, joinsAt, false, this.options);
+ optimizeProperties(selector, bodies, joinsAt, false, this.options, this.validator);
var processedCount = processedTokens.length;
var propertyIdx = bodies.length - 1;
Array.prototype.push.apply(target[2], moved[2]);
}
- optimizeProperties(target[1], target[2], joinAt, true, this.options);
+ optimizeProperties(target[1], target[2], joinAt, true, this.options, this.validator);
moved[2] = [];
}
}
}
};
-function recursivelyOptimizeProperties(tokens, options) {
+function recursivelyOptimizeProperties(tokens, options, validator) {
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);
+ optimizeProperties(token[1], token[2], false, true, options, validator);
break;
case 'block':
- recursivelyOptimizeProperties(token[2], options);
+ recursivelyOptimizeProperties(token[2], options, validator);
}
}
}
}
});
- recursivelyOptimizeProperties(tokens, self.options);
+ recursivelyOptimizeProperties(tokens, self.options, self.validator);
self.removeDuplicates(tokens);
self.mergeAdjacent(tokens);
]
}, { compatibility: { selectors: { adjacentSpace: true } } }),
'units - IE8 compatibility': cssContext({
- 'rems': 'div{padding-top:16px;padding-top:1rem}'
+ 'rems': 'div{padding-top:16px;color:red;padding-top:1rem}'
}, { compatibility: 'ie8' }),
'redefined more granular properties with property merging': cssContext({
'should merge background with background-attachment': [
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 breakUp = require('../../lib/properties/break-up');
function _breakUp(properties) {
+ var validator = new Validator(new Compatibility().toOptions());
var wrapped = wrapForOptimizing(properties);
- populateComponents(wrapped);
+ populateComponents(wrapped, validator);
return wrapped[0].components;
}
var Tokenizer = require('../../lib/selectors/tokenizer');
var SourceTracker = require('../../lib/utils/source-tracker');
var Compatibility = require('../../lib/utils/compatibility');
+var Validator = require('../../lib/properties/validator');
var addOptimizationMetadata = require('../../lib/selectors/optimization-metadata');
function _optimize(source) {
addOptimizationMetadata(tokens);
var compatibility = new Compatibility().toOptions();
- optimize(tokens[0][1], tokens[0][2], false, true, { compatibility: compatibility, aggressiveMerging: true, shorthandCompacting: true });
+ var validator = new Validator(compatibility);
+ optimize(tokens[0][1], tokens[0][2], false, true, { compatibility: compatibility, aggressiveMerging: true, shorthandCompacting: true }, validator);
return tokens[0][2];
}
var Tokenizer = require('../../lib/selectors/tokenizer');
var SourceTracker = require('../../lib/utils/source-tracker');
var Compatibility = require('../../lib/utils/compatibility');
+var Validator = require('../../lib/properties/validator');
var addOptimizationMetadata = require('../../lib/selectors/optimization-metadata');
var compatibility = new Compatibility().toOptions();
+var validator = new Validator(compatibility);
function _optimize(source, mergeAdjacent, aggressiveMerging) {
var tokens = new Tokenizer({
}).toTokens(source);
addOptimizationMetadata(tokens);
- optimize(tokens[0][1], tokens[0][2], mergeAdjacent, true, { compatibility: compatibility, aggressiveMerging: aggressiveMerging });
+ optimize(tokens[0][1], tokens[0][2], mergeAdjacent, true, { compatibility: compatibility, aggressiveMerging: aggressiveMerging }, validator);
return tokens[0][2];
}
var Tokenizer = require('../../lib/selectors/tokenizer');
var SourceTracker = require('../../lib/utils/source-tracker');
var Compatibility = require('../../lib/utils/compatibility');
+var Validator = require('../../lib/properties/validator');
var addOptimizationMetadata = require('../../lib/selectors/optimization-metadata');
function _optimize(source, compatibility, aggressiveMerging) {
}).toTokens(source);
compatibility = new Compatibility(compatibility).toOptions();
+ var validator = new Validator(compatibility);
var options = {
aggressiveMerging: undefined === aggressiveMerging ? true : aggressiveMerging,
compatibility: compatibility,
shorthandCompacting: true
};
addOptimizationMetadata(tokens);
- optimize(tokens[0][1], tokens[0][2], false, true, options);
+ optimize(tokens[0][1], tokens[0][2], false, true, options, validator);
return tokens[0][2];
}
]);
}
},
- 'multiplex longhand into multiplex shorthand123': {
+ '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), [
var restoreShorthands = require('../../lib/properties/restore-shorthands');
+var Compatibility = require('../../lib/utils/compatibility');
+var Validator = require('../../lib/properties/validator');
+
+var validator = new Validator(new Compatibility().toOptions());
+
vows.describe(restoreShorthands)
.addBatch({
'longhands': {
'topic': function () {
var properties = ['/*comment */', [['margin-top', false, false], ['0']]];
var _properties = wrapForOptimizing(properties);
- populateComponents(_properties);
+ populateComponents(_properties, validator);
restoreShorthands(_properties);
return properties;
'topic': function () {
var properties = ['/*comment */', [['background', false, false], ['url(image.png)']]];
var _properties = wrapForOptimizing(properties);
- populateComponents(_properties);
+ populateComponents(_properties, validator);
properties[1].pop();
_properties[0].dirty = true;
'topic': function () {
var properties = [[['background', false, false], ['url(image.png)']]];
var _properties = wrapForOptimizing(properties);
- populateComponents(_properties);
+ populateComponents(_properties, validator);
_properties[0].value = [];
_properties[0].dirty = true;
'topic': function () {
var properties = [[['background', false, false], ['url(image.png)']]];
var _properties = wrapForOptimizing(properties);
- populateComponents(_properties);
+ populateComponents(_properties, validator);
var cloned = shallowClone(_properties[0]);
cloned.components = _properties[0].components;
var wrapForOptimizing = require('../../lib/properties/wrap-for-optimizing').single;
var compactable = require('../../lib/properties/compactable');
+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 _property = wrapForOptimizing(property);
- _property.components = descriptor.breakUp(_property, compactable);
+ _property.components = descriptor.breakUp(_property, compactable, validator);
_property.multiplex = Array.isArray(_property.components[0].value[0][0]);
return _property;
}
var SelectorsOptimizer = require('../../lib/selectors/optimizer');
var stringify = require('../../lib/stringifier/simple');
var Compatibility = require('../../lib/utils/compatibility');
+var Validator = require('../../lib/properties/validator');
var SourceTracker = require('../../lib/utils/source-tracker');
function optimizerContext(group, specs, options) {
options.compatibility = new Compatibility(options.compatibility).toOptions();
var outerContext = {
options: {},
- sourceTracker: new SourceTracker()
+ sourceTracker: new SourceTracker(),
+ validator: new Validator(options.compatibility)
};
function optimized(target) {
]
]
],
- 'in properties123': [
+ 'in properties': [
'div{__ESCAPED_COMMENT_SPECIAL_CLEAN_CSS0(2,5)__background:__ESCAPED_URL_CLEAN_CSS0(0,20)__;color:blue}a{font-family:__ESCAPED_FREE_TEXT_CLEAN_CSS0(1,3)__;color:red}',
[
[