diff --git a/extra/Pages/alert.js b/extra/Pages/alert.js index 8552980..61202cc 100644 --- a/extra/Pages/alert.js +++ b/extra/Pages/alert.js @@ -1,23 +1,26 @@ import { SFrame, _ } from "../../main.js"; import { fadein, fadeout } from "../../utils.js"; -const preRender = false; - -const render = ({ }, {titel,text,callback}) => { +const call = async (stear, { find, resolve, render, call, event}, {text,titel=""}) => { + event.onloaded = ()=> { + fadein (find.main, 200, true); + find.btn._.focus(); + } + event.onresolve = async () => await fadeout(find.main); return _({ - find:"main", - class:"stear_alert", + find: "main", + class: "stear_alert", style: { - position:"fixed", + position: "fixed", left: "0", top: "0", - height:"100%", - width:"100%", - backgroundColor:"rgba(0,0,0,0.5)" + height: "100%", + width: "100%", + backgroundColor: "rgba(0,0,0,0.5)" } }, _({ - style:{ + style: { left: "50%", top: "50%", transform: "translate(-50%, -50%)", @@ -31,23 +34,19 @@ const render = ({ }, {titel,text,callback}) => { textAlign: "center" } }, [ - _({ type: "h2", style: { marginBottom: 0 }}, titel), - _({ type: "p"}, text), - _({ type: "button", find:"btn", event: {click: callback}, style:{ - borderRadius:"0.5rem", - }},"OK"), + _({ type: "h2", style: { marginBottom: 0 } }, titel), + _({ type: "p" }, text), + _({ + type: "button", + find: "btn", + event: { click: ()=>resolve() }, + style: { + borderRadius: "0.5rem", + } + }, "OK"), ])); } -const call = async (stear, { find, resolve, render, call }, {text,titel=""}) => { - render({titel,text,callback:()=>{ - resolve(); - fadeout(find.main._); - }}); - await fadein (find.main._, 200, true); - find.btn._.focus(); -} - export default new SFrame({ - preRender, render, call + preRender:true, call }); \ No newline at end of file diff --git a/extra/Pages/showStatus.js b/extra/Pages/showStatus.js index 62d630d..aa8455c 100644 --- a/extra/Pages/showStatus.js +++ b/extra/Pages/showStatus.js @@ -1,7 +1,6 @@ import { SFrame, Stear, _ } from "../../main.js"; import { fadein, fadeout, wait } from "../../utils.js"; -const preRender = true; Stear.addGlobalStyleJSON({ position: "fixed", @@ -19,20 +18,106 @@ Stear.addGlobalStyleJSON({ },".stear_status"); -const render = ({ }, { }) => { - - return _({ - find:"main", - class:"stear_status", - }); -} - const statusList = []; var statusActive = false; -const call = async (stear, { find, resolve, render, call }, { text, color="grey" }) => { +const call = async (stear, { find, resolve, render, close, call, event }, { text, color = "grey" }) => { + statusList.push({ text, color, resolve }); + if (statusActive) return false; + statusActive = true;; + + event.onloaded = () => { + fadein(find.main, 200, true); + }; + event.onclose = async() => { + await fadeout(find.main); + }; + event.onBeforRerender = async() => { + find.main.settings = { style: { backgroundColor: "#555" } }; + await wait(200); + }; + event.onAfterRerender = async() => { + find.main.settings = { style: { backgroundColor: "" } }; + }; + + var next = statusList.shift(); + + var timeoutId = setTimeout(nextMsg,3000); + + var inProgress = false; + + async function nextMsg(){ + if(inProgress)return; + inProgress = true; + if (timeoutId >= 0) clearTimeout(timeoutId); + timeoutId = -1; + + next.resolve(null,false); + next = statusList.shift(); + if(next == null){ + statusActive = false; + close(); + return; + } + render(false); + + timeoutId = setTimeout(nextMsg, 3000); + inProgress = false; + } + + return (first = true)=>_({ + find: "main", + class: "stear_status", + style: { + border: "2px solid " + next.color, + backgroundColor: first ? "":"#555" + }, + event: { click: nextMsg } + },next.text); +} + +/*const call = async (stear, { find, resolve, render, call, event }, { text, color="grey" }) => { + + + async function loop(){ + last = next; + next = statusList.shift(); + if (next == null) return finish(); + last.resolve(null, false); + + find.main.settings = { style: { backgroundColor: "#555" } }; + await wait(200); + find.main.settings = { + style: { + backgroundColor: "", + border: "2px solid " + next.color + } + }; + find.main._.innerText = next.text; + timeoutId = setTimeout(loop,3000); + } + var timeoutId = setTimeout(loop, 3000); + find.main._.onclick = ()=>{ + if(timeoutId<0)return; + clearTimeout(timeoutId); + timeoutId = -1; + loop(); + }; + + async function finish(){ + if (timeoutId >= 0)clearTimeout(timeoutId); + timeoutId = -1; + statusActive = false; + + await fadeout(find.main._); + + last.resolve(); + } + +}*/ +/*const call = async (stear, { find, resolve, render, call, event }, { text, color="grey" }) => { statusList.push({ text, color, resolve}); - if (statusActive) return; + if (statusActive) return false; statusActive = true; var next = statusList.shift(); @@ -43,7 +128,7 @@ const call = async (stear, { find, resolve, render, call }, { text, color="grey" }}; find.main._.innerText = next.text; - await fadein(find.main._, 200, true); + event.onloaded = () => fadein(find.main, 200, true); //find.main._.style.transition = ""; async function loop(){ @@ -80,8 +165,13 @@ const call = async (stear, { find, resolve, render, call }, { text, color="grey" last.resolve(); } -} + + return _({ + find: "main", + class: "stear_status", + }); +}*/ export default new SFrame({ - preRender, render, call + preRender:true, call }); \ No newline at end of file diff --git a/main.js b/main.js index 734a1bd..e2ece1d 100644 --- a/main.js +++ b/main.js @@ -70,56 +70,73 @@ ${Object.entries(json).map(d => " " + toCssAttr(d[0]) + ": " + d[1] + ";").jo export class SFrame{ #preRender; - #render; #call; - #find = {}; - #lastRender; - constructor({ preRender, render, call }){ + constructor({ call, preRender = true }){ this.#preRender = preRender; - this.#render = render; this.#call = call; - if(this.#preRender){ - this.render(); - } - } - - render(args={}){ - this.#lastRender = this.#render({ find: this.#find }, args); - this.#lastRender.render; - for (var member in this.#find) delete this.#find[member]; - Object.assign(this.#find, this.#lastRender.find); - return this.#lastRender; } async call(stear, args, layer = 1){ - if(this.#preRender){ - stear.elem.appendChild(this.#lastRender._); - this.#lastRender._.style.zIndex = layer; + let lastRender; + let renderElem; + + let event = { onloaded: () => { }, onclose: ()=>{}, onresolve: () => { }, onBeforRerender: () => { }, onAfterRerender: () => { } }; + let find = {}; + + let resolved = false; + + async function render(args){ + if(!renderElem) return; + if(lastRender)if ([...(stear.elem.children)].includes(lastRender._)) stear.elem.removeChild(lastRender._); + let now = renderElem; + if(typeof now == "function")now = await now(); + if(!(now instanceof class_)) throw new Error("The Element to render is not an instance of class_"); + await now.build(args); + + stear.elem.appendChild(now.render); + lastRender = now; + + now._.style.zIndex = layer; + + for (var member in find) delete find[member]; + Object.assign(find, now.find); + return lastRender; } - return new Promise((res,rej)=>{ - this.#call(stear,{ - find: this.#find, - render: (args) => { - this.render(args); - /*for (var member in find) delete find[member]; - Object.assign(find, (this.#lastRender?.find) ?? {});*/ - if ([...(stear.elem.children)].indexOf(this.#lastRender._) >= 0) stear.elem.removeChild(this.#lastRender._); - stear.elem.appendChild(this.#lastRender._); - this.#lastRender._.style.zIndex = layer; - return this.#find; + return new Promise(async (res,rej)=>{ + let firstRender = false; + renderElem = await this.#call(stear,{ + find, + render: async (...args) => { + await event.onBeforRerender(...args); + if(renderElem)await render(args); + firstRender = true; + await event.onAfterRerender(...args); + return find; }, - resolve: (r,close=true)=>{ - if (close&&this.#lastRender&&[...(stear.elem.children)].indexOf(this.#lastRender._) >= 0) stear.elem.removeChild(this.#lastRender._); + resolve: async (r,close=true)=>{ + if (resolved) return; + resolved = true; + await event.onresolve(); + if (close&&lastRender&&[...(stear.elem.children)].includes(lastRender._))stear.elem.removeChild(lastRender._); res(r); }, - call: (elem, args)=>{ + call: (elem, args= {})=>{ return stear.call(elem,args,layer+1); }, - close: ()=>{ - if (close && this.#lastRender && [...(stear.elem.children)].indexOf(this.#lastRender._) >= 0) stear.elem.removeChild(this.#lastRender._); - } + close: async ()=>{ + await event.onclose(); + if (close && lastRender && [...(stear.elem.children)].includes(lastRender._)) stear.elem.removeChild(lastRender._); + }, + event }, args); + if(!renderElem) { + + }else{ + if (this.#preRender | firstRender) await render([]); + event.onloaded(); + } + }); } @@ -129,7 +146,7 @@ export class SWindow extends SFrame{ #Frame; - constructor({ preRender, render, call, backgroundColor = "transparent"}){ + constructor({ call, preRender = true, backgroundColor = "transparent"}){ var Frame = _({ style: { top: "0px", @@ -144,10 +161,20 @@ export class SWindow extends SFrame{ find:"main" }, []); super({ - preRender, render: (settings, args) => { - Frame.childs = [render(settings, args)]; - return Frame; - }, call + call: async(...args) => _({ + style: { + top: "0px", + left: "0px", + position: "absolute", + height: "100%", + width: "100%", + display: "block", + backgroundColor, + //overflow:"scroll" + }, + find: "main" + }, await call(...args)), + preRender }); this.#Frame = Frame; } @@ -157,6 +184,7 @@ export class SWindow extends SFrame{ export class class_ { #elem; #childs; + #build; #find; constructor(settings,childs){ @@ -184,7 +212,7 @@ export class class_ { set childs(childs){ this.#childs = Array.isArray(childs) ? childs : [childs]; } - + set settings(settings){ var keys = Object.keys(settings); for (let i = 0; i < keys.length; i++) { @@ -201,15 +229,34 @@ export class class_ { } } + async build (args) { + this.#build = []; + for (let i = 0; i < this.#childs.length; i++) { + let elem = this.#childs[i]; + + if (typeof elem == "function") elem = await elem(...args); + + if(Array.isArray(elem)){ + for (let j = 0; j < elem.length; j++) { + if (elem[j] instanceof class_) await elem[j].build(args); + } + this.#build.push(...elem); + }else{ + if(elem instanceof class_)await elem.build(args); + this.#build.push(elem); + } + } + } + get render (){ this.#elem.innerHTML = ""; - for (let i = 0; i < this.#childs.length; i++) { - const elem = this.#childs[i]; - if(typeof elem == "string"){ + for (let i = 0; i < this.#build.length; i++) { + const elem = this.#build[i]; + if (typeof elem == "string") { this.#elem.appendChild(document.createTextNode(elem)); - }else{ + } else { this.#elem.appendChild(elem.render); - } + } } return this.#elem; } @@ -220,7 +267,7 @@ export class class_ { get find (){ var out = {}; - this.#childs.forEach(d=>{ + this.#build.forEach(d=>{ Object.assign(out,d.find); }); if (this.#find) out[this.#find]=this; diff --git a/utils.js b/utils.js index cda3a35..f6a2e1c 100644 --- a/utils.js +++ b/utils.js @@ -1,13 +1,17 @@ +import { class_ } from "./main.js"; + export const wait = (ms) => { return new Promise((res, rej) => { setTimeout(res, ms); }); } -export const fadeout = async (elems, ms = 200, force = false) => { +export const fadeout = async (Selems, ms = 200, force = false) => { var oldTrans = []; - if (!Array.isArray(elems)) elems = [elems]; - for (let i = 0; i < elems.length; i++) { + if (!Array.isArray(Selems)) Selems = [Selems]; + var elems = []; + for (let i = 0; i < Selems.length; i++) { + elems[i] = Selems[i] instanceof class_ ? Selems[i]._ : Selems[i]; oldTrans[i] = elems[i].style.transition; elems[i].style.transition = `opacity ${ms}ms`; if(force){ @@ -25,10 +29,12 @@ export const fadeout = async (elems, ms = 200, force = false) => { elems[i].style.transition = oldTrans[i]; } } -export const fadein = async (elems, ms = 200, force = false, display="") => { +export const fadein = async (Selems, ms = 200, force = false, display="") => { var oldTrans = []; - if (!Array.isArray(elems)) elems = [elems]; - for (let i = 0; i < elems.length; i++) { + if (!Array.isArray(Selems)) Selems = [Selems]; + var elems = []; + for (let i = 0; i < Selems.length; i++) { + elems[i] = (Selems[i] instanceof class_) ? Selems[i]._ : Selems[i]; oldTrans[i] = elems[i].style.transition elems[i].style.transition = `opacity ${ms}ms`; elems[i].style.display = display;