diff --git a/build/iui.js b/build/iui.js index e940907..5597bda 100644 --- a/build/iui.js +++ b/build/iui.js @@ -5784,9 +5784,8 @@ var _default = _IUI.IUI.module( /*#__PURE__*/function (_IUIElement) { window.router.on("route", function (e) { self.textContent = ''; // clear everything - var html = ""; - var route = e.route; - var current = document.createElement("div"); + let route = e.route; + let current = document.createElement("div"); current.innerHTML = route.caption; self.append(current); diff --git a/package.json b/package.json index a5c8351..0b247bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@esiur/iui", - "version": "1.1.2", + "version": "1.1.3", "description": "Interactive User Interface", "main": "iui.js", "type": "module", diff --git a/src/Core/App.js b/src/Core/App.js index 2149881..0842707 100644 --- a/src/Core/App.js +++ b/src/Core/App.js @@ -2,29 +2,28 @@ import { IUI } from "../Core/IUI.js"; import RefsCollection from "./RefsCollection.js"; -export default IUI.module(class App extends IUIElement { +export default IUI.module( + class App extends IUIElement { constructor() { - super(); - this.refs = new RefsCollection(this); + super(); + this.refs = new RefsCollection(this); } create() { - this._register("load"); - window.app = this; + this._register("load"); + window.app = this; } - created() { + IUI.bind(this, this, "/", { app: this, refs: this.refs }); - IUI.bind(this, this, "/", {app: this, refs: this.refs}); + // update referencing + this.refs._build(); - // update referencing - this.refs._build(); - - //IUIElement._make_bindings(this); - this.render(); - this._emit("load", { app: this }); - this.loaded = true; + //IUIElement._make_bindings(this); + this.render(); + this._emit("load", { app: this }); + this.loaded = true; } - -}); \ No newline at end of file + } +); diff --git a/src/Core/Binding.js b/src/Core/Binding.js index 64c4dc7..1f17752 100644 --- a/src/Core/Binding.js +++ b/src/Core/Binding.js @@ -2,382 +2,357 @@ import { IUI } from "./IUI.js"; export const BindingType = { - IUIElement: 0, // this will never happen ! - TextNode: 1, - ContentAttribute: 2, - Attribute: 3, - HTMLElementDataAttribute: 4, - IUIElementDataAttribute: 5, - IfAttribute: 6, - RevertAttribute: 7 + IUIElement: 0, // this will never happen ! + TextNode: 1, + ContentAttribute: 2, + Attribute: 3, + HTMLElementDataAttribute: 4, + IUIElementDataAttribute: 5, + IfAttribute: 6, + RevertAttribute: 7, }; export const AttributeBindingDestination = { - Field: 0, - Attribute: 1 + Field: 0, + Attribute: 1, }; -const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor; +const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor; export class Binding { - static create(nodeOrAttributeOrIUIElement, scope) { - var code, isAsync, type, attrType, attrKey, func, script; + static create(nodeOrAttributeOrIUIElement, scope) { + var code, isAsync, type, attrType, attrKey, func, script; - //if (nodeOrAttributeOrIUIElement.created) - // debugger; + //if (nodeOrAttributeOrIUIElement.created) + // debugger; - if (nodeOrAttributeOrIUIElement instanceof IUIElement) { - isAsync = nodeOrAttributeOrIUIElement.hasAttribute("async"); - type = BindingType.IUIElement; - } else if (nodeOrAttributeOrIUIElement instanceof Text) {// nodeOrAttribute.nodeType == 3) { - if (!nodeOrAttributeOrIUIElement.wholeText.match(/\${.*}/)) - return null; - type = BindingType.TextNode; - isAsync = nodeOrAttributeOrIUIElement.parentElement.hasAttribute("async"); - //code = "return `" + nodeOrAttributeOrIUIElement.wholeText + "`;"; + if (nodeOrAttributeOrIUIElement instanceof IUIElement) { + isAsync = nodeOrAttributeOrIUIElement.hasAttribute("async"); + type = BindingType.IUIElement; + } else if (nodeOrAttributeOrIUIElement instanceof Text) { + // nodeOrAttribute.nodeType == 3) { + if (!nodeOrAttributeOrIUIElement.wholeText.match(/\${.*}/)) return null; + type = BindingType.TextNode; + isAsync = nodeOrAttributeOrIUIElement.parentElement.hasAttribute("async"); + //code = "return `" + nodeOrAttributeOrIUIElement.wholeText + "`;"; - script = nodeOrAttributeOrIUIElement.wholeText; - - code = `try {\r\n context.value = \`${script}\`\r\n}\r\n catch(ex) { context.error = ex; }` + script = nodeOrAttributeOrIUIElement.wholeText; - - nodeOrAttributeOrIUIElement.data = ""; - nodeOrAttributeOrIUIElement.created = true; - } else if (nodeOrAttributeOrIUIElement instanceof Attr) { + code = `try {\r\n context.value = \`${script}\`\r\n}\r\n catch(ex) { context.error = ex; }`; - if (nodeOrAttributeOrIUIElement.name.startsWith("async::")) { - isAsync = true; - attrType = AttributeBindingDestination.Attribute; - attrKey = nodeOrAttributeOrIUIElement.name.substr(7); - } - else if (nodeOrAttributeOrIUIElement.name.startsWith("::")) { - isAsync = false; - attrType = AttributeBindingDestination.Attribute; - attrKey = nodeOrAttributeOrIUIElement.name.substr(2); - } - else if (nodeOrAttributeOrIUIElement.name.startsWith("async:")) { - isAsync = true; - attrType = AttributeBindingDestination.Field; - attrKey = nodeOrAttributeOrIUIElement.name.substr(6); + nodeOrAttributeOrIUIElement.data = ""; + nodeOrAttributeOrIUIElement.created = true; + } else if (nodeOrAttributeOrIUIElement instanceof Attr) { + if (nodeOrAttributeOrIUIElement.name.startsWith("async::")) { + isAsync = true; + attrType = AttributeBindingDestination.Attribute; + attrKey = nodeOrAttributeOrIUIElement.name.substr(7); + } else if (nodeOrAttributeOrIUIElement.name.startsWith("::")) { + isAsync = false; + attrType = AttributeBindingDestination.Attribute; + attrKey = nodeOrAttributeOrIUIElement.name.substr(2); + } else if (nodeOrAttributeOrIUIElement.name.startsWith("async:")) { + isAsync = true; + attrType = AttributeBindingDestination.Field; + attrKey = nodeOrAttributeOrIUIElement.name.substr(6); - // skip scope - // if (attrKey == "scope") - // return null; - } - else if (nodeOrAttributeOrIUIElement.name.startsWith(":")) { - isAsync = false; - attrType = AttributeBindingDestination.Field; - attrKey = nodeOrAttributeOrIUIElement.name.substr(1); + // skip scope + // if (attrKey == "scope") + // return null; + } else if (nodeOrAttributeOrIUIElement.name.startsWith(":")) { + isAsync = false; + attrType = AttributeBindingDestination.Field; + attrKey = nodeOrAttributeOrIUIElement.name.substr(1); - // skip scope - // if (attrKey == "scope") - // return null; - } - else { - return null; - } + // skip scope + // if (attrKey == "scope") + // return null; + } else { + return null; + } - // isAsync = nodeOrAttributeOrIUIElement.value.search("await"); + // isAsync = nodeOrAttributeOrIUIElement.value.search("await"); -// code = "return " + nodeOrAttributeOrIUIElement.value + ";"; + // code = "return " + nodeOrAttributeOrIUIElement.value + ";"; - script = nodeOrAttributeOrIUIElement.value - code = `try {\r\n context.value = ${script}; \r\n}\r\n catch(ex) { context.error = ex; }` + script = nodeOrAttributeOrIUIElement.value; + code = `try {\r\n context.value = ${script}; \r\n}\r\n catch(ex) { context.error = ex; }`; - let sentence = attrKey.split("-"); - for (var i = 1; i < sentence.length; i++) - sentence[i] = sentence[i].charAt(0).toUpperCase() + sentence[i].slice(1); - attrKey = sentence.join(""); + let sentence = attrKey.split("-"); + for (var i = 1; i < sentence.length; i++) + sentence[i] = + sentence[i].charAt(0).toUpperCase() + sentence[i].slice(1); + attrKey = sentence.join(""); - if (attrKey == "content") - type = BindingType.ContentAttribute; - else if (attrKey == "if") { - type = BindingType.IfAttribute; - //displayMode = - } - else if (attrKey == "revert") - type = BindingType.RevertAttribute; - else if (attrKey != "data") - type = BindingType.Attribute; - else if (nodeOrAttributeOrIUIElement.ownerElement instanceof IUIElement) - type = BindingType.IUIElementDataAttribute; - else - type = BindingType.HTMLElementDataAttribute; + if (attrKey == "content") type = BindingType.ContentAttribute; + else if (attrKey == "if") { + type = BindingType.IfAttribute; + //displayMode = + } else if (attrKey == "revert") type = BindingType.RevertAttribute; + else if (attrKey != "data") type = BindingType.Attribute; + else if (nodeOrAttributeOrIUIElement.ownerElement instanceof IUIElement) + type = BindingType.IUIElementDataAttribute; + else type = BindingType.HTMLElementDataAttribute; + } + + // test the function + + let scopeKeys = Object.keys(scope); + let scopeValues = Object.values(scope); + + try { + let args = ["data", "d", "context", "_test", ...scopeKeys]; + + if (isAsync) func = new AsyncFunction(...args, code); + else func = new Function(...args, code); + } catch (ex) { + console.log("Test failed: " + ex, code); + return null; + } + + let rt = new Binding(); + Object.assign(rt, { + isAsync, + type, + attrType, + attrKey, + func, + target: nodeOrAttributeOrIUIElement, + checked: false, + script, + scopeKeys, + scopeValues, + }); + return rt; + } + + constructor() { + this.watchList = []; + let self = this; + this.listener = function (name, value) { + self.render(self.data); + }; + } + + _findMap(thisArg) { + // @TODO: Map thisArg too + let map = {}; + + let detector = { + get: function (obj, prop) { + if (typeof prop == "string") { + obj[prop] = {}; + return new Proxy(obj[prop], detector); } + }, + }; + this.checked = true; - // test the function + let proxy = new Proxy(map, detector); - let scopeKeys = Object.keys(scope); - let scopeValues = Object.values(scope); + try { + let d = this.func.apply(thisArg, [ + proxy, + proxy, + {}, + true, + ...this.scopeValues, + ]); + this.map = map; + return d; + } catch (ex) { + //console.log("Proxy failed", ex); + this.map = map; + } + } + + async _execute(thisArg, data) { + if (!this.checked) this._findMap(thisArg); + + let context = {}; + var rt = this.func.apply(thisArg, [ + data, + data, + context, + false, + ...this.scopeValues, + ]); + + //console.log(rt); + if (rt instanceof Promise) await rt; + + if (context.error != undefined) { + console.log( + "Execution failed", + context.error.name + ": " + context.error.message, + this.script, + this.target + ); + return; + } else if (context.value == undefined) { + return; + } else if (context.value instanceof Promise) { + try { + return await context.value; + } catch (ex) { + console.log( + "Execution failed", + ex.name + ": " + ex.message, + this.script, + this.target + ); + } + } else { + return context.value; + } + } + + unbind() { + this.data = null; + for (var i = 0; i < this.watchList.length; i++) + this.watchList[i].data.off(this.watchList[i].event, this.listener); + this.watchList = []; + } + + bind(data, map) { + if (data == null) return; + + if (data?.on) { + for (var p in map) { + let event = ":" + p; + data.on(":" + p, this.listener); + this.watchList.push({ data, event }); + + this.bind(data[p], map[p]); + } + + //if (this.watchList.includes(data)) + // this.watchList.push({ data, event : }); + } else { + for (var p in map) { + this.bind(data[p], map[p]); + } + } + } + + async render(data) { + // @TODO: Checking properties bindings moved here + if (data != this.data) this.unbind(); + + try { + if (this.type === BindingType.IUIElement) { + //let d = this.func.apply(this.target, [data, data]); + //if (d instanceof Promise) + // d = await d; + + let d = await this._execute(this.target, data); + + await this.target.setData(d); + } else if (this.type === BindingType.TextNode) { try { - let args = ["data", "d", "context", "_test", - ...scopeKeys] - - if (isAsync) - func = new AsyncFunction(...args, code); - else - func = new Function(...args, code); - } - catch (ex) { - console.log("Test failed: " + ex, code); - return null; - } + let d = await this._execute(this.target.parentElement, data); + if (d === undefined) return false; + //if (d instanceof Promise) + // d = await d; - let rt = new Binding(); - Object.assign(rt, { isAsync, type, attrType, attrKey, func, target: nodeOrAttributeOrIUIElement, checked: false, script, scopeKeys, scopeValues }); - return rt; + this.target.data = d; // (d === undefined) ? "" : d; + + if (data != this.data) { + this.data = data; + this.bind(data, this.map); + } + } catch (ex) { + this.target.data = ""; + } + } + // Content Attribute + else if (this.type == BindingType.ContentAttribute) { + let targetElement = this.target.ownerElement; + + let d = await this._execute(targetElement, data); + + if (d === undefined) return false; + + //if (d instanceof Promise) + // d = await d; + + targetElement.innerHTML = d; + + if (window?.app?.loaded) { + await IUI.create(targetElement); + IUI.bind( + targetElement, + true, + "content", + targetElement.__i_bindings?.scope + ); + // update references + targetElement.__i_bindings?.scope?.refs?._build(); + await IUI.created(targetElement); + await IUI.render(targetElement, targetElement._data, true); + } + //await IUI.updateTree(targetElement); + } else if (this.type == BindingType.IfAttribute) { + let d = await this._execute(this.target.ownerElement, data); + + //if (d === undefined) + // return false; + + this.target.ownerElement.style.display = d ? "" : "none"; + } else if (this.type == BindingType.RevertAttribute) { + let d = await this._execute(this.target.ownerElement, data); + if (d === undefined) return false; + //if (d instanceof Promise) + // d = await d; + } + // Attribute + else if (this.type === BindingType.Attribute) { + //if (this.target.ownerElement.hasAttribute("debug")) + // debugger; + + let d = await this._execute(this.target.ownerElement, data); + + if (d === undefined) return false; + + //if (d instanceof Promise) + // d = await d; + + if (this.attrType == AttributeBindingDestination.Field) + this.target.ownerElement[this.attrKey] = d; + else this.target.ownerElement.setAttribute(this.attrKey, d); + + if (data != this.data) { + this.data = data; + this.bind(data, this.map); + } + } + + // Data Attribute of IUI Element + else if (this.type === BindingType.IUIElementDataAttribute) { + let d = await this._execute(this.target.ownerElement, data); + //if (d === undefined) + // return false; + + //if (d instanceof Promise) + // d = await d; + await this.target.ownerElement.setData(d); + } + // Data Attribute of HTML Element + else if (this.type == BindingType.HTMLElementDataAttribute) { + let d = await this._execute(this.target.ownerElement, data); + if (d === undefined) return false; + //if (d instanceof Promise) + // d = await d; + this.target.ownerElement.data = d; + } + + return true; + } catch (ex) { + // console.log(ex); + return false; } - - constructor() { - this.watchList = []; - let self = this; - this.listener = function (name, value) { - self.render(self.data); - }; - } - - _findMap(thisArg) { - - // @TODO: Map thisArg too - let map = {}; - - let detector = { - get: function (obj, prop) { - if (typeof prop == "string") { - obj[prop] = {}; - return new Proxy(obj[prop], detector); - } - } - }; - - this.checked = true; - - let proxy = new Proxy(map, detector); - - try { - let d = this.func.apply(thisArg, [proxy, proxy, {}, true - , ...this.scopeValues]); - - this.map = map; - return d; - } - catch (ex) { - //console.log("Proxy failed", ex); - this.map = map; - } - } - - async _execute(thisArg, data) { - if (!this.checked) - this._findMap(thisArg); - - let context = {}; - var rt = this.func.apply(thisArg, [data, data, context, false, - ...this.scopeValues]); - - //console.log(rt); - if (rt instanceof Promise) - await rt; - - if (context.error != undefined) - { - console.log("Execution failed", context.error.name + ": " + context.error.message, this.script, this.target); - return; - } - else if (context.value == undefined) - { - return; - } - else if (context.value instanceof Promise) - { - try - { - return await context.value; - } catch(ex) { - console.log("Execution failed", ex.name + ": " + ex.message, this.script, this.target); - } - } - else - { - return context.value; - } - } - - unbind() { - this.data = null; - for (var i = 0; i < this.watchList.length; i++) - this.watchList[i].data.off(this.watchList[i].event, this.listener); - this.watchList = []; - } - - bind(data, map) { - if (data == null) - return; - - if (data?.on) { - - for (var p in map) { - let event = ":" + p; - data.on(":" + p, this.listener); - this.watchList.push({ data, event}); - - this.bind(data[p], map[p]); - } - - //if (this.watchList.includes(data)) - // this.watchList.push({ data, event : }); - } - else { - for (var p in map) { - this.bind(data[p], map[p]); - } - } - } - - - - async render(data) { - - // @TODO: Checking properties bindings moved here - if (data != this.data) - this.unbind(); - - try { - if (this.type === BindingType.IUIElement) { - //let d = this.func.apply(this.target, [data, data]); - //if (d instanceof Promise) - // d = await d; - - let d = await this._execute(this.target, data); - - await this.target.setData(d); - } - else if (this.type === BindingType.TextNode) { - - try { - - let d = await this._execute(this.target.parentElement, data); - - if (d === undefined) - return false; - //if (d instanceof Promise) - // d = await d; - - this.target.data = d;// (d === undefined) ? "" : d; - - if (data != this.data) { - this.data = data; - this.bind(data, this.map); - } - - } - catch (ex) { - this.target.data = ""; - } - } - // Content Attribute - else if (this.type == BindingType.ContentAttribute) { - - let targetElement = this.target.ownerElement; - - let d = await this._execute(targetElement, data); - - if (d === undefined) - return false; - - //if (d instanceof Promise) - // d = await d; - - targetElement.innerHTML = d; - - if (window?.app?.loaded) - { - await IUI.create(targetElement); - IUI.bind(targetElement, true, "content", targetElement.__i_bindings?.scope); - // update references - targetElement.__i_bindings?.scope?.refs?._build(); - await IUI.created(targetElement); - await IUI.render(targetElement, targetElement._data, true); - } - //await IUI.updateTree(targetElement); - - } - else if (this.type == BindingType.IfAttribute) - { - let d = await this._execute(this.target.ownerElement, data); - - //if (d === undefined) - // return false; - - this.target.ownerElement.style.display = d ? "" : "none"; - } - else if (this.type == BindingType.RevertAttribute) - { - let d = await this._execute(this.target.ownerElement, data); - if (d === undefined) - return false; - //if (d instanceof Promise) - // d = await d; - - } - // Attribute - else if (this.type === BindingType.Attribute) { - - //if (this.target.ownerElement.hasAttribute("debug")) - // debugger; - - let d = await this._execute(this.target.ownerElement, data); - - if (d === undefined) - return false; - - //if (d instanceof Promise) - // d = await d; - - if (this.attrType == AttributeBindingDestination.Field) - this.target.ownerElement[this.attrKey] = d; - else - this.target.ownerElement.setAttribute(this.attrKey, d); - - if (data != this.data) { - this.data = data; - this.bind(data, this.map); - } - } - - // Data Attribute of IUI Element - else if (this.type === BindingType.IUIElementDataAttribute) { - - - - let d = await this._execute(this.target.ownerElement, data); - //if (d === undefined) - // return false; - - //if (d instanceof Promise) - // d = await d; - await this.target.ownerElement.setData(d); - } - // Data Attribute of HTML Element - else if (this.type == BindingType.HTMLElementDataAttribute) { - - let d = await this._execute(this.target.ownerElement, data); - if (d === undefined) - return false; - //if (d instanceof Promise) - // d = await d; - this.target.ownerElement.data = d; - } - - return true; - } - catch (ex) { - // console.log(ex); - return false; - } - } - -} \ No newline at end of file + } +} diff --git a/src/Core/BindingList.js b/src/Core/BindingList.js index 6075ddf..5be1764 100644 --- a/src/Core/BindingList.js +++ b/src/Core/BindingList.js @@ -1,37 +1,32 @@ - export default class BindingList extends Array { - - constructor(target, scope) { - super(); - this.target = target; - this.scope = scope; - this.events = []; - } + constructor(target, scope) { + super(); + this.target = target; + this.scope = scope; + this.events = []; + } - destroy(){ - for(var i = 0; i < this.length; i++) - this[i].unbind(); - this.scope = {}; - this.target = null; - for(var i = 0; i < this.events.length; i++) - this.target.removeEventListener(this.events[i].name, this.events[i].handle); - } + destroy() { + for (var i = 0; i < this.length; i++) this[i].unbind(); + this.scope = {}; + this.target = null; + for (var i = 0; i < this.events.length; i++) + this.target.removeEventListener( + this.events[i].name, + this.events[i].handle + ); + } - addEvent(name, handle) - { - this.target.addEventListener(name, handle); - this.events.push({name, handle}) - } + addEvent(name, handle) { + this.target.addEventListener(name, handle); + this.events.push({ name, handle }); + } - getArgumentsNames(){ - if (this.scope == null) - return []; + getArgumentsNames() { + if (this.scope == null) return []; - let rt; - for (var i in this.scope.length) - rt.push(i); - return rt; - } - - -} \ No newline at end of file + let rt; + for (var i in this.scope.length) rt.push(i); + return rt; + } +} diff --git a/src/Core/IUI.js b/src/Core/IUI.js index 78e7ea3..ae7f60b 100644 --- a/src/Core/IUI.js +++ b/src/Core/IUI.js @@ -1,68 +1,56 @@ import IUIElement from "./IUIElement.js"; import { Binding, BindingType } from "./Binding.js"; //import Route from '../Router/Route.js'; -import BindingList from "./BindingList.js"; - +import BindingList from "./BindingList.js"; export class IUI { + static _menus = []; + static views = []; + static modules = {}; + static registry = []; - static _menus = []; - static views = []; - static modules = {}; - static registry = []; + static format(input) { + if (typeof input == "string" || input instanceof String) { + let template = document.createElement("template"); + template.innerHTML = input; + let nodes = template.content.cloneNode(true).childNodes; + return nodes; + } else if (input instanceof HTMLCollection) return input; + else if (input instanceof HTMLElement) return [input]; + else return []; + } - static format(input) { - if (typeof input == "string" || input instanceof String) { - let template = document.createElement("template"); - template.innerHTML = input; - let nodes = template.content.cloneNode(true).childNodes; - return nodes; + static observer = new IntersectionObserver( + function (entries) { + // isIntersecting is true when element and viewport are overlapping + // isIntersecting is false when element and viewport don't overlap + for (var i = 0; i < entries.length; i++) { + if (entries[i].isIntersecting) { + if (entries[i]._require_update) entries[i].update(); } - else if (input instanceof HTMLCollection) - return input; - else if (input instanceof HTMLElement) - return [input]; - else - return []; + } + }, + { threshold: [0] } + ); + + static async created(element) { + for (var i = 0; i < element.children.length; i++) { + let e = element.children[i]; + if (e instanceof IUIElement) await e.created(); + await IUI.created(e); } + } - static observer = new IntersectionObserver(function(entries) { - // isIntersecting is true when element and viewport are overlapping - // isIntersecting is false when element and viewport don't overlap - for(var i = 0; i < entries.length; i++) - { - if (entries[i].isIntersecting) - { - if (entries[i]._require_update) - entries[i].update(); - } - } + static async create(element) { + for (let i = 0; i < element.children.length; i++) { + let e = element.children[i]; + if (e instanceof IUIElement) { + await e.create(); + } - }, { threshold: [0] }); - - - static async created (element) { - - for (var i = 0; i < element.children.length; i++) { - let e = element.children[i]; - if (e instanceof IUIElement) - await e.created(); - await IUI.created(e); - } + await IUI.create(e); } - - static async create(element) - { - - for (let i = 0; i < element.children.length; i++) { - let e = element.children[i]; - if (e instanceof IUIElement) { - await e.create(); - } - - await IUI.create(e); - } - /* + /* let router = document.getElementsByTagName("i-router")[0]; await router.create(); @@ -73,286 +61,256 @@ export class IUI { console.log(elements[i]); await elements[i].create(); } - */ - - //for(var i = 0; i < IUI.registry.length; i++) - //{ - // IUI.extend(IUI.registry[i], IUI.registry[i].properties); - // await IUI.registry[i].create(); - // //await IUI.registry[i].updateAttributes(); - //} - //return; - } + */ - static get(o) - { - return document.getElementById(o); + //for(var i = 0; i < IUI.registry.length; i++) + //{ + // IUI.extend(IUI.registry[i], IUI.registry[i].properties); + // await IUI.registry[i].create(); + // //await IUI.registry[i].updateAttributes(); + //} + //return; + } - //for(var i = 0; i < IUI.registry.length; i++) - // if (IUI.registry[i].id == o) - // return IUI.registry[i]; - //return null; - } + static get(o) { + return document.getElementById(o); - static put(o) - { - IUI.registry.push(o); - } + //for(var i = 0; i < IUI.registry.length; i++) + // if (IUI.registry[i].id == o) + // return IUI.registry[i]; + //return null; + } - static remove(id) - { - for(var i = 0; i < IUI.registry.length; i++) - if (IUI.registry[i].el.id == id) - { - IUI.registry.splice(i, 1); - break; - } - } + static put(o) { + IUI.registry.push(o); + } - static module(objectClass) - { - let moduleName = objectClass.moduleName; + static remove(id) { + for (var i = 0; i < IUI.registry.length; i++) + if (IUI.registry[i].el.id == id) { + IUI.registry.splice(i, 1); + break; + } + } - if (IUI.modules[moduleName] === undefined) { - customElements.define("i-" + moduleName, objectClass); - IUI.modules[moduleName] = { - cls: objectClass, init: function (properties) { - return new objectClass(properties); - } - }; - } - - return objectClass; - } + static module(objectClass) { + let moduleName = objectClass.moduleName; - static extend(properties, defaults, overwrite) - { - if (properties == null) - properties = defaults; - else - for(var i in defaults) - if (overwrite) - properties[i] = defaults[i]; - else if (properties[i] === undefined) - properties[i] = defaults[i]; - return properties; - } + if (IUI.modules[moduleName] === undefined) { + customElements.define("i-" + moduleName, objectClass); + IUI.modules[moduleName] = { + cls: objectClass, + init: function (properties) { + return new objectClass(properties); + }, + }; + } + return objectClass; + } - static bind(element, skipAttributes, sourcePath, scope) { + static extend(properties, defaults, overwrite) { + if (properties == null) properties = defaults; + else + for (var i in defaults) + if (overwrite) properties[i] = defaults[i]; + else if (properties[i] === undefined) properties[i] = defaults[i]; + return properties; + } - // ::Attribute - // : Field - // async:: Async Attribute - // async: Async Field - // @ Event + static bind(element, skipAttributes, sourcePath, scope) { + // ::Attribute + // : Field + // async:: Async Attribute + // async: Async Field + // @ Event - // skip element ? - if (element.hasAttribute("skip") - || element.hasAttribute("i-skip") - || element instanceof HTMLTemplateElement) - return; + // skip element ? + if ( + element.hasAttribute("skip") || + element.hasAttribute("i-skip") || + element instanceof HTMLTemplateElement + ) + return; - // tags to skip - //if (element instanceof HTMLScriptElement ) - //return; - - let bindings; - - - if (scope == null) - scope = {}; + // tags to skip + //if (element instanceof HTMLScriptElement ) + //return; - // get refs before they get overwritten - //let refs = scope?.refs; + let bindings; - // some element extended or overwritten the binding arguments - if (element.scope != null) - IUI.extend(scope, element.scope, true); - else if (element.hasAttribute(":scope")) - { - let script = element.getAttribute(":scope"); - let code = `try {\r\n context.value = ${script}; \r\n}\r\n catch(ex) { context.error = ex; }` - let func = new Function("context", code); - let context = {}; + if (scope == null) scope = {}; - func.call(element, context); + // get refs before they get overwritten + //let refs = scope?.refs; - if (context.error != undefined) - console.log("Scope binding failed", context.error.name + ": " + context.error.message, this.script, this.target); - else if (context.value != undefined - && context.value instanceof Object) - IUI.extend(scope, context.value, true); - } - - let scopeArgs = Object.keys(scope); - let scopeValues = Object.values(scope); + // some element extended or overwritten the binding arguments + if (element.scope != null) IUI.extend(scope, element.scope, true); + else if (element.hasAttribute(":scope")) { + let script = element.getAttribute(":scope"); + let code = `try {\r\n context.value = ${script}; \r\n}\r\n catch(ex) { context.error = ex; }`; + let func = new Function("context", code); + let context = {}; + func.call(element, context); - bindings = new BindingList(element, scope); + if (context.error != undefined) + console.log( + "Scope binding failed", + context.error.name + ": " + context.error.message, + this.script, + this.target + ); + else if (context.value != undefined && context.value instanceof Object) + IUI.extend(scope, context.value, true); + } - if (skipAttributes) - { - // copy attributes bindings - if (element.__i_bindings != null) - for(var i = 0; i < element.__i_bindings.length; i++) - if (element.__i_bindings[i].type != BindingType.TextNode) - bindings.push(element.__i_bindings[i]); - } - else - { - element.__i_bindings?.destroy(); + let scopeArgs = Object.keys(scope); + let scopeValues = Object.values(scope); - // compile attributes - for (var i = 0; i < element.attributes.length; i++) { + bindings = new BindingList(element, scope); - // skip scope - if (element.attributes[i].name == ":scope") - continue; + if (skipAttributes) { + // copy attributes bindings + if (element.__i_bindings != null) + for (var i = 0; i < element.__i_bindings.length; i++) + if (element.__i_bindings[i].type != BindingType.TextNode) + bindings.push(element.__i_bindings[i]); + } else { + element.__i_bindings?.destroy(); - if (element.attributes[i].name.startsWith("@")){ + // compile attributes + for (var i = 0; i < element.attributes.length; i++) { + // skip scope + if (element.attributes[i].name == ":scope") continue; - // make events - let code = element.attributes[i].value; - //let code = `try {\r\n context.value = ${script}; \r\n}\r\n catch(ex) { context.error = ex; }` - let func = new Function("event", ...scopeArgs, code); - let handler = (event) => { - func.call(element, event, ...scopeValues); - } + if (element.attributes[i].name.startsWith("@")) { + // make events + let code = element.attributes[i].value; + //let code = `try {\r\n context.value = ${script}; \r\n}\r\n catch(ex) { context.error = ex; }` + let func = new Function("event", ...scopeArgs, code); + let handler = event => { + func.call(element, event, ...scopeValues); + }; - bindings.addEvent(element.attributes[i].name.substr(1), handler); - } - else - { - let b = Binding.create(element.attributes[i], - bindings.scope); + bindings.addEvent(element.attributes[i].name.substr(1), handler); + } else { + let b = Binding.create(element.attributes[i], bindings.scope); - if (b != null) { - if (b.type == BindingType.HTMLElementDataAttribute - || b.type == BindingType.IUIElementDataAttribute) - element.dataMap = b; - else if (b.type == BindingType.RevertAttribute) - element.revertMap = b; - else - bindings.push(b); - } - } - } - - - // add reference - // if (element.hasAttribute("ref")) { - // let ref = element.getAttribute("ref"); - // if (refs[ref] == null) - // refs[ref] = element; - // else if (refs[ref] == element){ - // // do nothing - // } - // else if (refs[ref] instanceof Array){ - // refs[ref].push(element); - // } else { - // var firstRef = refs[ref]; - // refs[ref] =[firstRef, element]; - // } - // } + if (b != null) { + if ( + b.type == BindingType.HTMLElementDataAttribute || + b.type == BindingType.IUIElementDataAttribute + ) + element.dataMap = b; + else if (b.type == BindingType.RevertAttribute) + element.revertMap = b; + else bindings.push(b); + } } + } - // get new refs (scope might been overwritten) - //refs = scope?.refs; + // add reference + // if (element.hasAttribute("ref")) { + // let ref = element.getAttribute("ref"); + // if (refs[ref] == null) + // refs[ref] = element; + // else if (refs[ref] == element){ + // // do nothing + // } + // else if (refs[ref] instanceof Array){ + // refs[ref].push(element); + // } else { + // var firstRef = refs[ref]; + // refs[ref] =[firstRef, element]; + // } + // } + } - // compile nodes - for (var i = 0; i < element.childNodes.length; i++) { - let el = element.childNodes[i]; - if (el instanceof IUIElement) { - // @TODO: check if the IUI element handles the binding - IUI.bind(el, false, sourcePath, scope); - } - else if (el instanceof HTMLScriptElement) - { + // get new refs (scope might been overwritten) + //refs = scope?.refs; - try - { - // this because HTML parser don't evaluate script tag - /// let func = new Function("//# sourceURL=iui://" + sourcePath + "-" + Math.round(Math.random() * 10000) + "\r\n return " + el.text.trim()); - let func = new Function(...scopeArgs, - "//# sourceURL=iui://" + sourcePath + "-" - + Math.round(Math.random() * 10000) - + "\r\n" + el.text.trim()); + // compile nodes + for (var i = 0; i < element.childNodes.length; i++) { + let el = element.childNodes[i]; + if (el instanceof IUIElement) { + // @TODO: check if the IUI element handles the binding + IUI.bind(el, false, sourcePath, scope); + } else if (el instanceof HTMLScriptElement) { + try { + // this because HTML parser don't evaluate script tag + /// let func = new Function("//# sourceURL=iui://" + sourcePath + "-" + Math.round(Math.random() * 10000) + "\r\n return " + el.text.trim()); + let func = new Function( + ...scopeArgs, + "//# sourceURL=iui://" + + sourcePath + + "-" + + Math.round(Math.random() * 10000) + + "\r\n" + + el.text.trim() + ); - let rt = func.apply(el.parentElement, scopeValues); + let rt = func.apply(el.parentElement, scopeValues); - console.log("rt", rt); + console.log("rt", rt); - if (typeof (rt) === "object") { - for (var k in rt) - el.parentElement[k] = rt[k]; - } - } - catch (ex) { - console.log(ex); - } - } - else if (el instanceof HTMLElement) { - IUI.bind(el, false, sourcePath, scope); - } - else if (el instanceof Text) { - let b = Binding.create(el, bindings.scope); - if (b != null) - bindings.push(b); - } + if (typeof rt === "object") { + for (var k in rt) el.parentElement[k] = rt[k]; + } + } catch (ex) { + console.log(ex); } + } else if (el instanceof HTMLElement) { + IUI.bind(el, false, sourcePath, scope); + } else if (el instanceof Text) { + let b = Binding.create(el, bindings.scope); + if (b != null) bindings.push(b); + } + } - element.__i_bindings = bindings; - } + element.__i_bindings = bindings; + } - static async render(element, data, textNodesOnly = false) { - - if (!element.__i_bindings) { - return; - } + static async render(element, data, textNodesOnly = false) { + if (!element.__i_bindings) { + return; + } - let bindings = element.__i_bindings; + let bindings = element.__i_bindings; - if (textNodesOnly) { - for (var i = 0; i < bindings.length; i++) - if (bindings[i].type == BindingType.TextNode) - await bindings[i].render(data); - } else { - // render attributes & text nodes - for (var i = 0; i < bindings.length; i++) - await bindings[i].render(data); - } + if (textNodesOnly) { + for (var i = 0; i < bindings.length; i++) + if (bindings[i].type == BindingType.TextNode) + await bindings[i].render(data); + } else { + // render attributes & text nodes + for (var i = 0; i < bindings.length; i++) await bindings[i].render(data); + } - // render children - for (var i = 0; i < element.children.length; i++) { - let el = element.children[i]; - if (el instanceof IUIElement) - // @TODO should check if the element depends on parent or not - if (el.dataMap != null) { - // if map function failed to call setData, we will render without it - if (!(await el.dataMap.render(data))) - await el.render(); - } - else - await el.setData(data); - else { - if (el.dataMap != null) - await el.dataMap.render(data); - else - el.data = data; + // render children + for (var i = 0; i < element.children.length; i++) { + let el = element.children[i]; + if (el instanceof IUIElement) + if (el.dataMap != null) { + // @TODO should check if the element depends on parent or not + // if map function failed to call setData, we will render without it + if (!(await el.dataMap.render(data))) await el.render(); + } else await el.setData(data); + else { + if (el.dataMap != null) await el.dataMap.render(data); + else el.data = data; - //let data = e.mapData(data); - await IUI.render(el, el.data); - } - } - } -}; + //let data = e.mapData(data); + await IUI.render(el, el.data); + } + } + } +} -export function iui(selector) -{ - return IUI.get(selector); +export function iui(selector) { + return IUI.get(selector); - /* + /* if ((typeof selector === 'string' || selector instanceof String) && selector.length > 0) { var els = document.querySelectorAll(selector); @@ -365,64 +323,58 @@ export function iui(selector) } */ - if (typeof(this) == "undefined" || this == window) - { - var o = IUI.get(selector); - if (o) - return o; - else - { - var el; + if (typeof this == "undefined" || this == window) { + var o = IUI.get(selector); + if (o) return o; + else { + var el; - if (typeof Node === "object" ? o instanceof Node : ( - selector && typeof selector === "object" && typeof selector.nodeType === "number" && typeof selector.nodeName==="string") || selector === window) - { - el = selector; - } - else if (typeof selector === 'string' || selector instanceof String) - { - if (selector[0] == ".") - el = document.getElementsByClassName(selector.substr(1)); - else - el = document.getElementById(selector); - } + if ( + typeof Node === "object" + ? o instanceof Node + : (selector && + typeof selector === "object" && + typeof selector.nodeType === "number" && + typeof selector.nodeName === "string") || + selector === window + ) { + el = selector; + } else if (typeof selector === "string" || selector instanceof String) { + if (selector[0] == ".") + el = document.getElementsByClassName(selector.substr(1)); + else el = document.getElementById(selector); + } - if (el) - { - var rt = {}; - var makeFunc = function(module){ - return function(){ - if (el instanceof HTMLCollection) - { - let rt = []; - for(var i = 0; i < el.length; i++) - { - var args = [el[i]]; - for(var j = 0; j < arguments.length; j++) - args.push(arguments[j]); - rt.push(IUI.modules[module].init.apply(this, args)); - } - return rt; - } - else - { - var args = [el]; - for(var i = 0; i < arguments.length; i++) - args.push(arguments[i]); - return IUI.modules[module].init.apply(this, args); - } - } - }; + if (el) { + var rt = {}; + var makeFunc = function (module) { + return function () { + if (el instanceof HTMLCollection) { + let rt = []; + for (var i = 0; i < el.length; i++) { + var args = [el[i]]; + for (var j = 0; j < arguments.length; j++) + args.push(arguments[j]); + rt.push(IUI.modules[module].init.apply(this, args)); + } + return rt; + } else { + var args = [el]; + for (var i = 0; i < arguments.length; i++) + args.push(arguments[i]); + return IUI.modules[module].init.apply(this, args); + } + }; + }; - for(var m in IUI.modules) - rt[m] = makeFunc(m); - - return rt; - } - } - } - - /* + for (var m in IUI.modules) rt[m] = makeFunc(m); + + return rt; + } + } + } + + /* IUI.registry.push(this); @@ -486,7 +438,6 @@ iui.prototype.ne = function(tag) } */ - /* iui.prototype.destroy = function() { diff --git a/src/Core/IUIElement.js b/src/Core/IUIElement.js index cffb07b..159c534 100644 --- a/src/Core/IUIElement.js +++ b/src/Core/IUIElement.js @@ -1,178 +1,154 @@ import { IUI } from "./IUI.js"; -import { Binding, BindingType, AttributeBindingDestination } from "./Binding.js"; +import { + Binding, + BindingType, + AttributeBindingDestination, +} from "./Binding.js"; export default class IUIElement extends HTMLElement { - constructor(defaults) { - super(); + constructor(defaults) { + super(); - this._events = []; - this._data = null; - this._defaults = defaults; - - for (var i in defaults) - if (this[i] == undefined) - try { - this[i] = defaults[i]; - } catch { - // mostly because modifying dom attributes are not allowed in custom elements creation - } + this._events = []; + this._data = null; + this._defaults = defaults; - this._register("data"); - } - - static get moduleName(){ - return this.name.toLowerCase(); - } - - - get cssClass(){ - if (this.hasAttribute("css-class")) - return this.getAttribute("css-class"); - //else - // return this.constructor.moduleName; - } - - set cssClass(value) - { - this.classList.remove(this.cssClass); - this.setAttribute("css-class", value); - this.classList.add(value); - } - - async render() { - await IUI.render(this, this._data); - } - - _getParentData() { - var p = this.parentElement; - do { - if (p.data !== undefined) - return p.data; - } while (p = p.parentElement); - - return undefined; - } - - async setData(value) { - this._data = value; - this._emit("data", {data: value}); - await IUI.render(this, value); - } - - - get data() { - return this._data; - } - - async revert(){ - let e = this; - - do { - var p = e.parentElement; - - if (e.revertMap != null) - await e.revertMap.render(p?.data); - } while (e = p); - } - - async update(data) { - if (data == undefined) { - // get parent data - if (this.dataMap != null) { - await this.dataMap.render(this._getParentData()); - } else - await this.setData(this.data); - } - else { - // apply specified data - if (this.dataMap != null) { - await this.dataMap.render(data); - } else - await this.setData(data); - } - } - - // bindings arguments - get scope(){ - return null; - } - - // this meant to be inherited - modified() { - - } - - connectedCallback() { - if (this.hasAttribute("css-class")) - { - this.classList.add(this.getAttribute("css-class")); - } - else - { - let className = this.constructor.moduleName; - this.setAttribute("css-class", className); - this.classList.add(className); - } - } - - disconnectedCallback() { - // console.log("removed", this); - } - - adoptedCallback() { - - //console.log("adopted", this); - - } - - //appendChild(node) { - // // do some bindings - // super.appendChild(node); - //} - - created() { - - } - - create() { - - } - - destroy() { - IUI.registry.splice(IUI.registry.indexOf(this), 1); - if (this.parentNode) - this.parentNode.removeChild(this); - } - - - - _emit(event, values) { - //var args = Array.prototype.slice.call(arguments, 1); - var e = new CustomEvent(event, values); - for (let i in values) { - if (e[i] === undefined) - e[i] = values[i]; + for (var i in defaults) + if (this[i] == undefined) + try { + this[i] = defaults[i]; + } catch { + // mostly because modifying dom attributes are not allowed in custom elements creation } - try - { - return this.dispatchEvent(e); - } - catch(ex) - { - console.log(ex); - } + this._register("data"); + } + + static get moduleName() { + return this.name.toLowerCase(); + } + + get cssClass() { + if (this.hasAttribute("css-class")) return this.getAttribute("css-class"); + //else + // return this.constructor.moduleName; + } + + set cssClass(value) { + this.classList.remove(this.cssClass); + this.setAttribute("css-class", value); + this.classList.add(value); + } + + async render() { + await IUI.render(this, this._data); + } + + _getParentData() { + var p = this.parentElement; + do { + if (p.data !== undefined) return p.data; + } while ((p = p.parentElement)); + + return undefined; + } + + async setData(value) { + this._data = value; + this._emit("data", { data: value }); + await IUI.render(this, value); + } + + get data() { + return this._data; + } + + async revert() { + let e = this; + + do { + var p = e.parentElement; + + if (e.revertMap != null) await e.revertMap.render(p?.data); + } while ((e = p)); + } + + async update(data) { + if (data == undefined) { + // get parent data + if (this.dataMap != null) { + await this.dataMap.render(this._getParentData()); + } else await this.setData(this.data); + } else { + // apply specified data + if (this.dataMap != null) { + await this.dataMap.render(data); + } else await this.setData(data); + } + } + + // bindings arguments + get scope() { + return null; + } + + // this meant to be inherited + modified() {} + + connectedCallback() { + if (this.hasAttribute("css-class")) { + this.classList.add(this.getAttribute("css-class")); + } else { + let className = this.constructor.moduleName; + this.setAttribute("css-class", className); + this.classList.add(className); + } + } + + disconnectedCallback() { + // console.log("removed", this); + } + + adoptedCallback() { + //console.log("adopted", this); + } + + //appendChild(node) { + // // do some bindings + // super.appendChild(node); + //} + + created() {} + + create() {} + + destroy() { + IUI.registry.splice(IUI.registry.indexOf(this), 1); + if (this.parentNode) this.parentNode.removeChild(this); + } + + _emit(event, values) { + //var args = Array.prototype.slice.call(arguments, 1); + var e = new CustomEvent(event, values); + for (let i in values) { + if (e[i] === undefined) e[i] = values[i]; } - - _encapsulateEvent(code){ - return `try {\r\n ${code} \r\n}\r\n catch(ex) { console.log(ex.name + ":" + ex.message, this); }`; + try { + return this.dispatchEvent(e); + } catch (ex) { + console.log(ex); } + } - _register(event) { - this._events.push(event); + _encapsulateEvent(code) { + return `try {\r\n ${code} \r\n}\r\n catch(ex) { console.log(ex.name + ":" + ex.message, this); }`; + } - /* + _register(event) { + this._events.push(event); + + /* if (this.hasAttribute("@" + event)) { let handler = this.getAttribute("@" + event); if (handler.match(/^[A-Za-z\$_]+(?:[\$_][A-Za-z0-9]+)*$/g) === null) { @@ -198,15 +174,15 @@ export default class IUIElement extends HTMLElement { } } */ - } + } - off(event, func) { - this.removeEventListener(event, func); - return this; - } + off(event, func) { + this.removeEventListener(event, func); + return this; + } - on(event, func) { - this.addEventListener(event, func, false); - return this; - } -} \ No newline at end of file + on(event, func) { + this.addEventListener(event, func, false); + return this; + } +} diff --git a/src/Core/Path.js b/src/Core/Path.js new file mode 100644 index 0000000..1dbb3b4 --- /dev/null +++ b/src/Core/Path.js @@ -0,0 +1,12 @@ +export default class Path { + /** + * Similar to `os.path.join` in nodejs. + * @param {...String} args + * @returns {String} + */ + static join() { + return Array.from(arguments) + .join("/") + .replace(/\/{1,}/g, "/"); + } +} diff --git a/src/Core/RefsCollection.js b/src/Core/RefsCollection.js index 6fd5d65..35b4f21 100644 --- a/src/Core/RefsCollection.js +++ b/src/Core/RefsCollection.js @@ -1,46 +1,35 @@ +export default class RefsCollection { + constructor(rootElement) { + this._rootElement = rootElement; + } -export default class RefsCollection -{ + _build(element, append) { + if (element == undefined) element = this._rootElement; - constructor(rootElement){ - this._rootElement = rootElement; - } + if (!append) + for (var i in this) + if (i != "_rootElement" && i != "_build") delete this[i]; - _build(element, append) { + for (var i = 0; i < element.children.length; i++) { + let child = element.children[i]; - if (element == undefined) - element = this._rootElement; - - if (!append) - for(var i in this) - if (i != "_rootElement" && i != "_build") - delete this[i]; - - for(var i = 0; i < element.children.length; i++) - { - let child = element.children[i]; - - if (child.hasAttribute("ref")) - { - let ref = child.getAttribute("ref"); - if (this[ref] == null) - this[ref] = child; - else if (this[ref] == child){ - // do nothing - } - else if (this[ref] instanceof Array){ - this[ref].push(child); - } else { - var firstRef = this[ref]; - this[ref] =[firstRef, child]; - } - } - - if (child.refs != undefined) - // opt out if the element handles referencing - break; - else - this._build(child, true); + if (child.hasAttribute("ref")) { + let ref = child.getAttribute("ref"); + if (this[ref] == null) this[ref] = child; + else if (this[ref] == child) { + // do nothing + } else if (this[ref] instanceof Array) { + this[ref].push(child); + } else { + var firstRef = this[ref]; + this[ref] = [firstRef, child]; } + } + + if (child.refs != undefined) + // opt out if the element handles referencing + break; + else this._build(child, true); } -} \ No newline at end of file + } +} diff --git a/src/Data/DataList.js b/src/Data/DataList.js index 265b1ea..c729180 100644 --- a/src/Data/DataList.js +++ b/src/Data/DataList.js @@ -1,14 +1,13 @@ import IUIElement from "../Core/IUIElement.js"; -export default IUI.module(class DataList extends IUIElement -{ - constructor(properties) - { - super(properties); - } - - create() - { - this.style.display = "none"; - } -}); \ No newline at end of file +export default IUI.module( + class DataList extends IUIElement { + constructor(properties) { + super(properties); + } + + create() { + this.style.display = "none"; + } + } +); diff --git a/src/Data/Field.js b/src/Data/Field.js index d0c8097..cc17fb3 100644 --- a/src/Data/Field.js +++ b/src/Data/Field.js @@ -1,62 +1,56 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; - -export default IUI.module(class Field extends HTMLElement -{ - constructor() - { - super(); - } - - static get moduleName(){ - return this.name.toLowerCase(); +export default IUI.module( + class Field extends HTMLElement { + constructor() { + super(); } - create() - { - // if (this.formatter === undefined) { - // // load script - // for (var i = 0; i < this.children.length; i++) - // if (this.children[i] instanceof HTMLScriptElement) { - // //this.formatter = new Function this.children[i]. - // } - // } + static get moduleName() { + return this.name.toLowerCase(); + } - //this.style.display = "none"; + create() { + // if (this.formatter === undefined) { + // // load script + // for (var i = 0; i < this.children.length; i++) + // if (this.children[i] instanceof HTMLScriptElement) { + // //this.formatter = new Function this.children[i]. + // } + // } + //this.style.display = "none"; } get name() { - return this.getAttribute("name"); + return this.getAttribute("name"); } set name(value) { - this.setAttribute("name", value); + this.setAttribute("name", value); } serialize(tag) { + let template = document.createElement("template"); + let node = document.createElement(tag ?? "div"); + let width = null, + name = null, + type = null; - let template = document.createElement("template"); - let node = document.createElement(tag ?? "div"); - let width = null, name = null, type = null; + // copy attributes + for (var i = 0; i < this.attributes.length; i++) { + let attr = this.attributes[i]; + if (attr.name == "width") width = attr.value; + else if (attr.name == "name") name = attr.value; + else if (attr.name == "type") type = attr.value; + else node.setAttribute(attr.name, attr.value); + } - // copy attributes - for (var i = 0; i < this.attributes.length; i++) { - let attr = this.attributes[i]; - if (attr.name == "width") - width = attr.value; - else if (attr.name == "name") - name = attr.value; - else if (attr.name == "type") - type = attr.value; - else - node.setAttribute(attr.name, attr.value); - } + // copy html - // copy html + node.innerHTML = this.innerHTML; - node.innerHTML = this.innerHTML; - - return { node, width, name, type }; + return { node, width, name, type }; } -}); \ No newline at end of file + } +); diff --git a/src/Data/Form.js b/src/Data/Form.js index df1ffa1..0ac6391 100644 --- a/src/Data/Form.js +++ b/src/Data/Form.js @@ -2,70 +2,62 @@ import { IUI } from "../Core/IUI.js"; import Modifiable from "./Modifiable.js"; -export default IUI.module(class Form extends IUIElement { +export default IUI.module( + class Form extends IUIElement { constructor() { - super(); + super(); } - static _copy(val){ - if (typeof val === 'object' && val !== null) - { - let rt = {}; - for(var i in val) - if (val[i] instanceof Array) - // copy array - rt[i] = [...val[i]]; - else - rt[i] = val[i]; + static _copy(val) { + if (typeof val === "object" && val !== null) { + let rt = {}; + for (var i in val) + if (val[i] instanceof Array) + // copy array + rt[i] = [...val[i]]; + else rt[i] = val[i]; - return rt; - } - else - return val; + return rt; + } else return val; } async create() { - //var elements = this.querySelectorAll("*[field]"); - //for (var i = 0; i < elements.length; i++) - // this.form[elements[i].getAttribute("field")] = elements[i]; + //var elements = this.querySelectorAll("*[field]"); + //for (var i = 0; i < elements.length; i++) + // this.form[elements[i].getAttribute("field")] = elements[i]; } async setData(value) { - this.original = value; - //var copy = {}; - //Object.assign(copy, value); - super.setData(new Modifiable(this.original));// Form._copy(this.original)); - //super.setData({ ...this.original }); + this.original = value; + //var copy = {}; + //Object.assign(copy, value); + super.setData(new Modifiable(this.original)); // Form._copy(this.original)); + //super.setData({ ...this.original }); } - async reset() { - //super.setData({ ...this.original }); - super.setData(new Modifiable(this.original));//Form._copy(this.original)); - return this; + //super.setData({ ...this.original }); + super.setData(new Modifiable(this.original)); //Form._copy(this.original)); + return this; } - - get diff() { + return this._data._diff; - return this._data._diff; + if (this.original == null) return this._data; - if (this.original == null) - return this._data; + var rt = {}; + for (var i in this._data) + if (this._data[i] != this.original[i]) { + if ( + this._data[i] instanceof Array && + Form._areEqual(this._data[i], this.original[i]) + ) + continue; + else rt[i] = this._data[i]; + } - - var rt = {}; - for (var i in this._data) - if (this._data[i] != this.original[i]) - { - if (this._data[i] instanceof Array && Form._areEqual(this._data[i], this.original[i])) - continue; - else - rt[i] = this._data[i]; - } - - return rt; + return rt; } - -}); \ No newline at end of file + } +); diff --git a/src/Data/Include.js b/src/Data/Include.js index a041ccf..cc5b3b8 100644 --- a/src/Data/Include.js +++ b/src/Data/Include.js @@ -2,114 +2,110 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; import RefsCollection from "../Core/RefsCollection.js"; -export default IUI.module(class Include extends IUIElement -{ - constructor() - { - super(); - this.refs = new RefsCollection(); +export default IUI.module( + class Include extends IUIElement { + constructor() { + super(); + this.refs = new RefsCollection(); } - get src(){ - return this.getAttribute("src"); + get src() { + return this.getAttribute("src"); } - set src(value){ - this.setAttribute("src", value); - this._load(value); + set src(value) { + this.setAttribute("src", value); + this._load(value); } - get scope() { - return {view: this, refs: this.refs}; + return { view: this, refs: this.refs }; } - async _load(url) - { - if (this._loading) - return; + async _load(url) { + if (this._loading) return; - this._loading = true; + this._loading = true; - let src = url.replace(/^\/+|\/+$/g, ''); + let src = url.replace(/^\/+|\/+$/g, ""); - this.classList.add(this.cssClass + "-loading"); + this.classList.add(this.cssClass + "-loading"); - let x = await fetch(src); + let x = await fetch(src); - if (x.status == 200) - { - let t = await x.text(); + if (x.status == 200) { + let t = await x.text(); - this.innerHTML = t; + this.innerHTML = t; - //let xeval = (code) => eval(code); + //let xeval = (code) => eval(code); - if (window?.app?.loaded) - { - await IUI.create(this); - IUI.bind(this, true, "include:" + src, - IUI.extend(this._i__bindings.scope, this.scope, true)); - - this.refs._build(); - await IUI.created(this); - await IUI.render(this, this._data, true); - } + if (window?.app?.loaded) { + await IUI.create(this); + IUI.bind( + this, + true, + "include:" + src, + IUI.extend(this._i__bindings.scope, this.scope, true) + ); - // // call create for the new elements - // var newElements = this.querySelectorAll("*"); - // for (var i = 0; i < newElements.length; i++) { - // var el = newElements[i]; - - // // set route for all elements - // //newElements[i].route = this.route; - // el.route = this.route; - // el.view = this; - // if (el.hasAttribute("ref")) { - // this.refs[el.getAttribute("ref")] = el; - // } - - // if (el instanceof HTMLScriptElement) { - // // this because HTML parser don't evaluate script tag - // let func = new Function("//# sourceURL=iui://" + src + "-" + Math.round(Math.random() * 10000) + "\r\n return " + el.text.trim());// "return " + el.text + ";"); - - // let rt = func.call(el.parentElement); - - // //let rt = xeval.call(el.parentElement, "//# sourceURL=iui://" + src + Math.round(Math.random() * 10000) + "\r\n (" + el.text + ")"); - // if (typeof (rt) === "object") { - // for (var k in rt) - // el.parentElement[k] = rt[k]; - // } - // } - // } + this.refs._build(); + await IUI.created(this); + await IUI.render(this, this._data, true); } - this.classList.remove(this.cssClass + "-loading"); + // // call create for the new elements + // var newElements = this.querySelectorAll("*"); + // for (var i = 0; i < newElements.length; i++) { + // var el = newElements[i]; - // if (window?.app?.loaded) - // { - // await IUI.create(this); - // await IUI.created(this); + // // set route for all elements + // //newElements[i].route = this.route; + // el.route = this.route; + // el.view = this; + // if (el.hasAttribute("ref")) { + // this.refs[el.getAttribute("ref")] = el; + // } - // for(let i = 0; i < this.children.length; i++) - // { - // let el = this.children[i]; - // IUIElement._make_bindings(el); - // await IUIElement._renderElement(el, el._data); + // if (el instanceof HTMLScriptElement) { + // // this because HTML parser don't evaluate script tag + // let func = new Function("//# sourceURL=iui://" + src + "-" + Math.round(Math.random() * 10000) + "\r\n return " + el.text.trim());// "return " + el.text + ";"); + + // let rt = func.call(el.parentElement); + + // //let rt = xeval.call(el.parentElement, "//# sourceURL=iui://" + src + Math.round(Math.random() * 10000) + "\r\n (" + el.text + ")"); + // if (typeof (rt) === "object") { + // for (var k in rt) + // el.parentElement[k] = rt[k]; + // } // } // } + } - this._loading = false; + this.classList.remove(this.cssClass + "-loading"); + + // if (window?.app?.loaded) + // { + // await IUI.create(this); + // await IUI.created(this); + + // for(let i = 0; i < this.children.length; i++) + // { + // let el = this.children[i]; + // IUIElement._make_bindings(el); + // await IUIElement._renderElement(el, el._data); + // } + // } + + this._loading = false; } - async create() - { - if (this.hasAttribute("src")) - await this._load(this.getAttribute("src")); + async create() { + if (this.hasAttribute("src")) await this._load(this.getAttribute("src")); } async created() { - this.refs._build(); + this.refs._build(); } - -}); \ No newline at end of file + } +); diff --git a/src/Data/Layout.js b/src/Data/Layout.js index 09c5fb8..0198c07 100644 --- a/src/Data/Layout.js +++ b/src/Data/Layout.js @@ -1,64 +1,60 @@ import IUIElement from "../Core/IUIElement.js"; -import Field from './Field.js'; +import Field from "./Field.js"; import { IUI } from "../Core/IUI.js"; -export default IUI.module(class Layout extends HTMLElement// IUIElement -{ - constructor() - { - super(); - } - - static get moduleName(){ - return this.name.toLowerCase(); +export default IUI.module( + class Layout extends HTMLElement { + // IUIElement + constructor() { + super(); } - //create() - //{ - // for (var i = 0; i < this.children.length; i++) - // if (this.children[i] instanceof Field) { - // this[this.children[i].name] = this.children[i]; - // this.fields.push(this.children[i]); - // } - - // this.style.display = "none"; - //} - - static getHTML(el, removeSelf = false) { - for (var i = 0; i < el.children.length; i++) - if (el.children[i] instanceof Layout) { - let layout = el.children[i]; - let rt = layout.innerHTML; - - if (removeSelf) - el.removeChild(layout); - return rt; - } - - return null; - } - - static get(el, tag, removeSelf = false, collection = false) { - - for (var i = 0; i < el.children.length; i++) - if (el.children[i] instanceof Layout) { - let layout = el.children[i]; - let rt = collection ? {} : []; - for (var j = 0; j < layout.children.length; j++) { - if (layout.children[j] instanceof Field) { - let fd = layout.children[j].serialize(tag); - if (collection) - rt[fd.name] = fd; - else - rt.push(fd); - } - } - - if (removeSelf) - layout.parentElement.removeChild(layout); - return rt; - } - - return null; + static get moduleName() { + return this.name.toLowerCase(); } -}); \ No newline at end of file + + //create() + //{ + // for (var i = 0; i < this.children.length; i++) + // if (this.children[i] instanceof Field) { + // this[this.children[i].name] = this.children[i]; + // this.fields.push(this.children[i]); + // } + + // this.style.display = "none"; + //} + + static getHTML(el, removeSelf = false) { + for (var i = 0; i < el.children.length; i++) + if (el.children[i] instanceof Layout) { + let layout = el.children[i]; + let rt = layout.innerHTML; + + if (removeSelf) el.removeChild(layout); + return rt; + } + + return null; + } + + static get(el, tag, removeSelf = false, collection = false) { + for (var i = 0; i < el.children.length; i++) + if (el.children[i] instanceof Layout) { + let layout = el.children[i]; + let rt = collection ? {} : []; + for (var j = 0; j < layout.children.length; j++) { + if (layout.children[j] instanceof Field) { + let fd = layout.children[j].serialize(tag); + if (collection) rt[fd.name] = fd; + else rt.push(fd); + } + } + + if (removeSelf) layout.parentElement.removeChild(layout); + return rt; + } + + return null; + } + } +); diff --git a/src/Data/Modifiable.js b/src/Data/Modifiable.js index 4758f22..b4298b3 100644 --- a/src/Data/Modifiable.js +++ b/src/Data/Modifiable.js @@ -1,139 +1,111 @@ -export default class Modifiable -{ - static _copy(val){ - if (typeof val === 'object' && val !== null) - { - let rt = {}; - for(var i in val) - if (val[i] instanceof Array) - // copy array - rt[i] = [...val[i]]; - else - rt[i] = val[i]; +export default class Modifiable { + static _copy(val) { + if (typeof val === "object" && val !== null) { + let rt = {}; + for (var i in val) + if (val[i] instanceof Array) + // copy array + rt[i] = [...val[i]]; + else rt[i] = val[i]; - return rt; - } - else - return val; + return rt; + } else return val; + } + + // @TODO: Remove this when esiur adds suport to partially modified arrays with modified flag + static _areEqual(ar1, ar2) { + if (!(ar1 instanceof Array) || !(ar2 instanceof Array)) return false; + + if (ar1.length != ar2.length) return false; + + for (var i = 0; i < ar1.length; i++) if (ar1[i] != ar2[i]) return false; + + return true; + } + + constructor(original) { + this._events = {}; + this._data = Modifiable._copy(original); + this._original = original; + + for (let p in this._data) { + if (p.startsWith("_")) continue; + + this._register(":" + p); + + Object.defineProperty(this, p, { + get() { + return this._data[p]; + }, + set(value) { + this._data[p] = value; + this._emit(":" + p, value); + }, + }); } + } - // @TODO: Remove this when esiur adds suport to partially modified arrays with modified flag - static _areEqual(ar1, ar2) - { - if (!(ar1 instanceof Array) || !( ar2 instanceof Array)) - return false; + get _diff() { + if (this._original == null) return this._data; - if (ar1.length != ar2.length) - return false; + var rt = {}; + for (var i in this._data) + if (this._data[i] != this._original[i]) { + if ( + this._data[i] instanceof Array && + Modifiable._areEqual(this._data[i], this._original[i]) + ) + continue; + else rt[i] = this._data[i]; + } - for(var i = 0; i < ar1.length; i++) - if (ar1[i] != ar2[i]) - return false; - - return true; - } + return rt; + } - constructor(original){ + _register(event) { + this._events[event] = []; + } - this._events = {}; - this._data = Modifiable._copy(original); - this._original = original; + _emit(event) { + event = event.toLowerCase(); + var args = Array.prototype.slice.call(arguments, 1); + if (this._events[event]) + for (var i = 0; i < this._events[event].length; i++) + if (this._events[event][i].f.apply(this._events[event][i].i, args)) + return true; - for(let p in this._data) - { - if (p.startsWith("_")) - continue; + return false; + } - this._register(":" + p); + _emitArgs(event, args) { + event = event.toLowerCase(); + if (this._events[event]) + for (var i = 0; i < this._events[event].length; i++) + if (this._events[event][i].f.apply(this._events[event][i].i, args)) + return true; + return this; + } - Object.defineProperty(this, p, { - get() { - return this._data[p]; - }, - set(value) { - this._data[p] = value; - this._emit(":" + p, value); - } - }); - } + on(event, fn, issuer) { + if (!(fn instanceof Function)) return this; - } + event = event.toLowerCase(); + // add + if (!this._events[event]) this._events[event] = []; + this._events[event].push({ f: fn, i: issuer == null ? this : issuer }); + return this; + } - - get _diff() { - if (this._original == null) - return this._data; - - var rt = {}; - for (var i in this._data) - if (this._data[i] != this._original[i]) - { - if (this._data[i] instanceof Array && Modifiable._areEqual(this._data[i], this._original[i])) - continue; - else - rt[i] = this._data[i]; - } - - return rt; - } - - _register(event) - { + off(event, fn) { + event = event.toLowerCase(); + if (this._events[event]) { + if (fn) { + for (var i = 0; i < this._events[event].length; i++) + if (this._events[event][i].f == fn) + this._events[event].splice(i--, 1); + } else { this._events[event] = []; + } } - - - _emit(event) - { - event = event.toLowerCase(); - var args = Array.prototype.slice.call(arguments, 1); - if (this._events[event]) - for(var i = 0; i < this._events[event].length; i++) - if (this._events[event][i].f.apply(this._events[event][i].i, args)) - return true; - - return false; - } - - _emitArgs(event, args) - { - event = event.toLowerCase(); - if (this._events[event]) - for(var i = 0; i < this._events[event].length; i++) - if (this._events[event][i].f.apply(this._events[event][i].i, args)) - return true; - return this; - } - - on(event, fn, issuer) - { - if (!(fn instanceof Function)) - return this; - - event = event.toLowerCase(); - // add - if (!this._events[event]) - this._events[event] = []; - this._events[event].push({f: fn, i: issuer == null ? this: issuer}); - return this; - } - - - off(event, fn) - { - event = event.toLowerCase(); - if (this._events[event]) - { - if (fn) - { - for(var i = 0; i < this._events[event].length; i++) - if (this._events[event][i].f == fn) - this._events[event].splice(i--, 1); - } - else - { - this._events[event] = []; - } - } - } -} \ No newline at end of file + } +} diff --git a/src/Data/Repeat.js b/src/Data/Repeat.js index 9e32979..8df0c97 100644 --- a/src/Data/Repeat.js +++ b/src/Data/Repeat.js @@ -1,65 +1,56 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; -export default IUI.module(class Repeat extends IUIElement -{ - constructor() - { - super({ _data: [] }); - this.list = []; +export default IUI.module( + class Repeat extends IUIElement { + constructor() { + super({ _data: [] }); + this.list = []; } - _isDirectDecedent(x){ - while(x = x.parentElement) - if (x == this) - return true; - else if (x instanceof Repeat && x != this) - return false; + _isDirectDecedent(x) { + while ((x = x.parentElement)) + if (x == this) return true; + else if (x instanceof Repeat && x != this) return false; } - create() - { - ////////////// - /// Create /// - ////////////// - - if (this._created) - debugger; + create() { + ////////////// + /// Create /// + ////////////// - this._created = true; - - // create template to speed avoid HTML parsing each time. - let repeatables = this.querySelectorAll("*[repeat]"); - - repeatables = Array.from(repeatables).filter(x=>this._isDirectDecedent(x)); + if (this._created) debugger; - if (repeatables.length > 0) - { + this._created = true; - this._repeatNode = repeatables[0].cloneNode(true); - this._container = repeatables[0].parentElement; - this._beforeNode = repeatables[0].nextSibling; - repeatables[0].parentElement.removeChild(repeatables[0]); - } - else - { - if (this.children.length > 0) - this._repeatNode = this.children[0].cloneNode(true); - else - this._repeatNode = document.createElement("div"); + // create template to speed avoid HTML parsing each time. + let repeatables = this.querySelectorAll("*[repeat]"); - this.innerHTML = ""; - this._container = this; - } + repeatables = Array.from(repeatables).filter(x => + this._isDirectDecedent(x) + ); + if (repeatables.length > 0) { + this._repeatNode = repeatables[0].cloneNode(true); + this._container = repeatables[0].parentElement; + this._beforeNode = repeatables[0].nextSibling; + repeatables[0].parentElement.removeChild(repeatables[0]); + } else { + if (this.children.length > 0) + this._repeatNode = this.children[0].cloneNode(true); + else this._repeatNode = document.createElement("div"); - // var newElements = this.querySelectorAll("*"); - // for (var i = 0; i < newElements.length; i++) - // newElements[i].repeat = this; + this.innerHTML = ""; + this._container = this; + } - // var self = this; + // var newElements = this.querySelectorAll("*"); + // for (var i = 0; i < newElements.length; i++) + // newElements[i].repeat = this; - /* + // var self = this; + + /* this._repeatModified = function(propertyName, value) { @@ -86,83 +77,72 @@ export default IUI.module(class Repeat extends IUIElement */ } - - clear() - { - for (var i = 0; i < this.list.length; i++) - this._container.removeChild(this.list[i]); - this.list = []; - this._data = []; + clear() { + for (var i = 0; i < this.list.length; i++) + this._container.removeChild(this.list[i]); + this.list = []; + this._data = []; } - get data() { - return super.data; + return super.data; } get length() { - return this._data.length; + return this._data.length; } + async setData(value) { + // this to avoid interruption by an event + if (this._busy) { + console.log("Busy", this); + return false; + } - async setData(value) - { - - - // this to avoid interruption by an event - if (this._busy) - { - console.log("Busy", this); - return false; - } + this._busy = true; - this._busy = true; + // clear + this.clear(); - - // clear - this.clear(); + if (value?.toArray instanceof Function) value = value.toArray(); + else if ( + value == null || + !(value instanceof Array || value instanceof Int32Array) + ) + value = []; - if (value?.toArray instanceof Function) - value = value.toArray(); - else if (value == null || !(value instanceof Array || value instanceof Int32Array)) - value = []; + //debugger; + await super.setData(value); + for (let i = 0; i < value.length; i++) { + let e = this._repeatNode.cloneNode(true); - //debugger; - await super.setData(value); + this.list.push(e); - - for (let i = 0; i < value.length; i++) { + await IUI.create(e); - let e = this._repeatNode.cloneNode(true); + IUI.bind( + e, + false, + "repeat", + IUI.extend(this.__i_bindings?.scope, { index: i, repeat: this }, true) + ); - this.list.push(e); + this._container.insertBefore(e, this._beforeNode); - await IUI.create(e); + // update referencing + this.__i_bindings?.scope?.refs?._build(); - IUI.bind(e, false, "repeat", - IUI.extend(this.__i_bindings?.scope, - {index: i, repeat: this}, true)); - - this._container.insertBefore(e, this._beforeNode); - - // update referencing - this.__i_bindings?.scope?.refs?._build(); + await IUI.created(e); - await IUI.created(e); - - await IUI.render(e, value[i], false); - - } + await IUI.render(e, value[i], false); + } + // @TODO: check if this works for event names starting with ":" + this._emit(":data", { data: value }); + // this._emit("modified", { data: value, property: "data" }); - - // @TODO: check if this works for event names starting with ":" - this._emit(":data", { data: value }); - // this._emit("modified", { data: value, property: "data" }); - - - this._busy = false; + this._busy = false; } - -}); \ No newline at end of file + } +); diff --git a/src/Data/TableRow.js b/src/Data/TableRow.js index 10748ea..b1ecc5f 100644 --- a/src/Data/TableRow.js +++ b/src/Data/TableRow.js @@ -1,15 +1,16 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; - -export default IUI.module(class TableRow extends IUIElement { +export default IUI.module( + class TableRow extends IUIElement { constructor() { - super(); + super(); } create() { - //this.style.display = "none"; - this.style.display = "table-row"; - console.log("TR"); + //this.style.display = "none"; + this.style.display = "table-row"; + console.log("TR"); } -}); \ No newline at end of file + } +); diff --git a/src/Router/Link.js b/src/Router/Link.js index c6a7d5a..fc036fd 100644 --- a/src/Router/Link.js +++ b/src/Router/Link.js @@ -1,70 +1,65 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; -export default IUI.module(class Link extends IUIElement -{ - constructor() - { - //debugger; - super({ cssClass: 'link' }); +export default IUI.module( + class Link extends IUIElement { + constructor() { + //debugger; + super({ cssClass: "link" }); - // super({ cssClass: 'link' }); - this._register("route"); - this.addEventListener("click", - (e) => { + // super({ cssClass: 'link' }); + this._register("route"); + this.addEventListener("click", e => { + var r = this.getBoundingClientRect(); + this.style.setProperty("--x", e.x - r.x + "px"); + this.style.setProperty("--y", e.y - r.y + "px"); - var r = this.getBoundingClientRect(); - this.style.setProperty("--x", (e.x - r.x) + "px"); - this.style.setProperty("--y", (e.y - r.y) + "px"); - - this.style.setProperty("--w", r.width + "px"); - this.style.setProperty("--h", r.height + "px"); - - this.classList.remove(this.cssClass + "-clicked"); - void this.offsetWidth; - this.classList.add(this.cssClass + "-clicked"); + this.style.setProperty("--w", r.width + "px"); + this.style.setProperty("--h", r.height + "px"); - let url = this.getAttribute("href"); + this.classList.remove(this.cssClass + "-clicked"); + void this.offsetWidth; + this.classList.add(this.cssClass + "-clicked"); - let ok = this._emit("route", { url, cancelable: true, query: this.query}); - if (!ok) - return; + let url = this.getAttribute("href"); + let ok = this._emit("route", { + url, + cancelable: true, + query: this.query, + }); + if (!ok) return; - //if (url == "#") - // url = router.current.link; - // return; + //if (url == "#") + // url = router.current.link; + // return; - let target = this.hasAttribute("target") ? document.getElementById(this.getAttribute("target")) : null; + let target = this.hasAttribute("target") + ? document.getElementById(this.getAttribute("target")) + : null; - - if (url == ":back") { - window.router.back(); - return; - } + if (url == ":back") { + window.router.back(); + return; + } + if (this.query) + // || this.hasAttribute(":data")) + window.router.navigate(url || router.current.url, this.query, target); + else if (url != null) window.router.navigate(url, undefined, target); + }); - - if (this.query)// || this.hasAttribute(":data")) - window.router.navigate(url || router.current.url, this.query, target); - else if (url != null) - window.router.navigate(url, undefined, target); - } - ); - - //this._register("click"); + //this._register("click"); } get link() { - return this.getAttribute("href"); + return this.getAttribute("href"); } set link(value) { - this.setAttribute("href", value); + this.setAttribute("href", value); } - create() - { - - } -}); \ No newline at end of file + create() {} + } +); diff --git a/src/Router/Route.js b/src/Router/Route.js index cf9a76b..5b617dc 100644 --- a/src/Router/Route.js +++ b/src/Router/Route.js @@ -2,183 +2,136 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; import Router from "./Router.js"; import RefsCollection from "../Core/RefsCollection.js"; +import Path from "../Core/Path.js"; -export default IUI.module(class Route extends IUIElement { - +export default IUI.module( + class Route extends IUIElement { constructor() { - super(); + super(); - this.routes = []; - this.refs = new RefsCollection(this); + this.routes = []; + this.refs = new RefsCollection(this); - this._register("show"); - this._register("hide"); + this._register("show"); + this._register("hide"); } async setData(value) { - if (this.hasAttribute("debug")) - debugger; + if (this.hasAttribute("debug")) debugger; - return await super.setData(value); + return await super.setData(value); } - get scope(){ - return {route: this, view: this}; + get scope() { + return { route: this, view: this }; } _updateLinks() { - for (var i = 0; i < this.children.length; i++) { - if (this.children[i] instanceof Route) { - this.routes.push(this.children[i]); - window.router.add(this.children[i], this); - i--; - } + for (var i = 0; i < this.children.length; i++) { + if (this.children[i] instanceof Route) { + this.routes.push(this.children[i]); + window.router.add(this.children[i], this); + i--; } + } } - get link() { - var link = this.name; - var parent = this.parent; - while (parent != null) { - link = parent.name + "/" + link; - parent = parent.parent; - } + base = ""; - return link; + get link() { + var link = this.name; + var parent = this.parent; + while (parent != null) { + link = parent.name + "/" + link; + parent = parent.parent; + } + + return this.base + "/" + link; } get name() { - return this.getAttribute("name"); + return this.getAttribute("name"); } get src() { - return this.getAttribute("src"); + return this.getAttribute("src"); } get dst() { - return this._dst || this.getAttribute("dst"); + return this._dst || this.getAttribute("dst"); } - set dst(value){ - this._dst = value; + set dst(value) { + this._dst = value; } - + get caption() { - return this.getAttribute("caption"); + return this.getAttribute("caption"); } get private() { - return this.hasAttribute("private"); + return this.hasAttribute("private"); } get icon() { - return this.getAttribute("icon"); + return this.getAttribute("icon"); } _getParent() { - let e = null;//this.parentElement; - while (e = this.parentElement) { - if (e instanceof Route || e instanceof Router) - return e; - } + let e = null; //this.parentElement; + while ((e = this.parentElement)) { + if (e instanceof Route || e instanceof Router) return e; + } - return null; + return null; } - // get route() { - // return this; - // } - - // get view() { - // return this; - // } - async create() { + //window.router.add(this); + this._updateLinks(); - //window.router.add(this); - this._updateLinks(); + if (this.hasAttribute("src")) { + let src = this.getAttribute("src").replace(/^\/+|\/+$/g, ""); + let x = await fetch(src); + if (x.status != 200) return; - if (this.hasAttribute("src")) { + let t = await x.text(); - let src = this.getAttribute("src").replace(/^\/+|\/+$/g, ''); - let x = await fetch(src); - if (x.status != 200) - return; - - let t = await x.text(); + this.innerHTML = t; + } - this.innerHTML = t; - - //let xeval = (code) => eval(code); - } - - - if (window?.app?.loaded) - { - await IUI.create(this); - IUI.bind(this, true, "route:" + src, this.scope); - this.refs._build(); - await IUI.created(this); - await IUI.render(this, this._data, true); - } - - // // call create for the new elements - // var newElements = this.querySelectorAll("*"); - // for (var i = 0; i < newElements.length; i++) { - // // set route for all elements - // var el = newElements[i]; - // // newElements[i].route = this; - // el.view = this; - // el.route = this; - - // if (el.hasAttribute("ref")) { - // this.refs[el.getAttribute("ref")] = el; - // } - - // if (el instanceof HTMLScriptElement) { - // // this because HTML parsers don't evaluate script tag - // // xeval.call(el.parentElement, "//# sourceURL=iui://" + src + "\r\n" + el.text); - - // //let func = new Function("//# sourceURL=iui://" + - // // src + "-" + Math.round(Math.random() * 10000) + "\r\n return " + el.text.trim()); - - // let func = new Function("//# sourceURL=iui://" + this.link - // + "\r\n return " + el.text.trim()); - - // let rt = func.call(el.parentElement); - - // if (typeof (rt) === "object") { - // for (var k in rt) - // el.parentElement[k] = rt[k]; - // } - // } - // } - } - - created() - { + if (window?.app?.loaded) { + await IUI.create(this); + IUI.bind(this, true, "route:" + src, this.scope); this.refs._build(); + await IUI.created(this); + await IUI.render(this, this._data, true); + } } - + + created() { + this.refs._build(); + } + set(value) { - if (value == this.visible) - return; + if (value == this.visible) { + return; + } - if (value) { - - this.setAttribute("selected", ""); - this._emit("show"); - - - } - else - { - this.removeAttribute("selected"); - this._emit("hide"); - } + if (value) { + this.setAttribute("selected", ""); + this._emit("show"); + } else { + this.removeAttribute("selected"); + this._emit("hide"); + } } - get visible() { return this.hasAttribute("selected"); } - set visible(value) { this.set(value); } - -}); + get visible() { + return this.hasAttribute("selected"); + } + set visible(value) { + this.set(value); + } + } +); diff --git a/src/Router/Router.js b/src/Router/Router.js index 42920f2..e1c4a07 100644 --- a/src/Router/Router.js +++ b/src/Router/Router.js @@ -1,338 +1,273 @@ -import IUIElement from "../Core/IUIElement.js"; -import Route from "./Route.js" +import Route from "./Route.js"; import Target from "./Target.js"; import { IUI } from "../Core/IUI.js"; +import path from "../Core/Path.js"; +export default IUI.module( + class Router extends Target { + constructor() { + super({ + routes: [], + _states: new Map(), + active: null, + cssClass: "router", + }); -export default IUI.module(class Router extends Target -{ - - constructor() - { - super({routes: [], _states: new Map(), active: null, cssClass: "router"}); - - this._history = []; - - - //IUI._router = this; - - //Object.defineProperty(window, "router", { - // get() { - // if (!IUI._router.isConnected) - // IUI._router = document.getElementsByTagName("i-router")[0]; - // return IUI._router; - // } - //}); - + this._history = []; } _getRouteParent(route) { - let e = null; + let e = null; - while (e = route.parentElement) { - if (e instanceof Route || e instanceof Router) - return e; - } + while ((e = route.parentElement)) { + if (e instanceof Route || e instanceof Router) return e; + } - return null; + return null; } add(route, parent = null) { - if (parent == null) { - this.routes.push(route); - } - else { - route.parent = parent; - this.appendChild(route); - //parent.routes.push(route); - } + route.base = this._base; + + if (!parent) { + this.routes.push(route); + return; + } + + route.parent = parent; + this.appendChild(route); } - _routeInPath(name, routes) - { - for (var i = 0; i < routes.length; i++) - if (routes[i].name == name) - return routes[i]; - return null; + _routeInPath(name, routes) { + for (let i = 0; i < routes.length; i++) + if (routes[i].name == name) return routes[i]; + return null; } getRoute(url, data) { - let p = url.split("/"); + /** + * @type {String[]} + */ + const p = url.split("/"); + if (p[0] == this._base) p.shift(); + let searchRoutes = this.routes; + for (let i = 0; i < p.length; i++) { + const route = this._routeInPath(p[i], searchRoutes); - let searchRoutes = this.routes; + if (route == null) return [null, null]; - for (var i = 0; i < p.length; i++) { - var route = this._routeInPath(p[i], searchRoutes); + if (i == p.length - 1) { + // return [destination state route (link, icon,..etc) , actual route to view] + if (route.dst == null) return [route, route]; - if (route == null) - return [null, null]; - - if (i == p.length - 1) { - // return [destination state route (link, icon,..etc) , actual route to view] - if (route.dst == null) - return [route, route]; - else { - - let dst = route.dst instanceof Function ? route.dst(data) : route.dst; - let url = dst.replace(/^[/]*(.*?)[/]*$/g, '$1').trim(); - return [route, this.getRoute(url)[1]]; - } - } - - searchRoutes = route.routes; + const dst = + route.dst instanceof Function ? route.dst(data) : route.dst; + const url = dst.replace(/^[/]*(.*?)[/]*$/g, "$1").trim(); + return [route, this.getRoute(url)[1]]; } - + searchRoutes = route.routes; + } } back() { - //if (this._history.length > 1) { - // let last = this._history[this._history.length - 2]; - // this.navigate(last.url, last.data, last.target); - //} - - window.history.back(); - } + window.history.back(); + } _toQuery(o) { - let rt = []; - for (let i in o) - if (o[i] == undefined) - rt.push(i); - else - rt.push(i + "=" + encodeURI(o[i].toString().replace("&", "&&")));///encodeURIComponent(o[i])); - return rt.join("&"); + return Object.keys(o) + .map(i => + !i ? i : `${i}=${encodeURI(o[i].toString().replace("&", "&&"))}` + ) + .join("&"); } _fromQuery(q) { - let kv = q.replace("&&", "\0").split('&'); - let rt = {}; - for (let i = 0; i < kv.length; i++) { - let d = kv[i].replace("\0", "&").split('=', 2); - let v = decodeURI(d[1] || ''); //decodeURIComponent(d[1] || ''); - if (v != null && v.trim() != '' && !isNaN(v)) - v = new Number(v); - rt[d[0]] = v; - } - return JSON.parse(JSON.stringify(rt)); + const kv = q.replace("&&", "\0").split("&"); + const rt = {}; + for (let i = 0; i < kv.length; i++) { + const d = kv[i].replace("\0", "&").split("=", 2); + const v = decodeURI(d[1] || ""); + if (v != null && v.trim() != "" && !isNaN(v)) v = new Number(v); + rt[d[0]] = v; + } + return JSON.parse(JSON.stringify(rt)); } - async navigate(url, data, target, state, dataToQuery = true) - { - let q = url.match(/^\/*(.*?)\?(.*)$|^\/*(.*)$/); + async navigate(url, data, target, state, dataToQuery = true) { + let q = url.match(/^\/*(.*?)\?(.*)$|^\/*(.*)$/); - //debugger; + let path; - var path; + // Do we have a query string ? + if (q[2] !== undefined) { + path = q[1]; + data = this._fromQuery(q[2]); + url = path + "?" + q[2]; + } + // Do we have data? + else if (data !== undefined) { + path = q[3]; + url = dataToQuery ? path + "?" + this._toQuery(data) : path; + } else { + path = q[3]; + url = path; + } - // do we have a query string ? - if (q[2] !== undefined) { - path = q[1]; - data = this._fromQuery(q[2]); - url = path + "?" + q[2]; - } - // do we have data ? - else if (data !== undefined) { - path = q[3]; - url = dataToQuery ? path + "?" + this._toQuery(data) : path; - } - else { - path = q[3]; - url = path; - } - + const [stateRoute, viewRoute] = this.getRoute(path, data); - let [stateRoute, viewRoute] = this.getRoute(path, data); + if (stateRoute == null) { + console.warn("State not found ", path); + return; + } - if (stateRoute == null) - { - console.warn("State not found ", path); - return; - } + let ok = this._emit("navigate", { + url, + stateRoute, + viewRoute, + base: path, + data, + cancelable: true, + }); - let ok = this._emit("navigate", { url, stateRoute, viewRoute, base: path, data, cancelable: true }); + if (!ok) { + console.warn("Route not allowed", path); + return; + } - if (!ok) - { - console.warn("Route not allowed", path); - return; - } + // destination view not found + if (viewRoute == null) { + console.log(`Destination route not found ${stateRoute.dst}`); + viewRoute = stateRoute; + } - // destination view not found - if (viewRoute == null) { - console.log(`Destination route not found ${stateRoute.dst}`); - viewRoute = stateRoute; - } - + if (!(target instanceof Target)) target = this; - //let state = null; + if (state == null) { + const id = Math.random().toString(36).substring(2, 12); + state = { id, url, data, target, stateRoute, viewRoute }; + this._states.set(id, state); + history.pushState( + id, + stateRoute.caption, + this._hash ? "#" + url : "/" + url + ); + } - //if (data !== undefined) { - // for (let [k, v] of this._states) - // if (v == data) { - // state = k; - // break; - // } + this._history.push(state.id); // { url, data, target, stateRoute, viewRoute }); - // if (state == null) { - // state = Math.random().toString(36).substr(2, 10); - // this._states.set(state, data); - // } - //} + target.show(viewRoute, this.active); + viewRoute.set(true); - if (!(target instanceof Target)) - target = this; + this.active = viewRoute; - if (state == null) { - let id = Math.random().toString(36).substr(2, 10); - state = { id, url, data, target, stateRoute, viewRoute }; - this._states.set(id, state); - history.pushState(id, stateRoute.caption, this._hash ? "#" + url : "/" + url); - } + this._emit("route", { route: stateRoute }); - this._history.push(state.id);// { url, data, target, stateRoute, viewRoute }); + viewRoute.query = data || {}; + stateRoute.query = viewRoute.query; - target.show(viewRoute, this.active); - viewRoute.set(true); + target.setLoading(true); + if (stateRoute.dataMap != null) { + // if map function failed to call setData, we will render without it + if (!(await stateRoute.dataMap.render(data || {}))) + await stateRoute.render(); - this.active = viewRoute; + if (viewRoute != stateRoute) await viewRoute.setData(stateRoute.data); + } //if (data !== undefined) + else await viewRoute.setData(data); - - //{ url: "/", data: null, target: null }; - this._emit("route", { route: stateRoute }); - - viewRoute.query = data || {}; - stateRoute.query = viewRoute.query; - - - target.setLoading(true); - - if (stateRoute.dataMap != null) { - // if map function failed to call setData, we will render without it - if (!(await stateRoute.dataMap.render(data || {}))) - await stateRoute.render(); - - if (viewRoute != stateRoute) - await viewRoute.setData(stateRoute.data); - } - else //if (data !== undefined) - await viewRoute.setData(data); - - target.setLoading(false); - + target.setLoading(false); } hide() { - // do nothing, we're not here to hide. + // do nothing, we're not here to hide. } refresh() { - - let state = this.current; - this.navigate(state.url, state.data, state.target, state); - - //this.current.render(); - //this.current.data = this.current.data; - //if (updateAttributes) - // this.current.updateAttributes(true); + const state = this.current; + this.navigate(state.url, state.data, state.target, state); } show(route, active) { - super.show(route, active); - - + super.show(route, active); } get current() { - return this._states.get(history.state);//.viewRoute; - //return this._history[this._history.length - 1].viewRoute; + return this._states.get(history.state); //.viewRoute; } get previous() { - - if (this._history.length > 2) - return this._states.get(this._history[this._history.length - 2]);//.viewRoute; - else - return null; + if (this._history.length > 2) + return this._states.get(this._history[this._history.length - 2]); + //.viewRoute; + else return null; } create() { - - // save origin - this.origin = window.location.pathname + window.location.search; + // save origin + this.origin = window.location.pathname + window.location.search; + this._base = this.hasAttribute("base") ? this.getAttribute("base") : "/"; } destroy() { - console.log("Destroyed", this); + console.log("Destroyed", this); } - created() - { + created() { + if ( + this.hasAttribute("type") && + this.getAttribute("type").toLowerCase() == "hash" + ) { + this._hash = true; + } - if (this.hasAttribute("type") && this.getAttribute("type").toLowerCase() == "hash") - this._hash = true; - - - /// find all children - for (var i = 0; i < this.children.length; i++) { - let e = this.children[i]; - if (e instanceof Route) { - this.add(e); - if (e.visible) - this.navigate(e.name); - } + /// find all children + for (let i = 0; i < this.children.length; i++) { + const e = this.children[i]; + if (e instanceof Route) { + this.add(e); + if (e.visible) this.navigate(e.name); } + } - this._emit("created"); - - //console.log("Router created", this); + this._emit("created"); } connectedCallback() { - //console.log("New router", this); + window.router = this; - window.router = this; + const self = this; + window.addEventListener("popstate", function (event) { + const stateId = event.state; + let path; - let self = this; + if (self._hash) { + path = window.location.hash; - window.addEventListener("popstate", function (event) { + if (path.length > 0) path = path.substring(1); + } else { + path = window.location.pathname; + } - //console.log(event); - let stateId = event.state; - let path; + if (stateId != null) { + if (stateId != self._history[self._history.length - 1]) { + //this._lastStateId = stateId; + const state = self._states.get(stateId); + self.navigate(path, state.data, state.target, state); + } else { + console.log("SAME"); + } + } else { + this._lastState = null; + self.navigate(path, undefined, undefined, {}); + } + //alert("location: " + document.location + ", state: " + JSON.stringify(event.state)); + console.log(document.location.hash, event.state); + }); - if (self._hash) { - path = window.location.hash; - - if (path.length > 0) - path = path.substr(1); - } - else { - path = window.location.pathname; - } - - if (stateId != null) { - - if (stateId != self._history[self._history.length -1]) { - //this._lastStateId = stateId; - let state = self._states.get(stateId); - self.navigate(path, state.data, state.target, state); - } - else { - console.log("SAME"); - } - } - else { - this._lastState = null; - self.navigate(path, undefined, undefined, {}); - } - //alert("location: " + document.location + ", state: " + JSON.stringify(event.state)); - console.log(document.location.hash, event.state); - }); - - this._register("navigate"); - this._register("route"); - this._register("created"); + this._register("navigate"); + this._register("route"); + this._register("created"); } - -}); \ No newline at end of file + } +); diff --git a/src/Router/Target.js b/src/Router/Target.js index b4c84a5..59133ad 100644 --- a/src/Router/Target.js +++ b/src/Router/Target.js @@ -2,59 +2,52 @@ import { IUI } from "../Core/IUI.js"; import Route from "./Route.js"; -export default IUI.module(class Target extends IUIElement { +export default IUI.module( + class Target extends IUIElement { constructor(properties) { - super(IUI.extend(properties, { cssClass: 'target' })); - - this._register("show"); - this._register("hide"); + super(IUI.extend(properties, { cssClass: "target" })); + this._register("show"); + this._register("hide"); } - setLoading(value) - { - if (value) - this.classList.add(this.cssClass + "-loading"); - else - this.classList.remove(this.cssClass + "-loading"); + setLoading(value) { + if (value) this.classList.add(this.cssClass + "-loading"); + else this.classList.remove(this.cssClass + "-loading"); } - create() { - - } + create() {} show(route, previous) { + let previousTarget = previous?.target; - let previousTarget = previous?.target; + route.target = this; - route.target = this; - - for (var i = 0; i < this.children.length; i++) - if (this.children[i] instanceof Route && this.children[i] != route) { - this.children[i].set(false); - } - - //if (previous != null && previous != route && previous.target == this) { - // previous.set(false); - //} - //else - if (previousTarget != null && previousTarget != this) { - previousTarget.hide(this.active); + for (var i = 0; i < this.children.length; i++) + if (this.children[i] instanceof Route && this.children[i] != route) { + this.children[i].set(false); } + //if (previous != null && previous != route && previous.target == this) { + // previous.set(false); + //} + //else + if (previousTarget != null && previousTarget != this) { + previousTarget.hide(this.active); + } - if (route.parentElement != this) - this.appendChild(route); + if (route.parentElement != this) this.appendChild(route); - this._emit("show", { route, previous}); + this._emit("show", { route, previous }); } hide(route) { - for (var i = 0; i < this.children.length; i++) - if (this.children[i] instanceof Route) { - this.children[i].set(false); - } + for (var i = 0; i < this.children.length; i++) + if (this.children[i] instanceof Route) { + this.children[i].set(false); + } - this._emit("hide", { route }); + this._emit("hide", { route }); } -}); \ No newline at end of file + } +); diff --git a/src/UI/Background.js b/src/UI/Background.js index 48630d1..4d7538a 100644 --- a/src/UI/Background.js +++ b/src/UI/Background.js @@ -1,40 +1,36 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; -export default IUI.module(class Background extends IUIElement { +export default IUI.module( + class Background extends IUIElement { constructor() { - super({ cssClass: 'background' }); - - - this.classList.add(this.cssClass); - this._register("visible"); + super({ cssClass: "background" }); + this.classList.add(this.cssClass); + this._register("visible"); } - - create() { - - } + create() {} hide() { - return this.setVisible(false); + return this.setVisible(false); } show() { - return this.setVisible(true); + return this.setVisible(true); } setVisible(value) { - this.visible = value; - if (value) { - this.classList.add(this.cssClass + "-visible"); - } - else { - this.classList.remove(this.cssClass + "-visible"); - } + this.visible = value; + if (value) { + this.classList.add(this.cssClass + "-visible"); + } else { + this.classList.remove(this.cssClass + "-visible"); + } - this._emit("visible", value); + this._emit("visible", value); - return this; + return this; } -}); \ No newline at end of file + } +); diff --git a/src/UI/Button.js b/src/UI/Button.js index 1fef3fb..dba24c6 100644 --- a/src/UI/Button.js +++ b/src/UI/Button.js @@ -1,70 +1,66 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; -export default IUI.module(class Button extends IUIElement { +export default IUI.module( + class Button extends IUIElement { constructor() { - super({ cssClass: 'button' }); + super({ cssClass: "button" }); - this.addEventListener("mousedown", (e)=>{ + this.addEventListener( + "mousedown", + e => { + var r = this.getBoundingClientRect(); + this.style.setProperty("--x", e.x - r.x + "px"); + this.style.setProperty("--y", e.y - r.y + "px"); - var r = this.getBoundingClientRect(); - this.style.setProperty("--x", (e.x - r.x) + "px"); - this.style.setProperty("--y", (e.y - r.y) + "px"); + this.style.setProperty("--w", r.width + "px"); + this.style.setProperty("--h", r.height + "px"); - this.style.setProperty("--w", r.width + "px"); - this.style.setProperty("--h", r.height + "px"); + this.classList.remove(this.cssClass + "-clicked"); + void this.offsetWidth; + this.classList.add(this.cssClass + "-clicked"); + }, + true + ); - this.classList.remove(this.cssClass + "-clicked"); - void this.offsetWidth; - this.classList.add(this.cssClass + "-clicked"); - - }, true); - - this._register("check"); + this._register("check"); } get type() { - return this.getAttribute("type"); + return this.getAttribute("type"); } - set type(value) - { - this.setAttribute("type", value); + set type(value) { + this.setAttribute("type", value); } get checked() { - return this.hasAttribute("checked"); + return this.hasAttribute("checked"); } - set checked(value) - { - if (value) - this.setAttribute("checked", ""); - else - this.removeAttribute("checked"); + set checked(value) { + if (value) this.setAttribute("checked", ""); + else this.removeAttribute("checked"); } - get disabled() { - return this.getAttribute("disabled"); + return this.getAttribute("disabled"); } set disabled(value) { - this.setAttribute("disabled", value); + this.setAttribute("disabled", value); } - create() { + if (this.type == "check") { + this.addEventListener("click", () => { + let checked = !this.checked; + this.checked = checked; + this._emit("check", { checked }); + }); + } - if (this.type == "check") - { - this.addEventListener("click", ()=>{ - let checked = !this.checked; - this.checked = checked; - this._emit("check", {checked}); - }); - } - - //this.classList.add(this.cssClass); + //this.classList.add(this.cssClass); } -}); \ No newline at end of file + } +); diff --git a/src/UI/Check.js b/src/UI/Check.js index bccec3b..3149b04 100644 --- a/src/UI/Check.js +++ b/src/UI/Check.js @@ -1,58 +1,54 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; -export default IUI.module(class Check extends IUIElement { +export default IUI.module( + class Check extends IUIElement { constructor(properties) { - super(IUI.extend(properties, { cssClass: 'check' })); + super(IUI.extend(properties, { cssClass: "check" })); - this._register("check"); + this._register("check"); - this.on("click", () => { - this.checked = !this.checked; - }); + this.on("click", () => { + this.checked = !this.checked; + }); } get checked() { - return this.hasAttribute("checked"); + return this.hasAttribute("checked"); } set checked(value) { - this.check(value); - this._emit("check", { checked: value }); + this.check(value); + this._emit("check", { checked: value }); } check(value) { - if (value) - this.setAttribute("checked", "checked"); - else - this.removeAttribute("checked"); + if (value) this.setAttribute("checked", "checked"); + else this.removeAttribute("checked"); } create() { - this.field = this.getAttribute("field"); + this.field = this.getAttribute("field"); } async setData(value) { - await super.setData(value); - if (value != null && this.field != null) - this.value = value[this.field]; - else if (this.field != null) - this.value = null; + await super.setData(value); + if (value != null && this.field != null) this.value = value[this.field]; + else if (this.field != null) this.value = null; } - modified(name, value) { - if (name == this.field) { - this.value = value; - } + if (name == this.field) { + this.value = value; + } } get value() { - return this.checked; + return this.checked; } set value(value) { - this.checked = value; + this.checked = value; } - -}); \ No newline at end of file + } +); diff --git a/src/UI/CodePreview.js b/src/UI/CodePreview.js index dea36ac..b3dfb16 100644 --- a/src/UI/CodePreview.js +++ b/src/UI/CodePreview.js @@ -2,88 +2,87 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; import RefsCollection from "../Core/RefsCollection.js"; -export default IUI.module(class CodePreview extends IUIElement { +export default IUI.module( + class CodePreview extends IUIElement { constructor() { - super(); - this.refs = new RefsCollection(this); - this._code = this.innerHTML.trim(); - this.textContent = ''; - + super(); + this.refs = new RefsCollection(this); + this._code = this.innerHTML.trim(); + this.textContent = ""; } async create() { + if (this.hasAttribute("debug")) debugger; - if (this.hasAttribute("debug")) - debugger; + //this._code = this.innerHTML.trim(); + //this.textContent = ''; - //this._code = this.innerHTML.trim(); - //this.textContent = ''; - - // create elements - this.bar = document.createElement("div"); - this.bar.className = this.cssClass + "-bar"; - this.content = document.createElement("div"); - this.content.className = this.cssClass + "-content"; - this.editor = document.createElement("code"); - this.editor.className = this.cssClass + "-editor"; + // create elements + this.bar = document.createElement("div"); + this.bar.className = this.cssClass + "-bar"; + this.content = document.createElement("div"); + this.content.className = this.cssClass + "-content"; + this.editor = document.createElement("code"); + this.editor.className = this.cssClass + "-editor"; - this.editor.innerText = this._code; - this.editor.contentEditable = true; + this.editor.innerText = this._code; + this.editor.contentEditable = true; - this.editor.setAttribute("skip", true); + this.editor.setAttribute("skip", true); - let self = this; - this.editor.addEventListener("input", function() { - self._code = self.editor.textContent.trim(); - self.updatePreview(); - }, false); - - this.preview = document.createElement("div"); - this.preview.className = this.cssClass + "-preview"; - //this.preview.setAttribute(":content", ""); + let self = this; + this.editor.addEventListener( + "input", + function () { + self._code = self.editor.textContent.trim(); + self.updatePreview(); + }, + false + ); - this.content.append(this.editor); - this.content.append(this.preview); - - this.append(this.bar); - this.append(this.content); - this.field = this.getAttribute("field"); + this.preview = document.createElement("div"); + this.preview.className = this.cssClass + "-preview"; + //this.preview.setAttribute(":content", ""); - //await this.updatePreview(); - } - - async created(){ - await this.updatePreview(); + this.content.append(this.editor); + this.content.append(this.preview); + + this.append(this.bar); + this.append(this.content); + this.field = this.getAttribute("field"); + + //await this.updatePreview(); } - get scope(){ - return {view: this, refs: this.refs}; + async created() { + await this.updatePreview(); } - + + get scope() { + return { view: this, refs: this.refs }; + } + async updatePreview() { - + if (this._updating) return; - if (this._updating) - return; + this._updating = true; - this._updating = true; + this.preview.innerHTML = this._code; + //this.editor.innerHTML = hljs.highlightAuto(this._code).value; - this.preview.innerHTML = this._code; - //this.editor.innerHTML = hljs.highlightAuto(this._code).value; + // this.editor.innerHTML = hljs.highlight(this._code, {language: 'html'}).value -// this.editor.innerHTML = hljs.highlight(this._code, {language: 'html'}).value + // this.editor.innerHTML = hljs.highlightElement(this.editor, {language: 'html'}).value; - // this.editor.innerHTML = hljs.highlightElement(this.editor, {language: 'html'}).value; + if (window.app?.loaded) { + await IUI.create(this.preview); + await IUI.created(this.preview); + IUI.bind(this.preview, true, "preview", this.scope); + this.refs._build(); + await IUI.render(this.preview, this._data, true); + } - if (window.app?.loaded) - { - await IUI.create(this.preview); - await IUI.created(this.preview); - IUI.bind(this.preview, true, "preview", this.scope); - this.refs._build(); - await IUI.render(this.preview, this._data, true); - } - - this._updating = false; + this._updating = false; } -}); \ No newline at end of file + } +); diff --git a/src/UI/DateTimePicker.js b/src/UI/DateTimePicker.js index 8221ed1..24eea68 100644 --- a/src/UI/DateTimePicker.js +++ b/src/UI/DateTimePicker.js @@ -1,129 +1,124 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; -export default IUI.module(class DateTimePicker extends IUIElement { - - +export default IUI.module( + class DateTimePicker extends IUIElement { constructor() { - super(); + super(); } - - get layout() { - return this._layout; + return this._layout; } set layout(value) { + if (value == this._layout) return; - if (value == this._layout) - return; + this.innerHTML = ""; - this.innerHTML = ""; + this._layout = value; - this._layout = value; + this.calendar = document.createElement("div"); + this.calendar.className = this.cssClass + "-calendar"; - this.calendar = document.createElement("div"); - this.calendar.className = this.cssClass + "-calendar"; + this.calendarContent = document.createElement("div"); + this.calendarContent.className = this.cssClass + "-calendar-content"; + this.table = document.createElement("table"); + this.header = this.table.createTHead(); + this.body = this.table.createTBody(); - this.calendarContent = document.createElement("div"); - this.calendarContent.className = this.cssClass + "-calendar-content"; + this.calendarContent.appendChild(this.table); - this.table = document.createElement("table"); - this.header = this.table.createTHead(); - this.body = this.table.createTBody(); + var tr = this.header.insertRow(); - this.calendarContent.appendChild(this.table); + for (var i = 0; i < 7; i++) { + var td = tr.insertCell(); + td.innerHTML = this.layout.day.formatter( + (i + this.layout.weekStart) % 7 + ); + td.className = this.cssClass + "-day"; + } - var tr = this.header.insertRow(); + this.tools = document.createElement("div"); + this.tools.className = this.cssClass + "-tools"; - for (var i = 0; i < 7; i++) { - var td = tr.insertCell(); - td.innerHTML = this.layout.day.formatter((i + this.layout.weekStart) % 7); - td.className = this.cssClass + "-day"; + this.month = document.createElement("div"); + this.month.className = this.cssClass + "-month"; + this.monthName = document.createElement("div"); + this.monthName.className = this.cssClass + "-name"; + this.nextMonth = document.createElement("div"); + this.nextMonth.className = this.cssClass + "-next"; + this.previousMonth = document.createElement("div"); + this.previousMonth.className = this.cssClass + "-previous"; + + this.month.appendChild(this.previousMonth); + this.month.appendChild(this.monthName); + this.month.appendChild(this.nextMonth); + + this.year = document.createElement("div"); + this.year.className = this.cssClass + "-year"; + this.yearName = document.createElement("div"); + this.yearName.className = this.cssClass + "-name"; + this.nextYear = document.createElement("div"); + this.nextYear.className = this.cssClass + "-next"; + this.previousYear = document.createElement("div"); + this.previousYear.className = this.cssClass + "-previous"; + + this.year.appendChild(this.previousYear); + this.year.appendChild(this.yearName); + this.year.appendChild(this.nextYear); + + this.tools.appendChild(this.month); + this.tools.appendChild(this.year); + + let self = this; + + this.nextMonth.addEventListener("click", function () { + self._month = (self._month + 1) % 12; + self.render(); + }); + + this.previousMonth.addEventListener("click", function () { + self._month = (self._month + 11) % 12; + self.render(); + }); + + this.nextYear.addEventListener("click", function () { + self._year++; + self.render(); + }); + + this.previousYear.addEventListener("click", function () { + self._year--; + self.render(); + }); + + for (let i = 0; i < 6; i++) { + tr = this.body.insertRow(); + + for (var j = 0; j < 7; j++) { + let td = tr.insertCell(tr); + td.className = this.cssClass + "-day"; + td.innerHTML = i + "x" + j; + td.addEventListener("click", function () { + self._day = parseInt(this.getAttribute("data-day")); + self._month = parseInt(this.getAttribute("data-month")); + self._year = parseInt(this.getAttribute("data-year")); + self._value.setDate(self._day); + self._value.setFullYear(self._year); + self._value.setMonth(self._month); + self.render(); + self._emit("select", { value: self._value }); + self._emit(":value", { value }); + }); } + } - this.tools = document.createElement("div"); - this.tools.className = this.cssClass + "-tools"; + this.calendar.appendChild(this.tools); + this.calendar.appendChild(this.calendarContent); - this.month = document.createElement("div"); - this.month.className = this.cssClass + "-month"; - this.monthName = document.createElement("div"); - this.monthName.className = this.cssClass + "-name"; - this.nextMonth = document.createElement("div"); - this.nextMonth.className = this.cssClass + "-next"; - this.previousMonth = document.createElement("div");; - this.previousMonth.className = this.cssClass + "-previous"; - - this.month.appendChild(this.previousMonth); - this.month.appendChild(this.monthName); - this.month.appendChild(this.nextMonth); - - this.year = document.createElement("div"); - this.year.className = this.cssClass + "-year"; - this.yearName = document.createElement("div"); - this.yearName.className = this.cssClass + "-name"; - this.nextYear = document.createElement("div"); - this.nextYear.className = this.cssClass + "-next"; - this.previousYear = document.createElement("div"); - this.previousYear.className = this.cssClass + "-previous"; - - this.year.appendChild(this.previousYear); - this.year.appendChild(this.yearName); - this.year.appendChild(this.nextYear); - - this.tools.appendChild(this.month); - this.tools.appendChild(this.year); - - let self = this; - - this.nextMonth.addEventListener("click", function () { - self._month = (self._month + 1) % 12; - self.render(); - }); - - this.previousMonth.addEventListener("click", function () { - self._month = (self._month + 11) % 12; - self.render(); - }); - - this.nextYear.addEventListener("click", function () { - self._year++; - self.render(); - }); - - this.previousYear.addEventListener("click", function () { - self._year--; - self.render(); - }); - - - for (let i = 0; i < 6; i++) { - tr = this.body.insertRow(); - - for (var j = 0; j < 7; j++) { - let td = tr.insertCell(tr); - td.className = this.cssClass + "-day"; - td.innerHTML = i + "x" + j; - td.addEventListener("click", function () { - self._day = parseInt(this.getAttribute("data-day")); - self._month = parseInt(this.getAttribute("data-month")); - self._year = parseInt(this.getAttribute("data-year")); - self._value.setDate(self._day); - self._value.setFullYear(self._year); - self._value.setMonth(self._month); - self.render(); - self._emit("select", { value: self._value }); - self._emit(":value", { value }); - }); - } - } - - this.calendar.appendChild(this.tools); - this.calendar.appendChild(this.calendarContent); - - /* + /* this.minutes = document.createElement("div"); this.minutes.className = this.cssClass + "-clock"; @@ -149,166 +144,180 @@ export default IUI.module(class DateTimePicker extends IUIElement { } */ - this.clock = document.createElement("div"); - this.clock.className = this.cssClass + "-clock"; + this.clock = document.createElement("div"); + this.clock.className = this.cssClass + "-clock"; - for (let i = 0; i < 1440; i += this.layout.time.range) { - var range = document.createElement("div"); - range.className = this.cssClass + "-time"; - range.innerHTML = this.layout.time.formatter(i); - range.setAttribute("data-time", i); - this.clock.appendChild(range); + for (let i = 0; i < 1440; i += this.layout.time.range) { + var range = document.createElement("div"); + range.className = this.cssClass + "-time"; + range.innerHTML = this.layout.time.formatter(i); + range.setAttribute("data-time", i); + this.clock.appendChild(range); - range.addEventListener("click", function () { - var t = parseInt(this.getAttribute("data-time")); - var h = Math.floor(t / 60); - var m = Math.floor(t % 60); - self._value.setHours(h); - self._value.setMinutes(m); - self._emit("select", self._value); - self.render(); - }); - } + range.addEventListener("click", function () { + var t = parseInt(this.getAttribute("data-time")); + var h = Math.floor(t / 60); + var m = Math.floor(t % 60); + self._value.setHours(h); + self._value.setMinutes(m); + self._emit("select", self._value); + self.render(); + }); + } - //this.timeList = document.createElement("div"); - //this.timeList = - this.appendChild(this.calendar); - this.appendChild(this.clock); - // this.appendChild(this.minutes); -// this.appendChild(this.hours); + //this.timeList = document.createElement("div"); + //this.timeList = + this.appendChild(this.calendar); + this.appendChild(this.clock); + // this.appendChild(this.minutes); + // this.appendChild(this.hours); - this.value = new Date(); + this.value = new Date(); } create() { + var self = this; - var self = this; + this._register("select"); + this.classList.add(this.cssClass); - this._register("select"); + this.layout = { + day: { + formatter: function (index) { + return ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][index]; + //return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][index]; + }, + }, + month: { + formatter: function (index) { + return [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", + ][index]; + }, + }, + year: { + formatter: function (value) { + return value; + }, + }, + time: { + formatter: function (value) { + var formatDigit = function (d) { + return d < 10 ? "0" + d : d; + }; + var h = Math.floor(value / 60); + var m = Math.floor(value % 60); + return formatDigit(h) + ":" + formatDigit(m); + }, + range: 15, + }, - this.classList.add(this.cssClass); - - this.layout = { - day: { - formatter: function (index) { - return ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][index]; - //return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][index]; - } - }, - month: { - formatter: function (index) { - return ["January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December"][index]; - } - }, - year: { - formatter: function (value) { - return value; - } - }, - time: { - formatter: function (value) { - var formatDigit = function (d) { return (d < 10) ? "0" + d : d; }; - var h = Math.floor(value / 60); - var m = Math.floor(value % 60); - return formatDigit(h) + ":" + formatDigit(m); - }, - range: 15 - }, - - weekStart: 5 - }; + weekStart: 5, + }; } render() { + var start = new Date(this._year, this._month, 1); + var offset = 1 - start.getDay() - ((7 - this.layout.weekStart) % 7); //(this.weekStart > 3 ? (this.weekStart - 7) : this.weekStart); - var start = new Date(this._year, this._month, 1); - var offset = 1 - start.getDay() - (7 - this.layout.weekStart) % 7;//(this.weekStart > 3 ? (this.weekStart - 7) : this.weekStart); + this.yearName.innerHTML = this.layout.year.formatter(this._year); + this.monthName.innerHTML = this.layout.month.formatter(this._month); - this.yearName.innerHTML = this.layout.year.formatter(this._year); - this.monthName.innerHTML = this.layout.month.formatter(this._month); + var today = new Date(); - var today = new Date(); + for (var i = 0; i < 42; i++) { + var rowIndex = Math.floor(i / 7); + var cellIndex = i % 7; - for (var i = 0; i < 42; i++) { - var rowIndex = Math.floor(i / 7); - var cellIndex = i % 7; + var td = this.body.rows[rowIndex].cells[cellIndex]; - var td = this.body.rows[rowIndex].cells[cellIndex]; + var d = new Date(this._year, this._month, offset + i); - var d = new Date(this._year, this._month, offset + i); + td.classList.remove(this.cssClass + "-different-month"); - td.classList.remove(this.cssClass + "-different-month"); + // gray it + if (d.getMonth() != this._month) + td.classList.add(this.cssClass + "-different-month"); - // gray it - if (d.getMonth() != this._month) - td.classList.add(this.cssClass + "-different-month"); + if ( + d.getDate() == today.getDate() && + d.getMonth() == today.getMonth() && + d.getFullYear() == today.getFullYear() + ) + td.classList.add(this.cssClass + "-day-today"); + else td.classList.remove(this.cssClass + "-day-today"); - if (d.getDate() == today.getDate() && d.getMonth() == today.getMonth() && d.getFullYear() == today.getFullYear()) - td.classList.add(this.cssClass + "-day-today"); - else - td.classList.remove(this.cssClass + "-day-today"); + if ( + d.getDate() == this._value.getDate() && + d.getFullYear() == this._value.getFullYear() && + d.getMonth() == this._value.getMonth() + ) + td.classList.add(this.cssClass + "-day-selected"); + else td.classList.remove(this.cssClass + "-day-selected"); - if (d.getDate() == this._value.getDate() - && d.getFullYear() == this._value.getFullYear() - && d.getMonth() == this._value.getMonth()) - td.classList.add(this.cssClass + "-day-selected"); - else - td.classList.remove(this.cssClass + "-day-selected"); + td.setAttribute("data-day", d.getDate()); + td.setAttribute("data-month", d.getMonth()); + td.setAttribute("data-year", d.getFullYear()); + td.innerHTML = d.getDate(); + } - td.setAttribute("data-day", d.getDate()); - td.setAttribute("data-month", d.getMonth()); - td.setAttribute("data-year", d.getFullYear()); + for (var i = 0; i < this.clock.children.length; i++) + this.clock.children[i].classList.remove( + this.cssClass + "-time-selected" + ); - td.innerHTML = d.getDate(); - } + var time = this._value.getHours() * 60 + this._value.getMinutes(); - - for (var i = 0; i < this.clock.children.length; i++) - this.clock.children[i].classList.remove(this.cssClass + "-time-selected"); - - var time = (this._value.getHours() * 60) + this._value.getMinutes(); - - if (time % this.layout.time.range == 0) - this.clock.children[time / this.layout.time.range].classList.add(this.cssClass + "-time-selected"); + if (time % this.layout.time.range == 0) + this.clock.children[time / this.layout.time.range].classList.add( + this.cssClass + "-time-selected" + ); } async setData(value) { + await super.setData(value); - await super.setData(value); - - - if (value != null && this.field != null) - this.value = this.data[this.field]; - + if (value != null && this.field != null) + this.value = this.data[this.field]; } get data() { - return super.data; + return super.data; } modified(name, value) { - if (name == this.field) - this.value = value; + if (name == this.field) this.value = value; } set value(value) { - if (value && !isNaN(value.getTime())) { - this._value = value; - this._month = value.getMonth(); - this._year = value.getFullYear(); - this._day = value.getDate(); - this.render(); - this._emit("select", { value }); - this._emit("modified", { value, property: "value" }); - //this.modified("value", ); - //this.modified("modified", { value }); - } + if (value && !isNaN(value.getTime())) { + this._value = value; + this._month = value.getMonth(); + this._year = value.getFullYear(); + this._day = value.getDate(); + this.render(); + this._emit("select", { value }); + this._emit("modified", { value, property: "value" }); + //this.modified("value", ); + //this.modified("modified", { value }); + } } get value() { - return this._value; + return this._value; } -}); \ No newline at end of file + } +); diff --git a/src/UI/Dialog.js b/src/UI/Dialog.js index 4c1ea99..b124204 100644 --- a/src/UI/Dialog.js +++ b/src/UI/Dialog.js @@ -2,271 +2,265 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; import IUIWindow from "./Window.js"; -export default IUI.module(class IUIDialog extends IUIWindow -{ - static moduleName = "dialog"; +export default IUI.module( + class IUIDialog extends IUIWindow { + static moduleName = "dialog"; - constructor() - { - super({ - closeable: true, - resizeable: true, - draggable: false, - _dragging: false, - _expanding: false, - x: 0, - y: 0, - visible: false, - modal: false - } - ); + constructor() { + super({ + closeable: true, + resizeable: true, + draggable: false, + _dragging: false, + _expanding: false, + x: 0, + y: 0, + visible: false, + modal: false, + }); - var self = this; + var self = this; - this._register("visible"); - this._register("resize"); + this._register("visible"); + this._register("resize"); - this.on("close", function(){ - self.hide(); - }); - } + this.on("close", function () { + self.hide(); + }); + } - create() - { - - super.create(); - var self = this; + create() { + super.create(); + var self = this; - if (this.modal) - { - this.background = iui("iui_app_background"); - if (!this.background) - { - var bg = document.createElement("div"); - bg.id="iui_app_background"; - document.body.insertAdjacentElement("afterBegin", bg); - this.background = iui(bg).background(); - } - + if (this.modal) { + this.background = iui("iui_app_background"); + if (!this.background) { + var bg = document.createElement("div"); + bg.id = "iui_app_background"; + document.body.insertAdjacentElement("afterBegin", bg); + this.background = iui(bg).background(); + } - // this.modal.className = this.customClass + "-modal-background"; + // this.modal.className = this.customClass + "-modal-background"; - this.classList.add(this.customClass + "-modal"); + this.classList.add(this.customClass + "-modal"); + } - } - + this.loading = document.createElement("div"); + this.loading.className = this.customClass + "-loading"; - this.loading = document.createElement("div"); - this.loading.className = this.customClass + "-loading"; + if (this.loadingText) this.loading.innerHTML = this.loadingText; + else { + var lc = document.createElement("div"); + lc.className = this.customClass + "-loading-content"; + this.loading.appendChild(lc); + } - if (this.loadingText) - this.loading.innerHTML = this.loadingText; - else - { - var lc = document.createElement("div"); - lc.className = this.customClass + "-loading-content"; - this.loading.appendChild(lc); - } + this.body.appendChild(this.loading); - this.body.appendChild(this.loading); + if (this.draggable) { + this.addEventListener("mousedown", function (e) { + self._startDragging(e); + }); + } else { + this.header.addEventListener("mousedown", function (e) { + self._startDragging(e); + }); + } + document.addEventListener("mouseup", function () { + self._stopDragging(); + self._stopExpanding(); + }); - if (this.draggable) - { - this.addEventListener("mousedown", function(e){ - self._startDragging(e); - }); - } - else - { - this.header.addEventListener('mousedown', function (e) { - self._startDragging(e); - }); - } + document.addEventListener("mousemove", function (e) { + if (self._dragging) self._drag(e); + else if (self._expanding) self._expand(e); + }); - document.addEventListener('mouseup', function () { - self._stopDragging(); - self._stopExpanding(); - }); - - document.addEventListener('mousemove', function (e) { - if (self._dragging) - self._drag(e); - else if (self._expanding) - self._expand(e); - }); + this.addEventListener("mousedown", function (e) { + if (self.style.cursor == "nwse-resize") self._startExpanding(e); + }); - this.addEventListener("mousedown", function(e){ - if (self.style.cursor == "nwse-resize") - self._startExpanding(e); - }); + this.addEventListener("mousemove", function (e) { + if (self._dragging) return; - this.addEventListener("mousemove", function(e) - { - if (self._dragging) - return; + if (!self._expanding) { + var x = + (e.pageX || + e.clientX + + (document.documentElement.scrollLeft + ? document.documentElement.scrollLeft + : document.body.scrollLeft)) - self.offsetLeft; + var y = + (e.pageY || + e.clientY + + (document.documentElement.scrollTop + ? document.documentElement.scrollTop + : document.body.scrollTop)) - self.offsetTop; - if (!self._expanding) - { - var x = (e.pageX || e.clientX + (document.documentElement.scrollLeft ? - document.documentElement.scrollLeft : - document.body.scrollLeft)) - self.offsetLeft; - var y = (e.pageY || e.clientY + (document.documentElement.scrollTop ? - document.documentElement.scrollTop : - document.body.scrollTop) ) - self.offsetTop; + if (self.clientWidth - x < 5 && self.clientHeight - y < 5) { + self.style.cursor = "nwse-resize"; + } else { + self.style.cursor = ""; + } + } + }); + } - if (self.clientWidth - x < 5 && self.clientHeight - y < 5) - { - self.style.cursor = "nwse-resize"; - } - else - { - self.style.cursor = ""; - } - } - }); + _startDragging(e) { + this._dragging = true; - } + this._dragX = + (e.pageX || + e.clientX + + (document.documentElement.scrollLeft + ? document.documentElement.scrollLeft + : document.body.scrollLeft)) - this.offsetLeft; + this._dragY = + (e.pageY || + e.clientY + + (document.documentElement.scrollTop + ? document.documentElement.scrollTop + : document.body.scrollTop)) - this.offsetTop; - _startDragging(e) - { - this._dragging = true; + //corssbrowser mouse pointer values + document.onselectstart = function () { + return false; + }; + } - this._dragX = (e.pageX || e.clientX + (document.documentElement.scrollLeft ? - document.documentElement.scrollLeft : - document.body.scrollLeft)) - this.offsetLeft; - this._dragY = (e.pageY || e.clientY + (document.documentElement.scrollTop ? - document.documentElement.scrollTop : - document.body.scrollTop) ) - this.offsetTop; + _drag(e) { + var x = + e.pageX || + e.clientX + + (document.documentElement.scrollLeft + ? document.documentElement.scrollLeft + : document.body.scrollLeft); + var y = + e.pageY || + e.clientY + + (document.documentElement.scrollTop + ? document.documentElement.scrollTop + : document.body.scrollTop); + this.style.top = y - this._dragY + "px"; // (y - self.y) + "px"; + this.style.left = x - this._dragX + "px"; //(x - self.x) + "px"; + this._emit("move", { left: this.offsetLeft, top: this.offsetTop }); + } - //corssbrowser mouse pointer values - document.onselectstart = function() {return false}; - } - - _drag(e) - { - var x = e.pageX || e.clientX + (document.documentElement.scrollLeft ? - document.documentElement.scrollLeft : - document.body.scrollLeft); - var y = e.pageY || e.clientY + (document.documentElement.scrollTop ? - document.documentElement.scrollTop : - document.body.scrollTop); - this.style.top = (y - this._dragY ) + "px";// (y - self.y) + "px"; - this.style.left = (x -this._dragX ) + "px";//(x - self.x) + "px"; - this._emit("move", {left: this.offsetLeft, top: this.offsetTop}); - } + _stopDragging() { + this._dragging = false; + } - _stopDragging() - { - this._dragging = false; - } + _startExpanding(e) { + document.onselectstart = function () { + return false; + }; + this._expanding = true; + this._dragX = + (e.pageX || + e.clientX + + (document.documentElement.scrollLeft + ? document.documentElement.scrollLeft + : document.body.scrollLeft)) - this.offsetLeft; + this._dragY = + (e.pageY || + e.clientY + + (document.documentElement.scrollTop + ? document.documentElement.scrollTop + : document.body.scrollTop)) - this.offsetTop; + this._width = this.clientWidth; + this._height = this.clientHeight; + } - _startExpanding(e) - { - document.onselectstart = function() {return false}; - this._expanding = true; - this._dragX = (e.pageX || e.clientX + (document.documentElement.scrollLeft ? - document.documentElement.scrollLeft : - document.body.scrollLeft)) - this.offsetLeft; - this._dragY = (e.pageY || e.clientY + (document.documentElement.scrollTop ? - document.documentElement.scrollTop : - document.body.scrollTop) ) - this.offsetTop; - this._width = this.clientWidth; - this._height = this.clientHeight; - } + _expand(e) { + var x = + (e.pageX || + e.clientX + + (document.documentElement.scrollLeft + ? document.documentElement.scrollLeft + : document.body.scrollLeft)) - this.offsetLeft; + var y = + (e.pageY || + e.clientY + + (document.documentElement.scrollTop + ? document.documentElement.scrollTop + : document.body.scrollTop)) - this.offsetTop; - _expand(e) - { - var x = (e.pageX || e.clientX + (document.documentElement.scrollLeft ? - document.documentElement.scrollLeft : - document.body.scrollLeft)) - this.offsetLeft; - var y = (e.pageY || e.clientY + (document.documentElement.scrollTop ? - document.documentElement.scrollTop : - document.body.scrollTop)) - this.offsetTop; + this.resize( + this._width + x - this._dragX, + this._height + y - this._dragY + ); + } - - this.resize(this._width + x -this._dragX, this._height + y - this._dragY); - } + _stopExpanding() { + this._expanding = false; + this.style.cursor = ""; + this._width = this.clientWidth; + this._height = this.clientHeight; + document.onselectstart = function () { + return true; + }; + } - _stopExpanding() - { - this._expanding = false; - this.style.cursor = ""; - this._width = this.clientWidth; - this._height = this.clientHeight; - document.onselectstart = function() {return true}; - } + setLoading(visible) { + if (this.footer) + for (var i = 0; i < this.footer.children.length; i++) + if (this.footer.children[i].nodeName == "BUTTON") + this.footer.children[i].disabled = visible; - setLoading(visible) - { - if (this.footer) - for(var i = 0; i < this.footer.children.length; i++) - if (this.footer.children[i].nodeName == "BUTTON") - this.footer.children[i].disabled = visible; + if (visible) + this.loading.classList.add(this.customClass + "-loading-visible"); + else this.loading.classList.remove(this.customClass + "-loading-visible"); - if (visible) - this.loading.classList.add(this.customClass + "-loading-visible"); - else - this.loading.classList.remove(this.customClass + "-loading-visible"); + return this; + } - return this; - } + center() { + this._updateSize(); + return this.move( + window.pageXOffset + window.innerWidth / 2 - this.offsetWidth / 2, + window.pageYOffset + window.innerHeight / 2 - this.offsetHeight / 2 + ); + } - center() - { - this._updateSize(); - return this.move(window.pageXOffset + (window.innerWidth / 2) - (this.offsetWidth / 2), - window.pageYOffset + (window.innerHeight / 2) - (this.offsetHeight / 2)); - } + setVisible(visible) { + if (visible == this.visible) return; - setVisible(visible) - { + this.visible = visible; - if (visible == this.visible) - return; + if (visible) { + this.classList.add(this.customClass + "-visible"); - this.visible = visible; - - if (visible) - { - this.classList.add(this.customClass + "-visible"); - - if (this.background) - { - this.background.setVisible(true); + if (this.background) { + this.background.setVisible(true); + } + //else + if (!this._shown) { + this._updateSize(); + this._shown = true; + } - } - //else - if (!this._shown) - { - this._updateSize(); - this._shown = true; - } + this.setFocus(true); - this.setFocus(true); + this._updateSize(); + } else { + this._updateSize(); - this._updateSize(); + this.classList.remove(this.customClass + "-visible"); + this.classList.remove(this.customClass + "-active"); - } - else - { - this._updateSize(); + if (this.background) this.background.setVisible(false); - this.classList.remove(this.customClass + "-visible"); - this.classList.remove(this.customClass + "-active"); + //this.modal.classList.remove(this.customClass + "-modal-background-visible"); - if (this.background) - this.background.setVisible(false); + this.setFocus(false); - //this.modal.classList.remove(this.customClass + "-modal-background-visible"); + var i = IUI._nav_list.indexOf(this); + if (i > -1) IUI._nav_list.splice(i, 1); - this.setFocus(false); - - var i = IUI._nav_list.indexOf(this); - if (i > -1) - IUI._nav_list.splice(i, 1); - - /* + /* IUI._nav_list.pop if (IUI._previousWindow) if (IUI._previousWindow.visible) @@ -276,33 +270,37 @@ export default IUI.module(class IUIDialog extends IUIWindow else window.location.hash = ""; */ - } + } - this._emit("visible", {visible}); + this._emit("visible", { visible }); - return this; - } - - hide() - { - this.setVisible(false); - return this; - } - - show() - { - this.setVisible(true); - return this; - } -}); + return this; + } + + hide() { + this.setVisible(false); + return this; + } + + show() { + this.setVisible(true); + return this; + } + } +); document.addEventListener("keydown", function (e) { - if ( e.keyCode === 27 ) { // ESC - var dialogs = IUI.registry.filter(function(o){ return ( o instanceof IUIDialog); }).filter(function(x){return x.focus;}); - for(var i = 0; i < dialogs.length; i++) - dialogs[i].hide(); - } -}) + if (e.keyCode === 27) { + // ESC + var dialogs = IUI.registry + .filter(function (o) { + return o instanceof IUIDialog; + }) + .filter(function (x) { + return x.focus; + }); + for (var i = 0; i < dialogs.length; i++) dialogs[i].hide(); + } +}); - -//IUI.module("dialog", IUIDialog, function(el, modal, properties){ return new IUIDialog(el, modal, properties);}); \ No newline at end of file +//IUI.module("dialog", IUIDialog, function(el, modal, properties){ return new IUIDialog(el, modal, properties);}); diff --git a/src/UI/DropDown.js b/src/UI/DropDown.js index 4c0e67e..6993920 100644 --- a/src/UI/DropDown.js +++ b/src/UI/DropDown.js @@ -1,48 +1,45 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; -export default IUI.module(class DropDown extends IUIElement { +export default IUI.module( + class DropDown extends IUIElement { constructor() { - super({"direction": "down" }); + super({ direction: "down" }); - var self = this; + var self = this; - this._register("visible"); + this._register("visible"); - this.visible = false; + this.visible = false; - // this.classList.add(this.cssClass + "-" + this.direction); + // this.classList.add(this.cssClass + "-" + this.direction); - this.menu = this.getElementsByClassName(this.cssClass + "-menu")[0]; + this.menu = this.getElementsByClassName(this.cssClass + "-menu")[0]; + //this.arrow = document.createElement("div"); + //this.arrow.className = this.customClass + "-arrow"; - //this.arrow = document.createElement("div"); - //this.arrow.className = this.customClass + "-arrow"; + //this.el.appendChild(this.arrow); + if (this.getAttribute("fixed")) { + this._fixed = true; + document.body.appendChild(this.menu); + } - //this.el.appendChild(this.arrow); + //this.el.appendChild(this.menu); - if (this.getAttribute("fixed")) - { - this._fixed = true; - document.body.appendChild(this.menu); - } + this.addEventListener("click", function (e) { + var t = e.target; + do { + if (t == self.menu) return; + } while ((t = t.parentElement)); - //this.el.appendChild(this.menu); + self.setVisible(!self.visible); + }); - this.addEventListener("click", function (e) { - var t = e.target - do { - if (t == self.menu) - return; - } while (t = t.parentElement) + IUI._menus.push(this); - self.setVisible(!self.visible); - }); - - IUI._menus.push(this); - - /* + /* document.body.addEventListener("click", function(e) { if (!self.visible) @@ -62,135 +59,128 @@ export default IUI.module(class DropDown extends IUIElement { } set fixed(value) { - if (value) - document.body.appendChild(this.menu); - this._fixed = value; + if (value) document.body.appendChild(this.menu); + this._fixed = value; } get fixed() { - return this._fixed; + return this._fixed; } hide() { - return this.setVisible(false); + return this.setVisible(false); } show() { - return this.setVisible(true); + return this.setVisible(true); } getOffset() { - var el = this; - var _x = 0; - var _y = 0; - while (!isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) { - _x += el.offsetLeft - el.scrollLeft; - _y += el.offsetTop - el.scrollTop; - el = el.offsetParent; - } - _x += window.pageXOffset; - _y += window.pageYOffset; + var el = this; + var _x = 0; + var _y = 0; + while (!isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) { + _x += el.offsetLeft - el.scrollLeft; + _y += el.offsetTop - el.scrollTop; + el = el.offsetParent; + } + _x += window.pageXOffset; + _y += window.pageYOffset; - return { top: _y, left: _x, width: this.clientWidth, height: this.clientHeight }; + return { + top: _y, + left: _x, + width: this.clientWidth, + height: this.clientHeight, + }; } set data(value) { - // console.log("DD", value); - super.data = value; -// console.log("VV", this._uiBindings, this._dataBindings); + // console.log("DD", value); + super.data = value; + // console.log("VV", this._uiBindings, this._dataBindings); } setVisible(visible) { - this.visible = visible; + this.visible = visible; - if (!this.fixed) { - if (visible) { - this.menu.classList.add(this.cssClass + "-menu-visible"); - this.classList.add(this.cssClass + "-visible"); - } - else { - this.menu.classList.remove(this.cssClass + "-menu-visible"); - this.classList.remove(this.cssClass + "-visible"); - } + if (!this.fixed) { + if (visible) { + this.menu.classList.add(this.cssClass + "-menu-visible"); + this.classList.add(this.cssClass + "-visible"); + } else { + this.menu.classList.remove(this.cssClass + "-menu-visible"); + this.classList.remove(this.cssClass + "-visible"); } - else { - if (visible) { - var rect = this.getBoundingClientRect(); + } else { + if (visible) { + var rect = this.getBoundingClientRect(); - var menuWidth = this.menu.clientWidth; - var menuHeight = this.menu.clientHeight; + var menuWidth = this.menu.clientWidth; + var menuHeight = this.menu.clientHeight; - if (menuWidth > document.body.clientWidth) { - menuWidth = (document.body.clientWidth - 10); - this.menu.style.width = menuWidth + "px"; - } + if (menuWidth > document.body.clientWidth) { + menuWidth = document.body.clientWidth - 10; + this.menu.style.width = menuWidth + "px"; + } + var startX = rect.left + (rect.width / 2 - menuWidth / 2); - var startX = rect.left + (rect.width / 2 - menuWidth / 2); + if (this.direction == "up") { + // var menuTop = rect.top - this.arrow.clientHeight - this.menu.clientHeight; + var menuTop = rect.top - this.menu.clientHeight; + if (menuTop < 0) { + menuTop = 5; + // this.menu.style.height = (rect.top - this.arrow.clientHeight ) + "px"; + this.menu.style.height = rect.top + "px"; - if (this.direction == "up") { - // var menuTop = rect.top - this.arrow.clientHeight - this.menu.clientHeight; - var menuTop = rect.top - this.menu.clientHeight; + this.menu.classList.add(this.cssClass + "-menu-oversized"); + } else + this.menu.classList.remove(this.cssClass + "-menu-oversized"); - if (menuTop < 0) { - menuTop = 5; - // this.menu.style.height = (rect.top - this.arrow.clientHeight ) + "px"; - this.menu.style.height = (rect.top) + "px"; + //this.arrow.classList.remove(this.customClass + "-arrow-down"); + //this.arrow.classList.add(this.customClass + "-arrow-up"); + //this.arrow.style.top = ( rect.top - this.arrow.clientHeight ) + "px"; + this.menu.style.top = menuTop + "px"; + } else { + //var menuTop = rect.top + rect.height + this.arrow.clientHeight; + var menuTop = rect.top + rect.height; - this.menu.classList.add(this.cssClass + "-menu-oversized"); - } - else - this.menu.classList.remove(this.cssClass + "-menu-oversized"); + //this.arrow.classList.remove(this.customClass + "-arrow-up"); + //this.arrow.classList.add(this.customClass + "-arrow-down"); + //this.arrow.style.top = ( rect.top + rect.height ) + "px"; + this.menu.style.top = menuTop + "px"; - //this.arrow.classList.remove(this.customClass + "-arrow-down"); - //this.arrow.classList.add(this.customClass + "-arrow-up"); - //this.arrow.style.top = ( rect.top - this.arrow.clientHeight ) + "px"; - this.menu.style.top = (menuTop) + "px"; - } - else { - //var menuTop = rect.top + rect.height + this.arrow.clientHeight; - var menuTop = rect.top + rect.height; - - //this.arrow.classList.remove(this.customClass + "-arrow-up"); - //this.arrow.classList.add(this.customClass + "-arrow-down"); - //this.arrow.style.top = ( rect.top + rect.height ) + "px"; - - this.menu.style.top = menuTop + "px"; - - if (menuTop + menuHeight > document.body.clientHeight) { - this.menu.style.height = (document.body.clientHeight - menuTop) + "px"; - this.menu.classList.add(this.cssClass + "-menu-oversized"); - } - else { - this.menu.classList.remove(this.cssClass + "-menu-oversized"); - } - } - - if (startX < 0) - startX = 5; - else if (startX + menuWidth > document.body.clientWidth) - startX = document.body.clientWidth - menuWidth - 5; - - - //this.arrow.style.left = (rect.left + (rect.width/2 - this.arrow.clientWidth/2)) + "px"; - this.menu.style.left = startX + "px"; - - //this.arrow.classList.add(this.customClass + "-arrow-visible"); - this.menu.classList.add(this.cssClass + "-menu-visible"); - this.classList.add(this.cssClass + "-visible"); - - } - else { - //this.arrow.classList.remove(this.customClass + "-arrow-visible"); - this.menu.classList.remove(this.cssClass + "-menu-visible"); - this.classList.remove(this.cssClass + "-visible"); + if (menuTop + menuHeight > document.body.clientHeight) { + this.menu.style.height = + document.body.clientHeight - menuTop + "px"; + this.menu.classList.add(this.cssClass + "-menu-oversized"); + } else { + this.menu.classList.remove(this.cssClass + "-menu-oversized"); } + } + + if (startX < 0) startX = 5; + else if (startX + menuWidth > document.body.clientWidth) + startX = document.body.clientWidth - menuWidth - 5; + + //this.arrow.style.left = (rect.left + (rect.width/2 - this.arrow.clientWidth/2)) + "px"; + this.menu.style.left = startX + "px"; + + //this.arrow.classList.add(this.customClass + "-arrow-visible"); + this.menu.classList.add(this.cssClass + "-menu-visible"); + this.classList.add(this.cssClass + "-visible"); + } else { + //this.arrow.classList.remove(this.customClass + "-arrow-visible"); + this.menu.classList.remove(this.cssClass + "-menu-visible"); + this.classList.remove(this.cssClass + "-visible"); } + } - this._emit("visible", { visible}); - - return this; + this._emit("visible", { visible }); + return this; } -}); \ No newline at end of file + } +); diff --git a/src/UI/Form.js b/src/UI/Form.js index af49cd1..0e5f6ea 100644 --- a/src/UI/Form.js +++ b/src/UI/Form.js @@ -3,46 +3,45 @@ import { IUI } from "../Core/IUI.js"; import Tabs from "./Tabs.js"; import Tab from "./Tab.js"; -export default IUI.module(class Form extends IUIElement { +export default IUI.module( + class Form extends IUIElement { constructor() { - super(); + super(); } create() { + this._container = document.createElement("div"); + this._container.className = "container"; - this._container = document.createElement("div"); - this._container.className = "container"; + this._actions = document.createElement("div"); + this._actions.className = "actions"; - this._actions = document.createElement("div"); - this._actions.className = "actions"; + this._save = document.createElement("button"); + this._save.className = "button"; + this._save.innerHTML = this.hasAttribute("save") + ? this.getAttribute("save") + : "Save"; + this._cancel = document.createElement("button"); + this._cancel.className = "button"; + this._cancel = this.hasAttribute("cancel") + ? this.getAttribute("cancel") + : "Cancel"; - - this._save = document.createElement("button"); - this._save.className = "button"; - this._save.innerHTML = this.hasAttribute("save") ? this.getAttribute("save") : "Save"; - this._cancel = document.createElement("button"); - this._cancel.className = "button"; - this._cancel = this.hasAttribute("cancel") ? this.getAttribute("cancel") : "Cancel"; + this._save.addEventListener("click", x => {}); - this._save.addEventListener("click", (x) => { + this._cancel.addEventListener("click", x => { + window.router.back(); + }); - }); + this._actions.appendChild(this._save); + this._actions.appendChild(this._cancel); - this._cancel.addEventListener("click", (x) => { - window.router.back(); - }); - - - this._actions.appendChild(this._save); - this._actions.appendChild(this._cancel); - - this.appendChild(this._container); - this.appendChild(this._actions); - + this.appendChild(this._container); + this.appendChild(this._actions); } set layout(value) { - /* + /* mode:tabs, tabs: [ @@ -52,50 +51,48 @@ export default IUI.module(class Form extends IUIElement { ]} ] */ - // render layout - if (value.mode == "tabs") { - for (var i = 0; i < this.layout.tabs.length; i++) { - // render tab - this.mode = "tabs"; - this._tabs = new Tabs(); - var tab = new Tab(); - this._tabs.add(tab); - for (var j = 0; j < this._tabs.length; j++) { - - } - this.layout.tasbs[i].content - } + // render layout + if (value.mode == "tabs") { + for (var i = 0; i < this.layout.tabs.length; i++) { + // render tab + this.mode = "tabs"; + this._tabs = new Tabs(); + var tab = new Tab(); + this._tabs.add(tab); + for (var j = 0; j < this._tabs.length; j++) {} + this.layout.tasbs[i].content; } + } } set data(value) { - var self = this; + var self = this; - if (value == null) - this._input.value = ""; - else { - this._input.value = value[this._field]; + if (value == null) this._input.value = ""; + else { + this._input.value = value[this._field]; - if (value.on) - value.on("modified", (propertyName, value) => { - if (propertyName == self._field) - self._input.value = value[self._field]; - }); - } - //super.data = data; + if (value.on) + value.on("modified", (propertyName, value) => { + if (propertyName == self._field) + self._input.value = value[self._field]; + }); + } + //super.data = data; } get layout() { - return this._input.value; + return this._input.value; } set layout(value) { - // load layout + // load layout - for (var i = 0; i < value.length; i++) { - // [{tab: },{}] - } + for (var i = 0; i < value.length; i++) { + // [{tab: },{}] + } - this._input.value = value; + this._input.value = value; } -}); \ No newline at end of file + } +); diff --git a/src/UI/Grid.js b/src/UI/Grid.js index dd5f2e6..7f63ef0 100644 --- a/src/UI/Grid.js +++ b/src/UI/Grid.js @@ -1,204 +1,205 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; -export default IUI.module(class Grid extends IUIElement { - constructor() - { - super({index: "iid", - layout: {content: {field: "name", formatter: null}, - title: {field: "content", formatter: null}, - footer: {field: "footer", formatter: null}}}); +export default IUI.module( + class Grid extends IUIElement { + constructor() { + super({ + index: "iid", + layout: { + content: { field: "name", formatter: null }, + title: { field: "content", formatter: null }, + footer: { field: "footer", formatter: null }, + }, + }); - this._register("add"); - this._register("layout"); - this._register("contextmenu"); + this._register("add"); + this._register("layout"); + this._register("contextmenu"); - this.windows = []; - } + this.windows = []; + } create() { - for (var i = 0; i < this.children.length; i++) - this.add(this.children[i]); + for (var i = 0; i < this.children.length; i++) this.add(this.children[i]); } - setGridLayout(style) - { - this.style.grid = style; - this._emit("layout", style, this); - return this; - } + setGridLayout(style) { + this.style.grid = style; + this._emit("layout", style, this); + return this; + } add(win) { - let self = this; + let self = this; - win.setAttribute("draggable", true); - win.addEventListener("dragstart", function (e) { - e.dataTransfer.effectAllowed = 'move'; - self._dragItem = this; + win.setAttribute("draggable", true); + win.addEventListener("dragstart", function (e) { + e.dataTransfer.effectAllowed = "move"; + self._dragItem = this; - this.classList.add(self.cssClass + '-window-drag'); + this.classList.add(self.cssClass + "-window-drag"); + }); - }); + win.addEventListener("dragover", function (e) { + if (self._dragItem) { + e.preventDefault(); + this.classList.add(self.cssClass + "-window-over"); + e.dataTransfer.dropEffect = "move"; // See the section on the DataTransfer object. + } + }); - win.addEventListener("dragover", function (e) { - if (self._dragItem) { - e.preventDefault(); - this.classList.add(self.cssClass + '-window-over'); - e.dataTransfer.dropEffect = 'move'; // See the section on the DataTransfer object. - } - }); + win.addEventListener("dragleave", function (e) { + if (e.preventDefault) e.preventDefault(); - win.addEventListener("dragleave", function (e) { + this.classList.remove(self.cssClass + "-window-over"); + }); - if (e.preventDefault) - e.preventDefault(); + win.addEventListener("dragend", function (e) { + this.classList.remove(self.cssClass + "-window-drag"); + self._dragItem = null; + }); - this.classList.remove(self.cssClass + "-window-over"); - }); + win.addEventListener("drop", function (e) { + self._dragItem.classList.remove(self.cssClass + "-window-drag"); + e.currentTarget.classList.remove(self.cssClass + "-window-over"); - win.addEventListener("dragend", function (e) { - this.classList.remove(self.cssClass + '-window-drag'); - self._dragItem = null; - }); + for (var i = 0; i < self.children.length; i++) + if (self.children[i] == self._dragItem) { + self.insertBefore(self._dragItem, e.currentTarget.nextSibling); + break; + } else if (self.children[i] == e.currentTarget) { + self.insertBefore(self._dragItem, e.currentTarget); + break; + } - win.addEventListener("drop", function (e) { - self._dragItem.classList.remove(self.cssClass + "-window-drag"); - e.currentTarget.classList.remove(self.cssClass + "-window-over"); + self._dragItem = null; + }); - for (var i = 0; i < self.children.length; i++) - if (self.children[i] == self._dragItem) { - self.insertBefore(self._dragItem, e.currentTarget.nextSibling); - break; - } - else if (self.children[i] == e.currentTarget) { - self.insertBefore(self._dragItem, e.currentTarget); - break; - } + win.addEventListener("contextmenu", function (e) { + self.selected = win; + self._emit("contextmenu", { win }); + }); - self._dragItem = null; - }); - - win.addEventListener("contextmenu", function (e) { - self.selected = win; - self._emit("contextmenu", { win }); - }); - - win.on("close", function () { - self.remove(win); - }); + win.on("close", function () { + self.remove(win); + }); } - addOld(item) - { + addOld(item) { + var self = this; - var self = this; + var li = item; //document.createElement("li"); + //li.setAttribute("data-id", item[this.index]); - var li = item;//document.createElement("li"); - //li.setAttribute("data-id", item[this.index]); + li.setAttribute("draggable", true); - li.setAttribute("draggable", true); + li.addEventListener("dragstart", function (e) { + e.dataTransfer.effectAllowed = "move"; + self._dragItem = this; - li.addEventListener("dragstart", function(e){ - e.dataTransfer.effectAllowed = 'move'; - self._dragItem = this; + this.classList.add(self.cssClass + "-window-drag"); + }); - this.classList.add(self.cssClass + '-window-drag'); + li.addEventListener("dragover", function (e) { + if (self._dragItem) { + e.preventDefault(); + this.classList.add(self.cssClass + "-window-over"); + e.dataTransfer.dropEffect = "move"; // See the section on the DataTransfer object. + } + }); - }); + li.addEventListener("dragleave", function (e) { + if (e.preventDefault) e.preventDefault(); - li.addEventListener("dragover", function(e){ - if (self._dragItem) - { - e.preventDefault(); - this.classList.add(self.cssClass + '-window-over'); - e.dataTransfer.dropEffect = 'move'; // See the section on the DataTransfer object. - } - }); + this.classList.remove(self.cssClass + "-window-over"); + }); - li.addEventListener("dragleave", function(e){ + li.addEventListener("dragend", function (e) { + this.classList.remove(self.cssClass + "-window-drag"); + self._dragItem = null; + }); - if (e.preventDefault) - e.preventDefault(); + li.addEventListener("drop", function (e) { + self._dragItem.classList.remove(self.cssClass + "-window-drag"); + e.currentTarget.classList.remove(self.cssClass + "-window-over"); - this.classList.remove(self.cssClass + "-window-over"); - }); + for (var i = 0; i < self.children.length; i++) + if (self.children[i] == self._dragItem) { + self.insertBefore(self._dragItem, e.currentTarget.nextSibling); + break; + } else if (self.children[i] == e.currentTarget) { + self.insertBefore(self._dragItem, e.currentTarget); + break; + } - li.addEventListener("dragend", function(e){ - this.classList.remove(self.cssClass + '-window-drag'); - self._dragItem = null; - }); + self._dragItem = null; + }); - li.addEventListener("drop", function(e){ - self._dragItem.classList.remove(self.cssClass + "-window-drag"); - e.currentTarget.classList.remove(self.cssClass + "-window-over"); + li.addEventListener("contextmenu", function (e) { + self.selected = win; + self._emit("contextmenu", item, win, this, e); + }); - for(var i = 0; i < self.children.length; i++) - if (self.children[i] == self._dragItem) - { - self.insertBefore(self._dragItem, e.currentTarget.nextSibling); - break; - } - else if (self.children[i] == e.currentTarget) - { - self.insertBefore(self._dragItem, e.currentTarget); - break; - } - - self._dragItem = null; - }); + var win = iui(li).window({ + draggable: false, + title: this.layout.title.formatter + ? this.layout.title.formatter(item[this.layout.title.field], item) + : item[this.layout.title.field], + }); - li.addEventListener("contextmenu", function(e){ - self.selected = win; - self._emit("contextmenu", item, win, this, e); - }); + var body = this.layout.content.formatter + ? this.layout.content.formatter( + item[this.layout.content.field], + item, + win, + this + ) + : item[this.layout.content.field]; + if (body instanceof HTMLElement) win.body.appendChild(body); + else win.body.innerHTML = body; - var win = iui(li).window({draggable: false, title: this.layout.title.formatter ? this.layout.title.formatter(item[this.layout.title.field], item) : item[this.layout.title.field]}); + var footer = this.layout.footer.formatter + ? this.layout.footer.formatter( + item[this.layout.footer.field], + item, + win, + this + ) + : item[this.layout.footer.field]; + if (footer != null) { + var fe = document.createElement("div"); + fe.className = "window-footer"; - var body = this.layout.content.formatter ? this.layout.content.formatter(item[this.layout.content.field], item, win, this) : item[this.layout.content.field]; - if (body instanceof HTMLElement) - win.body.appendChild(body); - else - win.body.innerHTML = body; + if (footer instanceof HTMLElement) fe.appendChild(footer); + else fe.innerHTML = footer; - var footer = this.layout.footer.formatter ? this.layout.footer.formatter(item[this.layout.footer.field], item, win, this) : item[this.layout.footer.field]; - if (footer != null) - { - var fe = document.createElement("div"); - fe.className = "window-footer"; + win.appendChild(fe); + } - if (footer instanceof HTMLElement) - fe.appendChild(footer); - else - fe.innerHTML = footer; + win.on("close", function () { + self.remove(win); + }); - win.appendChild(fe); - } + this.appendChild(li); - win.on("close", function(){ - self.remove(win); - }); + win.control = item; - this.appendChild(li); + this.windows.push(win); - win.control = item; + this._emit("add", item, win, this); - this.windows.push(win); + return this; + //win._updateSize(); + } - this._emit("add", item, win, this); + remove(win) { + win.destroy(); + this.removeChild(win); + } - return this; - //win._updateSize(); - } - - remove(win) - { - win.destroy(); - this.removeChild(win); - } - - clear() - { - while (this.children.length > 0) - this.removeChild(this.children[0]); - } -}); \ No newline at end of file + clear() { + while (this.children.length > 0) this.removeChild(this.children[0]); + } + } +); diff --git a/src/UI/Input.js b/src/UI/Input.js index aa69b14..692f65e 100644 --- a/src/UI/Input.js +++ b/src/UI/Input.js @@ -1,163 +1,159 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; -export default IUI.module(class Input extends IUIElement { +export default IUI.module( + class Input extends IUIElement { constructor() { - super({ formatter: (x) => x }); - this._register("input"); - this._register("change"); + super({ formatter: x => x }); + this._register("input"); + this._register("change"); } _checkValidity() { - if (this.validate != null) { - try { - let valid = this.validate.apply(this); - if (!valid) { - this.setAttribute("invalid", ""); - this.classList.add(this.cssClass + "-invalid"); - return false; - } - else { - this.removeAttribute("invalid"); - this.classList.remove(this.cssClass + "-invalid"); - return true; - } - } - catch (e) { - console.log("Validation Error", e); - return false; - } + if (this.validate != null) { + try { + let valid = this.validate.apply(this); + if (!valid) { + this.setAttribute("invalid", ""); + this.classList.add(this.cssClass + "-invalid"); + return false; + } else { + this.removeAttribute("invalid"); + this.classList.remove(this.cssClass + "-invalid"); + return true; + } + } catch (e) { + console.log("Validation Error", e); + return false; } + } - return true; + return true; } - get caption(){ - return this.getAttribute("caption");// this._span.innerHTML; + get caption() { + return this.getAttribute("caption"); // this._span.innerHTML; } - set caption(value){ - this.setAttribute("caption", value); - this._span.innerHTML = value; + set caption(value) { + this.setAttribute("caption", value); + this._span.innerHTML = value; } create() { + this.isAuto = this.hasAttribute("auto"); + this.field = this.getAttribute("field"); - this.isAuto = this.hasAttribute("auto"); - this.field = this.getAttribute("field"); - - - if (this.field != null) - { - this.setAttribute(":data", `d['${this.field}']`) - this.setAttribute("async:revert", `d['${this.field}'] = await this.getData()`); - } + if (this.field != null) { + this.setAttribute(":data", `d['${this.field}']`); + this.setAttribute( + "async:revert", + `d['${this.field}'] = await this.getData()` + ); + } - this._span = document.createElement("span"); - this._span.innerHTML = this.getAttribute("caption"); + this._span = document.createElement("span"); + this._span.innerHTML = this.getAttribute("caption"); - this._input = document.createElement("input"); - this._input.placeholder = " "; + this._input = document.createElement("input"); + this._input.placeholder = " "; - let self = this; + let self = this; - this._input.addEventListener("input", () => { - if (self._checkValidity() && self.isAuto) - this.revert(); - //self.data[self.field] = self.value; + this._input.addEventListener("input", () => { + if (self._checkValidity() && self.isAuto) this.revert(); + //self.data[self.field] = self.value; + }); + + this._input.addEventListener("change", () => { + self._emit("change", { value: self.value }); + }); + + this.type = this.hasAttribute("type") + ? this.getAttribute("type").toLowerCase() + : "text"; + + this.accept = this.getAttribute("accept"); + + this.appendChild(this._input); + this.appendChild(this._span); + + if (this.type == "password") { + this._eye = document.createElement("div"); + this._eye.className = this.cssClass + "-eye"; + this._eye.addEventListener("mousedown", () => { + self._input.type = "text"; + self._eye.classList.add(self.cssClass + "-eye-active"); + }); + this._eye.addEventListener("mouseup", () => { + self._input.type = "password"; + self._eye.classList.remove(self.cssClass + "-eye-active"); }); - this._input.addEventListener("change", () => { - self._emit("change", { value: self.value }); - }); - - this.type = this.hasAttribute("type") ? this.getAttribute("type").toLowerCase() : "text"; - - this.accept = this.getAttribute("accept"); - - this.appendChild(this._input); - this.appendChild(this._span); - - if (this.type == "password") - { - this._eye = document.createElement("div"); - this._eye.className = this.cssClass + "-eye"; - this._eye.addEventListener("mousedown", ()=>{ - self._input.type = "text"; - self._eye.classList.add(self.cssClass + "-eye-active"); - }); - this._eye.addEventListener("mouseup", ()=>{ - self._input.type = "password"; - self._eye.classList.remove(self.cssClass + "-eye-active"); - }); - - this.appendChild(this._eye); - - } - + this.appendChild(this._eye); + } } async updateAttributes(deep, parentData) { - await super.updateAttributes(deep, parentData); - //this._input.type = this.type; - //this._input.value = this.value; + await super.updateAttributes(deep, parentData); + //this._input.type = this.type; + //this._input.value = this.value; } set type(value) { - this._input.type = value; + this._input.type = value; } get type() { - return this._input.type; + return this._input.type; } - set accept(value){ - this._input.accept = value; + set accept(value) { + this._input.accept = value; } get accept() { - return this._input.accept; + return this._input.accept; } set disabled(value) { - if (value) - this.setAttribute("disabled", "disabled"); - else - this.removeAttribute("disabled"); + if (value) this.setAttribute("disabled", "disabled"); + else this.removeAttribute("disabled"); - this._input.disabled = value; + this._input.disabled = value; } get disabled() { - return this._input.disabled; + return this._input.disabled; } set enabled(value) { - this.disabled = !value; + this.disabled = !value; } get enabled() { - return !this._input.disabled; + return !this._input.disabled; } async setData(value) { + await super.setData(value); - await super.setData(value); + if (this.type == "checkbox") this._input.checked = value; + else if (this.type == "date") + this._input.value = + value != null ? value.toISOString().slice(0, 10) : value; + else if ( + this.type == null || + this.type == "text" || + this.type == "search" || + this.type == "password" + ) + this._input.value = value == null ? "" : value; + else this._input.value = value; - if (this.type == "checkbox") - this._input.checked = value; - else if (this.type == "date") - this._input.value = value != null ? value.toISOString().slice(0, 10) : value; - else if (this.type == null || this.type == "text" || this.type == "search" || this.type == "password") - this._input.value = value == null ? '' : value; - else - this._input.value = value; + if (this._checkValidity() && this.isAuto) this.revert(); - if (this._checkValidity() && this.isAuto) - this.revert(); - - - /* + /* await super.setData(value); if (value != null && this.field != null) this.value = value[this.field]; @@ -166,40 +162,30 @@ export default IUI.module(class Input extends IUIElement { */ } - // modified(name, value) { // if (name == this.field) { // this.value = value; // } // } - async getData(){ - if (this.type == "checkbox") - return this._input.checked; - else if (this.type == "date") - return new Date(this._input.value); - else if (this.type == "file") - return new Uint8Array(await this._input.files[0].arrayBuffer()); - else - return this._input.value; + async getData() { + if (this.type == "checkbox") return this._input.checked; + else if (this.type == "date") return new Date(this._input.value); + else if (this.type == "file") + return new Uint8Array(await this._input.files[0].arrayBuffer()); + else return this._input.value; } - get data() - { - if (this.type == "checkbox") - return this._input.checked; - else if (this.type == "date") - return new Date(this._input.value); - else if (this.type == "file") - { - return new Promise((resolve)=>{ - this._input.files[0].arrayBuffer().then((x)=>{ - resolve(new Uint8Array(x)); - }); - }); - } - else - return this._input.value; + get data() { + if (this.type == "checkbox") return this._input.checked; + else if (this.type == "date") return new Date(this._input.value); + else if (this.type == "file") { + return new Promise(resolve => { + this._input.files[0].arrayBuffer().then(x => { + resolve(new Uint8Array(x)); + }); + }); + } else return this._input.value; } /* @@ -221,7 +207,7 @@ export default IUI.module(class Input extends IUIElement { // if (this.type == "checkbox") // this._input.checked = value; - // else if (this.type == "date") + // else if (this.type == "date") // this._input.value = value != null ? value.toISOString().slice(0, 10) : value; // else if (this.type == null || this.type == "text") // this._input.value = value == null ? '' : value; @@ -230,4 +216,5 @@ export default IUI.module(class Input extends IUIElement { // this._checkValidity(); // } -}); \ No newline at end of file + } +); diff --git a/src/UI/Location.js b/src/UI/Location.js index 5e79073..77a6cb3 100644 --- a/src/UI/Location.js +++ b/src/UI/Location.js @@ -1,39 +1,37 @@ - import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; -import Link from '../Router/Link.js'; +import Link from "../Router/Link.js"; -export default IUI.module(class Location extends IUIElement { +export default IUI.module( + class Location extends IUIElement { constructor() { - super(); + super(); } create() { - let self = this; - window.router.on("route", (e) => { + let self = this; + window.router.on("route", e => { + self.textContent = ""; // clear everything - self.textContent = ''; // clear everything + let html = ""; + let route = e.route; - - let html = ""; - let route = e.route; - - var current = document.createElement("div"); - current.innerHTML = route.caption; + var current = document.createElement("div"); + current.innerHTML = route.caption; - self.append(current); + self.append(current); - while (route = route.parent) { + while ((route = route.parent)) { + var sep = document.createElement("span"); + self.prepend(sep); - var sep = document.createElement("span"); - self.prepend(sep); - - let link = new Link(); - link.link = route.link; - link.innerHTML = route.caption; + let link = new Link(); + link.link = route.link; + link.innerHTML = route.caption; - self.prepend(link); - } - }); + self.prepend(link); + } + }); } -}); \ No newline at end of file + } +); diff --git a/src/UI/Login.js b/src/UI/Login.js index 01e066d..a00fec7 100644 --- a/src/UI/Login.js +++ b/src/UI/Login.js @@ -1,14 +1,12 @@ import IUIElement from "../Core/IUIElement.js"; import { IUI } from "../Core/IUI.js"; -export default IUI.module(class Login extends IUIElement -{ - constructor() - { - super(); +export default IUI.module( + class Login extends IUIElement { + constructor() { + super(); - - var template = `