diff --git a/css/iui.css b/css/iui.css index 274a520..fae6bbd 100644 --- a/css/iui.css +++ b/css/iui.css @@ -2778,7 +2778,7 @@ html[dir='rtl'] .multiselect-list-remove { margin: 6px; background-image: var(--search); background-repeat: no-repeat; - background-size: 25px; + background-size: 19px; background-position: 2px 50%; padding-left: 30px; } @@ -2797,12 +2797,31 @@ html[dir='rtl'] .multiselect-list-remove { transition: max-height ease-in-out 0.3s; } +.navbar-item[level='1'] { + padding-left: 10px; +} + +html[dir='rtl'] .navbar-item[level='1'] { + padding-right: 10px; + padding-left: unset; +} + + .navbar-container { overflow: auto; visibility: hidden; } +.navbar-item > i-link +{ + display: flex; + padding: 3px 10px; +} + +.navbar-item > i-link > span { + flex: 1; +} .navbar i-link > span > span, .sitebar i-link > span > span @@ -2812,6 +2831,9 @@ html[dir='rtl'] .multiselect-list-remove { font-weight: bold; } + + + .navbar-container::-webkit-scrollbar { width: 6px; height: 6px; @@ -2879,7 +2901,14 @@ html[dir='rtl'] .multiselect-list-remove { .navbar-container i-check { - width: 42px; + width: 26px; + background-image: var(--arrow-left); + background-position: 0px 48%; + background-repeat: no-repeat; + border-radius: 10px; +} + + /* width: 42px; background-image: var(--arrow-left); background-position: 0px 48%; background-repeat: no-repeat; @@ -2888,8 +2917,8 @@ html[dir='rtl'] .multiselect-list-remove { align-self: stretch; background-color: #d6d6d6; border-top-left-radius: 10px; - border-bottom-left-radius: 10px; -} + border-bottom-left-radius: 10px; */ + .sitebar-container i-check { @@ -3009,3 +3038,60 @@ html[dir='rtl'] .multiselect-list-remove { transform-origin: right; } + + +.location +{ + display: flex; + gap: 10px; + align-items: center; +} + +.location > i-link +{ + text-decoration: underline; +} + +.location > span::after +{ + content: '/'; +} + +.codepreview +{ + display: flex; + flex-flow: column; + border: 1px solid #c2c2c2; + padding: 10px; + margin: 10px; + background: #f8f8f8; + border-left: 4px solid #4ebeec; +} + +.codepreview-content +{ + display: flex; +} + +.codepreview-editor +{ + background: #e8e8e8; + padding: 10px; + + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; + flex: 1; +} + +.codepreview-preview{ + flex: 1; + background: white; + border-top-right-radius: 10px; + border-bottom-right-radius: 10px; + padding: 10px; +} + +.codepreview-bar +{ + +} \ No newline at end of file diff --git a/docs/android-chrome-192x192.png b/docs/android-chrome-192x192.png new file mode 100644 index 0000000..4228276 Binary files /dev/null and b/docs/android-chrome-192x192.png differ diff --git a/docs/android-chrome-512x512.png b/docs/android-chrome-512x512.png new file mode 100644 index 0000000..4615796 Binary files /dev/null and b/docs/android-chrome-512x512.png differ diff --git a/docs/apple-touch-icon.png b/docs/apple-touch-icon.png new file mode 100644 index 0000000..6177efe Binary files /dev/null and b/docs/apple-touch-icon.png differ diff --git a/docs/browserconfig.xml b/docs/browserconfig.xml new file mode 100644 index 0000000..249c5c1 --- /dev/null +++ b/docs/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #ffc40d + + + diff --git a/docs/favicon-16x16.png b/docs/favicon-16x16.png new file mode 100644 index 0000000..764867c Binary files /dev/null and b/docs/favicon-16x16.png differ diff --git a/docs/favicon-32x32.png b/docs/favicon-32x32.png new file mode 100644 index 0000000..0559e1d Binary files /dev/null and b/docs/favicon-32x32.png differ diff --git a/docs/favicon.ico b/docs/favicon.ico new file mode 100644 index 0000000..7edde42 Binary files /dev/null and b/docs/favicon.ico differ diff --git a/docs/img/logo.png b/docs/img/logo.png new file mode 100644 index 0000000..c591881 Binary files /dev/null and b/docs/img/logo.png differ diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..8a3a355 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +

Docs

+ +
+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + Getting started + + + + + + + + + + +
+
+ + diff --git a/docs/js/docs.js b/docs/js/docs.js new file mode 100644 index 0000000..ff61c07 --- /dev/null +++ b/docs/js/docs.js @@ -0,0 +1,16 @@ + + +marked.setOptions({ + highlight: function(code, lang) { + return hljs.highlight(lang, code).value; + } +}); + +async function load(route) { + var link = "md/" + route.link + ".md"; + let content = await fetch(link); + if (content.status != 200) + return "Not found " + content.url; + var md = marked(await content.text()); + return md; +} \ No newline at end of file diff --git a/docs/md/getting-started.md b/docs/md/getting-started.md new file mode 100644 index 0000000..1a30f42 --- /dev/null +++ b/docs/md/getting-started.md @@ -0,0 +1,17 @@ +# Compatibility +IUI depends on Web Components (customElement) to render its widgets. + +*PC* + +| Chrome | Firefox | Edge | IE | Opera | Safari | +|:------:|:--------|:----:|:--:|:-----:|--------| +| 54 | 79 | 63 | No | 41 | 10.1 | + ------------------------------------------------ + +*Mobile* + +| Android WebView | Chrome Android | Firefox Android | Safari iOS | Samsung Internet | +| :--------------: | :-------------:| :--------------:|:----------:| :--------------: | +| 54 | 54 | 63 | 10.3 | 6.0 | + ------------------------------------------------------------------------------------- + diff --git a/docs/md/getting-started/data-flow.md b/docs/md/getting-started/data-flow.md new file mode 100644 index 0000000..64bc12c --- /dev/null +++ b/docs/md/getting-started/data-flow.md @@ -0,0 +1,12 @@ +# Data flow + +When the :data attribute is set to an element any other attribute and child will be able to access this field directly using the variable *data* or the shortended *d*. + + + +
+ My name is ${d.name} and I work as a ${d.job}. +
+
+ + \ No newline at end of file diff --git a/docs/md/getting-started/declarative.md b/docs/md/getting-started/declarative.md new file mode 100644 index 0000000..c6f0f49 --- /dev/null +++ b/docs/md/getting-started/declarative.md @@ -0,0 +1,51 @@ +# Declarative Rendering + +# Text nodes +Text nodes are enclosed with `${...}` + + ${ navigator.userAgent } + + +# Fields + starts with `:` + + + + +# Attributes + starts with `::` + + + + +# Asynchronous + +*Promise* +Promises are automatically resolved. + + + ${fetch("md/hello.md")} + + +*Await* +To use await in text nodes **async** attribute must be added to the parent element + + + +
+ ${await (await fetch("md/hello.md")).text()} +
+
+ +In attributes, the attribute name must be preceded with **async:** + + + + + +Attributes are similar they must start with *async::* + + + + + \ No newline at end of file diff --git a/docs/md/getting-started/first.md b/docs/md/getting-started/first.md new file mode 100644 index 0000000..6e8785d --- /dev/null +++ b/docs/md/getting-started/first.md @@ -0,0 +1,14 @@ + +```html + + + + + + + + Current time: ${new Date()} + + + +``` \ No newline at end of file diff --git a/docs/md/getting-started/install.md b/docs/md/getting-started/install.md new file mode 100644 index 0000000..0fa9515 --- /dev/null +++ b/docs/md/getting-started/install.md @@ -0,0 +1,15 @@ + +NPM + +```html +npm install @esiur/iui +``` + +Include in web page + +# +```html + + +``` + diff --git a/docs/md/hello.md b/docs/md/hello.md new file mode 100644 index 0000000..1c8a3a1 --- /dev/null +++ b/docs/md/hello.md @@ -0,0 +1 @@ +Hello World ! \ No newline at end of file diff --git a/docs/mstile-150x150.png b/docs/mstile-150x150.png new file mode 100644 index 0000000..a5dfe49 Binary files /dev/null and b/docs/mstile-150x150.png differ diff --git a/docs/safari-pinned-tab.svg b/docs/safari-pinned-tab.svg new file mode 100644 index 0000000..844e766 --- /dev/null +++ b/docs/safari-pinned-tab.svg @@ -0,0 +1,73 @@ + + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + + + + diff --git a/docs/site.webmanifest b/docs/site.webmanifest new file mode 100644 index 0000000..b20abb7 --- /dev/null +++ b/docs/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/src/Core/App.js b/src/Core/App.js index 4718183..f927179 100644 --- a/src/Core/App.js +++ b/src/Core/App.js @@ -12,13 +12,11 @@ export default IUI.module(class App extends IUIElement { } created() { - this.updateBindings(); + IUI.bind(this, this, "/"); + //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 6ab76e5..f177c62 100644 --- a/src/Core/Binding.js +++ b/src/Core/Binding.js @@ -1,4 +1,5 @@ import IUIElement from "./IUIElement.js"; +import { IUI } from "./IUI.js"; export const BindingType = { IUIElement: 0, // this will never happen ! @@ -260,7 +261,10 @@ export class Binding { } // Content Attribute else if (this.type == BindingType.ContentAttribute) { - let d = await this._execute(this.target.ownerElement, data); + + let targetElement = this.target.ownerElement; + + let d = await this._execute(targetElement, data); if (d === undefined) return false; @@ -268,7 +272,17 @@ export class Binding { //if (d instanceof Promise) // d = await d; - this.target.ownerElement.innerHTML = d; + targetElement.innerHTML = d; + + if (window?.app?.loaded) + { + await IUI.create(targetElement); + await IUI.created(targetElement); + IUI.bind(targetElement, targetElement, "content"); + await IUI.render(targetElement, targetElement._data, true); + } + //await IUI.updateTree(targetElement); + } else if (this.type == BindingType.IfAttribute) { diff --git a/src/Core/IUI.js b/src/Core/IUI.js index 4349302..9106143 100644 --- a/src/Core/IUI.js +++ b/src/Core/IUI.js @@ -1,7 +1,16 @@ import IUIElement from "./IUIElement.js"; +import { Binding, BindingType } from "./Binding.js"; +//import Route from '../Router/Route.js'; -export const IUI = { - format: function (input) { + +export class IUI { + + 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; @@ -14,12 +23,9 @@ export const IUI = { return [input]; else return []; - }, - _menus: [], - views: [], - modules: {}, - registry : [], - observer: new IntersectionObserver(function(entries) { + } + + 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++) @@ -31,8 +37,10 @@ export const IUI = { } } - }, { threshold: [0] }), - created: async function (element) { + }, { threshold: [0] }); + + + static async created (element) { for (var i = 0; i < element.children.length; i++) { let e = element.children[i]; @@ -40,15 +48,15 @@ export const IUI = { await e.created(); await IUI.created(e); } - }, - create: async function(element) + } + + 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(); - // e.updateBindings(); } await IUI.create(e); @@ -73,8 +81,9 @@ export const IUI = { // //await IUI.registry[i].updateAttributes(); //} //return; - }, - get : function(o) + } + + static get(o) { return document.getElementById(o); @@ -82,12 +91,14 @@ export const IUI = { // if (IUI.registry[i].id == o) // return IUI.registry[i]; //return null; - }, - put: function(o) + } + + static put(o) { IUI.registry.push(o); - }, - remove: function(id) + } + + static remove(id) { for(var i = 0; i < IUI.registry.length; i++) if (IUI.registry[i].el.id == id) @@ -95,8 +106,9 @@ export const IUI = { IUI.registry.splice(i, 1); break; } - }, - module: function(objectClass) + } + + static module(objectClass) { let moduleName = objectClass.moduleName; @@ -110,8 +122,9 @@ export const IUI = { } return objectClass; - }, - extend: function(properties, defaults, force) + } + + static extend(properties, defaults, force) { if (properties == null) properties = defaults; @@ -123,6 +136,135 @@ export const IUI = { properties[i] = defaults[i]; return properties; } + + + static bind(element, rootElement, sourcePath){ + + // ::Attribute + // : Field + // async:: Async Attribute + // async: Async Field + // @ Event + + // skip element ? + if (element.hasAttribute("skip") + || element instanceof HTMLTemplateElement) + return; + + // tags to skip + //if (element instanceof HTMLScriptElement ) + //return; + + if (rootElement == null) + rootElement = element; + + let bindings; + + if (element != rootElement) + { + element.view = rootElement.view; + element.route = rootElement.route; + + bindings = []; + // compile attributes + for (var i = 0; i < element.attributes.length; i++) { + + let b = Binding.create(element.attributes[i]); + + 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")) { + rootElement.refs[el.getAttribute("ref")] = element; + } + } + else + { + // remove previous text node bindings + bindings = element.bindings == null ? [] : element.bindings.filter(x=> x.type != BindingType.TextNode); + element.refs = {}; + } + + // 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, rootElement, sourcePath); + } + else if (el instanceof HTMLElement) { + IUI.bind(el, rootElement, sourcePath); + } + else if (el instanceof Text) { + let b = Binding.create(el); + if (b != null) + bindings.push(b); + } + else if (el instanceof HTMLScriptElement) + { + // 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 rt = func.call(el.parentElement); + + if (typeof (rt) === "object") { + for (var k in rt) + el.parentElement[k] = rt[k]; + } + } + } + + element.bindings = bindings; + + } + + static async render(element, data, textNodesOnly = false) { + + if (!element.bindings) { + return; + } + + if (textNodesOnly) { + for (var i = 0; i < element.bindings.length; i++) + if (element.bindings[i].type == BindingType.TextNode) + await element.bindings[i].render(data); + } else { + // render attributes & text nodes + for (var i = 0; i < element.bindings.length; i++) + await element.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; + + //let data = e.mapData(data); + await IUI.render(el, el.data); + } + } + } }; export function iui(selector) diff --git a/src/Core/IUIElement.js b/src/Core/IUIElement.js index ed1aadb..16a16dc 100644 --- a/src/Core/IUIElement.js +++ b/src/Core/IUIElement.js @@ -40,7 +40,8 @@ export default class IUIElement extends HTMLElement { } async render() { - await this._renderElement(this, this._data); + await IUI.render(this, this._data); + //await IUIElement._renderElement(this, this._data); } _getParentData() { @@ -54,15 +55,9 @@ export default class IUIElement extends HTMLElement { } async setData(value) { - //if (this.bindings === undefined) - // this.updateBindings(); - - this._data = value; this._emit("data", {data: value}); - await this._renderElement(this, value); - - //console.log("IUI: SetData", value, this.tagName); + await IUIElement._renderElement(this, value); } get data() { @@ -106,7 +101,7 @@ export default class IUIElement extends HTMLElement { } } - async _renderElement(element, data) { + static async _renderElement(element, data) { if (!element.bindings) { return; } @@ -134,7 +129,7 @@ export default class IUIElement extends HTMLElement { e.data = data; //let data = e.mapData(data); - await this._renderElement(e, e.data); + await IUIElement._renderElement(e, e.data); } } } @@ -183,7 +178,7 @@ export default class IUIElement extends HTMLElement { } create() { - //this.updateBindings(); + } destroy() { @@ -196,7 +191,7 @@ export default class IUIElement extends HTMLElement { - _make_bindings(element) { + static _make_bindings(element, isRoot = false) { // ::Attribute // : Field @@ -205,6 +200,10 @@ export default class IUIElement extends HTMLElement { // @ Event + // skip element ? + if (element.hasAttribute("skip")) + return; + // tags to skip if (element instanceof HTMLScriptElement || element instanceof HTMLTemplateElement) @@ -213,19 +212,22 @@ export default class IUIElement extends HTMLElement { let bindings = []; - // compile attributes - for (var i = 0; i < element.attributes.length; i++) { + if (!isRoot) + { + // compile attributes + for (var i = 0; i < element.attributes.length; i++) { - let b = Binding.create(element.attributes[i]); + let b = Binding.create(element.attributes[i]); - 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); + 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); + } } } @@ -234,10 +236,10 @@ export default class IUIElement extends HTMLElement { let e = element.childNodes[i]; if (e instanceof IUIElement) { // @TODO: check if the IUI element handles the binding - this._make_bindings(e); + IUIElement._make_bindings(e); } else if (e instanceof HTMLElement) { - this._make_bindings(e); + IUIElement._make_bindings(e); } else if (e instanceof Text) { let b = Binding.create(e); @@ -268,9 +270,6 @@ export default class IUIElement extends HTMLElement { } } - updateBindings() { - this._make_bindings(this); - } _encapsulateEvent(code){ return `try {\r\n ${code} \r\n}\r\n catch(ex) { console.log(ex.name + ":" + ex.message, this); }`; diff --git a/src/Data/Include.js b/src/Data/Include.js index 4299903..4708711 100644 --- a/src/Data/Include.js +++ b/src/Data/Include.js @@ -39,43 +39,56 @@ export default IUI.module(class Include extends IUIElement //let xeval = (code) => eval(code); - // 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]; - } - } + if (window?.app?.loaded) + { + await IUI.create(this); + await IUI.created(this); + IUI.bind(this, this, "include:" + src); + 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++) { + // 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.classList.remove(this.cssClass + "-loading"); - if (window?.app?.loaded) - { - await IUI.create(this); - await IUI.created(this); - this.updateBindings(); - await this.render(); - } + // 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; } diff --git a/src/Data/Repeat.js b/src/Data/Repeat.js index ae2112f..46fb194 100644 --- a/src/Data/Repeat.js +++ b/src/Data/Repeat.js @@ -190,7 +190,8 @@ export default IUI.module(class Repeat extends IUIElement //console.log("ST4"); - this._make_bindings(e) + //this._make_bindings(e) + IUI.bind(e, this, "repeat"); this._container.insertBefore(e, this._beforeNode); this._assign(e, i);// { view: this.view, route: this.route, index: i }); @@ -260,9 +261,7 @@ export default IUI.module(class Repeat extends IUIElement } - //super._uiBindings = null; - //super.updateBindings(); - + // @TODO: check if this works for event names starting with ":" this._emit(":data", { data: value }); // this._emit("modified", { data: value, property: "data" }); diff --git a/src/Router/Route.js b/src/Router/Route.js index 0317db1..4fb6825 100644 --- a/src/Router/Route.js +++ b/src/Router/Route.js @@ -80,6 +80,13 @@ export default IUI.module(class Route extends IUIElement { return null; } + // get route() { + // return this; + // } + + // get view() { + // return this; + // } async create() { @@ -100,41 +107,52 @@ export default IUI.module(class Route extends IUIElement { //let xeval = (code) => eval(code); } - // 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 (window?.app?.loaded) + { + await IUI.create(this); + await IUI.created(this); + IUI.bind(this, this, "route:" + src); - 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]; - } - } + 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() { - //this.updateBindings(); + created() + { + } set(value) { diff --git a/src/UI/CodePreview.js b/src/UI/CodePreview.js new file mode 100644 index 0000000..e699b99 --- /dev/null +++ b/src/UI/CodePreview.js @@ -0,0 +1,68 @@ +import IUIElement from "../Core/IUIElement.js"; +import { IUI } from "../Core/IUI.js"; + +export default IUI.module(class CodePreview extends IUIElement { + constructor(properties) { + super(); + } + + async create() { + + + + if (this.hasAttribute("debug")) + debugger; + + this._code = this.innerHTML; + 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"; + + this.editor.innerText = this._code; + this.editor.contentEditable = true; + + this.editor.setAttribute("skip", true); + + let self = this; + this.editor.addEventListener("input", function() { + self._code = self.editor.innerText; + self.update(); + }, false); + + this.preview = document.createElement("div"); + this.preview.className = this.cssClass + "-preview"; + //this.preview.setAttribute(":content", ""); + + 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.update(); + } + + + async update() { + + if (this._updating) + return; + + this._updating = true; + this.preview.innerHTML = this._code; + + await IUI.create(this.preview); + await IUI.created(this.preview); + IUI.bind(this.preview, this.preview, "preview"); + await IUI.render(this.preview, this._data, true); + + this._updating = false; + } +}); \ No newline at end of file diff --git a/src/UI/Location.js b/src/UI/Location.js new file mode 100644 index 0000000..5e79073 --- /dev/null +++ b/src/UI/Location.js @@ -0,0 +1,39 @@ + +import IUIElement from "../Core/IUIElement.js"; +import { IUI } from "../Core/IUI.js"; +import Link from '../Router/Link.js'; + +export default IUI.module(class Location extends IUIElement { + constructor() { + super(); + } + + create() { + let self = this; + window.router.on("route", (e) => { + + self.textContent = ''; // clear everything + + + let html = ""; + let route = e.route; + + var current = document.createElement("div"); + current.innerHTML = route.caption; + + self.append(current); + + while (route = route.parent) { + + var sep = document.createElement("span"); + self.prepend(sep); + + let link = new Link(); + link.link = route.link; + link.innerHTML = route.caption; + + self.prepend(link); + } + }); + } +}); \ No newline at end of file diff --git a/src/UI/Select.js b/src/UI/Select.js index ed235a2..21e01a8 100644 --- a/src/UI/Select.js +++ b/src/UI/Select.js @@ -220,10 +220,13 @@ export default IUI.module(class Select extends IUIElement { app.appendChild(this.menu); if (app.loaded) { + ///console.log("Append", this.menu); await this.menu.create(); + IUI.bind(this.menu, this, "menu"); await IUI.create(this.menu); - this._make_bindings(this.menu); + + //this._make_bindings(this.menu); } } @@ -313,30 +316,7 @@ export default IUI.module(class Select extends IUIElement { await this.menu.setData(res); - // show results - //self.menu.clear(); - - - - // for (var i = 0; i < res.length; i++) { - // let nodes = this.template.content.cloneNode(true).childNodes; - - // while (nodes.length > 0) { - // let n = nodes[0]; - // if (n instanceof HTMLElement) - // n.setAttribute(":data", `d[${i}]`); - // self.menu.appendChild(n); - // } - - // } - - // self.menu.updateBindings(); - //self.menu.setData(res); - - - //}).catch(x => { - - //}); + } diff --git a/src/UI/TabbedTarget.js b/src/UI/TabbedTarget.js index 33e01f2..b357ed1 100644 --- a/src/UI/TabbedTarget.js +++ b/src/UI/TabbedTarget.js @@ -131,9 +131,7 @@ export default IUI.module(class TabbedTarget extends Target { this._body.append(item); - //this._bar.appendChild(label); - //this._bar.insertAdjacentElement("afterBegin", label); - + this.list.push(item); var self = this; label.on("check", function (v) { @@ -141,9 +139,7 @@ export default IUI.module(class TabbedTarget extends Target { self.select(item); }); - //this._updateSize(); - //this.updateBindings(); - + if (item.selected) this.select(item); diff --git a/src/UI/Table.js b/src/UI/Table.js index 0a4c5b5..a139d99 100644 --- a/src/UI/Table.js +++ b/src/UI/Table.js @@ -907,7 +907,10 @@ export default IUI.module(class Table extends IUIElement { let cl = column.node.cloneNode(true);// tr.insertCell(); - this._make_bindings(cl) + //this._make_bindings(cl) + + IUI.bind(cl, this, "table"); + tr.appendChild(cl); if (cl.dataMap != null) diff --git a/src/UI/Tabs.js b/src/UI/Tabs.js index 0ddc5e6..9fe089a 100644 --- a/src/UI/Tabs.js +++ b/src/UI/Tabs.js @@ -132,9 +132,7 @@ export default IUI.module(class Tabs extends IUIElement { this._body.append(item); - //this._bar.appendChild(label); - //this._bar.insertAdjacentElement("afterBegin", label); - + this.list.push(item); var self = this; label.on("check", function (v) { @@ -142,9 +140,7 @@ export default IUI.module(class Tabs extends IUIElement { self.select(item); }); - //this._updateSize(); - //this.updateBindings(); - + if (item.selected) this.select(item); diff --git a/src/UI/Window.js b/src/UI/Window.js index 116eac2..d8aeefb 100644 --- a/src/UI/Window.js +++ b/src/UI/Window.js @@ -42,7 +42,6 @@ export default IUI.module(class IUIWindow extends IUIElement { this.insertAdjacentElement("afterBegin", this._body); - //super.updateBindings(); } else this._body = b[0]; diff --git a/src/iui.js b/src/iui.js index 8cc855e..a38f323 100644 --- a/src/iui.js +++ b/src/iui.js @@ -38,6 +38,8 @@ import './UI/Select.js'; import './UI/DropDown.js'; import './UI/Grid.js'; +import './UI/Location.js'; +import './UI/CodePreview.js'; window.addEventListener("beforeprint", (e)=>{ let viewRoute = router.current.viewRoute;