// BIM SDK VERSION 3.0.0
/**
* @global
* @name BIMSDK
* @since 23.08.17
* @version 3.0.0
* @author Mauricio <cto@hitbim.com>
* @description
* Add '{@link bim}' to global Window Object
* @copyright
* <summary>
* {@link https://developer.hitbim.com Hitbim} © 2023 All Rights Reserved
*
* <details>
* All files and information contained in this Software are copyright by {@link https://developer.hitbim.com Hitbim},
* and may not be duplicated, copied, modified or adapted, in any way without our written permission.
* <br/>
*
* Our Software, Tools, Website, and Services may contain our service marks or trademarks as well as those of our affiliates
* or other companies, in the form of words, graphics, and logos.
* <br/>
*
* Your use of our Software and Services does not constitute any right or license for you
* to use our Services, Tools, Software, marks or trademarks, without the prior written permission of {@link https://developer.hitbim.com Hitbim}.
* <br/>
*
* Our Content, as found within our Software, Website, Tools and Services, are protected under United States and foreign copyrights.
* The copying, redistribution, use or publication by you of any such Content, is strictly prohibited.
* Your use of our Software, Website, Tools and Services does not grant you any ownership rights to our Content.
* <br/>
*
* Copyright © {@link https://developer.hitbim.com Hitbim} ©. All Rights Reserved.
* </details>
* </summary>
*/
(function (w) {
"use strict";
/**
* @since 23.08.17
* @version 3.0.0
* @author Mauricio <cto@hitbim.com>
* @exports bim
* @namespace bim
*
* @property {Object} app
* Collection which manages the overall functions of the App.
* See {@link bim.app} for more details.
*
* @property {function} event
* Function to add event listener to element on event type given.
* See {@link bim.event} for more details.
*
* @property {function} querySelector
* Function to get Element within the document that matches the specified selector.
* See {@link bim.querySelector} for more details.
*
* @property {Object} plugin
* Collection of functions that manage plugin.
* See {@link bim.plugin} for more details.
*
* @property {Object} config
* Object which has function to read files related to config.
* See {@link bim.config} for more details.
*
* @property {Object} native
* Collection of functions which control the App natively.
* See {@link bim.native} for more details.
*
* @property {Object} component
* Collection of functions that manage components.
* See {@link bim.component} for more details.
*
* @property {function} readFile
* Function to read the given file path and call the callback.
* See {@link bim.readFile} for more details.
*
* @property {Object} crawling
* Collection of Objects to control elements of the document.
* See {@link bim.crawling} for more details.
*
* @property {Object} functions
* Collection of useful general static functions.
* See {@link bim.functions} for more details.
*/
var __lib = (function () {
/**
* @name __pluginId__
* @inner
* @private
* @memberof bim
* @type {string}
* @description
* Variable which stores the plugin ID.
*
* Used in <code>bim.plugin.id</code>.
*/
var __pluginId__ = "";
/**
* @name __token__
* @inner
* @private
* @memberof bim
* @type {string}
* @description
* Variable assigned by reading the token value of the plugin from the "key" file.
*/
var __token__ = "";
/**
* @name __name__
* @inner
* @private
* @memberof bim
* @type {string}
* @description
* Variable which stores the plugin name.
*
* Used in <code>bim.plugin.name</code>.
*/
var __name__ = "";
/**
* @name __PLUGINS_DIR__
* @inner
* @private
* @memberof bim
* @type {string}
* @description
* Variable which stores the directory path where plugins are located.
*/
var __PLUGINS_DIR__ = "./PLUGINS";
/**
* @name pageNavigator
* @inner
* @private
* @memberof bim
* @type {Array}
* @description
* Container for page.
* <code>bim.app.page</code> push
* Object {
* index: {number},
* name: {string},
* OpenCallback: {function},
* CloseCallback: {function}
* }
*
* <code>bim.app.close.page</code> pop
*/
var pageNavigator = [];
/**
* @name disableBackPage
* @inner
* @private
* @memberof bim
* @type {boolean}
* @description
* Checks this private variable when native go back button is pressed.
* If this is true, blocks the callback function.
*/
var disableBackPage = false;
/**
* @constructor
* @name DOM
* @inner
* @private
* @memberof bim
*/
var DOM = function DOM(arr) {
var self = this;
// Create array-like object
for (var i = 0; i < arr.length; i += 1) {
self[i] = arr[i];
}
self.length = arr.length;
// Return collection with methods
return this;
};
/**
* @function tokenizer
* @inner
* @private
* @memberof bim
* @param {DOM | string} selector
* Selector to match the Element.
* Can be DOM, Document, Window Object or
* string.
* @param {*} context Context
* @returns {DOM} DOM object
*/
function tokenizer(selector, context) {
var arr = [];
var i = 0;
if (selector && !context) {
if (selector instanceof DOM) {
return selector;
}
}
if (selector) {
// String
if (typeof selector === "string") {
var els;
var tempParent;
var html = selector.trim();
if (html.indexOf("<") >= 0 && html.indexOf(">") >= 0) {
var toCreate = "div";
if (html.indexOf("<li") === 0) {
toCreate = "ul";
}
if (html.indexOf("<tr") === 0) {
toCreate = "tbody";
}
if (html.indexOf("<td") === 0 || html.indexOf("<th") === 0) {
toCreate = "tr";
}
if (html.indexOf("<tbody") === 0) {
toCreate = "table";
}
if (html.indexOf("<option") === 0) {
toCreate = "select";
}
tempParent = document.createElement(toCreate);
tempParent.innerHTML = html;
for (i = 0; i < tempParent.childNodes.length; i += 1) {
arr.push(tempParent.childNodes[i]);
}
} else {
if (
!context &&
selector[0] === "#" &&
!selector.match(/[ .<>:~]/)
) {
// Pure ID selector
els = [document.getElementById(selector.trim().split("#")[1])];
} else {
// Other selectors
els = (context || document).querySelectorAll(selector.trim());
}
for (i = 0; i < els.length; i += 1) {
if (els[i]) {
arr.push(els[i]);
}
}
}
} else if (
selector.nodeType ||
selector === window ||
selector === document
) {
// Node/element
arr.push(selector);
} else if (selector.length > 0 && selector[0].nodeType) {
// Array of elements or instance of Dom
for (i = 0; i < selector.length; i += 1) {
arr.push(selector[i]);
}
}
}
return new DOM(arr);
}
tokenizer.fn = DOM.prototype;
tokenizer.Class = DOM;
/**
* tokenizer use
*/
tokenizer.use = function use() {
var args = [],
len = arguments.length;
while (len--) args[len] = arguments[len];
args.forEach(function (methods) {
var isUtils = "__utils" in methods;
Object.keys(methods).forEach(function (methodName) {
if (methodName === "__utils") {
return;
}
if (isUtils) {
tokenizer[methodName] = methods[methodName];
} else {
tokenizer.fn[methodName] = methods[methodName];
}
});
});
};
/**
* @description
* By importing {@link BIMSDK}, functions are added to DOM Element.
*
* Use function {@link bim.app.element} to get DOM Element Object.
*
* Below methods can be called with DOM Element.
*
* <br/>
*
* @namespace DOM
* @property {function} is
* Function to check whether the element corresponds to the selector or not.
* See {@link DOM.is} for more details.
*
* @property {function} find
* Function to find Objects from the element with the selector.
* See {@link DOM.find} for more details.
*
* @property {function} filter
* Function to filter the element through a function given as a parameter.
* See {@link DOM.filter} for more details.
*
* @property {function} append
* Function to append array in arguments to the element.
* See {@link DOM.append} for more details.
*
* @property {function} last
* Function that returns the last element of the array.
* See {@link DOM.last} for more details.
*
* @property {function} eq
* Function that returns the element corresponding to the location of the array.
* See {@link DOM.eq} for more details.
*
* @property {function} index
* Function that returns the index number of the element from the array.
* See {@link DOM.index} for more details.
*
* @property {function} forEach
* Function to run the given callback function for each element.
* See {@link DOM.forEach} for more details.
*
* @property {function} parent
* Function to get the ancestor of each element matched to the selector.
* See {@link DOM.parent} for more details.
*
* @property {function} parents
* Function to get all the ancestors of each element matched to the selector.
* See {@link DOM.parents} for more details.
*
* @property {function} closest
* Function to get the closest DOM object from parent node and itself.
* See {@link DOM.closest} for more details.
*
* @property {function} addClass
* Function to add classes to current element.
* See {@link DOM.addClass} for more details.
*
* @property {function} removeClass
* Function to remove classes from current element.
* See {@link DOM.removeClass} for more details.
*
* @property {function} hasClass
* Function to check whether current element has specific class.
* See {@link DOM.hasClass} for more details.
*
* @property {function} attr
* Function to get or set the value of attribute of the element.
* See {@link DOM.attr} for more details.
*
* @property {function} removeAttr
* Function to remove the given attribute from the element.
* See {@link DOM.removeAttr} for more details.
*
* @property {function} prop
* Function to get or set the value of the given property of the element.
* See {@link DOM.prop} for more details.
*
* @property {function} val
* Function to get or set the value of the element.
* See {@link DOM.val} for more details.
*
* @property {function} remove
* Function to remove the current element from parentNode.
* See {@link DOM.remove} for more details.
*
* @property {function} empty
* Function to remove all the childNodes from the current element.
* See {@link DOM.empty} for more details.
*
* @property {function} on
* Function to bind eventListener and handleEvent to the element.
* See {@link DOM.on} for more details.
*
* @property {function} off
* Function to remove binded eventListener from the elemnet.
* See {@link DOM.off} for more details.
*
* @property {function} text
* Function to get or set the text value of the element.
* See {@link DOM.text} for more details.
*/
var Methods = {
/**
* @description
* Function to check whether the element corresponds to the selector or not.
* @method is
* @memberof DOM
* @param {string | DOM} selector
* The selector to compare elements.
* Should be in <code>string</code> or <code>DOM</code> Object types.
* @returns {boolean}
* Whether the element matches the selector.
*
* <code>true</code> | <code>false</code>
* @example
* if (bim.app.element(${1:selector}).is(${2:selector})) {
* // Do something ...
* }
* @example
* if (bim.app.element("#bimId").is(".bimClass")) {
* // Do something ...
* }
*/
is: function is(selector) {
var el = this[0];
var compareWith;
var i;
if (!el || typeof selector === "undefined") {
return false;
}
if (typeof selector === "string") {
if (el.matches) {
return el.matches(selector);
} else if (el.webkitMatchesSelector) {
return el.webkitMatchesSelector(selector);
} else if (el.msMatchesSelector) {
return el.msMatchesSelector(selector);
}
compareWith = __lib.app.element(selector);
for (i = 0; i < compareWith.length; i += 1) {
if (compareWith[i] === el) {
return true;
}
}
return false;
} else if (selector === document) {
return el === document;
} else if (selector === window) {
return el === window;
}
if (selector.nodeType || selector instanceof DOM) {
compareWith = selector.nodeType ? [selector] : selector;
for (i = 0; i < compareWith.length; i += 1) {
if (compareWith[i] === el) {
return true;
}
}
return false;
}
return false;
},
/**
* @description
* Function to find all Objects with the selector from the element
*
* @method find
* @memberof DOM
* @param {string | Object} selector
* The selector which would be used in the query.
* Should be in <code>string</code> or <code>DOM</code> Object types.
* @returns {Array}
* Found Objects in <code>Array</code> type.
* @example
* bim.app.element(${1:selector}).find(${2:selector});
* @example
* let foundElements = bim.app.element("bim").find("div");
*/
find: function find(selector) {
var this$1 = this;
var foundElements = [];
for (var i = 0; i < this.length; i += 1) {
var found = this$1[i].querySelectorAll(selector);
for (var j = 0; j < found.length; j += 1) {
foundElements.push(found[j]);
}
}
return new DOM(foundElements);
},
/**
* @description
* Function to filter the element through the given function which is handed over as a parameter.
* @method filter
* @memberof DOM
* @param {function} callback
* Filter function ({DOM}, {number}, {DOM})
*
* returns {boolean}
* @returns {Array<DOM>}
* Filtered Objects in <code>Array<DOM></code> type.
* @example
* bim.app.element(${1:selector}).filter(${2:function});
* @example
* let filteredElements = bim.app.element(".bimElements").filter(function (obj) {
* // Return {boolean} ..
* return obj.is(".bimClass");
* });
*/
filter: function filter(callback) {
var matchedItems = [];
var dom = this;
for (var i = 0; i < dom.length; i += 1) {
if (callback.call(dom[i], i, dom[i])) {
matchedItems.push(dom[i]);
}
}
return new DOM(matchedItems);
},
/**
* @description
* Function to append array in arguments to the element.
* @method append
* @memberof DOM
* @param {Array} args
* list of objects expected to be appended to the element
* @returns {DOM} self
* @example
* bim.app.element(${1:selector}).append(${2:array});
* @example
* bim.app.element("bim").append("<div>Hello Bim</div>");
* @example
* const p = document.createElement("p");
* bim.app.element("body").append(p);
*/
append: function append() {
let this$1 = this;
let args = [];
let len = arguments.length;
while (len--) args[len] = arguments[len];
for (var k = 0; k < args.length; k += 1) {
let newChild = args[k];
for (var i = 0; i < this.length; i += 1) {
if (typeof newChild === "string") {
var tempDiv = document.createElement("div");
tempDiv.innerHTML = newChild;
while (tempDiv.firstChild) {
this$1[i].appendChild(tempDiv.firstChild);
}
} else if (newChild instanceof DOM) {
for (var j = 0; j < newChild.length; j += 1) {
this$1[i].appendChild(newChild[j]);
}
} else {
this$1[i].appendChild(newChild);
}
}
}
return this;
},
/**
* @description
* Function that returns the last element of the array.
* @method last
* @memberof DOM
* @returns {boolean | DOM}
* <code>false</code> if the element is undefined or its length equals to 0 |
* <code>DOM</code> Object at the last of the given Array.
* @example
* bim.app.element(${1:selector}).last();
* @example
* bim.app.element("div").last();
*/
last: function last() {
if (!this || !this.length) {
return false;
}
return new DOM([this[this.length - 1]]);
},
/**
* @description
* Function that returns the element corresponding to the location of the array.
* @method eq
* @memberof DOM
* @param {number} index
* A number for where Object in Array is located.
* Should be a positive, or negative Integer.
* @returns {DOM}
* <code>DOM</code> Object
* located in the array at the index.
* @example
* bim.app.element(${1:selector}).eq(${2:index});
* @example
* let listItem = bim.app.element("li").eq(3);
*/
eq: function eq(index) {
if (typeof index === "undefined") {
return this;
}
var length = this.length;
var returnIndex;
if (index > length - 1) {
return new DOM([]);
}
if (index < 0) {
returnIndex = length + index;
if (returnIndex < 0) {
return new DOM([]);
}
return new DOM([this[returnIndex]]);
}
return new DOM([this[index]]);
},
/**
* @description
* Function that returns the index number of the element from the array
* @method index
* @memberof DOM
* @returns {number}
* The index of the element from the array.
* @example
* bim.app.element(${1:selector}).index();
* @example
* bim.app.element("li.bimClass").index();
*/
index: function index() {
var child = this[0];
var i;
if (child) {
i = 0;
while ((child = child.previousSibling) !== null) {
if (child.nodeType === 1) {
i += 1;
}
}
return i;
}
},
/**
* @description
* Function to run the given callback function for each element.
* If callback function returns <code>false</code>, terminates the loop early.
* @method forEach
* @memberof DOM
* @param {function} callback currentvalue, currentvalue, index as params
* @returns {DOM} self
* @example
* bim.app.element(${1:selector}).forEach(${2:callback});
* @example
* bim.app.element("li").forEach(function (item, item2, index) {
* // Do Something ...
* console.log("li : ", item);
* });
*/
forEach: function forEach(callback) {
var this$1 = this;
if (!callback) {
return this;
}
for (var i = 0; i < this.length; i += 1) {
if (callback.call(this$1[i], this$1[i], i) === false) {
// End the loop early
return this$1;
}
}
return this;
},
/**
* @description
* Function to get the ancestor of each element
* in the current set of elements matched to the selector.
* @method parent
* @memberof DOM
* @param {string= | DOM=} [selector]
* <b><i>Optional.</i></b>
* A string containing a selector expression to match elements against. |
* <code>DOM</code> Object to compare with.
* @returns {DOM}
* element
* @example
* bim.app.element(${1:selector}).parent();
* @example
* bim.app.element(${1:selector}).parent(${2:selector});
* @example
* let bimElement = bim.app.element("li").parent("ul");
*/
parent: function parent(selector) {
var this$1 = this;
var parents = [];
for (var i = 0; i < this.length; i += 1) {
var parent = this$1[i].parentNode;
if (parent !== null) {
if (selector) {
if (__lib.app.element(parent).is(selector)) {
parents.push(parent);
}
} else {
parents.push(parent);
}
}
}
return __lib.app.element(__lib.functions.unique(parents));
},
/**
* @description
* Function to get all the ancestors of each element
* in the current set of matched elements matched to the selector.
* Similar to <code>{@link DOM.parent}</code>, except this travels
* multiple level up the <code>DOM</code> tree.
* @method parents
* @memberof DOM
* @param {string= | DOM=} [selector]
* <b><i>Optional.</i></b>
* A string containing a selector expression to match elements against. |
* <code>DOM</code> Object to compare with.
* @returns {DOM}
* Matched parent <code>DOM</code> Element.
* @example
* bim.app.element(${1:selector}).parents();
* @example
* bim.app.element(${1:selector}).parents(${2:selector});
* @example
* let bimElements = bim.app.element("li").parents("ul");
*/
parents: function parents(selector) {
var this$1 = this;
var parents = [];
for (var i = 0; i < this.length; i += 1) {
var parent = this$1[i].parentNode;
while (parent) {
if (selector) {
if (__lib.app.element(parent).is(selector)) {
parents.push(parent);
}
} else {
parents.push(parent);
}
parent = parent.parentNode;
}
}
return __lib.app.element(__lib.functions.unique(parents));
},
/**
* @description
* Function to get the closest DOM object from parent node and itself.
* Traverses the element and its parents until it finds a node.
* If the element is undefined, returns new DOM.
* @method closest
* @memberof DOM
* @param {string | DOM} selector
* <b><i>Required.</i></b>
* Valid selector to match the element. |
* <code>DOM</code> Object to compare with.
* @returns {DOM}
* New <code>DOM</code> Object if selector is undefined,
* else closest parent <code>DOM</code> Object.
* @example
* bim.app.element(${1:selector}).closest(${2:selector});
* @example
* let closeElement = bim.app.element("li.bimList").closest("ul");
*/
closest: function closest(selector) {
var closest = this;
if (typeof selector === "undefined") {
return new DOM([]);
}
if (!closest.is(selector)) {
closest = closest.parents(selector).eq(0);
}
return closest;
},
/**
* @description
* Function to add classes to current element.
* Multiple classes can be added at the same time
* seperated by "space".
* @method addClass
* @memberof DOM
* @param {string} className
* Class name
* @returns {DOM} Self
* @example
* bim.app.element(${1:selector}).addClass(${2:className});
* @example
* bim.app.element("div").addClass("className1 className2 className3");
*/
addClass: function addClass(className) {
var this$1 = this;
if (typeof className === "undefined") {
return this;
}
var classes = className.split(" ");
for (var i = 0; i < classes.length; i += 1) {
for (var j = 0; j < this.length; j += 1) {
if (typeof this$1[j].classList !== "undefined") {
this$1[j].classList.add(classes[i]);
}
}
}
return this;
},
/**
* @description
* Function to remove classes from current element.
* Multiple classes can be removed at the same time
* seperated by "space".
* @method removeClass
* @memberof DOM
* @param {string} className
* Class name
* @returns {DOM} Self
* @example
* bim.app.element(${1:selector}).removeClass(${2:className});
* @example
* bim.app.element("div").removeClass("className1 className2 className3");
*/
removeClass: function removeClass(className) {
var this$1 = this;
var classes = className.split(" ");
for (var i = 0; i < classes.length; i += 1) {
for (var j = 0; j < this.length; j += 1) {
if (typeof this$1[j].classList !== "undefined") {
this$1[j].classList.remove(classes[i]);
}
}
}
return this;
},
/**
* @description
* Function to check whether current element has specific class given as parameter.
* @method hasClass
* @memberof DOM
* @param {string} className
* Class name
* @returns {boolean}
* Whether the element has the class or not.
*
* <code>true</code> | <code>false</code>
* @example
* bim.app.element(${1:selector}).hasClass(${2:className});
* @example
* if (bim.app.element("div").hasClass("className1")) {
* // Do something ...
* }
*/
hasClass: function hasClass(className) {
if (!this[0]) {
return false;
}
return this[0].classList.contains(className);
},
/**
* @description
* Function to get or set the value of attribute of the element.
* @method attr
* @memberof DOM
* @param {string} attrs
* @param {string=} value
* @returns {string | DOM}
* Value of attribute when 1 argument, else Self
* @example
* // Gets current element's attr
* bim.app.element(${1:selector}).attr(${2:attrName});
* @example
* // Sets value to current element's attr
* bim.app.element(${1:selector}).attr(${2:attrName}, ${3:value});
* @example
* // Sets values of the given attributes to the element
* bim.app.element(${1:selector}).attr({
* ${2:attrName} : ${3:value},
* ${4:attrName} : ${5:value}
* // ...
* });
* @example
* let inputTitle = bim.app.element("input").attr("title");
*/
attr: function attr(attrs, value) {
var arguments$1 = arguments;
var this$1 = this;
if (arguments.length === 1 && typeof attrs === "string") {
// Get attr
if (this[0]) {
return this[0].getAttribute(attrs);
}
return undefined;
}
// Set attrs
for (var i = 0; i < this.length; i += 1) {
if (arguments$1.length === 2) {
// String
this$1[i].setAttribute(attrs, value);
} else {
// Object
for (var attrName in attrs) {
this$1[i][attrName] = attrs[attrName];
this$1[i].setAttribute(attrName, attrs[attrName]);
}
}
}
return this;
},
/**
* @description
* Function to remove the given attribute from the element.
* @method removeAttr
* @memberof DOM
* @param {string} attr
* Attribute expected to be removed
* @returns {DOM} Self
* @example
* bim.app.element(${1:selector}).removeAttr(${2:attr});
* @example
* bim.app.element("input").removeAttr("title");
*/
removeAttr: function removeAttr(attr) {
var this$1 = this;
for (var i = 0; i < this.length; i += 1) {
this$1[i].removeAttribute(attr);
}
return this;
},
/**
* @description
* Function to get or set the value of the given property of the element.
* @method prop
* @memberof DOM
* @param {string | Object} props
* Property name
* @param {string=} value
* String value for property
* @returns {string | DOM} value of the property of the element | self
* @example
* // Get the value of the given property from the element
* bim.app.element(${1:selector}).prop(${2:propName});
* @example
* // Set the value of the given property to the element
* bim.app.element(${1:selector}).prop(${2:propName}, ${3:value});
* @example
* // Set the values of the given properties to the element
* bim.app.element(${1:selector}).prop({
* ${2:propName} : ${3:value},
* ${4:propName} : ${5:value}
* // ...
* });
* @example
* let checked = bim.app.element(".checkBox").prop("checked");
*/
prop: function prop(props, value) {
var arguments$1 = arguments;
var this$1 = this;
if (arguments.length === 1 && typeof props === "string") {
// Get prop
if (this[0]) {
return this[0][props];
}
} else {
// Set props
for (var i = 0; i < this.length; i += 1) {
if (arguments$1.length === 2) {
// String
this$1[i][props] = value;
} else {
// Object
for (var propName in props) {
this$1[i][propName] = props[propName];
}
}
}
return this;
}
},
/**
* @description
* Function to get or set the value of the element.
* @method val
* @memberof DOM
* @param {string=} value
* Value to assign
* @returns {string | string[] | DOM}
* Value of the element | Self
* @example
* // Get the value of the element
* bim.app.element(${1:selector}).val();
* @example
* // Set the value of the element
* bim.app.element(${1:selector}).val(${2:value});
* @example
* bim.app.element("input").val("Hello Bim~");
*/
val: function val(value) {
var this$1 = this;
if (typeof value === "undefined") {
if (this[0]) {
if (
this[0].multiple &&
this[0].nodeName.toLowerCase() === "select"
) {
var values = [];
for (var i = 0; i < this[0].selectedOptions.length; i += 1) {
values.push(this$1[0].selectedOptions[i].value);
}
return values;
}
return this[0].value;
}
return undefined;
}
for (var i$1 = 0; i$1 < this.length; i$1 += 1) {
this$1[i$1].value = value;
}
return this;
},
/**
* @description
* Function to remove the current element from parentNode.
* @method remove
* @memberof DOM
* @returns {DOM} Self | parentNode
* @example
* bim.app.element(${1:selector}).remove();
* @example
* bim.app.element("li").remove();
*/
remove: function remove() {
var this$1 = this;
for (var i = 0; i < this.length; i += 1) {
if (this$1[i].parentNode) {
this$1[i].parentNode.removeChild(this$1[i]);
}
}
return this;
},
/**
* @description
* Function to remove all the childNodes from the current element.
* @method empty
* @memberof DOM
* @returns {DOM} Self
* @example
* bim.app.element(${1:selector}).empty();
* @example
* bim.app.element("ul").empty();
*/
empty: function empty() {
var this$1 = this;
for (var i = 0; i < this.length; i += 1) {
var el = this$1[i];
if (el.nodeType === 1) {
for (var j = 0; j < el.childNodes.length; j += 1) {
if (el.childNodes[j].parentNode) {
el.childNodes[j].parentNode.removeChild(el.childNodes[j]);
}
}
el.textContent = "";
}
}
return this;
},
/**
* @description
* Function to bind eventListener and handleEvent to the element.
* @method on
* @memberof DOM
* @argument {string} eventType
* @argument {string=} targetSelector
* @argument {function} listener
* @argument {boolean=} [capture=false] true | false
* @returns {DOM} Self
* @example
* // with 2 arguments
* bim.app.element(${1:selector}).on(${2:eventType}, ${3:listener});
* @example
* // with 3 arguments
* bim.app.element(${1:selector}).on(${2:eventType}, ${3:targetSelector}, ${4:listener});
* @example
* // with 4 arguments
* bim.app.element(${1:selector}).on(${2:eventType}, ${3:targetSelector}, ${4:listener}, ${5:capture});
*/
on: function on() {
var this$1 = this;
var args = [],
len = arguments.length;
while (len--) args[len] = arguments[len];
var eventType = args[0];
var targetSelector;
var listener;
var capture = false;
if (typeof args[1] === "function") {
targetSelector = false;
listener = args[1];
capture = args[2];
} else {
targetSelector = args[1];
listener = args[2];
capture = args[3];
}
function handleLiveEvent(e) {
var target = e.target;
if (!target) {
return;
}
var eventData = e.target.domEventData || [];
eventData.unshift(e);
var eTarget = __lib.app.element(target);
if (eTarget.is(targetSelector)) {
listener.apply(target, eventData);
} else {
var parents = eTarget.parents();
for (var k = 0; k < parents.length; k += 1) {
var parentsTarget = __lib.app.element(parents[k]);
if (parentsTarget.is(targetSelector)) {
listener.apply(parents[k], eventData);
}
}
}
}
function handleEvent(e) {
var eventData = e && e.target ? e.target.domEventData || [] : [];
eventData.unshift(e);
listener.apply(this, eventData);
}
var events = eventType.split(" ");
var j;
for (var i = 0; i < this.length; i += 1) {
var el = this$1[i];
if (!targetSelector) {
for (j = 0; j < events.length; j += 1) {
if (!el.domListeners) {
el.domListeners = [];
}
el.domListeners.push({
type: eventType,
listener: listener,
proxyListener: handleEvent,
});
el.addEventListener(events[j], handleEvent, capture);
}
} else {
// Live events
for (j = 0; j < events.length; j += 1) {
if (!el.domLiveListeners) {
el.domLiveListeners = [];
}
el.domLiveListeners.push({
type: eventType,
listener: listener,
proxyListener: handleLiveEvent,
});
el.addEventListener(events[j], handleLiveEvent, capture);
}
}
}
return this;
},
/**
* @description
* Function to remove binded eventListener from the elemnet.
* @method off
* @memberof DOM
* @argument {string} eventType
* @argument {string} targetSelector
* @argument {function} listener
* @argument {boolean=} [capture=false] true | false
* @returns {DOM} self
* @todo Check the stability
* @example
* // with 2 arguments
* bim.app.element(${1:selector}).off(${2:eventType}, ${3:listener});
* @example
* // with 3 arguments
* bim.app.element(${1:selector}).off(${2:eventType}, ${3:targetSelector}, ${4:listener});
* @example
* // with 4 arguments
* bim.app.element(${1:selector}).off(${2:eventType}, ${3:targetSelector}, ${4:listener}, ${5:capture});
*/
off: function off() {
var this$1 = this;
var args = [],
len = arguments.length;
while (len--) args[len] = arguments[len];
var eventType = args[0];
var targetSelector;
var listener;
var capture = false;
if (typeof args[1] === "function") {
targetSelector = false;
listener = args[1];
capture = args[2];
} else {
targetSelector = args[1];
listener = args[2];
capture = args[3];
}
var events = eventType.split(" ");
for (var i = 0; i < events.length; i += 1) {
for (var j = 0; j < this.length; j += 1) {
var el = this$1[j];
if (!targetSelector) {
if (el.domListeners) {
for (var k = 0; k < el.domListeners.length; k += 1) {
if (listener) {
if (el.domListeners[k].listener === listener) {
el.removeEventListener(
events[i],
el.domListeners[k].proxyListener,
capture
);
}
} else if (el.domListeners[k].type === events[i]) {
el.removeEventListener(
events[i],
el.domListeners[k].proxyListener,
capture
);
}
}
}
} else if (el.domLiveListeners) {
for (var k$1 = 0; k$1 < el.domLiveListeners.length; k$1 += 1) {
if (listener) {
if (el.domLiveListeners[k$1].listener === listener) {
el.removeEventListener(
events[i],
el.domLiveListeners[k$1].proxyListener,
capture
);
}
} else if (el.domLiveListeners[k$1].type === events[i]) {
el.removeEventListener(
events[i],
el.domLiveListeners[k$1].proxyListener,
capture
);
}
}
}
}
}
return this;
},
/**
* @description
* Function to get or set the text value of the element.
* @method text
* @memberof DOM
* @param {string=} text$1
* Text value to assign
* @returns {string | DOM} Text value | self
* @example
* // Get text value of the element
* bim.app.element(${1:selector}).text();
* @example
* // Set text value to the element
* bim.app.element(${1:selector}).text(${2:text});
* @example
* bim.app.elemnt("h1").text("Hello Bim~");
*/
text: function text(text$1) {
var this$1 = this;
if (typeof text$1 === "undefined") {
if (this[0]) {
return this[0].textContent.trim();
}
return null;
}
for (var i = 0; i < this.length; i += 1) {
this$1[i].textContent = text$1;
}
return this;
},
};
tokenizer.use(Methods);
return {
/**
* @description
* Collection which manages the overall functions of the App.
* @namespace bim.app
* @type {Object}
* @property {function} formData
* Function to get data from form.
* See {@link bim.app.formData} for more details.
*
* @property {function} checkAppVersion
* Function to check app version natively.
* See {@link bim.app.checkAppVersion} for more details.
*
* @property {function} checkAppVersionCallback
* Callback function called after checking app version natively.
* See {@link bim.app.checkAppVersionCallback} for more details.
*
* @property {function} onGoBack
* Callback function when called on go back.
* See {@link bim.app.onGoBack} for more details.
*
* @property {function} scrollTop
* Function to change scroll position to top.
* See {@link bim.app.scrollTop} for more details.
*
* @property {function} init
* Function to initialize the App by setting up
* the information of current plugin.
* See {@link bim.app.init} for more details.
*
* @property {Object} data
* Core System, Collection of functions for sharing data
* between diffrent plugins.
* See {@link bim.app.data} for more details.
*
* @property {Object} user
* Collection of functions to control data of user of the App.
* See {@link bim.app.user} for more details.
*
* @property {function} session
* Function to get or set user session.
* See {@link bim.app.session} for more details.
*
* @property {function} getAppId
* Function to get the App's ID.
* See {@link bim.app.getAppId} for more details.
*
* @property {function} setAppId
* Function to set App's ID.
* See {@link bim.app.setAppId} for more details.
*
* @property {function} popup
* Function to show popup.
* See {@link bim.app.popup} for more details.
*
* @property {function} page
* Function to create new page in plugin.
* See {@link bim.app.page} for more details.
*
* @property {function} listener
* Function to add Event Listener to document.
* See {@link bim.app.listener} for more details.
*
* @property {Object} listeners
* Object which has a Function to make the last step to firing an event.
* See {@link bim.app.listeners} for more details.
*
* @property {function} navigation
* Function to add Event Listener "navigation" to document.
* See {@link bim.app.navigation} for more details.
*
* @property {Object} close
* Object, which has a Function to close opened page in plugin.
* See {@link bim.app.close} for more details.
*
* @property {function} element
* Function to return {@link DOM} Element.
* See {@link bim.app.element} for more details.
*
* @property {Object} logicless
* See {@link bim.app.logicless} for more details.
*
* @property {function} template
* Function to return templated "bim" element
* See {@link bim.app.template} for more details.
*
* @property {Object} storyboard
* Collection of functions to handle the storyboard of the App.
* See {@link bim.app.storyboard} for more details.
*
* @property {function} appendHTML
* Funciton to append HTML on document.
* See {@link bim.app.appendHTML} for more details.
*
* @property {function} isHTML
* Function to check whether is a HTML tag or not.
* See {@link bim.app.isHTML} for more details.
*
* @property {function} translate
* Function to translate language.
* See {@link bim.app.translate} for more details.
*/
app: {
/**
* @description
* Function to get data from form.
* @since 23.03.07
* @memberof bim.app
* @function formData
* @param {DOM | string} params
* <b><i>Required</i></b>.
* Selector to match the Element of <code>form</code>.
* @returns {boolean | Object}
* Returns <code>false</code>
* if parameter is empty or
* there is not only one inquired <code>form</code>. |
*
* Returns extract data from the inquired
* <code>form</code> in <code>Object</code> format.
*/
formData: function (params) {
if (!params || params == "") return false;
var form = __lib.app.element(params);
if (form.length !== 1) return false;
var formData = {};
var skipTypes = ["submit", "image", "button", "file"];
var skipNames = [];
form.find("input, select, textarea").each(function () {
var input = __lib.app.element(this);
var name = input.attr("name");
var type = input.attr("type");
var tag = this.nodeName.toLowerCase();
if (skipTypes.indexOf(type) >= 0) return;
if (skipNames.indexOf(name) >= 0 || !name) return;
if (tag === "select" && input.prop("multiple")) {
skipNames.push(name);
formData[name] = [];
form.find('select[name="' + name + '"] option').each(function () {
if (this.selected) formData[name].push(this.value);
});
} else {
switch (type) {
case "checkbox":
skipNames.push(name);
formData[name] = [];
form.find('input[name="' + name + '"]').each(function () {
if (this.checked) formData[name].push(this.value);
});
break;
case "radio":
skipNames.push(name);
form.find('input[name="' + name + '"]').each(function () {
if (this.checked) formData[name] = this.value;
});
break;
default:
formData[name] = input.val();
break;
}
}
});
return formData;
},
/**
* @description
* Function to send a request to native to check
* whether there's an update in app store or not.
* @deprecated
* ONLY USED IN SPECIFIC APP NOW.
* APP VERSION CAN BE CHECKED NATIVELY BY ITSELF.
* @since 22.08.17
* @function checkAppVersion
* @memberof bim.app
* @param {Object} params
* <b><i>Required.</i></b>
* @param {string} params.title
* @param {string} params.message
* @returns {}
*/
checkAppVersion: function (params) {
if (!params) {
return;
}
console.log(
"HTB_NATIVE_LOG",
"bim.app.checkAppVersion()",
"App version check called .."
);
},
/**
* @description
* Callback function for app version check.
* Show alert with <code>title</code> and <code>message</code>.
* Redirects to external link natively.
* @deprecated
* ONLY USED IN SPECIFIC APP NOW.
* APP VERSION CAN BE CHECKED NATIVELY BY ITSELF.
* @since 22.08.17
* @function checkAppVersionCallback
* @memberof bim.app
* @param {Object} params
* <b><i>Required.</i></b>
* @param {boolean} params.app_update_check
* <b><i>Required.</i></b>
* @param {string} params.app_name
* <b><i>Required.</i></b>
* Used to show externalLink in Android.
* @param {string} params.trackId
* Used to show externalLink in iOS.
* @param {string} params.title
* @param {string} params.message
* @returns {}
*/
checkAppVersionCallback: function (params) {
if (
!params ||
params == "" ||
!params.app_update_check ||
!params.app_name
) {
return;
}
console.log(
"HTB_NATIVE_LOG",
"bim.app.checkAppVersionCallback()",
"App version callback called .."
);
},
/**
* @description
* Callback function when called on go back.
* @memberof bim.app
* @function onGoBack
*/
onGoBack: function () {},
/**
* @description
* Function to change scroll position of Element to top.
* @since 22.03.17
* @memberof bim.app
* @function scrollTop
* @param {string | DOM} params
* <b><i>Required.</i></b>
* selector
* @returns {}
*/
scrollTop: function (params) {
if (!params || params == "") return;
if (params.trim().charAt(0) === ".") {
bim.app.element(params)[0].scroll(0, 0);
} else if (params.trim().charAt(0) === "#") {
bim.app.element(params).scroll(0, 0);
}
},
/**
* @description
* Function to initialize the App by setting up
* the information of current plugin.
*
* Sets
* <code>id</code>,
* <code>name</code>,
* <code>token</code>
* of the plugin to private variables.
*
* Load external JavaScript if received through parameters
* <code>params.onReady.js</code>.
* @since 22.03.17
* @memberof bim.app
* @async
* @function init
* @param {Object} params
* <b><i>Required.</i></b>
* @param {string} params.pluginId
* <b><i>Required.</i></b>
* Plugin id
* @param {string} params.name
* <b><i>Required.</i></b>
* Plugin name
* @param {Object=} params.onReady
* @param {Array<string>} params.onReady.js
* Should specify the path and filename
* where the script is located.
* @returns {}
*/
init: async function (params) {
if (!params) return console.error("bim.init() need to insert object");
if (!params.pluginId) return console.error("plugin id is necessary");
if (!params.name) return console.error("plugin name is necessary");
// set token
try {
await __lib.plugin.token.set();
} catch (e) {
console.error(e);
}
__lib.plugin.id.set(params.pluginId);
__lib.plugin.name.set(params.name);
__lib.app.data.set(
JSON.stringify({
navigation: {
plugin: params.pluginId,
href: window.location.href,
pathname: window.location.pathname,
protocol: window.location.protocol,
port: window.location.port,
origin: window.location.origin,
hostname: window.location.hostname,
},
})
);
document.onreadystatechange = function () {
if (document.readyState === "complete") {
bim.plugin.onResume();
}
};
__lib.crawling.inject.css.apply(
".bim-singleView{position:absolute;top:0;height:100%;background-color:white;width:100%;z-index:6666;}.bim-singleView-init{left:120%;}.bim-page-from-left{transform:translateX(0.1%);transition:0.3s;left:0%;}.bim-page-hide-from-left{transform:translateX(120%);transition:0.7s;}"
);
if (params.onReady && params.onReady !== "") {
for (var x = 0; x < params.onReady.js.length; x++) {
var response = {};
// load external JS libraries
var script = document.createElement("script");
script.src = params.onReady.js[x] + ".js";
script.async = true;
script.onload = () => {};
script.onerror = ee => {
response.error = true;
response.message = "Err-98enrr: loading library";
console.error(response);
};
//var firstScriptTag = document.getElementsByTagName('script')[0];
//firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
document.body.appendChild(script);
}
}
},
/**
* @description
* Core System.
* Collection of functions to control data
* through internal database for sharing data
* between diffrent plugins as an App.
* @since 22.03.17
* @namespace bim.app.data
* @type {Object}
* @property {function} bundle
* Function to get data from the internal database (indexedDB).
* See {@link bim.app.data.bundle} for more details.
*
* @property {Object} db
* See {@link bim.app.data.db} for more details.
*
* @property {function} set
* See {@link bim.app.data.set} for more details.
*
* @property {function} get
* See {@link bim.app.data.get} for more details.
*
* @property {function} deleteItem
* See {@link bim.app.data.deleteItem} for more details.
*/
data: {
/**
* @memberof bim.app.data
* @callback bundleCallback
* @param {Object} params
* @param {boolean} params.error
* Passes whether failed or not.
* @param {string} params.message
* Passes error message when fails.
* @param {Error} params.description
* Passes <code>Error</code> Object when fails.
* <code>Error</code>객체 자체로 넘겨줌.
* @param {string} params.errno
* Passes error number when fails.
* @param {Object} params.data
* Passes the result data when success.
*/
/**
* @see {@link https://w3c.github.io/IndexedDB/#introduction IndexedDB Description}
* @description
* Function to get item from the internal database.
* Uses <code>indexedDB</code>.
* @memberof bim.app.data
* @function bundle
* @param {Object} params
* <b><i>Required.</i></b>
* @param {Object} params.db
* <b><i>Required.</i></b>
* @param {string} params.db.name
* <b><i>Required.</i></b>
* Used for opening <code>indexedDB</code>.
* @param {string} params.db.table
* <b><i>Required.</i></b>
* Used for getting <code>ObjectStore</code> from <code>transaction</code>.
* @param {string} params.db.key
* <b><i>Required.</i></b>
* Used for getting item from <code>ObjectStore</code>.
* @param {bim.app.data.bundleCallback} callback
* <b><i>Required.</i></b>
* Callback function called with result data.
* See {@link bim.app.data.bundleCallback} for more details.
* @example
* bim.app.data.bundle({
* db: {
* name: ${1: name},
* table: ${2: table},
* key: ${3: key}
* }
* }, ${4: callback});
* @example
* bim.app.data.bundle({
* db: {
* name: "storyboard", // Name of indexedDB
* table: "plugins", // Which ObjectStore would be used
* key: "PLUGINS" // The key of the item
* }
* }, function (res) {
* if (res.error) {
* // Do Something ...
* console.error(res.message);
* } else {
* // Do Something ...
* bim.app.storyboard.moveTo({
* page: page,
* plugin: plugin_name,
* index: true
* });
* }
* });
*/
bundle: function (params, callback) {
var db = {};
// HANDLE ERROR
db.onerror = function (e) {
callback({
error: true,
message: "There was a problem reading app database",
});
};
var req = window.indexedDB.open(params.db.name);
req.onsuccess = event => {
db.database = req.result;
db.database.onclose = () => {
console.log("Database connection closed");
};
try {
var transaction = db.database.transaction(
[params.db.table],
"readwrite"
);
var objectStore = transaction.objectStore(params.db.table);
var objectStoreRequest = objectStore.get(params.db.key);
objectStoreRequest.onsuccess = function (event) {
var result = objectStoreRequest.result;
return callback({ error: false, data: result.data });
};
} catch (e) {
return callback({
error: true,
description: e,
errno: "e927b362",
message: "Something went wrong creating bundle!",
});
}
};
},
/**
* @description
* DB
* @namespace bim.app.data.db
* @type {Object}
* @property {Object} version
* See {@link bim.app.data.db.version} for more details.
*
* @property {function} addTable
* See {@link bim.app.data.db.addTable} for more details.
*
* @property {function} delete
* See {@link bim.app.data.db.delete} for more details.
*
* @property {function} create
* See {@link bim.app.data.db.create} for more details.
*
* @property {function} addItem
* See {@link bim.app.data.db.addItem} for more details.
*
* @property {function} addFile
* See {@link bim.app.data.db.addFile} for more details.
*
* @property {function} read
* See {@link bim.app.data.db.read} for more details.
*
* @property {function} deleteFile
* See {@link bim.app.data.db.deleteFile} for more details.
*
* @property {function} deleteItem
* See {@link bim.app.data.db.deleteItem} for more details.
*/
db: {
/**
* @description
* Version
* @memberof bim.app.data.db
* @name version
* @type {Object}
* @property {function} set
* Push the version of database which is Object in {db: {string}, version: {string}} to private variable <code>\_\_versions\_\_ {Array}</code>.
* @property {function} get
* See {@link bim.app.data.db.version.get} for more details
*/
version: (function () {
var __versions__ = [];
return {
/**
* @description
* Set version for db
* @memberof bim.app.data.db.version
* @function set
* @param {Object} params
* @param {string} params.db
* Database name
* @param {string} params.version
* Version of the database
* @example
* bim.app.data.db.set({db: ${1:_db}, version: ${2:_version}});
*/
set: function (params) {
var item = {};
item.db = params.db;
item.version = params.version;
__versions__.push(item);
},
/**
* @description
* Get version of db.
* @memberof bim.app.data.db.version
* @function get
* @param {Object} params
* @param {string} params.db
* @example
* bim.app.data.db.get({db: ${1:_db});
*/
get: function (params) {
for (var i = 0; i < __versions__.length; i++) {
if (__versions__[i].db === params.db) {
return __versions__[i];
}
}
},
};
})(),
/**
* @description
* Add Table
* @memberof bim.app.data.db
* @function addTable
* @param {Object} params
* @param {Object} params.db
* @param {string} params.db.name
* @param {string} params.db.version
* @param {string} params.db.table
* @param {string} params.db.keyPath
* @param {string} params.db.columns
* @param {function} callback
*/
addTable: function (params, callback) {
var db = {};
var request = indexedDB.open(params.db.name, params.db.version);
request.onupgradeneeded = function (e) {
db.database = e.target.result;
//const objectStore = db.database.createObjectStore(config.db.table);
const objectStore = db.database.createObjectStore(
params.db.table,
{ keyPath: params.db.keyPath }
);
for (var i = 0; i < params.db.columns.length; i++) {
objectStore.createIndex(
params.db.columns[i],
params.db.columns[i],
{ unique: false }
);
}
if (typeof callback === "function")
callback({ error: false, description: "All set!" });
};
request.onsuccess = function (e) {
var database = e.target.result;
//code to verify that the table was created
database.objectStoreNames.contains(params.db.table);
database.close();
};
request.onerror = function (e) {
return callback({
error: true,
message: "We couldn't add tables",
errno: "e0734g37",
description: e,
});
};
},
/**
* @description
* Delete
* @memberof bim.app.data.db
* @function delete
* @param {*} params
* @param {*} callback
*/
delete: function (params, callback) {
var req = indexedDB.deleteDatabase(params.db);
req.onsuccess = function () {
console.log("Deleted database successfully");
};
req.onerror = function (e) {
return callback({
error: true,
message: "We couldn't delete database",
errno: "e0734g36",
description: e,
});
};
req.onblocked = function () {
console.warn(
"Couldn't delete database due to the operation being blocked"
);
};
},
/**
* @description
* Create
* @memberof bim.app.data.db
* @function create
* @param {*} params
* @param {*} callback
*/
create: function (params, callback) {
var db = {};
// HANDLE ERROR
db.onerror = function (e) {
//console.warn('Full description: ', e);
if (typeof callback === "function")
callback({
error: true,
errno: "e0782b6bnN",
description: e,
});
};
// SPECIFICALLY FOR DATABASE CREATION ONLY
db.createDatabase = function (config) {
var req = window.indexedDB.open(config.db.name);
// CREATE DATABASE IF NOT EXISTS
var upgraded = false;
req.onupgradeneeded = function (e) {
db.database = e.target.result;
//const objectStore = db.database.createObjectStore(config.db.table);
const objectStore = db.database.createObjectStore(
config.db.table,
{ keyPath: config.db.keyPath }
);
for (var i = 0; i < config.db.columns.length; i++) {
objectStore.createIndex(
config.db.columns[i],
config.db.columns[i],
{ unique: false }
);
}
upgraded = true;
if (typeof callback === "function")
return callback({ error: false, description: "All set!" });
};
req.onsuccess = e => {
db.database = req.result;
// db.database.version
if (req.result.objectStoreNames.length == 0) {
// it means it wasnt created and need to be upgraded
if (typeof callback === "function")
return callback({
error: true,
description: "DB version should be upgraded",
message: "Something went wrong processing files",
});
} else if (
e.target.result.name &&
typeof e.target.result.name == "string" &&
e.target.result.name.length > 0
) {
if (typeof callback === "function")
return callback({
error: false,
process: 3,
description: "DB exists already!",
});
}
db.database.onclose = () => {
console.warn("Database connection closed");
};
};
req.onerror = e => {
console.error("onerror ", e);
};
};
db.createDatabase(params);
},
/**
* @description
* Add Item
* @memberof bim.app.data.db
* @function addItem
* @param {*} params
*/
addItem: function (params) {
var db = {};
// HANDLE ERROR
db.onerror = function (e) {
// ON ERROR HERE IT MEANS VALUE ALREADY EXISTS!
//console.error('Full description: ', e);
};
// ADD DATA TO DATABASE
db.addItems = function (data) {
let newItem = {};
newItem[data.keyPath.name] = data.keyPath.value;
if (
Object.prototype.toString.call(data.items.data) ==
"[object Array]"
) {
newItem.data = data.items.data[0];
} else if (typeof data.items.data == "string") {
newItem.data = data.items.data;
}
try {
var transaction = db.database.transaction(
[data.config.db.table],
"readwrite"
);
let objectStore = transaction.objectStore(
data.config.db.table
);
let objectStoreRequest = objectStore.add(newItem);
objectStoreRequest.onsuccess = function (e) {
console.log("Successfully added item: ", e);
};
objectStoreRequest.onerror = db.onerror;
} catch (e) {
return callback({
error: true,
description: e,
errno: "e0n2b36",
message: "Something went wrong adding Item!",
});
}
};
var req = window.indexedDB.open(params.db.name);
req.onsuccess = event => {
db.database = req.result;
db.database.onclose = () => {
console.log("Database connection closed");
};
if (params.db.items) {
for (var i = 0; i < params.db.items.length; i++) {
db.addItems({
config: params,
items: params.db.items[i],
keyPath: params.db.keyPath,
});
}
}
if (params.db.item) {
db.addItems({
config: params,
items: params.db.item,
keyPath: params.db.keyPath,
});
}
};
},
/**
* @description
* Add File
* @memberof bim.app.data.db
* @function addFile
* @param {*} params
* @param {*} callback
*/
addFile: function (params, callback) {
var db = {};
db.onerror = function (e) {
console.error("Full description: ", e);
};
db.addItems = function (data) {
let newItem = {};
newItem[data.keyPath.name] = data.keyPath.value;
newItem.data = data.items;
try {
var transaction = db.database.transaction(
[data.config.db.table],
"readwrite"
);
if (!transaction || !transaction.objectStore)
return callback({ error: true, description: transaction });
var objectStore = transaction.objectStore(
data.config.db.table
);
var objectStoreRequest = objectStore.put(newItem);
objectStoreRequest.onsuccess = function (e) {
if (typeof callback === "function")
return callback({ error: false, description: e });
};
objectStoreRequest.onerror = db.onerror;
} catch (e) {
return callback({
error: true,
description: e,
errno: "eO9bn2633v55A",
message: "Something went wrong adding files!",
});
}
};
var req = window.indexedDB.open(params.db.name);
req.onsuccess = event => {
db.database = req.result;
db.database.onclose = () => {
console.log("Database connection closed");
};
if (params.db.items) {
for (var i = 0; i < params.db.items.length; i++) {
db.addItems({
config: params,
items: params.db.items[i],
keyPath: params.db.keyPath,
});
}
console.log("ALL FILES ADDED! ");
}
if (params.db.item) {
db.addItems({
config: params,
items: params.db.item,
keyPath: params.db.keyPath,
});
}
};
},
/**
* @description
* Read
* @memberof bim.app.data.db
* @function read
* @param {*} params
* @param {*} callback
*/
read: function (params, callback) {
var db = {};
// HANDLE ERROR
db.onerror = function (e) {
return callback({
error: true,
message: "There was a problem reading app database",
});
};
var req = window.indexedDB.open(params.db.name);
req.onsuccess = event => {
db.database = req.result;
db.database.onclose = () => {
console.log("Database connection closed");
};
var transaction = db.database.transaction(
[params.db.table],
"readwrite"
);
try {
var objectStore = transaction.objectStore(params.db.table);
var objectStoreRequest = objectStore.get(params.db.key);
objectStoreRequest.onsuccess = function (event) {
var result = objectStoreRequest.result;
var error = objectStoreRequest.error;
console.log("objectStoreRequest ", objectStoreRequest);
if (!error && result && result.data) {
if (typeof callback === "function")
return callback({ error: false, data: result.data });
} else if (!error && !result) {
if (typeof callback === "function")
return callback({
error: false,
data: "Storage is empty",
});
} else {
if (typeof callback === "function")
return callback({
error: true,
message: "No file was found",
errno: "e09273b8",
});
}
};
} catch (e) {
return callback({
error: true,
description: e,
errno: "eO902b63vv5",
message: "Something went wrong reading the file!",
});
}
};
},
/**
* @description
* Delete File
* @memberof bim.app.data.db
* @function deleteFile
* @param {*} params
* @param {*} callback
*/
deleteFile: function (params, callback) {
var db = {};
db.onerror = function (e) {
return callback({
error: true,
message: "There was a problem reading app database",
});
};
var req = window.indexedDB.open(params.db.name);
req.onsuccess = event => {
db.database = req.result;
// console.log("db.database:", db.database);
// console.log("db.database:", req.result.version);
db.database.onclose = () => {
console.log("Database connection closed");
};
if (db.database.objectStoreNames.length > 0) {
try {
var transaction = db.database.transaction(
[params.db.table],
"readwrite"
);
// console.log("transaction:", transaction);
var objectStore = transaction.objectStore(params.db.table);
var objectStoreRequest = objectStore.delete(params.db.key);
objectStoreRequest.onsuccess = function (event) {
var error = objectStoreRequest.error;
if (!error) {
if (typeof callback === "function")
return callback({
error: false,
version: db.database.version,
data: "File deleted successfully!",
});
} else {
if (typeof callback === "function")
return callback({
error: true,
message: "Oops! Something went wrong",
errno: "e07b363b4",
});
}
};
} catch (e) {
return callback({
error: true,
description: e,
errno: "eO8b990172",
message: "Something went wrong deleting the file!",
});
}
} else {
return callback({
error: false,
length: 0,
version: db.database.version,
description: "No files stored found",
});
}
};
},
/**
* @description
* Delete Item
* @memberof bim.app.data.db
* @function deleteItem
* @param {*} params
* @param {*} callback
*/
deleteItem: function (params, callback) {
var db = {};
db.onerror = function (e) {
console.error("error ", e);
return callback({
error: true,
message: "There was a problem reading app database",
});
};
var req = window.indexedDB.open(params.db.name);
req.onsuccess = event => {
db.database = req.result;
db.database.onclose = () => {
console.log("Database connection closed");
};
var transaction = db.database.transaction(
[params.db.table],
"readwrite"
);
var objectStore = transaction.objectStore(params.db.table);
var objectStoreRequest = objectStore.delete(params.db.item);
objectStoreRequest.onsuccess = function (event) {
try {
var result = objectStoreRequest.result;
return callback({ error: false, data: result });
} catch (e) {
return callback({
error: true,
description: e,
errno: "eDn2723b",
message: "Something went wrong deleting the Item!",
});
}
};
};
},
},
/**
* @description
* Set
* @memberof bim.app.data
* @function set
* @param {*} params
* @returns {}
*/
set: function (params) {
if (!params || params == "") return;
if (
!params.file &&
Object.prototype.toString.call(params) === "[object Object]"
) {
var objectKey = Object.keys(params);
if (!objectKey || !objectKey[0]) return;
if ((!params[objectKey[0]] !== params[objectKey[0]]) == "")
return;
if (
Object.prototype.toString.call(params[objectKey[0]]) ===
"[object String]"
) {
window.localStorage.setItem(objectKey[0], params[objectKey[0]]);
} else if (
Object.prototype.toString.call(params[objectKey[0]]) ===
"[object Object]"
) {
window.localStorage.setItem(
objectKey[0],
JSON.stringify(params[objectKey[0]])
);
}
}
return;
},
/**
* @description
* Get
* @memberof bim.app.data
* @function get
* @param {*} params
* @param {*} callback
* @returns {}
*/
get: function (params, callback) {
if (!params || params == "") return;
if (typeof callback == "function")
return callback(window.localStorage.getItem(params));
return window.localStorage.getItem(params);
},
/**
* @description
* Delete Item
* @memberof bim.app.data
* @function deleteItem
* @param {*} params
* @param {*} callback
* @returns {}
*/
deleteItem: function (params, callback) {
if (!params || params == "" || typeof params !== "string")
return callback({
error: true,
errno: "e0o384",
description: "Item is required!",
});
try {
window.localStorage.removeItem(params);
return callback({
error: false,
message: "Item delete successfully!",
});
} catch (e) {
return { error: true, errno: "o08723bX", description: e };
}
},
},
/**
* @description
* User API.
* Collection of functions to control data of user with <code>localStorage</code>
* @since 22.03.17
* @namespace bim.app.user
* @property {Object} _uid
* Object which contains functions to generate texts for user ID.
* See {@link bim.app.user._uid} for more details.
*
* @property {Object} token
* Object which contains functions to set or get user token.
* See {@link bim.app.user.token} for more details.
*
* @property {function} name
* Function to get user name from local storage if exists.
* See {@link bim.app.user.name} for more details.
*
* @property {function} uid
* Function to get user ID from local storage if exists.
* See {@link bim.app.user.uid} for more details.
*
* @property {function} loggedIn
* Function to check whether user is logged in or not.
* See {@link bim.app.user.loggedIn} for more details.
*
* @property {function} register
* Function to register user information to local storage.
* See {@link bim.app.user.register} for more details.
*
* @property {function} logout
* Function to log out user.
* See {@link bim.app.user.logout} for more details.
*/
user: (function () {
var user = window.localStorage;
return {
/**
* @description
* Object which contains functions to generate texts
* for user ID.
* @memberof bim.app.user
* @name _uid
* @type {Object}
* @property {function} text
* Function to serve randomly generated text.
* @example
* bim.app.user._uid.text();
* @property {function} generate
* Function to serve randomly generated text with date.
* @example
* bim.app.user._uid.generate();
*/
_uid: {
/**
* @description
* Function that returns randomly generated text.
* @memberof bim.app.user._uid
* @function text
* @param {Number} [n=16]
* @returns {string}
* Randomly generated text.
* @example
* bim.app.user._uid.text();
* @example
* bim.app.user._uid.text(${1:number});
* @example
* let randomText = bim.app.user._uid.text(20);
*/
text: function (n) {
if (typeof n !== "number") {
n = 16;
}
var text = "";
var possible =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for (var i = 0; i < n; i++) {
text += possible.charAt(
Math.floor(Math.random() * possible.length)
);
}
return text;
},
/**
* @description
* Function to serve randomly generated text with date.
* @memberof bim.app.user._uid
* @function generate
* @returns {string}
* Randomly generated text with date.
* @example
* bim.app.user._uid.generate();
*/
generate: function () {
var n = Date.now();
return (
__lib.functions.text() + n + Math.floor(Math.random() * 100)
);
},
},
/**
* @description
* Object which contains functions to set or get the item,
* user token, to <code>localStorage</code>
* using "token" as the key.
* @memberof bim.app.user
* @name token
* @type {Object}
* @property {function} set
* Function to set <code>localStorage</code> item using "token" as a key.
* @property {function} get
* Function to get <code>localStorage</code> item using "token" as a key.
* @example
* bim.app.user.token.get();
*/
token: (function () {
return {
/**
* @description
* Function to set <code>localStorage</code> item using "token" as a key.
* @memberof bim.app.user.token
* @function set
* @param {string} token
* @returns {}
*/
set: function (token) {
user.setItem("token", token);
},
/**
* @description
* Function to get <code>localStorage</code> item using "token" as a key.
* @memberof bim.app.user.token
* @function get
*/
get: function () {
localStorage.getItem("token");
},
};
})(),
/**
* @description
* Searches by "user" from local storage,
* if exists, calls callback function with it as a parameter and returns it.
* Else, returns false.
* @memberof bim.app.user
* @function name
* @param {callback} callback
* @returns {string | boolean}
* <code>localStorage</code> item using key "user" | <code>false</code>
* @example
* bim.app.user.name();
*/
name: function (callback) {
if (user.getItem("user")) {
if (typeof callback == "function")
callback(localStorage.getItem("user"));
return localStorage.getItem("user");
} else {
return false;
}
},
/**
* @description
* Searches by "uid" from local storage,
* if exists, calls callback function with it as a parameter and returns it.
* Else, returns false.
* @memberof bim.app.user
* @function uid
* @param {callback} callback
* @returns {* | boolean} localStorage's item using key "uid" | false
* @example
* bim.app.user.uid();
*/
uid: function (callback) {
if (user.getItem("uid")) {
if (typeof callback == "function")
callback(localStorage.getItem("uid"));
return localStorage.getItem("uid");
} else {
return false;
}
},
/**
* @description
* Function to check whether user is logged in or not.
* Check items with "uid" & "user", as keys, from localstorage.
* If callback is a function,
* calls it with existence of items (true, false) as parameter.
* Else, returns whether they exist or not.
* @memberof bim.app.user
* @function loggedIn
* @param {function=} callback
* <b><i>Optional.</i></b>
* Callback function
* @returns {* | boolean}
* Result of callback if it is a function | Whether logged in or not. <code>true</code>, <code>false</code>
* @example
* bim.app.user.loggedIn(${1:callback});
*/
loggedIn: function (callback) {
if (__lib.app.user.uid() && __lib.app.user.name()) {
if (typeof callback == "function") return callback(true);
return true;
}
if (typeof callback == "function") return callback(false);
return false;
},
/**
* @description
* Function to register user information to local storage.
* Saves data "user", "uid" into <code>localStorage</code>.
* @memberof bim.app.user
* @param {Object} params
* <b><i>Required.</i></b>
* @param {string} params.user
* @param {string} params.uid
* @param {function=} callback
* @returns {* | Object}
* If callback is function, returns the result of callback
* with Object using {name, uid} property as a parameter.
* Else, returns Object having property {name, uid}.
* @example
* // Without callback function
* bim.app.user.register({name : ${1:userName}, uid : ${2:userId}});
* @example
* // With callback function
* bim.app.user.register({name : ${1:userName}, uid : ${2:userId}}, ${3:callback});
*/
register: function (params, callback) {
if (!params) {
if (callback == "function") callback(false);
return false;
}
user.setItem("user", params.user);
user.setItem("uid", params.uid);
if (typeof callback === "function") {
return callback({
name: __lib.app.user.name(),
uid: __lib.app.user.uid(),
});
}
return { name: __lib.app.user.name(), uid: __lib.app.user.uid() };
},
/**
* @description
* Function to log out user.
* Removes data "user", "uid" from <code>localStorage</code>.
* @memberof bim.app.user
* @function logout
* @returns {}
* @example
* bim.app.user.logout();
*/
logout: function () {
user.removeItem("user");
user.removeItem("uid");
user.clear();
},
};
})(),
/**
* @description
* Function to get or set user session.
*
* If parameter is empty, returns current user data.
*
* If not empty, sets the user data.
* @since 22.03.17
* @memberof bim.app
* @function session
* @param {Object=} params
* <b><i>Optional</i></b>
* @param {string} params.user
* User Name
* @param {string} params.uid
* User ID
* @param {function=} callback
* Callback Function
* @returns {Object | * | void}
* When gets empty parameter, returns Object
* {uid: {string}, name: {string}, guest: {boolean}}
*
* When <code>callback</code> is function,
* returns the result of callback.
*
* Else, returns void.
* @example
* // Get Session (uid & name & guest)
* bim.app.session();
* @example
* // Get Session (uid & name & guest) & Calls Callback
* bim.app.session(${1:callback});
* @example
* // Set Session & Calls Callback
* bim.app.session({"user" : ${1:userName}, "uid" : ${2:userID}}, ${3:callback});
*/
session: function (params, callback) {
// CREATE A GUEST USER
if (!params || (typeof params === "function" && !callback)) {
callback = params;
return __lib.app.user.loggedIn(function (IsLogin) {
if (IsLogin) {
return {
uid: __lib.app.user.uid(),
name: __lib.app.user.name(),
guest: false,
};
} else {
return {
uid: __lib.app.user.uid(),
name: __lib.app.user.name(),
guest: true,
};
}
});
} else if (
params.user &&
params.uid &&
params.user !== "" &&
params.uid !== ""
) {
return __lib.app.user.register(params, function (res) {
if (typeof callback === "function") {
return callback(res);
} else {
return res;
}
});
}
return;
},
/**
* @description
* Function to get the App's ID from Native side.
* Currently, only works for Android OS now.
* @since 22.03.17
* @memberof bim.app
* @function getAppId
* @example
* bim.app.getAppId();
*/
getAppId: function () {
console.log("HTB_NATIVE_LOG", "bim.app.getAppId() ");
},
/**
* @description
* Function to set App's ID to Native side.
* Currently, only works for Android OS now.
* @since 22.03.17
* @memberof bim.app
* @function setAppId
* @param {Object} params
* <b><i>Required.</i></b>
* Parameter would be sent to native after stringfied.
* @returns {Object | void}
* Error Object if params empty.
* @example
* bim.app.setAppId({$1:Object});
*/
setAppId: function (params) {
if (!params || params == "")
return {
error: true,
errno: "eO072bx3",
description:
"Parameters cannot be empty, read the documentation to know more about",
message: "Oops! Something went wrong implementing native plugin",
};
console.log("HTB_NATIVE_LOG", "bim.app.setAppId : ", params);
},
/**
* @description
* Function to create new page in plugin.
* @since 22.03.17
* @memberof bim.app
* @function page
* @param {Object} params
* <b><i>Required.</i></b>
* Contain page objects for Hitbim
* @param {Object} params.page
* <b><i>Required.</i></b>
* @param {string} params.page.name
* Name of the new screen.
* @param {Object} params.page.context
* Context to fill template dynamically.
* @param {Object} params.page.context.lang
* Path of the language.
* @param {Object} params.page.context.detect
* Detect in case of load automatically a language
* by detecting device language.
* @param {Object} params.page.content
* Template of the new screen.
* Placeholder should match the json keyNames from
* context lang key.
* @param {boolean} params.page.animate
* Load page with animation.
* @param {function | Object} callback
* Function to generate the new page,
* can be synchronously or asynchronously.
*
* callback can have two types
* 1. callback can be called when after creating page
*
* 2. callback can be Object contain two functions
*
* <code>onOpen: function(){}, // This runs like type 1 (called when after creating page)</code>
*
* <code>onClose: function(){} // Called when bim.app.close.page();</code>
* @param {function} callback.onOpen
* Called after creating new page
* @param {function} callback.onClose
* Called after deleting this page by
* <code>{@link bim.app.close bim.app.close.page();}</code>
* @example
* var page = {
* page: {
* name: {$1:name},
* context: {
* lang: {$2:lang},
* detect: {$3:detect}
* },
* content: {$4:content},
* animate: {$5:animate}
* }
* };
* bim.app.page(page, {$6:callback});
* @example
* var page = {
* page: {
* name: 'login',
* context: {
* lang: 'lang/en',
* detect: false
* },
* content: 'templates/login.html',
* animate: true
* }
* };
*
* bim.app.page(page, function() {
* console.log('trigger after opened', this);
* // Do Something ...
* });
*/
page: function (params, callback) {
if (params && params !== "") {
__lib.app
.template({
id: __lib.plugin.id.get(),
html: params.page.content,
context: {
lang: params.page.context.lang,
detect: params.page.context.detect,
},
name: params.page.name,
})
.then(function (res) {
if (!res.error) {
// temporary DOM
var bimElement = document.createElement("div");
bimElement.innerHTML = res.template;
var elementHTML = __lib.app.element(bimElement);
elementHTML.addClass("bim-singleView bim-singleView-init");
__lib.app.element("body").append(elementHTML);
var el = __lib.app.element("body").find(".bim-singleView");
for (var i = 0; i < el.length - 1; i++) {
el.eq(i).attr("visible", "false");
}
const lastDiv = document.querySelector(
".bim-singleView:last-child"
);
lastDiv.classList.remove("bim-page-from-left");
lastDiv.classList.add("bim-singleView-center");
lastDiv.setAttribute("singleView-name", params.page.name);
lastDiv.setAttribute("index", el.length - 1);
let OpenCallback =
typeof callback == "function"
? callback
: typeof callback == "object"
? callback.onOpen
: undefined;
let CloseCallback =
typeof callback == "object" ? callback.onClose : undefined;
// Set pageNavigator When create new page inside plugin
pageNavigator.push({
index: el.length - 1,
name: params.page.name,
OpenCallback: OpenCallback,
CloseCallback: CloseCallback,
});
for (var i = 0; i < el.length; i++) {
el.eq(i).attr("index", i);
}
setTimeout(function () {
el.addClass("bim-page-from-left");
__lib.app.listeners.transition(
{
event: "create",
name: params.page.name,
index: el.length - 1,
},
function (e) {
return OpenCallback(e);
}
);
}, 0);
} else {
if (typeof OpenCallback === "function")
return OpenCallback(res);
return res;
}
});
} else
console.error("bim.app.page() need parameter. Check document!");
},
/**
* @description
* Function to add Event Listener to document.
* @memberof bim.app
* @function listener
* @param {string} eventType
* @param {string} elementQuerySelector
* Used as a selector
* @param {function} cb
* Callback function for the event
* @example
* bim.app.listener(${1:eventType}, ${2:selector}, ${3:callback});
*/
listener: function (eventType, elementQuerySelector, cb) {
document.addEventListener(eventType, function (event) {
var qs = document.querySelectorAll(elementQuerySelector);
if (qs) {
var el = event.target,
index = -1;
while (
el &&
(index = Array.prototype.indexOf.call(qs, el)) === -1
) {
el = el.parentElement;
}
if (index > -1) {
if (/^[^{]+?=>/.test(cb.toString())) {
event.element = el;
return cb(event);
} else {
cb.call(el, event);
}
}
}
});
},
/**
* @description
* Object which has a Function to make the last step to firing an event.
* @memberof bim.app
* @name listeners
* @type {Object}
* @property {function} transition
* Function to make the last step to firing an event.
* @example
* bim.app.listeners.transition({
* event: ${1:event},
* name: ${2:name},
* index: ${3:index},
* on: ${4:on}
* }, ${5:callback});
* @example
* bim.app.listeners.transition({
* event: "create",
* name: _name,
* index: _index,
* }, function (e) {
* // Do Something ...
* });
*/
listeners: {
/**
* @memberof bim.app.listeners
* @function transition
* @param {Object} e
* <b><i>Required.</i></b>
* @param {*} e.on
* @param {*} e.event
* @param {*} e.name
* @param {*} e.index
* @param {function} callback
* Callback Function
* @returns {*}
* The result of callback
*/
transition: function (e, callback) {
if (!e || e == "") return;
//var element = (!e.listen || e.listen == '') ? 'document' : e.listen;
//if (!e.on || e.on == '') return;
var delay = true;
var evCallback;
switch (e.on) {
case "before":
evCallback = "transitionrun";
break;
case "onstart":
case "start":
evCallback = "transitionstart";
break;
case "cancel":
evCallback = "transitioncancel";
break;
case "after":
case "end":
case "finish":
delay = true;
evCallback = "transitionend";
break;
}
var option = {
detail: {
listener: "navigation",
event: e.event,
page: e.name,
index: e.index,
},
};
if (delay) {
setTimeout(function () {
document.dispatchEvent(new CustomEvent("navigation", option));
return callback(option);
}, 300);
} else {
document.dispatchEvent(new CustomEvent("navigation", option));
return callback(option);
}
},
},
/**
* @description
* Function to add Event Listener "navigation" to document.
* @memberof bim.app
* @function navigation
* @param {function} callback
* @example
* bim.app.navigation(${1:callback});
*/
navigation: function (callback) {
document.addEventListener("navigation", function (e) {
if (typeof callback === "function") return callback(e.detail);
});
},
/**
* @description
* Object, which has a Function to close opened page in plugin.
* @since 22.03.17
* @memberof bim.app
* @name close
* @type {Object}
* @property {function} page
* Function to close opened page in plugin.
* @example
* bim.app.close.page();
* @example
* bim.app.close.page({animatePages:true});
*/
close: {
/**
* @description
* Function to close opened page in plugin.
* @memberof bim.app.close
* @function page
* @param {*} params
* Close option
* @param {function} callback
* IF callback exists, run callback after close page
* IF not exists callback AND when set onClose function in
* <code>{@link bim.app.page}</code>,
* run onClose function automatically
* @returns {*}
* Result of callback function.
* @example
* bim.app.close.page(${1:params}, ${2:callback});
*/
page: function (params, callback) {
if (pageNavigator.length == 0) return;
let page_elements = bim.app.element(
".bim-singleView-center.bim-page-from-left"
);
if (page_elements.length == 0) return;
let last_element = page_elements[page_elements.length - 1];
last_element.remove();
let CloseCallback =
callback && typeof callback == "function"
? callback
: pageNavigator[pageNavigator.length - 1].CloseCallback;
pageNavigator.pop();
if (CloseCallback) return CloseCallback(false);
},
},
/**
* @description
* Function to return {@link DOM} Element.
* @memberof bim.app
* @function element
* @param {DOM | string} selector
* Selector to match the Element.
* Can be {@link DOM}, Document, Window Object or
* string.
* @returns {DOM}
* Returns {@link DOM} Element matched by selector.
* @example
* bim.app.element(${1:string});
*/
element: function (selector) {
return tokenizer(selector);
},
/**
* @description
* TEMPLATER LOGICLESS
* Tokenizing fraction in template.
* Pass the string and create structure to parse template object.
* @namespace bim.app.logicless
* @property {Object} htmlTemplate See {@link bim.app.logicless.htmlTemplate} for more details
* @property {Object} lang See {@link bim.app.logicless.lang} for more details
* @property {function} tokenizer See {@link bim.app.logicless.tokenizer} for more details
* @property {function} compiler See {@link bim.app.logicless.compiler} for more details
*/
logicless: {
/**
* @description
* HTML Template
* @memberof bim.app.logicless
* @name htmlTemplate
* @type {Object}
* @property {function} get See {@link bim.app.logicless.htmlTemplate} for more details
* @property {function} tokenizer See {@link bim.app.logicless.htmlTemplate.tokenizer} for more details
* @property {function} compiler See {@link bim.app.logicless.htmlTemplate.compiler} for more details
*/
htmlTemplate: {
/**
* @memberof bim.app.logicless.htmlTemplate
* @function get
* @param {*} params
* @returns {}
*/
get: function (params) {
return new Promise(function (resolve, reject) {
if (!params || !params.path || params.path == "")
return resolve({
error: true,
message: "Error loading template",
errno: "98b674bb55",
});
// Load lang file
var ext = params.path.split(".");
var file;
if (ext.length > 1) {
ext = params.path.split(/[#?]/)[0].split(".").pop().trim();
if (ext == "html") {
file = params.path.split(".")[0] + ".html";
} else {
return;
}
ext = ".html";
} else {
file = ext[0] + ".html";
}
if (!file)
return resolve({
error: true,
message: "Error loading template",
errno: "93b3464vf5",
});
__lib.readFile(
{ file: file, onErrorMessage: "Error loading template" },
function (res) {
if (res.error) {
return resolve(res);
} else {
return resolve({ error: false, data: res.data });
}
}
);
});
},
/**
* @memberof bim.app.logicless.htmlTemplate
* @function tokenizer
* @param {*} string
* @returns {}
*/
tokenizer: function (string) {
return new Promise(function (rv) {
if (!string || string == "")
return rv({
error: true,
message: "Params can be empty iterating template",
errno: "js7263in",
});
var current = 0;
var chunk = "";
var crawlHtml = "";
var methods = 0;
var allowCralwing = true;
var fk = "";
while (current <= string.length) {
var char = string[current];
if (/\s/.test(chunk)) {
if (chunk.indexOf("{{#") > -1) {
if (methods > 0) {
fk +=
',\n{\n "method": "' +
chunk.replace("{{#", "").trim() +
'",\n';
} else {
fk +=
'{\n "method": "' +
chunk.replace("{{#", "").trim() +
'",\n';
}
allowCralwing = true;
methods++;
} else if (
chunk.indexOf("}}") > -1 &&
chunk.indexOf(">") < 0 &&
chunk.indexOf("<") < 0 &&
chunk.indexOf("{{/") < 0
) {
fk +=
'"key": "' + chunk.replace("}}", "").trim() + '",\n ';
}
// TEMPLATE
else {
if (allowCralwing) {
crawlHtml += chunk;
}
}
chunk = "";
} else {
// END LOGILESS TEMPLATE LOOP METHOD
if (chunk.indexOf("{{/") > -1 && chunk.indexOf("}}") > -1) {
fk +=
'"template": ' +
JSON.stringify(crawlHtml.trim()) +
"\n}";
crawlHtml = "";
allowCralwing = false;
}
}
chunk += char;
current++;
}
try {
return rv({ error: false, data: JSON.parse("[" + fk + "]") });
} catch (e) {
return rv({
error: true,
description: e,
errno: "87h4s56a62",
});
}
});
},
/**
* @memberof bim.app.logicless.htmlTemplate
* @function compiler
* @param {*} params
* @returns {}
*/
compiler: function (params) {
return new Promise(function (rs) {
// LENGTH ITERATIONS
var fullbuilder = "";
var mainBuilder = [];
var item = {};
String.prototype.buildTemplate = function (result) {
return this.replace(/{{(.+?)}}/g, function (_, g1) {
return result[g1] || g1;
});
};
for (var a = 0; a < params.tokens.data.length; a++) {
var template = params.tokens.data[a].template;
var key = params.tokens.data[a].key;
var builder = "";
if (
params.parse &&
params.parse.data &&
params.parse.data[key]
) {
for (var b = 0; b < params.parse.data[key].length; b++) {
builder += template.buildTemplate(
params.parse.data[key][b]
);
}
}
}
return rs(builder);
});
},
},
/**
* @description
* Language
* @memberof bim.app.logicless
* @name lang
* @type {Object}
* @property {function} get See {@link bim.app.logicless.lang.get} for more details
*/
lang: {
/**
* @description
* Function to read language file.
* Returns void when extension is not in "json"
* @memberof bim.app.logicless.lang
* @function get
* @param {Object} params
* <b><i>Required.</i></b>
* parameter.
* @param {string} params.lang
* <b><i>Required.</i></b>
* Language file name with extension (.json)
* @returns {void | Object}
* If has extension and it's not ".json", void |
*
* Error data or read file data
*/
get: function (params) {
return new Promise(function (resolve, reject) {
if (!params || !params.lang || params.lang == "")
return resolve({
error: true,
message: "Error loading languaje file",
errno: "eO9b62v35",
});
// Load lang file
var ext = params.lang.split(".");
var file;
if (ext.length > 1) {
ext = params.lang.split(/[#?]/)[0].split(".").pop().trim();
if (ext == "json") {
file = params.lang.split(".")[0] + ".json";
} else {
return;
}
ext = ".json";
} else {
file = ext[0] + ".json";
}
if (!file)
return resolve({
error: true,
message: "Error loading language file",
errno: "eO9b364v",
});
__lib.readFile(
{ file: file, onErrorMessage: "Error reading language file" },
function (res) {
if (!res.error) {
try {
var parsedLanguage = JSON.parse(res.data);
return resolve({ error: false, data: parsedLanguage });
} catch (err) {
return resolve({
error: true,
message: "Oops! Error loading language file!",
description: err,
errno: "8745b4745bgv",
});
}
} else {
return resolve({
error: true,
message: "Oops! Error loading language file!",
description: err,
errno: "3b37843b6",
});
}
}
);
});
},
},
/**
* @description
* Tokenizer
* @memberof bim.app.logicless
* @function tokenizer
* @param {*} string
* @returns {Object} Object with error report or parsed JSON
*/
tokenizer: function (string) {
var blocks = [];
var i;
var j;
if (!string || typeof string !== "string" || string == "") {
return [];
}
var stringBlocks = string.split(/({{[^{^}]*}})/);
for (i = 0; i < stringBlocks.length; i += 1) {
var block = stringBlocks[i];
if (block === "") {
continue;
}
if (block.indexOf("{{") < 0) {
blocks.push({
type: "plain",
content: block,
});
} else {
if (block.indexOf("{/") >= 0) {
continue;
}
if (
block.indexOf("{#") < 0 &&
block.indexOf(" ") < 0 &&
block.indexOf("else") < 0
) {
// Simple variable
blocks.push({
type: "variable",
contextName: block.replace(/[{}]/g, ""),
});
continue;
}
// Helpers
var helperSlices = helperToSlices(block);
var helperName = helperSlices[0];
var isPartial = helperName === ">";
var helperContext = [];
var helperHash = {};
for (j = 1; j < helperSlices.length; j += 1) {
var slice = helperSlices[j];
if (isArray(slice)) {
// Hash
helperHash[slice[0]] =
slice[1] === "false" ? false : slice[1];
} else {
helperContext.push(slice);
}
}
if (block.indexOf("{#") >= 0) {
// Condition/Helper
var helperContent = "";
var elseContent = "";
var toSkip = 0;
var shiftIndex = void 0;
var foundClosed = false;
var foundElse = false;
var depth = 0;
for (j = i + 1; j < stringBlocks.length; j += 1) {
if (stringBlocks[j].indexOf("{{#") >= 0) {
depth += 1;
}
if (stringBlocks[j].indexOf("{{/") >= 0) {
depth -= 1;
}
if (stringBlocks[j].indexOf("{{#" + helperName) >= 0) {
helperContent += stringBlocks[j];
if (foundElse) {
elseContent += stringBlocks[j];
}
toSkip += 1;
} else if (
stringBlocks[j].indexOf("{{/" + helperName) >= 0
) {
if (toSkip > 0) {
toSkip -= 1;
helperContent += stringBlocks[j];
if (foundElse) {
elseContent += stringBlocks[j];
}
} else {
shiftIndex = j;
foundClosed = true;
break;
}
} else if (
stringBlocks[j].indexOf("else") >= 0 &&
depth === 0
) {
foundElse = true;
} else {
if (!foundElse) {
helperContent += stringBlocks[j];
}
if (foundElse) {
elseContent += stringBlocks[j];
}
}
}
if (foundClosed) {
if (shiftIndex) {
i = shiftIndex;
}
blocks.push({
type: "helper",
helperName: helperName,
contextName: helperContext,
content: helperContent,
inverseContent: elseContent,
hash: helperHash,
});
}
} else if (block.indexOf(" ") > 0) {
if (isPartial) {
helperName = "_partial";
if (helperContext[0]) {
helperContext[0] =
'"' + helperContext[0].replace(/"|'/g, "") + '"';
}
}
blocks.push({
type: "helper",
helperName: helperName,
contextName: helperContext,
hash: helperHash,
});
}
}
}
return blocks;
},
/**
* @description
* Compiler
* @memberof bim.app.logicless
* @function compiler
* @param {*} params
* @param {*} params.html
* @param {*} params.parse
* @param {*} callback
* @example
* bim.app.logicless.compiler(${1:params}, ${2:callback});
*/
compiler: function (params, callback) {
// CLEAN HTML
var bimElement = document.createElement("div");
bimElement.innerHTML = params.html;
var elementHTML = __lib.app.element(bimElement);
var selector = "bim";
elementHTML.find(selector).filter(function (index, el) {
var stringHTML = __lib.app.element(el)[0].innerHTML;
var ast = __lib.app.logicless.tokenizer(stringHTML);
var builder = "";
for (var i = 0; i < ast.length; i++) {
if (ast[i].type === "plain") {
builder += ast[i].content;
}
if (ast[i].type === "variable") {
builder += params.parse[ast[i].contextName];
}
}
if (typeof callback === "function") return callback(builder);
});
},
},
/**
* @description
* Function to return templated "bim" element
* with context language.
* @memberof bim.app
* @function template
* @param {Object} param
* <b><i>Required.</i></b>
* @param {string} param.id
* Plugin ID
* @param {string} param.html
* <b><i>Required.</i></b>
* @param {Object} param.context
* @param {string} param.context.lang
* The path of language file in json type.
* @param {boolean} param.context.detect
* @param {boolean} param.component
* @param {function} callback
* Callback function.
* @returns {{ error:boolean, template:string, message:string, errno:string }}
* {
* error {boolean},
* template {string},
* message: {string},
* errno: {string}
* }
* @example
* bim.app.template({
* id: bim.plugin.id.get(),
* html: "templates/your_template.html",
* context: {
* lang: "lang/en",
* detect: false
* },
* name: bim.plugin.name.get()
* }).then(function (compiled) {
* // Do Something ...
* });
*/
template: function (param, callback) {
return new Promise(function (rs, rj) {
if (!param)
return rs({ error: true, message: "Params cannot be empty" });
if (!param.html || param.html == "")
return rs({
error: true,
message:
"Template path is missing or <bim> tag missing in template file",
errno: "83gv364",
});
if (!__lib.plugin.id.get() || __lib.plugin.id.get() == "")
return rs({
error: true,
message: "Initialize app is required, plugin id is missing",
errno: "ue73g463",
});
if (!__lib.plugin.name.get() || __lib.plugin.name.get() == "")
return rs({
error: true,
message: "Initialize app is required, plugin name is missing",
errno: "93b343b",
});
if (typeof __lib.plugin.id.get() !== "string")
return rs({
error: true,
message: "Initialize app is required, plugin id is missing",
errno: "93b33nrv4",
});
var pluginId = __lib.plugin.id.get();
async function _run(s) {
var contextLang =
Object.prototype.toString.call(s.context) ==
"[object Object]" &&
s.context.lang &&
s.context.lang !== ""
? s.context.lang
: s.lang;
var contextDetect =
Object.prototype.toString.call(s.context) ==
"[object Object]" &&
s.context.detect &&
s.context.detect !== ""
? s.context.detect
: s.detect;
var langObject = await __lib.app.logicless.lang.get({
lang: contextLang,
detect: contextDetect,
});
var templateObject = await __lib.app.logicless.htmlTemplate.get({
path: s.html,
});
if (langObject.error) {
return rs(langObject);
} else if (templateObject.error) {
return rs(templateObject);
} else if (langObject.data == "" || templateObject.data == "") {
return rs({
error: true,
message: "Initialize app is required, plugin id is missing",
errno: "93n273aa33rv4",
});
} else {
// BUILD THE TEMPLATE
__lib.app.logicless.compiler(
{
html: templateObject.data,
parse: langObject.data,
lang: contextLang,
},
function (compiled) {
let compiledWithParams =
'<bim bim-id="' +
pluginId +
'" data-lang="' +
contextLang +
'">' +
compiled +
"</bim>";
return rs({ error: false, template: compiledWithParams });
}
);
}
}
_run(param);
});
},
/**
* @description
* Collection of functions to handle the storyboard of the App.
* @namespace bim.app.storyboard
* @type {Object}
* @property {function} containsStack
* Function to check whether contains stack or not.
* See {@link bim.app.storyboard.containsStack} for more details.
*
* @property {function} getStack
* Function to get stack from local storage.
* See {@link bim.app.storyboard.getStack} for more details.
*
* @property {function} setStack
* Function to set stack to local storage.
* See {@link bim.app.storyboard.setStack} for more details.
*
* @property {function} setCurrent
* Function to set current plugin to localstorage.
* See {@link bim.app.storyboard.setCurrent} for more details.
*
* @property {function} current
* Function to get current plugin from localstorage.
* See {@link bim.app.storyboard.current} for more details.
*
* @property {function} next
* Function to move to next plugin.
* See {@link bim.app.storyboard.next} for more details.
*
* @property {function} setPrevious
* Function to set previous plugin.
* See {@link bim.app.storyboard.setPrevious} for more details.
*
* @property {function} previous
* Function to get previous plugin.
* See {@link bim.app.storyboard.previous} for more details.
*
* @property {function} moveTo
* Function to move with data to other plugin.
* See {@link bim.app.storyboard.moveTo} for more details.
*
* @property {function} setGoBack
* Function to set "goBack" function in plugin.
* See {@link bim.app.storyboard.setGoBack} for more details.
*
* @property {function} resetGoBack
* Function to reset "goBack" function in plugin.
* See {@link bim.app.storyboard.resetGoBack} for more details.
*
* @property {function} goBack
* Function called directly or indirectly when user goes back.
* See {@link bim.app.storyboard.goBack} for more details.
*/
storyboard: {
/**
* @description
* Function which checks whether the storyboard
* contains stack in stack objects or not.
* Checked by second parameter's paths.
* @memberof bim.app.storyboard
* @function containsStack
* @param {string} stackObject
* @param {Array} stackObjects
* @returns {boolean} true | false
* @example
* bim.app.storyboard.containStack(${1:stackObject}, ${2:stackObjects});
*/
containsStack: function (stackObject, stackObjects) {
var i;
for (i = 0; i < stackObjects.length; i++) {
if (stackObjects[i].pathname === stackObject) {
return true;
}
}
return false;
},
/**
* @description
* Function to get stack from local storage.
* @memberof bim.app.storyboard
* @function getStack
* @returns {string}
* Returns the item in local storage which has key "navigation"
* @example
* bim.app.storyboard.getStack();
*/
getStack: function () {
return window.localStorage.getItem("navigation");
},
/**
* @description
* Function to set stack to local storage.
* Checks whether there is already existing stack or not before setting it.
* @memberof bim.app.storyboard
* @function setStack
* @param {Object} params
* <b><i>Required.</i></b>
* @param {string} params.pluginId
* Plugin ID.
* @returns {}
* @example
* bim.app.storyboard.setStack();
*/
setStack: function (params) {
if (!params || params == "") return;
// GET STACK IF EXISTS OR NOT
var stack = __lib.app.storyboard.getStack();
if (!stack || stack == "") {
__lib.app.data.set({
navigation: JSON.stringify([
{
plugin: params.pluginId,
href: window.location.href,
pathname: window.location.pathname,
protocol: window.location.protocol,
port: window.location.port,
origin: window.location.origin,
hostname: window.location.hostname,
},
]),
});
} else {
//
try {
var readStack = JSON.parse(stack);
if (
!__lib.app.storyboard.containsStack(
window.location.pathname,
readStack
)
) {
readStack.push({
plugin: __lib.app.storyboard.current(),
href: window.location.href,
pathname: window.location.pathname,
protocol: window.location.protocol,
port: window.location.port,
origin: window.location.origin,
hostname: window.location.hostname,
});
__lib.app.data.set({ navigation: JSON.stringify(readStack) });
}
} catch (e) {
console.warn("Warning: ", e);
}
}
},
/**
* @description
* Function to set current plugin to localstorage.
* @memberof bim.app.storyboard
* @function setCurrent
* @param {string} params
* <b><i>Required.</i></b>
* Plugin ID.
* @returns {}
* @example
* bim.app.storyboard.setCurrent(${1:pluginID});
*/
setCurrent: function (params) {
if (!params || params == "") return;
window.localStorage.setItem("current", params);
return;
},
/**
* @description
* Function to get current plugin from localstorage.
* @memberof bim.app.storyboard
* @function current
* @returns {string}
* Plugin ID.
* Get item using key "current" from local storage.
*/
current: function () {
return window.localStorage.getItem("current");
},
/**
* @description
* Function to move to next plugin.
* Get plugins data, save current plugin as previous,
* and move to next plugin.
* @memberof bim.app.storyboard
* @function next
* @param {function} callback
* @returns {}
* @example
* bim.app.storyboard.next(${1: callback});
*/
next: function (callback) {
// TODO:
// GET PLUGINS STORYBOARD
bim.app.data.bundle(
{
db: {
name: "storyboard",
table: "plugins",
key: "PLUGINS",
},
},
function (res) {
if (res.error) {
if (typeof callback === "function") return callback(res);
} else {
// SEARCH FOR CURRENT PLUGIN LOADED
// GET CURRENT SCREEN-PLUGIN ON STORYBOARD
if (
__lib.app.storyboard.current() &&
__lib.app.storyboard.current() !== ""
) {
var next;
var plugin_names = Object.keys(res.data);
for (var i = 0; i < plugin_names.length; i++) {
if (next) {
if (
res.data[plugin_names[i]].id &&
res.data[plugin_names[i]].id !== ""
) {
__lib.app.storyboard.setCurrent(
res.data[plugin_names[i]].id
);
__lib.app.storyboard.moveTo({
page: res.data[plugin_names[i]].page,
plugin: plugin_names[i],
});
}
break;
} else if (
res.data[plugin_names[i]].id ==
__lib.app.storyboard.current()
) {
// SET AS PREVIOUS
__lib.app.storyboard.setPrevious(
res.data[plugin_names[i]].id
);
next = true;
}
}
} else {
}
}
}
);
},
/**
* @description
* Function to set previous plugin.
* Set plugin item in local storage using key "previous".
* @memberof bim.app.storyboard
* @function setPrevious
* @param {string} params
* <b><i>Required.</i></b>
*/
setPrevious: function (params) {
if (!params || params == "") return;
window.localStorage.setItem("previous", params);
return;
},
/**
* @description
* Function to get previous plugin.
* Get previous plugin item from local storage using key "previous".
* @memberof bim.app.storyboard
* @function previous
* @returns {string}
* Previous plugin item.
*/
previous: function () {
return window.localStorage.getItem("previous");
},
/**
* @description
* Function to move with data to other plugin.
* Move with data to specific plugin's specific page.
* @memberof bim.app.storyboard
* @param {Object} params Required.
* @param {string} params.page
* <b><i>Required.</i></b>
* Specific page of the plugin wanted to move to.
* @param {Object} params.data Data wanted to be sent.
* @param {boolean} params.reload
* Whether reload or not.
* Sent to the plugin as <code>reloadBimPlugin=true</code>
* @param {string} params.scrollTop Scroll Top
* @param {string} params.animation Animation
* @returns {Object | boolean} Error detail object | <code>false</code> when success
*/
moveTo: function (params) {
if (!params || params == "")
return {
error: true,
message:
"There is no plugin screen to load, verify you added the correct parameters",
};
if (
!params.page ||
params.page == "" ||
typeof params.page !== "string"
)
return {
error: true,
message: "Index page name of plugin is missing {{page}}",
};
var re = /(?:\.([^.]+))?$/;
var ext = re.exec(params.page)[1];
// Prevent params dosent contain specific key
if (params.reload) {
if (!params.data || typeof params.data !== "object") {
params.data = {};
}
params.data.reloadBimPlugin = true;
}
if (params.scrollTop) {
if (!params.data || typeof params.data !== "object") {
params.data = {};
}
params.data.scrollTop = '"' + params.scrollTop + '"';
}
if (params.animation) {
if (!params.data || typeof params.data !== "object") {
params.data = {};
}
params.data.animation = params.animation;
}
if (!ext || ext.trim() !== "html") params.page += ".html";
var bURl = "";
if (
params.data &&
typeof params.data == "object" &&
params.data.key &&
params.data.value
) {
bURl = "?" + params.data.key + "=" + params.data.value;
} else if (
params.data &&
Object.prototype.toString.call(params.data) === "[object Object]"
) {
var keys = Object.keys(params.data);
var urlParts = "";
for (var i = 0; i < keys.length; i++) {
if (
keys[i] &&
keys[i] !== "" &&
params.data[keys[i]] &&
params.data[keys[i]] !== ""
) {
var suffix = "&";
if (i == keys.length - 1) {
suffix = "";
}
urlParts += keys[i] + "=" + params.data[keys[i]] + suffix;
}
}
bURl = "?" + urlParts;
}
if (params.index) {
window.location =
__PLUGINS_DIR__ +
"/" +
params.plugin +
"/" +
params.page +
bURl;
return false;
}
var url = window.location.toString();
url = url.split(window.location.pathname)[0];
var plugins_path = __PLUGINS_DIR__;
plugins_path = plugins_path.replace(".", "");
window.location = `${url}${plugins_path}/${params.plugin}/${params.page}${bURl}`;
return false;
},
/**
* @description
* Function to set "goBack" function in plugin.
*
* Set
* <code>bim.app.storyboard.goBack()</code>
* in plugin.
*
* Rewrites the default {@link bim.app.storyboard.goBack} made.
* @memberof bim.app.storyboard
* @function setGoBack
* @param {function} input
* @example
* bim.app.storyboard.setGoBack(function () {
* // Would be called when native back button pressed
* });
*/
setGoBack: function (input) {
if (input && typeof input == "function") {
__lib.app.storyboard.goBack = input;
}
},
/**
* @description
* Function to reset "goBack" function in plugin.
*
* Reset bim.app.storyboard.goBack() to default status
* It must be same with bim.app.storyboard.goBack()
* @memberof bim.app.storyboard
* @function resetGoBack
* @example
* bim.app.storyboard.resetGoBack();
*/
resetGoBack: function () {
__lib.app.storyboard.goBack = function () {
if (pageNavigator.length > 0 && !disableBackPage) {
bim.app.close.page({ animatePages: true });
return;
}
console.log(
"HTB_NATIVE_LOG",
"bim.app.storyboard.goBack()",
"Move to previous plugin in APP.."
);
};
},
/**
* @description
* Function called directly or indirectly when user goes back.
*
* Run by <code>bim.app.storyboard.goBack();</code> or Android Backbutton.
*
* If page exists, close page with
* <code>bim.app.close.page({ animatePages: true });</code>
*
* If there is no page, go to previous plugin
* @memberof bim.app.storyboard
* @function goBack
* @example
* bim.app.storyboard.goBack();
*/
goBack: function () {
if (pageNavigator.length > 0 && !disableBackPage) {
bim.app.close.page({ animatePages: true });
return;
}
console.log(
"HTB_NATIVE_LOG",
"bim.app.storyboard.goBack()",
"Move to previous plugin in APP.."
);
},
},
/**
* @description
* Funciton to append HTML on document.
* @memberof bim.app
* @function appendHTML
* @argument {string} selector
* Selector, used to find
* parent element, which child would be appended,
* by calling
* <code>document.querySelectorAll(arguments[0]);</code> *
* @argument {DOM} nodes
* Child nodes which would be append to parent.
* @returns {}
* @example
* bim.app.appendHTML(${1:selector}, ${2:nodes})
*/
appendHTML: function appendHTML() {
var this$1;
var content = arguments[1];
if (!arguments[0] || arguments[0].length == 0) return;
this$1 = document.querySelectorAll(arguments[0]);
if (this$1.length == 0) return;
this$1 = this$1[0];
if (!this$1) return;
var args = [];
var nodes =
typeof arguments[1] == "string"
? arguments
: arguments[1].childNodes;
var len = nodes.length;
while (len--) args[len] = nodes[len];
var newChild;
for (var k = 0; k < args.length; k++) {
newChild = args[k];
if (typeof newChild === "string") {
if (__lib.app.isHTML(newChild)) {
var tempDiv = document.createElement("div");
tempDiv.innerHTML = newChild;
while (tempDiv.firstChild) {
this$1.appendChild(tempDiv.firstChild);
}
}
} else {
this$1.appendChild(newChild);
}
}
},
/**
* @description
* Function to check whether the given string parameter is a tag of HTML or not.
* @memberof bim.app
* @function isHTML
* @param {string} html
* @returns {boolean}
* <code>true</code> |
* <code>false</code>
* @example
* if (bim.app.isHTML(${1:html})) ..;
*/
isHTML: function isHTML(html) {
if (!html) return false;
var isHTML = RegExp.prototype.test.bind(/(<([^>]+)>)/i);
if (isHTML(html)) {
return true;
}
return false;
},
/**
* @description
* Function to translate language.
* @memberof bim.app
* @async
* @function translate
* @param {Object} params
* <b><i>Required.</i></b>
* @param {*} params.template
* @param {boolean=} params.detect
* @returns {}
*/
translate: function (params) {
return new Promise(function (rs, rj) {
if (!params || params == "")
return rj({
error: true,
message: "Params are empty",
errno: "js8374bt",
});
var detect = params.detect || params.detect !== "" ? true : false;
async function _run() {
var langObject = await __lib.app.logicless.lang.get({
lang: params.lang,
detect: detect,
});
if (langObject.error) {
return rj(langObject);
}
var tmp = await __lib.app.logicless.tokenizer(params.template);
var ast = await __lib.app.logicless.methods.ast(tmp);
return rs({ error: false, data: "builder" });
}
_run();
});
},
},
/**
* @description
* Function to add event listener to element($) on event type given.
* @memberof bim
* @function event
* @param {Object} params parameters
* @param {string} params.$
* element wanted listener to be added
*
* @param {string} params.on
* Used as event type
*
* @param {function} callback
* The callback binded to the listener (element, event) as params
* @param {boolean} capture
* <code>true</code> | <code>false</code>
*/
event: function (params, callback, capture) {
if (!params.$ || params.$.length == 0) return;
var ev = params.on || params.on !== "" ? params.on : false;
var el = document.querySelector(params.$);
if (!ev || !el) {
// Live event
var e = params.$.trim();
var elType = e.charAt(0);
document.addEventListener(
ev,
function (event) {
var element = event.target;
var found;
if (elType == "#" && element.getAttribute("id")) {
var cl = "#" + element.getAttribute("id").trim();
if (cl === e) {
callback.call(element, event);
}
} else if (elType == ".") {
var matches = [];
if (element.tagName == "IMG") {
matches = element.parentElement
.getAttribute("class")
.trim()
.split(" ");
element = element.parentElement;
} else if (element.getAttribute("class")) {
matches = element.getAttribute("class").trim().split(" ");
}
for (var i = 0; i < matches.length; i++) {
var cl = "." + matches[i].trim();
if (cl === e) {
callback.call(element, event);
}
}
}
},
false
);
} else {
el.addEventListener(params.on, callback);
}
},
/**
* @description
* Returns the first <code>Element</code> within the document
* that matches the specified selector, or group of selectors.
* If no matches are found, <code>null</code> is returned.
* @memberof bim
* @function querySelector
* @param {string} element
* one or more selectors to match. must be a valid CSS selector string.
* @returns {Element}
* Object representing the first element in the document that matches the selectors.
* <code>null</code> is returned if there are no matches.
*/
querySelector: function (element) {
// BYPASS ONLY
return document.querySelector(element);
},
/**
* @description
* Collection of functions that manage plugin.
* Manages the overall life cycle of the plugin,
* such as created, resumed, and destroyed.
* Manages the information of the plugin by offering
* getters and setters.
* @namespace bim.plugin
* @type {Object}
* @property {function} onCreate
* Callback function called when plugin is created.
* See {@link bim.plugin.onCreate} for more details.
*
* @property {function} onResume
* Callback function called when plugin is resumed.
* See {@link bim.plugin.onResume} for more details.
*
* @property {function} onDestroy
* Callback function called when plugin is destroyed.
* See {@link bim.plugin.onDestroy} for more details.
*
* @property {Object} name
* Object to control the name of the plugin.
* See {@link bim.plugin.name} for more details.
*
* @property {Object} token
* Object to control the token of the plugin.
* See {@link bim.plugin.token} for more details.
*
* @property {Object} id
* Object to control the id of the plugin.
* See {@link bim.plugin.id} for more details.
*
* @property {Object} path
* Object saving the location information of the plugin.
* See {@link bim.plugin.path} for more details.
*/
plugin: {
/**
* @description
* Callback function called when plugin is created.
* @memberof bim.plugin
* @function onCreate
* @param {*} params
*/
onCreate: function (params) {},
/**
* @description
* Callback function called when plugin is resumed.
* @memberof bim.plugin
* @function onResume
* @param {*} params
*/
onResume: function (params) {},
/**
* @description
* Callback function called when plugin is destroyed.
* @memberof bim.plugin
* @function onDestroy
* @param {*} params
*/
onDestroy: function (params) {},
/**
* @description
* Manages Plugin Name with private variable.
* Provides getter & setter.
* @memberof bim.plugin
* @name name
* @type {Object}
* @property {function} set
* Set Plugin Name to private variable <code>\_\_name\_\_</code> with parameter passed over.
*
* @property {function} get
* Get Plugin Name from private variable <code>\_\_name\_\_</code>.
*/
name: {
/**
* @description
* Set Plugin Name
* @memberof bim.plugin.name
* @function set
* @param {string} v Required value for plugin name.
* @example
* bim.plugin.name.set(${1:name});
*/
set: function (v) {
if (!v) return;
__name__ = v;
},
/**
* @description
* Get Plugin Name
* @memberof bim.plugin.name
* @function get
* @returns {string} Plugin Name
* @example
* bim.plugin.name.get();
*/
get: function () {
return __name__;
},
},
/**
* @description
* Manage Plugin Token with private variable.
* Provides getter & setter.
* @memberof bim.plugin
* @name token
* @type {Object}
* @property {function} set
* Set Plugin Token to private variable <code>\_\_token\_\_</code>.
*
* Makes an error when reading file "key" fails.
* @property {function} get
* Get Plugin Token from private variable <code>\_\_token\_\_</code>.
*/
token: {
/**
* @memberof bim.plugin.token
* @function set
* @returns {Object} Error report Object when error occurs.
*/
set: function () {
return new Promise(function (rs, rj) {
__lib.readFile({ file: "key" }, function (token) {
if (token.error) {
return rj({
errno: "e83b364",
description:
"Verify key file exists in your Plugin root directory and contains your token key",
});
} else {
__token__ = token.data;
return rs();
}
});
});
},
/**
* @memberof bim.plugin.token
* @function get
* @returns {string} Get token data from private variable.
*/
get: function () {
return __token__;
},
},
/**
* @description
* Manage Plugin ID with private variable.
* Provides getter & setter.
* @memberof bim.plugin
* @name id
* @type {Object}
* @property {function} set
* Set Plugin ID to private variable <code>\_\_pluginId\_\_</code> with parameter passed over.
* @property {function} get
* Get Plugin ID from private variable <code>\_\_pluginId\_\_</code>.
*/
id: {
/**
* @description
* Set Plugin ID to private variable.
* @memberof bim.plugin.id
* @function set
* @param {string} v Plugin ID
*/
set: function (v) {
if (!v) return;
__pluginId__ = v;
},
/**
* @description
* Get Plugin ID from private variable.
* @memberof bim.plugin.id
* @function get
* @returns {string} Plugin ID from private variable.
*/
get: function () {
return __pluginId__;
},
},
/**
* @description
* Object saving the location information of the plugin.
* @memberof bim.plugin
* @name path
* @type {Object}
* @property {string} current <code>window.location.href</code>
* @property {Object} options
* @property {string} options.hash <code>window.location.hash</code>
* @property {string} options.host <code>window.location.host</code>
* @property {string} options.hostname <code>window.location.hostname</code>
* @property {string} options.href <code>window.location.href</code>
* @property {string} options.origin <code>window.location.origin</code>
* @property {string} options.pathname <code>window.location.pathname</code>
* @property {string} options.port <code>window.location.port</code>
* @property {string} options.protocol <code>window.location.protocol</code>
* @property {string} options.search <code>window.location.search</code>
*/
path: (function () {
return {
current: window.location.href,
options: {
hash: window.location.hash,
host: window.location.host,
hostname: window.location.hostname,
href: window.location.href,
origin: window.location.origin,
pathname: window.location.pathname,
port: window.location.port,
protocol: window.location.protocol,
search: window.location.search,
},
};
})(),
},
/**
* @description
* Object which has function to read files related to config.
* @namespace bim.config
* @property {function} plugins_installed
* Function to read and pass data of installed plugins in config file.
* See {@link bim.config.plugins_installed} for more details
*/
config: {
/**
* @description
* Function to read config file and run callback function with read data.
* File must have ".json" extension.
* @function plugins_installed
* @memberof bim.config
* @param {string} file
* File Name of ".json".
* Must be sent without an extension.
* @param {function} callback
* Callback Function.
* Called with below parameter in Object type.
*
* { error: {boolean}, data: {string}, message: {Error} }
* @example
* bim.config.plugins_installed('plugins', function (loaded) {
* if (!loaded.error) {
* try {
* let json = JSON.parse(loaded.data);
* let tempJson = JSON.stringfy(json[0]);
* let keys = Object.keys(json[0]);
*
* // Do Something ...
* } catch (e) {
* // Do Something ...
* }
* } else {
* // Do Something ...
* }
* });
*/
plugins_installed: function (file, callback) {
if (!file) return false;
var request = new XMLHttpRequest();
request.open("GET", file + ".json", true);
request.onload = function () {
if (
(request.status >= 200 && request.status < 400) ||
this.status == 0
) {
var response = {};
response.error = false;
response.data = request.responseText;
return callback(response);
}
};
request.onerror = function (err) {
var response = {};
response.error = true;
response.message = err;
return callback(response);
};
request.send();
},
},
/**
* @description
* Collection of functions which control the App natively.
* @namespace bim.native
* @property {Object} device
* Object which stores the OS of the current device.
* See {@link bim.native.device} for more details.
*
* @property {Object} backButton
* Native backbutton API.
* See {@link bim.native.backButton} for more details.
*
* @property {Object} keyboard
* Native keyboard setting API.
* See {@link bim.native.keyboard} for more details.
*
* @property {function} removeHistory
* Function to remove history of visited plugins.
* See {@link bim.native.removeHistory} for more details.
*
* @property {function} internalBrowser
* Function to open URL with internal browser.
* See {@link bim.native.internalBrowser} for more details.
*
* @property {function} shareUrl
* Function to share url through native feature.
* See {@link bim.native.shareUrl} for more details.
*
* @property {function} loadService
* Function to load service.
* See {@link bim.native.loadService} for more details.
*
* @property {function} exec
* Function to call native functions.
* See {@link bim.native.exec} for more details.
*
* @property {function} cameraChooser
* Function to make file-input to save file data internally.
* See {@link bim.native.cameraChooser} for more details.
*
* @property {function} plugin
* Function to run native functions.
* See {@link bim.native.plugin} for more details.
*
* @property {function} load
* Function to run native functions.
* See {@link bim.native.load} for more details.
*
* @property {function} call
* Function to call native functions.
* See {@link bim.native.call} for more details.
*
* @property {function} handleCallback
* Callback function saved by {@link bim.native.call}.
* See {@link bim.native.handleCallback} for more details.
*
* @property {Object} handleCallbacks
* Object saving callback functions seperated by name.
* See {@link bim.native.handleCallbacks} for more details.
*
* @property {function} callback
* Function to read media file and save into local database.
* See {@link bim.native.callback} for more details.
*
* @property {Object} fileSystem
* Object to manage local files in the device.
* See {@link bim.native.fileSystem} for more details.
*/
native: (function () {
return {
/**
* @description
* Object which stores separately whether OS of the current device matches each iOS or Android.
* @memberof bim.native
* @name device
* @property {boolean} ios
* Whether current device is ios or not
* @property {boolean} android
* Whether current device is android or not
*/
device: (function () {
return {
ios: false,
android: false,
};
})(),
/**
* @description
* Native backbutton API.
* Currently, only works for Android.
* @memberof bim.native
* @name backButton
* @property {function} set
* Function to set how native backbutton works.
* @example
* bim.native.backButton.set({
* backplugin: ${1:backplugin},
* backpage: ${2:backpage},
* backButton: ${3:backButton}
* });
* @example
* bim.native.backButton.set({
* backplugin: MAIN_PLUGIN,
* backpage: true,
* backButton: "enabled"
* });
* @example
* bim.native.backButton.set({
* backpage: false
* });
*/
backButton: {
/**
* @description
* Function to set how native backbutton works.
* @memberof bim.native.backButton
* @function set
* @param {Object} params
* <b><i>Required.</i></b>
* @param {string} params.backplugin
* @param {boolean} params.backpage
* Value, which would be the value of
* private variable <code>disableBackPage</code>
* @param {boolean | string} params.backButton
* <code>true</code>, <code>false</code> |
* "disable", "disabled", "enable", "enabled"
*/
set: function (params) {
if (!params || params == "") return;
let data = {};
if (params.hasOwnProperty("backplugin"))
data.backplugin = params.backplugin;
if (params.hasOwnProperty("backpage"))
disableBackPage = !params.backpage;
switch (params.backButton) {
case false:
case "disable":
case "disabled":
data.set = "disable";
break;
case true:
case "enable":
case "enabled":
data.set = "enable";
break;
}
console.log(
"HTB_NATIVE_LOG",
"bim.native.backButton.set()",
"Android backbutton setting : ",
params
);
return;
},
},
/**
* @description
* Native keyboard setting API.
* Currently, only works for Android OS now.
* @memberof bim.native
* @name keyboard
*
* @property {function} set
* Function to set callback function, which runs
* when native keyboard is opened or closed.
* Currently only works for Android OS now.
*
* @property {function} onOpen
* Callback function which runs when keyboard is opened.
* Must be set through function
* <code>bim.native.keyboard.set</code>.
*
* @property {function} onClose
* Callback function which runs when keyboard is closed.
* Must be set through function
* <code>bim.native.keyboard.set</code>.
*
* @example
* bim.native.keyboard.set({
* onOpen: function () {
* // Do Something ...
* },
* onClose: function () {
* // Do Something ...
* }
* });
*/
keyboard: {
/**
* @description
* Function to set callback function, which runs
* when native keyboard is opened or closed.
* Currently only works for Android OS now.
* @memberof bim.natvie.keyboard
* @function set
* @param {Object} params
* @param {function} params.onOpen
* Callback function which runs when keyboard is opened.
* @param {function} params.onClose
* Callback function which runs when keyboard is closed.
* @returns {}
*/
set: function (params) {
console.log(
"HTB_NATIVE_LOG",
"bim.native.keyboard.set(params)",
"Keyboard Open & Close callback is set for App .."
);
},
/**
* @description
* Callback function which runs when keyboard is opened.
* Must be set through function
* <code>bim.native.keyboard.set</code>.
* @memberof bim.natvie.keyboard
* @function onOpen
* @param {*} params
*/
onOpen: function (params) {},
/**
* @description
* Callback function which runs when keyboard is closed.
* Must be set through function
* <code>bim.native.keyboard.set</code>.
* @memberof bim.natvie.keyboard
* @function onClose
* @param {*} params
*/
onClose: function (params) {},
},
/**
* @description
* Function to remove history of visited plugins
* and reload whole plugins except current plugin.
*
* Currently only works for Android OS now.
*
* :: PROBLEM ::
*
* HARD TO USE WITH
* {@link bim.app.storyboard.moveTo},
* DUE TO SYNC PROBLEM.
*
* RECOMMENDED TO USE AFTER
* {@link bim.app.storyboard.moveTo},
* NOT BEFORE.
* @memberof bim.native
* @function removeHistory
* @returns {}
* @example
* bim.native.removeHistory();
*/
removeHistory: function () {
console.log(
"HTB_NATIVE_LOG",
"bim.native.removeHistory()",
"Remove history of visited plugin in App .."
);
},
/**
* @description
* Function to open URL with internal browser.
* Currently only works for Android OS now.
* @memberof bim.native
* @function internalBrowser
* @param {string} url
* <b><i>Required.</i></b>
* @returns {Object | void}
* if url is empty,
* returns error object with errno, message, description. |
* void
* @example
* bim.native.internalBrowser(${1:url});
*/
internalBrowser: function (url) {
if (!url || url == "" || typeof url !== "string")
return {
error: true,
errno: "031623b",
message: "No url found",
description: "To use internalBrowser, url value is necessary",
};
console.log(
"HTB_NATIVE_LOG",
"bim.native.internalBrowser(url)",
`${url} is opened in new view in APP ..`
);
},
/**
* @description
* Function to share url through native feature.
* Currently only works for Android OS now.
* @memberof bim.native
* @function shareUrl
* @param {string} url
* <b><i>Required.</i></b>
* @returns {Object | void}
* if url is empty, returns error object with errno, message, description.
* @example
* bim.native.shareUrl(${1:url});
*/
shareUrl: function (url) {
if (!url || url == "" || typeof url !== "string")
return {
error: true,
errno: "071622b",
message: "No url found",
description:
"To use a share function, it is necessary to add an url",
};
console.log(
"HTB_NATIVE_LOG",
"bim.native.shareUrl(url)",
`${url} is shared in APP ..`
);
},
/**
* @description
* Function to load service.
* Used in bundle.js in APP.
* Currently only works for Android now.
* @memberof bim.native
* @function loadService
* @param {Object} params
* <b><i>Required.</i></b>
* @returns {Object | void}
* if params is empty, returns error object with errno, message, description.
*/
loadService: function (params) {
if (!params || params == "") {
console.error({
error: true,
errno: "eO072bx3",
description:
"Parameters cannot be empty, read the documentation to know more about",
message:
"Oops! Something went wrong implementing native plugin",
});
}
},
/**
* @description
* Function to call native functions.
* Currently, only works for Android OS now.
* @memberof bim.native
* @function exec
* @param {Object} params
* <b><i>Required.</i></b>
* @param {string} params.hardware
* @param {string} params.event
* Custom parameters for a native function
* @param {string} params.fn
* The name of callback function
* @param {string} params.callback
* @param {Object | string} params.data
* @returns {}
* @example
* bim.native.exec({
* hardware: 'gallery',
* event: 'event_name',
* fn: 'my_callback_function_name',
* data: 'my_data'
* });
*/
exec: function (params) {},
/**
* @description
* Function to make file-input and
* save data to internal database of the App.
* Used in AnimalZ - post feature in App.
* @memberof bim.native
* @function cameraChooser
* @param {Object=} params
*/
cameraChooser: function (params) {},
/**
* @description
* Function to run native functions.
* Currently only works for Android OS now.
* @memberof bim.native
* @function plugin
* @param {Object} params
* <b><i>Required.</i></b>
* @example
* bim.native.plugin(${1:params});
*/
plugin: function (params) {},
/**
* @description
* Function to run native functions.
* Currently only works for Android OS now.
* @memberof bim.native
* @function load
* @param {Object} params
* <b><i>Required.</i></b>
* @example
* bim.native.load(${1:params});
*/
load: function (params) {},
/**
* @description
* Function to call native functions.
* Sets {@link bim.native.handleCallback} and
* {@link bim.native.handleCallbacks}
* with this function.
* @memberof bim.native
* @function call
* @param {Object} params
* <b><i>Required.</i></b>
* @param {string} params.name
* @param {string} params.method
* @param {function} params.callback
* @param {Object} params.params
* @example
* bim.native.call({
* 'name': ${1:name},
* 'method': ${2:method},
* 'callback': ${3:callback},
* 'params': ${4:params}
* });
* @example
* bim.native.call({
* 'name': 'Login',
* 'method': 'kakaoLogin',
* 'callback': () => {
* // Do Something ...
* },
* 'params': null
* });
*/
call: function (params) {},
/**
* @description
* Callback function saved by {@link bim.native.call}.
* Used in native source codes.
* @memberof bim.native
* @function handleCallback
*/
handleCallback: function () {},
/**
* @description
* Object saving callback functions seperated by name.
* Values are set by {@link bim.native.call}.
* @memberof bim.native
* @name handleCallbacks
* @type {Object}
*/
handleCallbacks: {},
/**
* @description
* Function to read media file and save into local database.
* This method runs in native source camera feature.
* @memberof bim.native
* @function callback
* @param {string} data
* <b><i>Required.</i></b>
* Stringfied data. Would be used after
* <code>JSON.parse(data);</code>
* @param {string} data.source
* File full path url.
* @param {string} data.type
* Type of the file. Should be in ["image", "video"]
* @param {string} data.page
* The page to go to after all the work is done.
* @param {string} data.plugin
* The plugin to go to after all the work is done.
* @returns {}
*/
callback: function (data) {},
/**
* @description
* Object to manage local files in the device.
* @memberof bim.native
* @name fileSystem
* @type {Object}
* @property {function} read
* Function to read.
*
* @property {function} readByPath
* Function to read file from device by file path.
*
* @property {function} get
* Function to get recently read file data.
*
* @property {function} reset
* Function to remove reserved read file data.
*/
fileSystem: {
/**
* @description
* Open file chooser in native
* @memberof bim.native.fileSystem
* @function read
*/
read: function () {
// 1. OPEN FILE CHOOSER IN NATIVE
// 2. AND RUN BELOW readByPath METHOD AND READ THAT FILE IN JS!
console.log(
"Run File Selector in Native And read that file in JS!"
);
},
/**
* @description
* Function to read file from device by file path.
* @memberof bim.native.fileSystem
* @function readByPath
* @async
* @param {string} params
* <b><i>Required.</i></b>
* Stringfied JSON Object
* @param params.db USE DB TABLE NAME, IF NULL, USE "Htb_FileSystem"
* @param params.path FILE PATH ARRAY
*/
readByPath: async function (params, callback) {
// IF THIS IS NOT CALLBACK, ADD DEFAULT CALLBACK
if (!callback || typeof callback != "function")
callback = function (err, data) {
if (err) return console.error(err);
};
let parsedParams; // parsed params
let data; // urlData
let IDBName; // IDB name
try {
parsedParams = JSON.parse(params);
IDBName = parsedParams.db ? parsedParams.db : "Htb_FileSystem";
data = parsedParams.path ? parsedParams.path : false;
} catch (e) {
return callback({
error: true,
errno: "e492416",
message: "Failed to send JSON data",
});
}
if (!data)
return callback({
error: true,
errno: "e192416",
message: "Failed to get filepath data",
});
let fileContainer = [];
for (let i = 0; i < data.length; i++) {
try {
let file = await fileReadRequest(data[i]);
fileContainer.push(file);
} catch (e) {
return callback(e);
}
}
let IDB_params = {
delete: {
db: {
name: IDBName,
table: "resources",
key: "files",
},
},
create: {
db: {
name: IDBName,
table: "resources",
columns: ["data"],
keyPath: "config",
},
},
addtable: {
db: {
table: "newOne",
name: IDBName,
version: 0, // res1.version,
keyPath: "config",
columns: ["data"],
},
},
addFile: {
db: {
name: IDBName,
table: "resources",
item: fileContainer, // File
keyPath: {
name: "config",
value: "files",
},
},
},
};
bim.app.data.db.create(IDB_params.create, function (res1) {
bim.app.data.db.deleteFile(IDB_params.delete, function (res2) {
if (res2 && res2.length == 0) {
IDB_params.addtable.db.version = res2.version + 1;
bim.app.data.db.addTable(
IDB_params.addtable,
function (res3) {
addFileIDB();
}
);
} else {
addFileIDB();
}
});
});
function fileReadRequest(fileurl) {
return new Promise(function (rs, rj) {
let request = new XMLHttpRequest();
let filePath = "file://" + fileurl;
let filename = fileurl.split("/").pop();
request.responseType = "arraybuffer";
request.open("GET", filePath, true);
request.onload = function () {
let blob = new Blob([request.response]);
let file = new File([blob], filename);
return rs(file);
};
request.onerror = function (err) {
return rj({
error: true,
errno: "e292811",
message: "Failed to read file in device",
});
};
request.send();
});
}
function addFileIDB() {
bim.app.data.db.addFile(IDB_params.addFile, function (res4) {
if (res4.error) {
return callback({
error: true,
errno: "e292819",
message: "Failed to save readed files in memory",
});
}
return callback(false, fileContainer);
});
}
},
/**
* @description
* Function to get recently read file data.
* Can share files by this method in every plugin in the app.
*
* Calls internally,
*
* <code>bim.app.data.db.read</code>.
* @memberof bim.native.fileSystem
* @function get
* @async
* @param {Object} params
* <b><i>Required.</i></b>
* @param {string} params.db
* <b><i>Required.</i></b>
* Would be used as
* <code>db.name</code>
* for parameter of
* <code>bim.app.data.db.read</code>
* @param {function} callback
* <b><i>Required.</i></b>
* argument 1 : {boolean} Error Y/N
* argument 2 : {Object} Read file data
* @returns {*}
* Result of callback function.
*/
get: async function (params, callback) {
if (!callback || typeof callback != "function")
return console.warn({
error: true,
errno: "e824219",
message: "Use this method with callback",
});
let IDBName = params && params.db ? params.db : "Htb_FileSystem";
if (!IDBName || IDBName == "")
return console.warn({
error: true,
errno: "e2824219",
message: "db name must be not empty string",
});
try {
let filesData = await readDB();
return callback(false, filesData);
} catch (e) {
return callback(e);
}
async function readDB() {
return new Promise(function (rs, rj) {
let IDB_ReadParam = {
db: {
name: IDBName,
table: "resources",
key: "files",
},
};
bim.app.data.db.read(IDB_ReadParam, function (res) {
if (res.error)
return rj({
error: true,
errno: "e192819",
message: "Failed to get reserved file data",
});
return rs(res.data);
});
});
}
},
/**
* @description
* Function to remove reserved read file data.
*
* Calls internally,
*
* <code>bim.app.data.db.deleteFile</code>
* @memberof bim.native.fileSystem
* @function reset
* @param {Object} params
* <b><i>Required.</i></b>
* @param {string} params.db
* <b><i>Required.</i></b>
* @returns {} void
*/
reset: function (params) {
let IDBName = params && params.db ? params.db : "Htb_FileSystem";
if (!IDBName || IDBName == "")
return console.warn({
error: true,
errno: "e1824219",
message: "db name must be not empty string",
});
let IDB_DeleteParam = {
db: {
name: IDBName,
table: "resources",
key: "files",
},
};
bim.app.data.db.deleteFile(IDB_DeleteParam, function (res) {
if (res.error) {
return console.error("Failed to reset read file");
} else {
console.log("File data deleted successfully!");
}
});
},
},
};
})(),
/**
* @description
* An Object which is a collection of functions that manage components.
* The component currently has "tabbar" only.
* @namespace bim.component
* @property {function} hide
* Function to hide component.
* See {@link bim.component.hide} for more details.
*
* @property {function} show
* Function to show component.
* See {@link bim.component.show} for more details.
*
* @property {function} active
* Function to activate component.
* See {@link bim.component.active} for more details.
*
* @property {function} set
* Function to set component.
* See {@link bim.component.set} for more details.
*
* @property {function} build
* Function to build component.
* See {@link bim.component.build} for more details
*/
component: {
/**
* @description
* Function to hide component.
* Currently, only "tabbar" is supported.
* Defaultly sets the animation delay to
* <code>500</code> ms.
* @memberof bim.component
* @function hide
* @param {Object} params
* <b><i>Required.</i></b>
* @param {string} params.type
* Currently, only "tabbar" is supported.
* @param {number} [params.delay=500]
* Delay of the animation.
* @returns {}
* @example
* bim.component.hide({type: "tabbar", delay: 300});
*/
hide: function (params) {
if (!params || params == "") return;
if (params.type == "tabbar") {
if (!params.delay) params.delay = 500;
console.log(
"HTB_NATIVE_LOG",
"bim.component.hide()",
`${params.type} is hidden ..`
);
}
},
/**
* @description
* Function to show component.
* Currently, only "tabbar" is supported.
* @memberof bim.component
* @function show
* @param {Object} params
* <b><i>Required.</i></b>
* @param {string} params.type
* Currently, only "tabbar" is supported.
* @returns {}
* @example
* bim.component.show({type: "tabbar"});
*/
show: function (params) {
if (!params || params == "") return;
if (params.type == "tabbar") {
console.log(
"HTB_NATIVE_LOG",
"bim.component.show()",
`${params.type} is opened ..`
);
}
},
/**
* @description
* Function to activate component.
* Currently, only "tabbar" is supported.
* @memberof bim.component
* @function active
* @param {Object} params
* <b><i>Required.</i></b>
* @param {string} params.type
* Currently, only "tabbar" is supported.
* @returns {}
* @example
* bim.component.active({type: "tabbar"});
*/
active: function (params) {
if (!params || params == "") return;
if (params.type == "tabbar") {
if (bim.native.device.android) {
window.native.activeTabbar(JSON.stringify(params));
} else if (bim.native.device.ios) {
window.webkit.messageHandlers.activeTabbar.postMessage(
JSON.stringify(params)
);
}
}
},
/**
* @description
* Function to set component.
* @memberof bim.component
* @function set
* @param {Object} params
* <b><i>Required.</i></b>
* @param {*} params.type
* <b><i>Required.</i></b>
* @param {*} params.id
* <b><i>Required.</i></b>
* @param {*} params.css
* <b><i>Required.</i></b>
* @param {*} params.js
* <b><i>Required.</i></b>
* @param {*} params.assets
* <b><i>Required.</i></b>
* @param {*} params.level
* <b><i>Required.</i></b>
* @param {*} params.body
* <b><i>Required.</i></b>
* @returns {}
* @example
* const bimComponent = {
* type: "tabbar",
* id: ${1:id},
* css: ${2:css},
* js: ${3:js},
* assets: ${4:assets},
* level: ${5:level},
* body: ${6:body},
* };
* bim.component.set(bimComponent);
*/
set: function (params) {
if (!params || params == "" || typeof params !== "object") return;
if (
!params.type ||
!params.id ||
!params.css ||
!params.js ||
!params.assets ||
!params.level ||
!params.body
)
return console.error(
"bimDB: Err-72M Some required parameters are missing"
);
console.log(
"HTB_NATIVE_LOG",
"bim.component.set()",
`${params.type} is set ..`
);
},
/**
* @description
* Function to build component.
* Currently, only "Android" is supported.
* Currently, only "tabbar" is supported.
* @memberof bim.component
* @function build
* @param {Object} params
* @param {string} params.type
* Currently, only "tabbar" is supported.
* @deprecated
* It is same with {@link bim.component.show}
* @example
* bim.component.build({type: "tabbar"});
*/
build: function (params) {
console.log(
"HTB_NATIVE_LOG",
"bim.component.build()",
`${params.type} is built ..`
);
},
},
/**
* @description
* Function to read the given file path and call the given function back with
* the read file as data property.
* @memberof bim
* @function readFile
* @param {Object} params
* @param {string} params.file
* Path of the file
* @param {string} params.onErrorMessage
* error message which would be sent to callback
* as parameter message when error occurs
* @param {function} callback
* @returns {*}
* result got from the callback function
*/
readFile: function (params, callback) {
if (!params || !params.file || params.file == "")
return callback({
error: true,
message: "File path cannot be empty",
errno: "83v363v4555",
});
var request = new XMLHttpRequest();
request.open("GET", params.file, true);
request.onload = function () {
if (
(request.status >= 200 && request.status < 400) ||
this.status == 0
) {
return callback({ error: false, data: request.responseText });
} else {
return callback({
error: true,
message: params.onErrorMessage,
errno: "934b45645v45",
});
}
};
request.onerror = function (err) {
return callback({
error: true,
message: params.onErrorMessage,
description: err,
errno: "84b65ba74",
});
};
request.send();
},
/**
* @description
* Collection of Objects to control elements of the document.
* Currently, only has
* <code>bim.crawling.inject.css.apply</code>
* @namespace bim.crawling
* @type {Object}
* @property {Object} inject
* Collection of Objects to inject elements to the document.
* See {@link bim.crawling.inject} for more details
*/
crawling: {
/**
* @description
* Collection of Objects to inject elements to the document.
* @memberof bim.crawling
* @name inject
* @type {Object}
* @property {Object} css
* Set of functions that create or manage style elements to inject into the document.
* @property {function} css.apply
* Function to create style element and append to head of document.
*/
inject: {
/**
* @description
* Set of functions that create or manage
* style elements to inject into the document.
* @memberof bim.crawling.inject
* @name css
* @type {Object}
*/
css: {
/**
* @description
* Function to create style element and append to head of document.
*
* Used in
* <code>bim.app.init</code>
* @memberof bim.crawling.inject.css
* @function apply
* @param {string} css
* Required.
*/
apply: function (css) {
if (!css || css == "") return;
var styleSheet = document.createElement("style");
styleSheet.type = "text/css";
styleSheet.innerText = css;
document.head.appendChild(styleSheet);
},
},
},
},
/**
* @description
* General static functions which can be called with <code>bim.functions</code>
* @namespace bim.functions
* @property {function} isHTML
* Function to check whether the given string parameter is a tag of HTML or not.
* See {@link bim.functions.isHTML} for more details.
*
* @property {function} parse
* Function to parse to JSON.
* See {@link bim.functions.parse} for more details.
*
* @property {function} text
* Function to randomly generate alphabetical string with given parameter number.
* See {@link bim.functions.text} for more details.
*
* @property {function} unique
* Function to remove duplicated values from an Array.
* See {@link bim.functions.unique} for more details.
*/
functions: {
/**
* @description
* Function to check whether the given string parameter is
* a valid tag of HTML or not.
* @memberof bim.functions
* @function isHTML
* @param {string} html
* <b><i>Required.</i></b>
* String to verify that it is a valid HTML tag.
* @returns {boolean}
* <code>true</code> | <code>false</code>
* @example
* if (bim.functions.isHTML(${1:html})) ..;
* @example
* let bimHtml = "<p>Hello Bim~</p>";
*
* if (bim.functions.isHTML(bimHtml)) {
* bim.app.element("#bimElement").append(bimHtml);
* }
*/
isHTML: function (html) {
if (!html) return false;
var isHTML = RegExp.prototype.test.bind(/(<([^>]+)>)/i);
if (isHTML(html)) {
return true;
}
return false;
},
/**
* @description
* Function that firstly parses the given parameter to JSON,
* secondly calls the callback function and returns the result.
* @memberof bim.functions
* @function parse
* @param {*} j Object expected to be parsed into JSON
* @param {function} callback function
* @returns {*} callback({boolean}, {parsedObject})
* @example bim.functions.parse(${1:parameter}, ${2:callback})
*/
parse: function (j, callback) {
var messageObject;
try {
messageObject = JSON.parse(j);
} catch (e) {
if (typeof callback == "function") return callback(true, e);
}
if (typeof callback == "function")
return callback(false, messageObject);
},
/**
* @description
* Randomly generates alphabetical string with given parameter number
* @memberof bim.functions
* @function text
* @param {number} [n = 16] length of the text
* @returns {string} randomlly generated text string
* @example bim.functions.text(${1:number})
*/
text: function (n) {
if (typeof n !== "number") {
n = 16;
}
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for (var i = 0; i < n; i++) {
text += possible.charAt(
Math.floor(Math.random() * possible.length)
);
}
return text;
},
/**
* @description
* Function that returns new Array duplicated values removed.
* @memberof bim.functions
* @function unique
* @param {Array} arr Array
* @returns {Array} New Array duplicated valued removed
*/
unique: function (arr) {
var uniqueArray = [];
for (var i = 0; i < arr.length; i += 1) {
if (uniqueArray.indexOf(arr[i]) === -1) {
uniqueArray.push(arr[i]);
}
}
return uniqueArray;
},
},
};
})();
const require = (function () {
var __parent_module;
var root = "project/app";
var bimsPath = "bims";
return {
package: (function () {
return {
json: function (params) {
var a = new XMLHttpRequest();
a.open("GET", params.package, 0);
a.send();
if (X.status && X.status !== 200) {
return { error: true, description: a.responseText };
} else {
return { error: false, data: a.responseText };
}
},
};
})(),
modulePath: function (params) {
return `./${root}/${bimsPath}/${params.module}`;
},
load: function () {
var moduledev = arguments[0];
var params = arguments[1];
if (!moduledev || moduledev == "") return;
if (!w.require.cache) w.require.cache = [];
var url =
moduledev.indexOf("./") > -1
? moduledev
: require.modulePath({ module: moduledev }) + "/index.js";
let __dirname =
moduledev.indexOf("./") > -1
? url
: url.substring(0, url.lastIndexOf("/"));
var a = new XMLHttpRequest();
var ext = moduledev.split(".").pop();
if (ext === "json") {
if (typeof __Main_Module__ !== "undefined") {
moduledev =
require.modulePath({ module: __Main_Module__ }) +
"/" +
moduledev.replace("./", "");
}
a.open("GET", moduledev, 0);
a.send();
if (a.status && a.status !== 200) {
console.error({
error: true,
description: a.statusText,
message: "File not found",
});
} else {
try {
var source = a.responseText;
return JSON.parse(source);
} catch (e) {
return {
error: true,
description: e,
message: "Verify if json file is correct",
};
}
}
} else {
// TODO: ADD TRACKING MODULES SEQUENCE
var exports = w.require.cache[moduledev];
if (!exports) {
exports = {};
a.open("GET", url, 0);
a.send();
if (a.status && a.status !== 200) {
console.error({
error: true,
description: a.statusText,
message: "Verify the bim module is correctly installed",
});
} else {
var isMain = false;
var isCmmn = "";
if (typeof __Main_Module__ == "undefined") {
isMain = moduledev;
isCmmn = "window.__Main_Module__ = module.main";
}
var source = a.responseText;
if (source.substr(0, 10) === "(function(") {
var moduleStart = source.indexOf("{");
var moduleEnd = source.lastIndexOf("})");
var CDTcomment = source.indexOf("//@ ");
if (CDTcomment > -1 && CDTcomment < moduleStart + 6)
moduleStart = source.indexOf("\n", CDTcomment);
source = source.slice(moduleStart + 1, moduleEnd - 1);
}
var module = {
id: url,
uri: url,
exports: exports,
main: isMain,
parent_module: __parent_module,
};
source =
"//@ sourceURL=" + window.location.origin + url + "\n" + source;
var __module = new Function(
"require",
"exports",
"module",
"__dirname",
source + isCmmn
);
__module(require.load, exports, module, __dirname);
w.require.cache[moduledev] = exports = module.exports;
__parent_module = moduledev;
}
}
return exports;
}
},
};
})();
w.require = require.load;
w.bim = __lib;
})(window);