import { LanguagePool, LanguagePoolString } from "./language.js" var counter = 0; var globalStyle = document.createElement("style"); document.head.appendChild(globalStyle); String.prototype.map = Array.prototype.map; function toCssAttr(txt){ return txt.map(d => (d.toUpperCase() === d && d !== d.toLowerCase()) ? "-" + d.toLowerCase(): d ).join(""); }; class callPromise extends Promise{ #opts = {}; constructor(cb){ super(cb); }; set opts(opts){ this.#opts = opts; } get opts(){ return this.#opts; } } const pools = { }; export class Stear{ elem; #childs = {}; constructor(elem){ this.elem = elem; elem.style.position="relative"; } style(css){ Object.entries(css).forEach(([k, d]) => { this.elem.style[k] = d; }); } addElement (id,elem){ if(!(elem instanceof SFrame))throw new TypeError("Cannot add Element not extending from SFrame"); this.#childs[id] = elem; } getElement (id) { return this.g(id); } g(id){ return this.#childs[id]; } async call (elem, args, layer = 1){ return await elem.call(this, args, layer); } include(elem, args, renderParent, layer = 1){ return elem.call(this, args, layer, renderParent); } static addGlobalStyleText(text){ globalStyle.innerHTML+="\n"+text; } static addAnimation(steps, name = "stearAnimation_" + counter++){ Stear.addGlobalStyleText(`@keyframes ${name} { ${ Object.entries(steps).map(([k,d])=> ` ${k} { ${Object.entries(d).map(d => " " + toCssAttr(d[0]) + ": " + d[1] + ";").join("\n")} }`).join("\n") } }`); return name; } static addGlobalStyleJSON(json, name = ".stearClass_" + counter++){ Stear.addGlobalStyleText(` ${name} { ${Object.entries(json).map(d => " " + toCssAttr(d[0]) + ": " + d[1] + ";").join("\n")} } `) return name; } static addLanguagePool(name){ if(typeof pools[name] == "undefined"){ pools[name] = new LanguagePool(); } return pools[name]; } static addLanguageFile(data,lang){ Object.entries(data).forEach(([k,d]) => { if (typeof pools[k] == "undefined") pools[k] = new LanguagePool(); pools[k].addFile(d,lang); }); } static set lang (lang){ Object.entries(pools).forEach(([k, d]) => { d.lang = lang; }); } static get getLanguageFile(){ var out = {}; Object.entries(pools).forEach(([k, d]) => { out[k] = d.getFile; }); return out; } } export class SFrame{ #preRender; #call; constructor({ call, preRender = true }){ this.#preRender = preRender; this.#call = call; } call(stear, args, layer = 1, renderParent = stear.elem){ let lastRender; let renderElem; let event = { onloaded: () => { }, onclose: ()=>{}, onresolve: () => { }, onBeforRerender: () => { }, onAfterRerender: () => { }, onParentRender:()=>{} }; let find = {}; let resolved = false; async function render(args){ if(!renderElem) return; if (lastRender) if ([...(renderParent.children)].includes(lastRender._)) renderParent.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); renderParent.appendChild(now.render); lastRender = now; now._.style.zIndex = layer; for (var member in find) delete find[member]; Object.assign(find, now.find); return lastRender; } const ppp = new callPromise(async (res,rej)=>{ const options = { find, render: async (...args) => { await event.onBeforRerender(...args); if (renderElem) await render(args); firstRender = true; await event.onAfterRerender(...args); return find; }, resolve: async (r, close = true) => { if (resolved) return; resolved = true; await event.onresolve(); if (close && lastRender && [...(renderParent.children)].includes(lastRender._)) renderParent.removeChild(lastRender._); res(r); }, call: (elem, args = {}) => { return stear.call(elem, args, layer + 1); }, close: async () => { await event.onclose(); if (close && lastRender && [...(renderParent.children)].includes(lastRender._)) renderParent.removeChild(lastRender._); }, include: (frame, args = {}) => { let iFrame = new includeFrame(stear, frame, layer + 1, args); return iFrame; }, event, }; window.queueMicrotask(() => ppp.opts = options); let firstRender = false; renderElem = await this.#call(stear, options, args); if(!renderElem) { }else{ if (this.#preRender | firstRender) await render([]); event.onloaded(); } }); return ppp; } } export class SWindow extends SFrame{ #Frame; constructor({ call, preRender = true, backgroundColor = "transparent"}){ var Frame = _({ style: { top: "0px", left: "0px", position: "absolute", height: "100%", width: "100%", display: "block", backgroundColor, //overflow:"scroll" }, find:"main" }, []); super({ 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; } } export class class_ { #elem; #childs; #build; #find; #doBuild; constructor(settings,childs,doBuild = true){ this.#elem = document.createElement(settings.type ?? "div"); this.#childs = childs; var keys = Object.keys(settings); for (let i = 0; i < keys.length; i++) { const key = keys[i]; if(key == "type"){} else if (key == "style"){ Object.entries(settings[key]).forEach(([k,d])=>{ this.#elem.style[k] = d; }); } else if (key == "find"){ this.#find = settings[key]; } else if (key == "event"){ Object.entries(settings[key]).forEach(([k, d]) => { this.#elem.addEventListener(k,d); }); } else if (key == "attr"){ Object.entries(settings[key]).forEach(([k, d]) => { this.#elem.setAttribute(k, d); }); } else { this.#elem.setAttribute(key,settings[key]); } } this.#doBuild = doBuild; } set childs(childs){ if (!this.#doBuild) return; this.#childs = Array.isArray(childs) ? childs : [childs]; } set settings(settings){ var keys = Object.keys(settings); for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (key == "type") { } else if (key == "style") { Object.entries(settings[key]).forEach(([k, d]) => { this.#elem.style[k] = d; }); } else if (key == "find") { this.#find = settings[key]; } else { this.#elem.setAttribute(key, settings[key]); } } } async build (args) { if(!this.#doBuild)return; 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 (){ if (!this.#doBuild) return this.#elem; this.#elem.innerHTML = ""; for (let i = 0; i < this.#build.length; i++) { const elem = this.#build[i]; if (typeof elem == "string" || elem instanceof LanguagePoolString) { this.#elem.appendChild(document.createTextNode(String(elem))); } else { this.#elem.appendChild(elem.render); } } return this.#elem; } get _ (){ return this.#elem; } get find (){ var out = {}; if (this.#doBuild){ this.#build.forEach(d=>{ Object.assign(out,d.find); }); } if (this.#find) out[this.#find]=this; return out; } } export const _ = (settings = {}, childs = []) => new class_(settings, Array.isArray(childs) ? childs : [childs]); export const s = (type,settings,...childs)=>new class_(Object.assign(settings,{type}),childs); class includeFrame{ #elem; #call; constructor(stear,frame,layer, args = {}){ this.#elem = new class_({},[],false); this.#call = stear.include(frame, args, this.#elem._, layer); this.#call.then(()=>{ }) .catch(()=>{ }); } get opts(){ return this.#call.opts; } close(){ if(this.#call){ this.#call.opts.close(); } } render(settings={}){ this.#elem.settings = settings; this.#call.opts.event.onParentRender(); return this.#elem; } };