// 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'); var override = require('../../utils/override'); // 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 // 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 = { animation: { canOverride: canOverride.generic.components([ canOverride.generic.time, canOverride.generic.timingFunction, canOverride.generic.time, canOverride.property.animationIterationCount, canOverride.property.animationDirection, canOverride.property.animationFillMode, canOverride.property.animationPlayState, canOverride.property.animationName, ]), components: [ 'animation-duration', 'animation-timing-function', 'animation-delay', 'animation-iteration-count', 'animation-direction', 'animation-fill-mode', 'animation-play-state', 'animation-name', ], breakUp: breakUp.multiplex(breakUp.animation), defaultValue: 'none', restore: restore.multiplex(restore.withoutDefaults), shorthand: true, vendorPrefixes: ['-moz-', '-o-', '-webkit-'], }, 'animation-delay': { canOverride: canOverride.generic.time, componentOf: ['animation'], defaultValue: '0s', intoMultiplexMode: 'real', vendorPrefixes: ['-moz-', '-o-', '-webkit-'], }, 'animation-direction': { canOverride: canOverride.property.animationDirection, componentOf: ['animation'], defaultValue: 'normal', intoMultiplexMode: 'real', vendorPrefixes: ['-moz-', '-o-', '-webkit-'], }, 'animation-duration': { canOverride: canOverride.generic.time, componentOf: ['animation'], defaultValue: '0s', intoMultiplexMode: 'real', keepUnlessDefault: 'animation-delay', vendorPrefixes: ['-moz-', '-o-', '-webkit-'], }, 'animation-fill-mode': { canOverride: canOverride.property.animationFillMode, componentOf: ['animation'], defaultValue: 'none', intoMultiplexMode: 'real', vendorPrefixes: ['-moz-', '-o-', '-webkit-'], }, 'animation-iteration-count': { canOverride: canOverride.property.animationIterationCount, componentOf: ['animation'], defaultValue: '1', intoMultiplexMode: 'real', vendorPrefixes: ['-moz-', '-o-', '-webkit-'], }, 'animation-name': { canOverride: canOverride.property.animationName, componentOf: ['animation'], defaultValue: 'none', intoMultiplexMode: 'real', vendorPrefixes: ['-moz-', '-o-', '-webkit-'], }, 'animation-play-state': { canOverride: canOverride.property.animationPlayState, componentOf: ['animation'], defaultValue: 'running', intoMultiplexMode: 'real', vendorPrefixes: ['-moz-', '-o-', '-webkit-'], }, 'animation-timing-function': { canOverride: canOverride.generic.timingFunction, componentOf: ['animation'], defaultValue: 'ease', intoMultiplexMode: 'real', vendorPrefixes: ['-moz-', '-o-', '-webkit-'], }, background: { canOverride: canOverride.generic.components([ canOverride.generic.image, canOverride.property.backgroundPosition, canOverride.property.backgroundSize, canOverride.property.backgroundRepeat, canOverride.property.backgroundAttachment, canOverride.property.backgroundOrigin, canOverride.property.backgroundClip, canOverride.generic.color, ]), 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-attachment': { canOverride: canOverride.property.backgroundAttachment, componentOf: ['background'], defaultValue: 'scroll', intoMultiplexMode: 'real', }, 'background-clip': { canOverride: canOverride.property.backgroundClip, componentOf: ['background'], defaultValue: 'border-box', intoMultiplexMode: 'real', shortestValue: 'border-box', }, 'background-color': { canOverride: canOverride.generic.color, componentOf: ['background'], defaultValue: 'transparent', intoMultiplexMode: 'real', // otherwise real color will turn into default since color appears in last multiplex only multiplexLastOnly: true, nonMergeableValue: 'none', shortestValue: 'red', }, 'background-image': { canOverride: canOverride.generic.image, componentOf: ['background'], defaultValue: 'none', intoMultiplexMode: 'default', }, 'background-origin': { canOverride: canOverride.property.backgroundOrigin, componentOf: ['background'], defaultValue: 'padding-box', intoMultiplexMode: 'real', shortestValue: 'border-box', }, 'background-position': { canOverride: canOverride.property.backgroundPosition, componentOf: ['background'], defaultValue: ['0', '0'], doubleValues: true, intoMultiplexMode: 'real', shortestValue: '0', }, 'background-repeat': { canOverride: canOverride.property.backgroundRepeat, componentOf: ['background'], defaultValue: ['repeat'], doubleValues: true, intoMultiplexMode: 'real', }, 'background-size': { canOverride: canOverride.property.backgroundSize, componentOf: ['background'], defaultValue: ['auto'], doubleValues: true, intoMultiplexMode: 'real', shortestValue: '0 0', }, bottom: { canOverride: canOverride.property.bottom, defaultValue: 'auto', }, border: { breakUp: breakUp.border, canOverride: canOverride.generic.components([ canOverride.generic.unit, canOverride.property.borderStyle, canOverride.generic.color, ]), components: ['border-width', 'border-style', 'border-color'], defaultValue: 'none', overridesShorthands: [ 'border-bottom', 'border-left', 'border-right', 'border-top', ], restore: restore.withoutDefaults, shorthand: true, shorthandComponents: true, }, 'border-bottom': { breakUp: breakUp.border, canOverride: canOverride.generic.components([ canOverride.generic.unit, canOverride.property.borderStyle, canOverride.generic.color, ]), components: [ 'border-bottom-width', 'border-bottom-style', 'border-bottom-color', ], defaultValue: 'none', restore: restore.withoutDefaults, shorthand: true, }, 'border-bottom-color': { canOverride: canOverride.generic.color, componentOf: ['border-bottom', 'border-color'], defaultValue: 'none', }, 'border-bottom-left-radius': { canOverride: canOverride.generic.unit, componentOf: ['border-radius'], defaultValue: '0', vendorPrefixes: ['-moz-', '-o-'], }, 'border-bottom-right-radius': { canOverride: canOverride.generic.unit, componentOf: ['border-radius'], defaultValue: '0', vendorPrefixes: ['-moz-', '-o-'], }, 'border-bottom-style': { canOverride: canOverride.property.borderStyle, componentOf: ['border-bottom', 'border-style'], defaultValue: 'none', }, 'border-bottom-width': { canOverride: canOverride.generic.unit, componentOf: ['border-bottom', 'border-width'], defaultValue: 'medium', oppositeTo: 'border-top-width', shortestValue: '0', }, 'border-collapse': { canOverride: canOverride.property.borderCollapse, defaultValue: 'separate', }, 'border-color': { breakUp: breakUp.fourValues, canOverride: canOverride.generic.components([ canOverride.generic.color, canOverride.generic.color, canOverride.generic.color, canOverride.generic.color, ]), componentOf: ['border'], components: [ 'border-top-color', 'border-right-color', 'border-bottom-color', 'border-left-color', ], defaultValue: 'none', restore: restore.fourValues, shortestValue: 'red', shorthand: true, }, 'border-left': { breakUp: breakUp.border, canOverride: canOverride.generic.components([ canOverride.generic.unit, canOverride.property.borderStyle, canOverride.generic.color, ]), components: ['border-left-width', 'border-left-style', 'border-left-color'], defaultValue: 'none', restore: restore.withoutDefaults, shorthand: true, }, 'border-left-color': { canOverride: canOverride.generic.color, componentOf: ['border-color', 'border-left'], defaultValue: 'none', }, 'border-left-style': { canOverride: canOverride.property.borderStyle, componentOf: ['border-left', 'border-style'], defaultValue: 'none', }, 'border-left-width': { canOverride: canOverride.generic.unit, componentOf: ['border-left', 'border-width'], defaultValue: 'medium', oppositeTo: 'border-right-width', shortestValue: '0', }, 'border-radius': { breakUp: breakUp.borderRadius, canOverride: canOverride.generic.components([ canOverride.generic.unit, canOverride.generic.unit, canOverride.generic.unit, canOverride.generic.unit, ]), components: [ 'border-top-left-radius', 'border-top-right-radius', 'border-bottom-right-radius', 'border-bottom-left-radius', ], defaultValue: '0', restore: restore.borderRadius, shorthand: true, vendorPrefixes: ['-moz-', '-o-'], }, 'border-right': { breakUp: breakUp.border, canOverride: canOverride.generic.components([ canOverride.generic.unit, canOverride.property.borderStyle, canOverride.generic.color, ]), components: [ 'border-right-width', 'border-right-style', 'border-right-color', ], defaultValue: 'none', restore: restore.withoutDefaults, shorthand: true, }, 'border-right-color': { canOverride: canOverride.generic.color, componentOf: ['border-color', 'border-right'], defaultValue: 'none', }, 'border-right-style': { canOverride: canOverride.property.borderStyle, componentOf: ['border-right', 'border-style'], defaultValue: 'none', }, 'border-right-width': { canOverride: canOverride.generic.unit, componentOf: ['border-right', 'border-width'], defaultValue: 'medium', oppositeTo: 'border-left-width', shortestValue: '0', }, 'border-style': { breakUp: breakUp.fourValues, canOverride: canOverride.generic.components([ canOverride.property.borderStyle, canOverride.property.borderStyle, canOverride.property.borderStyle, canOverride.property.borderStyle, ]), componentOf: ['border'], components: [ 'border-top-style', 'border-right-style', 'border-bottom-style', 'border-left-style', ], defaultValue: 'none', restore: restore.fourValues, shorthand: true, }, 'border-top': { breakUp: breakUp.border, canOverride: canOverride.generic.components([ canOverride.generic.unit, canOverride.property.borderStyle, canOverride.generic.color, ]), components: ['border-top-width', 'border-top-style', 'border-top-color'], defaultValue: 'none', restore: restore.withoutDefaults, shorthand: true, }, 'border-top-color': { canOverride: canOverride.generic.color, componentOf: ['border-color', 'border-top'], defaultValue: 'none', }, 'border-top-left-radius': { canOverride: canOverride.generic.unit, componentOf: ['border-radius'], defaultValue: '0', vendorPrefixes: ['-moz-', '-o-'], }, 'border-top-right-radius': { canOverride: canOverride.generic.unit, componentOf: ['border-radius'], defaultValue: '0', vendorPrefixes: ['-moz-', '-o-'], }, 'border-top-style': { canOverride: canOverride.property.borderStyle, componentOf: ['border-style', 'border-top'], defaultValue: 'none', }, 'border-top-width': { canOverride: canOverride.generic.unit, componentOf: ['border-top', 'border-width'], defaultValue: 'medium', oppositeTo: 'border-bottom-width', shortestValue: '0', }, 'border-width': { breakUp: breakUp.fourValues, canOverride: canOverride.generic.components([ canOverride.generic.unit, canOverride.generic.unit, canOverride.generic.unit, canOverride.generic.unit, ]), componentOf: ['border'], components: [ 'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width', ], defaultValue: 'medium', restore: restore.fourValues, shortestValue: '0', shorthand: true, }, clear: { canOverride: canOverride.property.clear, defaultValue: 'none', }, color: { canOverride: canOverride.generic.color, defaultValue: 'transparent', shortestValue: 'red', }, cursor: { canOverride: canOverride.property.cursor, defaultValue: 'auto', }, display: { canOverride: canOverride.property.display, }, float: { 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: 'normal', shortestValue: '400', }, height: { canOverride: canOverride.generic.unit, defaultValue: 'auto', shortestValue: '0', }, left: { canOverride: canOverride.property.left, defaultValue: 'auto', }, 'line-height': { canOverride: canOverride.generic.unitOrNumber, defaultValue: 'normal', shortestValue: '0', }, 'list-style': { canOverride: canOverride.generic.components([ canOverride.property.listStyleType, canOverride.property.listStylePosition, canOverride.property.listStyleImage, ]), components: ['list-style-type', 'list-style-position', 'list-style-image'], breakUp: breakUp.listStyle, restore: restore.withoutDefaults, defaultValue: 'outside', // can't use 'disc' because that'd override default 'decimal' for
    shortestValue: 'none', shorthand: true, }, 'list-style-image': { canOverride: canOverride.generic.image, componentOf: ['list-style'], defaultValue: 'none', }, 'list-style-position': { canOverride: canOverride.property.listStylePosition, componentOf: ['list-style'], defaultValue: 'outside', shortestValue: 'inside', }, 'list-style-type': { canOverride: canOverride.property.listStyleType, componentOf: ['list-style'], // NOTE: we can't tell the real default value here, it's 'disc' for