json-object-editor
Version:
JOE the Json Object Editor | Platform Edition
1,254 lines (1,207 loc) • 330 kB
JavaScript
/*/---------------------------------------------------------/*/
/*/ Craydent LLC v1.8.0 /*/
/*/ Copyright 2011 (http://craydent.com/about) /*/
/*/ Dual licensed under the MIT or GPL Version 2 licenses. /*/
/*/ (http://craydent.com/license) /*/
/*/---------------------------------------------------------/*/
/*----------------------------------------------------------------------------------------------------------------
/- Global CONTANTS and variables
/---------------------------------------------------------------------------------------------------------------*/
var __version = "1.8.0",
__thisIsNewer = true,
$w = typeof window != "undefined" ? window : {location:(typeof location != "undefined"?location:{href:''}),console:(typeof console != "undefined"?console:{})},
$d = typeof document != "undefined" ? document : {},
$l = $w.location;
if ($w.__craydentLoaded || typeof($c) != "undefined") {
var __current = ($w.__craydentVersion||$c.VERSION||"").split("."),
__thisVersion = __version.split(".");
if(__thisIsNewer = __isNewer(__current,__thisVersion)) {
$c.VERSION = __version;
}
}
function __isNewer(loadedVersion, thisVersion){
if (loadedVersion[0] == thisVersion[0]) {
loadedVersion.splice(0,1);
thisVersion.splice(0,1);
if (!thisVersion.length || !loadedVersion.length) {
return false;
}
return __isNewer(loadedVersion, thisVersion);
}
return parseInt(loadedVersion[0]) < parseInt(thisVersion[0]);
}
function __cleanUp() {
try {
delete $w.__current;
delete $w.__thisVersion;
delete $w.__thisIsNewer;
delete $w.__isNewer;
delete $w.__version;
delete $w._ie;
delete $w._droid;
delete $w._amay;
delete $w._browser;
delete $w._os;
delete $w._device;
delete $w._engine;
} catch(e) {
$w.__current = undefined;
$w.__thisVersion = undefined;
$w.__thisIsNewer = undefined;
$w.__isNewer = undefined;
$w.__version = undefined;
$w._ie = undefined;
$w._droid = undefined;
$w._amay = undefined;
$w._browser = undefined;
$w._os = undefined;
$w._device = undefined;
$w._engine = undefined;
}
}
$w.__craydentVersion = __version;
if (__thisIsNewer) {
var _ao,_ah, _df, _irregularNouns = {
"addendum":"addenda",
"alga":"algae",
"alumna":"alumnae",
"apparatus":"apparatuses",
"appendix":"appendices",
"bacillus":"bacilli",
"bacterium":"bacteria",
"beau":"beaux",
"bison":"bison",
"bureau":"bureaus",
"child":"children",
"corps":"corps",
"corpus":"corpora",
"curriculum":"curricula",
"datum":"data",
"deer":"deer",
"die":"dice",
"diagnosis":"diagnoses",
"erratum":"errata",
"fireman":"firemen",
"focus":"focuses",
"foot":"feet",
"genus":"genera",
"goose":"geese",
"index":"indices",
"louse":"lice",
"man":"men",
"matrix":"matrices",
"means":"means",
"medium":"media",
"memo":"memos",
"memorandum":"memoranda",
"moose":"moose",
"mouse":"mice",
"nebula":"nebulae",
"ovum":"ova",
"ox":"oxen",
"person":"people",
"radius":"radii",
"series":"series",
"sheep":"sheep",
"scissors":"scissors",
"species":"species",
"stratum":"strata",
"syllabus":"syllabi",
"tableau":"tableaux",
"that":"those",
"this":"these",
"tooth":"teeth",
"vertebra":"vertebrae",
"vita":"vitae",
"woman":"women",
"zero":"zeros"
};
/*----------------------------------------------------------------------------------------------------------------
/- define functions preventing overwriting other framework functions
/---------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------
/- private methods
/---------------------------------------------------------------------------------------------------------------*/
function __and (){
try {
var len = arguments.length;
for(var a = 0; a<len; a++){
if(!arguments[a]){
return arguments[a - 1] || "";
}
}
return arguments[len - 1];
} catch (e) {
error('fillTemplate.__or', e);
}
}
function __andNotHelper (record, query, operands, index) {
try {
for (var i = 0, len = query.length; i < len; i++) {
for (var prop in query[i]) {
if (!query[i].hasOwnProperty(prop)) {
continue;
}
if (!(prop in operands
&& _subQuery(record, query[i][prop], prop, index)
|| _subQuery(record, query[i][prop], "$equals", prop, index)
)) {
return false;
}
}
}
return true;
} catch (e) {
error('where.__andNotHelper', e);
}
}
function __convert_regex_safe(reg_str) {
try {
return reg_str.replace(/\\/gi,"\\\\")
.replace(/\$/gi, "\\$")
.replace(/\//gi, "\\/")
.replace(/\^/gi, "\\^")
.replace(/\./gi, "\\.")
.replace(/\|/gi, "\\|")
.replace(/\*/gi, "\\*")
.replace(/\+/gi, "\\+")
.replace(/\?/gi, "\\?")
.replace(/\!/gi, "\\!")
.replace(/\{/gi, "\\{")
.replace(/\}/gi, "\\}")
.replace(/\[/gi, "\\[")
.replace(/\]/gi, "\\]")
.replace(/\(/gi, "\\(")
.replace(/\)/gi, "\\)")
.replace('\n','\\n');
} catch (e) {
error('__convert_regex_safe', e);
}
}
function __dup (old) {
try {
for (prop in old){
this[prop] = old[prop];
}
} catch (e) {
error('__dup', e);
}
}
function __or (){
try {
for(var a = 0, len = arguments.length; a<len; a++){
if(arguments[a]){
return arguments[a];
}
}
return "";
} catch (e) {
error('fillTemplate.__or', e);
}
}
function __count(arr){
try {
return arr.length;
} catch (e) {
error('fillTemplate.count', e);
}
}
function __enum(obj, delimiter, prePost){
try {
delimiter = delimiter || ", ";
prePost = prePost || ["",""];
var props = [],
str = "";
if ($c.isArray(obj)) {
props = obj.slice(0);
}
if ($c.isObject(obj)) {
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
props.push(prop);
}
}
}
for (var i = 0, len = props.length; i < len; i++) {
var pre = prePost[0].replace_all(['{ENUM_VAR}','{ENUM_VAL}'],[props[i],obj[props[i]]]),
post = prePost[1].replace_all(['{ENUM_VAR}','{ENUM_VAL}'],[props[i],obj[props[i]]]);
str += pre + props[i] + post + delimiter;
}
return str.slice(0,-1*delimiter.length);
} catch (e) {
error('fillTemplate.enum', e);
}
}
function __run_replace (reg, template, use_run, obj) {
try {
var pre = "", post = "", split_param = "|", match;
use_run && (pre="RUN[",post="]", split_param=/;(?!\\)/);
while ((match = reg.exec(template)) && match[1]) {
var funcValue = [],
func = "";
funcValue = match[1].replace_all(['\\[','\\]'],['[',']']).split(split_param);
func = funcValue.splice(0,1)[0];
for (var i = 0, len = funcValue.length; i < len; i++) {
if (funcValue[i].contains("${")) {
funcValue[i] = fillTemplate(funcValue[i], obj);
}
try {funcValue[i] = eval("(" + funcValue[i].replace_all([';\\','\\[','\\]'], [';','[',']']) + ")");} catch (e) {}
}
template = template.contains(match[1]) ? template.replace(match[1], (match[1] = match[1].replace_all(['\\[', '\\]'], ['[', ']']))) : template;
template = template.replace_all("${" + pre + match[1] + post +"}", $w.getProperty(func) ? $w.getProperty(func).apply(obj, funcValue) : "");
}
return template;
} catch (e) {
error('fillTemplate.__run_replace', e);
}
}
function _ajaxServerResponse(response) {
try {
if (response.readyState == 4 && response.status==200) {
var objResponse = {};
try {
objResponse = eval(response.responseText.trim());
} catch (e) {
objResponse = eval("(" + response.responseText.trim() + ")");
}
if (!objResponse || objResponse.hasErrors) {
return false;
}
return objResponse;
}
return false;
} catch (e) {
error("ajax._ajaxServerResponse", e);
return false;
}
}
function _condense (obj, check_values) {
try {
var skip = [], arr = [];
for (var i = 0, len = obj.length; i < len; i++) {
if (check_values) {
var index = i;
if (skip.indexOf(i) != -1) {
continue;
}
while ((index = obj.indexOf(obj[i],index+1)) != -1) {
skip.push(index);
}
}
(skip.indexOf && skip.indexOf(i) || _indexOf(skip, i)) == -1 && obj[i] && arr.push(obj[i]);
}
return arr;
} catch (e) {
error("_condence", e);
return false;
}
}
function _copyWithProjection(projection, record) {
var copy = {}, len = 0;
projection = projection || "*";
if ($c.isString(projection)) {
projection = projection.split(',');
}
if ($c.isArray(projection)) {
if (!(len = projection.length)) {
// _copyWithProjectionHelper(record,copy);
copy = $c.duplicate(record);
return copy;
}
var arr = projection;
projection = {};
for (var i = 0, len; i < len; i++) {
projection[arr[i]] = 1;
}
}
for (var prop in projection) {
if (projection.hop(prop)) {
if (prop == "*") {
// _copyWithProjectionHelper(record,copy);
copy = $c.duplicate(record);
} else if (record[prop] && !$c.isArray(record[prop])) {
copy[prop] = record[prop];
} else if (record[prop]) {
if (prop.slice(-2) == ".$") {
prop = prop.slice(0,-2);
copy[prop] = record[prop].slice(0,1);
} else if (projection[prop]['$elemMatch']) {
copy[prop] = record[prop].where(projection[prop]['$elemMatch']).slice(0,1);
} else if (projection[prop]['$slice']) {
var start = 0, length = $c.isInt(projection[prop]['$slice']) ? projection[prop]['$slice'] : 0;
if ($c.isArray(projection[prop]['$slice'])) {
start = projection[prop]['$slice'][0];
length = projection[prop]['$slice'][1];
}
copy[prop] = record[prop].slice(start, length);
}
if (!copy[prop].length) {
delete copy[prop];
}
}
}
}
return copy;
}
function _copyWithProjectionHelper(record,copy) {
for (var prop in record) {
if (record.hop(prop)) {
copy[prop] = record[prop];
}
}
}
function _craydentSelector (by, overwrite, object, single) {
try {
if (!object || object === true) {
return undefined;
}
var elem = $d[by](object);
if (single) {
return ((elem && ((elem.length && elem[0]) || elem)) || $w[overwrite](object)[0]);
}
return (elem || $w[overwrite](object));
} catch (e) {
error('_craydentSelector', e);
}
}
function _dataset (){
try {
var attributes = this.attributes,
ds = {};
for (var i in attributes) {
attribute = attributes[i];
if (attribute.name.indexOf("data-") == 0) {
ds[attribute.name.substring(5)] = attribute.value;
}
}
return ds;
} catch (e) {
error("DOM._dataset", e);
}
};
function _defineFunction (name, func, override) {
try {
var args = _getFuncArgs(func),
fstr = func.toString().replace(/this/g,'obj'),
exec = "",
// extra code to account for when this == window
extra_code = "if(obj === undefined && this == $c){return;}",
fnew = args.length === 0 || (args.length === 1 && !_trim(args[0])) ?
// fstr.toString().replace(/(\(\s*?\)\s*?\{)/, ' ' + name + '(obj){'+extra_code) :
fstr.toString().replace(/(\(\s*?\)\s*?\{)/, ' (obj){'+extra_code) :
"(" + fstr.toString().replace(/\((.*?)\)\s*?\{/, '(obj,$1){'+extra_code) + ")";
if (!override && eval("typeof("+name+")") !== "undefined") {
eval("$c."+name+" = "+fnew);
return;
}
eval("$c."+name+" = "+fnew);
//eval(fnew.replace("function","function "+name));
} catch (ex) {
error("_defineFunction", ex);
}
}
_df = _defineFunction;
function _displayHelper(object, func){
try {
return (($d.getElementById(object) && $(object)[func]())
|| (object instanceof HTMLElement && object[func]())
|| $w['_'+func+'overwrite'](object));
} catch (e) {
error("_displayHelper." + func, e);
}
}
function _duplicate(obj, original, recursive/*, ref, current_path, exec*/){
try {
if ($c.isString(obj) || $c.isString(original)
|| $c.isInt(obj) || $c.isInt(original)
|| $c.isFloat(obj) || $c.isFloat(original)
|| $c.isNumber(obj) || $c.isNumber(original)) {
return original;
}
var argIndex = 3;
// remove all properties if it is the root level
var ref = arguments[argIndex] || {objects:[{obj:original,path:"this"}]},
current_path = arguments[argIndex+1] || "this";
(arguments[argIndex+2] || (arguments[argIndex+2] = {})) && (arguments[argIndex+2].command = arguments[argIndex+2].command || "");
if (!ref.objects.length == 1) {
for (prop in obj){
if (obj.hasOwnProperty(prop)) {
delete obj[prop];
}
}
}
var loop_func = function (prop, original) {
if (original.hasOwnProperty(prop) && original[prop] && (!$c.isFunction(original[prop]) || !recursive)) {
var index = ref.objects.indexOfAlt(original[prop],function(obj,value){
return obj.obj===value;
}),
new_path = current_path+"["+parseRaw(prop)+"]";
if (index != -1) {
arguments[argIndex+1].command += new_path + "="+ref.objects[index].path+";";
return;
}
if (typeof(original[prop]) == "object" && recursive) {
obj[prop] = typeof(original[prop].constructor) == "function" ? new original[prop].constructor() : {};
ref.objects.push({obj:original[prop],path:new_path});
_duplicate(obj[prop], original[prop], true, ref, new_path, arguments[argIndex+1]);
return;
}
} else if (!original.hasOwnProperty(prop)) {
return;
}
obj[prop] = original[prop];
}
//JSON.parse(JSON.stringify(obj));
if ($c.isArray(original)) {
for (var i = 0, len = original.length; i < len; i++){
loop_func.call(obj, i, original, ref, current_path, arguments[argIndex+2]);
}
} else {
for (prop in original){
loop_func.call(obj, prop, original, ref, current_path, arguments[argIndex+2]);
}
}
if (!arguments[argIndex+1]) {
eval(arguments[argIndex+2].command);
}
return obj;
} catch (e) {
error('_duplicate', e);
}
}
function _ext (cls, property, func, override) {
try {
cls['prototype'][property] = cls['prototype'][property] || func;
_df(property, func, override);
} catch (e) {
error('_ext', e);
}
}
function _even (num) {
try {
if (isNaN(num)) {
return false;
}
return !(num&1);
} catch (e) {
error('_even', e);
}
}
function _firstElementChild () {
try {
var children = this.childNodes;
for (var i = 0, len = children.length; i < len; i++) {
if (children[i].nodeType == 1) {
return children[i];
}
}
return false;
} catch (e) {
error("DOM._firstElementChild", e);
return false;
}
}
function _getBrowserVersion(browser){
try {
var info = navigator.userAgent;
if (browser == "safari") {
info = navigator.vendor;
} else if (browser == "Opera") {
info = $w.opera;
}
var index = navigator.userAgent.indexOf(browser);
if (index == -1 && $w["is"+browser]()) return -1;
return parseFloat(navigator.userAgent.substring(index+browser.length+1));
} catch(e){
error('_getBrowserVersion', e);
}
}
function _getDimension(isBody, dimension) {
try {
if (!isBody && this.tagName.toLowerCase() == 'body') {
var dim, currentStyle = $d.body.style[dimension];
$d.body.style[dimension] = "100%";
dim = $d.body[dimension](true);
$d.body.style[dimension] = currentStyle;
}
var cRect = this.getClientRects && this.getClientRects()[0];
return (cRect && cRect[dimension]) || this["offset" + dimension.capitalize()] || this["scroll" + dimension.capitalize()];
} catch (e) {
if (!this.parentNode && this != $d) {
var temp = this.cloneNode(1),
rtn;
temp.style.visible = 'hidden';
temp.style.position = 'absolute';
temp["get" + dimension.capitalize()] = $d.body[dimension];
$d.body.appendChild(temp);
rtn = temp["get" + dimension.capitalize()]();
temp.remove();
return rtn;
}
error("_getDimension", e);
return false;
}
}
function _getFuncName (func) {
try {
return _trim(func.toString().replace(/\/\/.*?[\r\n]/gi,'').replace(/[\t\r\n]*/gi, '').replace(/\/\*.*?\*\//gi, '').replace(/.*?function\s*?(.*?)\s*?\(.*/,'$1'));
} catch (e) {
error('_getFuncName', e);
}
}
function _getFuncArgs (func) {
try {
return _condense(_trim(_strip(func.toString(), '(')).replace(/\s*/gi, '').replace(/\/\*.*?\*\//g,'').replace(/.*?\((.*?)\).*/, '$1').split(','));
} catch (e) {
error('_getFuncArgs', e);
}
}
function _getGMTOffset () {
try {
return this.getHours() - 24 - this.getUTCHours();
} catch (e) {
error('_getGMTOffset', e);
}
}
function _groupFieldHelper (obj, fields) {
var prop = "";
for (var j = 0, jlen = fields.length; j < jlen; j++) {
prop += fields[j] + ":" + obj[fields[j]] + ",";
}
return prop;
}
function _indexOf (obj, value) {
try {
var len = obj.length,
i = 0;
while (i < len) {
if (obj[i] === value) return i;
++i;
}
return -1;
} catch (e) {
error("_indexOf", e);
}
}
function _invokeHashChange() {
try {
var hc = $COMMIT.onhashchange || $c.onhashchange;
hc && $c.isFunction(hc) && hc();
} catch (e) {
error('_invokeHashChange', e);
}
}
function _isArray (obj) {
try {
if (obj === undefined) {return false;}
return (obj.constructor == Array);
} catch (e) {
error('_isArray', e);
}
}
function _isString (obj) {
try {
if (obj === undefined) {return false;}
return (obj.constructor == String);
} catch (e) {
error('_isString', e);
}
}
function _joinHelper (obj, arr, on, exclusive) {
var records = [], propRef = [], objRef = arr[0] || {};
if ($c.isString(on)) {
on = on.split('=');
if (on.length == 1) {
on = [on,on];
}
var name = arguments.callee.caller.getName();
on = on.trim();
name == "joinRight" && (on = [on[1],on[0]]);
}
for (var prop in objRef) {
if (objRef.hasOwnProperty(prop)) {
propRef.push(prop);
}
}
for (var i = 0, len = obj.length; i < len; i++) {
var record = $c.copyObject(obj[i]), query = {};
query[on[1]] = record[on[0]],
results = arr.where(query);
if (results.length > 0) {
records.push($c.merge(record, results[0]));
} else if (!exclusive) {
for (var j = 0, jlen = propRef.length; j < jlen; j++) {
record[propRef[j]] = record[propRef[j]] || null;
}
records.push(record);
}
}
return records;
}
function _makePrecidenceBlocks(condition) {
try {
var index = condition.indexOf('('),
parts = {before:'',after:'',block:{}};
if (index != -1) {
var lindex = condition.lastIndexOf('(');
parts.before = condition.substring(0,index).trim();
parts.after = condition.substring(lindex).trim();
parts.block = _makePrecidenceBlocks(condition.substring(index+1,lindex-1));
return parts;
}
parts.block = condition;
return parts;
} catch (e) {
error('_makePrecidenceBlocks', e);
}
}
function _nextElementSibling () {
try {
var next = this.nextSibling;
while (next && next.nodeType != 1) {
next = next.nextSibling;
}
return next;
} catch (e) {
error("DOM._nextElementSibling", e);
return false;
}
}
function _processClause (clause) {
try {
var index = clause.indexOfAlt(/between/i);
if (index != -1) { // contains between predicate
//replace AND in the between to prevent confusion for AND clause separator
clause.replace(/between( .*? )and( .*?)( |$)/gi,'between$1&and$2$3');
}
var ORs = clause.split(/ or /i), query = {"$or":[]};
for (var i = 0, len = ORs.length; i < len; i++) {
var ANDs = ORs[i].split(/ and /i),
aquery = {'$and':[]};
for (var j = 0, jlen = ANDs.length; j < jlen; j++) {
var predicateClause = ANDs[j],
cond = {};
//=, <>, >, >=, <, <=, IN, BETWEEN, LIKE, IS NULL or IS NOT NULL
switch (true) {
case (index = predicateClause.indexOf('=')) != -1 :
cond[predicateClause.substring(0, index).trim()] = {'$equals':tryEval(predicateClause.substring(index + 1).trim())};
aquery['$and'].push(cond);
break;
case (index = predicateClause.indexOf('<>')) != -1 :
cond[predicateClause.substring(0, index).trim()] = {'$ne':tryEval(predicateClause.substring(index + 1).trim())};
aquery['$and'].push(cond);
break;
case (index = predicateClause.indexOf('>')) != -1 :
cond[predicateClause.substring(0, index).trim()] = {'$gt':tryEval(predicateClause.substring(index + 1).trim())};
aquery['$and'].push(cond);
break;
case (index = predicateClause.indexOf('>=')) != -1 :
cond[predicateClause.substring(0, index).trim()] = {'$gte':tryEval(predicateClause.substring(index + 1).trim())};
aquery['$and'].push({'$gte':cond});
break;
case (index = predicateClause.indexOf('<')) != -1 :
cond[predicateClause.substring(0, index).trim()] = {'$lt':tryEval(predicateClause.substring(index + 1).trim())};
aquery['$and'].push(cond);
break;
case (index = predicateClause.indexOf('<=')) != -1 :
cond[predicateClause.substring(0, index).trim()] = {'$lte':tryEval(predicateClause.substring(index + 1).trim())};
aquery['$and'].push(cond);
break;
case predicateClause.indexOfAlt(/between/i) == 0 :
var nums = predicateClause.replace(/between (.*?) &and (.*?) ( |$)/i,'$1,$2').split(',');
aquery['$and'].push({'$gte':tryEval(nums[0])});
aquery['$and'].push({'$lte':tryEval(nums[1])});
break;
case (index = predicateClause.indexOfAlt(/ in /i)) != -1 :
var _in = tryEval(predicateClause.substring(index + 4).trim().replace(/\((.*)\)/,'[$1]'));
if (!_in) {
throw "Invalid syntax near 'in'";
}
cond[predicateClause.substring(0, index).trim()] = _in;
aquery['$and'].push({'$in':cond});
break;
case (index = predicateClause.indexOfAlt(/is null/i)) != -1 :
cond[predicateClause.substring(0, index).trim()] = null;
aquery['$and'].push({'$equals':cond});
break;
case (index = predicateClause.indexOfAlt(/is not null/i)) != -1 :
cond[predicateClause.substring(0, index).trim()] = null;
aquery['$and'].push({'$ne':cond});
break;
case (index = predicateClause.indexOfAlt(/ like /i)) != -1 :
var likeVal = "^" + _trim(predicateClause.substring(index + 6),null,[' ', "'", '"']).replace_all("%",".*?") + "$";
cond[predicateClause.substring(0, index).trim()] = {'$regex': new RegExp(likeVal,'i')};
aquery['$and'].push(cond);
break;
}
}
query['$or'].push(aquery);
}
return query;
} catch (e) {
error('where.processClause', e);
}
}
function _replace_all(replace, subject, flag) {
try {
if (!$c.isArray(replace) && !$c.isArray(subject)) {
replace = [replace];
subject = [subject];
}
var str = this;
for (var i = 0, len = replace.length; i < len; i++)
{
if (!str.contains(replace[i])) {
continue;
}
str = str.replace(RegExp(__convert_regex_safe(replace[i]), flag), subject[i] || subject[0]);
}
return str;
} catch (e) {
error("_replace_all", e);
}
}
function _run_func_array(funcs, args) {
try {
for (var i = 0, len = funcs.length; i < len; i++) {
funcs[i].apply(this, args);
}
} catch (e) {
error("_run_func_array", e);
}
}
function _set (variable, value, defer, options, loc){
try {
value = encodeURI(value);
var ignoreCase = options.ignoreCase || options == "ignoreCase" ? "i" : "",
regex = new RegExp('(.*)?(' + variable +'=)(.*?)(([&]|[@])(.*)|$)', ignoreCase),
attr = "search",
symbol = "&",
queryStr = "";
attr = variable.indexOf('@') == 0 ? (symbol='', "hash") : attr;
$COMMIT[attr] = $COMMIT[attr] || "";
if (defer) {
$COMMIT[attr] = ($COMMIT[attr] || $l[attr]);
queryStr = regex.test($COMMIT[attr]) ?
$COMMIT[attr].replace(regex, '$1$2' + value + '$4') :
$COMMIT[attr] + symbol + variable + '=' + value;
if (symbol == "&" && queryStr.indexOf('&') == 0) {
queryStr = "?" + queryStr.substring(1);
}
$COMMIT[attr] = queryStr;
$COMMIT.update = true;
} else {
queryStr = regex.test(loc[attr]) ?
loc[attr].replace(regex, '$1$2' + value + '$4') :
loc[attr] + symbol + variable + '=' + value;
if (symbol == "&" && queryStr.indexOf('&') == 0) {
queryStr = "?" + queryStr.substring(1);
}
loc[attr] = queryStr;
if (attr == 'hash') {
$COOKIE("CRAYDENTHASH", loc.hash[0] == '#' ? loc.hash.substring(1) : loc.hash);
_invokeHashChange();
}
}
return loc;
} catch (e) {
error("_set", e);
}
}
function _setDOMElementProperties(_elem) {
try {
if (!_elem) {
return;
}
for (var prop in $w.HTMLElement.prototype) {
if ($w.HTMLElement.prototype.hasOwnProperty(prop)) {
try {
if (prop == "dataset" || prop == "firstElementChild" || prop == "nextElementSibling") {
_elem[prop] = $w['_' + prop]();
//return;
}
_elem[prop] = $w.HTMLElement.prototype[prop];
} catch(e) {
}
}
}
} catch (e) {
error("_setDOMElementProperties", e);
}
}
function _strip (str, character) {
try {
return _trim(str, undefined, character);
} catch (e) {
error("_strip", e);
}
}
function _subFieldHelper(obj, operands) {
try {
if (!$c.isObject(obj)) {
return false;
}
for (var prop in obj) {
if (prop in operands) {
return prop;
}
}
return false;
} catch (e) {
error('_subFieldHelper', e);
}
}
function _subQuery(record, query, operator, field, index) {
try {
if (isNull(index)) {
index = field;
field = null;
}
var operands = {
"$or":1,
"$and":1,
"$in":1,
"$nin":1,
"$regex":1,
"$gt":1,
"$lt":1,
"$gte":1,
"$lte":1,
"$exists":1,
"$equals":1,
"$ne":1,
"$nor":1,
"$type":1,
"$text":1,
"$mod":1,
"$all":1,
"$size":1,
"$where":1,
"$elemMatch":1,
"$not":1},
value = $c.getProperty(record, field || ""),
opt = operator,
rtn = false;
// prep multiple subqueries
for (var prop in query) {
if (query.hasOwnProperty(prop) && prop in operands) {
if(!$c.isArray(opt)) {
opt = [];
}
opt.push(prop);
}
}
if (!$c.isArray(opt)) {
opt = [opt];
}
for (var i = 0, len = opt.length; i < len; i++) {
if (!rtn && i > 0) {
return rtn;
}
switch(opt[i]) {
// value is the record in the array
// q is the conditional value
case "$equals":
if (isNull(query) || isNull(value)) {
return false;
}
var q = $c.getValue(query.hasOwnProperty("$equals") ? query['$equals'] : query),
isRegex = q.constructor == RegExp;
rtn = isRegex ? q.test(value) :
($c.isFunction(q) ? q(record, field, index) : value == q);
break;
case "$ne":
if (isNull(query) || isNull(value)) {
return false;
}
var q = query['$ne'],
isRegex = q.constructor == RegExp;
rtn = !(isRegex ? q.test(value) : value == q);
break;
case "$lt":
if (isNull(value)) {
return false;
}
rtn = value < query['$lt'];
break;
case "$lte":
if (isNull(value)) {
return false;
}
rtn = value <= query['$lte'];
break;
case "$gt":
if (isNull(value)) {
return false;
}
rtn = value > query['$gt'];
break;
case "$gte":
if (isNull(value)) {
return false;
}
rtn = value >= query['$gte'];
break;
case "$nor":
for(var i = 0, len = query.length; i < len; i++) {
if (_subQuery(record,[query[i]],'$or',field, index)) {
return false;
}
}
rtn = true;
break;
case "$regex":
if (isNull(value)) {
return false;
}
rtn = query["$regex"].test(value);
break;
case "$exists":
var finished = {validPath:0};
$c.getProperty(record, field,".",finished);
rtn = finished.validPath == query["$exists"];
break;
case "$type":
if (isNull(value) && isNull(query) || !isNull(value) && value.constructor == query) {
// return true;
rtn = true;
break;
}
return false;
break;
case "$text":
//return record.getProperty(field).contains(query['$search']);
break;
case "$mod":
if (!$c.isArray(query) || isNull(value)) {
return false;
}
rtn = value % query[0] == query[1];
break;
case "$all":
if (!$c.isArray(value) || !$c.isArray(query)) {
return false;
}
for (var i = 0, len = query.length; i < len; i++) {
if (!$c.contains(value, query[i])) {
return false;
}
}
rtn = true;
break;
case "$size":
var val = parseInt(query);
if (!$c.isArray(value) || !val && val !== 0) {
return false;
}
rtn = value.length == val;
break;
case "$where":
rtn = $c.isFunction(query) ? query.call(record) : tryEval.call(record, "(function(){"+query+"}).call(this)");
break;
case "$elemMatch":
//query = { student: "Jane", grade: { $gt: 85 } } } };
if (!$c.isArray(value)) {
return false;
}
for (var i = 0, brk = false, len = value.length; i < len && !brk; i++) {
var obj = value[i],
val, operand;
for (var prop in query) {
if (!query.hasOwnProperty(prop)) {
continue;
}
if ($c.isObject(query[prop])) {
val = [query[prop]];
operand = "$or";
} else {
val = query[prop];
operand = "$equals";
}
if (_subQuery(record, val, operand, prop, index)) {
brk = true;
break;
// return true;
}
}
}
rtn = brk;
break;
case "$or":
if (!$c.isArray(query)) {
return false;
}
var satisfied = false;
for (var i = 0, len = query.length; i < len && !satisfied; i++) {
for (var prop in query[i]) {
if (!query[i].hasOwnProperty(prop)) {
continue;
}
var subprop = _subFieldHelper(query[i][prop], operands);
if (!(satisfied = prop in operands?
_subQuery(record, query[i][prop], prop, index) :
(subprop ? _subQuery(record, query[i][prop], subprop, prop, index) :
_subQuery(record, query[i][prop], "$equals", prop, index)))) {
break;
}
}
}
rtn = satisfied;
break;
case "$and":
rtn = __andNotHelper (record, query, operands, index);
break;
case "$not":
if ($c.isObject(query)) {
rtn = !__andNotHelper (record, query, operands, index);
break;
}
var isRegex = query == RegExp;
rtn = isRegex ? query.test(value) : value == query;
break;
case "$in":
case "$nin":
var isNIN = operator == "$nin";
rtn = isNIN;
for (var fieldProp in query) {
if (!query.hasOwnProperty(fieldProp)) {
continue;
}
value = $c.getProperty(record, field);
for (var k = 0, klen = query[fieldProp].length; k < klen; k++) {
var isRegex = query[fieldProp][k] && query[fieldProp][k].constructor == RegExp; //array of values
if (($c.isArray(value) && value.contains(query[fieldProp][k]))
|| (isRegex ? query[fieldProp][k].test(value) : value == query[fieldProp][k])) {
rtn = true;
if (isNIN) {
return !rtn;
}
break;
}
}
break;
}
break;
}
}
return rtn;
} catch (e) {
error('_subQuery', e);
}
}
function _trim(str, side, characters) {
try {
var temp = str,
trimChars = {
" ":1,
"\t":1,
"\n":1
};
if (characters) {
if (_isArray(characters)) {
var char = "", i = 0;
trimChars = {};
while (char = characters[i++]) {
trimChars[char] = 1;
}
} else if (_isString(characters)) {
trimChars = eval('({"'+characters+'":1})');
}
}
if (!side || side == 'l') {
while (temp.charAt(0) in trimChars) {
temp = temp.substring(1);
}
}
if (!side || side == 'r') {
while (temp.charAt(temp.length - 1) in trimChars) {
temp = temp.substring(0, temp.length - 1);
}
}
return temp.toString();
} catch (e) {
error("_trim", e);
}
}
function _whereHelper(objs,condition,callback) {
var returnAll = true;
for (var prop in condition) {
if (condition.hasOwnProperty(prop)) {
returnAll = false;
break;
}
}
// if sql syntax convert to mongo object syntax
if ($c.isString(condition) && condition) {
condition = _processClause(condition);
returnAll = false;
}
for (var i = 0, len = objs.length; i < len; i++) {
if (returnAll || _subQuery(objs[i], [condition],'$or', i)) {
if(!callback.call(objs, objs[i], i)) {
break;
}
}
}
}
/*----------------------------------------------------------------------------------------------------------------
/- Class prototypes
/---------------------------------------------------------------------------------------------------------------*/
function addObjectPrototype(name, fn, override) {
/*| {info: "Method to extend the Object Class",
* category: "Global",
* parameters:{
* name: "(String) name of the method to add",
* fn: "(Function) method implementation",
* override: "(Bool) if true, override the previously defined prototype"},
*
* description: "http://www.craydent.com/library/1.8.0/docs#addObjectPrototype"},
* returnType: "(void)"
* |*/
try {
var shouldOverride = false;
if (eval("typeof("+name+")") == "undefined") {
shouldOverride = true;
}
(!override && Object.prototype[name]) || Object.defineProperty(Object.prototype, name, {
writable: true,
enumerable: false,
configurable: true,
value: fn
});
override = shouldOverride;
} catch (e) {
error("addPrototype", e);
try {
Array.prototype[name] = !override && Array.prototype[name] || fn;
Function.prototype[name] = !override && Function.prototype[name] || fn;
String.prototype[name] = !override && String.prototype[name] || fn;
Number.prototype[name] = !override && Number.prototype[name] || fn;
Boolean.prototype[name] = !override && Boolean.prototype[name] || fn;
if (navigator.geolocation) {
var GeoLocation = navigator.geolocation.constructor;
GeoLocation.prototype[name] = !override && GeoLocation.prototype[name] || fn;
}
} catch (ex) {
error("addPrototype:Non-ECMAScript 5", e);
}
}
_df(name, fn, override);
}
function addHTMLPrototype (name, fn, override) {
/*| {info: "Method to extend the HTMLElement Class",
* category: "Global",
* parameters:{
* name: "(String) name of the method to add",
* fn: "(Function) method implementation",
* override: "(Bool) if true, override the previously defined prototype"},
*
* description: "http://www.craydent.com/library/1.8.0/docs#addHTMLPrototype"},
* returnType: "(void)"
* |*/
try {
var prototypeDefined = !!HTMLElement.prototype[name];
if (prototypeDefined && HTMLElement.prototype[name].overwritten) {
override = true;
}
var original = override ? "" : "HTMLElement.prototype." + name + " || ";