You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							247 lines
						
					
					
						
							7.3 KiB
						
					
					
				
			
		
		
	
	
							247 lines
						
					
					
						
							7.3 KiB
						
					
					
				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 propertyValue = token[2]; | 
						|
  var isPropertyBlock = propertyValue && propertyValue[0] === Token.PROPERTY_BLOCK; | 
						|
 | 
						|
  var needsSemicolon; | 
						|
  if ( context.format ) { | 
						|
    if ( context.format.semicolonAfterLastProperty || isPropertyBlock ) { | 
						|
      needsSemicolon = true; | 
						|
    } else if ( position < lastPropertyAt ) { | 
						|
      needsSemicolon = true; | 
						|
    } else { | 
						|
      needsSemicolon = false; | 
						|
    } | 
						|
  } else { | 
						|
    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)); | 
						|
      if (propertyValue) { | 
						|
        value(context, token); | 
						|
      } | 
						|
      store(context, needsSemicolon ? semicolon(context, Breaks.AfterProperty, isLast) : emptyCharacter); | 
						|
      break; | 
						|
    case Token.RAW: | 
						|
      store(context, token); | 
						|
  } | 
						|
} | 
						|
 | 
						|
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) ? context.format.breakWith : 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) ? context.format.breakWith : emptyCharacter) + | 
						|
      context.indentWith + | 
						|
      Marker.CLOSE_CURLY_BRACKET + | 
						|
      (isLast ? emptyCharacter : (allowsBreak(context, where) ? context.format.breakWith : 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 : context.format.breakWith + context.indentWith) : | 
						|
    Marker.SEMICOLON; | 
						|
} | 
						|
 | 
						|
function comma(context) { | 
						|
  return context.format ? | 
						|
    Marker.COMMA + (allowsBreak(context, Breaks.BetweenSelectors) ? context.format.breakWith : 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) ? context.format.breakWith : emptyCharacter); | 
						|
        break; | 
						|
      case Token.RAW: | 
						|
        store(context, token); | 
						|
        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 | 
						|
};
 | 
						|
 |