@extjs/sencha-cmd-linux-32
Version:
Productivity and performance optimization tool for building applications with Sencha Ext JS and Sencha Touch.
217 lines (179 loc) • 5.45 kB
JavaScript
"use strict";
var Fashion = require('../Base.js');
var Type = require('../type/Type.js');
var Statics = require('../type/Statics.js');
var Types = require('../type/Types.js'),
Color = Types.Color,
Text = Types.Text,
Numeric = Types.Numeric,
List = Types.List,
Bool = Types.Bool,
Literal = Types.Literal,
ColorRGBA = Types.ColorRGBA,
ColorHSLA = Types.ColorHSLA,
FunctionCall = Types.FunctionCall;
class Parser {
constructor () {
this.index = 0;
}
_advance () {
var me = this,
buff = '',
str = me.str,
len = str.length,
isString = false,
escaped = false,
isParen = 0,
ch;
while(me.index < len) {
ch = str[me.index];
me.index++;
// whitespace
if (ch <= ' ') {
if (!isString && !isParen) {
if (buff.length) {
break;
}
continue;
}
}
// terminal char
if (ch === ';' && !isString && !escaped) {
break;
}
if (ch === '(') {
isParen++;
}
if (ch === ')') {
isParen && isParen--;
}
if (ch === ',' && !isString && !escaped && !isParen) {
if (buff.length) {
me.index--;
break;
}
else {
return ch;
}
}
if (ch === '\\') {
if (isString) {
escaped = 1;
me.index++;
continue;
}
}
if (ch === '"' || ch === "'") {
if(!isString) {
isString = ch;
}
else if (isString === ch) {
isString = false;
}
}
escaped = false;
buff += ch;
}
return buff;
}
parseValue (token) {
var rx = {
number: /^(\d+)(px|pt|pc|cm|mm|in|em|rem|ex)?$/g,
shortHexColor: /^#([A-Fa-f0-9]{3})$/,
longHexColor: /^#([A-Fa-f0-9]{6})$/,
functionCall: /^([A-Za-z0-9_]+)\((.*)\)$/,
parenList: /^\((.*?)\)$/,
},
match, value;
if (token[0] === '"' || token[0] === "'") {
value = token = token.substring(1, token.length - 1);
return new Text(value, token[0]);
}
if (token === 'true') {
return new Bool(true);
}
if (token === 'false') {
return new Bool(false);
}
if (token === 'null') {
return Literal.Null;
}
if (token === 'none') {
return Literal.None;
}
if (Fashion.Color.map[token]) {
var rgb = Color.map[token],
color = new ColorRGBA(rgb[0], rgb[1], rgb[2], rgb[3]);
color.stringified = token;
return color;
}
if (match = rx.number.exec(token)) {
return new Numeric(parseFloat(match[1]), match[2]);
}
if (match = rx.shortHexColor.exec(token)) {
return ColorRGBA.fromHex(match[1]);
}
if (match = rx.longHexColor.exec(token)) {
return ColorRGBA.fromHex(match[1]);
}
if (match = rx.functionCall.exec(token)) {
var name = match[1],
args = this.parse(match[2]).items;
if (name === 'hsla' || name === 'hsl') {
return new ColorHSLA(
Type.unbox(args[0]),
Type.unbox(args[1]),
Type.unbox(args[2]),
Type.unbox(args[3]) || 1);
}
else if(name === 'rgba' || name === 'rgb') {
return new ColorRGBA(
Type.unbox(args[0]),
Type.unbox(args[1]),
Type.unbox(args[2]),
Type.unbox(args[3]) || 1);
}
return new FunctionCall(name, args);
}
if (match = rx.parenList.exec(token)) {
return new FunctionCall(this.parse(match[1]));
}
return new Fashion.Literal(token);
}
parse (str) {
var me = this,
tokens = [],
values = [],
csv = null,
token;
me.str = str;
me.index = 0;
while (token = me._advance()) {
tokens.push(token);
}
for (var i = 0; i < tokens.length; i++) {
token = tokens[i].trim();
if (tokens[i+1] === ',') {
csv = csv || [];
csv.push(me.parseValue(token));
i++;
}
else if (csv) {
csv.push(me.parseValue(token));
values.push(new List(csv, ', '));
csv = null;
}
else {
values.push(me.parseValue(token));
}
}
if (values.length === 1) {
return values[0];
}
return new List(values, ' ');
}
}
// Fashion.apply(Parser.prototype, {
// regex:
// });
module.exports = Parser;