242 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
var override = require('../utils/override');
 | 
						|
 | 
						|
function getSystemLineBreak() {
 | 
						|
  var systemLineBreak = '\n';
 | 
						|
  try {
 | 
						|
    var os = require('os');
 | 
						|
    systemLineBreak = os.EOL;
 | 
						|
  } catch (_) {
 | 
						|
    // no op
 | 
						|
  }
 | 
						|
  return systemLineBreak;
 | 
						|
}
 | 
						|
 | 
						|
var Breaks = {
 | 
						|
  AfterAtRule: 'afterAtRule',
 | 
						|
  AfterBlockBegins: 'afterBlockBegins',
 | 
						|
  AfterBlockEnds: 'afterBlockEnds',
 | 
						|
  AfterComment: 'afterComment',
 | 
						|
  AfterProperty: 'afterProperty',
 | 
						|
  AfterRuleBegins: 'afterRuleBegins',
 | 
						|
  AfterRuleEnds: 'afterRuleEnds',
 | 
						|
  BeforeBlockEnds: 'beforeBlockEnds',
 | 
						|
  BetweenSelectors: 'betweenSelectors'
 | 
						|
};
 | 
						|
 | 
						|
var BreakWith = {
 | 
						|
  CarriageReturnLineFeed: '\r\n',
 | 
						|
  LineFeed: '\n',
 | 
						|
  System: getSystemLineBreak()
 | 
						|
};
 | 
						|
 | 
						|
var IndentWith = {
 | 
						|
  Space: ' ',
 | 
						|
  Tab: '\t'
 | 
						|
};
 | 
						|
 | 
						|
var Spaces = {
 | 
						|
  AroundSelectorRelation: 'aroundSelectorRelation',
 | 
						|
  BeforeBlockBegins: 'beforeBlockBegins',
 | 
						|
  BeforeValue: 'beforeValue'
 | 
						|
};
 | 
						|
 | 
						|
var DEFAULTS = {
 | 
						|
  breaks: breaks(false),
 | 
						|
  breakWith: BreakWith.System,
 | 
						|
  indentBy: 0,
 | 
						|
  indentWith: IndentWith.Space,
 | 
						|
  spaces: spaces(false),
 | 
						|
  wrapAt: false,
 | 
						|
  semicolonAfterLastProperty: false
 | 
						|
};
 | 
						|
 | 
						|
var BEAUTIFY_ALIAS = 'beautify';
 | 
						|
var KEEP_BREAKS_ALIAS = 'keep-breaks';
 | 
						|
 | 
						|
var OPTION_SEPARATOR = ';';
 | 
						|
var OPTION_NAME_VALUE_SEPARATOR = ':';
 | 
						|
var HASH_VALUES_OPTION_SEPARATOR = ',';
 | 
						|
var HASH_VALUES_NAME_VALUE_SEPARATOR = '=';
 | 
						|
 | 
						|
var FALSE_KEYWORD_1 = 'false';
 | 
						|
var FALSE_KEYWORD_2 = 'off';
 | 
						|
var TRUE_KEYWORD_1 = 'true';
 | 
						|
var TRUE_KEYWORD_2 = 'on';
 | 
						|
 | 
						|
function breaks(value) {
 | 
						|
  var breakOptions = {};
 | 
						|
 | 
						|
  breakOptions[Breaks.AfterAtRule] = value;
 | 
						|
  breakOptions[Breaks.AfterBlockBegins] = value;
 | 
						|
  breakOptions[Breaks.AfterBlockEnds] = value;
 | 
						|
  breakOptions[Breaks.AfterComment] = value;
 | 
						|
  breakOptions[Breaks.AfterProperty] = value;
 | 
						|
  breakOptions[Breaks.AfterRuleBegins] = value;
 | 
						|
  breakOptions[Breaks.AfterRuleEnds] = value;
 | 
						|
  breakOptions[Breaks.BeforeBlockEnds] = value;
 | 
						|
  breakOptions[Breaks.BetweenSelectors] = value;
 | 
						|
 | 
						|
  return breakOptions;
 | 
						|
}
 | 
						|
 | 
						|
function spaces(value) {
 | 
						|
  var spaceOptions = {};
 | 
						|
 | 
						|
  spaceOptions[Spaces.AroundSelectorRelation] = value;
 | 
						|
  spaceOptions[Spaces.BeforeBlockBegins] = value;
 | 
						|
  spaceOptions[Spaces.BeforeValue] = value;
 | 
						|
 | 
						|
  return spaceOptions;
 | 
						|
}
 | 
						|
 | 
						|
function formatFrom(source) {
 | 
						|
  if (source === undefined || source === false) {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  if (typeof source == 'object' && 'breakWith' in source) {
 | 
						|
    source = override(source, { breakWith: mapBreakWith(source.breakWith) });
 | 
						|
  }
 | 
						|
 | 
						|
  if (typeof source == 'object' && 'indentBy' in source) {
 | 
						|
    source = override(source, { indentBy: parseInt(source.indentBy) });
 | 
						|
  }
 | 
						|
 | 
						|
  if (typeof source == 'object' && 'indentWith' in source) {
 | 
						|
    source = override(source, { indentWith: mapIndentWith(source.indentWith) });
 | 
						|
  }
 | 
						|
 | 
						|
  if (typeof source == 'object') {
 | 
						|
    return remapBreaks(override(DEFAULTS, source));
 | 
						|
  }
 | 
						|
 | 
						|
  if (typeof source == 'string' && source == BEAUTIFY_ALIAS) {
 | 
						|
    return remapBreaks(
 | 
						|
      override(DEFAULTS, {
 | 
						|
        breaks: breaks(true),
 | 
						|
        indentBy: 2,
 | 
						|
        spaces: spaces(true)
 | 
						|
      })
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  if (typeof source == 'string' && source == KEEP_BREAKS_ALIAS) {
 | 
						|
    return remapBreaks(
 | 
						|
      override(DEFAULTS, {
 | 
						|
        breaks: {
 | 
						|
          afterAtRule: true,
 | 
						|
          afterBlockBegins: true,
 | 
						|
          afterBlockEnds: true,
 | 
						|
          afterComment: true,
 | 
						|
          afterRuleEnds: true,
 | 
						|
          beforeBlockEnds: true
 | 
						|
        }
 | 
						|
      })
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  if (typeof source == 'string') {
 | 
						|
    return remapBreaks(override(DEFAULTS, toHash(source)));
 | 
						|
  }
 | 
						|
 | 
						|
  return DEFAULTS;
 | 
						|
}
 | 
						|
 | 
						|
function toHash(string) {
 | 
						|
  return string
 | 
						|
    .split(OPTION_SEPARATOR)
 | 
						|
    .reduce(function(accumulator, directive) {
 | 
						|
      var parts = directive.split(OPTION_NAME_VALUE_SEPARATOR);
 | 
						|
      var name = parts[0];
 | 
						|
      var value = parts[1];
 | 
						|
 | 
						|
      if (name == 'breaks' || name == 'spaces') {
 | 
						|
        accumulator[name] = hashValuesToHash(value);
 | 
						|
      } else if (name == 'indentBy' || name == 'wrapAt') {
 | 
						|
        accumulator[name] = parseInt(value);
 | 
						|
      } else if (name == 'indentWith') {
 | 
						|
        accumulator[name] = mapIndentWith(value);
 | 
						|
      } else if (name == 'breakWith') {
 | 
						|
        accumulator[name] = mapBreakWith(value);
 | 
						|
      }
 | 
						|
 | 
						|
      return accumulator;
 | 
						|
    }, {});
 | 
						|
}
 | 
						|
 | 
						|
function hashValuesToHash(string) {
 | 
						|
  return string
 | 
						|
    .split(HASH_VALUES_OPTION_SEPARATOR)
 | 
						|
    .reduce(function(accumulator, directive) {
 | 
						|
      var parts = directive.split(HASH_VALUES_NAME_VALUE_SEPARATOR);
 | 
						|
      var name = parts[0];
 | 
						|
      var value = parts[1];
 | 
						|
 | 
						|
      accumulator[name] = normalizeValue(value);
 | 
						|
 | 
						|
      return accumulator;
 | 
						|
    }, {});
 | 
						|
}
 | 
						|
 | 
						|
function normalizeValue(value) {
 | 
						|
  switch (value) {
 | 
						|
  case FALSE_KEYWORD_1:
 | 
						|
  case FALSE_KEYWORD_2:
 | 
						|
    return false;
 | 
						|
  case TRUE_KEYWORD_1:
 | 
						|
  case TRUE_KEYWORD_2:
 | 
						|
    return true;
 | 
						|
  default:
 | 
						|
    return value;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function mapBreakWith(value) {
 | 
						|
  switch (value) {
 | 
						|
  case 'windows':
 | 
						|
  case 'crlf':
 | 
						|
  case BreakWith.CarriageReturnLineFeed:
 | 
						|
    return BreakWith.CarriageReturnLineFeed;
 | 
						|
  case 'unix':
 | 
						|
  case 'lf':
 | 
						|
  case BreakWith.LineFeed:
 | 
						|
    return BreakWith.LineFeed;
 | 
						|
  default:
 | 
						|
    return BreakWith.System;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function mapIndentWith(value) {
 | 
						|
  switch (value) {
 | 
						|
  case 'space':
 | 
						|
    return IndentWith.Space;
 | 
						|
  case 'tab':
 | 
						|
    return IndentWith.Tab;
 | 
						|
  default:
 | 
						|
    return value;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function remapBreaks(source) {
 | 
						|
  for (var key in Breaks) {
 | 
						|
    var breakName = Breaks[key];
 | 
						|
    var breakValue = source.breaks[breakName];
 | 
						|
 | 
						|
    if (breakValue === true) {
 | 
						|
      source.breaks[breakName] = source.breakWith;
 | 
						|
    } else if (breakValue === false) {
 | 
						|
      source.breaks[breakName] = '';
 | 
						|
    } else {
 | 
						|
      source.breaks[breakName] = source.breakWith.repeat(parseInt(breakValue));
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return source;
 | 
						|
}
 | 
						|
 | 
						|
module.exports = {
 | 
						|
  Breaks: Breaks,
 | 
						|
  Spaces: Spaces,
 | 
						|
  formatFrom: formatFrom
 | 
						|
};
 |