parent
ef5ee212e3
commit
08300f67fe
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -389,3 +389,7 @@ export function bindRef<T>(node: T, ref: RefObject<T> | RefCallback<T>): void {
|
|||
export function createElement(tag: string) {
|
||||
return document.createElement(tag);
|
||||
}
|
||||
|
||||
export function createText(text: string) {
|
||||
return document.createTextNode(text);
|
||||
}
|
||||
|
|
|
@ -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<string> = 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<string> | undefined = node[DELEGATE_EVENTS_KEY];
|
||||
if (events) {
|
||||
|
|
|
@ -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 <div id="count">Count value is 0.</div>;
|
||||
* };
|
||||
*
|
||||
* render(() => <CountingComponent />, container);
|
||||
*/
|
||||
|
||||
// 编译后:
|
||||
const CountingComponent = () => {
|
||||
return <div id="count">Count value is 0.</div>;
|
||||
};
|
||||
|
@ -50,139 +42,59 @@ describe('render', () => {
|
|||
});
|
||||
|
||||
it('should render jsx expression with slots', ({ container }) => {
|
||||
/**
|
||||
* 源码:
|
||||
* const CountingComponent = () => {
|
||||
* return <div id="count">Count value is {0}.</div>;
|
||||
* };
|
||||
*
|
||||
* render(() => <CountingComponent />, container);
|
||||
*/
|
||||
|
||||
// 编译后:
|
||||
const $tmpl = /*#__PURE__*/ $$template('<div id="count">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 <div id="count">Count value is {0}.</div>;
|
||||
};
|
||||
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 <>
|
||||
* <div id="count">Count value is {count()}.</div>
|
||||
* <div><button onClick={add}>add</button></div>
|
||||
* </>;
|
||||
* };
|
||||
*/
|
||||
|
||||
// 编译后:
|
||||
const $tmpl = /*#__PURE__*/ $$template('<div id="count">Count value is <!>.'),
|
||||
$tmpl_2 = /*#__PURE__*/ $$template('<div><button id="btn">add');
|
||||
const CountingComponent = () => {
|
||||
const count = reactive(0);
|
||||
const add = () => {
|
||||
count.set(c => c + 1);
|
||||
};
|
||||
return [
|
||||
(() => {
|
||||
const _el$ = $tmpl(),
|
||||
_el$2 = _el$.firstChild,
|
||||
_el$4 = _el$2.nextSibling;
|
||||
$$insert(_el$, count, _el$4);
|
||||
return _el$;
|
||||
})(),
|
||||
(() => {
|
||||
const _el$5 = $tmpl_2(),
|
||||
_el$6 = _el$5.firstChild;
|
||||
$$on(_el$6, 'click', add, true);
|
||||
return _el$5;
|
||||
})(),
|
||||
];
|
||||
return (
|
||||
<>
|
||||
<div id="count">Count value is {count.get()}.</div>
|
||||
<div>
|
||||
<button id="btn" onClick={add}>add</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
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 <div id="count">Count value is {props.count} .</div>;
|
||||
* }
|
||||
*
|
||||
* const CountingComponent = () => {
|
||||
* const [count, setCount] = createSignal(0);
|
||||
* const add = () => {
|
||||
* setCount((c) => c + 1);
|
||||
* }
|
||||
*
|
||||
* return <div>
|
||||
* <CountValue count={count} />
|
||||
* <div><button onClick={add}>add</button></div>
|
||||
* </div>;
|
||||
* };
|
||||
*
|
||||
* render(() => <CountingComponent />, document.getElementById("app"));
|
||||
*/
|
||||
|
||||
// 编译后:
|
||||
const $tmpl = /*#__PURE__*/ $$template('<div id="count">Count value is <!>.'),
|
||||
$tmpl_2 = /*#__PURE__*/ $$template('<div><div><button id="btn">add');
|
||||
const CountValue = props => {
|
||||
return (() => {
|
||||
const _el$ = $tmpl(),
|
||||
_el$2 = _el$.firstChild,
|
||||
_el$4 = _el$2.nextSibling;
|
||||
$$insert(_el$, () => props.count, _el$4);
|
||||
return _el$;
|
||||
})();
|
||||
return <div id="count">Count value is {props.count} .</div>;
|
||||
};
|
||||
const CountingComponent = () => {
|
||||
const count = reactive(0);
|
||||
const add = () => {
|
||||
count.set(c => c + 1);
|
||||
};
|
||||
return (() => {
|
||||
const _el$5 = $tmpl_2(),
|
||||
_el$6 = _el$5.firstChild,
|
||||
_el$7 = _el$6.firstChild;
|
||||
$$insert(
|
||||
_el$5,
|
||||
$$runComponent(CountValue, {
|
||||
count: count,
|
||||
}),
|
||||
_el$6
|
||||
);
|
||||
$$on(_el$7, 'click', add, true);
|
||||
return _el$5;
|
||||
})();
|
||||
return (
|
||||
<div>
|
||||
<CountValue count={count} />
|
||||
<div>
|
||||
<button id="btn" onClick={add}>add</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
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 }) => {
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue