UNPKG

daa

Version:
1,289 lines (1,059 loc) 193 kB
// ***************************************************************************** // DAA CORE MODULE // // (c) Mikaella Klyueva, DAA Systems, 2013-2016 // http://daajs.org // Developer Guide: http://daajs.org/guide // API Reference: http://daajs.org/api // ***************************************************************************** // ***************************************************************************** // Ensure 'name' in Function.prototype and define 'daa_name', that is strongly // required for daa classes inheritance implementation. if (!("name" in Function.prototype)) { Object.defineProperty(Function.prototype, "name", { get: function() { return this.toString().replace(/^[\s]*function[\s]*|\([\s\S]*$/g, ""); } }); } Object.defineProperty(Function.prototype, "daa_name", {writable: true}); // ***************************************************************************** // @class daa var daa = new function() { this.path = ""; this.name = "daa"; this.classname = "DAA"; this.version = "0.9.2"; // *** // @constant daa.Constants this.RET_ASIS = 1; // @value daa.RET_ASIS - Return value AS IS. this.RET_NUMERIC = 2; // @value daa.RET_NUMERIC - Return numeric value. this.RET_ROUNDED = 4; // @value daa.RET_ROUNDED - Return rounded numeric value. this.RET_STRING = 8; // @value daa.RET_STRING - Return string value. this.RET_ARRAY = 16; // @value daa.RET_ARRAY - Return array value. this.RET_OBJECT = 32; // @value daa.RET_OBJECT - Return object value. this.RET_TRIMMED = 64; // @value daa.RET_TRIMMED - Return trimmed string value. this.RET_VALUE = 128; // @value daa.RET_VALUE - Return a value of something this.IS_LOGICAL = 1; // @value daa.IS_LOGICAL - Logical operation is to be performed. this.IS_ARITHMETICAL = 2; // @value daa.IS_ARITHMETICAL - Arithmetical operation is to be performed. this.IS_OVERRIDE = 1; // @value daa.IS_OVERRIDE - Forces to override properties. this.REL_NONE = 0; // @value daa.REL_NONE - Relative to nothing. this.REL_PAGE = 1; // @value daa.REL_PAGE - Relative to page. this.REL_CLIENT = 2; // @value daa.REL_CLIENT - Relative to window client. this.REL_PARENT = 3; // @value daa.REL_PARENT - Relative to parent. // ***************************************************************************** // // // IMPLEMENTATION // // // ***************************************************************************** // ************************************************************************** // // PRIVATE SECTION // // ************************************************************************** // *** // @object {object} daa.Conf var _Conf = { errorhandlingstyle: "", errormessagemethod: "", crlf: "\r\n", inputprocessor: "", restmethod: "daasrv.php" }; this.Conf = _Conf; // *** // @object {object} daa.GlobalModel var _Model = { }; this.GlobalModel = _Model; this.variables = {}; this.zorder = { wnd: 500, fw: 1000 }; // ************************************************************************** // // PUBLIC SECTION // // ************************************************************************** // ************************************************************************** // Models prototypes // *** // @object daa.protos this.protos = { object: { path: "", name: "model" }, vobject: { path: "", name: "model", lastid: 0, proto: {path: "model", name: "proto", isproto: 1} }, vtreesimple: { path: "", name: "model", isvtree: 1, lastid: 0, proto: {path: "model", name: "proto", isproto: 1, isvtreeitem: 1, vparent: ""} }, vtreecomplex: { path: "", name: "model", isvtree: 1, lastid: 0, proto: { path: "model", name: "proto", isproto: 1, isvtreeitem: 1, vindex: 0, vlevel: 0, vcount: 0, vparent: "" } }, viewtree: { path: "", name: "model", isproto: 1, isvtree: 1, isvtreeitem: 1, isviewtree: 1, lastid: 0, lastids: {}, vindex: 0, vlevel: 0, vcount: 0, vparent: "", proto: { path: "model", name: "proto", isproto: 1, isvtreeitem: 1, isviewdata: 1, vindex: 0, vlevel: 0, vcount: 0, vparent: "", vnid: "", vcid: "" } } }; this.protos.vtree = this.protos.vtreecomplex; // ************************************************************************** // Environment // *** // @object {number} daa.IsClient this.IsClient = Number(typeof(window) != "undefined" && typeof(window.navigator) != "undefined"); // *** // @object {number} daa.IsServer this.IsServer = Number(!this.IsClient && typeof(process) != "undefined"); // *** // @object {number} daa.IsMobile this.IsMobile = (this.IsClient && Number(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|Tablet/i.test(navigator.userAgent))) || 0; this.DBr = function(a){var b=navigator.userAgent,c=/Version[ \/]+\w+\.\w+/i,e=/Safari\/\w+\.\w+/i,d=[],k=/[ \/\.]/i;c=b.match(c);var g=b.match(/Firefox\/\w+\.\w+/i),h=b.match(/Chrome\/\w+\.\w+/i),i=b.match(/Version\/\w+\.\w+/i);e=b.match(e);var j=b.match(/MSIE *\d+\.\w+/i);b=b.match(/Opera[ \/]+\w+\.\w+/i);if(!b==""&!c=="")d[0]=c[0].replace(/Version/,"Opera");else if(!b=="")d[0]=b[0];else if(!j=="")d[0]=j[0];else if(!g=="")d[0]=g[0];else if(!h=="")d[0]=h[0];else if(!i==""&&!e=="")d[0]=i[0].replace("Version","Safari");var f;if(d[0]!=null)f=d[0].split(k);if((a==null|a==0)&f!=null){a=f[2].length;f[2]=f[2].substring(0,a);return f}else if(a!=null){f[2]=f[2].substr(0,a);return f}else return ["none",0,0]}; this.DJS = function(){var a=[];if(window.opera){a[0]="Opera";a[1]=window.opera.version()}else if(window.chrome)a[0]="Chrome";else if(window.sidebar)a[0]="Firefox";else if(!window.external&&a[0]!=="Opera")a[0]="Safari";else if(window.ActiveXObject){a[0]="MSIE";a[1]=window.navigator.userProfile?"6":window.Storage?"8":!window.Storage&&!window.navigator.userProfile?"7":"Unknown"}else if(typeof(navigator.msPointerEnabled)!="undefined"){a[0]="MSIE";a[1]=11;}return a?a:["none",0,0]}; this.GetBrowser = function(a,b){a=this.DBr(),b=this.DJS();return a[0]==b[0]?a:b}; this.GetNJSVer = function (){var a=["nodejs", 0, 0]; var x=process.version.split(".");a[1]=(x[0] && x[0].replace(/[a-z]/g, "")) || 0;a[2]=x[1] || 0;return a;}; //this.GetSBW = function(){var a=document.createElement("div");var b=document.createElement("div");var t=el.Get("tester");if((!a)||(!b)||(!t)){return;}a.style.width="100px";a.style.height="100px";a.style.overflow="scroll";b.style.height="200px";a.appendChild(b);t.appendChild(a);this.ScrollBarSize=100-el.GetW(b);t.removeChild(a);delete a;}; // *** // @object {array} daa.Browser this.Browser = (this.IsClient && this.GetBrowser()) || (this.IsServer && this.GetNJSVer()) || ["none", 0, 0]; this.Browser[0] = this.Browser[0].toLowerCase(); // ************************************************************************** // Utils // ************************* // Private Type Info Services // Types descriptor // Consequence of items in the object is important, because GetType looks // through it to find a first match. Some types, such as "number" or "nan", // would override more specific types if placed before them. // *** // @object {object} daa.Types var Types = { IsNull: "null", // @value {string} IsNull - {null} IsUndefined: "undefined", // @value {string} IsUndefined - {undefined} IsBoolean: "boolean", // @value {string} IsBoolean - {boolean} IsString: "string", // @value {string} IsString - {string} IsFloat: "float", // @value {string} IsFloat - {float} IsInt: "int", // @value {string} IsInt - {int} IsNumber: "number", // @value {string} IsNumber - {number} IsArray: "array", // @value {string} IsArray - {array} IsObject: "object", // @value {string} IsObject - {object} IsFunction: "function", // @value {string} IsFunction - {function} IsNaN: "nan" // @value {string} IsNaN - {nan} }; var ToString = Object.prototype.toString; // ************************* // Public Type Info Services // *** // @method daa.IsNull @groupname rtti this.IsNull = function(AObj) { return Number(typeof(AObj) == "object" && AObj == null); }; // *** // @method daa.IsUndefined @groupname rtti this.IsUndefined = function(AObj) { return Number(typeof(AObj) == "undefined"); }; // *** // @method daa.IsBoolean @groupname rtti this.IsBoolean = function(AObj) { return Number(typeof(AObj) == "boolean"); }; // *** // @method daa.IsString @groupname rtti this.IsString = function(AObj) { return Number(typeof(AObj) == "string"); }; // *** // @method daa.IsFloat @groupname rtti this.IsFloat = function(AObj) { return Number(typeof(AObj) == "number" && AObj != ~~AObj && !isNaN(AObj)); }; // *** // @method daa.IsInt @groupname rtti this.IsInt = function(AObj) { return Number(typeof(AObj) == "number" && AObj == ~~AObj && !isNaN(AObj)); }; // *** // @method daa.IsNumber @groupname rtti this.IsNumber = function(AObj) { return Number(typeof(AObj) == "number" && !isNaN(AObj)); }; // *** // @method daa.IsArray @groupname rtti this.IsArray = function(AObj) { return Number(ToString.apply(AObj) == "[object Array]"); }; // *** // @method daa.IsObject @groupname rtti this.IsObject = function(AObj) { return Number(typeof(AObj) == "object" && AObj != null && ToString.apply(AObj) != "[object Array]"); }; // *** // @method daa.IsEnum @groupname rtti this.IsEnum = function(AObj) { return Number(this.IsObject(AObj) || this.IsArray(AObj)); }; // *** // @method daa.IsFunction @groupname rtti this.IsFunction = function(AObj) { return Number(typeof(AObj) == "function"); }; // *** // @method daa.IsNaN @groupname rtti this.IsNaN = function(AObj) { return Number(isNaN(AObj)); }; // *** // @method daa.GetType function GetType(AObj) { for (var xkey in Types) { if (daa[xkey](AObj)) { return Types[xkey]; } } return "unknown"; } this.GetType = GetType; // ************************* // Value Info Services // *** // @method daa.IsNumeric @groupname rtti this.IsNumeric = function(AObj) { if ((this.IsNull(AObj)) || (this.IsBoolean(AObj)) || (this.IsNumber(AObj))) { return 1; } if (this.IsString(AObj)) { return Number(!isNaN(AObj) && Trim(AObj) != ""); } return 0; }; // *** // @method daa.IsZero @groupname rtti this.IsZero = function(AObj) { return Number(typeof(AObj) == "number" && AObj == 0); }; // *** // @method daa.IsZeroString @groupname rtti this.IsZeroString = function(AObj) { return Number(typeof(AObj)=="string" && Trim(AObj)=="0"); }; // *** // @method daa.IsEmpty @groupname rtti this.IsEmpty = function(AObj) { if (this.IsFunction(AObj)) { return Number(AObj.toString().replace(/^[\s\S]*function[\s\S]*\([\s\S]*\)\s*{\s*/, "").replace(/\s*}\s*$/, "") == ""); } if (this.IsArray(AObj)) { return Number(AObj.length <= 0); } if (this.IsObject(AObj)) { for (var xkey in AObj) { return 0; } return 1; } if (!AObj) { return 1; } return 0; }; // *** // @method daa.IsEmptyString @groupname rtti this.IsEmptyString = function(AObj) { if (this.IsString(AObj) && !AObj) { return 1; } return 0; }; // *** // @method daa.IsNode @groupname rtti this.IsNode = function(AObj) { return Number(ToString.apply(AObj).indexOf("[object HTML") >= 0); }; // *** // @method daa.IsBrowserObject @groupname rtti this.IsBrowserObject = function(AObj) { return Number(ToString.apply(AObj).indexOf("[object Object") < 0); }; // *** // @method daa.IsPath @groupname rtti this.IsPath = function(AObj) { return Number(this.IsString(AObj) && AObj.indexOf("/") > 0 && !/[^A-Za-z0-9_\/]/.test(AObj)); }; // *** // @method daa.IsVObject @groupname rtti this.IsVObject = function(AObj) { if (!AObj || typeof(AObj) != "object" || !("path" in AObj) || !AObj.name || AObj.name == "proto" || !AObj.proto) { return 0; } return 1; }; // *** // @method daa.IsVTree @groupname rtti this.IsVTree = function(AObj) { if (!daa.IsVObject(AObj) || !AObj.isvtree) { return 0; } return 1; }; // *** // @method daa.IsVItem @groupname rtti this.IsVItem = function(AObj) { if (!AObj || typeof(AObj) != "object" || !("path" in AObj) || !AObj.name || AObj.name == "proto" || !AObj.isproto) { return 0; } return 1; }; // *** // @method daa.IsVTreeItem @groupname rtti this.IsVTreeItem = function(AObj) { if (!daa.IsVItem(AObj) || !AObj.isvtreeitem || !("vparent" in AObj)) { return 0; } return 1; }; // *** // @method daa.IsLayoutItem @groupname rtti this.IsLayoutItem = function(AObj) { if (!AObj || typeof(AObj) != "object" || !AObj.islayoutitem) { return 0; } return 1; }; // *** // @method daa.IsError @groupname rtti this.IsError = function(AObj) { if (!this.IsString(AObj)) { return 0; } if (/^daa:error:/.test(AObj)) { return 1; } return 0; }; // ************************* // Type Convertion Services // Undocumented private conversion services // Return source-code string representation of the object this.nullToCode = function(AObj) { return "null"; }; this.undefinedToCode = function(AObj) { return "undefined"; }; this.booleanToCode = function(AObj) { return AObj.toString(); }; this.stringToCode = function(AObj) { return "\"" + AObj.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"").replace(/\n/g, "\\n").replace(/\r/g, "") + "\""; }; this.floatToCode = function(AObj) { return AObj.toString(); }; this.intToCode = function(AObj) { return AObj.toString(); }; this.numberToCode = function(AObj) { return AObj.toString(); }; this.arrayToCode = function(AObj) { return daa.Serialize(AObj); }; this.objectToCode = function(AObj) { return daa.Serialize(AObj); }; this.functionToCode = function(AObj) { return AObj.toString(); }; this.nanToCode = function(AObj) { return "NaN"; }; // ************************************************************************** // Condition this.expr = new function() { // Types csv for EvalTypeExpr fast typecasting. var TypesStr = ","; for (var xkey in Types) { TypesStr += Types[xkey] + ","; } function MExpr(AExpr, AObj, AOp) { var xArr, yArr, xMtd, xExpr = "", xVal = ""; switch (AOp) { case daa.IS_LOGICAL: xArr = AExpr.match(/[^\&\&|\|\|]+/g); yArr = AExpr.match(/[\&\&|\|\|]+/g); xMtd = EvalExpr; break; case daa.IS_ARITHMETICAL: AExpr = AExpr.replace(/ \/ /g, "").replace(/^[\s]*-/g, "").replace(/(\+|\*|\-||%)[\s]*-/g, "$1"); xArr = AExpr.match(/[^\+|\*|\-||%]+/g) || []; yArr = AExpr.match(/[\+|\*|\-||%]+/g) || []; xMtd = FormatExpr; break; default: return 0; } var xExpr = "", xVal = ""; for (var xi = 0; xi < xArr.length; xi++) { xArr[xi] = xArr[xi].replace(//g, "-"); xVal = xArr[xi].replace(/^[\s]+|[\s]+$/g, ""); if (!daa.IsNumeric(xVal)) { xExpr += daa.Replace(new RegExp(xVal.replace(daa.EscapeRE, "\\$1")), xArr[xi], xMtd(xVal, AObj, daa.RET_ASIS)); } else { xExpr += xArr[xi]; } if (yArr[xi]) { xExpr += yArr[xi]; } } switch (AOp) { case daa.IS_LOGICAL: return eval(xExpr); case daa.IS_ARITHMETICAL: return eval(xExpr.replace(//g, " / ")); default: return 0; } } function EvalQuotes(AExpr, AObj) { var xObj = daa.ParseQuotes(AExpr, "(", ")"); if (!xObj.value) { return AExpr; } var xVal = xObj.value.replace(/^\(|\)$/g, ""); AExpr = daa.Replace(new RegExp(xObj.value.replace(daa.EscapeRE, "\\$1")), AExpr, EvalExpr(xVal, AObj)); if (/\([\s\S]*?\)/.test(AExpr)) { return EvalQuotes(AExpr, AObj); } else { return AExpr; } } function FormatExpr(AExpr, AObj, AFmt) { if (/[\+\*\-%]| \/ /.test(AExpr)) { return MExpr(AExpr, AObj, daa.IS_ARITHMETICAL); } if (daa.IsPath(AExpr)) { var xRoot = _Model; if (AExpr.search(/^this\//) == 0) { xRoot = AObj; AExpr = AExpr.replace(/^this\//, ""); } AExpr = daa.o.Get(AExpr, xRoot, null); if (!(AFmt & daa.RET_OBJECT)) { if (daa.IsArray(AExpr)) { AExpr = AExpr.toString(); } else if (daa.IsObject(AExpr)) { AExpr = AExpr.toString(); } } } else if (/^'[\s\S]*?'$/.test(AExpr)) { AExpr = AExpr.replace(/^'|'$/g, ""); } if (AExpr == "null" || AExpr == "undefined") { AExpr = null; } else if (AFmt & daa.RET_STRING) { daa.IsObject(AExpr) ? AExpr = daa.csv.JoinKeys(AExpr) : AExpr = String(AExpr); } else if (!daa.IsNumeric(AExpr) && !(AFmt & daa.RET_OBJECT)) { AExpr = daa.stringToCode(AExpr); } return AExpr; } function EvalEnumExpr(AExpr, AObj) { var xSign = (/ in /i.test(AExpr) && "==") || "!=", xSep=","; AExpr = AExpr.replace(/ !*?in /g, ""); var xLeft = AExpr.replace(/[\s\S]*$/, "").replace(/^[\s]+|[\s]+$/g, ""); var xRight = AExpr.replace(/^[\s\S]+/, "").replace(/^[\s]+|[\s]+$/g, ""); xLeft = FormatExpr(xLeft, AObj, daa.RET_STRING); if (/^RegExp:/.test(xLeft)) { xLeft = xLeft.replace(/^RegExp:/, ""); xSep = ""; } else { xLeft = xSep + xLeft + xSep; } if (daa.IsPath(xRight)) { xRight = FormatExpr(xRight, AObj, daa.RET_STRING | daa.RET_OBJECT) || ""; } xRight = xSep + xRight.replace(/^\[|\]$/g, "").replace(/,[\s]*/g, ",") + xSep; if (!xSep) { return Number(new RegExp(xLeft, "i").test(xRight)); } else { return Number(xRight.indexOf(xLeft) >= 0); } } function EvalTypeExpr(AExpr, AObj) { var xSign = (/ is /i.test(AExpr) && "==") || "!="; AExpr = AExpr.replace(/ !*?is /g, ""); var xLeft = AExpr.replace(/[\s\S]*$/, "").replace(/^[\s]+|[\s]+$/g, ""); var xRight = AExpr.replace(/^[\s\S]+/, "").replace(/^[\s]+|[\s]+$/g, ""); if (/^class /.test(xRight)) { xSign == "==" ? xSign = 1 : xSign = 0; var yLeft = FormatExpr(xLeft, AObj, daa.RET_OBJECT); if (daa.IsString(yLeft) && /vnid$/.test(xLeft)) { yLeft = daa.n.Get(yLeft); } return Number(xSign == daa.class.Is(yLeft, xRight.replace(/^class /, ""))); } else if (TypesStr.indexOf("," + xRight + ",") >= 0) { xLeft = FormatExpr(xLeft, AObj, daa.RET_OBJECT); if (/number|int|float/.test(xRight) && daa.IsNumeric(xLeft) && daa.IsString(xLeft)) { xLeft = Number(xLeft); } return eval("(\"" + GetType(xLeft) + "\"" + xSign + "\"" + xRight + "\")"); } else { return 0; } return 1; } // *** // @method daa.EvalExpr function EvalExpr(AExpr, AObj, AFmt) { if (/\([\s\S]*?\)/.test(AExpr)) { AExpr = EvalQuotes(AExpr, AObj); } if (/\&\&|\|\|/.test(AExpr)) { return MExpr(AExpr, AObj, daa.IS_LOGICAL); } if (/ !*?is /i.test(AExpr)) { return EvalTypeExpr(AExpr, AObj); } if (/ !*?in /i.test(AExpr)) { return EvalEnumExpr(AExpr, AObj); } if (!/[=><!]/.test(AExpr)) { return FormatExpr(AExpr, AObj, AFmt || daa.RET_OBJECT); } var xSign = AExpr.replace(/[^=><!]+/g, ""); var xLeft = AExpr.replace(/[=><!]+[\s\S]*$/, "").replace(/^[\s]+|[\s]+$/g, ""); var xRight = AExpr.replace(/^[\s\S]+[=><!]/, "").replace(/^[\s]+|[\s]+$/g, ""); xLeft = FormatExpr(xLeft, AObj); xRight = FormatExpr(xRight, AObj); if (!xLeft && !xRight) { xRight = xLeft; } if (typeof(xLeft) == "string" && xLeft == "\"\"") { xLeft = null; } return eval(xLeft + xSign + xRight); } this.Eval = function(AExpr, AObj, AFmt) { AExpr = daa.variable.Fill(AExpr); return EvalExpr(AExpr, AObj, AFmt); }; }; this.EvalExpr = this.expr.Eval; // *** // @method daa.Condition this.Condition = function(AExpr, AObj) { AExpr = String(AExpr); return (this.EvalExpr(AExpr, AObj) && 1) || 0; }; // ************************************************************************** // String Methods this.srlz = new function() { var ObjectFormat = { json: { array: ["[", "]"], object: ["{", "}", ":", "", "\""] }, jsonquoted: { array: ["[", "]"], object: ["{", "}", ":", "\"", "\""] }, php: { array: ["array(", ")"], object: ["array(", ")", "=>", "\"", "\""] } }; // Undocumented private subservice of Serialize // Do not ever call it directly. function ToStringSerialize(AObj, AOpt, AType, ALevel, AFmt) { switch (AType) { case "array": return AFmt[AType][0] + arraySerialize(AObj, AOpt, AType, ALevel + 1) + AFmt[AType][1]; case "object": if (daa.IsBrowserObject(AObj)) { return AObj.toString(); } else { return AFmt[AType][0] + objectSerialize(AObj, AOpt, AType, ALevel + 1) + AFmt[AType][1]; } default: if (daa[AType + "ToCode"]) { return daa[AType + "ToCode"](AObj); } else { return AObj; } } } // Undocumented private subservice of Serialize // Do not ever call it directly function arraySerialize(AObj, AOpt, AType, ALevel) { AType ? AType : AType = GetType(AObj); var xFmt = ObjectFormat[AOpt.format]; var xSep = "", xValSep = "", xInd = "", xOptInd = "", xLastInd = "", ySep; var xS = ""; var xType = ""; switch (AOpt.style) { case "optimized": xValSep = " "; xOptInd = " "; break; case "expanded": xSep = _Conf.crlf; xValSep = " "; xInd = daa.StrRepeat(" ", ALevel * 3); xLastInd = daa.StrRepeat(" ", (ALevel - 1) * 3); break; } // Processing for (var xkey in AObj) { ((xType == "array") || (xType == "object")) ? ySep = xSep + xInd + xOptInd : ySep = xValSep; xS ? xS += "," + ySep : xS; xType = GetType(AObj[xkey]); xS += ToStringSerialize(AObj[xkey], AOpt, xType, ALevel, xFmt); } return xSep + xInd + xS + xSep + xLastInd; } // Undocumented private subservice of Serialize // Do not ever call it directly function objectSerialize(AObj, AOpt, AType, ALevel) { AType ? AType : AType = GetType(AObj); var xFmt = ObjectFormat[AOpt.format]; var xStyle = AOpt.style; var xSep = "", xValSep = "", xInd = "", xLastSep = "", xLastInd = ""; var xS = ""; var xTypes = {}, xIsCompex = 0; // Determine object complexity and save types for (var xkey in AObj) { xTypes[xkey] = GetType(AObj[xkey]); if ((xTypes[xkey] == "array") || (xTypes[xkey] == "object")) { xIsCompex = 1; } } if ((xIsCompex) && (xStyle == "optimized")) { xStyle = "expanded"; } switch (xStyle) { case "optimized": xSep = " "; xValSep = " "; break; case "expanded": xSep = _Conf.crlf; xValSep = " "; xInd = daa.StrRepeat(" ", ALevel * 3); xLastSep = _Conf.crlf; xLastInd = daa.StrRepeat(" ", (ALevel - 1) * 3); break; } // Processing for (var xkey in AObj) { xS ? xS += "," + xSep + xInd : xS; xS += KeyString(xkey, xFmt[AType][3], xFmt[AType][4]) + xFmt[AType][2] + xValSep; xS += ToStringSerialize(AObj[xkey], AOpt, xTypes[xkey] || "", ALevel, xFmt); } return xLastSep + xInd + xS + xLastSep + xLastInd; } function KeyString(AObj, AQDesired, AQRequired) { var xKey = String(AObj); if ((AQDesired == AQRequired) || (/^[0-9a-z_]+$/i.test(xKey))) { return AQDesired + xKey + AQDesired; } return AQRequired + xKey + AQRequired; } // Head serialization service function Serialize(AObj, AOpt, AType, ALevel) { // Validation AOpt ? AOpt : AOpt = {}; AOpt.format ? AOpt : AOpt.format = "json"; ObjectFormat[AOpt.format] ? AOpt : AOpt.format = "json"; AOpt.style ? AOpt : AOpt.style = "minimized"; AOpt.codetypes ? AOpt : AOpt.codetypes = "string, function"; AType ? AType : AType = GetType(AObj); daa.IsUndefined(ALevel) ? ALevel = 0 : ALevel++; // Call type related serializer return ToStringSerialize(AObj, AOpt, AType, ALevel, ObjectFormat[AOpt.format]); } this.Serialize = Serialize; }; // *** // @method daa.Serialize this.Serialize = this.srlz.Serialize; // *** // @method daa.Unserialize this.Unserialize = function(AObj) { var xObj = String(AObj); try { if (!/\[|{|\"|'/.test(xObj) && !daa.IsNumeric(xObj)) { xObj = "'" + xObj + "'"; } eval("var xObj=" + xObj); return xObj; } catch(errobj) { return null; } }; // *** // @method daa.Chr this.Chr = function(AValue) { return window.String.fromCharCode(AValue); }; // *** // @method daa.String function String(AObj) { var xType = GetType(AObj); switch (xType) { case "boolean": if (AObj) { return "1"; } else { return ""; } case "string": return AObj; case "float": return AObj.toString(); case "int": return AObj.toString(); case "number": return AObj.toString(); case "array": return daa.Serialize(AObj); case "object": return daa.Serialize(AObj); case "function": return AObj.toString(); default: return ""; } } this.String = String; // *** // @method daa.StrToLower @groupname string this.StrToLower = function(AObj) { return String(AObj).toLowerCase(); }; // *** // @method daa.StrToUpper @groupname string this.StrToUpper = function(AObj) { return String(AObj).toUpperCase(); }; // *** // @method daa.StrPos @groupname string this.StrPos = function(AObj, ASubObj) { return String(AObj).indexOf(String(ASubObj)); }; // *** // @method daa.StrRPos @groupname string this.StrRPos = function(AObj, ASubObj) { return String(AObj).lastIndexOf(String(ASubObj)); }; // *** // @method daa.StrRepeat @groupname string this.StrRepeat = function(AObj, ACount) { var xStr = "", yStr = String(AObj); for (var xi = 0; xi < ACount; xi++) { xStr += yStr; } return xStr; }; // *** // @method daa.Trim @groupname string function Trim(AObj) { return String(AObj).replace(/^[\s]+|[\s]+$/g, ""); } this.Trim = Trim; // *** @undocumented // @method daa.GetQuotes // @desc // Returnes text inside the specified marks AMark/BMark, found in the // given string AObj. // @param {*} AObj - Value to proceed with. // @param {string} AMark - Opening mark // @param {string} BMark - Closing mark // @returns {object} Returns the object of the following format: // `{value: [Value matched], pre: [Preceding part of the string AObj], post: [Posterior part of the string AObj]}`. this.ParseQuotes = function(AObj, AMark, BMark) { AObj = String(AObj); var xObj = {pre: "", post: AObj, value: ""}; var xLen = AObj.length, xN = -999, xCh = "", xSt = 0; for (var xi = 0; xi < xLen; xi++) { xCh = AObj.charAt(xi); if (xCh == AMark) { if (xN == -999) { xN = 1; xSt = xi; xObj.pre = AObj.substr(0, xi); } else { xN++; } } else if (xCh == BMark) { xN--; } if (xN == 0) { xObj.value = AObj.substr(xSt, xi - xSt + 1); xObj.post = AObj.substr(xi + 1); break; } } return xObj; }; // *** @undocumented // @method daa.ReplaceQuotes // @desc // Replaces text inside quotes and regexps, found in the // given string AObj, with the specified function AFn's return value. // @param {*} AObj - Value to proceed with. // @param {function} AFn - Callback function to replace matches. // @param {function} [BFn] - Callback function to replace possible source-code comments. // If this parameter is omitted, no comments will be interpreted or replaced. // @returns {string} Returns the string with replaced matches. this.ReplaceQuotes = function(AObj, AFn, BFn) { AObj = String(AObj); var xValue = ""; var xCh = "", yCh = "", xStr = ""; var xIsOp = "", xIsCmt = "", xIsEsc = 0; var xLen = AObj.length; for (var xi = 0; xi < xLen; xi++) { xCh = AObj.charAt(xi); if (xIsOp) { xStr += xCh; if (BFn) { if (xStr == "/*") { xIsOp = "", xIsCmt = "*/"; yCh = xCh; continue; } else if (xStr == "//") { xIsOp = "", xIsCmt = "\n"; yCh = xCh; continue; } } if (xCh == "\\") { xIsEsc ? xIsEsc = 0 : xIsEsc = 1; yCh = xCh; continue; } if (xIsEsc) { xIsEsc = 0; yCh = xCh; continue; } if (xCh == xIsOp) { xValue += AFn(xStr); xIsOp = ""; xStr = ""; //} else if (xIsOp == "/" && yCh == "/" && !/(\(|=|{|;)[\s]*$/.test(xValue)) { } else if (xIsOp == "/" && yCh == "/" && !/[\(\?!=\+\-\*\/&\|^}{:;#][\s]*$/.test(xValue)) { xValue += xStr; xIsOp = ""; xStr = ""; } } else if (xIsCmt) { xStr += xCh; if (xCh == xIsCmt || (yCh + xCh) == xIsCmt) { xValue += BFn(xStr); xIsCmt = ""; xStr = ""; } } else { if (/\"|'|\//.test(xCh)) { xIsOp = xCh; xStr = xCh; } else { xValue += xCh; } } yCh = xCh; } return xValue; }; this.EscapeRE = /(\[|\]|\(|\)|\{|\}|\.|\?|\+|\*|\\|\/|\^|\$|\|)/g; this.Replace = function(ARE, AStr, BStr) { if (/\$/.test(BStr)) { BStr = BStr.replace(/\$/g, "$$$$"); } return AStr.replace(ARE, BStr); }; // *** // @method daa.Rand this.Rand = function(AMin, AMax) { if (AMax) { return Math.floor(Math.random() * (AMax - AMin + 1)) + AMin; } else { return Math.floor(Math.random() * (AMin + 1)); } }; this.Time = function() { var x=new Date(); return Math.round((x/1000) - (x.getTimezoneOffset() * 60)); }; // ************************************************************************** // Some utils methods this.LessInt = function(a,b){a=Number(a);b=Number(b);if(a<=b){return a;}else{return b;}}; this.MostInt = function(a,b){a=Number(a);b=Number(b);if(a>=b){return a;}else{return b;}}; this.Neg = function(a){if(!a){return 1;}else{return 0;}}; this.PosVal = function(a){if(a>0){return a;}else{return 0;}}; this.Swap = function(a){ if(daa.IsString(a)){ // Orientation if (a == "v") { return "h"; } if (a=="h") { return "v"; } // Display if (this.StrPos(a, "display:") == 0) { a = a.replace(/display:\s*/, ""); if (a == "block") { return "none"; } else { return "block"; } } }else{ if(a){return 0;}return 1; } }; // ************************************************************************** // Core SubClasses // ************************************************************************** // // CLASS CSV // // ************************************************************************** // ************************************************************************** // @class CSV daa.csv this.csv = new function() { this.path = "daa"; this.name = "csv"; this.classname = "CSV"; this.requires = "daa"; // *** // @method daa.csv.Split this.Split = function(AObj, ASeparator) { ASeparator = ASeparator || ","; var xArr = String(AObj).split(ASeparator); var xRes = []; for (var xi = 0; xi < xArr.length; xi++) { xArr[xi] = Trim(xArr[xi]); if (daa.IsEmptyString(xArr[xi])) { continue; } xRes.push(xArr[xi]); } return xRes; }; // *** // @method daa.csv.SplitAsKeys this.SplitAsKeys = function(AObj, ASeparator, AProto) { ASeparator = ASeparator || ","; var xArr = String(AObj).split(ASeparator); var xRes = {}; for (var xi = 0; xi < xArr.length; xi++) { xArr[xi] = Trim(xArr[xi]); if (daa.IsEmptyString(xArr[xi])) { continue; } if (AProto) { xRes[xArr[xi]] = AProto; } else { xRes[xArr[xi]] = 1; } } return xRes; }; // *** // @method daa.csv.Join // AIsNU - undocumented IsNonUnique param. Used only internally by daa.path.Join // to remain non unique values in the result string. this.Join = function(AObj, ASeparator, AIsNU) { AIsNU = AIsNU || 0; var xSep = ASeparator || ","; var xRes = xSep; var xVal = ""; if (daa.IsEnum(AObj)) { for (var xkey in AObj) { xVal = Trim(AObj[xkey]); if (daa.IsEmptyString(xVal)) { continue; } if (!AIsNU) { if (xRes.indexOf(xSep + xVal + xSep) >= 0) { continue; } } xRes += xVal + xSep; } } else if (AObj.toString) { xRes = xSep + (daa && Trim(AObj) || AObj) + xSep; } return xRes.replace(new RegExp("^" + xSep + "|" + xSep + "$", "g"), ""); }; // *** // @method daa.csv.JoinKeys this.JoinKeys = function(AObj, ASeparator) { if (!daa.IsEnum(AObj)) { return "0"; } var xSep = ASeparator || ","; var xRes = ""; for (var xkey in AObj) { if (daa.IsEmptyString(xkey)) { continue; } xRes ? xRes += xSep : xRes; xRes += Trim(xkey); } return xRes; }; // *** // @method daa.csv.Count this.Count = function(AObj, ASeparator) { return String(AObj).split(ASeparator || ",").length; }; // *** // @method daa.csv.Get this.Get = function(AObj, AIndex, ASeparator) { var xArr = this.Split(AObj, ASeparator); return xArr[AIndex] || ""; }; // *** // @method daa.csv.Set this.Set = function(AObj, AIndex, AValue, ASeparator) { var xArr = this.Split(AObj, ASeparator); AIndex = Math.abs(AIndex); AIndex > xArr.length ? AIndex = xArr.length : AIndex; xArr[AIndex] = String(AValue); return this.Join(xArr, ASeparator); }; function Args(AObj, AValue, ASeparator) { var xSep = ASeparator || ","; var xStr = xSep; if (daa.IsString(AObj)) { xStr += daa.csv.JoinKeys(daa.csv.SplitAsKeys(AObj, xSep), xSep); } else if (daa.IsArray(AObj)) { xStr += daa.csv.Join(AObj, xSep); } else if (daa.IsObject(AObj)) { xStr += daa.csv.JoinKeys(AObj, xSep); } if (xStr != xSep) { xStr += xSep; } return { s: xSep, v: (daa.IsEnum(AValue) && AValue) || daa.csv.Split(AValue, xSep), o: xStr }; } function RE(AValue, ASep) { ASep = ASep.replace(daa.EscapeRE, "\\$1"); return new RegExp(ASep + "[\\s]*?" + AValue.replace(daa.EscapeRE, "\\$1") + "[\\s]*?" + ASep); } function Ret(AValue, ASep) { ASep = ASep.replace(daa.EscapeRE, "\\$1"); return AValue.replace(new RegExp("^" + ASep + "|" + ASep + "$", "g"), ""); } // *** // @method daa.csv.HAS @groupname bitwise this.HAS = function(AObj, AValue, ASeparator) { var xA = Args(AObj, AValue, ASeparator); for (var xi = 0; xi < xA.v.length; xi++) { if (!RE(xA.v[xi], xA.s).test(xA.o)) { return 0; } } return 1; }; // *** // @method daa.csv.EQV @groupname bitwise this.EQV = function(AObj, AValue, ASeparator) { var xSep = ASeparator || ","; return Number(this.HAS(AObj, AValue, xSep) && this.HAS(AValue, AObj, xSep)); }; // *** // @method daa.csv.AND @groupname bitwise this.AND = function(AObj, AValue, ASeparator) { var xA = Args(AObj, AValue, ASeparator), xRe; var xR = xA.s; for (var xi = 0; xi < xA.v.length; xi++) { xRe = RE(xA.v[xi], xA.s); if (xRe.test(xA.o) && !xRe.test(xR)) { xR += xA.v[xi] + xA.s; } } return Ret(xR, xA.s); }; // *** // @method daa.csv.OR @groupname bitwise this.OR = function(AObj, AValue, ASeparator) { var xA = Args(AObj, AValue, ASeparator); for (var xi = 0; xi < xA.v.length; xi++) { if (!RE(xA.v[xi], xA.s).test(xA.o)) { xA.o += xA.v[xi] + xA.s; } } return Ret(xA.o, xA.s); }; // *** // @method daa.csv.XOR @groupname bitwise this.XOR = function(AObj, AValue, ASeparator) { var xA = Args(AObj, AValue, ASeparator), xRe; for (var xi = 0; xi < xA.v.length; xi++) { xRe = RE(xA.v[xi], xA.s); if (xRe.test(xA.o)) { xA.o = xA.o.replace(xRe, xA.s); } else { xA.o += xA.v[xi] + xA.s; } } return Ret(xA.o, xA.s); }; // *** // @method daa.csv.NOT @groupname bitwise this.NOT = function(AObj, AValue, ASeparator) { var xA = Args(AObj, AValue, ASeparator), xRe; for (var xi = 0; xi < xA.v.length; xi++) { xRe = RE(xA.v[xi], xA.s); if (xRe.test(xA.o)) { xA.o = xA.o.replace(xRe, xA.s); } } return Ret(xA.o, xA.s); }; }; // ************************************************************************** // // CLASS QS // // ************************************************************************** // ************************************************************************** // @class QS daa.qs this.qs = new function () { this.path = "daa"; this.name = "qs"; this.classname = "QS"; // *** // @method daa.qs.Split this.Split = function(AObj, ASeparator, BSeparator, AFormat) { AObj = String(AObj); var xSep = (ASeparator && ASeparator) || "&", ySep = (BSeparator && BSeparator) || "=", zSep = (xSep == "#" && "") || "#"; zSep = zSep + "DAA_SEP" + zSep; var xRO = {n: 0, f: function(a) { return a.replace(new RegExp(xSep, "g"), zSep); } }; var xRF = function(a) { xRO.n > 0 ? a = xRO.f(a) : a = a.replace(new RegExp(xRO.se + "[\\s\\S]+$"), xRO.f); xRO.n = xRO.n + a.split(xRO.s).length - 2; return a; }; xRO.s = "{"; xRO.se = "{"; AObj = AObj.replace(/[\s\S]*?}/g, xRF); xRO.s = "<"; xRO.se = "<"; AObj = AObj.replace(/[\s\S]*?>/g, xRF); xRO.s = "("; xRO.se = "\\("; AObj = AObj.replace(/[\s\S]*?\)/g, xRF); xRO.s = "["; xRO.se = "\\["; AObj = AObj.replace(/[\s\S]*?\]/g, xRF); AObj = daa.ReplaceQuotes(AObj, xRO.f); var xObj = {}, xArr = AObj.split(xSep), xKey, xValue; if (arguments.length > 2 && daa.IsNull(BSeparator)) { for (var xi = 0; xi < xArr.length; xi++) { xArr[xi] = xArr[xi].replace(new RegExp(zSep, "g"), xSep); if (AFormat & daa.RET_TRIMMED) { xArr[xi] = Trim(xArr[xi]); } if (AFormat & daa.RET_NUMERIC && daa.IsNumeric(xArr[xi])) { xArr[xi] = Number(xArr[xi]); } } return xArr; } for (var xi = 0; xi < xArr.length; xi++) { if (!xArr[xi]) { continue; } xArr[xi] = xArr[xi].replace(new RegExp(zSep, "g"), xSep); xKey = xArr[xi].replace(new RegExp(ySep + "[\\s\\S]*$"), "").replace(/^[\s]+|[\s]+$/g, ""); xArr[xi].indexOf(ySep) >= 0 ? xValue = xArr[xi].replace(new RegExp("^[\\s\\S]*?" + ySep), "") : xValue = ""; if (AFormat & daa.RET_TRIMMED) { xValue = Trim(xValue); } if ((AFormat & daa.RET_NUMERIC) && daa.IsNumeric(xValue)) { xValue = Number(xValue); } xObj[xKey] = xValue; } return xObj; }; // *** // @method daa.qs.Join this.Join = function(AObj, ASeparator, BSeparator) { var xSep = (ASeparator && ASeparator) || "&", ySep = (BSeparator && BSeparator) || "="; var xStr = ""; for (var xkey in AObj) { xStr ? xStr += xSep : xStr; xStr += xkey + ySep + AObj[xkey] || ""; } return xStr; }; }; // ************************************************************************** // // CLASS LC // // ************************************************************************** // ************************************************************************** // @class LC daa.lc this.lc = new function () { this.path = "daa"; this.name = "lc"; this.classname = "LC"; // *** // @method daa.lc.ToSnake function ToSnakeA(a, b, c) { return (c ? "_" : "") + b.toLowerCase(); } function ToSnakeB(a, c) { return (c ? "_" : "") + a.toLowerCase(); } this.ToSnake = function(AValue) { AValue = String(AValue); if (/-/.test(AValue)) { return AValue.replace(/-(\S)/g, ToSnakeA).replace(/[A-Z]/g, ToSnakeB); } else if (/_/.test(AValue)) { return AValue.replace(/_(\S)/g, ToSnakeA).replace(/[A-Z]/g, ToSnakeB); } else { return AValue.replace(/[A-Z]/g, ToSnakeB); } }; // *** // @method daa.lc.ToCamel function ToCamelA(a, b, c) { return c ? b.toUpperCase() : b.toLowerCase(); } function ToCamelB(a) { return a.toLowerCase(); } this.ToCamel = function(AValue) { AValue = String(AValue); if (/_/.test(AValue)) { return AValue.replace(/_(\S)/g, ToCamelA).replace(/^[A-Z]/, ToCamelB); } else if (/-/.test(AValue)) { return AValue.replace(/-(\S)/g, ToCamelA).replace(/^[A-Z]/, ToCamelB); } else { return AValue.replace(/^[A-Z]/, ToCamelB); } }; // *** // @method daa.lc.ToPascal function ToPascalA(a, b) { return b.toUpperCase(); } function ToPascalB(a) { return a.toUpperCase(); } this.ToPascal = function(AValue) { AValue = String(AValue); if (/_/.test(AValue)) { return AValue.replace(/_(\S)/g, ToPascalA).replace(/^[a-z]/, ToPascalB); } else if (/-/.test(AValue)) { return AValue.replace(/-(\S)/g, ToPascalA).replace(/^[a-z]/, ToPascalB); } else { return AValue.replace(/^[a-z]/, ToPascalB); } }; // *** // @method daa.lc.ToKebab function ToKebabA(a, b, c) { return (c ? "-" : "") + b.toLowerCase(); } function ToKebabB(a, c) { return (c ? "-" : "") + a.toLowerCase(); } this.ToKebab = function(AValue) { AValue = String(AValue); if (/-/.test(AValue)) { return AValue.replace(/-(\S)/g, ToKebabA).replace(/[A-Z]/g, ToKebabB); } else if (/_/.test(AValue)) { return AValue.replace(/_(\S)/g, ToKebabA).replace(/[A-Z]/g, ToKebabB); } else { return AValue.replace(/[A-Z]/g, ToKebabB); } }; // *** // @method daa.lc.ToTrain function ToTrainA(a, b, c) { return (c ? "-" : "") + b.toUpperCase(); } function ToTrainB(a, c) { return (c ? "-" : "") + a.toUpperCase(); } this.ToTrain = function(AValue) { AValue = String(AValue); if (/-/.test(AValue)) { return AValue.replace(/-(\S)/g, ToTrainA).replace(/^[a-z]/, ToPascalB); } else if (/_/.test(AValue)) { return AValue.replace(/_(\S)/g, ToTrainA).replace(/^[a-z]/, ToPascalB); } else { return AValue.replace(/[A-Z]/g, ToTrainB).replace(/^[a-z]/, ToPascalB); } }; }; // ************************************************************************** // // CLASS VARIABLE // // ************************************************************************** // ************************************************************************** // @class Variable daa.variable this.variable = new function () { this.path = "daa"; this.name = "variable"; this.classname = "Variable"; // *** // @method daa.variable.Fill this.Fill = function(AValue) { if (!AValue || !/\$/.test(AValue)) { return AValue; } AValue = daa.String(AValue); var xRE1, yRE1, xRE2, yRE2; for (var xkey in daa.variables) { if (!/^\$/.test(xkey)) { continue; } xRE1 = new RegExp(xkey.replace(/\$/, "\\$") + "\\b"); yRE1 = new RegExp("\\\\(" + xkey.replace(/\$/, "\\$") + ")\\b"); xRE2 = new RegExp("{" + xkey.replace(/\$/, "\\$") + "}"); yRE2 = new RegExp("{{" + xkey.replace(/\$/, "\\$") + "}}"); if (xRE2.test(AValue) && !yRE2.test(AValue)) { AValue = AValue.replace(xRE2, daa.variables[xkey]); } if (xRE1.test(AValue) && !yRE1.test(AValue)) { AValue = AValue.replace(xRE1, daa.variables[xkey]); } if (yRE1.test(AValue)) { AValue = AValue.replace(yRE1, "$1"); } if (!/\$/.test(AValue)) { break; } } return AValue; }; }; // ************************************************************************** // // CLASS PATTERN // // ************************************************************************** // ************************************************************************** // @class Pattern daa.pattern this.pattern = new function () { this.path = "daa"; this.name = "pattern"; this.classname = "Pattern"; function Validate(AExpr) { AExpr = AExpr.replace(/([{\(])[\s]*?([&\|\^\+\-\*\/=!\?])/g, "$1 0 $2") .replace(/([&\|\^\+\-\*\/=!\?])[\s]*?([}\)])/g, "$1 0 $2") .replace(/([&\|\^\+\-\*\/=!\?])[\s]+?([&\|\^\+\-\*\/=!\?])/g, "$1 0 $2"); return AExpr; } function EvalExpr(AExpr, AObj) { var xVal = undefined, xDefault = ""; if (/\?/.test(AExpr)) { xDefault = AExpr.replace(/^[\s\S]*?\?/, ""); AExpr = AExpr.replace(/\?[\s\S]*$/, ""); } if (/\"|'/.test(AExpr)) { xVal = AExpr.replace(/[\"']/g, ""); } else { if (!daa.IsEnum(AObj)) { if (AExpr == "value") { xVal = AObj;