UNPKG

webix

Version:

Webix UI

1,821 lines (1,569 loc) 1.52 MB
/** * @license * webix UI v.11.0.0 * 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 */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.webix = {}))); }(this, (function (exports) { 'use strict'; function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var global = window; var queueId = 1; var queue = {}; var isRunningTask = false; if (!global.setImmediate && global.addEventListener) global.addEventListener("message", function (e) { if (e.source == global) { if (isRunningTask) nextTick(queue[e.data]);else { isRunningTask = true; try { if (typeof queue[e.data] === "function") queue[e.data](); } catch (e) {// eslint-disable-line } delete queue[e.data]; isRunningTask = false; } } }); function nextTick(fn) { if (global.setImmediate) global.setImmediate(fn); // if inside of web worker else if (global.importScripts || !global.addEventListener) setTimeout(fn);else { queueId++; queue[queueId] = fn; global.postMessage(queueId, "*"); } } Deferred.resolve = function (value) { if (!(this._d == 1)) throw TypeError(); if (value instanceof Deferred) return value; return new Deferred(function (resolve) { resolve(value); }); }; Deferred.reject = function (value) { if (!(this._d == 1)) throw TypeError(); return new Deferred(function (resolve, reject) { reject(value); }); }; Deferred.all = function (arr) { if (!(this._d == 1)) throw TypeError(); if (!(arr instanceof Array)) return Deferred.reject(TypeError()); var d = new Deferred(); function done(e, v) { if (v) return d.resolve(v); if (e) return d.reject(e); var unresolved = arr.reduce(function (cnt, v) { if (v && v.then) return cnt + 1; return cnt; }, 0); if (unresolved == 0) d.resolve(arr); arr.map(function (v, i) { if (v && v.then) v.then(function (r) { arr[i] = r; done(); return r; }, done); }); } done(); return d; }; Deferred.race = function (arr) { if (!(this._d == 1)) throw TypeError(); if (!(arr instanceof Array)) return Deferred.reject(TypeError()); if (arr.length == 0) return new Deferred(); var d = new Deferred(); function done(e, v) { if (v) return d.resolve(v); if (e) return d.reject(e); var unresolved = arr.reduce(function (cnt, v) { if (v && v.then) return cnt + 1; return cnt; }, 0); if (unresolved == 0) d.resolve(arr); arr.map(function (v) { if (v && v.then) v.then(function (r) { done(null, r); }, done); }); } done(); return d; }; Deferred._d = 1; /** * @constructor */ function Deferred(resolver) { if (typeof resolver != "function" && resolver != undefined) throw TypeError(); if (_typeof(this) != "object" || this && this.then) throw TypeError(); // states // 0: pending // 1: resolving // 2: rejecting // 3: resolved // 4: rejected var self = this, state = 0, val = 0, next = [], fn, er; self["promise"] = self; self["resolve"] = function (v) { fn = self.fn; er = self.er; if (!state) { val = v; state = 1; nextTick(fire); } return self; }; self["reject"] = function (v) { fn = self.fn; er = self.er; if (!state) { val = v; state = 2; nextTick(fire); } return self; }; self["_d"] = 1; self["then"] = function (_fn, _er) { if (!(this._d == 1)) throw TypeError(); var d = new Deferred(); d.fn = _fn; d.er = _er; if (state == 3) { d.resolve(val); } else if (state == 4) { d.reject(val); } else { next.push(d); } return d; }; self["finally"] = function (_handler) { var _value; var handler = function (value) { _value = value; return _handler(); }; var value = function () { var d = new Deferred(); if (state == 4) return d.reject(_value);else return d.resolve(_value); }; return self.then(handler, handler).then(value, value); }; self["catch"] = function (_er) { return self["then"](null, _er); }; //compatibility with old version of promiz lib self["fail"] = function (_er) { return self["then"](null, _er); }; var finish = function (type) { state = type || 4; for (var i = 0; i < next.length; i++) { var p = next[i]; state == 3 && p.resolve(val) || p.reject(val); } }; try { if (typeof resolver == "function") resolver(self["resolve"], self["reject"]); } catch (e) { self["reject"](e); } return self; // ref : reference to 'then' function // cb, ec, cn : successCallback, failureCallback, notThennableCallback function thennable(ref, cb, ec, cn) { // Promises can be rejected with other promises, which should pass through if (state == 2) { return cn(); } if ((_typeof(val) == "object" || typeof val == "function") && typeof ref == "function") { try { // cnt protects against abuse calls from spec checker var cnt = 0; ref.call(val, function (v) { if (cnt++) return; val = v; cb(); }, function (v) { if (cnt++) return; val = v; ec(); }); } catch (e) { val = e; ec(); } } else { cn(); } } function fire() { // check if it's a thenable var ref; try { ref = val && val.then; } catch (e) { val = e; state = 2; return fire(); } thennable(ref, function () { state = 1; fire(); }, function () { state = 2; fire(); }, function () { try { if (state == 1 && typeof fn == "function") { val = fn(val); } else if (state == 2 && typeof er == "function") { val = er(val); state = 1; } } catch (e) { val = e; return finish(); } if (val == self) { val = TypeError(); finish(); } else thennable(ref, function () { finish(3); }, finish, function () { finish(state == 1 && 3); }); }); } } // promise factory Deferred.defer = function () { return new Deferred(null); }; // resolves circular dependencies // quick solution, must be removed in the next versions var services = {}; function define(name, value) { services[name] = value; } function use(name) { return services[name]; } function assert(test, msg) { if (!test) { log("error", msg); var message = use("message"); if (message && typeof msg == "string") message({ type: "debug", text: msg, expire: -1 }); debugger; // eslint-disable-line } } //show log message function log(type, message, details) { if (arguments.length == 1) { message = type; type = "log"; } 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); } } var debug_mode = {}; function debug(mode) { if (!mode) debug_mode = {};else if (_typeof(mode) !== "object") debug_mode = { events: true };else for (var key in mode) { debug_mode[key] = mode[key]; } } var debug_size_indent = 0; function debug_size_step() { var str = ""; for (var i = 0; i < debug_size_indent; i++) { str += "| "; } return str; } function debug_size_box_start(comp, get) { if (!debug_mode.size) return; if (!debug_size_indent) log(get ? "--- get sizes ---" : "--- set sizes ---"); log(debug_size_step() + comp.name + "@" + comp.config.id); debug_size_indent++; } function debug_size_box_end(comp, sizes) { if (!debug_mode.size) return; debug_size_indent--; log(debug_size_step() + sizes.join(",")); } function debug_size_box(comp, sizes, get) { if (!debug_mode.size) return; if (!debug_size_indent) log(get ? "--- get sizes ---" : "--- set sizes ---"); log(debug_size_step() + comp.name + "@" + comp.config.id + " " + sizes.join(",")); } var level = 0; function level_in() { level++; assert(level !== 100, "Attempt to copy object with self reference"); } function level_out() { level--; } //coding helpers function clone(source) { var f = clone._function; f.prototype = source; return new f(); } clone._function = function () {}; //copies methods and properties from source to the target exports.extend = function (base, source, force) { assert(base, "Invalid mixing target"); assert(source, "Invalid mixing source"); if (base.$protoWait) { _power_array.insertAt.call(base.$protoWait, source, 1); return base; } //copy methods, overwrite existing ones in case of conflict for (var method in source) { if (!(method in base) || force) base[method] = source[method]; } //in case of defaults - preffer top one if (source.defaults) exports.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 function copy(source, origin, allowViewRefs) { assert(source, "Invalid mixing target"); level_in(); var esModern = !!window.Map && !!window.Set && !!window.WeakMap && !!window.WeakSet; var target; if (origin) { target = source; source = origin; } else target = isArray(source) ? [] : {}; for (var method in source) { var from = source[method]; if (from && _typeof(from) == "object" && !(from instanceof RegExp)) { var viewInstance = !!from._settings && !!from.$init && !!from.define; if (isDate(from)) target[method] = new Date(from); /* jshint ignore:start */ else if (esModern && (from instanceof Map || from instanceof Set || from instanceof WeakMap || from instanceof WeakSet) || allowViewRefs && viewInstance) { target[method] = from; } /* jshint ignore:end */ else { target[method] = isArray(from) ? [] : {}; copy(target[method], from, allowViewRefs); } } else { target[method] = from; } } level_out(); return target; } function single(source) { var instance = null; var t = function () { if (!instance) instance = new source({}); if (instance._reinit) instance._reinit.apply(instance, arguments); return instance; }; return t; } //creates function with specified "this" pointer function bind(functor, object) { return function () { return functor.apply(object, arguments); }; } //evaluate javascript code in the global scope function exec(code) { return window.eval(code); } function wrap(code, wrap) { if (!code) return wrap; return function () { var result = code.apply(this, arguments); wrap.apply(this, arguments); return result; }; } //check === undefined function isUndefined(a) { return typeof a == "undefined"; } //delay call to after-render time function delay(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); } function once(method) { var flag = true; return function () { if (flag) { flag = false; method.apply(this, arguments); } }; } //common helpers //generates unique ID (unique per window, nog GUID) var _seed = new Date().valueOf(); function uid() { _seed++; return _seed; } //resolve ID as html object function toNode(node) { if (typeof node == "string") return document.getElementById(node); return node; } //resolve function name function toFunctor(str, scope) { if (typeof str == "string") { var method = str.replace("()", ""); if (scope && scope[method]) return scope[method]; return window[method] || exec(str); } return str; } /*checks where an object is instance of Array*/ function isArray(obj) { return Array.isArray(obj); } function isDate(obj) { return obj instanceof Date; } //adds extra methods for the array function _to_array(array) { return exports.extend(array || [], _power_array, true); } //can be used by _to_array() var _power_array = { //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 { this.splice(pos, 0, data); } }, //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; } }; //hook for documentation generator { if (window.webix_on_core_ready) { exports.extend = window.webix_on_core_ready({ extend: exports.extend }).extend; } } var i18n = { parseFormat: "%Y-%m-%d %H:%i:%s", parseTimeFormat: "%H:%i:%s" }; function stringify(obj) { var origin = Date.prototype.toJSON; Date.prototype.toJSON = function () { return i18n.parseFormatStr(this); }; var result; if (obj instanceof Date) result = obj.toJSON();else result = JSON.stringify(obj); Date.prototype.toJSON = origin; return result; } var 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) { exports.extend(this._evs_map, map, true); }, on_setter: function (config) { if (config) { for (var i in config) { var method = toFunctor(config[i], this.$scope); var sub = i.indexOf("->"); if (sub !== -1) { this[i.substr(0, sub)].attachEvent(i.substr(sub + 2), bind(method, this)); } else this.attachEvent(i, method); } } }, //trigger event callEvent: function (type, params) { var master = this._event_master || this; 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 ((debug_mode.events || this.debug) && type !== "onmousemoving") //can slowdown a lot 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(master, 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) { assert(functor, "Invalid event handler for " + type); type = type.toLowerCase(); id = id || uid(); //ID can be used for detachEvent functor = toFunctor(functor, this.$scope); //functor can be a name of method var event_stack = this._evs_events[type] || _to_array(); //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]) { var name = (id + "").toLowerCase(); if (this._evs_events[name]) { this._evs_events[name] = _to_array(); } 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]; if (stack && stack.length) return true; var parent = this._evs_map[type]; if (parent) return parent.hasEvent(type); return false; } }; var evs = {}; exports.extend(evs, EventSystem, true); var callEvent = function (a, b) { return evs.callEvent(a, b); }; var attachEvent = function (a, b, c, d) { return evs.attachEvent(a, b, c, d); }; var detachEvent = function (a) { return evs.detachEvent(a); }; var blockEvent = function () { return evs.blockEvent(); }; var unblockEvent = function () { return evs.unblockEvent(); }; var mapEvent = function (map) { return evs.mapEvent(map); }; var hasEvent = function (type) { return evs.hasEvent(type); }; var xml = { _isValidXML: function (data) { if (!data || !data.documentElement) return null; if (data.getElementsByTagName("parsererror").length) return null; return data; }, //convert xml string to xml object if necessary toObject: function (text, response) { var data = response ? response.rawxml ? response.rawxml() : response : null; if (this._isValidXML(data)) return data; if (typeof text == "string") data = this.fromString(text.replace(/^[\s]+/, ""));else data = text; if (this._isValidXML(data)) return data; return null; }, //get array of records getRecords: function (data) { return this.xpath(data, this.records); }, records: "/*/item", child: "item", config: "/*/config", //get hash of properties for single record getDetails: function (data) { return this.tagToObject(data, {}); }, getOptions: function () { return false; }, //get count of data and position at which new data_loading need to be inserted getInfo: function (data) { var config = this.xpath(data, this.config); if (config.length) config = this.assignTypes(this.tagToObject(config[0], {}));else config = null; return { size: data.documentElement.getAttribute("total_count") || 0, from: data.documentElement.getAttribute("pos"), parent: data.documentElement.getAttribute("parent") || 0, config: config }; }, //xpath helper xpath: function (xml, path) { if (window.XPathResult) { //FF, KHTML, Opera var node = xml; if (xml.nodeName.indexOf("document") == -1) xml = xml.ownerDocument; var res = []; var col = xml.evaluate(path, node, null, XPathResult.ANY_TYPE, null); var temp = col.iterateNext(); while (temp) { res.push(temp); temp = col.iterateNext(); } return res; } else { var test = true; try { if (typeof xml.selectNodes == "undefined") test = false; } catch (e) { /*IE7 and below can't operate with xml object*/ } //IE if (test) return xml.selectNodes(path);else { //there is no interface to do XPath //use naive approach var name = path.split("/").pop(); return xml.getElementsByTagName(name); } } }, assignTypes: function (obj) { for (var k in obj) { var test = obj[k]; if (_typeof(test) == "object") this.assignTypes(test);else if (typeof test == "string") { if (test === "") continue; if (test == "true") obj[k] = true;else if (test == "false") obj[k] = false;else if (test == test * 1) obj[k] = obj[k] * 1; } } return obj; }, //convert xml tag to js object, all subtags and attributes are mapped to the properties of result object tagToObject: function (tag, z) { var isArray = tag.nodeType == 1 && tag.getAttribute("stack"); var hasSubTags = 0; if (!isArray) { z = z || {}; //map attributes var a = tag.attributes; if (a && a.length) for (var i = 0; i < a.length; i++) { z[a[i].name] = a[i].value; hasSubTags = 1; } //map subtags var b = tag.childNodes; for (var _i = 0; _i < b.length; _i++) { if (b[_i].nodeType == 1) { var name = b[_i].tagName; if (z[name]) { if (typeof z[name].push != "function") z[name] = [z[name]]; z[name].push(this.tagToObject(b[_i], {})); } else z[name] = this.tagToObject(b[_i], {}); //sub-object for complex subtags hasSubTags = 2; } } if (!hasSubTags) return this.nodeValue(tag); //each object will have its text content as "value" property //only if has not sub tags if (hasSubTags < 2) z.value = z.value || this.nodeValue(tag); } else { z = []; var _b = tag.childNodes; for (var _i2 = 0; _i2 < _b.length; _i2++) { if (_b[_i2].nodeType == 1) z.push(this.tagToObject(_b[_i2], {})); } } return z; }, //get value of xml node nodeValue: function (node) { if (node.firstChild) { return node.firstChild.wholeText || node.firstChild.data; } return ""; }, //convert XML string to XML object fromString: function (xmlString) { try { if (window.DOMParser) // FF, KHTML, Opera return new DOMParser().parseFromString(xmlString, "text/xml"); /* global ActiveXObject */ if (window.ActiveXObject) { // IE, utf-8 only var temp = new ActiveXObject("Microsoft.xmlDOM"); temp.loadXML(xmlString); return temp; } } catch (e) { assert(0, e); return null; } assert(0, "Load from xml string is not supported"); } }; var json = { //convert json string to json object if necessary toObject: function (data) { if (!data) return null; if (typeof data == "string") { try { if (this.parseDates) { var isodate = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(.\d{1-3})?Z/; data = JSON.parse(data, function (key, value) { if (typeof value == "string") { if (isodate.test(value)) return new Date(value); } return value; }); } else { data = JSON.parse(data); } } catch (e) { log(e); log(data); assert(0, "Invalid JSON data for parsing"); return null; } } return data; }, //get array of records getRecords: function (data) { if (data && data.data) data = data.data; if (data && !isArray(data)) return [data]; return data; }, //get hash of properties for single record getDetails: function (data) { if (typeof data == "string") return { id: data || uid(), value: data }; return data; }, getOptions: function (data) { return data.collections; }, //get count of data and position at which new data need to be inserted getInfo: function (data) { return { size: data.total_count || 0, from: data.pos, parent: data.parent || 0, config: data.config }; }, child: "data", parseDates: false }; function ajax(url, params, call) { //if parameters was provided - made fast call if (arguments.length !== 0) { return new ajax().get(url, params, call); } if (!this || !this.getXHR) return new ajax(); //allow to create new instance without direct new declaration return this; } ajax.count = 0; ajax.prototype = { master: null, //creates xmlHTTP object getXHR: function () { return new XMLHttpRequest(); }, stringify: function (obj) { return stringify(obj); }, /* send data to the server params - hash of properties which will be added to the url call - callback, can be an object with success and error functions */ _send: function (url, params, call, mode) { var master; //webix.ajax(url, callback) - can be called only by user if (params && (isArray(params) || typeof (params.success || params.error || params) == "function")) { master = call; call = params; params = null; } var defer = Deferred.defer(); var x = this.getXHR(); var headers = this._header || {}; if (!callEvent("onBeforeAjax", [mode, url, params, x, headers, null, defer])) { return defer.reject(x); } //add content-type to POST|PUT|DELETE var json_mode = false; if (mode !== "GET") { var found = false; for (var key in headers) { if (key.toString().toLowerCase() == "content-type") { found = true; if (headers[key] == "application/json") json_mode = true; } } if (!found && !(window.FormData && params instanceof window.FormData)) headers["Content-Type"] = "application/x-www-form-urlencoded"; } //add extra params to the url if (_typeof(params) == "object" && !(window.FormData && params instanceof window.FormData)) { if (json_mode) params = this.stringify(params);else { var t = []; for (var a in params) { var value = params[a]; if (value === null || value === undefined) value = ""; if (_typeof(value) === "object") value = this.stringify(value); t.push(encodeURIComponent(a) + "=" + encodeURIComponent(value)); // utf-8 escaping } params = t.join("&"); } } if (params && mode === "GET") { url = url + (url.indexOf("?") != -1 ? "&" : "?") + params; params = null; } x.open(mode, url, !this._sync); var type = this._response; if (type) x.responseType = type; //if header was provided - use it for (var _key in headers) { x.setRequestHeader(_key, headers[_key]); } //async mode, define loading callback var self = this; this.master = this.master || master; x.onreadystatechange = function () { if (!x.readyState || x.readyState == 4) { ajax.count++; var is_error = x.status >= 400 || x.status === 0; var text, data; if (x.responseType == "blob" || x.responseType == "arraybuffer") { text = ""; data = x.response; } else { text = x.responseText || ""; data = self._data(x); } if (is_error) { callEvent("onAjaxError", [x]); defer.reject(x); if (call) ajax.$callback(self.master || window, call, text, data, x, is_error); } else { defer.resolve(data); if (call) ajax.$callback(self.master || window, call, text, data, x, is_error); } } }; if (this._timeout) x.timeout = this._timeout; //IE can use sync mode sometimes, fix it if (!this._sync) setTimeout(function () { x.send(params || null); }, 0);else x.send(params || null); if (this.master && !this._sync) { defer.then(function (data) { //anti-leak self.master = null; call = self = master = null; return data; }); } return this._sync ? x : defer; //return XHR, which can be used in case of sync. mode }, _data: function (x) { return { xml: function () { try { return xml.tagToObject(xml.toObject(x.responseText, this)); } catch (e) { log(x.responseText); log(e.toString()); assert(0, "Invalid xml data for parsing"); } }, rawxml: function () { if (!window.XPathResult) return xml.fromString(x.responseText); return x.responseXML; }, text: function () { return x.responseText; }, json: function () { return json.toObject(x.responseText, false); } }; }, //GET request get: function (url, params, call) { return this._send(url, params, call, "GET"); }, //POST request post: function (url, params, call) { return this._send(url, params, call, "POST"); }, //PUT request put: function (url, params, call) { return this._send(url, params, call, "PUT"); }, //DELETE request del: function (url, params, call) { return this._send(url, params, call, "DELETE"); }, //PATCH request patch: function (url, params, call) { return this._send(url, params, call, "PATCH"); }, sync: function () { this._sync = true; return this; }, timeout: function (num) { this._timeout = num; return this; }, response: function (value) { this._response = value; return this; }, headers: function (header) { this._header = exports.extend(this._header || {}, header); return this; }, bind: function (master) { this.master = master; return this; } }; ajax.$callback = function (owner, call, text, data, x, is_error) { if (owner.$destructed) return; if (is_error) callEvent("onAjaxError", [x]); if (call) { var method = call.success || call; if (is_error) method = call.error; if (method && method.call) method.call(owner, text, data, x); } }; var proxy = { $proxy: true, load: function () { var parts = this.source.split("@"); var ext = parts[0].split(".").pop(); return ajax().response("arraybuffer").get(parts[0]).then(function (res) { var options = { ext: ext, dataurl: parts[1] }; return { data: res, options: options }; }); } }; var proxy$1 = { $proxy: true, load: function () {}, save: function (v, u, d) { delay(function () { window.console.log("[DP] " + u.id + " -> " + u.operation, u.data); var data = { id: u.data.id, newid: u.data.id, status: u.data.operation }; d.processResult(data, data); }); } }; var proxy$2 = { $proxy: true, load: function () { return ajax(this.source); }, save: function (view, update) { return proxy$2._save_logic.call(this, update, ajax()); }, _save_logic: function (update, ajax$$1) { var url = this.source; var query = ""; var mark = url.indexOf("?"); if (mark !== -1) { query = url.substr(mark); url = url.substr(0, mark); } url += url.charAt(url.length - 1) == "/" ? "" : "/"; var mode = update.operation; var data = update.data; if (mode == "insert") delete data.id; //call rest URI if (mode == "update") { return ajax$$1.put(url + data.id + query, data); } else if (mode == "delete") { return ajax$$1.del(url + data.id + query, data); } else { return ajax$$1.post(url + query, data); } } }; var proxy$3 = { $proxy: true, load: function () { return ajax(this.source); }, save: function (view, update) { var xhr = ajax().headers({ "Content-Type": "application/json" }); return proxy$2._save_logic.call(this, update, xhr); } }; var proxy$4 = { $proxy: true, load: function (view, params) { params = exports.extend(params || {}, this.params || {}, true); return ajax().post(this.source, params); } }; function unbox(data) { if (!data || !_typeof(data) === "object" || Array.isArray(data)) return data; var lkey = ""; var count = 0; for (var key in data) { count++; if (count == 2) return data; lkey = key; } return data[lkey]; } var GraphQL = { $proxy: true, ignoreErrors: true, save: function (data) { return this.load(data); }, load: function (view) { var params = { query: this.source }; var isView = arguments.length > 1; var xhr; if (!isView) params.variables = view; return ajax().headers({ "Content-type": "application/json" }).post(this.url, params, function () { xhr = arguments.length <= 2 ? undefined : arguments[2]; }).then(function (data) { var res = data.json(); var resData = res.data, errors = res.errors; if (errors && !GraphQL.ignoreErrors) { if (isView) { return Deferred.reject(xhr); } else { // promise rejection for external callers // the error must be handled via fail/catch in such cases return Deferred.reject({ xhr: xhr, errors: errors }); } } return unbox(resData); }); } }; function proxy$5(name, source, extra) { assert(proxy$5[name], "Invalid proxy name: " + name); var copy$$1 = copy(proxy$5[name]); copy$$1.source = source; if (extra) exports.extend(copy$$1, extra, true); if (copy$$1.init) copy$$1.init(); return copy$$1; } proxy$5.$parse = function (value) { if (typeof value == "string" && value.indexOf("->") != -1) { var parts = value.split("->"); return proxy$5(parts[0], parts[1]); } return value; }; proxy$5.binary = proxy; proxy$5.debug = proxy$1; proxy$5.json = proxy$3; proxy$5.post = proxy$4; proxy$5.rest = proxy$2; proxy$5.GraphQL = GraphQL; var jsarray = { //parse jsarray string to jsarray object if necessary toObject: function (data) { if (typeof data == "string") return JSON.parse(data); return data; }, //get array of records getRecords: function (data) { if (data && data.data) data = data.data; return data; }, //get hash of properties for single record, in case of array they will have names as "data{index}" getDetails: function (data) { var result = {}; for (var i = 0; i < data.length; i++) { result["data" + i] = data[i]; } if (this.idColumn !== null) result.id = data[this.idColumn]; return result; }, getOptions: function () { return false; }, //dyn loading is not supported by js-array data source getInfo: function () { return { size: 0 }; }, idColumn: null }; var csv = { //incoming data always a string toObject: function (data) { return data; }, //get array of records getRecords: function (data) { return data.split(this.row); }, //get hash of properties for single record, data named as "data{index}" getDetails: function (data) { data = this.stringToArray(data); var result = {}; for (var i = 0; i < data.length; i++) { result["data" + i] = data[i]; } if (this.idColumn !== null) result.id = data[this.idColumn]; return result; }, getOptions: function () { return false; }, //dyn loading is not supported by csv data source getInfo: function () { return { size: 0 }; }, //split string in array, takes string surrounding quotes in account stringToArray: function (data) { data = data.split(this.cell); for (var i = 0; i < data.length; i++) { data[i] = data[i].replace(/^[ \t\n\r]*("|)/g, "").replace(/("|)[ \t\n\r]*$/g, ""); } return data; }, idColumn: null, row: "\n", //default row separator cell: "," //default cell separator }; var html = { /* incoming data can be - ID of parent container - HTML text */ toObject: function (data) { if (typeof data == "string") { var t = null; if (data.indexOf("<") == -1) //if no tags inside - probably its an ID t = toNode(data); if (!t) { t = document.createElement("DIV"); t.innerHTML = data; } return t.firstChild; } return data; }, //get array of records getRecords: function (node) { return node.getElementsByTagName(this.tag); }, //get hash of properties for single record getDetails: function (data) { return xml.tagToObject(data); }, getOptions: function () { return false; }, //dyn loading is not supported by HTML data source getInfo: function () { return { size: 0 }; }, tag: "LI" }; var _native_on_selectstart = 0; var _style_element = {}; var _style_cache = {}; function denySelect() { if (!_native_on_selectstart) _native_on_selectstart = document.onselectstart; document.onselectstart = stopEvent; } function allowSelect() { if (_native_on_selectstart !== 0) { document.onselectstart = _native_on_selectstart || null; } _native_on_selectstart = 0; } function index(node) { var k = 0; //must be =, it is not a comparation! while (node = node.previousSibling) { k++; } return k; } function createCss(rule, sufix) { var text = ""; sufix = sufix || ""; for (var key in rule) { text += key + ":" + rule[key] + ";"; } var name = _style_cache[text + sufix]; if (!name) { name = "s" + uid(); addStyle("." + name + (sufix || "") + "{" + text + "}"); _style_cache[text + sufix] = name; } return name; } function addStyle(rule, group) { var style = group ? _style_element[group] : _style_element["default"]; if (!style) { style = document.createElement("style"); style.setAttribute("type", "text/css"); style.setAttribute("media", "screen,print"); document.getElementsByTagName("head")[0].appendChild(style); if (group) _style_element[group] = style;else _style_element["default"] = style; } style.appendChild(document.createTextNode(rule)); } function removeStyle(group) { var box = _style_element[group || "default"]; if (box) box.innerHTML = ""; } function create(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 function getValue(node) { node = toNode(node); if (!node) return ""; return isUndefined(node.value) ? node.innerHTML : node.value; } //remove html node, can process an array of nodes at once function remove(node) { if (node instanceof Array) for (var i = 0; i < node.length; i++) { 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 function insertBefore(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 function locate(e, id) { var trg; if (e.tagName) trg = e;else { trg = e.target; } 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 function offset(elem) { 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 }; } //returns relative position of event function posRelative(ev) { return { x: ev.offsetX, y: ev.offsetY }; } //returns position of event function pos(ev) { if (!ev.type) // webix touch event return { x: ev.x, y: ev.y }; if (ev.touches && ev.touches[0]) ev = ev.touches[0]; return { x: ev.pageX, y: ev.pageY }; } //prevent event action function preventEvent(e) { e.preventDefault(); return stopEvent(e); } //stop event bubbling function stopEvent(e) { e.stopPropagation(); return false; } function triggerEvent(node, type, name, details) { var event; if (typeof window[type] === "function") { details = exports.extend(details || {}, { bubbles: true, cancelable: true }); event = new window[type](name, details); } else { //IE 11 support event = document.createEvent(type); event.initEvent(name, true, true); } node.dispatchEvent(event); } //add css class to the node function addCss(node, name, check) { if (!check || node.className.indexOf(name) === -1) node.className += " " + name; } //remove css class from the node function removeCss(node, name) { node.className = node.className.replace(RegExp(" " + name, "g"), ""); } function getTextSize(text, css, basewidth) { var d = create("DIV", { "class": "webix_view webix_measure_size " + (css || "") }, ""); d.style.cssText = "height:auto;visibility:hidden; position:absolute; top:0px; left:0px; overflow:hidden;" + (basewidth ? "width:" + basewidth + "px;" : "width:auto;white-space:nowrap;"); document.body.appendChild(d); var all = _typeof(text) !== "object" ? [text] : text; var width = 0, height = 0; for (var i = 0; i < all.length; i++) { d.innerHTML = all[i]; var rect = d.getBoundingClientRect(); width = Math.max(width, Math.ceil(rect.width)); height = Math.max(height, Math.ceil(rect.height)); } remove(d); return { width: width, height: height }; } function download(data, filename) { var objUrl = false; if (_typeof(data) == "object") { //blob if (window.navigator.msSaveBlob) return window.navigator.msSaveBlob(data, filename);else { data = window.URL.createObjectURL(data); objUrl = true; } } //data url or blob url var link = document.createElement("a"); link.href = data; link.download = filename; document.body.appendChild(link); link.click(); delay(function () { if (objUrl) window.URL.revokeObjectURL(data); document.body.removeChild(link); link.remove(); }); } function _getClassName(node) { if (!node) return ""; var className = node.className || ""; if (className.baseVal) //'className' exist but not a string - IE svg element in DOM className = className.baseVal; if (!className.indexOf) className = ""; return className; } function setSelectionRange(node, start, end) { node.focus(); var types = ["password", "search", "tel", "text", "url"]; if (node.setSelectionRange && types.includes(node.type)) { start = start || 0; end = end || start; node.setSelectionRange(start, end); } } function getSelectionRange(node) { return { start: node.selectionStart || 0, end: node.selectionEnd || 0 }; } function addMeta(name, value) { document.getElementsByTagName("head").item(0).appendChild(create("meta", { name: name, content: value })); } var html$1 = /*#__PURE__*/Object.freeze({ denySelect: denySelect, allowSelect: allowSelect, index: index, createCss: createCss, addStyle: addStyle, removeStyle: removeStyle, create: create, getValue: getValue, remove: remove, insertBefore: insertBefore, locate: locate, offset: offset, posRelative: posRelative, pos: pos, preventEvent: preventEvent, stopEvent: stopEvent, triggerEvent: triggerEvent, addC