diff --git a/.jshintrc b/.jshintrc index 5c138e362515..7d594bea02cc 100644 --- a/.jshintrc +++ b/.jshintrc @@ -6,9 +6,7 @@ "globals": { "define": true, "require": true, - "console": true, - "jsonPath": false, - "rison": false + "console": true }, "camelcase": false, diff --git a/src/kibana/apps/discover/directives/field_chooser.js b/src/kibana/apps/discover/directives/field_chooser.js index 866ce5ea93c5..95838a7baaf7 100644 --- a/src/kibana/apps/discover/directives/field_chooser.js +++ b/src/kibana/apps/discover/directives/field_chooser.js @@ -2,6 +2,7 @@ define(function (require) { var app = require('modules').get('app/discover'); var html = require('text!../partials/field_chooser.html'); var _ = require('lodash'); + var jsonPath = require('jsonpath'); require('directives/css_truncate'); require('directives/field_name'); diff --git a/src/kibana/components/state_management/_state_sync.js b/src/kibana/components/state_management/_state_sync.js index 62955b5f06db..5c63dfa8fef1 100644 --- a/src/kibana/components/state_management/_state_sync.js +++ b/src/kibana/components/state_management/_state_sync.js @@ -2,6 +2,7 @@ define(function (require) { var angular = require('angular'); var _ = require('lodash'); + var rison = require('utils/rison'); // invokable/private angular dep return function ($location) { diff --git a/src/kibana/components/state_management/app_state.js b/src/kibana/components/state_management/app_state.js index e6e8329cc9e9..874a43ff6a6a 100644 --- a/src/kibana/components/state_management/app_state.js +++ b/src/kibana/components/state_management/app_state.js @@ -1,8 +1,5 @@ define(function (require) { var module = require('modules').get('kibana/factories'); - var angular = require('angular'); - var _ = require('lodash'); - var rison = require('utils/rison'); require('./global_state'); diff --git a/src/kibana/components/state_management/global_state.js b/src/kibana/components/state_management/global_state.js index 9362d2178471..538dcee908b3 100644 --- a/src/kibana/components/state_management/global_state.js +++ b/src/kibana/components/state_management/global_state.js @@ -2,7 +2,7 @@ define(function (require) { var _ = require('lodash'); var angular = require('angular'); var qs = require('utils/query_string'); - + var rison = require('utils/rison'); var module = require('modules').get('kibana/global_state'); diff --git a/src/kibana/controllers/kibana.js b/src/kibana/controllers/kibana.js index 7294968ed4b8..dfb344ec074c 100644 --- a/src/kibana/controllers/kibana.js +++ b/src/kibana/controllers/kibana.js @@ -4,6 +4,7 @@ define(function (require) { var moment = require('moment'); var nextTick = require('utils/next_tick'); var qs = require('utils/query_string'); + var rison = require('utils/rison'); require('config/config'); require('courier/courier'); diff --git a/src/kibana/directives/table.js b/src/kibana/directives/table.js index c8c6d19fd3d1..21b347ea3d22 100644 --- a/src/kibana/directives/table.js +++ b/src/kibana/directives/table.js @@ -3,7 +3,7 @@ define(function (require) { var _ = require('lodash'); var nextTick = require('utils/next_tick'); var $ = require('jquery'); - var jsonpath = require('jsonpath'); + var jsonPath = require('jsonpath'); require('directives/truncated'); require('directives/infinite_scroll'); diff --git a/src/kibana/index.js b/src/kibana/index.js index 3b84325099d6..caaea22d774c 100644 --- a/src/kibana/index.js +++ b/src/kibana/index.js @@ -8,7 +8,6 @@ define(function (require) { var modules = require('modules'); var routes = require('routes'); - require('utils/rison'); require('elasticsearch'); require('angular-route'); require('angular-bindonce'); diff --git a/src/kibana/utils/rison.js b/src/kibana/utils/rison.js index 819c57ec60e2..211671513d06 100644 --- a/src/kibana/utils/rison.js +++ b/src/kibana/utils/rison.js @@ -1,499 +1,498 @@ -/* jshint ignore:start */ +define(function () { + var rison = {}; + /* jshint ignore:start */ + ////////////////////////////////////////////////// + // + // the stringifier is based on + // http://json.org/json.js as of 2006-04-28 from json.org + // the parser is based on + // http://osteele.com/sources/openlaszlo/json + // -////////////////////////////////////////////////// -// -// the stringifier is based on -// http://json.org/json.js as of 2006-04-28 from json.org -// the parser is based on -// http://osteele.com/sources/openlaszlo/json -// + /** + * rules for an uri encoder that is more tolerant than encodeURIComponent + * + * encodeURIComponent passes ~!*()-_.' + * + * we also allow ,:@$/ + * + */ + rison.uri_ok = { // ok in url paths and in form query args + '~': true, '!': true, '*': true, '(': true, ')': true, + '-': true, '_': true, '.': true, ',': true, + ':': true, '@': true, '$': true, + "'": true, '/': true + }; -if (typeof rison == 'undefined') - window.rison = {}; + /* + * we divide the uri-safe glyphs into three sets + * - used by rison ' ! : ( ) , + * - not common in strings, reserved * @ $ & ; = + * + * we define as anything that's not forbidden + */ -/** - * rules for an uri encoder that is more tolerant than encodeURIComponent - * - * encodeURIComponent passes ~!*()-_.' - * - * we also allow ,:@$/ - * - */ -rison.uri_ok = { // ok in url paths and in form query args - '~': true, '!': true, '*': true, '(': true, ')': true, - '-': true, '_': true, '.': true, ',': true, - ':': true, '@': true, '$': true, - "'": true, '/': true -}; + /** + * punctuation characters that are legal inside ids. + */ + // this var isn't actually used + //rison.idchar_punctuation = "_-./~"; -/* - * we divide the uri-safe glyphs into three sets - * - used by rison ' ! : ( ) , - * - not common in strings, reserved * @ $ & ; = - * - * we define as anything that's not forbidden - */ - -/** - * punctuation characters that are legal inside ids. - */ -// this var isn't actually used -//rison.idchar_punctuation = "_-./~"; - -(function () { - var l = []; - for (var hi = 0; hi < 16; hi++) { - for (var lo = 0; lo < 16; lo++) { - if (hi+lo == 0) continue; - var c = String.fromCharCode(hi*16 + lo); - if (! /\w|[-_.\/~]/.test(c)) - l.push('\\u00' + hi.toString(16) + lo.toString(16)); - } - } - /** - * characters that are illegal inside ids. - * and classes are illegal in ids. - * - */ - rison.not_idchar = l.join('') - //idcrx = new RegExp('[' + rison.not_idchar + ']'); - //console.log('NOT', (idcrx.test(' ')) ); -})(); -//rison.not_idchar = " \t\r\n\"<>[]{}'!=:(),*@$;&"; -rison.not_idchar = " '!:(),*@$"; + (function () { + var l = []; + for (var hi = 0; hi < 16; hi++) { + for (var lo = 0; lo < 16; lo++) { + if (hi+lo == 0) continue; + var c = String.fromCharCode(hi*16 + lo); + if (! /\w|[-_.\/~]/.test(c)) + l.push('\\u00' + hi.toString(16) + lo.toString(16)); + } + } + /** + * characters that are illegal inside ids. + * and classes are illegal in ids. + * + */ + rison.not_idchar = l.join('') + //idcrx = new RegExp('[' + rison.not_idchar + ']'); + //console.log('NOT', (idcrx.test(' ')) ); + })(); + //rison.not_idchar = " \t\r\n\"<>[]{}'!=:(),*@$;&"; + rison.not_idchar = " '!:(),*@$"; -/** - * characters that are illegal as the start of an id - * this is so ids can't look like numbers. - */ -rison.not_idstart = "-0123456789"; + /** + * characters that are illegal as the start of an id + * this is so ids can't look like numbers. + */ + rison.not_idstart = "-0123456789"; -(function () { - var idrx = '[^' + rison.not_idstart + rison.not_idchar + - '][^' + rison.not_idchar + ']*'; + (function () { + var idrx = '[^' + rison.not_idstart + rison.not_idchar + + '][^' + rison.not_idchar + ']*'; - rison.id_ok = new RegExp('^' + idrx + '$'); + rison.id_ok = new RegExp('^' + idrx + '$'); - // regexp to find the end of an id when parsing - // g flag on the regexp is necessary for iterative regexp.exec() - rison.next_id = new RegExp(idrx, 'g'); -})(); + // regexp to find the end of an id when parsing + // g flag on the regexp is necessary for iterative regexp.exec() + rison.next_id = new RegExp(idrx, 'g'); + })(); -/** - * this is like encodeURIComponent() but quotes fewer characters. - * - * @see rison.uri_ok - * - * encodeURIComponent passes ~!*()-_.' - * rison.quote also passes ,:@$/ - * and quotes " " as "+" instead of "%20" - */ -rison.quote = function(x) { - if (/^[-A-Za-z0-9~!*()_.',:@$\/]*$/.test(x)) - return x; + /** + * this is like encodeURIComponent() but quotes fewer characters. + * + * @see rison.uri_ok + * + * encodeURIComponent passes ~!*()-_.' + * rison.quote also passes ,:@$/ + * and quotes " " as "+" instead of "%20" + */ + rison.quote = function(x) { + if (/^[-A-Za-z0-9~!*()_.',:@$\/]*$/.test(x)) + return x; - return encodeURIComponent(x) - .replace('%2C', ',', 'g') - .replace('%3A', ':', 'g') - .replace('%40', '@', 'g') - .replace('%24', '$', 'g') - .replace('%2F', '/', 'g') - .replace('%20', '+', 'g'); -}; + return encodeURIComponent(x) + .replace('%2C', ',', 'g') + .replace('%3A', ':', 'g') + .replace('%40', '@', 'g') + .replace('%24', '$', 'g') + .replace('%2F', '/', 'g') + .replace('%20', '+', 'g'); + }; -// -// based on json.js 2006-04-28 from json.org -// license: http://www.json.org/license.html -// -// hacked by nix for use in uris. -// + // + // based on json.js 2006-04-28 from json.org + // license: http://www.json.org/license.html + // + // hacked by nix for use in uris. + // -(function () { - var sq = { // url-ok but quoted in strings - "'": true, '!': true - }, - enc = function (v) { - if (v && typeof v.toJSON === 'function') v = v.toJSON(); - var fn = s[typeof v]; - if (fn) return fn(v); - }, - s = { - array: function (x) { - var a = ['!('], b, f, i, l = x.length, v; - for (i = 0; i < l; i += 1) { - v = enc(x[i]); - if (typeof v == 'string') { - if (b) { - a[a.length] = ','; - } - a[a.length] = v; - b = true; - } - } - a[a.length] = ')'; - return a.join(''); - }, - 'boolean': function (x) { - if (x) - return '!t'; - return '!f' - }, - 'null': function (x) { - return "!n"; - }, - number: function (x) { - if (!isFinite(x)) - return '!n'; - // strip '+' out of exponent, '-' is ok though - return String(x).replace(/\+/,''); - }, - object: function (x) { - if (x) { - if (x instanceof Array) { - return s.array(x); - } + (function () { + var sq = { // url-ok but quoted in strings + "'": true, '!': true + }, + enc = function (v) { + if (v && typeof v.toJSON === 'function') v = v.toJSON(); + var fn = s[typeof v]; + if (fn) return fn(v); + }, + s = { + array: function (x) { + var a = ['!('], b, f, i, l = x.length, v; + for (i = 0; i < l; i += 1) { + v = enc(x[i]); + if (typeof v == 'string') { + if (b) { + a[a.length] = ','; + } + a[a.length] = v; + b = true; + } + } + a[a.length] = ')'; + return a.join(''); + }, + 'boolean': function (x) { + if (x) + return '!t'; + return '!f' + }, + 'null': function (x) { + return "!n"; + }, + number: function (x) { + if (!isFinite(x)) + return '!n'; + // strip '+' out of exponent, '-' is ok though + return String(x).replace(/\+/,''); + }, + object: function (x) { + if (x) { + if (x instanceof Array) { + return s.array(x); + } - var a = ['('], b, f, i, v, ki, ks=[]; - for (i in x) - ks[ks.length] = i; - ks.sort(); - for (ki = 0; ki < ks.length; ki++) { - i = ks[ki]; - v = enc(x[i]); - if (typeof v == 'string') { - if (b) { - a[a.length] = ','; - } - a.push(s.string(i), ':', v); - b = true; - } - } - a[a.length] = ')'; - return a.join(''); - } - return '!n'; - }, - string: function (x) { - if (x == '') - return "''"; + var a = ['('], b, f, i, v, ki, ks=[]; + for (i in x) + ks[ks.length] = i; + ks.sort(); + for (ki = 0; ki < ks.length; ki++) { + i = ks[ki]; + v = enc(x[i]); + if (typeof v == 'string') { + if (b) { + a[a.length] = ','; + } + a.push(s.string(i), ':', v); + b = true; + } + } + a[a.length] = ')'; + return a.join(''); + } + return '!n'; + }, + string: function (x) { + if (x == '') + return "''"; - if (rison.id_ok.test(x)) - return x; + if (rison.id_ok.test(x)) + return x; - x = x.replace(/(['!])/g, function(a, b) { - if (sq[b]) return '!'+b; - return b; - }); - return "'" + x + "'"; - }, - undefined: function (x) { - // ignore undefined just like JSON - // throw new Error("rison can't encode the undefined value"); - } - }; + x = x.replace(/(['!])/g, function(a, b) { + if (sq[b]) return '!'+b; + return b; + }); + return "'" + x + "'"; + }, + undefined: function (x) { + // ignore undefined just like JSON + // throw new Error("rison can't encode the undefined value"); + } + }; - /** - * rison-encode a javascript structure - * - * implemementation based on Douglas Crockford's json.js: - * http://json.org/json.js as of 2006-04-28 from json.org - * - */ - rison.encode = function (v) { - return enc(v); - }; + /** + * rison-encode a javascript structure + * + * implemementation based on Douglas Crockford's json.js: + * http://json.org/json.js as of 2006-04-28 from json.org + * + */ + rison.encode = function (v) { + return enc(v); + }; - /** - * rison-encode a javascript object without surrounding parens - * - */ - rison.encode_object = function (v) { - if (typeof v != 'object' || v === null || v instanceof Array) - throw new Error("rison.encode_object expects an object argument"); - var r = s[typeof v](v); - return r.substring(1, r.length-1); - }; + /** + * rison-encode a javascript object without surrounding parens + * + */ + rison.encode_object = function (v) { + if (typeof v != 'object' || v === null || v instanceof Array) + throw new Error("rison.encode_object expects an object argument"); + var r = s[typeof v](v); + return r.substring(1, r.length-1); + }; - /** - * rison-encode a javascript array without surrounding parens - * - */ - rison.encode_array = function (v) { - if (!(v instanceof Array)) - throw new Error("rison.encode_array expects an array argument"); - var r = s[typeof v](v); - return r.substring(2, r.length-1); - }; + /** + * rison-encode a javascript array without surrounding parens + * + */ + rison.encode_array = function (v) { + if (!(v instanceof Array)) + throw new Error("rison.encode_array expects an array argument"); + var r = s[typeof v](v); + return r.substring(2, r.length-1); + }; - /** - * rison-encode and uri-encode a javascript structure - * - */ - rison.encode_uri = function (v) { - return rison.quote(s[typeof v](v)); - }; + /** + * rison-encode and uri-encode a javascript structure + * + */ + rison.encode_uri = function (v) { + return rison.quote(s[typeof v](v)); + }; -})(); + })(); -// -// based on openlaszlo-json and hacked by nix for use in uris. -// -// Author: Oliver Steele -// Copyright: Copyright 2006 Oliver Steele. All rights reserved. -// Homepage: http://osteele.com/sources/openlaszlo/json -// License: MIT License. -// Version: 1.0 + // + // based on openlaszlo-json and hacked by nix for use in uris. + // + // Author: Oliver Steele + // Copyright: Copyright 2006 Oliver Steele. All rights reserved. + // Homepage: http://osteele.com/sources/openlaszlo/json + // License: MIT License. + // Version: 1.0 -/** - * parse a rison string into a javascript structure. - * - * this is the simplest decoder entry point. - * - * based on Oliver Steele's OpenLaszlo-JSON - * http://osteele.com/sources/openlaszlo/json - */ -rison.decode = function(r) { - var errcb = function(e) { throw Error('rison decoder error: ' + e); }; - var p = new rison.parser(errcb); - return p.parse(r); -}; + /** + * parse a rison string into a javascript structure. + * + * this is the simplest decoder entry point. + * + * based on Oliver Steele's OpenLaszlo-JSON + * http://osteele.com/sources/openlaszlo/json + */ + rison.decode = function(r) { + var errcb = function(e) { throw Error('rison decoder error: ' + e); }; + var p = new rison.parser(errcb); + return p.parse(r); + }; -/** - * parse an o-rison string into a javascript structure. - * - * this simply adds parentheses around the string before parsing. - */ -rison.decode_object = function(r) { - return rison.decode('('+r+')'); -}; + /** + * parse an o-rison string into a javascript structure. + * + * this simply adds parentheses around the string before parsing. + */ + rison.decode_object = function(r) { + return rison.decode('('+r+')'); + }; -/** - * parse an a-rison string into a javascript structure. - * - * this simply adds array markup around the string before parsing. - */ -rison.decode_array = function(r) { - return rison.decode('!('+r+')'); -}; + /** + * parse an a-rison string into a javascript structure. + * + * this simply adds array markup around the string before parsing. + */ + rison.decode_array = function(r) { + return rison.decode('!('+r+')'); + }; -/** - * construct a new parser object for reuse. - * - * @constructor - * @class A Rison parser class. You should probably - * use rison.decode instead. - * @see rison.decode - */ -rison.parser = function (errcb) { - this.errorHandler = errcb; -}; + /** + * construct a new parser object for reuse. + * + * @constructor + * @class A Rison parser class. You should probably + * use rison.decode instead. + * @see rison.decode + */ + rison.parser = function (errcb) { + this.errorHandler = errcb; + }; -/** - * a string containing acceptable whitespace characters. - * by default the rison decoder tolerates no whitespace. - * to accept whitespace set rison.parser.WHITESPACE = " \t\n\r\f"; - */ -rison.parser.WHITESPACE = ""; + /** + * a string containing acceptable whitespace characters. + * by default the rison decoder tolerates no whitespace. + * to accept whitespace set rison.parser.WHITESPACE = " \t\n\r\f"; + */ + rison.parser.WHITESPACE = ""; -// expose this as-is? -rison.parser.prototype.setOptions = function (options) { - if (options['errorHandler']) - this.errorHandler = options.errorHandler; -}; + // expose this as-is? + rison.parser.prototype.setOptions = function (options) { + if (options['errorHandler']) + this.errorHandler = options.errorHandler; + }; -/** - * parse a rison string into a javascript structure. - */ -rison.parser.prototype.parse = function (str) { - this.string = str; - this.index = 0; - this.message = null; - var value = this.readValue(); - if (!this.message && this.next()) - value = this.error("unable to parse string as rison: '" + rison.encode(str) + "'"); - if (this.message && this.errorHandler) - this.errorHandler(this.message, this.index); - return value; -}; + /** + * parse a rison string into a javascript structure. + */ + rison.parser.prototype.parse = function (str) { + this.string = str; + this.index = 0; + this.message = null; + var value = this.readValue(); + if (!this.message && this.next()) + value = this.error("unable to parse string as rison: '" + rison.encode(str) + "'"); + if (this.message && this.errorHandler) + this.errorHandler(this.message, this.index); + return value; + }; -rison.parser.prototype.error = function (message) { - if (typeof(console) != 'undefined') - console.log('rison parser error: ', message); - this.message = message; - return undefined; -} + rison.parser.prototype.error = function (message) { + if (typeof(console) != 'undefined') + console.log('rison parser error: ', message); + this.message = message; + return undefined; + } -rison.parser.prototype.readValue = function () { - var c = this.next(); - var fn = c && this.table[c]; + rison.parser.prototype.readValue = function () { + var c = this.next(); + var fn = c && this.table[c]; - if (fn) - return fn.apply(this); + if (fn) + return fn.apply(this); - // fell through table, parse as an id + // fell through table, parse as an id - var s = this.string; - var i = this.index-1; + var s = this.string; + var i = this.index-1; - // Regexp.lastIndex may not work right in IE before 5.5? - // g flag on the regexp is also necessary - rison.next_id.lastIndex = i; - var m = rison.next_id.exec(s); + // Regexp.lastIndex may not work right in IE before 5.5? + // g flag on the regexp is also necessary + rison.next_id.lastIndex = i; + var m = rison.next_id.exec(s); - // console.log('matched id', i, r.lastIndex); + // console.log('matched id', i, r.lastIndex); - if (m.length > 0) { - var id = m[0]; - this.index = i+id.length; - return id; // a string - } + if (m.length > 0) { + var id = m[0]; + this.index = i+id.length; + return id; // a string + } - if (c) return this.error("invalid character: '" + c + "'"); - return this.error("empty expression"); -} + if (c) return this.error("invalid character: '" + c + "'"); + return this.error("empty expression"); + } -rison.parser.parse_array = function (parser) { - var ar = []; - var c; - while ((c = parser.next()) != ')') { - if (!c) return parser.error("unmatched '!('"); - if (ar.length) { - if (c != ',') - parser.error("missing ','"); - } else if (c == ',') { - return parser.error("extra ','"); - } else - --parser.index; - var n = parser.readValue(); - if (typeof n == "undefined") return undefined; - ar.push(n); - } - return ar; -}; + rison.parser.parse_array = function (parser) { + var ar = []; + var c; + while ((c = parser.next()) != ')') { + if (!c) return parser.error("unmatched '!('"); + if (ar.length) { + if (c != ',') + parser.error("missing ','"); + } else if (c == ',') { + return parser.error("extra ','"); + } else + --parser.index; + var n = parser.readValue(); + if (typeof n == "undefined") return undefined; + ar.push(n); + } + return ar; + }; -rison.parser.bangs = { - t: true, - f: false, - n: null, - '(': rison.parser.parse_array -} + rison.parser.bangs = { + t: true, + f: false, + n: null, + '(': rison.parser.parse_array + } -rison.parser.prototype.table = { - '!': function () { - var s = this.string; - var c = s.charAt(this.index++); - if (!c) return this.error('"!" at end of input'); - var x = rison.parser.bangs[c]; - if (typeof(x) == 'function') { - return x.call(null, this); - } else if (typeof(x) == 'undefined') { - return this.error('unknown literal: "!' + c + '"'); - } - return x; - }, - '(': function () { - var o = {}; - var c; - var count = 0; - while ((c = this.next()) != ')') { - if (count) { - if (c != ',') - this.error("missing ','"); - } else if (c == ',') { - return this.error("extra ','"); - } else - --this.index; - var k = this.readValue(); - if (typeof k == "undefined") return undefined; - if (this.next() != ':') return this.error("missing ':'"); - var v = this.readValue(); - if (typeof v == "undefined") return undefined; - o[k] = v; - count++; - } - return o; - }, - "'": function () { - var s = this.string; - var i = this.index; - var start = i; - var segments = []; - var c; - while ((c = s.charAt(i++)) != "'") { - //if (i == s.length) return this.error('unmatched "\'"'); - if (!c) return this.error('unmatched "\'"'); - if (c == '!') { - if (start < i-1) - segments.push(s.slice(start, i-1)); - c = s.charAt(i++); - if ("!'".indexOf(c) >= 0) { - segments.push(c); - } else { - return this.error('invalid string escape: "!'+c+'"'); - } - start = i; - } - } - if (start < i-1) - segments.push(s.slice(start, i-1)); - this.index = i; - return segments.length == 1 ? segments[0] : segments.join(''); - }, - // Also any digit. The statement that follows this table - // definition fills in the digits. - '-': function () { - var s = this.string; - var i = this.index; - var start = i-1; - var state = 'int'; - var permittedSigns = '-'; - var transitions = { - 'int+.': 'frac', - 'int+e': 'exp', - 'frac+e': 'exp' - }; - do { - var c = s.charAt(i++); - if (!c) break; - if ('0' <= c && c <= '9') continue; - if (permittedSigns.indexOf(c) >= 0) { - permittedSigns = ''; - continue; - } - state = transitions[state+'+'+c.toLowerCase()]; - if (state == 'exp') permittedSigns = '-'; - } while (state); - this.index = --i; - s = s.slice(start, i) - if (s == '-') return this.error("invalid number"); - return Number(s); - } -}; -// copy table['-'] to each of table[i] | i <- '0'..'9': -(function (table) { - for (var i = 0; i <= 9; i++) - table[String(i)] = table['-']; -})(rison.parser.prototype.table); + rison.parser.prototype.table = { + '!': function () { + var s = this.string; + var c = s.charAt(this.index++); + if (!c) return this.error('"!" at end of input'); + var x = rison.parser.bangs[c]; + if (typeof(x) == 'function') { + return x.call(null, this); + } else if (typeof(x) == 'undefined') { + return this.error('unknown literal: "!' + c + '"'); + } + return x; + }, + '(': function () { + var o = {}; + var c; + var count = 0; + while ((c = this.next()) != ')') { + if (count) { + if (c != ',') + this.error("missing ','"); + } else if (c == ',') { + return this.error("extra ','"); + } else + --this.index; + var k = this.readValue(); + if (typeof k == "undefined") return undefined; + if (this.next() != ':') return this.error("missing ':'"); + var v = this.readValue(); + if (typeof v == "undefined") return undefined; + o[k] = v; + count++; + } + return o; + }, + "'": function () { + var s = this.string; + var i = this.index; + var start = i; + var segments = []; + var c; + while ((c = s.charAt(i++)) != "'") { + //if (i == s.length) return this.error('unmatched "\'"'); + if (!c) return this.error('unmatched "\'"'); + if (c == '!') { + if (start < i-1) + segments.push(s.slice(start, i-1)); + c = s.charAt(i++); + if ("!'".indexOf(c) >= 0) { + segments.push(c); + } else { + return this.error('invalid string escape: "!'+c+'"'); + } + start = i; + } + } + if (start < i-1) + segments.push(s.slice(start, i-1)); + this.index = i; + return segments.length == 1 ? segments[0] : segments.join(''); + }, + // Also any digit. The statement that follows this table + // definition fills in the digits. + '-': function () { + var s = this.string; + var i = this.index; + var start = i-1; + var state = 'int'; + var permittedSigns = '-'; + var transitions = { + 'int+.': 'frac', + 'int+e': 'exp', + 'frac+e': 'exp' + }; + do { + var c = s.charAt(i++); + if (!c) break; + if ('0' <= c && c <= '9') continue; + if (permittedSigns.indexOf(c) >= 0) { + permittedSigns = ''; + continue; + } + state = transitions[state+'+'+c.toLowerCase()]; + if (state == 'exp') permittedSigns = '-'; + } while (state); + this.index = --i; + s = s.slice(start, i) + if (s == '-') return this.error("invalid number"); + return Number(s); + } + }; + // copy table['-'] to each of table[i] | i <- '0'..'9': + (function (table) { + for (var i = 0; i <= 9; i++) + table[String(i)] = table['-']; + })(rison.parser.prototype.table); -// return the next non-whitespace character, or undefined -rison.parser.prototype.next = function () { - var s = this.string; - var i = this.index; - do { - if (i == s.length) return undefined; - var c = s.charAt(i++); - } while (rison.parser.WHITESPACE.indexOf(c) >= 0); - this.index = i; - return c; -}; - -/* jshint ignore:end */ + // return the next non-whitespace character, or undefined + rison.parser.prototype.next = function () { + var s = this.string; + var i = this.index; + do { + if (i == s.length) return undefined; + var c = s.charAt(i++); + } while (rison.parser.WHITESPACE.indexOf(c) >= 0); + this.index = i; + return c; + }; + /* jshint ignore:end */ + return rison; +}); \ No newline at end of file