Companent render is must be queque

This commit is contained in:
Abdussamed ULUTAŞ 2023-01-21 22:30:07 +03:00
parent 4ff19e9b0e
commit 8ad90af4b1
3 changed files with 318 additions and 176 deletions

470
core.js
View File

@ -1,186 +1,326 @@
function render(...entries) ((window)=>{
{ function render(...entries)
let content = {};
let domContainer = document.createElement('div');
renderTreeQueQue(
domContainer,
entries,
content
);
return domContainer;
};
function renderTreeQueQue(domContainer, entries, content)
{
if(!content._renderPlanned)
{ {
requestAnimationFrame(()=>{ let content = {};
createTree( let domContainer = document.createElement('div');
domContainer, renderTreeQueQue(
entries, domContainer,
content entries,
) content
}); );
content._renderPlanned = true; return domContainer;
}
};
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))
}; };
return fragment; function renderTreeQueQue(domContainer, entries, content)
} {
if(!content._renderPlanned)
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)
)
{ {
_requireedRender = true; requestAnimationFrame(()=>{
_stateIndex[n]=o; 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) function createTree(domContainer, entries, content)
{ {
let elem = document.createElement(data.$ || "div"); let root = é(entries[0]);
for (const [name,value] of Object.entries(data)) { RenderElement(domContainer, root);
switch(name) }
/**
* @param {vnode} data
*/
function RenderElement(parent, data)
{
let elem;
if(
(typeof data == "boolean" && !data) ||
data == null ||
data === undefined
)
{ {
case "$": return document.createDocumentFragment()
break; };
case "in": if(data.type == é.type)
break; {
default:{ if(typeof data.companent == "string")
if(name.startsWith('on')) {
elem = document.createElement(data.companent);
for (const [name,value] of Object.entries(data.props))
{ {
elem.addEventListener(name.slice(2),value) if(["key","children"].includes(name))
}else{ {
elem.setAttribute(name, value) 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)
};
if(data.in instanceof Array)
{
for (const companent of (data.in||[])) {
if(
typeof companent != élement &&
typeof companent == "string"
)
{ {
elem.append(document.createTextNode(companent)); if(data.in instanceof Array)
}else{ {
elem.append( for (const companent of (data.in||[])) {
é(companent).render() 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{ else if(typeof data == "string")
if(
typeof data.in != élement &&
typeof data.in == "string"
)
{ {
elem.append(document.createTextNode(data.in)); elem = document.createTextNode(data);
}else{ };
elem.append( data._render = false;
é(data.in).render() if(parent)
); {
parent.append(elem);
}
else
{
return elem;
} }
} }
return elem;
}
let currentCompanent; function RenderCompanent(data)
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; useCompanent(data);
}; let result = data.companent(data.props);
return [ useCompanent(undefined);
state[index], return result;
(newValue) => { }
if(newValue instanceof Function) function é(a,b)
{ {
newValue = newValue(state[index]); if(a instanceof Array)
}; {
if(Object.is( let t = b instanceof Array ? b : [];
state[index], for (const _a of a) {
newValue if(_a instanceof Array)
)) {
{ é(_a, t);
currentCompanent._requireedRender = true; }else{
t.push(é(_a));
}
}; };
t = t.flat(Infinity);
return é({
$: é.fragment,
in: t
})
} }
] if(a.type == é.type)
return [value, () => {}]; {
}; 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) let currentCompanent;
{ let currentCompanentStateIndex = 0;
return a instanceof élement ? a : new élement(a,b);
} 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)

1
core.min.js vendored Normal file
View File

@ -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);

View File

@ -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);