123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- var lineBreak = require('os').EOL;
- var emptyCharacter = '';
-
- var Breaks = require('../options/format').Breaks;
- var Spaces = require('../options/format').Spaces;
-
- var Marker = require('../tokenizer/marker');
- var Token = require('../tokenizer/token');
-
- function supportsAfterClosingBrace(token) {
- return token[1][1] == 'background' || token[1][1] == 'transform' || token[1][1] == 'src';
- }
-
- function afterClosingBrace(token, valueIndex) {
- return token[valueIndex][1][token[valueIndex][1].length - 1] == Marker.CLOSE_ROUND_BRACKET;
- }
-
- function afterComma(token, valueIndex) {
- return token[valueIndex][1] == Marker.COMMA;
- }
-
- function afterSlash(token, valueIndex) {
- return token[valueIndex][1] == Marker.FORWARD_SLASH;
- }
-
- function beforeComma(token, valueIndex) {
- return token[valueIndex + 1] && token[valueIndex + 1][1] == Marker.COMMA;
- }
-
- function beforeSlash(token, valueIndex) {
- return token[valueIndex + 1] && token[valueIndex + 1][1] == Marker.FORWARD_SLASH;
- }
-
- function inFilter(token) {
- return token[1][1] == 'filter' || token[1][1] == '-ms-filter';
- }
-
- function disallowsSpace(context, token, valueIndex) {
- return !context.spaceAfterClosingBrace && supportsAfterClosingBrace(token) && afterClosingBrace(token, valueIndex) ||
- beforeSlash(token, valueIndex) ||
- afterSlash(token, valueIndex) ||
- beforeComma(token, valueIndex) ||
- afterComma(token, valueIndex);
- }
-
- function rules(context, tokens) {
- var store = context.store;
-
- for (var i = 0, l = tokens.length; i < l; i++) {
- store(context, tokens[i]);
-
- if (i < l - 1) {
- store(context, comma(context));
- }
- }
- }
-
- function body(context, tokens) {
- var lastPropertyAt = lastPropertyIndex(tokens);
-
- for (var i = 0, l = tokens.length; i < l; i++) {
- property(context, tokens, i, lastPropertyAt);
- }
- }
-
- function lastPropertyIndex(tokens) {
- var index = tokens.length - 1;
-
- for (; index >= 0; index--) {
- if (tokens[index][0] != Token.COMMENT) {
- break;
- }
- }
-
- return index;
- }
-
- function property(context, tokens, position, lastPropertyAt) {
- var store = context.store;
- var token = tokens[position];
- var isPropertyBlock = token[2][0] == Token.PROPERTY_BLOCK;
- var needsSemicolon = position < lastPropertyAt || isPropertyBlock;
- var isLast = position === lastPropertyAt;
-
- switch (token[0]) {
- case Token.AT_RULE:
- store(context, token);
- store(context, semicolon(context, Breaks.AfterProperty, false));
- break;
- case Token.AT_RULE_BLOCK:
- rules(context, token[1]);
- store(context, openBrace(context, Breaks.AfterRuleBegins, true));
- body(context, token[2]);
- store(context, closeBrace(context, Breaks.AfterRuleEnds, false, isLast));
- break;
- case Token.COMMENT:
- store(context, token);
- break;
- case Token.PROPERTY:
- store(context, token[1]);
- store(context, colon(context));
- value(context, token);
- store(context, needsSemicolon ? semicolon(context, Breaks.AfterProperty, isLast) : emptyCharacter);
- }
- }
-
- function value(context, token) {
- var store = context.store;
- var j, m;
-
- if (token[2][0] == Token.PROPERTY_BLOCK) {
- store(context, openBrace(context, Breaks.AfterBlockBegins, false));
- body(context, token[2][1]);
- store(context, closeBrace(context, Breaks.AfterBlockEnds, false, true));
- } else {
- for (j = 2, m = token.length; j < m; j++) {
- store(context, token[j]);
-
- if (j < m - 1 && (inFilter(token) || !disallowsSpace(context, token, j))) {
- store(context, Marker.SPACE);
- }
- }
- }
- }
-
- function allowsBreak(context, where) {
- return context.format && context.format.breaks[where];
- }
-
- function allowsSpace(context, where) {
- return context.format && context.format.spaces[where];
- }
-
- function openBrace(context, where, needsPrefixSpace) {
- if (context.format) {
- context.indentBy += context.format.indentBy;
- context.indentWith = context.format.indentWith.repeat(context.indentBy);
- return (needsPrefixSpace && allowsSpace(context, Spaces.BeforeBlockBegins) ? Marker.SPACE : emptyCharacter) +
- Marker.OPEN_CURLY_BRACKET +
- (allowsBreak(context, where) ? lineBreak : emptyCharacter) +
- context.indentWith;
- } else {
- return Marker.OPEN_CURLY_BRACKET;
- }
- }
-
- function closeBrace(context, where, beforeBlockEnd, isLast) {
- if (context.format) {
- context.indentBy -= context.format.indentBy;
- context.indentWith = context.format.indentWith.repeat(context.indentBy);
- return (allowsBreak(context, Breaks.AfterProperty) || beforeBlockEnd && allowsBreak(context, Breaks.BeforeBlockEnds) ? lineBreak : emptyCharacter) +
- context.indentWith +
- Marker.CLOSE_CURLY_BRACKET +
- (isLast ? emptyCharacter : (allowsBreak(context, where) ? lineBreak : emptyCharacter) + context.indentWith);
- } else {
- return Marker.CLOSE_CURLY_BRACKET;
- }
- }
-
- function colon(context) {
- return context.format ?
- Marker.COLON + (allowsSpace(context, Spaces.BeforeValue) ? Marker.SPACE : emptyCharacter) :
- Marker.COLON;
- }
-
- function semicolon(context, where, isLast) {
- return context.format ?
- Marker.SEMICOLON + (isLast || !allowsBreak(context, where) ? emptyCharacter : lineBreak + context.indentWith) :
- Marker.SEMICOLON;
- }
-
- function comma(context) {
- return context.format ?
- Marker.COMMA + (allowsBreak(context, Breaks.BetweenSelectors) ? lineBreak : emptyCharacter) + context.indentWith :
- Marker.COMMA;
- }
-
- function all(context, tokens) {
- var store = context.store;
- var token;
- var isLast;
- var i, l;
-
- for (i = 0, l = tokens.length; i < l; i++) {
- token = tokens[i];
- isLast = i == l - 1;
-
- switch (token[0]) {
- case Token.AT_RULE:
- store(context, token);
- store(context, semicolon(context, Breaks.AfterAtRule, isLast));
- break;
- case Token.AT_RULE_BLOCK:
- rules(context, token[1]);
- store(context, openBrace(context, Breaks.AfterRuleBegins, true));
- body(context, token[2]);
- store(context, closeBrace(context, Breaks.AfterRuleEnds, false, isLast));
- break;
- case Token.NESTED_BLOCK:
- rules(context, token[1]);
- store(context, openBrace(context, Breaks.AfterBlockBegins, true));
- all(context, token[2]);
- store(context, closeBrace(context, Breaks.AfterBlockEnds, true, isLast));
- break;
- case Token.COMMENT:
- store(context, token);
- store(context, allowsBreak(context, Breaks.AfterComment) ? lineBreak : emptyCharacter);
- break;
- case Token.RULE:
- rules(context, token[1]);
- store(context, openBrace(context, Breaks.AfterRuleBegins, true));
- body(context, token[2]);
- store(context, closeBrace(context, Breaks.AfterRuleEnds, false, isLast));
- break;
- }
- }
- }
-
- module.exports = {
- all: all,
- body: body,
- property: property,
- rules: rules,
- value: value
- };
|