Skip to content

Commit

Permalink
feat(signal): add a solid.js like create signal function
Browse files Browse the repository at this point in the history
  • Loading branch information
Masquerade-Circus committed Dec 23, 2022
1 parent d041c06 commit 7c4e8e3
Show file tree
Hide file tree
Showing 19 changed files with 2,067 additions and 770 deletions.
824 changes: 791 additions & 33 deletions bench/.buffalo-test.json

Large diffs are not rendered by default.

7 changes: 2 additions & 5 deletions bench/mount_n_update_bench.js
Original file line number Diff line number Diff line change
Expand Up @@ -779,15 +779,12 @@ compare("Mount and update: Update class", () => {
});
});

compare("Mount and update: Update class with hooks vs shouldupdate property", () => {
compare("Mount and update: Update class with hooks vs v-keep", () => {
let updateClass2 = "";
let Component = () => (
<div>
{
<div
class={updateClass2 === "test" ? "test" : false}
shouldupdate={(vnode, oldVnode) => vnode.props.class !== oldVnode.props.class}
>
<div class={updateClass2 === "test" ? "test" : false} v-keep={updateClass2}>
test
</div>
}
Expand Down
7 changes: 2 additions & 5 deletions bench/mount_n_update_no_memo_bench.js
Original file line number Diff line number Diff line change
Expand Up @@ -804,15 +804,12 @@ compare("(No memo) Mount and update: Update class", () => {
});
});

compare("(No memo) Mount and update: Update class with hooks vs shouldupdate property", () => {
compare.only("(No memo) Mount and update: Update class with hooks vs v-keep", () => {
let updateClass2 = "";
let Component = () => (
<div>
{
<div
class={updateClass2 === "test" ? "test" : false}
shouldupdate={(vnode, oldVnode) => vnode.props.class !== oldVnode.props.class}
>
<div class={updateClass2 === "test" ? "test" : false} v-keep={updateClass2}>
test
</div>
}
Expand Down
119 changes: 71 additions & 48 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ __export(lib_exports, {
unmount: () => unmount,
update: () => update,
updateAttributes: () => updateAttributes,
updateVnode: () => updateVnode,
v: () => v
});
module.exports = __toCommonJS(lib_exports);
Expand Down Expand Up @@ -307,11 +308,12 @@ function directive(name, directive2) {
}
function sharedSetAttribute(name, value, newVnode, oldVnode) {
if (typeof value === "function") {
if (name in eventListenerNames === false) {
mainVnode.dom.addEventListener(name.slice(2), eventListener);
eventListenerNames[name] = true;
let lowercaseName = name.toLowerCase();
if (lowercaseName in eventListenerNames === false) {
mainVnode.dom.addEventListener(lowercaseName.slice(2), eventListener);
eventListenerNames[lowercaseName] = true;
}
newVnode.dom[`v-${name}`] = value;
newVnode.dom[`v-${lowercaseName}`] = value;
return;
}
if (name in newVnode.dom && newVnode.isSVG === false) {
Expand Down Expand Up @@ -410,41 +412,18 @@ function patch(newVnode, oldVnode) {
for (let i = 0; i < newTree.length; i++) {
let newChild = newTree[i];
if (newChild instanceof Vnode && newChild.tag !== textTag) {
if (typeof newChild.tag !== "string") {
current.component = newChild.tag;
newTree.splice(
i--,
1,
("view" in newChild.tag ? newChild.tag.view.bind(newChild.tag) : newChild.tag.bind(newChild.tag))(
newChild.props,
...newChild.children
)
);
if (typeof newChild.tag === "string") {
continue;
}
newChild.isSVG = newVnode.isSVG || newChild.tag === "svg";
if (i < oldTreeLength) {
let oldChild = oldTree[i];
if (newChild.tag === oldChild.tag) {
newChild.dom = oldChild.dom;
if ("v-keep" in newChild.props && newChild.props["v-keep"] === oldChild.props["v-keep"]) {
newChild.children = oldChild.children;
continue;
}
updateAttributes(newChild, oldChild);
patch(newChild, oldChild);
continue;
}
newChild.dom = createDomElement(newChild.tag, newChild.isSVG);
updateAttributes(newChild);
newVnode.dom.replaceChild(newChild.dom, oldChild.dom);
patch(newChild);
continue;
}
newChild.dom = createDomElement(newChild.tag, newChild.isSVG);
updateAttributes(newChild);
newVnode.dom.appendChild(newChild.dom);
patch(newChild);
current.component = newChild.tag;
newTree.splice(
i--,
1,
("view" in newChild.tag ? newChild.tag.view.bind(newChild.tag) : newChild.tag.bind(newChild.tag))(
newChild.props,
...newChild.children
)
);
continue;
}
if (Array.isArray(newChild)) {
Expand All @@ -455,26 +434,55 @@ function patch(newVnode, oldVnode) {
newTree.splice(i--, 1);
continue;
}
newTree[i] = new Vnode(textTag, {}, []);
if (newChild instanceof Vnode) {
newTree[i].dom = newChild.dom;
newChild = newChild.dom.textContent;
newChild.children[0] = newChild.dom.textContent;
continue;
}
newChild = newTree[i] = new Vnode(textTag, {}, [newChild]);
}
for (let i = 0; i < newTree.length; i++) {
let newChild = newTree[i];
if (newChild.tag === textTag) {
if (i < oldTreeLength) {
let oldChild = oldTree[i];
if (oldChild.tag === textTag) {
newChild.dom = oldChild.dom;
if (newChild.children[0] != oldChild.dom.textContent) {
oldChild.dom.textContent = newChild.children[0];
}
continue;
}
newChild.dom = document.createTextNode(newChild.children[0]);
newVnode.dom.replaceChild(newChild.dom, oldChild.dom);
continue;
}
newChild.dom = document.createTextNode(newChild.children[0]);
newVnode.dom.appendChild(newChild.dom);
continue;
}
newChild.isSVG = newVnode.isSVG || newChild.tag === "svg";
if (i < oldTreeLength) {
let oldChild = oldTree[i];
if (oldChild.tag === textTag) {
newTree[i].dom = oldChild.dom;
if (newChild != oldChild.dom.textContent) {
oldChild.dom.textContent = newChild;
if (newChild.tag === oldChild.tag) {
newChild.dom = oldChild.dom;
if ("v-keep" in newChild.props && newChild.props["v-keep"] === oldChild.props["v-keep"]) {
newChild.children = oldChild.children;
continue;
}
updateAttributes(newChild, oldChild);
patch(newChild, oldChild);
continue;
}
newTree[i].dom = document.createTextNode(newChild);
newVnode.dom.replaceChild(newTree[i].dom, oldChild.dom);
newChild.dom = createDomElement(newChild.tag, newChild.isSVG);
updateAttributes(newChild);
newVnode.dom.replaceChild(newChild.dom, oldChild.dom);
patch(newChild);
continue;
}
newTree[i].dom = document.createTextNode(newChild);
newVnode.dom.appendChild(newTree[i].dom);
newChild.dom = createDomElement(newChild.tag, newChild.isSVG);
updateAttributes(newChild);
newVnode.dom.appendChild(newChild.dom);
patch(newChild);
}
for (let i = newTree.length; i < oldTreeLength; i++) {
newVnode.dom.removeChild(oldTree[i].dom);
Expand All @@ -498,6 +506,21 @@ function update() {
}
}
}
function updateVnode(vnode, oldVnode) {
callSet(onCleanupSet);
patch(vnode, oldVnode);
oldVnode.tag = vnode.tag;
oldVnode.props = { ...vnode.props };
oldVnode.children = [...vnode.children];
callSet(isMounted ? onUpdateSet : onMountSet);
isMounted = true;
current.vnode = null;
current.oldVnode = null;
current.component = null;
if (isNodeJs) {
return vnode.dom.innerHTML;
}
}
function unmount() {
if (mainVnode) {
mainComponent = new Vnode(() => null, {}, []);
Expand Down
Loading

0 comments on commit 7c4e8e3

Please sign in to comment.