From 08300f67febb47bcdfdde6d1c19106209c471746 Mon Sep 17 00:00:00 2001 From: Hoikan <408255371@qq.com> Date: Thu, 22 Feb 2024 02:45:52 +0000 Subject: [PATCH] !156 feat(no-vdom): render * feat(no-vdom): render --- packages/inula-novdom/package.json | 3 +- packages/inula-novdom/src/dom.ts | 4 + packages/inula-novdom/src/event.ts | 11 ++ packages/inula-novdom/tests/render.test.tsx | 140 ++++-------------- .../src/HelperGenerators/HTMLPropGenerator.ts | 26 ++-- 5 files changed, 56 insertions(+), 128 deletions(-) diff --git a/packages/inula-novdom/package.json b/packages/inula-novdom/package.json index c5597b82..8b73d689 100644 --- a/packages/inula-novdom/package.json +++ b/packages/inula-novdom/package.json @@ -11,9 +11,10 @@ "inula-reactive": "workspace:^0.0.1" }, "devDependencies": { - "jsdom": "^24.0.0", "@testing-library/user-event": "^12.1.10", "@vitest/ui": "^0.34.5", + "jsdom": "^24.0.0", + "vite-plugin-inula-no-vdom": "workspace:*", "vitest": "^1.2.2" } } diff --git a/packages/inula-novdom/src/dom.ts b/packages/inula-novdom/src/dom.ts index 27153578..c305c73a 100644 --- a/packages/inula-novdom/src/dom.ts +++ b/packages/inula-novdom/src/dom.ts @@ -389,3 +389,7 @@ export function bindRef(node: T, ref: RefObject | RefCallback): void { export function createElement(tag: string) { return document.createElement(tag); } + +export function createText(text: string) { + return document.createTextNode(text); +} diff --git a/packages/inula-novdom/src/event.ts b/packages/inula-novdom/src/event.ts index 734d6ad1..c741e00b 100644 --- a/packages/inula-novdom/src/event.ts +++ b/packages/inula-novdom/src/event.ts @@ -31,6 +31,17 @@ export function delegateEvents(eventNames: string[], node: Node = window.documen } } +export function delegateEvent(source: HTMLElement, eventName: string, listener: EventListener, delegator: Node = window.document): void { + const events: Set = delegator[DELEGATE_EVENTS_KEY] || (delegator[DELEGATE_EVENTS_KEY] = new Set()); + + if (!events.has(eventName)) { + events.add(eventName); + delegator.addEventListener(eventName, eventHandler); + } + + source[`$$DELEGATE_EVENT_${eventName}`] = listener; +} + export function clearDelegatedEvents(node: Node = window.document): void { const events: Set | undefined = node[DELEGATE_EVENTS_KEY]; if (events) { diff --git a/packages/inula-novdom/tests/render.test.tsx b/packages/inula-novdom/tests/render.test.tsx index c3420b20..47f49bb2 100644 --- a/packages/inula-novdom/tests/render.test.tsx +++ b/packages/inula-novdom/tests/render.test.tsx @@ -22,25 +22,17 @@ import { style as $$style, className as $$className, setAttribute as $$attr, - createElement + createElement, + createText, + insert, } from '../src/dom'; -import { runComponent as $$runComponent, render } from '../src/core'; -import { delegateEvents as $$delegateEvents, addEventListener as $$on } from '../src/event'; +import { runComponent as $$runComponent, render, runComponent as createComponent } from '../src/core'; +import { delegateEvents as $$delegateEvents, addEventListener as $$on, delegateEvent } from '../src/event'; import { describe, expect } from 'vitest'; import { domTest as it } from './utils'; describe('render', () => { it('should render plain jsx', ({ container }) => { - /** - * 源码: - * const CountingComponent = () => { - * return
Count value is 0.
; - * }; - * - * render(() => , container); - */ - - // 编译后: const CountingComponent = () => { return
Count value is 0.
; }; @@ -50,139 +42,59 @@ describe('render', () => { }); it('should render jsx expression with slots', ({ container }) => { - /** - * 源码: - * const CountingComponent = () => { - * return
Count value is {0}.
; - * }; - * - * render(() => , container); - */ - - // 编译后: - const $tmpl = /*#__PURE__*/ $$template('
Count value is .'); const CountingComponent = () => { - return (() => { - const _el$ = $tmpl(), - _el$2 = _el$.firstChild, - _el$4 = _el$2.nextSibling; - $$insert(_el$, 0, _el$4); - return _el$; - })(); + return
Count value is {0}.
; }; render(() => $$runComponent(CountingComponent, {}), container); - expect(container.querySelector('#count').innerHTML).toEqual('Count value is 0.'); + expect(container.querySelector('#count').innerHTML).toEqual('Count value is 0.'); }); it('should render fragment', ({ container }) => { - /** - * 源码: - * const CountingComponent = () => { - * const [count, setCount] = createSignal(0); - * const add = () => { - * setCount((c) => c + 1); - * } - * return <> - *
Count value is {count()}.
- *
- * ; - * }; - */ - - // 编译后: - const $tmpl = /*#__PURE__*/ $$template('
Count value is .'), - $tmpl_2 = /*#__PURE__*/ $$template('
+
+ + ); }; render(() => $$runComponent(CountingComponent, {}), container); - $$delegateEvents(['click']); - container.querySelector('#btn').click(); - expect(container.querySelector('#count').innerHTML).toEqual('Count value is 1.'); + expect(container.querySelector('#count').innerHTML).toEqual('Count value is 1.'); }); it('should render components', ({ container }) => { - /** - * 源码: - * const CountValue = (props) => { - * return
Count value is {props.count} .
; - * } - * - * const CountingComponent = () => { - * const [count, setCount] = createSignal(0); - * const add = () => { - * setCount((c) => c + 1); - * } - * - * return
- * - *
- *
; - * }; - * - * render(() => , document.getElementById("app")); - */ - - // 编译后: - const $tmpl = /*#__PURE__*/ $$template('
Count value is .'), - $tmpl_2 = /*#__PURE__*/ $$template('
+
+
+ ); }; render(() => $$runComponent(CountingComponent, {}), container); - $$delegateEvents(['click']); container.querySelector('#btn').click(); - expect(container.querySelector('#count').innerHTML).toEqual('Count value is 1.'); + expect(container.querySelector('#count').innerHTML).toEqual('Count value is 1.'); }); it('should render components with slot', ({ container }) => { diff --git a/packages/transpiler/jsx-view-generator/src/HelperGenerators/HTMLPropGenerator.ts b/packages/transpiler/jsx-view-generator/src/HelperGenerators/HTMLPropGenerator.ts index 7d413cfa..5f218386 100644 --- a/packages/transpiler/jsx-view-generator/src/HelperGenerators/HTMLPropGenerator.ts +++ b/packages/transpiler/jsx-view-generator/src/HelperGenerators/HTMLPropGenerator.ts @@ -28,7 +28,7 @@ export class HTMLPropGenerator extends BaseGenerator { ]) addHTMLProp( - nodeName: string, + nodeName: string, tag: string, key: string, value: t.Expression, @@ -45,7 +45,7 @@ export class HTMLPropGenerator extends BaseGenerator { * setStyle($node, value) */ private setStyle( - nodeName: string, + nodeName: string, value: t.Expression, ) { return this.t.callExpression( @@ -59,7 +59,7 @@ export class HTMLPropGenerator extends BaseGenerator { * setDataset($node, value) */ private setDataset( - nodeName: string, + nodeName: string, value: t.Expression, ) { return this.t.callExpression( @@ -73,7 +73,7 @@ export class HTMLPropGenerator extends BaseGenerator { * $node.key = value */ private setStaticProperty( - nodeName: string, + nodeName: string, key: string, value: t.Expression, ) { @@ -92,7 +92,7 @@ export class HTMLPropGenerator extends BaseGenerator { * setProperty($node, key, value) */ private setDynamicProperty( - nodeName: string, + nodeName: string, key: string, value: t.Expression, ) { @@ -107,7 +107,7 @@ export class HTMLPropGenerator extends BaseGenerator { * $node.setAttribute(key, value) */ private setStaticAttribute( - nodeName: string, + nodeName: string, key: string, value: t.Expression, ) { @@ -126,7 +126,7 @@ export class HTMLPropGenerator extends BaseGenerator { * setAttribute($node, key, value) */ private setDynamicAttribute( - nodeName: string, + nodeName: string, key: string, value: t.Expression, ) { @@ -141,12 +141,12 @@ export class HTMLPropGenerator extends BaseGenerator { * delegateEvent($node, eventName, value) */ private setDelegatedEvent( - nodeName: string, + nodeName: string, eventName: string, value: t.Expression, ) { return this.t.callExpression( - this.t.identifier(this.importMap.delegateEvent), + this.t.identifier(this.importMap.delegateEvents), [this.t.identifier(nodeName), this.t.stringLiteral(eventName), value] ); } @@ -156,7 +156,7 @@ export class HTMLPropGenerator extends BaseGenerator { * $node.addEventListener(eventName, value) */ private setStaticEvent( - nodeName: string, + nodeName: string, eventName: string, value: t.Expression, ) { @@ -174,7 +174,7 @@ export class HTMLPropGenerator extends BaseGenerator { * addEventListener($node, eventName, value) */ private setDynamicEvent( - nodeName: string, + nodeName: string, eventName: string, value: t.Expression, ) { @@ -185,7 +185,7 @@ export class HTMLPropGenerator extends BaseGenerator { } private setDynamicHTMLProp( - nodeName: string, + nodeName: string, tag: string, key: string, value: t.Expression, @@ -220,4 +220,4 @@ export class HTMLPropGenerator extends BaseGenerator { this.elementAttributeMap[tag]?.includes(attribute) ); } -} \ No newline at end of file +}