blob: 8e6a119a837c1322bdb09c4f3a55828c2aaa98ec [file] [log] [blame]
var DEFAULTS = {
'*': {
colors: {
opacity: true // rgba / hsla
},
properties: {
backgroundClipMerging: true, // background-clip to shorthand
backgroundOriginMerging: true, // background-origin to shorthand
backgroundSizeMerging: true, // background-size to shorthand
colors: true, // any kind of color transformations, like `#ff00ff` to `#f0f` or `#fff` into `red`
ieBangHack: false, // !ie suffix hacks on IE<8
ieFilters: false, // whether to preserve `filter` and `-ms-filter` properties
iePrefixHack: false, // underscore / asterisk prefix hacks on IE
ieSuffixHack: false, // \9 suffix hacks on IE6-9
merging: true, // merging properties into one
shorterLengthUnits: false, // optimize pixel units into `pt`, `pc` or `in` units
spaceAfterClosingBrace: true, // 'url() no-repeat' to 'url()no-repeat'
urlQuotes: false, // whether to wrap content of `url()` into quotes or not
zeroUnits: true // 0[unit] -> 0
},
selectors: {
adjacentSpace: false, // div+ nav Android stock browser hack
ie7Hack: false, // *+html hack
mergeablePseudoClasses: [
':active',
':after',
':before',
':empty',
':checked',
':disabled',
':empty',
':enabled',
':first-child',
':first-letter',
':first-line',
':first-of-type',
':focus',
':hover',
':lang',
':last-child',
':last-of-type',
':link',
':not',
':nth-child',
':nth-last-child',
':nth-last-of-type',
':nth-of-type',
':only-child',
':only-of-type',
':root',
':target',
':visited'
], // selectors with these pseudo-classes can be merged as these are universally supported
mergeablePseudoElements: [
'::after',
'::before',
'::first-letter',
'::first-line'
], // selectors with these pseudo-elements can be merged as these are universally supported
mergeLimit: 8191, // number of rules that can be safely merged together
multiplePseudoMerging: true
},
units: {
ch: true,
in: true,
pc: true,
pt: true,
rem: true,
vh: true,
vm: true, // vm is vmin on IE9+ see https://developer.mozilla.org/en-US/docs/Web/CSS/length
vmax: true,
vmin: true,
vw: true
}
}
};
DEFAULTS.ie11 = DEFAULTS['*'];
DEFAULTS.ie10 = DEFAULTS['*'];
DEFAULTS.ie9 = merge(DEFAULTS['*'], {
properties: {
ieFilters: true,
ieSuffixHack: true
}
});
DEFAULTS.ie8 = merge(DEFAULTS.ie9, {
colors: {
opacity: false
},
properties: {
backgroundClipMerging: false,
backgroundOriginMerging: false,
backgroundSizeMerging: false,
iePrefixHack: true,
merging: false
},
selectors: {
mergeablePseudoClasses: [
':after',
':before',
':first-child',
':first-letter',
':focus',
':hover',
':visited'
],
mergeablePseudoElements: []
},
units: {
ch: false,
rem: false,
vh: false,
vm: false,
vmax: false,
vmin: false,
vw: false
}
});
DEFAULTS.ie7 = merge(DEFAULTS.ie8, {
properties: {
ieBangHack: true
},
selectors: {
ie7Hack: true,
mergeablePseudoClasses: [
':first-child',
':first-letter',
':hover',
':visited'
]
},
});
function compatibilityFrom(source) {
return merge(DEFAULTS['*'], calculateSource(source));
}
function merge(source, target) {
for (var key in source) {
var value = source[key];
if (typeof value === 'object' && !Array.isArray(value)) {
target[key] = merge(value, target[key] || {});
} else {
target[key] = key in target ? target[key] : value;
}
}
return target;
}
function calculateSource(source) {
if (typeof source == 'object')
return source;
if (!/[,\+\-]/.test(source))
return DEFAULTS[source] || DEFAULTS['*'];
var parts = source.split(',');
var template = parts[0] in DEFAULTS ?
DEFAULTS[parts.shift()] :
DEFAULTS['*'];
source = {};
parts.forEach(function (part) {
var isAdd = part[0] == '+';
var key = part.substring(1).split('.');
var group = key[0];
var option = key[1];
source[group] = source[group] || {};
source[group][option] = isAdd;
});
return merge(template, source);
}
module.exports = compatibilityFrom;