182 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			182 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
var DEFAULTS = {
 | 
						|
  '*': {
 | 
						|
    colors: {
 | 
						|
      hexAlpha: false, // 4- and 8-character hex notation
 | 
						|
      opacity: true // rgba / hsla
 | 
						|
    },
 | 
						|
    customUnits: { rpx: false },
 | 
						|
    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, \0 suffix hack on IE6-11
 | 
						|
      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: true, // 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 = merge(DEFAULTS['*'], { properties: { ieSuffixHack: true } });
 | 
						|
 | 
						|
DEFAULTS.ie10 = merge(DEFAULTS['*'], { properties: { ieSuffixHack: true } });
 | 
						|
 | 
						|
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) {
 | 
						|
    if (Object.prototype.hasOwnProperty.call(source, key)) {
 | 
						|
      var value = source[key];
 | 
						|
 | 
						|
      if (Object.prototype.hasOwnProperty.call(target, key) && 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;
 |