Spaces:
Running
Running
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 | |
}; | |