// Contains the interpretation of CSS properties, as used by the property optimizer var breakUp = require('./break-up'); var canOverride = require('./can-override'); var restore = require('./restore'); // Properties to process // Extend this object in order to add support for more properties in the optimizer. // // Each key in this object represents a CSS property and should be an object. // Such an object contains properties that describe how the represented CSS property should be handled. // Possible options: // // * components: array (Only specify for shorthand properties.) // Contains the names of the granular properties this shorthand compacts. // // * canOverride: function (Default is canOverride.sameValue - meaning that they'll only be merged if they have the same value.) // Returns whether two tokens of this property can be merged with each other. // This property has no meaning for shorthands. // // * defaultValue: string // Specifies the default value of the property according to the CSS standard. // For shorthand, this is used when every component is set to its default value, therefore it should be the shortest possible default value of all the components. // // * shortestValue: string // Specifies the shortest possible value the property can possibly have. // (Falls back to defaultValue if unspecified.) // // * breakUp: function (Only specify for shorthand properties.) // Breaks the shorthand up to its components. // // * restore: function (Only specify for shorthand properties.) // Puts the shorthand together from its components. // var compactable = { 'color': { canOverride: canOverride.color, defaultValue: 'transparent', shortestValue: 'red' }, 'background': { components: [ 'background-image', 'background-position', 'background-size', 'background-repeat', 'background-attachment', 'background-origin', 'background-clip', 'background-color' ], breakUp: breakUp.multiplex(breakUp.background), defaultValue: '0 0', restore: restore.multiplex(restore.background), shortestValue: '0', shorthand: true }, 'background-clip': { canOverride: canOverride.always, defaultValue: 'border-box', shortestValue: 'border-box' }, 'background-color': { canOverride: canOverride.color, defaultValue: 'transparent', multiplexLastOnly: true, nonMergeableValue: 'none', shortestValue: 'red' }, 'background-image': { canOverride: canOverride.backgroundImage, defaultValue: 'none' }, 'background-origin': { canOverride: canOverride.always, defaultValue: 'padding-box', shortestValue: 'border-box' }, 'background-repeat': { canOverride: canOverride.always, defaultValue: ['repeat'], doubleValues: true }, 'background-position': { canOverride: canOverride.alwaysButIntoFunction, defaultValue: ['0', '0'], doubleValues: true, shortestValue: '0' }, 'background-size': { canOverride: canOverride.alwaysButIntoFunction, defaultValue: ['auto'], doubleValues: true, shortestValue: '0 0' }, 'background-attachment': { canOverride: canOverride.always, defaultValue: 'scroll' }, 'border': { breakUp: breakUp.border, canOverride: canOverride.border, components: [ 'border-width', 'border-style', 'border-color' ], defaultValue: 'none', restore: restore.withoutDefaults, shorthand: true }, 'border-color': { canOverride: canOverride.color, defaultValue: 'none', shorthand: true }, 'border-style': { canOverride: canOverride.always, defaultValue: 'none', shorthand: true }, 'border-width': { canOverride: canOverride.unit, defaultValue: 'medium', shortestValue: '0', shorthand: true }, 'list-style': { components: [ 'list-style-type', 'list-style-position', 'list-style-image' ], canOverride: canOverride.always, breakUp: breakUp.listStyle, restore: restore.withoutDefaults, defaultValue: 'outside', // can't use 'disc' because that'd override default 'decimal' for <ol> shortestValue: 'none', shorthand: true }, 'list-style-type' : { canOverride: canOverride.always, defaultValue: '__hack', // NOTE: we can't tell the real default value here, it's 'disc' for <ul> and 'decimal' for <ol> // -- this is a hack, but it doesn't matter because this value will be either overridden or it will disappear at the final step anyway shortestValue: 'none' }, 'list-style-position' : { canOverride: canOverride.always, defaultValue: 'outside', shortestValue: 'inside' }, 'list-style-image' : { canOverride: canOverride.always, defaultValue: 'none' }, 'outline': { components: [ 'outline-color', 'outline-style', 'outline-width' ], breakUp: breakUp.outline, restore: restore.withoutDefaults, defaultValue: '0', shorthand: true }, 'outline-color': { canOverride: canOverride.color, defaultValue: 'invert', shortestValue: 'red' }, 'outline-style': { canOverride: canOverride.always, defaultValue: 'none' }, 'outline-width': { canOverride: canOverride.unit, defaultValue: 'medium', shortestValue: '0' }, '-moz-transform': { canOverride: canOverride.sameFunctionOrValue }, '-ms-transform': { canOverride: canOverride.sameFunctionOrValue }, '-webkit-transform': { canOverride: canOverride.sameFunctionOrValue }, 'transform': { canOverride: canOverride.sameFunctionOrValue } }; var addFourValueShorthand = function (prop, components, options) { options = options || {}; compactable[prop] = { canOverride: options.canOverride, components: components, breakUp: options.breakUp || breakUp.fourValues, defaultValue: options.defaultValue || '0', restore: options.restore || restore.fourValues, shortestValue: options.shortestValue, shorthand: true }; for (var i = 0; i < components.length; i++) { compactable[components[i]] = { breakUp: options.breakUp || breakUp.fourValues, canOverride: options.canOverride || canOverride.unit, defaultValue: options.defaultValue || '0', shortestValue: options.shortestValue }; } }; ['', '-moz-', '-o-'].forEach(function (prefix) { addFourValueShorthand(prefix + 'border-radius', [ prefix + 'border-top-left-radius', prefix + 'border-top-right-radius', prefix + 'border-bottom-right-radius', prefix + 'border-bottom-left-radius' ], { breakUp: breakUp.borderRadius, restore: restore.borderRadius }); }); addFourValueShorthand('border-color', [ 'border-top-color', 'border-right-color', 'border-bottom-color', 'border-left-color' ], { breakUp: breakUp.fourValues, canOverride: canOverride.color, defaultValue: 'none', shortestValue: 'red' }); addFourValueShorthand('border-style', [ 'border-top-style', 'border-right-style', 'border-bottom-style', 'border-left-style' ], { breakUp: breakUp.fourValues, canOverride: canOverride.always, defaultValue: 'none' }); addFourValueShorthand('border-width', [ 'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width' ], { defaultValue: 'medium', shortestValue: '0' }); addFourValueShorthand('padding', [ 'padding-top', 'padding-right', 'padding-bottom', 'padding-left' ]); addFourValueShorthand('margin', [ 'margin-top', 'margin-right', 'margin-bottom', 'margin-left' ]); // Adds `componentOf` field to all longhands for (var property in compactable) { if (compactable[property].shorthand) { for (var i = 0, l = compactable[property].components.length; i < l; i++) { compactable[compactable[property].components[i]].componentOf = property; } } } module.exports = compactable;