lib/editTree/css.js
function consumeSingleProperty(it, text) {
		var name, value, end;
		var token = it.current();

		if (!token) {
			return null;
		}

		// skip whitespace
		var ws = {'white': 1, 'line': 1, 'comment': 1};
		while ((token = it.current())) {
			if (!(token.type in ws)) {
				break;
			}
			it.next();
		}

		if (!it.hasNext()) {
			return null;
		}

		// consume property name
		token = it.current();
		name = range(token.start, token.value);
		var isAtProperty = token.value.charAt(0) == '@';
		while (token = it.next()) {
			name.end = token.end;
			if (token.type == ':' || token.type == 'white') {
				name.end = token.start;
				it.next();
				if (token.type == ':' || isAtProperty) {
					// XXX I really ashame of this hardcode, but I need
					// to stop parsing if this is an SCSS mixin call,
					// for example: @include border-radius(10px)
					break;
				}
			} else if (token.type == ';' || token.type == 'line') {
				// there’s no value, looks like a mixin
				// or a special use case:
				// user is writing a new property or abbreviation
				name.end = token.start;
				value = range(token.start, 0);
				it.next();
				break;
			}
		}

		token = it.current();
		if (!value && token) {
			if (token.type == 'line') {
				lastNewline = token;
			}
			// consume value
			value = range(token.start, token.value);
			var lastNewline;
			while ((token = it.next())) {
				value.end = token.end;
				if (token.type == 'line') {
					lastNewline = token;
				} else if (token.type == '}' || token.type == ';') {
					value.end = token.start;
					if (token.type == ';') {
						end = range(token.start, token.value);
					}
					it.next();
					break;
				} else if (token.type == ':' && lastNewline) {
					// A special case: 
					// user is writing a value before existing
					// property, but didn’t inserted closing semi-colon.
					// In this case, limit value range to previous
					// newline
					value.end = lastNewline.start;
					it._i = it.tokens.indexOf(lastNewline);
					break;
				}
			}
		}

		if (!value) {
			value = range(name.end, 0);
		}

		return {
			name: trimWhitespaceInRange(name, text),
			value: trimWhitespaceInRange(value, text, WHITESPACE_REMOVE_FROM_START | (end ? WHITESPACE_REMOVE_FROM_END : 0)),
			end: end || range(value.end, 0)
		};
	}
function consumeSingleProperty(it, text) {
		var name, value, end;
		var token = it.current();

		if (!token) {
			return null;
		}

		// skip whitespace
		var ws = {'white': 1, 'line': 1, 'comment': 1};
		while ((token = it.current())) {
			if (!(token.type in ws)) {
				break;
			}
			it.next();
		}

		if (!it.hasNext()) {
			return null;
		}

		// consume property name
		token = it.current();
		name = range(token.start, token.value);
		var isAtProperty = token.value.charAt(0) == '@';
		while (token = it.next()) {
			name.end = token.end;
			if (token.type == ':' || token.type == 'white') {
				name.end = token.start;
				it.next();
				if (token.type == ':' || isAtProperty) {
					// XXX I really ashame of this hardcode, but I need
					// to stop parsing if this is an SCSS mixin call,
					// for example: @include border-radius(10px)
					break;
				}
			} else if (token.type == ';' || token.type == 'line') {
				// there’s no value, looks like a mixin
				// or a special use case:
				// user is writing a new property or abbreviation
				name.end = token.start;
				value = range(token.start, 0);
				it.next();
				break;
			}
		}

		token = it.current();
		if (!value && token) {
			if (token.type == 'line') {
				lastNewline = token;
			}
			// consume value
			value = range(token.start, token.value);
			var lastNewline;
			while ((token = it.next())) {
				value.end = token.end;
				if (token.type == 'line') {
					lastNewline = token;
				} else if (token.type == '}' || token.type == ';') {
					value.end = token.start;
					if (token.type == ';') {
						end = range(token.start, token.value);
					}
					it.next();
					break;
				} else if (token.type == ':' && lastNewline) {
					// A special case: 
					// user is writing a value before existing
					// property, but didn’t inserted closing semi-colon.
					// In this case, limit value range to previous
					// newline
					value.end = lastNewline.start;
					it._i = it.tokens.indexOf(lastNewline);
					break;
				}
			}
		}

		if (!value) {
			value = range(name.end, 0);
		}

		return {
			name: trimWhitespaceInRange(name, text),
			value: trimWhitespaceInRange(value, text, WHITESPACE_REMOVE_FROM_START | (end ? WHITESPACE_REMOVE_FROM_END : 0)),
			end: end || range(value.end, 0)
		};
	}
function consumeSingleProperty ( it , text ) { var name , value , end ; var token = it . current ( ) ; if ( ! token ) { return null ; } // skip whitespace var ws = { 'white' : 1 , 'line' : 1 , 'comment' : 1 } ; while ( ( token = it . current ( ) ) ) { if ( ! ( token . type in ws ) ) { break ; } it . next ( ) ; } if ( ! it . hasNext ( ) ) { return null ; } // consume property name token = it . current ( ) ; name = range ( token . start , token . value ) ; var isAtProperty = token . value . charAt ( 0 ) == '@' ; while ( token = it . next ( ) ) { name . end = token . end ; if ( token . type == ':' || token . type == 'white' ) { name . end = token . start ; it . next ( ) ; if ( token . type == ':' || isAtProperty ) { // XXX I really ashame of this hardcode, but I need // to stop parsing if this is an SCSS mixin call, // for example: @include border-radius(10px) break ; } } else if ( token . type == ';' || token . type == 'line' ) { // there’s no value, looks like a mixin // or a special use case: // user is writing a new property or abbreviation name . end = token . start ; value = range ( token . start , 0 ) ; it . next ( ) ; break ; } } token = it . current ( ) ; if ( ! value && token ) { if ( token . type == 'line' ) { lastNewline = token ; } // consume value value = range ( token . start , token . value ) ; var lastNewline ; while ( ( token = it . next ( ) ) ) { value . end = token . end ; if ( token . type == 'line' ) { lastNewline = token ; } else if ( token . type == '}' || token . type == ';' ) { value . end = token . start ; if ( token . type == ';' ) { end = range ( token . start , token . value ) ; } it . next ( ) ; break ; } else if ( token . type == ':' && lastNewline ) { // A special case:  // user is writing a value before existing // property, but didn’t inserted closing semi-colon. // In this case, limit value range to previous // newline value . end = lastNewline . start ; it . _i = it . tokens . indexOf ( lastNewline ) ; break ; } } } if ( ! value ) { value = range ( name . end , 0 ) ; } return { name : trimWhitespaceInRange ( name , text ) , value : trimWhitespaceInRange ( value , text , WHITESPACE_REMOVE_FROM_START | ( end ? WHITESPACE_REMOVE_FROM_END : 0 ) ) , end : end || range ( value . end , 0 ) } ; }
Consumes CSS property and value from current token
iterator state. Offsets iterator pointer into token
that can be used for next value consmption
@param  {TokenIterator} it
@param  {String} text
@return {Object}    Object with `name` and `value` properties
ar ranges. Value range can be zero-length.
Consumes CSS property and value from current token iterator state . Offsets iterator pointer into token that can be used for next value consmption