webdriverio-automation
Version:
WebdriverIO-Automation android ios project
1,916 lines (1,648 loc) • 911 kB
JavaScript
/*
@license
webix UI v.2.4.5
This software is allowed to use under GPL or you need to obtain Commercial License
to use it in non-GPL project. Please contact sales@webix.com for details
*/
if (!window.webix)
webix={};
//check some rule, show message as error if rule is not correct
webix.assert = function(test, message){
if (!test){
webix.assert_error(message);
}
};
webix.assert_config = function(obj){
var coll = obj.cells || obj.rows || obj.elements || obj.cols;
if (coll)
for (var i=0; i<coll.length; i++)
if (coll[i] === null || typeof coll[i] === "undefined")
webix.assert_error("You have trailing comma or Null element in collection's configuration");
};
webix.assert_error = function(message){
//jshint debug:true
webix.log("error",message);
if (webix.message && typeof message == "string")
webix.message({ type:"debug", text:message, expire:-1 });
if (webix.debug !== false)
debugger;
};
//entry point for analitic scripts
webix.assert_core_ready = function(){
if (window.webix_on_core_ready)
window.webix_on_core_ready();
};
webix.assert_level = 0;
webix.assert_level_in = function(){
webix.assert_level++;
if (webix.assert_level == 100)
webix.assert_error("Attempt to copy object with self reference");
};
webix.assert_level_out = function(){
webix.assert_level--;
};
/*
Common helpers
*/
webix.version="2.4.5";
webix.codebase="./";
webix.name = "core";
//coding helpers
webix.clone = function(source){
var f = webix.clone._function;
f.prototype = source;
return new f();
};
webix.clone._function = function(){};
//copies methods and properties from source to the target
webix.extend = function(base, source, force){
webix.assert(base,"Invalid mixing target");
webix.assert(source,"Invalid mixing source");
if (base._webix_proto_wait){
webix.PowerArray.insertAt.call(base._webix_proto_wait, source,1);
return base;
}
//copy methods, overwrite existing ones in case of conflict
for (var method in source)
if (!base[method] || force)
base[method] = source[method];
//in case of defaults - preffer top one
if (source.defaults)
webix.extend(base.defaults, source.defaults);
//if source object has init code - call init against target
if (source.$init)
source.$init.call(base);
return base;
};
//copies methods and properties from source to the target from all levels
webix.copy = function(source){
webix.assert(source,"Invalid mixing target");
webix.assert_level_in();
var target;
if(arguments.length>1){
target = arguments[0];
source = arguments[1];
} else
target = (webix.isArray(source)?[]:{});
for (var method in source){
if(source[method] && typeof source[method] == "object" && !webix.isDate(source[method])){
target[method] = (webix.isArray(source[method])?[]:{});
webix.copy(target[method],source[method]);
}else{
target[method] = source[method];
}
}
webix.assert_level_out();
return target;
};
webix.single = function(source){
var instance = null;
var t = function(config){
if (!instance)
instance = new source({});
if (instance._reinit)
instance._reinit.apply(instance, arguments);
return instance;
};
return t;
};
webix.protoUI = function(){
if (webix.debug_proto)
webix.log("UI registered: "+arguments[0].name);
var origins = arguments;
var selfname = origins[0].name;
var t = function(data){
if (!t)
return webix.ui[selfname].prototype;
var origins = t._webix_proto_wait;
if (origins){
var params = [origins[0]];
for (var i=1; i < origins.length; i++){
params[i] = origins[i];
if (params[i]._webix_proto_wait)
params[i] = params[i].call(webix, params[i].name);
if (params[i].prototype && params[i].prototype.name)
webix.ui[params[i].prototype.name] = params[i];
}
webix.ui[selfname] = webix.proto.apply(webix, params);
if (t._webix_type_wait)
for (var i=0; i < t._webix_type_wait.length; i++)
webix.type(webix.ui[selfname], t._webix_type_wait[i]);
t = origins = null;
}
if (this != webix)
return new webix.ui[selfname](data);
else
return webix.ui[selfname];
};
t._webix_proto_wait = Array.prototype.slice.call(arguments, 0);
return (webix.ui[selfname]=t);
};
webix.proto = function(){
if (webix.debug_proto)
webix.log("Proto chain:"+arguments[0].name+"["+arguments.length+"]");
var origins = arguments;
var compilation = origins[0];
var has_constructor = !!compilation.$init;
var construct = [];
webix.assert(compilation,"Invalid mixing target");
for (var i=origins.length-1; i>0; i--) {
webix.assert(origins[i],"Invalid mixing source");
if (typeof origins[i]== "function")
origins[i]=origins[i].prototype;
if (origins[i].$init)
construct.push(origins[i].$init);
if (origins[i].defaults){
var defaults = origins[i].defaults;
if (!compilation.defaults)
compilation.defaults = {};
for (var def in defaults)
if (webix.isUndefined(compilation.defaults[def]))
compilation.defaults[def] = defaults[def];
}
if (origins[i].type && compilation.type){
for (var def in origins[i].type)
if (!compilation.type[def])
compilation.type[def] = origins[i].type[def];
}
for (var key in origins[i]){
if (!compilation[key] && compilation[key] !== false)
compilation[key] = origins[i][key];
}
}
if (has_constructor)
construct.push(compilation.$init);
compilation.$init = function(){
for (var i=0; i<construct.length; i++)
construct[i].apply(this, arguments);
};
if (compilation.$skin)
compilation.$skin();
var result = function(config){
this.$ready=[];
webix.assert(this.$init,"object without init method");
this.$init(config);
if (this._parseSettings)
this._parseSettings(config, this.defaults);
for (var i=0; i < this.$ready.length; i++)
this.$ready[i].call(this);
};
result.prototype = compilation;
compilation = origins = null;
return result;
};
//creates function with specified "this" pointer
webix.bind=function(functor, object){
return function(){ return functor.apply(object,arguments); };
};
//loads module from external js file
webix.require=function(module, callback, master){
if (webix.require.disabled){
if (callback)
callback.call(master||this);
return;
}
if (typeof module != "string"){
var count = module.length||0;
var callback_origin = callback;
if (!count){
for (var file in module) count++;
callback = function(){ count--; if (count === 0) callback_origin.apply(this, arguments); };
for (var file in module)
webix.require(file, callback, master);
} else {
callback = function(){
if (count){
count--;
webix.require(module[module.length - count - 1], callback, master);
} else
return callback_origin.apply(this, arguments);
};
callback();
}
return;
}
if (webix._modules[module] !== true){
if (module.substr(-4) == ".css") {
var link = webix.html.create("LINK",{ type:"text/css", rel:"stylesheet", href:webix.codebase+module});
document.head.appendChild(link);
if (callback)
callback.call(master||window);
return;
}
var step = arguments[4];
//load and exec the required module
if (!callback){
//sync mode
webix.exec( webix.ajax().sync().get(webix.codebase+module).responseText );
webix._modules[module]=true;
} else {
if (!webix._modules[module]){ //first call
webix._modules[module] = [[callback, master]];
webix.ajax(webix.codebase+module, function(text){
webix.exec(text); //evaluate code
var calls = webix._modules[module]; //callbacks
webix._modules[module] = true;
for (var i=0; i<calls.length; i++)
calls[i][0].call(calls[i][1]||window, !i); //first callback get true as parameter
});
} else //module already loading
webix._modules[module].push([callback, master]);
}
} else
if (callback) callback.call(master);
};
webix._modules = {}; //hash of already loaded modules
//evaluate javascript code in the global scoope
webix.exec=function(code){
if (window.execScript) //special handling for IE
window.execScript(code);
else window.eval(code);
};
webix.wrap = function(code, wrap){
if (!code) return wrap;
return function(){
var result = code.apply(this, arguments);
wrap.apply(this,arguments);
return result;
};
};
//check === undefined
webix.isUndefined=function(a){
return typeof a == "undefined";
};
//delay call to after-render time
webix.delay=function(method, obj, params, delay){
return window.setTimeout(function(){
if(!(obj&&obj.$destructed)){
var ret = method.apply(obj,(params||[]));
method = obj = params = null;
return ret;
}
},delay||1);
};
webix.once=function(method){
var flag = true;
return function(){
if (flag){
flag = false;
method.apply(this, arguments);
}
};
};
//common helpers
//generates unique ID (unique per window, nog GUID)
webix.uid = function(){
if (!this._seed) this._seed=(new Date()).valueOf(); //init seed with timestemp
this._seed++;
return this._seed;
};
//resolve ID as html object
webix.toNode = function(node){
if (typeof node == "string") return document.getElementById(node);
return node;
};
//adds extra methods for the array
webix.toArray = function(array){
return webix.extend((array||[]),webix.PowerArray, true);
};
//resolve function name
webix.toFunctor=function(str, scope){
if (typeof(str)=="string"){
var method = str.replace("()","");
if (scope && scope[method]) return scope[method];
return window[method] || eval(str);
}
return str;
};
/*checks where an object is instance of Array*/
webix.isArray = function(obj) {
return Array.isArray?Array.isArray(obj):(Object.prototype.toString.call(obj) === '[object Array]');
};
webix.isDate = function(obj){
return obj instanceof Date;
};
//dom helpers
//hash of attached events
webix._events = {};
//attach event to the DOM element
webix.event=function(node,event,handler,master){
node = webix.toNode(node);
webix.assert(node, "Invalid node as target for webix.event");
var id = webix.uid();
if (master)
handler=webix.bind(handler,master);
webix._events[id]=[node,event,handler]; //store event info, for detaching
//use IE's of FF's way of event's attaching
if (node.addEventListener)
node.addEventListener(event, handler, arguments[4]);
else if (node.attachEvent)
node.attachEvent("on"+event, webix._events[id][2] = function(){
return handler.apply(node, arguments); //IE8 fix
});
return id; //return id of newly created event, can be used in eventRemove
};
//remove previously attached event
webix.eventRemove=function(id){
if (!id) return;
webix.assert(this._events[id],"Removing non-existing event");
var ev = webix._events[id];
//browser specific event removing
if (ev[0].removeEventListener)
ev[0].removeEventListener(ev[1],ev[2],false);
else if (ev[0].detachEvent)
ev[0].detachEvent("on"+ev[1],ev[2]);
delete this._events[id]; //delete all traces
};
//debugger helpers
//anything starting from error or log will be removed during code compression
//add message in the log
webix.log = function(type,message,details){
if (arguments.length == 1){
message = type;
type = "log";
}
/*jsl:ignore*/
if (window.console && window.console.log){
type=type.toLowerCase();
if (window.console[type])
window.console[type](message||"unknown error");
else
window.console.log(type +": "+message);
if (details)
window.console.log(details);
}
/*jsl:end*/
};
//register rendering time from call point
webix.log_full_time = function(name){
webix._start_time_log = new Date();
webix.log("Timing start ["+name+"]");
window.setTimeout(function(){
var time = new Date();
webix.log("Timing end ["+name+"]:"+(time.valueOf()-webix._start_time_log.valueOf())/1000+"s");
},1);
};
//register execution time from call point
webix.log_time = function(name){
var fname = "_start_time_log"+name;
if (!webix[fname]){
webix[fname] = new Date();
webix.log("Info","Timing start ["+name+"]");
} else {
var time = new Date();
webix.log("Info","Timing end ["+name+"]:"+(time.valueOf()-webix[fname].valueOf())/1000+"s");
webix[fname] = null;
}
};
webix.debug_code = function(code){
code.call(webix);
};
//event system
webix.EventSystem={
$init:function(){
if (!this._evs_events){
this._evs_events = {}; //hash of event handlers, name => handler
this._evs_handlers = {}; //hash of event handlers, ID => handler
this._evs_map = {};
}
},
//temporary block event triggering
blockEvent : function(){
this._evs_events._block = true;
},
//re-enable event triggering
unblockEvent : function(){
this._evs_events._block = false;
},
mapEvent:function(map){
webix.extend(this._evs_map, map, true);
},
on_setter:function(config){
if(config){
for(var i in config){
var method = webix.toFunctor(config[i], this.$scope);
var sub = i.indexOf("->");
if (sub !== -1){
this[i.substr(0,sub)].attachEvent(i.substr(sub+2), webix.bind(method, this));
} else
this.attachEvent(i, method);
}
}
},
//trigger event
callEvent:function(type,params){
if (this._evs_events._block) return true;
type = type.toLowerCase();
var event_stack =this._evs_events[type.toLowerCase()]; //all events for provided name
var return_value = true;
if (webix.log)
if ((webix.debug || this.debug) && !webix.debug_blacklist[type]) //can slowdown a lot
webix.log("info","["+this.name+"@"+((this._settings||{}).id)+"] event:"+type,params);
if (event_stack)
for(var i=0; i<event_stack.length; i++){
/*
Call events one by one
If any event return false - result of whole event will be false
Handlers which are not returning anything - counted as positive
*/
if (event_stack[i].apply(this,(params||[]))===false) return_value=false;
}
if (this._evs_map[type]){
var target = this._evs_map[type];
target.$eventSource = this;
if (!target.callEvent(type,params))
return_value = false;
target.$eventSource = null;
}
return return_value;
},
//assign handler for some named event
attachEvent:function(type,functor,id){
webix.assert(functor, "Invalid event handler for "+type);
type=type.toLowerCase();
id=id||webix.uid(); //ID can be used for detachEvent
functor = webix.toFunctor(functor, this.$scope); //functor can be a name of method
var event_stack=this._evs_events[type]||webix.toArray();
//save new event handler
if (arguments[3])
event_stack.unshift(functor);
else
event_stack.push(functor);
this._evs_events[type]=event_stack;
this._evs_handlers[id]={ f:functor,t:type };
return id;
},
//remove event handler
detachEvent:function(id){
if(!this._evs_handlers[id]){
return;
}
var type=this._evs_handlers[id].t;
var functor=this._evs_handlers[id].f;
//remove from all collections
var event_stack=this._evs_events[type];
event_stack.remove(functor);
delete this._evs_handlers[id];
},
hasEvent:function(type){
type=type.toLowerCase();
var stack = this._evs_events[type];
return (stack && stack.length) ? true : false;
}
};
webix.extend(webix, webix.EventSystem, true);
//array helper
//can be used by webix.toArray()
webix.PowerArray={
//remove element at specified position
removeAt:function(pos,len){
if (pos>=0) this.splice(pos,(len||1));
},
//find element in collection and remove it
remove:function(value){
this.removeAt(this.find(value));
},
//add element to collection at specific position
insertAt:function(data,pos){
if (!pos && pos!==0) //add to the end by default
this.push(data);
else {
var b = this.splice(pos,(this.length-pos));
this[pos] = data;
this.push.apply(this,b); //reconstruct array without loosing this pointer
}
},
//return index of element, -1 if it doesn't exists
find:function(data){
for (var i=0; i<this.length; i++)
if (data==this[i]) return i;
return -1;
},
//execute some method for each element of array
each:function(functor,master){
for (var i=0; i < this.length; i++)
functor.call((master||this),this[i]);
},
//create new array from source, by using results of functor
map:function(functor,master){
for (var i=0; i < this.length; i++)
this[i]=functor.call((master||this),this[i]);
return this;
},
filter:function(functor, master){
for (var i=0; i < this.length; i++)
if (!functor.call((master||this),this[i])){
this.splice(i,1);
i--;
}
return this;
}
};
webix.env = {};
// webix.env.transform
// webix.env.transition
(function(){
webix.env.strict = !!window.webix_strict;
if (navigator.userAgent.indexOf("Mobile")!=-1 || navigator.userAgent.indexOf("Windows Phone")!=-1)
webix.env.mobile = true;
if (webix.env.mobile || navigator.userAgent.indexOf("iPad")!=-1 || navigator.userAgent.indexOf("Android")!=-1)
webix.env.touch = true;
if (navigator.userAgent.indexOf('Opera')!=-1)
webix.env.isOpera=true;
else{
//very rough detection, but it is enough for current goals
webix.env.isIE=!!document.all || (navigator.userAgent.indexOf("Trident") !== -1);
if (webix.env.isIE){
var version = parseFloat(navigator.appVersion.split("MSIE")[1]);
if (version == 8)
webix.env.isIE8 = true;
}
webix.env.isFF=(navigator.userAgent.indexOf("Firefox")!=-1);
webix.env.isWebKit=(navigator.userAgent.indexOf("KHTML")!=-1);
webix.env.isSafari=webix.env.isWebKit && (navigator.userAgent.indexOf('Mac')!=-1);
}
if(navigator.userAgent.toLowerCase().indexOf("android")!=-1){
webix.env.isAndroid = true;
if(navigator.userAgent.toLowerCase().indexOf("trident")){
webix.env.isAndroid = false;
webix.env.isIEMobile = true;
}
}
webix.env.transform = false;
webix.env.transition = false;
var found_index = -1;
var js_list = ['', 'webkit', 'Moz', 'O', 'ms'];
var css_list = ['', '-webkit-', '-Moz-', '-o-', '-ms-'];
var d = document.createElement("DIV");
for (var j=0; j < js_list.length; j++) {
var name = js_list[j] ? (js_list[j]+"Transform") : "transform";
if(typeof d.style[name] != 'undefined'){
found_index = j;
break;
}
}
if (found_index > -1){
webix.env.cssPrefix = css_list[found_index];
var jp = webix.env.jsPrefix = js_list[found_index];
webix.env.transform = jp ? jp+"Transform" : "transform";
webix.env.transition = jp ? jp+"Transition" : "transition";
webix.env.transitionDuration = jp ? jp+"TransitionDuration" : "transitionDuration";
d.style[webix.env.transform] = "translate3d(0,0,0)";
webix.env.translate = (d.style[webix.env.transform])?"translate3d":"translate";
webix.env.transitionEnd = ((webix.env.cssPrefix == '-Moz-')?"transitionend":(jp ? jp+"TransitionEnd" : "transitionend"));
}
})();
webix.env.svg = (function(){
return document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1");
})();
//html helpers
webix.html={
_native_on_selectstart:0,
denySelect:function(){
if (!webix._native_on_selectstart)
webix._native_on_selectstart = document.onselectstart;
document.onselectstart = webix.html.stopEvent;
},
allowSelect:function(){
if (webix._native_on_selectstart !== 0){
document.onselectstart = webix._native_on_selectstart||null;
}
webix._native_on_selectstart = 0;
},
index:function(node){
var k=0;
//must be =, it is not a comparation!
while ((node = node.previousSibling)) k++;
return k;
},
_style_cache:{},
createCss:function(rule){
var text = "";
for (var key in rule)
text+= key+":"+rule[key]+";";
var name = this._style_cache[text];
if (!name){
name = "s"+webix.uid();
this.addStyle("."+name+"{"+text+"}");
this._style_cache[text] = name;
}
return name;
},
addStyle:function(rule){
var style = this._style_element;
if(!style){
style = this._style_element = document.createElement("style");
style.setAttribute("type", "text/css");
style.setAttribute("media", "screen");
document.getElementsByTagName("head")[0].appendChild(style);
}
/*IE8*/
if (style.styleSheet)
style.styleSheet.cssText += rule;
else
style.appendChild(document.createTextNode(rule));
},
create:function(name,attrs,html){
attrs = attrs || {};
var node = document.createElement(name);
for (var attr_name in attrs)
node.setAttribute(attr_name, attrs[attr_name]);
if (attrs.style)
node.style.cssText = attrs.style;
if (attrs["class"])
node.className = attrs["class"];
if (html)
node.innerHTML=html;
return node;
},
//return node value, different logic for different html elements
getValue:function(node){
node = webix.toNode(node);
if (!node) return "";
return webix.isUndefined(node.value)?node.innerHTML:node.value;
},
//remove html node, can process an array of nodes at once
remove:function(node){
if (node instanceof Array)
for (var i=0; i < node.length; i++)
this.remove(node[i]);
else if (node && node.parentNode)
node.parentNode.removeChild(node);
},
//insert new node before sibling, or at the end if sibling doesn't exist
insertBefore: function(node,before,rescue){
if (!node) return;
if (before && before.parentNode)
before.parentNode.insertBefore(node, before);
else
rescue.appendChild(node);
},
//return custom ID from html element
//will check all parents starting from event's target
locate:function(e,id){
var trg;
if (e.tagName)
trg = e;
else {
e=e||event;
trg=e.target||e.srcElement;
}
while (trg){
if (trg.getAttribute){ //text nodes has not getAttribute
var test = trg.getAttribute(id);
if (test) return test;
}
trg=trg.parentNode;
}
return null;
},
//returns position of html element on the page
offset:function(elem) {
if (elem.getBoundingClientRect) { //HTML5 method
var box = elem.getBoundingClientRect();
var body = document.body;
var docElem = document.documentElement;
var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
var clientTop = docElem.clientTop || body.clientTop || 0;
var clientLeft = docElem.clientLeft || body.clientLeft || 0;
var top = box.top + scrollTop - clientTop;
var left = box.left + scrollLeft - clientLeft;
return { y: Math.round(top), x: Math.round(left), width:elem.offsetWidth, height:elem.offsetHeight };
} else { //fallback to naive approach
var top=0, left=0;
while(elem) {
top = top + parseInt(elem.offsetTop,10);
left = left + parseInt(elem.offsetLeft,10);
elem = elem.offsetParent;
}
return { y: top, x: left, width:elem.offsetHeight, height:elem.offsetWidth };
}
},
//returns relative position of event
posRelative:function(ev){
ev = ev || event;
if (!webix.isUndefined(ev.offsetX))
return { x:ev.offsetX, y:ev.offsetY }; //ie, webkit
else
return { x:ev.layerX, y:ev.layerY }; //firefox
},
//returns position of event
pos:function(ev){
ev = ev || event;
if (ev.touches && ev.touches[0])
ev = ev.touches[0];
if(ev.pageX || ev.pageY) //FF, KHTML
return {x:ev.pageX, y:ev.pageY};
//IE
var d = ((webix.env.isIE)&&(document.compatMode != "BackCompat"))?document.documentElement:document.body;
return {
x:ev.clientX + d.scrollLeft - d.clientLeft,
y:ev.clientY + d.scrollTop - d.clientTop
};
},
//prevent event action
preventEvent:function(e){
if (e && e.preventDefault) e.preventDefault();
if(e) e.returnValue = false;
return webix.html.stopEvent(e);
},
//stop event bubbling
stopEvent:function(e){
(e||event).cancelBubble=true;
return false;
},
//add css class to the node
addCss:function(node,name,check){
if (!check || node.className.indexOf(name) === -1)
node.className+=" "+name;
},
//remove css class from the node
removeCss:function(node,name){
node.className=node.className.replace(RegExp(" "+name,"g"),"");
}
};
webix.ready = function(code){
if (this._ready) code.call();
else this._ready_code.push(code);
};
webix.debug_ready = webix.ready; //same command but will work only in dev. build
webix._ready_code = [];
//autodetect codebase folder
(function(){
var temp = document.getElementsByTagName("SCRIPT"); //current script, most probably
webix.assert(temp.length,"Can't locate codebase");
if (temp.length){
//full path to script
temp = (temp[temp.length-1].getAttribute("src")||"").split("/");
//get folder name
temp.splice(temp.length-1, 1);
webix.codebase = temp.slice(0, temp.length).join("/")+"/";
}
var ready = function(){
if(webix.env.isIE)
document.body.className += " webix_ie";
webix.callEvent("onReady",[]);
};
var doit = function(){
webix._ready = true;
//global plugins
if (window.webix_ready && webix.isArray(webix_ready))
webix._ready_code = webix_ready.concat(webix._ready_code);
for (var i=0; i < webix._ready_code.length; i++)
webix._ready_code[i].call();
webix._ready_code=[];
};
webix.attachEvent("onReady", function(force){
if (force)
doit();
else
webix.delay(doit);
});
if (document.readyState == "complete") ready();
else webix.event(window, "load", ready);
})();
webix.locale=webix.locale||{};
webix.assert_core_ready();
webix.ready(function(){
webix.event(document.body,"click", function(e){
webix.callEvent("onClick",[e||event]);
});
});
webix.editStop = function(){
webix.callEvent("onEditEnd", []);
};
webix.debug_blacklist={
onmousemoving:1
};
//Bazed on Promiz
//A fast Promises/A+ library
//Author: https://github.com/Zolmeister/promiz
//License: MIT
/* jshint ignore:start */
(function (self) {
var now = typeof setImmediate !== 'undefined' ? setImmediate : function(cb) {
setTimeout(cb, 0)
}
/**
* @constructor
*/
function promise(fn, er) {
var self = this
self.promise = self
self.state = 'pending'
self.val = null
self.fn = fn || null
self.er = er || null
self.next = [];
}
promise.prototype.resolve = function (v) {
var self = this
if (self.state === 'pending') {
self.val = v
self.state = 'resolving'
now(function () {
self.fire()
})
}
}
promise.prototype.reject = function (v) {
var self = this
if (self.state === 'pending') {
self.val = v
self.state = 'rejecting'
now(function () {
self.fire()
})
}
}
promise.prototype.then = function (fn, er) {
var self = this
var p = new promise(fn, er)
self.next.push(p)
if (self.state === 'resolved') {
p.resolve(self.val)
}
if (self.state === 'rejected') {
p.reject(self.val)
}
return p
}
promise.prototype.fail = function (er) {
return this.then(null, er)
}
promise.prototype.finish = function (type) {
var self = this
self.state = type
if (self.state === 'resolved') {
for (var i = 0; i < self.next.length; i++)
self.next[i].resolve(self.val);
}
if (self.state === 'rejected') {
for (var i = 0; i < self.next.length; i++)
self.next[i].reject(self.val);
if (webix.assert && !self.next.length)
throw(self.val);
}
}
// ref : reference to 'then' function
// cb, ec, cn : successCallback, failureCallback, notThennableCallback
promise.prototype.thennable = function (ref, cb, ec, cn, val) {
var self = this
val = val || self.val
if (typeof val === 'object' && typeof ref === 'function') {
try {
// cnt protects against abuse calls from spec checker
var cnt = 0
ref.call(val, function(v) {
if (cnt++ !== 0) return
cb(v)
}, function (v) {
if (cnt++ !== 0) return
ec(v)
})
} catch (e) {
ec(e)
}
} else {
cn(val)
}
}
promise.prototype.fire = function () {
var self = this
// check if it's a thenable
var ref;
try {
ref = self.val && self.val.then
} catch (e) {
self.val = e
self.state = 'rejecting'
return self.fire()
}
self.thennable(ref, function (v) {
self.val = v
self.state = 'resolving'
self.fire()
}, function (v) {
self.val = v
self.state = 'rejecting'
self.fire()
}, function (v) {
self.val = v
if (self.state === 'resolving' && typeof self.fn === 'function') {
try {
self.val = self.fn.call(undefined, self.val)
} catch (e) {
self.val = e
return self.finish('rejected')
}
}
if (self.state === 'rejecting' && typeof self.er === 'function') {
try {
self.val = self.er.call(undefined, self.val)
self.state = 'resolving'
} catch (e) {
self.val = e
return self.finish('rejected')
}
}
if (self.val === self) {
self.val = TypeError()
return self.finish('rejected')
}
self.thennable(ref, function (v) {
self.val = v
self.finish('resolved')
}, function (v) {
self.val = v
self.finish('rejected')
}, function (v) {
self.val = v
self.state === 'resolving' ? self.finish('resolved') : self.finish('rejected')
})
})
}
promise.prototype.done = function () {
if (this.state = 'rejected' && !this.next) {
throw this.val
}
return null
}
promise.prototype.nodeify = function (cb) {
if (typeof cb === 'function') return this.then(function (val) {
try {
cb(null, val)
} catch (e) {
setImmediate(function () {
throw e
})
}
return val
}, function (val) {
try {
cb(val)
} catch (e) {
setImmediate(function () {
throw e
})
}
return val
})
return this
}
promise.prototype.spread = function (fn, er) {
return this.all().then(function (list) {
return typeof fn === 'function' && fn.apply(null, list)
}, er)
}
promise.prototype.all = function() {
var self = this
return this.then(function(list){
var p = new promise()
if(!(list instanceof Array)) {
p.reject(TypeError)
return p
}
var cnt = 0
var target = list.length
function done() {
if (++cnt === target) p.resolve(list)
}
for(var i=0, l=list.length; i<l; i++) {
var value = list[i]
var ref;
try {
ref = value && value.then
} catch (e) {
p.reject(e)
break
}
(function(i){
self.thennable(ref, function(val){
list[i] = val
done()
}, function(val){
list[i] = val
done()
}, function(){
done()
}, value)
})(i)
}
return p
})
}
// self object gets globalalized/exported
var promiz = {
all:function(list){
var p = new promise(null, null);
p.resolve(list);
return p.all();
},
// promise factory
defer: function () {
return new promise(null, null)
},
// calls a function and resolved as a promise
fcall: function() {
var def = new promise()
var args = Array.apply([], arguments)
var fn = args.shift()
try {
var val = fn.apply(null, args)
def.resolve(val)
} catch(e) {
def.reject(e)
}
return def
},
// calls a node-style function (eg. expects callback as function(err, callback))
nfcall: function() {
var def = new promise()
var args = Array.apply([], arguments)
var fn = args.shift()
try {
// Add our custom promise callback to the end of the arguments
args.push(function(err, val){
if(err) {
return def.reject(err)
}
return def.resolve(val)
})
fn.apply(null, args)
} catch (e) {
def.reject(e)
}
return def
}
}
self.promise = promiz
})(webix);
/* jshint ignore:end */
(function(){
var token = "";
var config = {
timeout:30,
parseDates:true,
multicall:true
};
var queue = [];
var nexttimer;
function call_remote(url, name, args){
var pack = { name: name, data:args, key:token };
var defer = webix.promise.defer();
queue.push([url, pack, defer]);
if (!nexttimer)
nexttimer = setTimeout(next_timer_call,1);
defer.sync = function(){
pack.sync = true;
return call_remote_sync(url, pack);
};
return defer;
}
function next_timer_call(){
var megapack = [];
var megaqueue = [];
var megaurl = "";
for (var i=0; i<queue.length; i++){
var pack = queue[i];
if (!pack[1].sync){
if (config.multicall){
megaurl = pack[0];
megapack.push(pack[1]);
megaqueue.push(pack);
} else
call_remote_async.apply(this, pack);
}
}
queue = [];
nexttimer = false;
if (config.multicall && megapack.length)
call_remote_async(megaurl,
{ data:megapack, key:token, multicall:true },
megaqueue
);
}
function resolve(defer, data){
if (config.multicall)
for (var i = 0; i < defer.length; i++)
defer[i][2].resolve(data[i]);
else
defer.resolve(data);
}
function reject(defer, data){
if (config.multicall)
for (var i = 0; i < defer.length; i++)
defer[i][2].reject(data);
else
defer.reject(data);
}
function call_remote_async(url, pack, defer){
var ajax = webix.ajax();
pack.data = ajax.stringify(pack.data);
ajax.post(url, pack).then(function(text){
var data = parse_responce(text.text());
if (!data)
reject(defer, text.text());
else
resolve(defer, data.data);
}, function(x){
reject(defer, x);
});
webix.callEvent("onRemoteCall", [defer, pack]);
}
function call_remote_sync(url, pack, args){
var ajax = webix.ajax();
webix.callEvent("onRemoteCall", [null, pack]);
pack.data = ajax.stringify(pack.data);
return parse_responce( ajax.sync().post(url, pack).responseText ).data;
}
function parse_responce(text){
return webix.DataDriver.json.toObject.call(config, text);
}
var t = webix.remote = function(api, url, obj, prefix){
if (!url){
var scripts = document.getElementsByTagName("script");
url = scripts[scripts.length - 1].src;
}
obj = obj || t;
prefix = prefix || "";
for (var key in api){
if (key == "$key")
token = api.$key;
else if (key.indexOf("$") === 0)
t[key] = api[key];
else if (typeof api[key] == "object"){
var sub = obj[key] = {};
t(api[key], url, sub, key+".");
} else
obj[key] = api_helper(url, prefix+key);
}
};
var api_helper = function(url, key){
return function(){
return call_remote(url, key, [].splice.call(arguments,0));
};
};
t.config = config;
t.flush = next_timer_call;
})();
/*
UI:DataView
*/
webix.skin={};
webix.skin.air = {
topLayout:"wide",
//bar in accordion
barHeight:34, //!!!Set the same in skin.less!!!
tabbarHeight: 36,
rowHeight:34,
toolbarHeight:22,
listItemHeight:28, //list, grouplist, dataview, etc.
inputHeight:34,
inputPadding: 2,
menuHeight: 34,
menuMargin:0,
labelTopHeight: 16,
//margin - distance between cells
layoutMargin:{ space:10, wide:4, clean:0, head:4, line:-1, toolbar:4, form:8 },
//padding - distance insede cell between cell border and cell content
layoutPadding:{ space:10, wide:0, clean:0, head:0, line:0, toolbar:4, form:8 },
//space between tabs in tabbar
tabMargin:0,
calendarHeight: 70,
padding:0,
optionHeight: 27
};
webix.skin["aircompact"] = {
topLayout:"wide",
//bar in accordion
barHeight:24, //!!!Set the same in skin.less!!!
tabbarHeight: 26,
rowHeight:26,
toolbarHeight:22,
listItemHeight:28, //list, grouplist, dataview, etc.
inputHeight:29,
inputPadding: 2,
menuHeight: 25,
menuMargin:0,
labelTopHeight: 16,
//margin - distance between cells
layoutMargin:{ space:10, wide:4, clean:0, head:4, line:-1, toolbar:4, form:8 },
//padding - distance insede cell between cell border and cell content
layoutPadding:{ space:10, wide:0, clean:0, head:0, line:0, toolbar:4, form:8 },
//space between tabs in tabbar
tabMargin:0,
calendarHeight: 70,
padding:0,
optionHeight: 23
};
webix.skin.web = {
name:"web",
topLayout:"space",
//bar in accordion
barHeight:28, //!!!Set the same in skin.less!!!
tabbarHeight: 30,
rowHeight:30,
toolbarHeight:22,
listItemHeight:28, //list, grouplist, dataview, etc.
inputHeight:28,
inputPadding: 2,
menuMargin: 0,
menuHeight: 27,
labelTopHeight: 16,
//accordionMargin: 9,
//margin - distance between cells
layoutMargin:{ space:10, wide:4, clean:0, head:4, line:-1, toolbar:4, form:8, accordion: 9 },
//padding - distance insede cell between cell border and cell content
layoutPadding:{ space:10, wide:0, clean:0, head:0, line:0, toolbar:4, form:8, accordion:0 },
//space between tabs in tabbar
tabMargin:3,
tabTopOffset:3,
calendarHeight: 70,
padding:0,
optionHeight: 22
};
webix.skin.clouds = {
topLayout:"wide",
//bar in accordion
barHeight:36, //!!!Set the same in skin.less!!!
tabbarHeight: 46,
rowHeight:34,
toolbarHeight:22,
listItemHeight:32, //list, grouplist, dataview, etc.
inputHeight:30,
inputPadding: 2,
menuHeight: 34,
labelTopHeight: 16,
//margin - distance between cells
layoutMargin:{ space:10, wide:4, clean:0, head:4, line:-1, toolbar:4, form:8 },
//padding - distance insede cell between cell border and cell content
layoutPadding:{ space:10, wide:0, clean:0, head:0, line:0, toolbar:4, form:8 },
//space between tabs in tabbar
tabMargin:2,
tabOffset:0,
tabBottomOffset: 10,
calendarHeight: 70,
padding:0
};
webix.skin.terrace = {
topLayout:"space",
//bar in accordion
barHeight:37, //!!!Set the same in skin.less!!!
tabbarHeight: 39,
rowHeight:38,
toolbarHeight:22,
listItemHeight:28, //list, grouplist, dataview, etc.
inputHeight:30,
inputPadding: 2,
menuMargin: 0,
menuHeight: 32,
labelTopHeight: 16,
//margin - distance between cells
layoutMargin:{ space:20, wide:20, clean:0, head:4, line:-1, toolbar:4, form:8},
//padding - distance insede cell between cell border and cell content
layoutPadding:{ space:20, wide:0, clean:0, head:0, line:0, toolbar:4, form:8 },
tabMargin:2,
tabOffset:0,
calendarHeight: 70,
//space between tabs in tabbar
padding:17,
optionHeight: 24
};
webix.skin.metro = {
topLayout:"space",
//bar in accordion
barHeight:36, //!!!Set the same in skin.less!!!
tabbarHeight: 46,
rowHeight:34,
toolbarHeight:36,
listItemHeight:32, //list, grouplist, dataview, etc.
inputHeight:30,
buttonHeight: 45,
inputPadding: 2,
menuHeight: 36,
labelTopHeight: 16,
//margin - distance between cells
layoutMargin:{ space:10, wide:4, clean:0, head:4, line:-1, toolbar:4, form:8, accordion: 9 },
//padding - distance insede cell between cell border and cell content
layoutPadding:{ space:10, wide:0, clean:0, head:0, line:0, toolbar:0, form:8, accordion: 0 },
//space between tabs in tabbar
tabMargin:2,
tabOffset:0,
tabBottomOffset: 10,
calendarHeight: 70,
padding:0,
optionHeight: 23
};
webix.skin.light = {
topLayout:"space",
//bar in accordion
barHeight:36, //!!!Set the same in skin.less!!!
tabbarHeight: 46,
rowHeight:32,
toolbarHeight:36,
listItemHeight:32, //list, grouplist, dataview, etc.
inputHeight:34,
buttonHeight: 45,
inputPadding: 3,
menuHeight: 36,
labelTopHeight: 16,
//margin - distance between cells
layoutMargin:{ space:15, wide:15, clean:0, head:4, line:-1, toolbar:4, form:8, accordion: 10 },
//padding - distance insede cell between cell border and cell content
layoutPadding:{ space:15, wide:0, clean:0, head:0, line:0, toolbar:0, form:8, accordion: 0 },
//space between tabs in tabbar
tabMargin:2,
tabOffset:0,
tabBottomOffset: 10,
calendarHeight: 70,
padding:0,
optionHeight: 27
};
webix.skin.glamour = {
topLayout:"space",
//bar in accordion
barHeight:39, //!!!Set the same in skin.less!!!
tabbarHeight: 39,
rowHeight:32,
toolbarHeight:39,
listItemHeight:32, //list, grouplist, dataview, etc.
inputHeight:34,
buttonHeight: 34,
inputPadding: 3,
menuHeight: 36,
labelTopHeight: 16,
//margin - distance between cells
layoutMargin:{ space:15, wide:15, clean:0, head:4, line:-1, toolbar:4, form:8, accordion: 10 },
//padding - distance insede cell between cell border and cell content
layoutPadding:{ space:15, wide:0, clean:0, head:0, line:0, toolbar:3, form:8, accordion: 0 },
//space between tabs in tabbar
tabMargin:1,
tabOffset:0,
tabBottomOffset: 1,
calendarHeight: 70,
padding:0,
optionHeight: 27
};
webix.skin.touch = {
topLayout:"space",
//bar in accordion
barHeight:42, //!!!Set the same in skin.less!!!
tabbarHeight: 50,
rowHeight:42,
toolbarHeight: 42,
listItemHeight:42, //list, grouplist, dataview, etc.
inputHeight:42,
inputPadding: 4,
menuHeight: 42,
labelTopHeight: 24,
unitHeaderHeight: 34,
//margin - distance between cells
layoutMargin:{ space:10, wide:4, clean:0, head:4, line:-1, toolbar:0, form:0, accordion: 9 },
//padding - distance insede cell between cell border and cell content
layoutPadding:{ space:10, wide:0, clean:0, head:0, line:0, toolbar:4, form:8, accordion: 0 },
//space between tabs in tabbar
tabMargin:2,
tabOffset:0,
tabBottomOffset: 10,
calendar:{headerHeight: 70, timepickerHeight:35, height: 310, width: 300},
padding:0,
customCheckbox: true,
customRadio: true,
optionHeight: 32
};
webix.skin.flat = {
topLayout:"space",
//bar in accordion
barHeight:45, //!!!Set the same in skin.less!!!
tabbarHeight: 45,
rowHeight:34,
toolbarHeight:45,
listItemHeight:34, //list, grouplist, dataview, etc.
inputHeight: 38,
buttonHeight: 38,
inputPadding: 3,
menuHeight: 34,
labelTopHeight: 22,
propertyItemHeight: 28,
//margin - distance between cells
layoutMargin:{ space:10, wide:10, clean:0, head:4, line:-1, toolbar:4, form:8, accordion: 10 },
//padding - distance insede cell between cell border and cell content
layoutPadding:{ space:10, wide:0, clean:0, head:0, line:0, toolbar:5, form:17, accordion: 0 },
//space between tabs in tabbar
tabMargin:4,
tabOffset: 0,
tabBottomOffset: 6,
tabTopOffset:1,
customCheckbox: true,
customRadio: true,
calendarHeight: 70,
padding:0,
accordionType: "accordion",
optionHeight: 29
};
webix.skin.compact = {
topLayout:"space",
//bar in accordion
barHeight:34, //!!!Set the same in skin.less!!!
tabbarHeight: 34,
rowHeight:24,
toolbarHeight:34,
listItemHeight:28, //list, grouplist, dataview, etc.
inputHeight: 30,
buttonHeight: 30,
inputPadding: 3,
menuHeight: 28,
labelTopHeight: 16,
//margin - distance between cells
layoutMargin:{ space:5, wide:5, clean:0, head:4, line:-1, toolbar:4, form:4, accordion: 5 },
//padding - distance insede cell between cell border and cell content
layoutPadding:{ space:5, wide:0, clean:0, head:0, line:0, toolbar:3, form:12, accordion: 0 },
//space between tabs in tabbar
tabMargin:3,
tabOffset: 0,
tabBottomOffset: 3,
tabTopOffset:1,
customCheckbox: true,
customRadio: true,
calendarHeight: 70,
padding:0,
accordionType: "accordion",
optionHeight: 23
};
webix.skin.material = {
topLayout:"space",
//bar in accordion
barHeight:45, //!!!Set the same in skin.less!!!
tabbarHeight:47,
rowHeight:38,
toolbarHeight:22,
listItemHeight:34, //list, grouplist, dataview, etc.
inputHeight:38,
buttonHeight:38,
inputPadding: 2,
menuMargin: 0,
menuHeight: 34,
labelTopHeight: 16,
propertyItemHeight: 34,
//margin - distance between cells
layoutMargin:{ material:10, space:10, wide:10, clean:0, head:4, line:-1, toolbar:4, form:16, accordion: 0 },
//padding - distance insede cell between cell border and cell content
layoutPadding:{ material:10, space:10, wide:0, clean:0, head:0, line:0, toolbar:4, form:16, accordion: 0 },
//space between tabs in tabbar
tabMargin:0,
tabOffset: 0,
tabBottomOffset: 0,
tabTopOffset:0,
customCheckbox: true,
customRadio: true,
calendarHeight: 70,
padding:0,
accordionType: "accordion"
};
webix.skin.set = function(name){
webix.assert(webix.skin[name], "Incorrect skin name: "+name);
webix.skin.$active = webix.skin[name];
webix.skin.$name = name;
if (webix.ui){
for (var key in webix.ui){
var view = webix.ui[key];
if (view && view.prototype && view.prototype.$skin)
view.prototype.$skin(view.prototype);
}
}
};
webix.skin.set(window.webix_skin || "flat");
/*
Behavior:Destruction
@export
destructor
*/
webix.Destruction = {
$init:function(){
//register self in global list of destructors
webix.destructors.push(this);
},
//will be called automatically on unload, can be called manually
//simplifies job of GC
destructor:function(){
var config = this._settings;
if (this._last_editor)
this.editCancel();
if(this.callEvent)
this.callEvent("onDestruct",[]);
this.destructor=function(){}; //destructor can be called only once
//destroy child and related cells
if (this.getChildViews){
var cells = this.getChildViews();
if (cells)
for (var i=0; i < cells.length; i++)
cells[i].destructor();
if (this._destroy_with_me)
for (var i=0; i < this._destroy_with_me.length; i++)
this._destroy_with_me[i].destructor();
}
delete webix.ui.views[config.id];
//html collection
this._htmlmap = null;
this._htmlrows = null;
this._html = null;
if (this._contentobj) {
this._contentobj.innerHTML="";
this._contentobj._htmlmap = null;
}
//removes view container
if (this._viewobj&&this._viewobj.parentNode){
this._viewobj.parentNode.removeChild(this._viewobj);
}
if (this.data && this.data.destructor)
this.data.destructor();
if (this.unbind)
this.unbind();
this.data = null;
this._viewobj = this.$view = this._contentobj = this._dataobj = null;
this._evs_events = this._evs_handlers = {};
//remove focus from destructed view
if (webix.UIManager._view == this)
webix.UIManager._view = null;
var url = config.url;
if (url && url.$proxy && url.release)
url.release();
this.$scope = null;
// this flag is checked in delay method
this.$destructed = true;
}
};
//global list of destructors
webix.destructors = [];
webix.event(window,"unload",function(){
webix.callEvent("unload", []);
webix._final_destruction = true;
//call all registered destructors
for (var i=0; i<webix.destructors.length; i++)
webix.destructors[i].destructor();
webix.destructors = [];
webix.ui._popups = webix.toArray();
//detach all known DOM events
for (var a in webix._events){
var ev = webix._events[a];
if (ev[0].removeEventListener)
ev[0].removeEventListener(ev[1],ev[2],false);
else if (ev[0].detachEvent)
ev[0].detachEvent("on"+ev[1],ev[2]);
delete webix._events[a];
}
});
/*
Behavior:Settings
@export
customize
config
*/
/*
Template - handles html templates
*/
(function(){
var _cache = {};
var _csp_cache = {};
var newlines = new RegExp("(\\r\\n|\\n)","g");
var quotes = new RegExp("(\\\")","g");
var slashes = new RegExp("(\\\\)","g");
var escape = {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'",
"`": "`"
};
var badChars = /[&<>"'`]/g;
var escapeChar = function(chr) {
return escape[chr] || "&";
};
webix.template = function(str){
if (typeof str == "function") return str;
if (_cache[str])
return _cache[str];
str=(str||"").toString();
if (str.indexOf("->")!=-1){
var teststr = str.split("->");
switch(teststr[0]){
case "html": //load from some container on the page
str = webix.html.getValue(teststr[1]);
break;
case "http": //load from external file
str = new webix.ajax().sync().get(teststr[1],{uid:webix.uid()}).responseText;
break;
default:
//do nothing, will use template as is
break;
}
}
//supported idioms
// {obj.attr} => named attribute or value of sub-tag in case of xml
str=(str||"").toString();
// Content Security Policy enabled
if(webix.env.str