Companent render is must be queque
This commit is contained in:
parent
4ff19e9b0e
commit
8ad90af4b1
358
core.js
358
core.js
|
@ -1,3 +1,4 @@
|
||||||
|
((window)=>{
|
||||||
function render(...entries)
|
function render(...entries)
|
||||||
{
|
{
|
||||||
let content = {};
|
let content = {};
|
||||||
|
@ -9,7 +10,6 @@ function render(...entries)
|
||||||
);
|
);
|
||||||
return domContainer;
|
return domContainer;
|
||||||
};
|
};
|
||||||
|
|
||||||
function renderTreeQueQue(domContainer, entries, content)
|
function renderTreeQueQue(domContainer, entries, content)
|
||||||
{
|
{
|
||||||
if(!content._renderPlanned)
|
if(!content._renderPlanned)
|
||||||
|
@ -27,71 +27,73 @@ function renderTreeQueQue(domContainer, entries, content)
|
||||||
|
|
||||||
function createTree(domContainer, entries, content)
|
function createTree(domContainer, entries, content)
|
||||||
{
|
{
|
||||||
let vdom = renderTree(entries, content);
|
let root = é(entries[0]);
|
||||||
for (const vnode of vdom) {
|
RenderElement(domContainer, root);
|
||||||
domContainer.append(vnode)
|
|
||||||
}
|
}
|
||||||
}
|
/**
|
||||||
|
* @param {vnode} data
|
||||||
function * renderTree(entries,content)
|
*/
|
||||||
|
function RenderElement(parent, data)
|
||||||
{
|
{
|
||||||
let fragment = document.createDocumentFragment();
|
let elem;
|
||||||
for (const entry of entries) {
|
|
||||||
fragment.appendChild(é(entry).render(content))
|
|
||||||
};
|
|
||||||
return fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
function élement(...args)
|
|
||||||
{
|
|
||||||
this._args = args;
|
|
||||||
let _stateIndex = [];
|
|
||||||
let _requireedRender = true;
|
|
||||||
let _previousCopy = [];
|
|
||||||
let _shadow = null;
|
|
||||||
this.hooks = [];
|
|
||||||
let _currentCopy = [];
|
|
||||||
this.getState = function(n){
|
|
||||||
return _stateIndex[n];
|
|
||||||
};
|
|
||||||
this.setCurrentCopy = function(shadow){
|
|
||||||
_previousCopy = _currentCopy;
|
|
||||||
_currentCopy = shadow;
|
|
||||||
};
|
|
||||||
this.setState = function(n,o){
|
|
||||||
if(
|
if(
|
||||||
Object.is(_stateIndex[n], o)
|
(typeof data == "boolean" && !data) ||
|
||||||
|
data == null ||
|
||||||
|
data === undefined
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_requireedRender = true;
|
return document.createDocumentFragment()
|
||||||
_stateIndex[n]=o;
|
};
|
||||||
|
if(data.type == é.type)
|
||||||
|
{
|
||||||
|
if(typeof data.companent == "string")
|
||||||
|
{
|
||||||
|
elem = document.createElement(data.companent);
|
||||||
|
for (const [name,value] of Object.entries(data.props))
|
||||||
|
{
|
||||||
|
if(["key","children"].includes(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(name.startsWith('on'))
|
||||||
|
{
|
||||||
|
elem.addEventListener(name.slice(2),value)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elem.setAttribute(name, value)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.render = function(ctx) {
|
|
||||||
if(_requireedRender)
|
|
||||||
{
|
|
||||||
if(this._args[0] instanceof Function)
|
|
||||||
{
|
|
||||||
_shadow = document.createDocumentFragment();
|
|
||||||
RenderCompanent(
|
|
||||||
this,
|
|
||||||
ctx,
|
|
||||||
this._args[1]
|
|
||||||
);
|
|
||||||
for (const entry of _currentCopy) {
|
|
||||||
_shadow.appendChild(é(entry).render(ctx))
|
|
||||||
};
|
|
||||||
}else{
|
|
||||||
_shadow = RenderElement(this._args[0], ctx);
|
|
||||||
}
|
}
|
||||||
};
|
else if(typeof data.companent == "function")
|
||||||
return _shadow || [];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
function RenderElement(data)
|
|
||||||
{
|
{
|
||||||
let elem = document.createElement(data.$ || "div");
|
let companent = RenderCompanent(data);
|
||||||
|
elem = RenderElement(null, companent)
|
||||||
|
}
|
||||||
|
else if(typeof data.companent == "string")
|
||||||
|
{
|
||||||
|
elem = document.createTextNode(companent);
|
||||||
|
}
|
||||||
|
else if(!data.companent)
|
||||||
|
{
|
||||||
|
elem = document.createDocumentFragment()
|
||||||
|
};
|
||||||
|
if(data.props && data.props.children instanceof Array)
|
||||||
|
{
|
||||||
|
for (const companent of (data.props.children||[]))
|
||||||
|
{
|
||||||
|
if( typeof companent == "string" )
|
||||||
|
{
|
||||||
|
elem.append(document.createTextNode(companent));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RenderElement(elem, companent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(data.$){
|
||||||
|
elem = document.createElement(data.$ || "div");
|
||||||
for (const [name,value] of Object.entries(data)) {
|
for (const [name,value] of Object.entries(data)) {
|
||||||
switch(name)
|
switch(name)
|
||||||
{
|
{
|
||||||
|
@ -99,88 +101,226 @@ function RenderElement(data)
|
||||||
break;
|
break;
|
||||||
case "in":
|
case "in":
|
||||||
break;
|
break;
|
||||||
default:{
|
default:
|
||||||
|
{
|
||||||
if(name.startsWith('on'))
|
if(name.startsWith('on'))
|
||||||
{
|
{
|
||||||
elem.addEventListener(name.slice(2),value)
|
elem.addEventListener(name.slice(2),value)
|
||||||
}else{
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
elem.setAttribute(name, value)
|
elem.setAttribute(name, value)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if(data.in)
|
||||||
|
{
|
||||||
if(data.in instanceof Array)
|
if(data.in instanceof Array)
|
||||||
{
|
{
|
||||||
for (const companent of (data.in||[])) {
|
for (const companent of (data.in||[])) {
|
||||||
if(
|
if(
|
||||||
typeof companent != élement &&
|
|
||||||
typeof companent == "string"
|
typeof companent == "string"
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
elem.append(document.createTextNode(companent));
|
elem.append(document.createTextNode(companent));
|
||||||
}else{
|
}
|
||||||
elem.append(
|
else
|
||||||
é(companent).render()
|
{
|
||||||
);
|
RenderElement(elem, companent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(
|
if(
|
||||||
typeof data.in != élement &&
|
|
||||||
typeof data.in == "string"
|
typeof data.in == "string"
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
elem.append(document.createTextNode(data.in));
|
elem.append(document.createTextNode(data.in));
|
||||||
}else{
|
}
|
||||||
elem.append(
|
else
|
||||||
é(data.in).render()
|
{
|
||||||
);
|
RenderElement(elem, companent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
data.parent = parent;
|
||||||
|
data.dom = elem;
|
||||||
|
}
|
||||||
|
else if(data instanceof Array)
|
||||||
|
{
|
||||||
|
if(parent)
|
||||||
|
{
|
||||||
|
for (const vdata of data.flat(Infinity)) {
|
||||||
|
RenderElement(parent, vdata)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
let d = document.createDocumentFragment();
|
||||||
|
for (const vdata of data.flat(Infinity)) {
|
||||||
|
RenderElement(d, vdata)
|
||||||
|
};
|
||||||
|
elem = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(typeof data == "string")
|
||||||
|
{
|
||||||
|
elem = document.createTextNode(data);
|
||||||
|
};
|
||||||
|
data._render = false;
|
||||||
|
if(parent)
|
||||||
|
{
|
||||||
|
parent.append(elem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
let currentCompanent;
|
|
||||||
let currentStateIndex = 0;
|
|
||||||
function RenderCompanent(élement, context, attr)
|
|
||||||
{
|
|
||||||
currentCompanent = élement;
|
|
||||||
currentStateIndex = 0;
|
|
||||||
let vshadow = élement._args[0].apply(context,[attr]);
|
|
||||||
élement.setCurrentCopy(vshadow instanceof Array ? vshadow : [vshadow]);
|
|
||||||
};
|
|
||||||
function Update()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
function Var(value)
|
|
||||||
{
|
|
||||||
let index = currentStateIndex++;
|
|
||||||
let state = currentCompanent.getState();
|
|
||||||
if(state.length)
|
|
||||||
{
|
|
||||||
state[index] = value;
|
|
||||||
};
|
|
||||||
return [
|
|
||||||
state[index],
|
|
||||||
(newValue) => {
|
|
||||||
if(newValue instanceof Function)
|
|
||||||
{
|
|
||||||
newValue = newValue(state[index]);
|
|
||||||
};
|
|
||||||
if(Object.is(
|
|
||||||
state[index],
|
|
||||||
newValue
|
|
||||||
))
|
|
||||||
{
|
|
||||||
currentCompanent._requireedRender = true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
]
|
|
||||||
return [value, () => {}];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
function RenderCompanent(data)
|
||||||
|
{
|
||||||
|
useCompanent(data);
|
||||||
|
let result = data.companent(data.props);
|
||||||
|
useCompanent(undefined);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
function é(a,b)
|
function é(a,b)
|
||||||
{
|
{
|
||||||
return a instanceof élement ? a : new élement(a,b);
|
if(a instanceof Array)
|
||||||
|
{
|
||||||
|
let t = b instanceof Array ? b : [];
|
||||||
|
for (const _a of a) {
|
||||||
|
if(_a instanceof Array)
|
||||||
|
{
|
||||||
|
é(_a, t);
|
||||||
|
}else{
|
||||||
|
t.push(é(_a));
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
t = t.flat(Infinity);
|
||||||
|
return é({
|
||||||
|
$: é.fragment,
|
||||||
|
in: t
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if(a.type == é.type)
|
||||||
|
{
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
let t = vnode(), companent, key, props = {};
|
||||||
|
if(typeof a == "function")
|
||||||
|
{
|
||||||
|
t.companent = a;
|
||||||
|
t.key = b && ('key' in b) ? b.key : undefined;
|
||||||
|
t.props = b;
|
||||||
|
}else if(typeof a == "string"){
|
||||||
|
t.companent = null;
|
||||||
|
t.props = {
|
||||||
|
children: [a]
|
||||||
|
};
|
||||||
|
}else if('$' in a){
|
||||||
|
props = {};
|
||||||
|
for (const index of Object.keys(a)) {
|
||||||
|
switch(index)
|
||||||
|
{
|
||||||
|
case "$": companent = a[index]; break;
|
||||||
|
case "in":{
|
||||||
|
if(a[index] instanceof Array)
|
||||||
|
{
|
||||||
|
props.children = a[index].map(é);
|
||||||
|
}else{
|
||||||
|
props.children = [
|
||||||
|
é(a[index])
|
||||||
|
]
|
||||||
|
}
|
||||||
|
break
|
||||||
|
};
|
||||||
|
case "key": key = a[index]; break;
|
||||||
|
default:{
|
||||||
|
props[index] = a[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t.companent = companent;
|
||||||
|
t.key = key;
|
||||||
|
t.props = props;
|
||||||
|
}else{
|
||||||
|
throw new Error("Unknown companent type")
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
é.type = Symbol("élement");
|
||||||
|
é.fragment = Symbol("framént");
|
||||||
|
|
||||||
|
let currentCompanent;
|
||||||
|
let currentCompanentStateIndex = 0;
|
||||||
|
|
||||||
|
function useCompanent(vnode)
|
||||||
|
{
|
||||||
|
currentCompanent = vnode;
|
||||||
|
currentCompanentStateIndex = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
function useState(initial)
|
||||||
|
{
|
||||||
|
let companent = currentCompanent;
|
||||||
|
let id = currentCompanentStateIndex++;
|
||||||
|
let value;
|
||||||
|
if(!companent)
|
||||||
|
{
|
||||||
|
throw new Error("Cannot be used outside of components")
|
||||||
|
};
|
||||||
|
if(companent._state.length <= id)
|
||||||
|
{
|
||||||
|
if(typeof initial == "function")
|
||||||
|
{
|
||||||
|
value = initial();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = initial;
|
||||||
|
}
|
||||||
|
companent._state[id] = value;
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
value = companent._state[id];
|
||||||
|
};
|
||||||
|
return [
|
||||||
|
value,
|
||||||
|
newValue => {
|
||||||
|
if(typeof newValue == "function")
|
||||||
|
{
|
||||||
|
value = newValue();
|
||||||
|
}
|
||||||
|
if(!Object.is(newValue, value))
|
||||||
|
{
|
||||||
|
companent._state[id] = value;
|
||||||
|
return companent._render = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
é.useState = useState;
|
||||||
|
|
||||||
|
function vnode()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
type: é.type,
|
||||||
|
// Raw render requirements
|
||||||
|
parent: undefined,
|
||||||
|
key: undefined,
|
||||||
|
companent: undefined,
|
||||||
|
props:{},
|
||||||
|
// Companent requirements
|
||||||
|
ref: undefined,
|
||||||
|
dom: undefined,
|
||||||
|
_state: [],
|
||||||
|
_hooks: [],
|
||||||
|
_render: true,
|
||||||
|
context: undefined
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.é = é;
|
||||||
|
window.render = render;
|
||||||
|
})(window)
|
|
@ -0,0 +1 @@
|
||||||
|
(e=>{function t(e,o){let r;if("boolean"==typeof o&&!o||null==o||void 0===o)return document.createDocumentFragment();if(o.type==n.type){if("string"==typeof o.companent){r=document.createElement(o.companent);for(const[e,t]of Object.entries(o.props))["key","children"].includes(e)||(e.startsWith("on")?r.addEventListener(e.slice(2),t):r.setAttribute(e,t))}else if("function"==typeof o.companent){let e=function(e){i(e);let t=e.companent(e.props);return i(void 0),t}(o);r=t(null,e)}else"string"==typeof o.companent?r=document.createTextNode(companent):o.companent||(r=document.createDocumentFragment());if(o.props&&o.props.children instanceof Array)for(const e of o.props.children||[])"string"==typeof e?r.append(document.createTextNode(e)):t(r,e)}else if(o.$){r=document.createElement(o.$||"div");for(const[e,t]of Object.entries(o))switch(e){case"$":case"in":break;default:e.startsWith("on")?r.addEventListener(e.slice(2),t):r.setAttribute(e,t)}if(o.in)if(o.in instanceof Array)for(const e of o.in||[])"string"==typeof e?r.append(document.createTextNode(e)):t(r,e);else"string"==typeof o.in?r.append(document.createTextNode(o.in)):t(r,companent);o.parent=e,o.dom=r}else if(o instanceof Array)if(e)for(const n of o.flat(1/0))t(e,n);else{let e=document.createDocumentFragment();for(const n of o.flat(1/0))t(e,n);r=e}else"string"==typeof o&&(r=document.createTextNode(o));if(o._render=!1,!e)return r;e.append(r)}function n(e,t){if(e instanceof Array){let o=t instanceof Array?t:[];for(const t of e)t instanceof Array?n(t,o):o.push(n(t));return o=o.flat(1/0),n({$:n.fragment,in:o})}if(e.type==n.type)return e;let o,r,i={type:n.type,parent:void 0,key:void 0,companent:void 0,props:{},ref:void 0,dom:void 0,_state:[],_hooks:[],_render:!0,context:void 0},c={};if("function"==typeof e)i.companent=e,i.key=t&&"key"in t?t.key:void 0,i.props=t;else if("string"==typeof e)i.companent=null,i.props={children:[e]};else{if(!("$"in e))throw new Error("Unknown companent type");c={};for(const t of Object.keys(e))switch(t){case"$":o=e[t];break;case"in":e[t]instanceof Array?c.children=e[t].map(n):c.children=[n(e[t])];break;case"key":r=e[t];break;default:c[t]=e[t]}i.companent=o,i.key=r,i.props=c}return i}let o;n.type=Symbol("élement"),n.fragment=Symbol("framént");let r=0;function i(e){o=e,r=0}n.useState=function(e){let t,n=o,i=r++;if(!n)throw new Error("Cannot be used outside of components");return n._state.length<=i?(t="function"==typeof e?e():e,n._state[i]=t):t=n._state[i],[t,e=>{if("function"==typeof e&&(t=e()),!Object.is(e,t))return n._state[i]=t,n._render=!0}]},e.é=n,e.render=function(...e){let o=document.createElement("div");return function(e,o,r){r._renderPlanned||(requestAnimationFrame((()=>{!function(e,o,r){let i=n(o[0]);t(e,i)}(e,o)})),r._renderPlanned=!0)}(o,e,{}),o}})(window);
|
23
index.js
23
index.js
|
@ -1,8 +1,14 @@
|
||||||
function BoldText({text})
|
function Bootstrap()
|
||||||
{
|
{
|
||||||
|
let [get, set] = é.useState(1);
|
||||||
|
setTimeout(()=>{
|
||||||
|
set(2);
|
||||||
|
}, 5000);
|
||||||
return {
|
return {
|
||||||
$:"b",
|
$:"link",
|
||||||
in: text
|
rel: "stylesheet",
|
||||||
|
href: "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/css/bootstrap.min.css",
|
||||||
|
v: get
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let e = é({
|
let e = é({
|
||||||
|
@ -11,13 +17,8 @@ let e = é({
|
||||||
onclick:()=>{
|
onclick:()=>{
|
||||||
alert("Clicked ")
|
alert("Clicked ")
|
||||||
},
|
},
|
||||||
in:[
|
in: é(Bootstrap)
|
||||||
"Hi !",
|
|
||||||
é(BoldText,{
|
|
||||||
text: "Bold Hi!"
|
|
||||||
})
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
e = e.render();
|
let t = render(e);
|
||||||
document.body.appendChild(e);
|
document.body.appendChild(t);
|
Loading…
Reference in New Issue