Companent render is must be queque
This commit is contained in:
parent
4ff19e9b0e
commit
8ad90af4b1
470
core.js
470
core.js
|
@ -1,186 +1,326 @@
|
|||
function render(...entries)
|
||||
{
|
||||
let content = {};
|
||||
let domContainer = document.createElement('div');
|
||||
renderTreeQueQue(
|
||||
domContainer,
|
||||
entries,
|
||||
content
|
||||
);
|
||||
return domContainer;
|
||||
};
|
||||
|
||||
function renderTreeQueQue(domContainer, entries, content)
|
||||
{
|
||||
if(!content._renderPlanned)
|
||||
((window)=>{
|
||||
function render(...entries)
|
||||
{
|
||||
requestAnimationFrame(()=>{
|
||||
createTree(
|
||||
domContainer,
|
||||
entries,
|
||||
content
|
||||
)
|
||||
});
|
||||
content._renderPlanned = true;
|
||||
}
|
||||
};
|
||||
|
||||
function createTree(domContainer, entries, content)
|
||||
{
|
||||
let vdom = renderTree(entries, content);
|
||||
for (const vnode of vdom) {
|
||||
domContainer.append(vnode)
|
||||
}
|
||||
}
|
||||
|
||||
function * renderTree(entries,content)
|
||||
{
|
||||
let fragment = document.createDocumentFragment();
|
||||
for (const entry of entries) {
|
||||
fragment.appendChild(é(entry).render(content))
|
||||
let content = {};
|
||||
let domContainer = document.createElement('div');
|
||||
renderTreeQueQue(
|
||||
domContainer,
|
||||
entries,
|
||||
content
|
||||
);
|
||||
return domContainer;
|
||||
};
|
||||
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(
|
||||
Object.is(_stateIndex[n], o)
|
||||
)
|
||||
function renderTreeQueQue(domContainer, entries, content)
|
||||
{
|
||||
if(!content._renderPlanned)
|
||||
{
|
||||
_requireedRender = true;
|
||||
_stateIndex[n]=o;
|
||||
requestAnimationFrame(()=>{
|
||||
createTree(
|
||||
domContainer,
|
||||
entries,
|
||||
content
|
||||
)
|
||||
});
|
||||
content._renderPlanned = true;
|
||||
}
|
||||
};
|
||||
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);
|
||||
}
|
||||
};
|
||||
return _shadow || [];
|
||||
};
|
||||
};
|
||||
|
||||
function RenderElement(data)
|
||||
{
|
||||
let elem = document.createElement(data.$ || "div");
|
||||
for (const [name,value] of Object.entries(data)) {
|
||||
switch(name)
|
||||
function createTree(domContainer, entries, content)
|
||||
{
|
||||
let root = é(entries[0]);
|
||||
RenderElement(domContainer, root);
|
||||
}
|
||||
/**
|
||||
* @param {vnode} data
|
||||
*/
|
||||
function RenderElement(parent, data)
|
||||
{
|
||||
let elem;
|
||||
if(
|
||||
(typeof data == "boolean" && !data) ||
|
||||
data == null ||
|
||||
data === undefined
|
||||
)
|
||||
{
|
||||
case "$":
|
||||
break;
|
||||
case "in":
|
||||
break;
|
||||
default:{
|
||||
if(name.startsWith('on'))
|
||||
return document.createDocumentFragment()
|
||||
};
|
||||
if(data.type == é.type)
|
||||
{
|
||||
if(typeof data.companent == "string")
|
||||
{
|
||||
elem = document.createElement(data.companent);
|
||||
for (const [name,value] of Object.entries(data.props))
|
||||
{
|
||||
elem.addEventListener(name.slice(2),value)
|
||||
}else{
|
||||
elem.setAttribute(name, value)
|
||||
if(["key","children"].includes(name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(name.startsWith('on'))
|
||||
{
|
||||
elem.addEventListener(name.slice(2),value)
|
||||
}
|
||||
else
|
||||
{
|
||||
elem.setAttribute(name, value)
|
||||
}
|
||||
};
|
||||
}
|
||||
else if(typeof data.companent == "function")
|
||||
{
|
||||
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)) {
|
||||
switch(name)
|
||||
{
|
||||
case "$":
|
||||
break;
|
||||
case "in":
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if(name.startsWith('on'))
|
||||
{
|
||||
elem.addEventListener(name.slice(2),value)
|
||||
}
|
||||
else
|
||||
{
|
||||
elem.setAttribute(name, value)
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
if(data.in instanceof Array)
|
||||
{
|
||||
for (const companent of (data.in||[])) {
|
||||
if(
|
||||
typeof companent != élement &&
|
||||
typeof companent == "string"
|
||||
)
|
||||
if(data.in)
|
||||
{
|
||||
elem.append(document.createTextNode(companent));
|
||||
}else{
|
||||
elem.append(
|
||||
é(companent).render()
|
||||
);
|
||||
if(data.in instanceof Array)
|
||||
{
|
||||
for (const companent of (data.in||[])) {
|
||||
if(
|
||||
typeof companent == "string"
|
||||
)
|
||||
{
|
||||
elem.append(document.createTextNode(companent));
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderElement(elem, companent)
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(
|
||||
typeof data.in == "string"
|
||||
)
|
||||
{
|
||||
elem.append(document.createTextNode(data.in));
|
||||
}
|
||||
else
|
||||
{
|
||||
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.in != élement &&
|
||||
typeof data.in == "string"
|
||||
)
|
||||
else if(typeof data == "string")
|
||||
{
|
||||
elem.append(document.createTextNode(data.in));
|
||||
}else{
|
||||
elem.append(
|
||||
é(data.in).render()
|
||||
);
|
||||
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)
|
||||
function RenderCompanent(data)
|
||||
{
|
||||
state[index] = value;
|
||||
};
|
||||
return [
|
||||
state[index],
|
||||
(newValue) => {
|
||||
if(newValue instanceof Function)
|
||||
{
|
||||
newValue = newValue(state[index]);
|
||||
};
|
||||
if(Object.is(
|
||||
state[index],
|
||||
newValue
|
||||
))
|
||||
{
|
||||
currentCompanent._requireedRender = true;
|
||||
useCompanent(data);
|
||||
let result = data.companent(data.props);
|
||||
useCompanent(undefined);
|
||||
return result;
|
||||
}
|
||||
function é(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
|
||||
})
|
||||
}
|
||||
]
|
||||
return [value, () => {}];
|
||||
};
|
||||
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");
|
||||
|
||||
function é(a,b)
|
||||
{
|
||||
return a instanceof élement ? a : new élement(a,b);
|
||||
}
|
||||
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 {
|
||||
$:"b",
|
||||
in: text
|
||||
$:"link",
|
||||
rel: "stylesheet",
|
||||
href: "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/css/bootstrap.min.css",
|
||||
v: get
|
||||
}
|
||||
}
|
||||
let e = é({
|
||||
|
@ -11,13 +17,8 @@ let e = é({
|
|||
onclick:()=>{
|
||||
alert("Clicked ")
|
||||
},
|
||||
in:[
|
||||
"Hi !",
|
||||
é(BoldText,{
|
||||
text: "Bold Hi!"
|
||||
})
|
||||
]
|
||||
in: é(Bootstrap)
|
||||
});
|
||||
|
||||
e = e.render();
|
||||
document.body.appendChild(e);
|
||||
let t = render(e);
|
||||
document.body.appendChild(t);
|
Loading…
Reference in New Issue