UNPKG

json-object-editor

Version:

JOE the Json Object Editor | Platform Edition

1,254 lines (1,207 loc) 330 kB
/*/---------------------------------------------------------/*/ /*/ 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 + " || ";