Skip to content

Commit

Permalink
feat: rootdom remove feature and fix removeEvent not working
Browse files Browse the repository at this point in the history
  • Loading branch information
superlucky84 committed Jun 21, 2023
1 parent 8a02ad4 commit 0afe113
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 33 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ pnpm add -D htm
import { h, render, mount } from 'lithent';
import htm from 'htm';
const html = htm.bind(h);
);
```

#### With JSX
Expand Down
1 change: 0 additions & 1 deletion lithentDocs/src/pages/install.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const html = htm.bind(h);
const Component = mount(() => () => html\`<li>count: \${'htm example'}</li>\`;
render(html\`<\${Component} />\`);
);
`;

const code = `$ npm install lithent`;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lithent",
"version": "0.33.0",
"version": "0.34.0",
"description": "lithent",
"packageManager": "pnpm@7.6.0",
"main": "./dist/lithent.umd.js",
Expand Down
33 changes: 31 additions & 2 deletions src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
checkRadioElement,
} from '@/utils/predicator';

import { componentRef } from '@/utils/universalRef';
import { runUnmountQueueFromWDom } from '@/hook/unmount';
import { runMountedQueueFromWDom } from '@/hook/mountCallback';
import { runUpdatedQueueFromWDom } from '@/hook/useUpdate';
import { getParent } from '@/utils';
Expand All @@ -45,6 +47,17 @@ export const render = (
} else {
wrapElement.appendChild(Dom);
}

return () => {
if (wDom.componentProps) {
const component = componentRef.get(wDom.componentProps)?.vd.value;
if (component) {
runUnmountQueueFromWDom(component);
recursiveRemoveEvent(component);
rootDelete(component);
}
}
};
};

export const wDomUpdate = (newWDomTree: WDom) => {
Expand Down Expand Up @@ -73,14 +86,24 @@ export const recursiveRemoveEvent = (originalWDom: WDom) => {
});
};

const rootDelete = (newWDom: WDom) => {
const parent = findRealParentElement(newWDom) as HTMLElement;

deleteRealDom(newWDom, parent);
};

const typeDelete = (newWDom: WDom) => {
const parentWDom = getParent(newWDom);
const parent = findRealParentElement(parentWDom);
const parent = findRealParentElement(parentWDom) as HTMLElement;

if (newWDom.oldProps && newWDom.el) {
removeEvent(newWDom.oldProps, newWDom.el);
}

deleteRealDom(newWDom, parent);
};

const deleteRealDom = (newWDom: WDom, parent: HTMLElement) => {
if (parent && newWDom.el) {
if (newWDom.el?.nodeType === 1) {
parent.removeChild(newWDom.el);
Expand Down Expand Up @@ -221,7 +244,13 @@ const removeEvent = (
Object.entries(oldProps || {}).forEach(
([dataKey, dataValue]: [string, unknown]) => {
if (dataKey.match(/^on/)) {
element.removeEventListener(dataKey, dataValue as (e: Event) => void);
const eventName = dataKey.replace(/^on(.*)/, (_match, p1) =>
p1.toLowerCase()
);
element.removeEventListener(
eventName,
dataValue as (e: Event) => void
);
}
}
);
Expand Down
72 changes: 44 additions & 28 deletions src/wDom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,6 @@ import {

export type Children = WDom[];

type WDomInfoParam = {
componentMaker: (props: Props) => WDom;
componentKey: Props;
tag: TagFunction;
props: Props;
children: WDom[];
};
type WDomInfoWithRenderParam = WDomInfoParam & {
reRender: () => WDom;
};

export const Fragment = (_props: Props, ...children: WDom[]) => ({
type: 'fragment',
children,
Expand Down Expand Up @@ -108,13 +97,13 @@ const makeWDomResolver = (tag: TagFunction, props: Props, children: WDom[]) => {
children
);

const customNode = makeCustomNode({
const customNode = makeCustomNode(
componentMaker,
componentKey,
tag,
props,
children,
});
children
);

const originalWDom = customNode;

Expand All @@ -131,25 +120,47 @@ const makeWDomResolver = (tag: TagFunction, props: Props, children: WDom[]) => {
return { tagName, constructor, props, children, resolve };
};

const makeCustomNode = (wDomInfo: WDomInfoParam) => {
const { componentMaker, props } = wDomInfo;
const makeCustomNode = (
componentMaker: (props: Props) => WDom,
componentKey: Props,
tag: TagFunction,
props: Props,
children: WDom[]
) => {
const customNode = componentMaker(props);
const reRender = makeReRender(wDomInfo);
const reRender = makeReRender(
componentMaker,
componentKey,
tag,
props,
children
);

addComponentProps(customNode, { ...wDomInfo, reRender });
addComponentProps(customNode, componentKey, tag, props, children, reRender);

return customNode;
};

const makeReRender = (wDomInfo: WDomInfoParam) => {
const reRender = () => wDomMaker({ ...wDomInfo, reRender });

const makeReRender = (
componentMaker: (props: Props) => WDom,
componentKey: Props,
tag: TagFunction,
props: Props,
children: WDom[]
) => {
const reRender = () =>
wDomMaker(componentMaker, componentKey, tag, props, children, reRender);
return reRender;
};

const wDomMaker = (wDomInfo: WDomInfoWithRenderParam) => {
const { componentMaker, componentKey, tag, props, children } = wDomInfo;

const wDomMaker = (
componentMaker: (props: Props) => WDom,
componentKey: Props,
tag: TagFunction,
props: Props,
children: WDom[],
reRender: () => WDom
) => {
initUpdateHookState(componentKey);
runUpdateCallback();

Expand All @@ -159,17 +170,22 @@ const wDomMaker = (wDomInfo: WDomInfoWithRenderParam) => {
reRenderCustomComponent(tag, props, children, originalWDom)
);

addComponentProps(originalWDom, wDomInfo);
addComponentProps(originalWDom, componentKey, tag, props, children, reRender);

(getComponentSubInfo(componentKey, 'vd') as { value: WDom }).value =
originalWDom;

return originalWDom;
};

const addComponentProps = (wDom: WDom, info: WDomInfoWithRenderParam) => {
const { componentKey, tag, props, children, reRender } = info;

const addComponentProps = (
wDom: WDom,
componentKey: Props,
tag: TagFunction,
props: Props,
children: WDom[],
reRender: () => WDom
) => {
Object.assign(wDom, {
componentProps: props,
componentChildren: children,
Expand Down

0 comments on commit 0afe113

Please sign in to comment.