1var DEFAULTS = { 2 '*': { 3 colors: { 4 opacity: true // rgba / hsla 5 }, 6 properties: { 7 backgroundClipMerging: true, // background-clip to shorthand 8 backgroundOriginMerging: true, // background-origin to shorthand 9 backgroundSizeMerging: true, // background-size to shorthand 10 colors: true, // any kind of color transformations, like `#ff00ff` to `#f0f` or `#fff` into `red` 11 ieBangHack: false, // !ie suffix hacks on IE<8 12 ieFilters: false, // whether to preserve `filter` and `-ms-filter` properties 13 iePrefixHack: false, // underscore / asterisk prefix hacks on IE 14 ieSuffixHack: false, // \9 suffix hacks on IE6-9 15 merging: true, // merging properties into one 16 shorterLengthUnits: false, // optimize pixel units into `pt`, `pc` or `in` units 17 spaceAfterClosingBrace: true, // 'url() no-repeat' to 'url()no-repeat' 18 urlQuotes: false, // whether to wrap content of `url()` into quotes or not 19 zeroUnits: true // 0[unit] -> 0 20 }, 21 selectors: { 22 adjacentSpace: false, // div+ nav Android stock browser hack 23 ie7Hack: false, // *+html hack 24 mergeablePseudoClasses: [ 25 ':active', 26 ':after', 27 ':before', 28 ':empty', 29 ':checked', 30 ':disabled', 31 ':empty', 32 ':enabled', 33 ':first-child', 34 ':first-letter', 35 ':first-line', 36 ':first-of-type', 37 ':focus', 38 ':hover', 39 ':lang', 40 ':last-child', 41 ':last-of-type', 42 ':link', 43 ':not', 44 ':nth-child', 45 ':nth-last-child', 46 ':nth-last-of-type', 47 ':nth-of-type', 48 ':only-child', 49 ':only-of-type', 50 ':root', 51 ':target', 52 ':visited' 53 ], // selectors with these pseudo-classes can be merged as these are universally supported 54 mergeablePseudoElements: [ 55 '::after', 56 '::before', 57 '::first-letter', 58 '::first-line' 59 ], // selectors with these pseudo-elements can be merged as these are universally supported 60 mergeLimit: 8191, // number of rules that can be safely merged together 61 multiplePseudoMerging: true 62 }, 63 units: { 64 ch: true, 65 in: true, 66 pc: true, 67 pt: true, 68 rem: true, 69 vh: true, 70 vm: true, // vm is vmin on IE9+ see https://developer.mozilla.org/en-US/docs/Web/CSS/length 71 vmax: true, 72 vmin: true, 73 vw: true 74 } 75 } 76}; 77 78DEFAULTS.ie11 = DEFAULTS['*']; 79 80DEFAULTS.ie10 = DEFAULTS['*']; 81 82DEFAULTS.ie9 = merge(DEFAULTS['*'], { 83 properties: { 84 ieFilters: true, 85 ieSuffixHack: true 86 } 87}); 88 89DEFAULTS.ie8 = merge(DEFAULTS.ie9, { 90 colors: { 91 opacity: false 92 }, 93 properties: { 94 backgroundClipMerging: false, 95 backgroundOriginMerging: false, 96 backgroundSizeMerging: false, 97 iePrefixHack: true, 98 merging: false 99 }, 100 selectors: { 101 mergeablePseudoClasses: [ 102 ':after', 103 ':before', 104 ':first-child', 105 ':first-letter', 106 ':focus', 107 ':hover', 108 ':visited' 109 ], 110 mergeablePseudoElements: [] 111 }, 112 units: { 113 ch: false, 114 rem: false, 115 vh: false, 116 vm: false, 117 vmax: false, 118 vmin: false, 119 vw: false 120 } 121}); 122 123DEFAULTS.ie7 = merge(DEFAULTS.ie8, { 124 properties: { 125 ieBangHack: true 126 }, 127 selectors: { 128 ie7Hack: true, 129 mergeablePseudoClasses: [ 130 ':first-child', 131 ':first-letter', 132 ':hover', 133 ':visited' 134 ] 135 }, 136}); 137 138function compatibilityFrom(source) { 139 return merge(DEFAULTS['*'], calculateSource(source)); 140} 141 142function merge(source, target) { 143 for (var key in source) { 144 if (Object.prototype.hasOwnProperty.call(source, key)) { 145 var value = source[key]; 146 147 if (Object.prototype.hasOwnProperty.call(target, key) && typeof value === 'object' && !Array.isArray(value)) { 148 target[key] = merge(value, target[key] || {}); 149 } else { 150 target[key] = key in target ? target[key] : value; 151 } 152 } 153 } 154 155 return target; 156} 157 158function calculateSource(source) { 159 if (typeof source == 'object') 160 return source; 161 162 if (!/[,\+\-]/.test(source)) 163 return DEFAULTS[source] || DEFAULTS['*']; 164 165 var parts = source.split(','); 166 var template = parts[0] in DEFAULTS ? 167 DEFAULTS[parts.shift()] : 168 DEFAULTS['*']; 169 170 source = {}; 171 172 parts.forEach(function (part) { 173 var isAdd = part[0] == '+'; 174 var key = part.substring(1).split('.'); 175 var group = key[0]; 176 var option = key[1]; 177 178 source[group] = source[group] || {}; 179 source[group][option] = isAdd; 180 }); 181 182 return merge(template, source); 183} 184 185module.exports = compatibilityFrom; 186