documentation and global render

This commit is contained in:
jusax23 2022-11-12 14:17:48 +01:00
parent 10e9a68989
commit fe23109834

329
main.js
View file

@ -27,27 +27,51 @@ const pools = {
}; };
/** Stear class */
export class Stear{ export class Stear{
elem; elem;
#childs = {}; #childs = {};
#frames = [];
/**
* Creating a Stear class. It can be used to render "stear" in an Element.
*
* @param {HTMLElement} elem
*/
constructor(elem){ constructor(elem){
this.elem = elem; this.elem = elem;
elem.style.position="relative"; elem.style.position="relative";
} }
/**
* Change the Style of the render Element.
*
* @param {JSON} css
*/
style(css){ style(css){
Object.entries(css).forEach(([k, d]) => { Object.entries(css).forEach(([k, d]) => {
this.elem.style[k] = d; this.elem.style[k] = d;
}); });
} }
/**
* An Store for Frames
*
* @param {string} id
* @param {SFrame} elem
*/
addElement (id,elem){ addElement (id,elem){
if(!(elem instanceof SFrame))throw new TypeError("Cannot add Element not extending from SFrame"); if(!(elem instanceof SFrame))throw new TypeError("Cannot add Element not extending from SFrame");
this.#childs[id] = elem; this.#childs[id] = elem;
} }
/**
* Access an Element from the Frame Store
*
* @param {string} id
* @returns
*/
getElement (id) { getElement (id) {
return this.g(id); return this.g(id);
} }
@ -56,18 +80,69 @@ export class Stear{
return this.#childs[id]; return this.#childs[id];
} }
/**
* Render an Element gloabal.
*
* @param {SFrame} elem
* @param {*} args
* @param {number} layer
* @returns
*/
async call (elem, args, layer = 1){ async call (elem, args, layer = 1){
return await elem.call(this, args, layer); return await elem.call(this, args, this.#frames, layer);
} }
/**
* Render an Element in annother Element.
*
* @param {SFrame} elem
* @param {*} args
* @param {HTMLElement} renderParent
* @param {number} layer
* @returns
*/
include(elem, args, renderParent, layer = 1){ include(elem, args, renderParent, layer = 1){
return elem.call(this, args, layer, renderParent); return elem.call(this, args, this.#frames, layer, renderParent);
} }
/**
* Rernder everthing.
*
* @param {*} arg
* @returns
*/
rerenderGlobal(arg){
if(this.#frames.length == 0)return;
return new Promise((res,rej)=>{
let running = this.#frames.length;
for (let i = 0; i < this.#frames.length; i++) {
const element = this.#frames[i];
element.globalRenderRequest(arg)
.then(()=>{
running--;
if(running==0)res();
});
}
});
}
/**
* Add raw css Data.
*
* @param {string} text
*/
static addGlobalStyleText(text){ static addGlobalStyleText(text){
globalStyle.innerHTML+="\n"+text; globalStyle.innerHTML+="\n"+text;
} }
/**
* Add a css Animation
*
* @param {object} steps - css like json Syntax
* @param {string} name
* @returns {string} name
*/
static addAnimation(steps, name = "stearAnimation_" + counter++){ static addAnimation(steps, name = "stearAnimation_" + counter++){
Stear.addGlobalStyleText(`@keyframes ${name} { Stear.addGlobalStyleText(`@keyframes ${name} {
${ ${
@ -80,6 +155,13 @@ ${Object.entries(d).map(d => " " + toCssAttr(d[0]) + ": " + d[1] + ";").joi
return name; return name;
} }
/**
*
* @param {object} json - css like json Syntax
* @param {string} name - e.g. .classname
* @returns {string} name
*/
static addGlobalStyleJSON(json, name = ".stearClass_" + counter++){ static addGlobalStyleJSON(json, name = ".stearClass_" + counter++){
Stear.addGlobalStyleText(` Stear.addGlobalStyleText(`
${name} { ${name} {
@ -89,6 +171,12 @@ ${Object.entries(json).map(d => " " + toCssAttr(d[0]) + ": " + d[1] + ";").jo
return name; return name;
} }
/**
* Add A Language Pool. E.g. for a subpage.
*
* @param {string} name
* @returns {LanguagePool}
*/
static addLanguagePool(name){ static addLanguagePool(name){
if(typeof pools[name] == "undefined"){ if(typeof pools[name] == "undefined"){
pools[name] = new LanguagePool(); pools[name] = new LanguagePool();
@ -96,19 +184,32 @@ ${Object.entries(json).map(d => " " + toCssAttr(d[0]) + ": " + d[1] + ";").jo
return pools[name]; return pools[name];
} }
/**
* Add a file containing translations.
*
* @param {JSON} data
* @param {string} lang
*/
static addLanguageFile(data,lang){ static addLanguageFile(data,lang){
Object.entries(data).forEach(([k,d]) => { Object.entries(data).forEach(([k,d]) => {
if (typeof pools[k] == "undefined") pools[k] = new LanguagePool(); if (typeof pools[k] == "undefined") pools[k] = new LanguagePool();
pools[k].addFile(d,lang); pools[k].addFile(d,lang);
}); });
} }
/**
* Used Language
*/
static set lang (lang){ static set lang (lang){
Object.entries(pools).forEach(([k, d]) => { Object.entries(pools).forEach(([k, d]) => {
d.lang = lang; d.lang = lang;
}); });
this.globalRenderRequest();
} }
/**
* Generate Language File with defaults
*/
static get getLanguageFile(){ static get getLanguageFile(){
var out = {}; var out = {};
Object.entries(pools).forEach(([k, d]) => { Object.entries(pools).forEach(([k, d]) => {
@ -118,20 +219,141 @@ ${Object.entries(json).map(d => " " + toCssAttr(d[0]) + ": " + d[1] + ";").jo
} }
} }
////////////////////////////////////////////////////////////////////////
//utils
/**
* Can be called to close a frame and return a response.
* @async
* @callback utilsResolveCallback
* @param {*} returnValue
* @param {boolean} close
*/
/**
* Remove this Frame from Screen
* @async
* @callback utilsCloseCallback
*/
/**
* Rerender the local Content
* @async
* @callback utilsRenderCallback
* @param {...*} args
* @return {objectt} find
*/
/**
* Open and run another frame with the ability to return data.
* @async
* @callback utilsCallCallback
* @param {SFrame} elem
* @param {*} args
* @return {callPromise}
*/
/**
* Embet another Frame
* @async
* @callback utilsIncludeCallback
* @param {SFrame} elem
* @param {*} args
* @return {includeFrame}
*/
/////////////////////////////////////////////////////////////////////////
//eventCallbacks
/**
* Called when Page is fully loaded.
* @callback eventOnLoadedCallback
*/
/**
* Will be called and awaited bevor resolving.
* @async
* @callback eventOnResolveCallback
*/
/**
* Will be called and awaited bevor closing.
* @async
* @callback eventOnCloseCallback
*/
/**
* Will be called and awaited bevor rerendering.
* @async
* @callback eventOnBeforRerenderCallback
* @param {...*} args - any given param
*/
/**
* Will be called and awaited after rerendering.
* @async
* @callback eventOnAfterRerenderCallback
* @param {...*} args - any given param
*/
/**
* Will be called when included in another Frame and that Frame rerenders.
* @callback eventOnParentRenderCallback
*/
/**
* Will be called when included in another Frame and that Frame rerenders.
* @callback eventOnGlobalRenderCallback
*/
/**
* @typedef callUtils
* @type {Object}
* @property {Object} find - find an element in local tree
* @property {utilsResolveCallback} resolve - Return the Data
* @property {utilsCloseCallback} close - Close the Frame
* @property {utilsRenderCallback} render - Rerender the Frame
* @property {utilsCallCallback} call - Use another Frame
* @property {utilsIncludeCallback} include - Include another Frame
* @property {Object} event - local Events
* @property {eventOnLoadedCallback} event.onloaded
* @property {eventOnResolveCallback} event.onresolve
* @property {eventOnCloseCallback} event.close
* @property {eventOnBeforRerenderCallback} event.onBeforRerender
* @property {eventOnAfterRerenderCallback} event.onAfterRerender
* @property {eventOnParentRenderCallback} event.onParentRender
* @property {eventOnGlobalRenderCallback} event.onGlobalRenderRequest
*/
/**
* This callback will be called, when a frame should be opened.
* @callback callCallback
* @param {Stear} stear
* @param {callUtils} utils - lots of utils for Frame manipulation
* @param {*} args
*/
/**
* SFrame class
*/
export class SFrame{ export class SFrame{
#preRender; #preRender;
#call; #call;
/**
*
* @param {Object} args
* @param {callCallback} args.call
* @param {boolean} [args.preRender]
*/
constructor({ call, preRender = true }){ constructor({ call, preRender = true }){
this.#preRender = preRender; this.#preRender = preRender;
this.#call = call; this.#call = call;
} }
call(stear, args, layer = 1, renderParent = stear.elem){ call(stear, args, frames, layer = 1, renderParent = stear.elem){
let lastRender; let lastRender;
let renderElem; let renderElem;
let event = { onloaded: () => { }, onclose: ()=>{}, onresolve: () => { }, onBeforRerender: () => { }, onAfterRerender: () => { }, onParentRender:()=>{} }; let event = { onloaded: () => { }, onclose: ()=>{}, onresolve: () => { }, onBeforRerender: () => { }, onAfterRerender: () => { }, onParentRender:()=>{}, onGlobalRenderRequest:()=>true };
let find = {}; let find = {};
let resolved = false; let resolved = false;
@ -155,6 +377,14 @@ export class SFrame{
} }
const ppp = new callPromise(async (res,rej)=>{ const ppp = new callPromise(async (res,rej)=>{
const globalRegister = {
globalRenderRequest: async (...args)=>{
const arg = await event.onGlobalRenderRequest(...args);
if(arg===false) return;
await options.render(arg);
}
}
frames.push(globalRegister);
const options = { const options = {
find, find,
render: async (...args) => { render: async (...args) => {
@ -169,6 +399,8 @@ export class SFrame{
resolved = true; resolved = true;
await event.onresolve(); await event.onresolve();
if (close && lastRender && [...(renderParent.children)].includes(lastRender._)) renderParent.removeChild(lastRender._); if (close && lastRender && [...(renderParent.children)].includes(lastRender._)) renderParent.removeChild(lastRender._);
let i = frames.indexOf(globalRegister);
if(i>-1)frames.splice(i,1);
res(r); res(r);
}, },
call: (elem, args = {}) => { call: (elem, args = {}) => {
@ -176,7 +408,7 @@ export class SFrame{
}, },
close: async () => { close: async () => {
await event.onclose(); await event.onclose();
if (close && lastRender && [...(renderParent.children)].includes(lastRender._)) renderParent.removeChild(lastRender._); if (lastRender && [...(renderParent.children)].includes(lastRender._)) renderParent.removeChild(lastRender._);
}, },
include: (frame, args = {}) => { include: (frame, args = {}) => {
let iFrame = new includeFrame(stear, frame, layer + 1, args); let iFrame = new includeFrame(stear, frame, layer + 1, args);
@ -199,12 +431,19 @@ export class SFrame{
} }
/** Create a SWindow, a Fullscreen Frame. */
export class SWindow extends SFrame{ export class SWindow extends SFrame{
#Frame; #Frame;
/**
*
* @param {Object} args
* @param {callCallback} args.call
* @param {boolean} [args.preRender]
*/
constructor({ call, preRender = true, backgroundColor = "transparent"}){ constructor({ call, preRender = true, backgroundColor = "transparent"}){
var Frame = _({ /*var Frame = _({
style: { style: {
top: "0px", top: "0px",
left: "0px", left: "0px",
@ -216,7 +455,7 @@ export class SWindow extends SFrame{
//overflow:"scroll" //overflow:"scroll"
}, },
find:"main" find:"main"
}, []); }, []);*/
super({ super({
call: async(...args) => _({ call: async(...args) => _({
style: { style: {
@ -233,11 +472,21 @@ export class SWindow extends SFrame{
}, await call(...args)), }, await call(...args)),
preRender preRender
}); });
this.#Frame = Frame; //this.#Frame = Frame;
} }
} }
/**
* @typedef renderNodeSettings
* @type {Object}
* @property {string}[type]
* @property {string}[find]
* @property {Object}[event]
* @property {Object}[attr]
*/
/** Create a Render node, */
export class class_ { export class class_ {
#elem; #elem;
#childs; #childs;
@ -245,6 +494,13 @@ export class class_ {
#find; #find;
#doBuild; #doBuild;
/**
* Generate a new Stear render Node.
*
* @param {renderNodeSettings} settings
* @param {(LanguagePoolString|string|class_)[]} childs
* @param {boolean} doBuild
*/
constructor(settings,childs,doBuild = true){ constructor(settings,childs,doBuild = true){
this.#elem = document.createElement(settings.type ?? "div"); this.#elem = document.createElement(settings.type ?? "div");
this.#childs = childs; this.#childs = childs;
@ -272,11 +528,17 @@ export class class_ {
this.#doBuild = doBuild; this.#doBuild = doBuild;
} }
/**
* @param {(LanguagePoolString|string|class_)[]} childs
*/
set childs(childs){ set childs(childs){
if (!this.#doBuild) return; if (!this.#doBuild) return;
this.#childs = Array.isArray(childs) ? childs : [childs]; this.#childs = Array.isArray(childs) ? childs : [childs];
} }
/**
* @param {renderNodeSettings} settings
*/
set settings(settings){ set settings(settings){
var keys = Object.keys(settings); var keys = Object.keys(settings);
for (let i = 0; i < keys.length; i++) { for (let i = 0; i < keys.length; i++) {
@ -293,6 +555,11 @@ export class class_ {
} }
} }
/**
* Build Stear Structure
*
* @param {*} args
*/
async build (args) { async build (args) {
if(!this.#doBuild)return; if(!this.#doBuild)return;
this.#build = []; this.#build = [];
@ -313,6 +580,11 @@ export class class_ {
} }
} }
/**
* Genereate HTML Structure
*
* @return {HTMLElement}
*/
get render (){ get render (){
if (!this.#doBuild) return this.#elem; if (!this.#doBuild) return this.#elem;
this.#elem.innerHTML = ""; this.#elem.innerHTML = "";
@ -327,10 +599,18 @@ export class class_ {
return this.#elem; return this.#elem;
} }
/**
* @return {HTMLElement}
*/
get _ (){ get _ (){
return this.#elem; return this.#elem;
} }
/**
* Returns find Object
*
* @return {Object} find
*/
get find (){ get find (){
var out = {}; var out = {};
if (this.#doBuild){ if (this.#doBuild){
@ -342,15 +622,32 @@ export class class_ {
return out; return out;
} }
} }
/**
*
* @param {renderNodeSettings} [settings]
* @param {(LanguagePoolString|string|class_)[]} [childs]
* @returns
*/
export const _ = (settings = {}, childs = []) => new class_(settings, Array.isArray(childs) ? childs : [childs]); export const _ = (settings = {}, childs = []) => new class_(settings, Array.isArray(childs) ? childs : [childs]);
export const s = (type,settings,...childs)=>{ export const s = (type,settings,...childs)=>{
settings = settings ?? {};
settings.type = type; settings.type = type;
return new class_(settings,childs); return new class_(settings,childs);
} }
/** includeFrame */
class includeFrame{ class includeFrame{
#elem; #elem;
#call; #call;
/**
* Call another Frame and generate an includeFrame.
*
* @param {Stear} stear
* @param {SFrame} frame
* @param {number} layer
* @param {*} args
*/
constructor(stear,frame,layer, args = {}){ constructor(stear,frame,layer, args = {}){
this.#elem = new class_({},[],false); this.#elem = new class_({},[],false);
this.#call = stear.include(frame, args, this.#elem._, layer); this.#call = stear.include(frame, args, this.#elem._, layer);
@ -362,16 +659,28 @@ class includeFrame{
}); });
} }
/**
* @return {callUtils} utils from included Frame
*/
get opts(){ get opts(){
return this.#call.opts; return this.#call.opts;
} }
/**
* Close the included Frame.
*/
close(){ close(){
if(this.#call){ if(this.#call){
this.#call.opts.close(); this.#call.opts.close();
} }
} }
/**
* Trigger onParentRender event
*
* @param {*} settings
* @returns
*/
render(settings={}){ render(settings={}){
this.#elem.settings = settings; this.#elem.settings = settings;
this.#call.opts.event.onParentRender(); this.#call.opts.event.onParentRender();