You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1640 lines
40 KiB

// Contains the interpretation of CSS properties, as used by the property optimizer
var breakUp = require('./configuration/break-up');
var canOverride = require('./configuration/can-override');
var restore = require('./configuration/restore');
var propertyOptimizers = require('./level-1/property-optimizers');
var valueOptimizers = require('./level-1/value-optimizers');
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 configuration = {
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,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.textQuotes,
valueOptimizers.time,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
],
vendorPrefixes: [
'-moz-',
'-o-',
'-webkit-'
]
},
'animation-delay': {
canOverride: canOverride.generic.time,
componentOf: [
'animation'
],
defaultValue: '0s',
intoMultiplexMode: 'real',
valueOptimizers: [
valueOptimizers.time,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
],
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',
valueOptimizers: [
valueOptimizers.time,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
],
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',
valueOptimizers: [
valueOptimizers.textQuotes
],
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',
propertyOptimizer: propertyOptimizers.background,
restore: restore.multiplex(restore.background),
shortestValue: '0',
shorthand: true,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.urlWhiteSpace,
valueOptimizers.fraction,
valueOptimizers.zero,
valueOptimizers.color,
valueOptimizers.urlPrefix,
valueOptimizers.urlQuotes
]
},
'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',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.color
]
},
'background-image': {
canOverride: canOverride.generic.image,
componentOf: [
'background'
],
defaultValue: 'none',
intoMultiplexMode: 'default',
valueOptimizers: [
valueOptimizers.urlWhiteSpace,
valueOptimizers.urlPrefix,
valueOptimizers.urlQuotes,
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero,
valueOptimizers.color
]
},
'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',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'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',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
bottom: {
canOverride: canOverride.property.bottom,
defaultValue: 'auto',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
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,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.zero,
valueOptimizers.color
]
},
'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,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.zero,
valueOptimizers.color
]
},
'border-bottom-color': {
canOverride: canOverride.generic.color,
componentOf: [
'border-bottom',
'border-color'
],
defaultValue: 'none',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.color
]
},
'border-bottom-left-radius': {
canOverride: canOverride.generic.unit,
componentOf: [
'border-radius'
],
defaultValue: '0',
propertyOptimizer: propertyOptimizers.borderRadius,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
],
vendorPrefixes: [
'-moz-',
'-o-'
]
},
'border-bottom-right-radius': {
canOverride: canOverride.generic.unit,
componentOf: [
'border-radius'
],
defaultValue: '0',
propertyOptimizer: propertyOptimizers.borderRadius,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
],
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',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'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,
singleTypeComponents: true,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.color
]
},
'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,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.zero,
valueOptimizers.color
]
},
'border-left-color': {
canOverride: canOverride.generic.color,
componentOf: [
'border-color',
'border-left'
],
defaultValue: 'none',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.color
]
},
'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',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'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',
propertyOptimizer: propertyOptimizers.borderRadius,
restore: restore.borderRadius,
shorthand: true,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
],
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,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.color
]
},
'border-right-color': {
canOverride: canOverride.generic.color,
componentOf: [
'border-color',
'border-right'
],
defaultValue: 'none',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.color
]
},
'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',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'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,
singleTypeComponents: 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,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.zero,
valueOptimizers.color,
valueOptimizers.unit
]
},
'border-top-color': {
canOverride: canOverride.generic.color,
componentOf: [
'border-color',
'border-top'
],
defaultValue: 'none',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.color
]
},
'border-top-left-radius': {
canOverride: canOverride.generic.unit,
componentOf: [
'border-radius'
],
defaultValue: '0',
propertyOptimizer: propertyOptimizers.borderRadius,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
],
vendorPrefixes: [
'-moz-',
'-o-'
]
},
'border-top-right-radius': {
canOverride: canOverride.generic.unit,
componentOf: [
'border-radius'
],
defaultValue: '0',
propertyOptimizer: propertyOptimizers.borderRadius,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
],
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',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'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,
singleTypeComponents: true,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'box-shadow': {
propertyOptimizer: propertyOptimizers.boxShadow,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero,
valueOptimizers.color
],
vendorPrefixes: [
'-moz-',
'-ms-',
'-o-',
'-webkit-'
]
},
clear: {
canOverride: canOverride.property.clear,
defaultValue: 'none'
},
clip: {
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
color: {
canOverride: canOverride.generic.color,
defaultValue: 'transparent',
shortestValue: 'red',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.color
]
},
'column-gap': {
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
cursor: {
canOverride: canOverride.property.cursor,
defaultValue: 'auto'
},
display: { canOverride: canOverride.property.display },
filter: {
propertyOptimizer: propertyOptimizers.filter,
valueOptimizers: [
valueOptimizers.fraction
]
},
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,
valueOptimizers: [
valueOptimizers.textQuotes
]
},
'font-family': {
canOverride: canOverride.property.fontFamily,
defaultValue: 'user|agent|specific',
valueOptimizers: [
valueOptimizers.textQuotes
]
},
'font-size': {
canOverride: canOverride.generic.unit,
defaultValue: 'medium',
shortestValue: '0',
valueOptimizers: [
valueOptimizers.fraction
]
},
'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',
propertyOptimizer: propertyOptimizers.fontWeight,
shortestValue: '400'
},
gap: {
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
height: {
canOverride: canOverride.generic.unit,
defaultValue: 'auto',
shortestValue: '0',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
left: {
canOverride: canOverride.property.left,
defaultValue: 'auto',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'letter-spacing': {
valueOptimizers: [
valueOptimizers.fraction,
valueOptimizers.zero
]
},
'line-height': {
canOverride: canOverride.generic.unitOrNumber,
defaultValue: 'normal',
shortestValue: '0',
valueOptimizers: [
valueOptimizers.fraction,
valueOptimizers.zero
]
},
'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 <ol>
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 <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
defaultValue: 'decimal|disc',
shortestValue: 'none'
},
margin: {
breakUp: breakUp.fourValues,
canOverride: canOverride.generic.components([
canOverride.generic.unit,
canOverride.generic.unit,
canOverride.generic.unit,
canOverride.generic.unit
]),
components: [
'margin-top',
'margin-right',
'margin-bottom',
'margin-left'
],
defaultValue: '0',
propertyOptimizer: propertyOptimizers.margin,
restore: restore.fourValues,
shorthand: true,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'margin-bottom': {
canOverride: canOverride.generic.unit,
componentOf: [
'margin'
],
defaultValue: '0',
oppositeTo: 'margin-top',
propertyOptimizer: propertyOptimizers.margin,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'margin-inline-end': {
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'margin-inline-start': {
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'margin-left': {
canOverride: canOverride.generic.unit,
componentOf: [
'margin'
],
defaultValue: '0',
oppositeTo: 'margin-right',
propertyOptimizer: propertyOptimizers.margin,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'margin-right': {
canOverride: canOverride.generic.unit,
componentOf: [
'margin'
],
defaultValue: '0',
oppositeTo: 'margin-left',
propertyOptimizer: propertyOptimizers.margin,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'margin-top': {
canOverride: canOverride.generic.unit,
componentOf: [
'margin'
],
defaultValue: '0',
oppositeTo: 'margin-bottom',
propertyOptimizer: propertyOptimizers.margin,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'max-height': {
canOverride: canOverride.generic.unit,
defaultValue: 'none',
shortestValue: '0',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'max-width': {
canOverride: canOverride.generic.unit,
defaultValue: 'none',
shortestValue: '0',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'min-height': {
canOverride: canOverride.generic.unit,
defaultValue: '0',
shortestValue: '0',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'min-width': {
canOverride: canOverride.generic.unit,
defaultValue: '0',
shortestValue: '0',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
opacity: {
valueOptimizers: [
valueOptimizers.fraction,
valueOptimizers.precision
]
},
outline: {
canOverride: canOverride.generic.components([
canOverride.generic.color,
canOverride.property.outlineStyle,
canOverride.generic.unit
]),
components: [
'outline-color',
'outline-style',
'outline-width'
],
breakUp: breakUp.outline,
restore: restore.withoutDefaults,
defaultValue: '0',
propertyOptimizer: propertyOptimizers.outline,
shorthand: true,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'outline-color': {
canOverride: canOverride.generic.color,
componentOf: [
'outline'
],
defaultValue: 'invert',
shortestValue: 'red',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.color
]
},
'outline-style': {
canOverride: canOverride.property.outlineStyle,
componentOf: [
'outline'
],
defaultValue: 'none'
},
'outline-width': {
canOverride: canOverride.generic.unit,
componentOf: [
'outline'
],
defaultValue: 'medium',
shortestValue: '0',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
overflow: {
canOverride: canOverride.property.overflow,
defaultValue: 'visible'
},
'overflow-x': {
canOverride: canOverride.property.overflow,
defaultValue: 'visible'
},
'overflow-y': {
canOverride: canOverride.property.overflow,
defaultValue: 'visible'
},
padding: {
breakUp: breakUp.fourValues,
canOverride: canOverride.generic.components([
canOverride.generic.unit,
canOverride.generic.unit,
canOverride.generic.unit,
canOverride.generic.unit
]),
components: [
'padding-top',
'padding-right',
'padding-bottom',
'padding-left'
],
defaultValue: '0',
propertyOptimizer: propertyOptimizers.padding,
restore: restore.fourValues,
shorthand: true,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'padding-bottom': {
canOverride: canOverride.generic.unit,
componentOf: [
'padding'
],
defaultValue: '0',
oppositeTo: 'padding-top',
propertyOptimizer: propertyOptimizers.padding,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'padding-left': {
canOverride: canOverride.generic.unit,
componentOf: [
'padding'
],
defaultValue: '0',
oppositeTo: 'padding-right',
propertyOptimizer: propertyOptimizers.padding,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'padding-right': {
canOverride: canOverride.generic.unit,
componentOf: [
'padding'
],
defaultValue: '0',
oppositeTo: 'padding-left',
propertyOptimizer: propertyOptimizers.padding,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'padding-top': {
canOverride: canOverride.generic.unit,
componentOf: [
'padding'
],
defaultValue: '0',
oppositeTo: 'padding-bottom',
propertyOptimizer: propertyOptimizers.padding,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
position: {
canOverride: canOverride.property.position,
defaultValue: 'static'
},
right: {
canOverride: canOverride.property.right,
defaultValue: 'auto',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'row-gap': {
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
src: {
valueOptimizers: [
valueOptimizers.urlWhiteSpace,
valueOptimizers.urlPrefix,
valueOptimizers.urlQuotes
]
},
'stroke-width': {
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'text-align': {
canOverride: canOverride.property.textAlign,
// NOTE: we can't tell the real default value here, as it depends on default text direction
// this is a hack, but it doesn't matter because this value will be either overridden or
// it will disappear anyway
defaultValue: 'left|right'
},
'text-decoration': {
canOverride: canOverride.property.textDecoration,
defaultValue: 'none'
},
'text-indent': {
canOverride: canOverride.property.textOverflow,
defaultValue: 'none',
valueOptimizers: [
valueOptimizers.fraction,
valueOptimizers.zero
]
},
'text-overflow': {
canOverride: canOverride.property.textOverflow,
defaultValue: 'none'
},
'text-shadow': {
canOverride: canOverride.property.textShadow,
defaultValue: 'none',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.zero,
valueOptimizers.color
]
},
top: {
canOverride: canOverride.property.top,
defaultValue: 'auto',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
transform: {
canOverride: canOverride.property.transform,
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.degrees,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
],
vendorPrefixes: [
'-moz-',
'-ms-',
'-o-',
'-webkit-'
]
},
transition: {
breakUp: breakUp.multiplex(breakUp.transition),
canOverride: canOverride.generic.components([
canOverride.property.transitionProperty,
canOverride.generic.time,
canOverride.generic.timingFunction,
canOverride.generic.time
]),
components: [
'transition-property',
'transition-duration',
'transition-timing-function',
'transition-delay'
],
defaultValue: 'none',
restore: restore.multiplex(restore.withoutDefaults),
shorthand: true,
valueOptimizers: [
valueOptimizers.time,
valueOptimizers.fraction
],
vendorPrefixes: [
'-moz-',
'-ms-',
'-o-',
'-webkit-'
]
},
'transition-delay': {
canOverride: canOverride.generic.time,
componentOf: [
'transition'
],
defaultValue: '0s',
intoMultiplexMode: 'real',
valueOptimizers: [
valueOptimizers.time
],
vendorPrefixes: [
'-moz-',
'-ms-',
'-o-',
'-webkit-'
]
},
'transition-duration': {
canOverride: canOverride.generic.time,
componentOf: [
'transition'
],
defaultValue: '0s',
intoMultiplexMode: 'real',
keepUnlessDefault: 'transition-delay',
valueOptimizers: [
valueOptimizers.time,
valueOptimizers.fraction
],
vendorPrefixes: [
'-moz-',
'-ms-',
'-o-',
'-webkit-'
]
},
'transition-property': {
canOverride: canOverride.generic.propertyName,
componentOf: [
'transition'
],
defaultValue: 'all',
intoMultiplexMode: 'placeholder',
placeholderValue: '_', // it's a short value that won't match any property and still be a valid `transition-property`
vendorPrefixes: [
'-moz-',
'-ms-',
'-o-',
'-webkit-'
]
},
'transition-timing-function': {
canOverride: canOverride.generic.timingFunction,
componentOf: [
'transition'
],
defaultValue: 'ease',
intoMultiplexMode: 'real',
vendorPrefixes: [
'-moz-',
'-ms-',
'-o-',
'-webkit-'
]
},
'vertical-align': {
canOverride: canOverride.property.verticalAlign,
defaultValue: 'baseline',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
visibility: {
canOverride: canOverride.property.visibility,
defaultValue: 'visible'
},
'-webkit-tap-highlight-color': {
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.color
]
},
'-webkit-margin-end': {
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'white-space': {
canOverride: canOverride.property.whiteSpace,
defaultValue: 'normal'
},
width: {
canOverride: canOverride.generic.unit,
defaultValue: 'auto',
shortestValue: '0',
valueOptimizers: [
valueOptimizers.whiteSpace,
valueOptimizers.fraction,
valueOptimizers.precision,
valueOptimizers.unit,
valueOptimizers.zero
]
},
'z-index': {
canOverride: canOverride.property.zIndex,
defaultValue: 'auto'
}
};
// generate vendor-prefixed configuration
var vendorPrefixedConfiguration = {};
function cloneDescriptor(propertyName, prefix) {
var clonedDescriptor = override(configuration[propertyName], {});
if ('componentOf' in clonedDescriptor) {
clonedDescriptor.componentOf = clonedDescriptor.componentOf.map(function(shorthandName) {
return prefix + shorthandName;
});
}
if ('components' in clonedDescriptor) {
clonedDescriptor.components = clonedDescriptor.components.map(function(longhandName) {
return prefix + longhandName;
});
}
if ('keepUnlessDefault' in clonedDescriptor) {
clonedDescriptor.keepUnlessDefault = prefix + clonedDescriptor.keepUnlessDefault;
}
return clonedDescriptor;
}
for (var propertyName in configuration) {
var descriptor = configuration[propertyName];
if (!('vendorPrefixes' in descriptor)) {
continue;
}
for (var i = 0; i < descriptor.vendorPrefixes.length; i++) {
var prefix = descriptor.vendorPrefixes[i];
var clonedDescriptor = cloneDescriptor(propertyName, prefix);
delete clonedDescriptor.vendorPrefixes;
vendorPrefixedConfiguration[prefix + propertyName] = clonedDescriptor;
}
delete descriptor.vendorPrefixes;
}
module.exports = override(configuration, vendorPrefixedConfiguration);