2
0
mirror of https://github.com/esiur/iui.git synced 2025-09-13 15:13:18 +00:00

initial commit

This commit is contained in:
2021-02-22 11:39:50 +03:00
commit e82f4bc4cf
87 changed files with 14463 additions and 0 deletions

14
src/Data/DataList.js Normal file
View File

@@ -0,0 +1,14 @@
import IUIElement from "../Core/IUIElement.js";
export default IUI.module(class DataList extends IUIElement
{
constructor(properties)
{
super(properties);
}
create()
{
this.style.display = "none";
}
});

62
src/Data/Field.js Normal file
View File

@@ -0,0 +1,62 @@
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();
}
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");
}
set 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;
// 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
node.innerHTML = this.innerHTML;
return { node, width, name, type };
}
});

82
src/Data/Form.js Normal file
View File

@@ -0,0 +1,82 @@
import IUIElement from "../Core/IUIElement.js";
import { IUI } from "../Core/IUI.js";
export default IUI.module(class Form extends IUIElement {
constructor() {
super();
//this.form = {};
}
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;
}
async create() {
//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(Form._copy(this.original));
//super.setData({ ...this.original });
}
async reset() {
//super.setData({ ...this.original });
super.setData(Form._copy(this.original));
return this;
}
// @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;
}
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 && Form._areEqual(this._data[i], this.original[i]))
continue;
else
rt[i] = this._data[i];
}
return rt;
}
});

68
src/Data/Include.js Normal file
View File

@@ -0,0 +1,68 @@
import IUIElement from "../Core/IUIElement.js";
import { IUI } from "../Core/IUI.js";
export default IUI.module(class Include extends IUIElement
{
constructor()
{
super();
this.refs = {};
}
async create()
{
//console.log("Create ...", this.getAttribute("src"));
if (this.getAttribute("src") == "views/studio/realestate.html")
console.log("Create include");
if (this.hasAttribute("src")) {
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;
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];
}
}
}
}
//this.updateBindings();
}
get src()
{
return this._src;
}
});

64
src/Data/Layout.js Normal file
View File

@@ -0,0 +1,64 @@
import IUIElement from "../Core/IUIElement.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();
}
//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;
}
});

273
src/Data/Repeat.js Normal file
View File

@@ -0,0 +1,273 @@
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 = [];
}
_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;
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 (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");
this.innerHTML = "";
this._container = 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)
{
var bindings = self._repeatBindings.get(this);
// update view
for(var i = 0; i < bindings.length; i++)
{
if (bindings[i].props)
{
for(var j = 0; j < bindings[i].props.length; j++)
{
if (bindings[i].props[j] == propertyName)
{
bindings[i].node.data = bindings[i].func.apply(self,
[this, this, this, this, 0, 0]);
break;
}
}
}
}
};
*/
}
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;
}
get length() {
return this._data.length;
}
_assign(node, index) {
// update fields
// this so we won't mess with i-include view
if (node.view == undefined)
node.view = this.view;
node.rotue = this.route;
node.index = index;
// update references
if (node.hasAttribute("ref"))
{
let ref = node.getAttribute("ref");
// create new array
if (!(this.view.refs[ref] instanceof Array))
this.view.refs[ref] = [];
this.view.refs[ref][index] = node;
}
//Object.assign(node, customFields);
for (var i = 0; i < node.children.length; i++)
this._assign(node.children[i], index);
}
async setData(value)
{
// this to avoid interruption by an event
if (this._busy)
{
console.log("Busy", this);
return false;
}
//console.log("RPT: SetData", value);
this._busy = true;
// var id = Math.random();
//console.log("SetData " + this.getAttribute("ref") + " " + id, value);
//console.trace();
// clear
this.clear();
if (value instanceof Structure)
value = value.toPairs();
else if (value == null || !(value instanceof Array || value instanceof Int32Array))
value = [];
//debugger;
await super.setData(value);
for (let i = 0; i < value.length; i++) {
///console.log("ST1");
//let content = this.template.content.cloneNode(true);
//let nodes = content.childNodes;
let e = this._repeatNode.cloneNode(true);
this.list.push(e);
//console.log("ST2");
// Create node
if (e instanceof IUIElement)
await e.create();
// console.log("ST3");
// Create children
//console.log("Create repeat " + i, this, e);
await IUI.create(e);
//console.log("Created repeat " + i, this, e);
//console.log("ST4");
this._make_bindings(e)
this._container.insertBefore(e, this._beforeNode);
this._assign(e, i);// { view: this.view, route: this.route, index: i });
//console.log("ST5");
if (e instanceof IUIElement) {
// @TODO should check if the element depends on parent or not
if (e.dataMap != null) {
// if map function failed to call setData, we will render without it
if (!(await e.dataMap.render(value[i])))
await e.render();
}
else{
await e.setData(value[i]);
// console.log("ST6.1");
}
}
else {
if (e.dataMap != null)
await e.dataMap.render(value[i]);
else
e.data = value[i];
// console.log("ST6.2", e);
await this._renderElement(e, e.data);
// console.log("ST6.3");
}
// if (node.dataMap != null) {
// await node.dataMap.render(value[i]);
// this._renderElement(node, node.data);
// }
// else {
// node.data = value[i];
// this._renderElement(node, node.data);
// }
/*
var newElements = content.querySelectorAll("*");
while (nodes.length > 0) {
let n = nodes[0];
//n.index = i;
if (n instanceof HTMLElement)
n.setAttribute(":data", `d[${i}]`);
this._container.appendChild(n);
}
// this has to be called after appending the child otherwise node will be HTMLElement and not IUIElement , bug maybe in webkit ?
for (var j = 0; j < newElements.length; j++) {
let el = newElements[j];
// set route for all elements
el.index = i;
el.view = this;
el.route = this.route;
//newElements[j].route = this.route;
if (el instanceof IUIElement)
el.create();
}
*/
}
//super._uiBindings = null;
//super.updateBindings();
this._emit("modified", { data: value, property: "data" });
// console.log("SetDataEnd " + this.getAttribute("ref") + " " + id);
this._busy = false;
}
});

15
src/Data/TableRow.js Normal file
View File

@@ -0,0 +1,15 @@
import IUIElement from "../Core/IUIElement.js";
import { IUI } from "../Core/IUI.js";
export default IUI.module(class TableRow extends IUIElement {
constructor() {
super();
}
create() {
//this.style.display = "none";
this.style.display = "table-row";
console.log("TR");
}
});