* `minify` method improved signature accepting a list of hashes for a predictable traversal;
* `selectorsSortingMethod` level 1 optimization allows `false` or `'none'` for disabling selector sorting;
* `fetch` option controlling a function for handling remote requests;
+* new `font` shorthand and `font-*` longhand optimizers;
## Constructor options
var formatPosition = require('../../utils/format-position');
+var FORWARD_SLASH = '/';
var MULTIPLEX_SEPARATOR = ',';
+function _anyIsInherit(values) {
+ var i, l;
+
+ for (i = 0, l = values.length; i < l; i++) {
+ if (values[i][1] == 'inherit') {
+ return true;
+ }
+ }
+
+ return false;
+}
+
function _colorFilter(validator) {
return function (value) {
return value[1] == 'invert' || validator.isValidColor(value[1]) || validator.isValidVendorPrefixedValue(value[1]);
return target.components;
}
+function font(property, compactable, validator) {
+ var style = _wrapDefault('font-style', property, compactable);
+ var variant = _wrapDefault('font-variant', property, compactable);
+ var weight = _wrapDefault('font-weight', property, compactable);
+ var stretch = _wrapDefault('font-stretch', property, compactable);
+ var size = _wrapDefault('font-size', property, compactable);
+ var height = _wrapDefault('line-height', property, compactable);
+ var family = _wrapDefault('font-family', property, compactable);
+ var components = [style, variant, weight, stretch, size, height, family];
+ var values = property.value;
+ var fuzzyMatched = 4; // style, variant, weight, and stretch
+ var index = 0;
+ var isStretchSet = false;
+ var isStretchValid;
+ var isStyleSet = false;
+ var isStyleValid;
+ var isVariantSet = false;
+ var isVariantValid;
+ var isWeightSet = false;
+ var isWeightValid;
+ var isSizeSet = false;
+ var appendableFamilyName = false;
+
+ if (!values[index]) {
+ throw new InvalidPropertyError('Missing font values at ' + formatPosition(property.all[property.position][1][2][0]) + '. Ignoring.');
+ }
+
+ if (values.length == 1 && values[0][1] == 'inherit') {
+ style.value = variant.value = weight.value = stretch.value = size.value = height.value = family.value = values;
+ return components;
+ }
+
+ if (values.length > 1 && _anyIsInherit(values)) {
+ throw new InvalidPropertyError('Invalid font values at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
+ }
+
+ // fuzzy match style, variant, weight, and stretch on first elements
+ while (index < fuzzyMatched) {
+ isStretchValid = validator.isValidKeywordValue('font-stretch', values[index][1], true);
+ isStyleValid = validator.isValidKeywordValue('font-style', values[index][1], true);
+ isVariantValid = validator.isValidKeywordValue('font-variant', values[index][1], true);
+ isWeightValid = validator.isValidKeywordValue('font-weight', values[index][1], true);
+
+ if (isStyleValid && !isStyleSet) {
+ style.value = [values[index]];
+ isStyleSet = true;
+ } else if (isVariantValid && !isVariantSet) {
+ variant.value = [values[index]];
+ isVariantSet = true;
+ } else if (isWeightValid && !isWeightSet) {
+ weight.value = [values[index]];
+ isWeightSet = true;
+ } else if (isStretchValid && !isStretchSet) {
+ stretch.value = [values[index]];
+ isStretchSet = true;
+ } else if (isStyleValid && isStyleSet || isVariantValid && isVariantSet || isWeightValid && isWeightSet || isStretchValid && isStretchSet) {
+ throw new InvalidPropertyError('Invalid font style / variant / weight / stretch value at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
+ } else {
+ break;
+ }
+
+ index++;
+ }
+
+ // now comes font-size ...
+ if (validator.isValidFontSize(values[index][1])) {
+ size.value = [values[index]];
+ isSizeSet = true;
+ index++;
+ } else {
+ throw new InvalidPropertyError('Missing font size at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
+ }
+
+ if (!values[index]) {
+ throw new InvalidPropertyError('Missing font family at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
+ }
+
+ // ... and perhaps line-height
+ if (isSizeSet && values[index] && values[index][1] == FORWARD_SLASH && values[index + 1] && validator.isValidLineHeight(values[index + 1][1])) {
+ height.value = [values[index + 1]];
+ index++;
+ index++;
+ }
+
+ // ... and whatever comes next is font-family
+ family.value = [];
+
+ while (values[index]) {
+ if (values[index][1] == MULTIPLEX_SEPARATOR) {
+ appendableFamilyName = false;
+ } else {
+ if (appendableFamilyName) {
+ family.value[family.value.length - 1][1] += ' ' + values[index][1];
+ } else {
+ family.value.push(values[index]);
+ }
+
+ appendableFamilyName = true;
+ }
+
+ index++;
+ }
+
+ if (family.value.length === 0) {
+ throw new InvalidPropertyError('Missing font family at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
+ }
+
+ return components;
+}
+
function fourValues(property, compactable) {
var componentNames = compactable[property.name].components;
var components = [];
background: background,
border: widthStyleColor,
borderRadius: borderRadius,
+ font: font,
fourValues: fourValues,
listStyle: listStyle,
multiplex: multiplex,
};
}
+function fontFamily(validator, value1, value2) {
+ return understandable(validator, value1, value2, 0, true);
+}
+
function image(validator, value1, value2) {
if (!understandable(validator, value1, value2, 0, true) && !validator.isValidImage(value2)) {
return false;
cursor: keywordWithGlobal('cursor'),
display: keywordWithGlobal('display'),
float: keywordWithGlobal('float'),
- fontStyle: keywordWithGlobal('font-style'),
left: unitOrKeywordWithGlobal('left'),
+ fontFamily: fontFamily,
+ fontStretch: keywordWithGlobal('font-stretch'),
+ fontStyle: keywordWithGlobal('font-style'),
+ fontVariant: keywordWithGlobal('font-variant'),
fontWeight: keywordWithGlobal('font-weight'),
listStyleType: keywordWithGlobal('list-style-type'),
listStylePosition: keywordWithGlobal('list-style-position'),
canOverride: canOverride.property.float,
defaultValue: 'none'
},
+ 'font': {
+ breakUp: breakUp.font,
+ canOverride: canOverride.generic.components([
+ canOverride.property.fontStyle,
+ canOverride.property.fontVariant,
+ canOverride.property.fontWeight,
+ canOverride.property.fontStretch,
+ canOverride.generic.unit,
+ canOverride.generic.unit,
+ canOverride.property.fontFamily
+ ]),
+ components: [
+ 'font-style',
+ 'font-variant',
+ 'font-weight',
+ 'font-stretch',
+ 'font-size',
+ 'line-height',
+ 'font-family'
+ ],
+ restore: restore.font,
+ shorthand: true
+ },
+ 'font-family': {
+ canOverride: canOverride.property.fontFamily,
+ defaultValue: 'user|agent|specific'
+ },
'font-size': {
canOverride: canOverride.generic.unit,
defaultValue: 'medium',
shortestValue: '0'
},
+ 'font-stretch': {
+ canOverride: canOverride.property.fontStretch,
+ defaultValue: 'normal'
+ },
'font-style': {
canOverride: canOverride.property.fontStyle,
defaultValue: 'normal'
},
+ 'font-variant': {
+ canOverride: canOverride.property.fontVariant,
+ defaultValue: 'normal'
+ },
'font-weight': {
canOverride: canOverride.property.fontWeight,
- defaultValue: '400',
+ defaultValue: 'normal',
shortestValue: '400'
},
'height': {
}
}
+function font(property, compactable) {
+ var components = property.components;
+ var restored = [];
+ var component;
+ var componentIndex = 0;
+ var fontFamilyIndex = 0;
+
+ // first four components are optional
+ while (componentIndex < 4) {
+ component = components[componentIndex];
+
+ if (component.value[0][1] != compactable[component.name].defaultValue) {
+ Array.prototype.push.apply(restored, component.value);
+ }
+
+ componentIndex++;
+ }
+
+ // then comes font-size
+ Array.prototype.push.apply(restored, components[componentIndex].value);
+ componentIndex++;
+
+ // then may come line-height
+ if (components[componentIndex].value[0][1] != compactable[components[componentIndex].name].defaultValue) {
+ Array.prototype.push.apply(restored, [[Token.PROPERTY_VALUE, Marker.FORWARD_SLASH]]);
+ Array.prototype.push.apply(restored, components[componentIndex].value);
+ }
+
+ componentIndex++;
+
+ // then comes font-family
+ while (components[componentIndex].value[fontFamilyIndex]) {
+ restored.push(components[componentIndex].value[fontFamilyIndex]);
+
+ if (components[componentIndex].value[fontFamilyIndex + 1]) {
+ restored.push([Token.PROPERTY_VALUE, Marker.COMMA]);
+ }
+
+ fontFamilyIndex++;
+ }
+
+ if (isInheritOnly(restored)) {
+ return [restored[0]];
+ }
+
+ return restored;
+}
+
function fourValues(property) {
var components = property.components;
var value1 = components[0].value[0];
module.exports = {
background: background,
borderRadius: borderRadius,
+ font: font,
fourValues: fourValues,
multiplex: multiplex,
withoutDefaults: withoutDefaults
'left': [
'auto'
],
+ 'font-size': [
+ 'large',
+ 'larger',
+ 'medium',
+ 'small',
+ 'smaller',
+ 'x-large',
+ 'x-small',
+ 'xx-large',
+ 'xx-small'
+ ],
+ 'font-stretch': [
+ 'condensed',
+ 'expanded',
+ 'extra-condensed',
+ 'extra-expanded',
+ 'normal',
+ 'semi-condensed',
+ 'semi-expanded',
+ 'ultra-condensed',
+ 'ultra-expanded'
+ ],
'font-style': [
'italic',
'normal',
'oblique'
],
+ 'font-variant': [
+ 'normal',
+ 'small-caps'
+ ],
'font-weight': [
'100',
'200',
'lighter',
'normal'
],
+ 'line-height': [
+ 'normal'
+ ],
'list-style-position': [
'inside',
'outside'
isValidHslaColor(value);
}
+function isValidFontSize(compatibleCssUnitRegex, value) {
+ return isValidUnit(compatibleCssUnitRegex, value) || Keywords['font-size'].indexOf(value) > -1;
+}
+
function isValidFunction(value) {
return !urlRegex.test(value) && cssFunctionAnyRegex.test(value);
}
return Keywords[propertyName].indexOf(value) > -1 || includeGlobal && isValidGlobalValue(value);
}
+function isValidLineHeight(compatibleCssUnitRegex, value) {
+ return isValidUnit(compatibleCssUnitRegex, value) || isValidNumber(value) || Keywords['line-height'].indexOf(value) > -1;
+}
+
function isValidListStyleType(value) {
return Keywords['list-style-type'].indexOf(value) > -1;
}
return value !== 'auto' && (value === 'transparent' || value === 'inherit' || /^[a-zA-Z]+$/.test(value));
}
+function isValidNumber(value) {
+ return ('' + parseFloat(value)) === value;
+}
+
function isValidRgbaColor(value) {
return value.length > 0 && value.indexOf('rgba(') === 0 && value.indexOf(')') === value.length - 1;
}
isValidBackgroundSizePart: isValidBackgroundSizePart,
isValidColor: isValidColor,
isValidColorValue: isValidColorValue,
+ isValidFontSize: isValidFontSize.bind(null, compatibleCssUnitRegex),
isValidFunction: isValidFunction,
isValidFunctionWithoutVendorPrefix: isValidFunctionWithoutVendorPrefix,
isValidGlobalValue: isValidGlobalValue,
isValidHslaColor: isValidHslaColor,
isValidImage: isValidImage,
isValidKeywordValue: isValidKeywordValue,
+ isValidLineHeight: isValidLineHeight.bind(null, compatibleCssUnitRegex),
isValidListStylePosition: isValidListStylePosition,
isValidListStyleType: isValidListStyleType,
isValidNamedColor: isValidNamedColor,
sub,sup{line-height:0}
abbr,acronym{border-bottom:1px dotted #666}
pre{margin:1.5em 0;white-space:pre}
-code,pre,tt{font:1em 'andale mono','lucida console',monospace;line-height:1.5}
+code,pre,tt{font:1em/1.5 'andale mono','lucida console',monospace}
label,legend{font-weight:700}
ol,ul{margin:0 1.5em 1.5em 0;padding-left:1.5em}
ul{list-style-type:disc}
hr{background:#ddd;color:#ddd;float:none;height:1px;margin:0 0 1.45em;border:none}
hr.space{color:#fff;visibility:hidden}
.clearfix:after,.container:after{content:"\0020";display:block;height:0;clear:both;visibility:hidden;overflow:hidden}
-.clearfix,.container{display:block}
\ No newline at end of file
+.clearfix,.container{display:block}
img{border:0}
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}
-code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}
+code,kbd,pre,samp{font-size:1em}
button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}
.glyphicon,address{font-style:normal}
button{overflow:visible}
@media print{
.visible-print-inline-block{display:inline-block!important}
.hidden-print{display:none!important}
-}
\ No newline at end of file
+}
}
}
},
+ 'font': {
+ 'all values': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'italic'],
+ ['property-value', 'small-caps'],
+ ['property-value', 'bold'],
+ ['property-value', 'normal'],
+ ['property-value', '18px'],
+ ['property-value', '/'],
+ ['property-value', '16px'],
+ ['property-value', 'sans-serif']
+ ]
+ ]);
+ },
+ 'has 7 components': function (components) {
+ assert.lengthOf(components, 7);
+ },
+ 'has font-style': function (components) {
+ assert.equal(components[0].name, 'font-style');
+ assert.deepEqual(components[0].value, [['property-value', 'italic']]);
+ },
+ 'has font-variant': function (components) {
+ assert.equal(components[1].name, 'font-variant');
+ assert.deepEqual(components[1].value, [['property-value', 'small-caps']]);
+ },
+ 'has font-weight': function (components) {
+ assert.equal(components[2].name, 'font-weight');
+ assert.deepEqual(components[2].value, [['property-value', 'bold']]);
+ },
+ 'has font-stretch': function (components) {
+ assert.equal(components[3].name, 'font-stretch');
+ assert.deepEqual(components[3].value, [['property-value', 'normal']]);
+ },
+ 'has font-size': function (components) {
+ assert.equal(components[4].name, 'font-size');
+ assert.deepEqual(components[4].value, [['property-value', '18px']]);
+ },
+ 'has line-height': function (components) {
+ assert.equal(components[5].name, 'line-height');
+ assert.deepEqual(components[5].value, [['property-value', '16px']]);
+ },
+ 'has font-family': function (components) {
+ assert.equal(components[6].name, 'font-family');
+ assert.deepEqual(components[6].value, [['property-value', 'sans-serif']]);
+ }
+ },
+ 'multiple font-family': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'italic'],
+ ['property-value', 'small-caps'],
+ ['property-value', 'bold'],
+ ['property-value', 'normal'],
+ ['property-value', '18px'],
+ ['property-value', '/'],
+ ['property-value', '16px'],
+ ['property-value', 'Helvetica'],
+ ['property-value', ','],
+ ['property-value', 'Arial'],
+ ['property-value', ','],
+ ['property-value', 'sans-serif']
+ ]
+ ]);
+ },
+ 'has all font-family': function (components) {
+ assert.equal(components[6].name, 'font-family');
+ assert.deepEqual(components[6].value, [['property-value', 'Helvetica'], ['property-value', 'Arial'], ['property-value', 'sans-serif']]);
+ }
+ },
+ 'no line-height': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'italic'],
+ ['property-value', 'small-caps'],
+ ['property-value', 'bold'],
+ ['property-value', 'normal'],
+ ['property-value', '18px'],
+ ['property-value', 'sans-serif']
+ ]
+ ]);
+ },
+ 'has 7 components': function (components) {
+ assert.lengthOf(components, 7);
+ },
+ 'has font-size': function (components) {
+ assert.equal(components[4].name, 'font-size');
+ assert.deepEqual(components[4].value, [['property-value', '18px']]);
+ },
+ 'has line-height': function (components) {
+ assert.equal(components[5].name, 'line-height');
+ assert.deepEqual(components[5].value, [['property-value', 'normal']]);
+ },
+ 'has font-family': function (components) {
+ assert.equal(components[6].name, 'font-family');
+ assert.deepEqual(components[6].value, [['property-value', 'sans-serif']]);
+ }
+ },
+ 'no line-height or fuzzy matched properties': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', '18px'],
+ ['property-value', 'sans-serif']
+ ]
+ ]);
+ },
+ 'has 7 components': function (components) {
+ assert.lengthOf(components, 7);
+ },
+ 'has font-style': function (components) {
+ assert.equal(components[0].name, 'font-style');
+ assert.deepEqual(components[0].value, [['property-value', 'normal']]);
+ },
+ 'has font-variant': function (components) {
+ assert.equal(components[1].name, 'font-variant');
+ assert.deepEqual(components[1].value, [['property-value', 'normal']]);
+ },
+ 'has font-weight': function (components) {
+ assert.equal(components[2].name, 'font-weight');
+ assert.deepEqual(components[2].value, [['property-value', 'normal']]);
+ },
+ 'has font-stretch': function (components) {
+ assert.equal(components[3].name, 'font-stretch');
+ assert.deepEqual(components[3].value, [['property-value', 'normal']]);
+ },
+ 'has font-size': function (components) {
+ assert.equal(components[4].name, 'font-size');
+ assert.deepEqual(components[4].value, [['property-value', '18px']]);
+ },
+ 'has line-height': function (components) {
+ assert.equal(components[5].name, 'line-height');
+ assert.deepEqual(components[5].value, [['property-value', 'normal']]);
+ },
+ 'has font-family': function (components) {
+ assert.equal(components[6].name, 'font-family');
+ assert.deepEqual(components[6].value, [['property-value', 'sans-serif']]);
+ }
+ },
+ 'some fuzzy matched properties #1': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'bold'],
+ ['property-value', 'small-caps'],
+ ['property-value', '18px'],
+ ['property-value', 'sans-serif']
+ ]
+ ]);
+ },
+ 'has 7 components': function (components) {
+ assert.lengthOf(components, 7);
+ },
+ 'has font-style': function (components) {
+ assert.equal(components[0].name, 'font-style');
+ assert.deepEqual(components[0].value, [['property-value', 'normal']]);
+ },
+ 'has font-variant': function (components) {
+ assert.equal(components[1].name, 'font-variant');
+ assert.deepEqual(components[1].value, [['property-value', 'small-caps']]);
+ },
+ 'has font-weight': function (components) {
+ assert.equal(components[2].name, 'font-weight');
+ assert.deepEqual(components[2].value, [['property-value', 'bold']]);
+ },
+ 'has font-stretch': function (components) {
+ assert.equal(components[3].name, 'font-stretch');
+ assert.deepEqual(components[3].value, [['property-value', 'normal']]);
+ }
+ },
+ 'some fuzzy matched properties #2': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'ultra-condensed'],
+ ['property-value', 'italic'],
+ ['property-value', '18px'],
+ ['property-value', 'sans-serif']
+ ]
+ ]);
+ },
+ 'has 7 components': function (components) {
+ assert.lengthOf(components, 7);
+ },
+ 'has font-style': function (components) {
+ assert.equal(components[0].name, 'font-style');
+ assert.deepEqual(components[0].value, [['property-value', 'italic']]);
+ },
+ 'has font-variant': function (components) {
+ assert.equal(components[1].name, 'font-variant');
+ assert.deepEqual(components[1].value, [['property-value', 'normal']]);
+ },
+ 'has font-weight': function (components) {
+ assert.equal(components[2].name, 'font-weight');
+ assert.deepEqual(components[2].value, [['property-value', 'normal']]);
+ },
+ 'has font-stretch': function (components) {
+ assert.equal(components[3].name, 'font-stretch');
+ assert.deepEqual(components[3].value, [['property-value', 'ultra-condensed']]);
+ }
+ },
+ 'repeated fuzzy matched value': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'italic', [[0, 13, undefined]]],
+ ['property-value', 'italic'],
+ ['property-value', '18px'],
+ ['property-value', 'sans-serif']
+ ]
+ ]);
+ },
+ 'has 0 components': function (components) {
+ assert.lengthOf(components, 0);
+ }
+ },
+ 'line-height and font-size as functions': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'calc(27px / 2)', [[0, 13, undefined]]],
+ ['property-value', '/'],
+ ['property-value', 'calc(31px / 2)'],
+ ['property-value', 'sans-serif']
+ ]
+ ]);
+ },
+ 'has 0 components': function (components) {
+ assert.lengthOf(components, 0);
+ }
+ },
+ 'missing font size value': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'italic', [[0, 13, undefined]]],
+ ['property-value', 'sans-serif']
+ ]
+ ]);
+ },
+ 'has 0 components': function (components) {
+ assert.lengthOf(components, 0);
+ }
+ },
+ 'missing font family value': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'italic', [[0, 13, undefined]]],
+ ['property-value', '12px']
+ ]
+ ]);
+ },
+ 'has 0 components': function (components) {
+ assert.lengthOf(components, 0);
+ }
+ },
+ 'missing font family value after line height': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'italic', [[0, 13, undefined]]],
+ ['property-value', '12px'],
+ ['property-value', '/'],
+ ['property-value', '12px']
+ ]
+ ]);
+ },
+ 'has 0 components': function (components) {
+ assert.lengthOf(components, 0);
+ }
+ },
+ 'missing font family when only commas given': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'italic', [[0, 13, undefined]]],
+ ['property-value', '12px'],
+ ['property-value', ','],
+ ['property-value', ',']
+ ]
+ ]);
+ },
+ 'has 0 components': function (components) {
+ assert.lengthOf(components, 0);
+ }
+ },
+ 'missing all values': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font', [[0, 13, undefined]]]
+ ]
+ ]);
+ },
+ 'has 0 components': function (components) {
+ assert.lengthOf(components, 0);
+ }
+ },
+ 'values after font family': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', '12px'],
+ ['property-value', 'Helvetica'],
+ ['property-value', ','],
+ ['property-value', 'sans-serif'],
+ ['property-value', 'italic']
+ ]
+ ]);
+ },
+ 'has 7 components': function (components) {
+ assert.lengthOf(components, 7);
+ },
+ 'has font-family': function (components) {
+ assert.equal(components[6].name, 'font-family');
+ assert.deepEqual(components[6].value, [['property-value', 'Helvetica'], ['property-value', 'sans-serif italic']]);
+ }
+ },
+ 'single inherit': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'inherit']
+ ]
+ ]);
+ },
+ 'has 7 components': function (components) {
+ assert.lengthOf(components, 7);
+ },
+ 'has font-style': function (components) {
+ assert.equal(components[0].name, 'font-style');
+ assert.deepEqual(components[0].value, [['property-value', 'inherit']]);
+ },
+ 'has font-variant': function (components) {
+ assert.equal(components[1].name, 'font-variant');
+ assert.deepEqual(components[1].value, [['property-value', 'inherit']]);
+ },
+ 'has font-weight': function (components) {
+ assert.equal(components[2].name, 'font-weight');
+ assert.deepEqual(components[2].value, [['property-value', 'inherit']]);
+ },
+ 'has font-stretch': function (components) {
+ assert.equal(components[3].name, 'font-stretch');
+ assert.deepEqual(components[3].value, [['property-value', 'inherit']]);
+ },
+ 'has font-size': function (components) {
+ assert.equal(components[4].name, 'font-size');
+ assert.deepEqual(components[4].value, [['property-value', 'inherit']]);
+ },
+ 'has line-height': function (components) {
+ assert.equal(components[5].name, 'line-height');
+ assert.deepEqual(components[5].value, [['property-value', 'inherit']]);
+ },
+ 'has font-family': function (components) {
+ assert.equal(components[6].name, 'font-family');
+ assert.deepEqual(components[6].value, [['property-value', 'inherit']]);
+ }
+ },
+ 'multiple inherit': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'inherit', [[0, 13, undefined]]],
+ ['property-value', 'inherit']
+ ]
+ ]);
+ },
+ 'has 0 components': function (components) {
+ assert.lengthOf(components, 0);
+ }
+ },
+ 'mixed inherit #1': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'inherit', [[0, 13, undefined]]],
+ ['property-value', '12px'],
+ ['property-value', 'sans-serif']
+ ]
+ ]);
+ },
+ 'has 0 components': function (components) {
+ assert.lengthOf(components, 0);
+ }
+ },
+ 'mixed inherit #2': {
+ 'topic': function () {
+ return _breakUp([
+ [
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'bold', [[0, 13, undefined]]],
+ ['property-value', 'inherit'],
+ ['property-value', '12px'],
+ ['property-value', 'sans-serif']
+ ]
+ ]);
+ },
+ 'has 0 components': function (components) {
+ assert.lengthOf(components, 0);
+ }
+ }
+ },
'four values': {
'four given': {
'topic': function () {
}
}
})
+ .addBatch({
+ 'font shorthand and longhand': {
+ 'topic': function () {
+ return _optimize('.block{font:12px sans-serif;font-weight:bold}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'font', [[1, 7, undefined]]],
+ ['property-value', 'bold', [[1, 40, undefined]]],
+ ['property-value', '12px', [[1, 12, undefined]]],
+ ['property-value', 'sans-serif', [[1, 17, undefined]]]
+ ]
+ ]);
+ }
+ },
+ 'font shorthand and line-height': {
+ 'topic': function () {
+ return _optimize('.block{font:12px sans-serif;line-height:16px}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'font', [[1, 7, undefined]]],
+ ['property-value', '12px', [[1, 12, undefined]]],
+ ['property-value', '/'],
+ ['property-value', '16px', [[1, 40, undefined]]],
+ ['property-value', 'sans-serif', [[1, 17, undefined]]]
+ ]
+ ]);
+ }
+ },
+ 'font longhand and shorthand': {
+ 'topic': function () {
+ return _optimize('.block{font-stretch:extra-condensed;font:12px sans-serif}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'font', [[1, 36, undefined]]],
+ ['property-value', '12px', [[1, 41, undefined]]],
+ ['property-value', 'sans-serif', [[1, 46, undefined]]]
+ ]
+ ]);
+ }
+ },
+ 'font shorthand with overriddable shorthand': {
+ 'topic': function () {
+ return _optimize('.block{font:bold 14px serif;font:12px sans-serif}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'font', [[1, 7, undefined]]],
+ ['property-value', '12px', [[1, 33, undefined]]],
+ ['property-value', 'sans-serif', [[1, 38, undefined]]]
+ ]
+ ]);
+ }
+ },
+ 'font shorthand with non-overriddable shorthand': {
+ 'topic': function () {
+ return _optimize('.block{font:bold 14px serif;font:16px -moz-sans-serif}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'font', [[1, 7, undefined]]],
+ ['property-value', 'bold', [[1, 12, undefined]]],
+ ['property-value', '14px', [[1, 17, undefined]]],
+ ['property-value', 'serif', [[1, 22, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'font', [[1, 28, undefined]]],
+ ['property-value', '16px', [[1, 33, undefined]]],
+ ['property-value', '-moz-sans-serif', [[1, 38, undefined]]]
+ ]
+ ]);
+ }
+ },
+ 'font shorthand after non-component longhands': {
+ 'topic': function () {
+ return _optimize('.block{font-kerning:none;font-synthesis:none;font:14px serif}');
+ },
+ 'into': function (properties) {
+ assert.deepEqual(properties, [
+ [
+ 'property',
+ ['property-name', 'font-kerning', [[1, 7, undefined]]],
+ ['property-value', 'none', [[1, 20, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'font-synthesis', [[1, 25, undefined]]],
+ ['property-value', 'none', [[1, 40, undefined]]]
+ ],
+ [
+ 'property',
+ ['property-name', 'font', [[1, 45, undefined]]],
+ ['property-value', '14px', [[1, 50, undefined]]],
+ ['property-value', 'serif', [[1, 55, undefined]]]
+ ]
+ ]);
+ }
+ }
+ })
.addBatch({
'padding !important then not !important': {
'topic': function () {
]);
}
},
+ 'font with all non-default values': {
+ 'topic': function () {
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'italic'],
+ ['property-value', 'small-caps'],
+ ['property-value', 'bold'],
+ ['property-value', 'ultra-condensed'],
+ ['property-value', '12px'],
+ ['property-value', '/'],
+ ['property-value', '16px'],
+ ['property-value', 'sans-serif']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'italic'],
+ ['property-value', 'small-caps'],
+ ['property-value', 'bold'],
+ ['property-value', 'ultra-condensed'],
+ ['property-value', '12px'],
+ ['property-value', '/'],
+ ['property-value', '16px'],
+ ['property-value', 'sans-serif']
+ ]);
+ }
+ },
+ 'font with some default values': {
+ 'topic': function () {
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'normal'],
+ ['property-value', 'small-caps'],
+ ['property-value', 'normal'],
+ ['property-value', 'ultra-condensed'],
+ ['property-value', '12px'],
+ ['property-value', '/'],
+ ['property-value', '16px'],
+ ['property-value', 'sans-serif']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'small-caps'],
+ ['property-value', 'ultra-condensed'],
+ ['property-value', '12px'],
+ ['property-value', '/'],
+ ['property-value', '16px'],
+ ['property-value', 'sans-serif']
+ ]);
+ }
+ },
+ 'font without line height': {
+ 'topic': function () {
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', '12px'],
+ ['property-value', 'sans-serif']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', '12px'],
+ ['property-value', 'sans-serif']
+ ]);
+ }
+ },
+ 'font with multiple font family values': {
+ 'topic': function () {
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', '12px'],
+ ['property-value', '"Helvetica Neue"'],
+ ['property-value', ','],
+ ['property-value', 'Helvetica'],
+ ['property-value', ','],
+ ['property-value', 'sans-serif']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', '12px'],
+ ['property-value', '"Helvetica Neue"'],
+ ['property-value', ','],
+ ['property-value', 'Helvetica'],
+ ['property-value', ','],
+ ['property-value', 'sans-serif']
+ ]);
+ }
+ },
+ 'font with inherit': {
+ 'topic': function () {
+ return _restore(
+ _breakUp([
+ 'property',
+ ['property-name', 'font'],
+ ['property-value', 'inherit']
+ ])
+ );
+ },
+ 'gives right value back': function (restoredValue) {
+ assert.deepEqual(restoredValue, [
+ ['property-value', 'inherit']
+ ]);
+ }
+ },
'list with some values': {
'topic': function () {
return _restore(