beautify-css.js: 1.6.12
This commit is contained in:
parent
1cfd2752d5
commit
1fcac0ddf4
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2007-2013 Einar Lielmanis and contributors.
|
Copyright (c) 2007-2017 Einar Lielmanis, Liam Newman, and contributors.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation files
|
obtaining a copy of this software and associated documentation files
|
||||||
|
@ -39,13 +39,15 @@
|
||||||
css_beautify(source_text, options);
|
css_beautify(source_text, options);
|
||||||
|
|
||||||
The options are (default in brackets):
|
The options are (default in brackets):
|
||||||
indent_size (4) — indentation size,
|
indent_size (4) — indentation size,
|
||||||
indent_char (space) — character to indent with,
|
indent_char (space) — character to indent with,
|
||||||
selector_separator_newline (true) - separate selectors with newline or
|
preserve_newlines (default false) - whether existing line breaks should be preserved,
|
||||||
not (e.g. "a,\nbr" or "a, br")
|
selector_separator_newline (true) - separate selectors with newline or
|
||||||
end_with_newline (false) - end with a newline
|
not (e.g. "a,\nbr" or "a, br")
|
||||||
newline_between_rules (true) - add a new line after every css rule
|
end_with_newline (false) - end with a newline
|
||||||
|
newline_between_rules (true) - add a new line after every css rule
|
||||||
|
space_around_selector_separator (false) - ensure space around selector separators:
|
||||||
|
'>', '+', '~' (e.g. "a>b" -> "a > b")
|
||||||
e.g
|
e.g
|
||||||
|
|
||||||
css_beautify(css_source_text, {
|
css_beautify(css_source_text, {
|
||||||
|
@ -53,7 +55,8 @@
|
||||||
'indent_char': '\t',
|
'indent_char': '\t',
|
||||||
'selector_separator': ' ',
|
'selector_separator': ' ',
|
||||||
'end_with_newline': false,
|
'end_with_newline': false,
|
||||||
'newline_between_rules': true
|
'newline_between_rules': true,
|
||||||
|
'space_around_selector_separator': true
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -61,23 +64,69 @@
|
||||||
// http://www.w3.org/TR/css3-syntax/
|
// http://www.w3.org/TR/css3-syntax/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
function css_beautify(source_text, options) {
|
|
||||||
options = options || {};
|
|
||||||
var indentSize = options.indent_size || 4;
|
|
||||||
var indentCharacter = options.indent_char || ' ';
|
|
||||||
var selectorSeparatorNewline = (options.selector_separator_newline === undefined) ? true : options.selector_separator_newline;
|
|
||||||
var end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
|
|
||||||
var newline_between_rules = (options.newline_between_rules === undefined) ? true : options.newline_between_rules;
|
|
||||||
|
|
||||||
// compatibility
|
function mergeOpts(allOptions, targetType) {
|
||||||
if (typeof indentSize === "string") {
|
var finalOpts = {};
|
||||||
indentSize = parseInt(indentSize, 10);
|
var name;
|
||||||
|
|
||||||
|
for (name in allOptions) {
|
||||||
|
if (name !== targetType) {
|
||||||
|
finalOpts[name] = allOptions[name];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//merge in the per type settings for the targetType
|
||||||
|
if (targetType in allOptions) {
|
||||||
|
for (name in allOptions[targetType]) {
|
||||||
|
finalOpts[name] = allOptions[targetType][name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return finalOpts;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lineBreak = /\r\n|[\n\r\u2028\u2029]/;
|
||||||
|
var allLineBreaks = new RegExp(lineBreak.source, 'g');
|
||||||
|
|
||||||
|
function css_beautify(source_text, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
// Allow the setting of language/file-type specific options
|
||||||
|
// with inheritance of overall settings
|
||||||
|
options = mergeOpts(options, 'css');
|
||||||
|
|
||||||
|
source_text = source_text || '';
|
||||||
|
|
||||||
|
var newlinesFromLastWSEat = 0;
|
||||||
|
var indentSize = options.indent_size ? parseInt(options.indent_size, 10) : 4;
|
||||||
|
var indentCharacter = options.indent_char || ' ';
|
||||||
|
var preserve_newlines = (options.preserve_newlines === undefined) ? false : options.preserve_newlines;
|
||||||
|
var selectorSeparatorNewline = (options.selector_separator_newline === undefined) ? true : options.selector_separator_newline;
|
||||||
|
var end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
|
||||||
|
var newline_between_rules = (options.newline_between_rules === undefined) ? true : options.newline_between_rules;
|
||||||
|
var space_around_combinator = (options.space_around_combinator === undefined) ? false : options.space_around_combinator;
|
||||||
|
space_around_combinator = space_around_combinator || ((options.space_around_selector_separator === undefined) ? false : options.space_around_selector_separator);
|
||||||
|
var eol = options.eol ? options.eol : 'auto';
|
||||||
|
|
||||||
|
if (options.indent_with_tabs) {
|
||||||
|
indentCharacter = '\t';
|
||||||
|
indentSize = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eol === 'auto') {
|
||||||
|
eol = '\n';
|
||||||
|
if (source_text && lineBreak.test(source_text || '')) {
|
||||||
|
eol = source_text.match(lineBreak)[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eol = eol.replace(/\\r/, '\r').replace(/\\n/, '\n');
|
||||||
|
|
||||||
|
// HACK: newline parsing inconsistent. This brute force normalizes the input.
|
||||||
|
source_text = source_text.replace(allLineBreaks, '\n');
|
||||||
|
|
||||||
// tokenizer
|
// tokenizer
|
||||||
var whiteRe = /^\s+$/;
|
var whiteRe = /^\s+$/;
|
||||||
var wordRe = /[\w$\-_]/;
|
|
||||||
|
|
||||||
var pos = -1,
|
var pos = -1,
|
||||||
ch;
|
ch;
|
||||||
|
@ -89,6 +138,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function peek(skipWhitespace) {
|
function peek(skipWhitespace) {
|
||||||
|
var result = '';
|
||||||
var prev_pos = pos;
|
var prev_pos = pos;
|
||||||
if (skipWhitespace) {
|
if (skipWhitespace) {
|
||||||
eatWhitespace();
|
eatWhitespace();
|
||||||
|
@ -121,12 +171,16 @@
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
function eatWhitespace() {
|
function eatWhitespace(preserve_newlines_local) {
|
||||||
var result = '';
|
var result = 0;
|
||||||
while (whiteRe.test(peek())) {
|
while (whiteRe.test(peek())) {
|
||||||
next();
|
next();
|
||||||
result += ch;
|
if (ch === '\n' && preserve_newlines_local && preserve_newlines) {
|
||||||
|
print.newLine(true);
|
||||||
|
result++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
newlinesFromLastWSEat = result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,11 +221,20 @@
|
||||||
// and the next special character found opens
|
// and the next special character found opens
|
||||||
// a new block
|
// a new block
|
||||||
function foundNestedPseudoClass() {
|
function foundNestedPseudoClass() {
|
||||||
|
var openParen = 0;
|
||||||
for (var i = pos + 1; i < source_text.length; i++) {
|
for (var i = pos + 1; i < source_text.length; i++) {
|
||||||
var ch = source_text.charAt(i);
|
var ch = source_text.charAt(i);
|
||||||
if (ch === "{") {
|
if (ch === "{") {
|
||||||
return true;
|
return true;
|
||||||
} else if (ch === ";" || ch === "}" || ch === ")") {
|
} else if (ch === '(') {
|
||||||
|
// pseudoclasses can contain ()
|
||||||
|
openParen += 1;
|
||||||
|
} else if (ch === ')') {
|
||||||
|
if (openParen === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
openParen -= 1;
|
||||||
|
} else if (ch === ";" || ch === "}") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,12 +261,18 @@
|
||||||
print["{"] = function(ch) {
|
print["{"] = function(ch) {
|
||||||
print.singleSpace();
|
print.singleSpace();
|
||||||
output.push(ch);
|
output.push(ch);
|
||||||
print.newLine();
|
if (!eatWhitespace(true)) {
|
||||||
|
print.newLine();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
print["}"] = function(ch) {
|
print["}"] = function(newline) {
|
||||||
print.newLine();
|
if (newline) {
|
||||||
output.push(ch);
|
print.newLine();
|
||||||
print.newLine();
|
}
|
||||||
|
output.push('}');
|
||||||
|
if (!eatWhitespace(true)) {
|
||||||
|
print.newLine();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
print._lastCharWhitespace = function() {
|
print._lastCharWhitespace = function() {
|
||||||
|
@ -211,15 +280,17 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
print.newLine = function(keepWhitespace) {
|
print.newLine = function(keepWhitespace) {
|
||||||
if (!keepWhitespace) {
|
|
||||||
print.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (output.length) {
|
if (output.length) {
|
||||||
|
if (!keepWhitespace && output[output.length - 1] !== '\n') {
|
||||||
|
print.trim();
|
||||||
|
} else if (output[output.length - 1] === basebaseIndentString) {
|
||||||
|
output.pop();
|
||||||
|
}
|
||||||
output.push('\n');
|
output.push('\n');
|
||||||
}
|
|
||||||
if (basebaseIndentString) {
|
if (basebaseIndentString) {
|
||||||
output.push(basebaseIndentString);
|
output.push(basebaseIndentString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
print.singleSpace = function() {
|
print.singleSpace = function() {
|
||||||
|
@ -228,6 +299,12 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
print.preserveSingleSpace = function() {
|
||||||
|
if (isAfterSpace) {
|
||||||
|
print.singleSpace();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
print.trim = function() {
|
print.trim = function() {
|
||||||
while (print._lastCharWhitespace()) {
|
while (print._lastCharWhitespace()) {
|
||||||
output.pop();
|
output.pop();
|
||||||
|
@ -236,12 +313,10 @@
|
||||||
|
|
||||||
|
|
||||||
var output = [];
|
var output = [];
|
||||||
if (basebaseIndentString) {
|
|
||||||
output.push(basebaseIndentString);
|
|
||||||
}
|
|
||||||
/*_____________________--------------------_____________________*/
|
/*_____________________--------------------_____________________*/
|
||||||
|
|
||||||
var insideRule = false;
|
var insideRule = false;
|
||||||
|
var insidePropertyValue = false;
|
||||||
var enteringConditionalGroup = false;
|
var enteringConditionalGroup = false;
|
||||||
var top_ch = '';
|
var top_ch = '';
|
||||||
var last_top_ch = '';
|
var last_top_ch = '';
|
||||||
|
@ -256,8 +331,12 @@
|
||||||
if (!ch) {
|
if (!ch) {
|
||||||
break;
|
break;
|
||||||
} else if (ch === '/' && peek() === '*') { /* css comment */
|
} else if (ch === '/' && peek() === '*') { /* css comment */
|
||||||
var header = lookBack("");
|
var header = indentLevel === 0;
|
||||||
print.newLine();
|
|
||||||
|
if (isAfterNewline || header) {
|
||||||
|
print.newLine();
|
||||||
|
}
|
||||||
|
|
||||||
output.push(eatComment());
|
output.push(eatComment());
|
||||||
print.newLine();
|
print.newLine();
|
||||||
if (header) {
|
if (header) {
|
||||||
|
@ -271,40 +350,46 @@
|
||||||
output.push(eatComment());
|
output.push(eatComment());
|
||||||
print.newLine();
|
print.newLine();
|
||||||
} else if (ch === '@') {
|
} else if (ch === '@') {
|
||||||
// pass along the space we found as a separate item
|
print.preserveSingleSpace();
|
||||||
if (isAfterSpace) {
|
|
||||||
print.singleSpace();
|
|
||||||
}
|
|
||||||
output.push(ch);
|
|
||||||
|
|
||||||
// strip trailing space, if present, for hash property checks
|
// deal with less propery mixins @{...}
|
||||||
var variableOrRule = peekString(": ,;{}()[]/='\"");
|
if (peek() === '{') {
|
||||||
|
output.push(eatString('}'));
|
||||||
|
} else {
|
||||||
|
output.push(ch);
|
||||||
|
|
||||||
if (variableOrRule.match(/[ :]$/)) {
|
// strip trailing space, if present, for hash property checks
|
||||||
// we have a variable or pseudo-class, add it and insert one space before continuing
|
var variableOrRule = peekString(": ,;{}()[]/='\"");
|
||||||
next();
|
|
||||||
variableOrRule = eatString(": ").replace(/\s$/, '');
|
|
||||||
output.push(variableOrRule);
|
|
||||||
print.singleSpace();
|
|
||||||
}
|
|
||||||
|
|
||||||
variableOrRule = variableOrRule.replace(/\s$/, '')
|
if (variableOrRule.match(/[ :]$/)) {
|
||||||
|
// we have a variable or pseudo-class, add it and insert one space before continuing
|
||||||
|
next();
|
||||||
|
variableOrRule = eatString(": ").replace(/\s$/, '');
|
||||||
|
output.push(variableOrRule);
|
||||||
|
print.singleSpace();
|
||||||
|
}
|
||||||
|
|
||||||
// might be a nesting at-rule
|
variableOrRule = variableOrRule.replace(/\s$/, '');
|
||||||
if (variableOrRule in css_beautify.NESTED_AT_RULE) {
|
|
||||||
nestedLevel += 1;
|
// might be a nesting at-rule
|
||||||
if (variableOrRule in css_beautify.CONDITIONAL_GROUP_RULE) {
|
if (variableOrRule in css_beautify.NESTED_AT_RULE) {
|
||||||
enteringConditionalGroup = true;
|
nestedLevel += 1;
|
||||||
|
if (variableOrRule in css_beautify.CONDITIONAL_GROUP_RULE) {
|
||||||
|
enteringConditionalGroup = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (ch === '#' && peek() === '{') {
|
||||||
|
print.preserveSingleSpace();
|
||||||
|
output.push(eatString('}'));
|
||||||
} else if (ch === '{') {
|
} else if (ch === '{') {
|
||||||
if (peek(true) === '}') {
|
if (peek(true) === '}') {
|
||||||
eatWhitespace();
|
eatWhitespace();
|
||||||
next();
|
next();
|
||||||
print.singleSpace();
|
print.singleSpace();
|
||||||
output.push("{}");
|
output.push("{");
|
||||||
print.newLine();
|
print['}'](false);
|
||||||
if (newline_between_rules && indentLevel === 0) {
|
if (newlinesFromLastWSEat < 2 && newline_between_rules && indentLevel === 0) {
|
||||||
print.newLine(true);
|
print.newLine(true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -321,25 +406,35 @@
|
||||||
}
|
}
|
||||||
} else if (ch === '}') {
|
} else if (ch === '}') {
|
||||||
outdent();
|
outdent();
|
||||||
print["}"](ch);
|
print["}"](true);
|
||||||
insideRule = false;
|
insideRule = false;
|
||||||
|
insidePropertyValue = false;
|
||||||
if (nestedLevel) {
|
if (nestedLevel) {
|
||||||
nestedLevel--;
|
nestedLevel--;
|
||||||
}
|
}
|
||||||
if (newline_between_rules && indentLevel === 0) {
|
if (newlinesFromLastWSEat < 2 && newline_between_rules && indentLevel === 0) {
|
||||||
print.newLine(true);
|
print.newLine(true);
|
||||||
}
|
}
|
||||||
} else if (ch === ":") {
|
} else if (ch === ":") {
|
||||||
eatWhitespace();
|
eatWhitespace();
|
||||||
if ((insideRule || enteringConditionalGroup) &&
|
if ((insideRule || enteringConditionalGroup) &&
|
||||||
!(lookBack("&") || foundNestedPseudoClass())) {
|
!(lookBack("&") || foundNestedPseudoClass()) &&
|
||||||
|
!lookBack("(")) {
|
||||||
// 'property: value' delimiter
|
// 'property: value' delimiter
|
||||||
// which could be in a conditional group query
|
// which could be in a conditional group query
|
||||||
output.push(':');
|
output.push(':');
|
||||||
print.singleSpace();
|
if (!insidePropertyValue) {
|
||||||
|
insidePropertyValue = true;
|
||||||
|
print.singleSpace();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// sass/less parent reference don't use a space
|
// sass/less parent reference don't use a space
|
||||||
// sass nested pseudo-class don't use a space
|
// sass nested pseudo-class don't use a space
|
||||||
|
|
||||||
|
// preserve space before pseudoclasses/pseudoelements, as it means "in any child"
|
||||||
|
if (lookBack(" ") && output[output.length - 1] !== " ") {
|
||||||
|
output.push(" ");
|
||||||
|
}
|
||||||
if (peek() === ":") {
|
if (peek() === ":") {
|
||||||
// pseudo-element
|
// pseudo-element
|
||||||
next();
|
next();
|
||||||
|
@ -350,13 +445,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ch === '"' || ch === '\'') {
|
} else if (ch === '"' || ch === '\'') {
|
||||||
if (isAfterSpace) {
|
print.preserveSingleSpace();
|
||||||
print.singleSpace();
|
|
||||||
}
|
|
||||||
output.push(eatString(ch));
|
output.push(eatString(ch));
|
||||||
} else if (ch === ';') {
|
} else if (ch === ';') {
|
||||||
|
insidePropertyValue = false;
|
||||||
output.push(ch);
|
output.push(ch);
|
||||||
print.newLine();
|
if (!eatWhitespace(true)) {
|
||||||
|
print.newLine();
|
||||||
|
}
|
||||||
} else if (ch === '(') { // may be a url
|
} else if (ch === '(') { // may be a url
|
||||||
if (lookBack("url")) {
|
if (lookBack("url")) {
|
||||||
output.push(ch);
|
output.push(ch);
|
||||||
|
@ -370,9 +466,7 @@
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parenLevel++;
|
parenLevel++;
|
||||||
if (isAfterSpace) {
|
print.preserveSingleSpace();
|
||||||
print.singleSpace();
|
|
||||||
}
|
|
||||||
output.push(ch);
|
output.push(ch);
|
||||||
eatWhitespace();
|
eatWhitespace();
|
||||||
}
|
}
|
||||||
|
@ -381,38 +475,58 @@
|
||||||
parenLevel--;
|
parenLevel--;
|
||||||
} else if (ch === ',') {
|
} else if (ch === ',') {
|
||||||
output.push(ch);
|
output.push(ch);
|
||||||
eatWhitespace();
|
if (!eatWhitespace(true) && selectorSeparatorNewline && !insidePropertyValue && parenLevel < 1) {
|
||||||
if (!insideRule && selectorSeparatorNewline && parenLevel < 1) {
|
|
||||||
print.newLine();
|
print.newLine();
|
||||||
} else {
|
} else {
|
||||||
print.singleSpace();
|
print.singleSpace();
|
||||||
}
|
}
|
||||||
|
} else if ((ch === '>' || ch === '+' || ch === '~') &&
|
||||||
|
!insidePropertyValue && parenLevel < 1) {
|
||||||
|
//handle combinator spacing
|
||||||
|
if (space_around_combinator) {
|
||||||
|
print.singleSpace();
|
||||||
|
output.push(ch);
|
||||||
|
print.singleSpace();
|
||||||
|
} else {
|
||||||
|
output.push(ch);
|
||||||
|
eatWhitespace();
|
||||||
|
// squash extra whitespace
|
||||||
|
if (ch && whiteRe.test(ch)) {
|
||||||
|
ch = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (ch === ']') {
|
} else if (ch === ']') {
|
||||||
output.push(ch);
|
output.push(ch);
|
||||||
} else if (ch === '[') {
|
} else if (ch === '[') {
|
||||||
if (isAfterSpace) {
|
print.preserveSingleSpace();
|
||||||
print.singleSpace();
|
|
||||||
}
|
|
||||||
output.push(ch);
|
output.push(ch);
|
||||||
} else if (ch === '=') { // no whitespace before or after
|
} else if (ch === '=') { // no whitespace before or after
|
||||||
eatWhitespace()
|
eatWhitespace();
|
||||||
ch = '=';
|
output.push('=');
|
||||||
output.push(ch);
|
if (whiteRe.test(ch)) {
|
||||||
} else {
|
ch = '';
|
||||||
if (isAfterSpace) {
|
|
||||||
print.singleSpace();
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
print.preserveSingleSpace();
|
||||||
output.push(ch);
|
output.push(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var sweetCode = output.join('').replace(/[\r\n\t ]+$/, '');
|
var sweetCode = '';
|
||||||
|
if (basebaseIndentString) {
|
||||||
|
sweetCode += basebaseIndentString;
|
||||||
|
}
|
||||||
|
|
||||||
|
sweetCode += output.join('').replace(/[\r\n\t ]+$/, '');
|
||||||
|
|
||||||
// establish end_with_newline
|
// establish end_with_newline
|
||||||
if (end_with_newline) {
|
if (end_with_newline) {
|
||||||
sweetCode += "\n";
|
sweetCode += '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eol !== '\n') {
|
||||||
|
sweetCode = sweetCode.replace(/[\n]/g, eol);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sweetCode;
|
return sweetCode;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user