/** @module WrapperTracer */
/**
* <i style="display:none;">@namespace</i>
* @class
* @classdesc
* <img src="img/WrapperTracer-logo.png" title="WrapperTracer logo" alt="logo" style="float:right;" />
* <p>It creates a WRAPPER OBJECT that tracks the methods execution of other objects. Serves of 'TRACER'
* to obtain a visual representation of execution cycle of the methods, as well as
* help with information (elapsed time, nesting, types of methods, parameters, ...).
* With only two parameters required: The 'original object' and the 'DOM container' element,
* we obtain the 'wrapped' object and all visual inteface.
* </p>
* @overview
* <pThis 'class' relies heavily on the utility functions containing another object
* implemented in the same file, the 'UTIL' object, which contains methods and static objects
* that, although are oriented specifically for the object 'wrapper', could
* Used outside it following his 'classpath'.</p>
*
* <p>The constructor allows three parameters: </p>
* <ul>
* <li>{Object} obj - The Javascript object to wrap.</li>
* <li>{HTMLElement|string} container - The 'HTMLElement' or your 'Element' which will serve as container for all UI.</li>
* <li>{Function} callback [OPTIONAL] - The function to embed in each object methods.</li>
* </ul>
*
* <p>TESTED ON :: http://jsperf.com/wrapper-compare/3</p>
* @example <caption>To Wrap a JS object.</caption>
* //Gets the Wrapper and builds entire interface in the 'idElement' element
* var wrapper = new WrapperTracer(objJS, 'idElement', null);
* //Gets the wrapped
* var wrapped = wrapper.getWrapped();
* //Executes a method in the wrapped object to observe its tracking and tracing
* wrapped.execBlahBlahBlah(blah, blah, blah);
*
* @author GuerraTron - 2015. <dinertron@gmail.com> - GPL-v3
* @version 1.0.0b
* @summary It is a <b>namespace</b> / <b>class</b>. This generate a <b>Wrapper</b> object to inject events in objects methods and tracking their execution cycle.
* @namespace WrapperTracer {namespace}
*/
var WrapperTracer = (function Auto() {
/** STATIC OBJECT WITH UTILITY METHODS BUT WITHOUT STATE
* @summary Static object of utility. It can be obtained through its GETTER {@link WrapperTracer#getUtil()}
* @name Util
* @inner
* @private
* @memberof module:WrapperTracer
* @property {Object} Util - The Util object
* @property {Function} Util.wrapp - The wrapped object
* @property {Function} Util.clone - Clone the original object
* @property {Function} Util.inyect - Inyect events in the methods
* @property {Function} Util.getProperties - Gets a listing with the properties
* @property {Object} Util.LIFO - Stack which manages the routes
* @property {Object} Util.UI - Builds the interface
* @property {Function} Util.addClass - Adds a class to DOM element
* @property {Function} Util.removeClass - Remove a class from DOM element
* @property {Function} Util.toggleClass - Add/Remove a class to DOM element
* @property {Function} Util.hasClass - Checks for a class in a DOM element
* @property {Function} Util.addEvent - [CROSS-BROWSER] Adds a event to DOM element
* @property {Function} Util.removeEvent - [CROSS-BROWSER] Remove a event from DOM element
* @property {Function} Util.hasEvent - [CROSS-BROWSER] Checks for a event in a DOM element
* @property {Function} Util.toggleDisplay - Toggle a DOM element visibility
* @property {Function} Util.getClassName - It gets a class name based on an object
* @property {string} Util.name - [DEBUG] Name of this object.
*/
var Util = {
/** STATIC :: It wraps all properties (objects, functions, strings, ...) have previously been defined in the object,
* even if they have been defined 'undefined'. The other properties (internal or undefined) do not appear.
* The properties are set as in the original object, respecting the own properties and those of its prototype.
* CONCLUSION: For view undefined properties them even would be necessary to establish them 'undefined' in
* the original object !!.
* @memberof module:WrapperTracer.Util
* @type {Function}
* @param {Object} obj - The original object
* @param {Function} callback - The outer callback function to inject
* @param {Function} notify - Other inner function to inject
* @return {Object}*/
wrapp: function (obj, callback, notify) {
// First clone all properties
var wrapped = Util.clone(obj);
// Then inject the 'Tracers' events within each method
for (var p in obj) {
if (typeof obj[p] === "function") {
wrapped[p] = Util.inject(wrapped, obj, p, callback, notify);
}
}
return wrapped;
},
/** STATIC :: It handles clone the original object wrapped in and return it, differentiating the own methods
* of the prototypal methods
* @memberof module:WrapperTracer.Util
* @type {Function}
* @param {Object} obj - The original object
* @return {Object} */
clone: function (obj) {
/** IDENTIFICATOR */
var id = ("WrapperTracer-" + new Date().getTime() + "-" + Math.floor((Math.random() * 10) + 1));
//CONSTRUCTOR
function F(id) {
this.id = id;
}
var wrapped = new F(id); //new (function(){}); //reset the object
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
wrapped[p] = obj[p];
}
else {
//wrapped.__proto__[p] = obj[p];
F.prototype[p] = obj[p];
}
}
return wrapped;
},
/** STATIC :: Injected into a particular method of an object the tracer event
* @memberof module:WrapperTracer.Util
* @type {Function}
* @param {Object} wrapped - The wrapped object
* @param {Object} obj - The original object
* @param {string} nameFunct - The method name which to inject
* @param {Function} callback - The outer callback function to inject
* @param {Function} notify - Other inner function to inject
* @return {Function} */
inject: function (wrapped, obj, nameFunct, callback, notify) {
return function () {
Util.LIFO.add(nameFunct); //add an element to followed path
var timeIni = new Date().getTime(); //msg.
var result = obj[nameFunct].apply(wrapped, arguments);
var elapsed = new Date().getTime() - timeIni; //msg.
if (notify) {
notify(elapsed, nameFunct, result, arguments);
}
if (callback) {
callback(elapsed, nameFunct, result, arguments);
}
Util.LIFO.del(); //removes the last element of the route to follow
return result;
};
},
/** STATIC :: Gets all the properties of the original object (strings, numbers, functions, ...) both own properties
* as their prototype properties (as the last parameter) and constructs an object with all them separate by your
* type (objects, functions, strings, numbers, booleans and undefined) and returns it.
* @memberof module:WrapperTracer.Util
* @type {Function}
* @param {Object} obj - The original object
* @param {number} own - Only own properties (1), inherited (-1), or both (0).
* @return {Object}*/
getProperties: function (obj, own) {
own || (own = 0);
var arr = {
"objects": [],
"functions": [],
"strings": [],
"numbers": [],
"booleans": [],
"undefineds": []
};
for (var p in obj) {
if (arr[(typeof obj[p]).toLowerCase() + "s"]) {
if ((own === 1) && obj.hasOwnProperty(p)) {
arr[(typeof obj[p]).toLowerCase() + "s"].push(p);
}
else if ((own === -1) && !obj.hasOwnProperty(p)) {
arr[(typeof obj[p]).toLowerCase() + "s"].push(p);
}
else if (own === 0) {
arr[(typeof obj[p]).toLowerCase() + "s"].push(p);
}
}
}
return arr;
},
/** Useful object for creating deep routes or tracking, similar to LIFO stacks.
* It contains a root element which derives (separated by SEP parameter) the different elements that we go adding. It contains 'add',
* 'the', 'count', 'last' and 'reset' methods.
* @memberof module:WrapperTracer.Util
* @name LIFO
* @inner
* @type {Object}
* @property {Object} LIFO - The LIFO stack
* @property {string} LIFO.root - Root Path
* @property {string} LIFO.path - Path to follow
* @property {string} LIFO.SEP - Separator symbol
* @property {Function} LIFO.add - Add element
* @property {Function} LIFO.del - Remove element
* @property {Function} LIFO.last - Last element
* @property {Function} LIFO.count - Count elements
* @property {Function} LIFO.reset - Reset to 'root'*/
LIFO: {
/** Root element of the path. It will allways exist */
root: "WrapperTracer",
/** Parameter that tracks the route to follow. */
path: "WrapperTracer",
/** Separator symbol for each path element. */
SEP: ".",
/** Sum or adding a new element to path */
add: function (name) {
this.path = this.path + this.SEP + name;
},
/** Deletes the path's last element without allowing him to remain empty */
del: function () {
if (this.path.split(this.SEP).length > 1) {
var arr = this.path.split(this.SEP);
arr.pop();
this.path = arr.join(this.SEP);
}
},
/** Returns the path's last element, without modification. */
last: function () {
return this.path.split(this.SEP)[this.path.split(this.SEP).length - 1];
},
/** Count the path's parts */
count: function () {
return this.path.split(this.SEP).length;
},
/** Reset the path */
reset: function () {
this.path = this.root;
}
},
/** Useful object for create the tracking interface of executed methods within object
* @memberof module:WrapperTracer.Util
* @name UI
* @inner
* @type {Object}
* @property {Object} UI - The UI builder
* @property {function} UI.fatherStylized - Apply style to parent elements
* @property {Object} UI.propertyStylized - Apply style to properties
* @property {Function} UI.getDepthColor - Color depending on the depth
* @property {Function} UI.getPropertyTypeColor - Color depending on the property type
* @property {Function} UI.getPropertyTypeNamed - Name depending on the property type
* @property {Function} UI.getPropertyType - Number which representing the property type
* @property {Function} UI.prepareBody - Build the UI
* @property {Function} UI.buildPropertiesInfo - Build the information for ALL properties
* @property {Function} UI.buildPropertyInfo - Build the information for only one property
* @property {Function} UI.buildDOMPath - Build the DOM tree from path
* @property {Function} UI.getLastDOMPath - Returns the last DOM element from path
* @property {Function} UI.enhanced - [EFECTOS] Stand out the 'border property', indicating the time in milliseconds.
* @property {Function} UI.highlight - [EFECTOS] Stand out the 'border property', indicating the HTML color.
* @property {Function} UI.transparency - [EFECTOS] Apply the transparency (0-1). */
UI: {
/** Applying styles to the father of all elements representing methods executed and returns it, but stylized. It does only the first time. */
fatherStylized: function (padre, obj, path) {
//APPLY STYLE TO PARENT
if ((padre)) {
var h6, hr, a;
if (padre.getElementsByTagName("h6").length > 0) {
h6 = padre.getElementsByTagName("h6")[0];
//STANDING TO FINAL FOR THE 'hr' ELEMENT
hr = padre.getElementsByTagName("hr")[0];
padre.removeChild(hr);
padre.appendChild(hr);
}
else {
h6 = document.createElement("h6");
padre.insertBefore(h6, padre.childNodes[0]);
padre.style.background = "navajoWhite";
padre.style.borderRadius = "8px";
padre.style.boxShadow = "1px 1px 2px";
padre.style.padding = "2px";
padre.style.margin = "1px";
padre.style.zIndex = "100";
padre.style.position = "relative";
//h6.innerHTML = path;
hr = document.createElement("hr");
hr.style.clear = "both";
padre.appendChild(hr);
}
Util.addClass(padre, "wrapperEventFather");
a = document.createElement("a");
a.style.margin = "2px";
a.innerHTML = path + ", ";
a.href = "#" + path; //It headed us toward the element
//HIGHLIGHT THE ELEMENT AND IT FIRES YOUR ASSOCIATE METHOD
Util.addEvent(a, "click", function fireEventElement(e) {
/*e.preventDefault();*/
var partes = a.href.split("#");
var el = document.getElementById(partes[partes.length - 1]);
if (el) {
Util.UI.enhanced(el, 4000); //msg. de resalte
var imgs = el.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
if (Util.hasClass(imgs[i], "firerFunction")) {
imgs[i].click();
break;
}
}
}
e.stopPropagation();
return true;
});
//HIGHLIGHT THE ELEMENT WHILE IT IS ON THE LINK
Util.addEvent(a, "mouseover", function enhancedElement(e) {
/*e.preventDefault();*/
var partes = a.href.split("#");
var el = document.getElementById(partes[partes.length - 1]);
if (el) {
el.style.border = "2px solid yellow";
}
e.stopPropagation();
return true;
});
//UNHIGHLIGHT THE ELEMENT
Util.addEvent(a, "mouseleave", function unenhancedElement(e) {
/*e.preventDefault();*/
var partes = a.href.split("#");
var el = document.getElementById(partes[partes.length - 1]);
if (el) {
el.style.border = "1px solid maroon";
}
e.stopPropagation();
return true;
});
h6.appendChild(a);
// HIDE/SHOW ALL CHILDREN BY CLICKING ON THE TOTAL PARENT
function showHideInFather(e) {
e.preventDefault();
e.stopPropagation();
var hijos = padre.getElementsByTagName("div");
for (var i = 0; i < hijos.length; i++) {
Util.toggleDisplay(hijos[i]);
}
return true; //CONSUME
}
//Util.removeEvent (padre, "click", showHideInFather);
//Util.addEvent (padre, "click", showHideInFather);
padre.onclick = showHideInFather;
}
return padre;
},
/** It apply styles to the property corresponding to the last passed element. Their properties will be the time elapsed by the method executed,
* the method name, its path, the result and the arguments consumed by the method.
* The (original or wrapped) object is also delivered for get the reference function and use with trigger ('onclick' event).
* Return the same DOM element in parameters, but stylized. */
propertyStylized: function (p, obj, elapsed, nameFunct, path, result, args) {
if (p) {
var params = [].slice.call(args).toString();
p.id = path;
p.setAttribute("name", path);
Util.addClass(p, "wrapperEventFunction");
p.style.background = Util.UI.getDepthColor(path, null); //"darkOrange"; //[220, 100, 75]
p.style.border = "1px solid maroon";
p.style.borderRadius = "8px";
p.style.boxShadow = "1px 1px 2px";
//p.style.width = "10px";
p.style.padding = "2px";
p.style.margin = "1px";
p.style.cursor = "pointer";
p.style.cssFloat = "left";
p.style.fontSize = "x-small";
p.style.zIndex = (100 + path.split(Util.LIFO.SEP).length) + "";
p.style.position = "relative";
p.style.display = "block";
//INFORMATION OF METHOD
var ul = document.createElement("ul");
var li1 = document.createElement("li");
li1.innerHTML = "PATH:: " + path;
var li2 = document.createElement("li");
li2.innerHTML = "ELAPSED:: " + elapsed;
var li3 = document.createElement("li");
li3.innerHTML = "RESULT:: " + result;
ul.appendChild(li1);
ul.appendChild(li2);
ul.appendChild(li3);
p.insertBefore(ul, p.childNodes[0]);
//FUNCTION NAME AND PARAMETERS
var parr = document.createElement("p");
parr.style.color = "maroon";
parr.style.fontSize = "larger";
parr.innerHTML = nameFunct + " ( " + params + " ) ";
p.insertBefore(parr, p.childNodes[0]);
//METHOD TYPE AND TRIGGER
var menu = document.createElement("p");
menu.className = "ctrMethod";
menu.style.background = "lightYellow";
menu.style.color = "white";
menu.style.padding = "1px";
menu.style.borderRadius = "2px";
menu.style.position = "absolute";
menu.style.right = "0";
menu.style.fontSize = "smaller";
p.insertBefore(menu, p.childNodes[0]);
var spanType = document.createElement("span");
spanType.className = "infoMethod";
spanType.style.background = Util.UI.getPropertyTypeColor(obj, nameFunct);
spanType.style.color = "white";
spanType.style.padding = "4px";
spanType.style.margin = "1px";
spanType.style.borderRadius = "4px";
spanType.style.boxShadow = "1px 1px 2px";
spanType.style.cssFloat = "left";
spanType.title = Util.UI.getPropertyTypeNamed(obj, nameFunct);
spanType.innerHTML = spanType.title.substr(0, 1) + "<sub>" + Util.UI.getPropertyType(obj, nameFunct) + "</sub>";
menu.appendChild(spanType);
//FIRER element of method
var firer = document.createElement("img");
//IMG BASE64 RAYO : data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAACVBMVEVHAGiSXx700VSdCvDNAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQffDAMWDTUDTyMZAAAARElEQVQI12NgYNBawcDAsHIBkFjWwMDANAvI4MoAEpogITWgEMOqZQsYmFYtA7IYZgAxUwKQ4ARJaICEJoCEQDwOIAYAKIgLxkkVELUAAAAASUVORK5CYII=
//IMG BASE64 DARTBOARD : data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEVvcm0BAQD7AAD0BQHzBgLYHwn7/Bog997YAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQffDAMWDQfLmHKZAAAAVElEQVQI12NgQALBphDaSUlJBUQzKSkKKSmABYAMkJCSUqKYkhIDA6uSWqJYklIAA7OSmqJQkpIBggGUSlIDSQEVp6WBFIPMg5jIBGIoIFuBsBQCALW2DWubFikRAAAAAElFTkSuQmCC
//IMG BASE64 DARTBOARD2: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMBAMAAACkW0HUAAAAFVBMVEX/jYvEAAL0AAC2Hx1CSVDKtLL8//uFUdIFAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAAFxIAABcSAWef0lIAAAAHdElNRQffCwcRBRS/8uSNAAAAMUlEQVQI12NggAEXFwgJpl3c0lwcGFhc0sCUW5JiCogKEgRTycJACqoEpoHFBcSBAADyqwwbcf9r5QAAAABJRU5ErkJggg=="
firer.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMBAMAAACkW0HUAAAAFVBM" +
"VEX/jYvEAAL0AAC2Hx1CSVDKtLL8//uFUdIFAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAA" +
"JcEhZcwAAFxIAABcSAWef0lIAAAAHdElNRQffCwcRBRS/8uSNAAAAMUlEQVQI12NggAEXFwgJpl" +
"3c0lwcGFhc0sCUW5JiCogKEgRTycJACqoEpoHFBcSBAADyqwwbcf9r5QAAAABJRU5ErkJggg==";
firer.className = "firerFunction";
firer.style.cssFloat = "left";
firer.style.width = "16px";
firer.style.cursor = "pointer";
firer.style.border = "1px dashed maroon";
//firer.innerHTML = "⊙";
firer.title = (obj && obj[nameFunct]) ? obj[nameFunct].toString() : "???";
menu.appendChild(firer);
/*
var circle=document.createElement("span");
circle.style.color="red";
circle.style.fontSize="x-large";
circle.style.fontWeight="bolder";
circle.innerHTML = "⦿"; //"⊚"; //"⊙";
menu.appendChild(circle);*/
//FIRER EVENTS
Util.addEvent(firer, "mouseenter", function borderShow(e) {
e.preventDefault();
e.stopPropagation();
firer.style.border = "2px dashed red";
return true;
});
Util.addEvent(firer, "mouseleave", function borderHide(e) {
e.preventDefault();
e.stopPropagation();
firer.style.border = "1px ridge maroon";
return true;
});
//PASS THE ARGUMENTS BY CLICKING ON THE FUNCTION
Util.addEvent(firer, "click", function execFunction(e) {
e.preventDefault();
e.stopPropagation();
if (obj && obj[nameFunct]) {
obj[nameFunct].apply(obj, args);
}
return true;
});
//ELEMENT EVENTS
Util.addEvent(p, "click", function eventNull(e) {
e.preventDefault();
e.stopPropagation();
return true;
});
Util.addEvent(p, "mouseenter", function borderShow(e) {
e.preventDefault();
e.stopPropagation();
p.style.border = "2px ridge red";
return true;
});
Util.addEvent(p, "mouseleave", function borderHide(e) {
e.preventDefault();
e.stopPropagation();
p.style.border = "1px ridge maroon";
return true;
});
//SHOW/HIDE ALL 'DIV' CHILDREN OF ELEMENT, IF HAS IT
function showHideInSon(e) {
e.preventDefault();
e.stopPropagation();
for (var i = 0; i < hijos.length; i++) {
if (Util.hasClass(hijos[i], "wrapperEventFunction")) {
Util.toggleDisplay(hijos[i]);
}
}
return true;
}
var hijos = p.getElementsByTagName("div");
if ((hijos.length > 0)) {
Util.removeEvent(p, "click", showHideInSon);
Util.addEvent(p, "click", showHideInSon);
}
}
return p;
},
/** Returns an HTML color based on the depth of your path. Allows some initial RGB colors ([red, green, blue]) */
getDepthColor: function (path, rgb) {
rgb || (rgb = [220, 125, 25]);
var depth = path.split(Util.LIFO.SEP).length * 25;
return ("RGB(" + parseInt((rgb[0] + depth / 8) + "") + ", " +
parseInt((rgb[1] + depth / 2) + "") + ", " +
parseInt((rgb[2] + depth) + "") + ")");
},
/** Returns an HTML color based on the property type (function, object, string, ...) and inheritance.
* It can also be obtained if indicating the color index (the other parameters are ignored).
* Internally uses the 'getPropertyType' method */
getPropertyTypeColor: function (obj, prop, index) {
if (index === void 0) { index = undefined; }
if (isNaN(index))
index = Util.UI.getPropertyType(obj, prop);
switch (index) {
//FUNCTION
case 0: return "chartreuse"; //"function OWN"
case 1: return "limeGreen"; //"function INHERITED"
//OBJECT
case 2: return "mediumPurple"; //"object OWN"
case 3: return "blueViolet"; //"object INHERITED"
//ARRAY
case 4: return "khaki"; //"array OWN"
case 5: return "darkKhaki"; //"array INHERITED"
//STRING
case 6: return "navajoWhite"; //"string OWN"
case 7: return "coral"; //"string INHERITED"
//NUMBER
case 8: return "skyBlue "; //"number OWN"
case 9: return "steelBlue"; //"number INHERITED"
//BOOLEAN
case 10: return "cadetBlue"; //"boolean OWN"
case 11: return "Turquoise"; //"boolean INHERITED"
//UNDEFINED
case 12: return "#AAAAAA"; //"undefined OWN"
case 13: return "#666666"; //"undefined INHERITED"
//NULL
case 14: return "dimGray"; //"null OWN"
case 15: return "darkSlateGray"; //"null INHERITED"
//UNKNOW
case 16: return "darkGray"; //"desconocida OWN"
case 17: return "lightGray"; //"desconocida INHERITED"
//NON-EXISTENT
default: return "#333333"; //INEXISTENTE
}
return "#555555";
},
/** Returns a name based on the type of property (function, object, string, ...) and heritage.
* You can also obtained the name indicating its index (the other parameters are ignored).
* Internally uses the 'getPropertyType' method */
getPropertyTypeNamed: function (obj, prop, index) {
if (index === void 0) { index = undefined; }
if (isNaN(index))
index = Util.UI.getPropertyType(obj, prop);
switch (index) {
//FUNCTION
case 0: return "function OWN";
case 1: return "function INHERITED";
//OBJECT
case 2: return "object OWN";
case 3: return "object INHERITED";
//ARRAY
case 4: return "array OWN";
case 5: return "array INHERITED";
//STRING
case 6: return "string OWN";
case 7: return "string INHERITED";
//NUMBER
case 8: return "number OWN";
case 9: return "number INHERITED";
//BOOLEAN
case 10: return "boolean OWN";
case 11: return "boolean INHERITED";
//UNDEFINED
case 12: return "undefined OWN";
case 13: return "undefined INHERITED";
//NULL
case 14: return "null OWN";
case 15: return "null INHERITED";
//UNKNOW
case 16: return "unknown OWN";
case 17: return "unknown INHERITED";
//NON-EXISTENT
default: return "NON-EXISTENT";
}
return "NON-EXISTENT";
},
/** Returns the property type (function, object, string, ...) taking into account its inheritance. */
getPropertyType: function (obj, prop) {
if (obj) {
var own = obj.hasOwnProperty(prop); //check if the property is own or inherited.
switch ((typeof obj[prop]).toLowerCase()) {
case "function": return (own ? 0 : 1); //"green" : "lightGreen");
case "object": return (obj[prop] instanceof Array) ? (own ? 4 : 5) : ((obj[prop] === null) ? (own ? 14 : 15) : (own ? 2 : 3)); //"yellow" : "lightYellow");//"lime" : "lemmon");
case "array": return (own ? 4 : 5); //"lime" : "lemmon");
case "string": return (own ? 6 : 7); //"coral" : "navajoWhite");
case "number": return (own ? 8 : 9); //"blue" : "aquamarine");
case "boolean": return (own ? 10 : 11); //"blue" : "aquamarine");
case "undefined": return (obj[prop] === null) ? (own ? 14 : 15) : (own ? 12 : 13); //"blue" : "aquamarine");
case "null": return (own ? 14 : 15); //"blue" : "aquamarine");
default: return (own ? 16 : 17); //"darkGray" : "lightGray");
}
}
return 20; //UNKNOWN
},
/** Build and apply styles to the UI. There needs the container element (supports its id).
* @return Returns the DOM element (HTMLDivElement) */
prepareBody: function (container) {
//::prepareBody::
if (container) {
//Checks whether it has cast a string
try {
if (typeof container === "string") {
container = document.getElementById(container + "");
}
container.id = container.id; //It causes an exception if doesn't exists the container
}
catch (e) {
return container;
}
var h3 = document.createElement("h3");
h3.style.textDecoration = "underline";
h3.style.margin = "auto";
h3.style.textShadow = "1px 1px whiteSmoke";
h3.appendChild(document.createTextNode("WRAPPER-TRACER:"));
container.appendChild(h3);
var hr;
var wrapperInfo = document.createElement("div");
wrapperInfo.id = "wrapperInfo";
wrapperInfo.className = "wrapperInfo";
wrapperInfo.style.background = "lightGray";
wrapperInfo.style.borderRadius = "6px";
wrapperInfo.style.boxShadow = "4px 4px 6px";
wrapperInfo.style.width = "99%";
wrapperInfo.style.padding = "4px";
wrapperInfo.style.margin = "1px";
//TITLE
var h4 = document.createElement("h4");
h4.id = "wrapperInfo-title";
h4.innerHTML = "OBJECT SKELETON: ";
h4.style.cssFloat = "left";
h4.style.margin = "2px";
h4.style.maxWidth = "50%";
wrapperInfo.appendChild(h4);
hr = document.createElement("hr");
hr.style.clear = "both";
hr.style.marginBottom = "0";
wrapperInfo.appendChild(hr);
container.appendChild(wrapperInfo);
hr = document.createElement("hr");
hr.style.clear = "both";
container.appendChild(hr);
var wrapperEvents = document.createElement("div");
wrapperEvents.id = "wrapperEvents";
wrapperEvents.style.background = "lightYellow";
wrapperEvents.style.borderRadius = "6px";
wrapperEvents.style.boxShadow = "4px 4px 6px";
wrapperEvents.style.width = "99%";
wrapperEvents.style.padding = "4px";
wrapperEvents.style.margin = "1px";
wrapperEvents.style.clear = "both";
wrapperEvents.innerHTML = "OBJECT TRAITS:";
hr = document.createElement("hr");
hr.style.clear = "both";
wrapperEvents.appendChild(hr);
container.appendChild(wrapperEvents);
hr = document.createElement("hr");
hr.style.clear = "both";
hr.style.marginBottom = "0";
container.appendChild(hr);
}
return container;
},
/** Build all information relating to all methods and properties of the object, used or not, showing relevant information such as type of
* property and its value.
* It call internally to Util.UI.buildPropertyInfo (...) */
buildPropertiesInfo: function (container, obj) {
//::buildPropertiesInfo::
if (container && obj) {
//WRAPPER TITLE
var tituloWrapper = container.parentNode.firstChild; //the title already existed in a Heading h4 element
tituloWrapper.textContent += " '" + Util.getClassName(obj) + "' [" + typeof obj + "]";
//PROPERTIES CONTAINER
var divP = document.createElement("div");
divP.className = "wrapperProperties";
divP.style.clear = "both";
container.appendChild(divP);
//HIDE THE PROPERTIES
var spanVer = document.createElement("span");
spanVer.className = "viewEnabled";
spanVer.style.fontSize = "smaller";
spanVer.style.cssFloat = "left";
spanVer.style.textShadow = "1px 1px whiteSmoke";
spanVer.style.cursor = "pointer";
spanVer.style.padding = "2px";
spanVer.style.border = "4px ridge gray";
spanVer.style.borderRadius = "6px";
spanVer.style.boxShadow = "2px 2px 4px";
spanVer.title = "PROPERTIES (VIEW / HIDDEN)";
spanVer.onclick = function toggleFunction() {
if (spanVer.className === "viewEnabled") {
divP.style.display = "none";
spanVer.className = "viewDisabled";
}
else {
divP.style.display = "block";
spanVer.className = "viewEnabled";
}
};
spanVer.onmouseover = function hoverStyle() { spanVer.style.opacity = "0.8"; };
spanVer.onmouseout = function inhoverStyle() { spanVer.style.opacity = "1"; };
/*var plusMinus=document.createElement("span");
plusMinus.innerHTML="⊖⊕";*/
spanVer.appendChild(document.createTextNode("+/-")); //document.createTextNode("+/-") //plusMinus
container.insertBefore(spanVer, container.firstChild.nextSibling); // appendChild(spanVer);
var divInfo = document.createElement("div");
divInfo.className = "wrapperProperties-infoColors";
divInfo.style.fontSize = "x-small";
divInfo.style.cssFloat = "right";
divInfo.style.textShadow = "1px 1px whiteSmoke";
divInfo.style.padding = "2px";
divInfo.style.border = "1px solid gray";
divInfo.style.borderRadius = "6px";
divInfo.style.textAlign = "center";
divInfo.style.boxShadow = "2px 2px 4px";
divInfo.style.background = "whiteSmoke";
divInfo.innerHTML = "<-?:";
container.insertBefore(divInfo, container.firstChild.nextSibling);
for (var i = 0; i <= 18; i++) {
var infoColor = document.createElement("div");
infoColor.innerHTML = i + "";
infoColor.title = Util.UI.getPropertyTypeNamed(null, null, i);
infoColor.style.background = Util.UI.getPropertyTypeColor(null, null, i);
infoColor.style.borderRadius = "4px";
infoColor.style.width = "14px";
infoColor.style.height = "14px";
infoColor.style.padding = "0";
infoColor.style.margin = "1px";
infoColor.style.cssFloat = "left";
infoColor.style.cursor = "pointer";
infoColor.style.opacity = "1";
Util.UI.transparency(infoColor, 0.7);
divInfo.appendChild(infoColor);
}
//PROPERTIES SEPARATORS (NUMBER, STRINGS, OBJECTS, ARRAYS Y FUNCIONES)
var id = obj["id"] || parseInt((((Math.random() + 1) * 1000) / 10) + ""); //del 1 al 100
var pNumberString = document.createElement("div");
pNumberString.className = "wrapperPropertiesNumbers";
pNumberString.id = "wrapperPropertiesNumbers-" + id;
pNumberString.style.cssFloat = "left";
pNumberString.style.maxWidth = "18%";
pNumberString.style.border = "2px ridge maroon";
pNumberString.style.borderRadius = "8px";
pNumberString.style.textAlign = "center";
var h5 = document.createElement("h5");
h5.style.textDecoration = "underline";
h5.style.margin = "auto";
h5.style.textShadow = "1px 1px whiteSmoke";
h5.appendChild(document.createTextNode("NUMBERS, STRINGS, ..."));
pNumberString.appendChild(h5);
divP.appendChild(pNumberString);
var pObjectArray = document.createElement("div");
pObjectArray.className = "wrapperPropertiesObjects";
pObjectArray.style.cssFloat = "left";
pObjectArray.style.maxWidth = "18%";
pObjectArray.style.border = "2px ridge maroon";
pObjectArray.style.borderRadius = "8px";
pObjectArray.style.textAlign = "center";
h5 = document.createElement("h5");
h5.style.textDecoration = "underline";
h5.style.margin = "auto";
h5.style.textShadow = "1px 1px whiteSmoke";
h5.appendChild(document.createTextNode("OBJECTS, ARRAYS, ..."));
pObjectArray.appendChild(h5);
divP.appendChild(pObjectArray);
var pFunction = document.createElement("div");
pFunction.className = "wrapperPropertiesFunctions";
pFunction.style.cssFloat = "left";
pFunction.style.maxWidth = "58%";
pFunction.style.border = "2px ridge maroon";
pFunction.style.borderRadius = "8px";
pFunction.style.textAlign = "center";
//pFunction.style.overflow="auto";
h5 = document.createElement("h5");
h5.style.textDecoration = "underline";
h5.style.margin = "auto";
h5.style.textShadow = "1px 1px whiteSmoke";
h5.appendChild(document.createTextNode("FUNCTIONS, ..."));
pFunction.appendChild(h5);
divP.appendChild(pFunction);
/** Internal object for organize the methods types */
var objElements = {
"pNumberString": pNumberString,
"pObjectArray": pObjectArray,
"pFunction": pFunction
};
for (var s in obj) {
Util.UI.buildPropertyInfo(container, obj, s, objElements);
}
var br = document.createElement("br");
br.style.clear = "both";
container.appendChild(br);
}
return container;
},
/** Build information relating to a property of the object, is used or not, showing relevant information such as type of property and its value.
* The '<b>objElements</b>' parameter contain the 'divs' elements that will house all methods and properties depending on their type.
* This sirve to organize the used methods and is intended primarily for harboring at least the following structure:
* <pre>
* var objElements = {
* "pNumberString" : pNumberString,
* "pObjectArray" : pObjectArray,
* "pFunction" : pFunction
* }
* </pre> */
buildPropertyInfo: function (container, obj, s, objElements) {
if (container && obj) {
//PROPERTY
var divElements = null;
var p = document.createElement("div");
var own = obj.hasOwnProperty(s);
var iconTypeTxt = "?";
var iconTypeColor = "white"; //in the type-color is stored the color that is even to the method
p.className = "wrapperProperty-Info";
p.style.background = Util.UI.getPropertyTypeColor(obj, s);
switch (Util.UI.getPropertyType(obj, s)) {
case 0:
case 1:
divElements = objElements["pFunction"];
iconTypeTxt = "∮"; //"f";
iconTypeColor = (own ? "limeGreen" : "chartreuse");
break;
case 2:
case 3:
divElements = objElements["pObjectArray"];
iconTypeTxt = "☆"; //"░"; //"∴"; //"∷"; //"{}";
iconTypeColor = (own ? "blueViolet" : "mediumPurple");
break;
case 4:
case 5:
divElements = objElements["pObjectArray"];
iconTypeTxt = "∴"; //"∶"; //"⋮"; //"⋯"; //"[ ]";
iconTypeColor = (own ? "darkKhaki" : "khaki");
break;
case 6:
case 7:
divElements = objElements["pNumberString"];
iconTypeTxt = "æ"; //"𝕊"; //"ab";
iconTypeColor = (own ? "coral" : "navajoWhite");
break;
case 8:
case 9:
divElements = objElements["pNumberString"];
iconTypeTxt = "ℕ"; //"12";
iconTypeColor = (own ? "steelBlue" : "skyBlue");
break;
case 10:
case 11:
divElements = objElements["pNumberString"];
iconTypeTxt = "⊶"; //"⌽"; //"⊶"; //"01";
iconTypeColor = (own ? "Turquoise" : "cadetBlue");
break;
case 12:
case 13:
divElements = objElements["pNumberString"];
iconTypeTxt = "!";
iconTypeColor = (own ? "#666666" : "#AAAAAA");
break;
case 14:
case 15:
divElements = objElements["pNumberString"];
iconTypeTxt = "∅"; //"θ"; //"Θ";
iconTypeColor = (own ? "darkSlateGray" : "dimGray");
break;
default:
divElements = objElements["pFunction"];
iconTypeTxt = "?";
iconTypeColor = (own ? "lightGray" : "darkGray");
}
p.style.borderRadius = "6px";
p.style.boxShadow = "2px 2px 3px";
p.style.padding = "2px";
p.style.margin = "1px";
p.style.cssFloat = "left";
p.style.maxWidth = "98%";
p.style.maxHeight = "75px";
p.style.overflow = "auto";
p.onmouseover = function hoverStyle() { p.style.opacity = "0.8"; };
p.onmouseout = function inhoverStyle() { p.style.opacity = "1"; };
//PROPERTY TITLE
var title = document.createElement("h3");
title.className = "wrapperTitleProperty";
title.style.display = "inline";
title.title = "Property type: [" + (typeof obj[s]) + "]";
title.appendChild(document.createTextNode(" = " + s + " = "));
//PROPERTY BODY
var body = document.createElement("div");
body.className = "wrapperBodyProperty";
body.style.background = (own ? "white" : "whiteSmoke");
body.style.borderRadius = "2px";
body.style.boxShadow = "2px 2px 3px";
body.style.padding = "2px";
body.style.margin = "1px";
if (obj[s])
body.title = obj[s].toString();
var txt2 = document.createTextNode(obj[s]);
body.appendChild(txt2);
//ICON
var iconTxt = document.createElement("span");
iconTxt.innerHTML = iconTypeTxt;
iconTxt.style.padding = "2px";
iconTxt.style.background = iconTypeColor;
iconTxt.style.borderRadius = "2px";
iconTxt.style.cssFloat = "right";
iconTxt.style.width = "16px";
iconTxt.style.textShadow = "1px 1px whiteSmoke";
iconTxt.title = Util.UI.getPropertyTypeNamed(obj, s) + " [" + (own ? "Own" : "Inherited") + "]";
iconTxt.style.cursor = "pointer";
p.appendChild(title);
p.appendChild(iconTxt);
p.appendChild(body);
divElements.appendChild(p);
}
return container;
},
/** WARNIGN:: RECURSIVE FUNCTION::
* Build the DOM tree specified by the route in the container element indicated, and returns the element Father of them all.
* The route normally be in 'point' format: one.two.three */
buildDOMPath: function buildDOMPath(pContainer, path) {
var p;
if (pContainer) {
var partes = path.split(Util.LIFO.SEP);
var path2 = partes[0];
try {
var pp = pContainer.getElementsByTagName("div");
for (var j = 0; j < pp.length; j++) {
var ruta = pp[j].id.split(Util.LIFO.SEP);
if (ruta[ruta.length - 1] === path2) {
p = pp[j];
}
}
p.id = p.id; //if doesn't exists the element, it will throw an exception
}
catch (e) {
p = document.createElement("div");
p.id = path2;
pContainer.appendChild(p);
}
//IF IT HAS MORE THAN ONE PART, THEN RECURSIVITY
if (partes.length > 1) {
var ppp = buildDOMPath(p, partes.slice(1).join(Util.LIFO.SEP));
if (ppp) {
p.appendChild(ppp);
}
}
}
return p;
},
/** Returns a reference to the last DOM element of the path. The element must exist in the DOM tree. */
getLastDOMPath: function (pContainer, path) {
var p;
if (pContainer) {
var partes = path.split(Util.LIFO.SEP);
for (var i = 1; i < partes.length; i++) {
var path2 = partes[i];
try {
var pp = pContainer.getElementsByTagName("div");
for (var j = 0; j < pp.length; j++) {
if (pp[j].id === path2) {
p = pp[j];
}
}
p.id = p.id; //if doesn't exists the element, it will throw an exception
pContainer = p;
}
catch (e) {
p = null;
break; //Exit from 'For' structure with a NULL element. It doesn't has created within DOM yet.
}
}
}
return p;
},
/** Highlight the element based on its 'border' style property. Specify the highlighted time (in milliseconds.)
* The 'Util' object is returned to allow 'chaining' */
enhanced: function (el, time) {
if (time === void 0) { time = 2000; }
if (el) {
time || (time = 2000); //2 sg. por defecto
var oldBorde = el.style.border;
var oldDisplay = el.style.display;
el.style.display = "block";
el.style.border = "2px solid yellow";
window.setTimeout(function () {
el.style.display = oldDisplay;
el.style.border = oldBorde;
}, time);
}
return this;
},
/** Highlight the element based on its 'border' style property. Allows specify the highlighted color.
* The 'Util' object is returned to allow 'chaining' */
highlight: function (el, color) {
if (color === void 0) { color = "yellow"; }
if (el) {
color || (color = "yellow");
var oldBorde = el.style.border;
var oldDisplay = el.style.display;
Util.addEvent(el, "mouseover", function showHighlight(e) {
e.preventDefault();
e.stopPropagation();
el.style.display = "block";
el.style.border = "1px solid " + color;
return true;
});
Util.addEvent(el, "mouseleave", function hideHighlight(e) {
e.preventDefault();
e.stopPropagation();
el.style.display = oldDisplay;
el.style.border = oldBorde;
return true;
});
}
return this;
},
/** Highlight the element based on its 'opacity' style property. Allows specify the transparency level (0-1).
* The 'Util' object is returned to allow 'chaining' */
transparency: function (el, level) {
if (level === void 0) { level = 0.8; }
if (el) {
level || (level = 0.8);
var old = el.style.opacity;
Util.addEvent(el, "mouseover", function showTransparency(e) {
e.preventDefault();
e.stopPropagation();
el.style.opacity = level + "";
return true;
});
Util.addEvent(el, "mouseleave", function hideTransparency(e) {
e.preventDefault();
e.stopPropagation();
el.style.opacity = old;
return true;
});
}
return this;
}
},
/** Add a class to an element (if not previously existed). It uses the modern property 'classList'; should support it, but if not, applies a 'shim-code'.
* The 'Util' object is returned to allow 'chaining'
* @memberof module:WrapperTracer.Util
* @type {Function}
* @param {HTMLElement} elem - DOM element
* @param {string} className - The class to insert
* @return {Object:this} */
addClass: function (elem, className) {
if (elem.classList) {
elem.classList.add(className);
}
else {
if (elem.className.indexOf(className) === -1) {
//elem.className = elem.className + " " + className;
var clases = elem.className.split(" ");
clases.push(className);
elem.className = clases.join(" ");
}
}
return this;
},
/** Remove a class from an element (if not previously existed). It uses the modern property 'classList'; should support it, but if not, applies a 'shim-code'.
* The 'Util' object is returned to allow 'chaining'
* @memberof module:WrapperTracer.Util
* @type {Function}
* @param {HTMLElement} elem - DOM element
* @param {string} className - The class to remove
* @return {Object:this} */
removeClass: function (elem, className) {
if (elem.classList) {
elem.classList.remove(className);
}
else {
if (elem.className.indexOf(className) > -1) {
var clases = elem.className.split(" ");
var index = clases.indexOf(className);
clases.splice(index, 1);
elem.className = clases.join(" ");
}
}
return this;
},
/** Switch a class from an element (if not previously existed). It uses the modern property 'classList'; should support it, but if not, applies a 'shim-code'.
* The 'Util' object is returned to allow 'chaining'
* @memberof module:WrapperTracer.Util
* @type {Function}
* @param {HTMLElement} elem - DOM element
* @param {string} className - The class to toggle
* @return {Object:this} */
toggleClass: function myFunction(elem, className) {
if (elem.classList) {
elem.classList.toggle(className);
}
else {
if (elem.className.indexOf(className) > -1) {
Util.removeClass(elem, className);
}
else {
Util.addClass(elem, className);
}
}
return this;
},
/** This checks if the element contains the specified class. It uses the modern property 'classList'; should support it, but if not, applies a 'shim-code'.
* @return boolean
* @memberof module:WrapperTracer.Util
* @type {Function}
* @param {HTMLElement} elem - DOM element
* @param {string} className - The class to check
* @return {Object:this} */
hasClass: function myFunction(elem, className) {
if (elem.classList) {
return elem.classList.contains(className);
}
return (elem.className.indexOf(className) > -1);
},
/** EVENTS COMPATIBILIZER
* where 'a' is the item you want to set the listening, 'enventType' is a string (no prefix 'on') and 'handler' is a function to run.
* The 'Util' object is returned to allow 'chaining'
* @memberof module:WrapperTracer.Util
* @type {Function}
* @param {HTMLElement} elem - DOM element
* @param {string} eventType - The event type ('click', 'mouseover', 'mouseout', ...)
* @param {Function} handler - Function to execute for event
* @return {Object:this} */
addEvent: function (elem, eventType, handler) {
if (elem.addEventListener) {
elem.addEventListener(eventType, handler, false);
}
else if (elem.attachEvent) {
elem.attachEvent('on' + eventType, handler);
}
return this;
},
/** EVENTS COMPATIBILIZER
* where 'elem' is the item which to unset the listening, 'enventType' is a string (no prefix 'on') and 'handler' is a function to remove.
* The 'Util' object is returned to allow 'chaining'
* @memberof module:WrapperTracer.Util
* @type {Function}
* @param {HTMLElement} elem - DOM element
* @param {string} eventType - The event type ('click', 'mouseover', 'mouseout', ...)
* @param {Function} handler - Function to remove withing event
* @return {Object:this} */
removeEvent: function (elem, eventType, handler) {
elem[eventType] = null;
if (elem.removeEventListener) {
elem.removeEventListener(eventType, handler, false);
}
else if (elem.detachEvent) {
elem.detachEvent('on' + eventType, handler);
}
return this;
},
/** EVENTS COMPATIBILIZER
* where 'elem' is the item that is to determine if the event exists and 'enventType' is a string (no prefix 'on') to verify its existence.
* @return boolean
* @memberof module:WrapperTracer.Util
* @type {Function}
* @param {HTMLElement} elem - DOM element
* @param {string} eventType - The event type ('click', 'mouseover', 'mouseout', ...)
* @return {boolean} */
hasEvent: function (elem, eventType) {
eventType = (elem.attachEvent) ? "on" + eventType : eventType;
var comprobacion1 = (typeof elem[eventType] == "function");
var comprobacion2 = (elem[eventType] !== undefined);
var comprobacion3 = elem.hasOwnProperty(eventType);
return comprobacion1 || comprobacion2;
},
/** Switch the element visibility (if it showing then hide it, else not) based in your 'display' style property.
* The 'Util' object is returned to allow 'chaining'
* @memberof module:WrapperTracer.Util
* @type {Function}
* @param {HTMLElement} elem - DOM element
* @return {Object:this} */
toggleDisplay: function (elem) {
if (elem.style.display === "block") {
elem.style.display = "none";
}
else {
elem.style.display = "block";
}
return this;
},
/** Extract the class name which owns the actual object.
* @memberof module:WrapperTracer.Util
* @type {Function}
* @param {Object} obj - JS object to get a proper class name
* @return {string} */
getClassName: function (obj) {
return (obj && obj.constructor) ? ("" + obj.constructor).split("function ")[1].split("(")[0].trim() : "[NONE]";
},
/** Just for debugging purposes
* @memberof module:WrapperTracer.Util
* @type {string} */
name: "Util"
}; //END UTIL
/** IDENTIFICATOR
* @private
* @type {string}
* @default none */
var _id; //= "WrapperTracer-"+new Date().getTime +"-"+ Math.floor((Math.random()*10)+1);
/** Original Object
* @private
* @type {Object:Javascript}
* @default none */
var _target; //ORIGINAL OBJECT, DON'T MODIFIED
/** Wrapped Objeto
* @private
* @type {Object:WrapperTracer#Wrapped}
* @default none */
var _wrapped; //WRAPPED OBJECT
/** Grouping Properties (string, numbers, functions, objects, ...) in an Object, both own properties and private.
* @private
* @type {Object}
* @default empty {} */
var _props = {}; //OBJECT OF ARRAYs
/** Collection of information objects for each executed method, where informations are displayed as the consumed time, the operation result,
* the different parameters passed, ...
* @private
* @type {Object}
* @default empty {} */
var _info = {};
/** External function to insert the object 'wrapped' within each method. [OPTIONAL]
* You will pass as parameters the time spent by the method (in msg.), the method name to run, the result of this method and parameters that
* need the method. Allows externally interact with the API, it is a way to extend its possibilities.
* @private
* @type {Function}
* @default none
* @return {void|number|boolean|string|object} anything */
var _callback;
/** Internal function to insert the object 'wrapped' within each method, to follow a trail of its activity.
* You will pass as parameters the time spent by the method (in msg.), the method name to run, the result of this method and parameters that
* need the method.
* @private
* @type {Function}
* @return void */
var _notify = function (elapsed, nameFunct, result, args) {
//if(_info[nameFunct]) nameFunct += "_BIS";
var path = Util.LIFO.path;
_info[nameFunct] = {
"path": path,
"elapsed": elapsed,
"result": result,
"args": [].slice.call(args),
"type": Util.UI.getPropertyType(_target, nameFunct) //A number indicating the type of property
};
//USE THE UI
if (_container && _wrapperInfo && _wrapperEvents) {
//CREATE THE MISSING ELEMENTS OF THE ROUTE AND GETS THE FATHER OF ALL THEM
var padre = Util.UI.buildDOMPath(_wrapperEvents, path);
//STYLING FOR ELEMENT AND PROVIDES INFORMATION
padre = Util.UI.fatherStylized(padre, _target, path);
//OBTAIN THE REFERENCE TO DOM ELEMENT CREATED (THE LAST OF THE ROUTE)
var el = Util.UI.getLastDOMPath(_wrapperEvents, path);
//STYLING FOR ELEMENT AND PROVIDES INFORMATION
el = Util.UI.propertyStylized(el, _target, elapsed, nameFunct, path, result, args);
}
};
/** DOMElement container to insert the entire user interface and the result of tracking methods.
* @private
* @type {HTMLElement}
* @default none */
var _container;
/** This element is created from the 'prepareBody' method and serves as secondary container of the entire UI, usually to insert information
* such as the number of object methods.
* IMPORTANT: There must exist previously to the main 'container' element.
* @private
* @type {HTMLElement}
* @default null
* @defaultvalue null */
var _wrapperInfo = null;
/** Element created by the 'preparedBody' method, will house tracking methods fired by the object to be treated.
* IMPORTANT: There must exist previously to the main 'container' element.
* @private
* @type {HTMLElement}
* @default null */
var _wrapperEvents = null;
//FUNCTIONS FOR THE PUBLIC API
/** You may be calling this constructor with a callback function that will injected within each executed method.
* @constructor
* @constructs
* @summary CONSTRUCTOR.
* @param {Object} obj - The Javascript object to 'wrapper'.
* @param {HTMLElement|string} container - The 'HTMLElement' or its 'idElement' to serve as container for all UI.
* @param {Function} callback [OPTIONAL] - The function to embed within each object method. */
function WrapperTracer(obj, container, callback) {
//_initialize(obj, container, callback);
/** @summary Original Object */
_target = obj; //ORIGINAL OBJECT, DOESN'T MODIFY
/** Outer function to insert in 'wrapped' object within each method. [OPCIONAL]
* @summary Callback to insert in the wrapped. */
_callback = callback;
/** Build the UI informative interface
* @summary container element */
_container = setContainer(container);
/** Build the UI executive
* @summary Object Wrapped. */
_wrapped = Util.wrapp(obj, _callback, _notify); //WRAPPED OBJECT
/** @summary SELF-GENERATED IDENTIFICATOR */
_id = _wrapped["id"];
}
//PRIVATE FUNCTIONS
/** Private method initializer. Which is used within internally constructor.
* @private
* @function
* @param {Object} obj - The Javascript object to 'wrapper'.
* @param {HTMLElement|string} container - The 'HTMLElement' or its 'idElement' to serve as container for all UI.
* @param {Function} callback [OPTIONAL] - The function to embed within each object method.
* @return void
* @ignore */
function _initialize(obj, container, callback) {
}
//GETTERs METHODS
/** @summary Gets the id from this wrapper
* @public
* @type {Function}
* @return {string} */
WrapperTracer.prototype.getId = function () {
return _id || _wrapped["id"];
}
/** @export
* @summary Gets the original JS Object
* @public
* @type {Function}
* @return {Object:Javascript} */
WrapperTracer.prototype.getTarget = function () {
return _target;
}
/** @export
* @summary Gets the generated 'wrapped' Object
* @public
* @type {Function}
* @return {Object:WrapperTracer.Util#wrapp} */
WrapperTracer.prototype.getWrapped = function () {
return _wrapped || Util.wrapp(_target, _callback, _notify);
}
/** <i style="display:none;">@ lends WrapperTracer.prototype</i>
* @export
* @summary Gets the external callback function, if it had provided the builder
* @public
* @type {Function}
* @return {Function|null} */
WrapperTracer.prototype.getCallback = function () {
return _callback;
}
/** @export
* @summary Gets the all properties from JS Object
* @public
* @type {Function}
* @return {Object} */
WrapperTracer.prototype.getProps = function () {
return _props || Util.getProperties(_target, 0);
}
/** @export
* @summary Gets information from JS Object
* @public
* @type {Function}
* @return {Object} */
WrapperTracer.prototype.getInfo = function () {
return _info;
}
/** @export
* @summary Gets the DOM Element which is container for the all UI
* @public
* @type {Function}
* @return {Object:HTMLElement} */
WrapperTracer.prototype.getContainer = function () {
return _container;
}
/** @summary Returns the 'Util' Object.
* @this {WrapperTracer}
* @export
* @public
* @type {Function}
* @return {Object:WrapperTracer.Util} */
WrapperTracer.prototype.getUtil = function(){
return Util;
}
//SETTERs METHODS
/** Setter method to set the container to house all the UI. It also prepares the body of the container (info and events)
* @summary Sets the UI container
* @export
* @public
* @type {Function}
* @param {HTMLElement|string} container - The 'HTMLElement' or its 'idElement' to serve as container for all UI.
* @return {HTMLElement} */
WrapperTracer.prototype.setContainer = function (container) {
_container = container;
_container = Util.UI.prepareBody(_container);
if (_container) {
var divs = _container.getElementsByTagName("div"); //.getElementsByClassName("wrapperInfo");
_wrapperInfo = divs[0];
_wrapperEvents = divs[1];
_wrapperInfo = Util.UI.buildPropertiesInfo(_wrapperInfo, _target);
}
return _container;
}
return WrapperTracer;
})();
//# sourceMappingURL=WrapperTracer.en.js.map