Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / jsbuilder / src / Parser.js
diff --git a/jsbuilder/src/Parser.js b/jsbuilder/src/Parser.js
new file mode 100644 (file)
index 0000000..00ba569
--- /dev/null
@@ -0,0 +1,156 @@
+// Singleton
+Parser = new(Ext.extend(Object, {
+    params: {},
+
+    parse: function(filename) {
+        var stream = new Stream(filename),
+            ret;
+
+        Loader.require('Parser.Statement');
+        ret = (new Parser.Statement()).parse(stream);
+        stream.close();
+
+        return ret;
+    },
+
+    evaluate: function(name, value) {
+        var modifier = null,
+            param = (this.params.hasOwnProperty(name)) ? this.params[name] : false,
+            match;
+
+        if (value === undefined) {
+            value = true;
+        }
+
+        if (Ext.isString(value)) {
+            match = value.match(/^(\!|<=|>=|<|>)/);
+
+            if (match) {
+                modifier = match[0];
+                value = value.slice(modifier.length);
+            }
+
+            // Boolean
+            if (value === 'true') {
+                value = true;
+            }
+            else if (value === 'false') {
+                value = false;
+            }
+            // Numeric
+            else if (!isNaN(value)) {
+                value = parseFloat(value);
+            }
+        }
+
+        switch (modifier) {
+            case '!':
+                return (param !== value);
+            case '>':
+                return (param > value);
+            case '<':
+                return (param < value);
+            case '<=':
+                return (param <= value);
+            case '>=':
+                return (param >= value);
+            default:
+                return (param === value);
+        }
+    },
+
+    setParams: function(params) {
+        this.params = params || {};
+    },
+
+    isCloseOf: function(str, statement) {
+        if (!statement.type) {
+            return false;
+        }
+
+        return str.trim().match(new RegExp("^\\/\\/(?:\\t|\\s)*<\\/" + ((statement.isInverted) ? "!" : "") + statement.type + ">$")) !== null;
+    },
+
+    isStatement: function(str) {
+        return this.parseStatementParts(str) !== null;
+    },
+
+    parseStatementParts: function(str) {
+        return str.trim().match(/^\/\/(?:\t|\s)*<([^\/]+)>$/);
+    },
+
+    parseStatementProperties: function(str) {
+        var properties = {},
+            expect = function(regexp) {
+                var result = str.match(regexp);
+
+                if (result !== null) {
+                    str = str.slice(result[0].length);
+                    return result[0];
+                }
+
+                return null;
+            },
+            name, equalSign, valueWrapper, valueCheck, value;
+
+        while (str.length > 0) {
+            expect(/^[^\w]+/i);
+            name = expect(/^[\w]+/i);
+
+            if (name === null) {
+                break;
+            }
+
+            equalSign = expect(/^=/);
+
+            if (equalSign === null) {
+                properties[name] = true;
+                continue;
+            }
+
+            valueWrapper = expect(/^('|")/i);
+            valueCheck = valueWrapper || "\\s";
+
+            value = expect(new RegExp('^[^' + valueCheck + ']+'));
+
+            if (valueWrapper !== null) {
+                expect(new RegExp(valueWrapper));
+            }
+
+            properties[name] = value;
+        }
+
+        return properties;
+    },
+
+    parseStatement: function(string) {
+        var str = string.trim(),
+            parts = this.parseStatementParts(str),
+            typeMatch, statement;
+
+        // Check if it's actually a valid statement
+        if (parts === null) {
+            return false;
+        }
+
+        str = parts[1];
+
+        typeMatch = str.match(/^(\!)?([\w]+)/i);
+
+        if (typeMatch === null) {
+            return false;
+        }
+
+        statement = {
+            properties: {}
+        };
+
+        statement.type = typeMatch[2];
+        statement.isInverted = (typeMatch[1] !== undefined);
+
+        str = str.substr(typeMatch[0].length, str.length).trim();
+        statement.properties = this.parseStatementProperties(str);
+
+        return statement;
+    }
+}));