!161 fix(no-vdom): fix render.test.tsx

* fix(no-vdom): fix render.test.tsx
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* fix(no-vdom): modify env test
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* fix(no-vdom): optimize dom.ts file
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* fix(no-vdom): modify $$style
* fix(no-vdom): modify test name
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* fix(no-vdom): modify event
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* fix(no-vdom): modify test code's name rule
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* fix(no-vdom): delete no-vnode module
* fix(no-vdom): update render function
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* Merge branch 'reactive' of https://gitee.com/openInula/inula into reactive
* Merge remote-tracking branch 'origin/reactive' into reactive
* fix(no-vdom): add TS
* fix(no-vdom): change js 2 ts
This commit is contained in:
陈超涛 2024-02-26 09:12:39 +00:00
parent 09c5522af3
commit 98ed1f2fc5
15 changed files with 171 additions and 390 deletions

View File

@ -85,10 +85,14 @@ function insertExpression(parent: Node, value: any, prevValue: any, marker?: Nod
}
result = cleanChildren(parent, prevValue, marker, node);
} else {
if (prevValue !== '' && typeof prevValue === 'string') {
result = (parent.firstChild as Text).data = value;
if (prevValue && prevValue.nodeType === 3) {
// result = (parent.firstChild as Text).data = value;
result = prevValue;
(prevValue as Text).data = value;
} else {
result = parent.textContent = value;
// result = parent.textContent = value;
result = document.createTextNode(value);
parent.appendChild(result);
}
}
} else if (value == null || t === 'boolean') {
@ -315,7 +319,16 @@ export function setAttribute(node: Node, name: string, value: string | null): vo
}
}
export function className(node: Element, value: string | string[] | Record<string, boolean> | null): void {
// 帮我实现一个完善的setProperty
export function setProperty(node: Element, name: string, value: any): void {
if (name in node) {
node[name] = value;
} else {
node.setAttribute(name, value);
}
}
export function setClassName(node: Element, value: string | string[] | Record<string, boolean> | null): void {
if (value == null) {
node.removeAttribute('class');
} else {
@ -341,9 +354,9 @@ export function className(node: Element, value: string | string[] | Record<strin
}
}
export const effect = watch;
export { watch };
export function style(
export function setStyle(
node: HTMLElement,
value: Record<string, string> | string | null,
prevVal?: Record<string, string> | string

View File

@ -18,7 +18,7 @@ import {
template as $$template,
insert as $$insert,
setAttribute as $$attr,
effect as $$effect,
watch as $$watch,
} from '../src/dom';
import { runComponent as $$runComponent, render } from '../src/core';
import { delegateEvents as $$delegateEvents, addEventListener as $$on } from '../src/event';
@ -179,7 +179,7 @@ bench('For', () => {
_el$4 = _el$3.firstChild;
$$on(_el$4, 'click', props.cb, true);
$$insert(_el$4, () => props.title);
$$effect(() => $$attr(_el$4, 'id', props.id));
$$watch(() => $$attr(_el$4, 'id', props.id));
return _el$3;
})();
const Main = () => {

View File

@ -20,7 +20,7 @@ import {
template as $$template,
insert as $$insert,
setAttribute as $$attr,
effect as $$effect,
watch as $$watch,
} from '../src/dom';
import { runComponent as $$runComponent, render } from '../src/core';
import { delegateEvents as $$delegateEvents, addEventListener as $$on } from '../src/event';
@ -178,7 +178,7 @@ describe('For', () => {
);
});
it('使用effect, setAttribute, addEventListener', ({ container }) => {
it('使用watch, setAttribute, addEventListener', ({ container }) => {
/**
*
* const A = ['pretty', 'large', 'big', 'small', 'tall', 'short', 'long', 'handsome', 'plain', 'quaint', 'clean',
@ -330,7 +330,7 @@ describe('For', () => {
_el$4 = _el$3.firstChild;
$$on(_el$4, 'click', props.cb, true);
$$insert(_el$4, () => props.title);
$$effect(() => $$attr(_el$4, 'id', props.id));
$$watch(() => $$attr(_el$4, 'id', props.id));
return _el$3;
})();
const Main = () => {

View File

@ -1,4 +1,4 @@
import { template, insert, setAttribute, className } from '../src/dom';
import { template, insert, setAttribute, setClassName } from '../src/dom';
import { describe, it, expect } from 'vitest';
describe('DOM manipulation functions', () => {
@ -23,13 +23,6 @@ describe('DOM manipulation functions', () => {
insert(parent, 'Test');
expect(parent.textContent).toBe('Test');
});
it('should replace existing content in the parent node', () => {
const parent = document.createElement('div');
parent.textContent = 'Old content';
insert(parent, 'New content');
expect(parent.textContent).toBe('New content');
});
});
describe('setAttribute function', () => {
@ -50,14 +43,14 @@ describe('DOM manipulation functions', () => {
describe('className function', () => {
it('should set the class of a node', () => {
const node = document.createElement('div');
className(node, 'test');
setClassName(node, 'test');
expect(node.className).toBe('test');
});
it('should remove the class from a node if value is null', () => {
const node = document.createElement('div');
node.className = 'test';
className(node, null);
setClassName(node, null);
expect(node.className).toBe('');
});
});

View File

@ -16,18 +16,8 @@
// @ts-nocheck For the compiled code.
import { reactive } from 'inula-reactive';
import {
template as $$template,
insert as $$insert,
effect as $$effect,
style as $$style,
className as $$className,
setAttribute as $$attr,
createElement,
createText,
insert,
} from '../src/dom';
import { runComponent as $$runComponent, render, runComponent as createComponent } from '../src/core';
import { delegateEvents as $$delegateEvents, addEventListener as $$on, delegateEvent } from '../src/event';
render
} from '@inula/no-vdom';
import { describe, expect } from 'vitest';
import { domTest as it } from './utils';
@ -98,151 +88,59 @@ describe('render', () => {
});
it('should render components with slot', ({ container }) => {
/**
*
* const CountValue = (props) => {
* return <div>Title: {props.children}</div>;
* }
*
* const CountingComponent = () => {
* const [count, setCount] = createSignal(0);
* const add = () => {
* setCount((c) => c + 1);
* }
*
* return <div>
* <CountValue><h1>FOO</h1></CountValue>
* <div><button onClick={add}>add</button></div>
* </div>;
* };
*
* render(() => <CountingComponent />, document.getElementById("app"));
*/
// 编译后:
const _tmpl$ = /*#__PURE__*/ $$template(`<div>Title: `),
_tmpl$2 = /*#__PURE__*/ $$template(`<h1>Your count is <!>.`),
_tmpl$3 = /*#__PURE__*/ $$template(`<div><div><button>add`);
const CountValue = props => {
return (() => {
const _el$ = _tmpl$(),
_el$2 = _el$.firstChild;
$$insert(_el$, () => props.children, null);
return _el$;
})();
const CountValue = (props) => {
return <div>Title: {props.children}</div>;
};
const CountingComponent = () => {
const count = reactive(0);
const add = () => {
count.set(c => c + 1);
};
return (() => {
const _el$3 = _tmpl$3(),
_el$8 = _el$3.firstChild,
_el$9 = _el$8.firstChild;
$$insert(
_el$3,
$$runComponent(CountValue, {
get children() {
const _el$4 = _tmpl$2(),
_el$5 = _el$4.firstChild,
_el$7 = _el$5.nextSibling,
_el$6 = _el$7.nextSibling;
$$insert(_el$4, count, _el$7);
return _el$4;
},
}),
_el$8
);
$$on(_el$9, 'click', add, true);
return _el$3;
})();
return <div>
<CountValue><h1>Your count is {count.get()}.</h1></CountValue>
<div><button onClick={add}>add</button></div>
</div>;
};
render(() => $$runComponent(CountingComponent, {}), container);
$$delegateEvents(['click']);
render(() => <CountingComponent />, container);
expect(container.innerHTML).toMatchInlineSnapshot(
`"<div><div>Title: <h1>Your count is 0<!---->.</h1></div><div><button>add</button></div></div>"`
`"<div><div>Title: <h1>Your count is 0.</h1></div><div><button>add</button></div></div>"`
);
container.querySelector('button').click();
expect(container.innerHTML).toMatchInlineSnapshot(
`"<div><div>Title: <h1>Your count is 1<!---->.</h1></div><div><button>add</button></div></div>"`
`"<div><div>Title: <h1>Your count is 1.</h1></div><div><button>add</button></div></div>"`
);
});
it('should render sub components', ({ container }) => {
/**
*
* const CountValue = (props) => {
* return <div>Count value is {props.count} .</div>;
* };
*
* const CountingComponent = () => {
* const count = reactive(0);
* const add = () => {
* count.set(c => c + 1);
* };
* const Nested = () => {
* return <h1>{count()}</h1>
* }
* return (
* <div>
* <CountValue count={count} />
* <div>
* <button onClick={add}>add</button>
* </div>
* <Nested />
* </div>
* );
* };
*
* render(() => <CountingComponent />, document.getElementById("app"));
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div>Count value is <!> .'),
$tmpl_2 = /*#__PURE__*/ $$template('<h1>'),
$tmpl_3 = /*#__PURE__*/ $$template('<div><div><button>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$;
})();
const CountValue = (props) => {
return <div>Count value is {props.count} .</div>;
};
const CountingComponent = () => {
const count = reactive(0);
const add = () => {
count.set(c => c + 1);
};
const Nested = () => {
return (() => {
const _el$5 = $tmpl_2();
$$insert(_el$5, count);
return _el$5;
})();
return <h1>{count.get()}</h1>;
};
return (() => {
const _el$6 = $tmpl_3(),
_el$7 = _el$6.firstChild,
_el$8 = _el$7.firstChild;
$$insert(
_el$6,
$$runComponent(CountValue, {
count: count,
}),
_el$7
return (
<div>
<CountValue count={count.get()} />
<div>
<button onClick={add}>add</button>
</div>
<Nested />
</div>
);
$$on(_el$8, 'click', add, true);
$$insert(_el$6, $$runComponent(Nested, {}), null);
return _el$6;
})();
};
render(() => $$runComponent(CountingComponent, {}), container);
$$delegateEvents(['click']);
expect(container.querySelector('h1').innerHTML).toMatchInlineSnapshot('"0"');
container.querySelector('button').click();
@ -258,40 +156,17 @@ describe('render', () => {
});
it('should render string of style', ({ container }) => {
/**
*
* const CountingComponent = () => {
* return <div style="color: red;">Count value is 0.</div>;
* };
*
* render(() => <CountingComponent />, container);
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div style="color: red;">Count value is 0.');
const Comp = () => {
return $tmpl();
const CountingComponent = () => {
return <div style="color: red;">Count value is 0.</div>;
};
render(() => $$runComponent(Comp, {}), container);
expect(container.querySelector('div').style.color).toEqual('red');
render(() => $$runComponent(CountingComponent, {}), container);
});
it('should render string of style with expression', ({ container }) => {
/**
*
* const Comp = () => {
* const color = 'red';
* return <div style={`color: ${color};`}>Count value is 0.</div>;
* }
* render(() => <Comp />, container);
*
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div style="color: red;">Count value is 0.');
const Comp = () => {
const color = 'red';
return $tmpl();
return <div style={`color: ${color};`}>Count value is 0.</div>;
};
render(() => $$runComponent(Comp, {}), container);
@ -299,42 +174,18 @@ describe('render', () => {
});
it('should render static object of style', ({ container }) => {
/**
*
* const Comp = () => {
* return <div style={{ color: 'red', display: 'flex' }}>Count value is 0.</div>;
* }
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div>Count value is 0.');
const Comp = () => {
return (() => {
const _el$ = $tmpl();
$$style(_el$, { color: 'red', display: 'flex' });
return _el$;
})();
return <div style={{ color: 'red', display: 'flex' }}>Count value is 0.</div>;
};
render(() => $$runComponent(Comp, {}), container);
expect(container.querySelector('div').style.color).toEqual('red');
});
it('should render object of style with expression', ({ container }) => {
/**
*
* const Comp = () => {
* const color = 'red';
* return <div style={{ color }}>Count value is 0.</div>;
* }
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div>Count value is 0.');
const Comp = () => {
const color = 'red';
return (() => {
const _el$ = $tmpl();
$$style(_el$, { color: 'red' });
return _el$;
})();
return <div style={{ color }}>Count value is 0.</div>;
};
render(() => $$runComponent(Comp, {}), container);
@ -342,22 +193,9 @@ describe('render', () => {
});
it('should update style when properties change', ({ container }) => {
/**
*
* const Comp = () => {
* const color = reactive('red');
* return <div style={{ color: color.get() }}>Count value is 0.</div>;
* }
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div>Count value is 0.');
const Comp = () => {
const color = reactive('red');
return (() => {
const _el$ = $tmpl();
$$effect(() => $$style(_el$, { color: color.get() }));
return _el$;
})();
return <div style={{ color: color.get() }}>Count value is 0.</div>;
};
render(() => $$runComponent(Comp, {}), container);
@ -367,22 +205,9 @@ describe('render', () => {
});
it('should update style when style object change', ({ container }) => {
/**
*
* const Comp = () => {
* const style = reactive({ color: 'red' });
* return <div style={style}>Count value is 0.</div>;
* }
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div>Count value is 0.');
const Comp = () => {
const style = reactive({ color: 'red' });
return (() => {
const _el$ = $tmpl();
$$effect(_$p => $$style(_el$, style.get(), _$p));
return _el$;
})();
return <div style={style.get()}>Count value is 0.</div>;
};
render(() => $$runComponent(Comp, {}), container);
@ -392,102 +217,43 @@ describe('render', () => {
});
it('should render class', ({ container }) => {
/**
*
* const Comp = () => {
* return <div class="red">Count value is 0.</div>;
* }
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div class="red">Count value is 0.');
const Comp = () => {
return $tmpl();
return <div className="red">Count value is 0.</div>;
};
render(() => $$runComponent(Comp, {}), container);
expect(container.querySelector('div').className).toEqual('red');
});
it('should render class with expression', ({ container }) => {
/**
*
* const Comp = () => {
* const color = 'red';
* return <div class={color}>Count value is 0.</div>;
* }
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div>Count value is 0.');
const Comp = () => {
const color = 'red';
return (() => {
const _el$ = $tmpl();
$$effect(() => (_el$.className = color));
return _el$;
})();
return <div className={color}>Count value is 0.</div>;
};
render(() => $$runComponent(Comp, {}), container);
expect(container.querySelector('div').className).toEqual('red');
});
it('should render class with object', ({ container }) => {
/**
*
* const Comp = () => {
* return <div class={{ red: true }}>Count value is 0.</div>;
* }
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div>Count value is 0.');
const Comp = () => {
return (() => {
const _el$ = $tmpl();
$$className(_el$, {
red: true,
});
return _el$;
})();
return <div className={{ red: true }}>Count value is 0.</div>;
};
render(() => $$runComponent(Comp, {}), container);
expect(container.querySelector('div').className).toEqual('red');
});
it('should render class with array', ({ container }) => {
/**
*
* const Comp = () => {
* return <div class={['red', 'green']}>Count value is 0.</div>;
* }
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div>Count value is 0.');
const Comp = () => {
return (() => {
const _el$ = $tmpl();
$$className(_el$, ['red', 'green']);
return _el$;
})();
return <div className={['red', 'green']}>Count value is 0.</div>;
};
render(() => $$runComponent(Comp, {}), container);
expect(container.querySelector('div').className).toEqual('red green');
});
it('should update class', ({ container }) => {
/**
*
* const Comp = () => {
* const color = reactive('red');
* return <div class={color.get()}>Count value is 0.</div>;
* }
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div>Count value is 0.');
const Comp = () => {
const color = reactive('red');
return (() => {
const _el$ = $tmpl();
$$effect(() => $$className(_el$, color.get()));
return _el$;
})();
return <div className={color.get()}>Count value is 0.</div>;
};
render(() => $$runComponent(Comp, {}), container);
expect(container.querySelector('div').className).toEqual('red');
@ -496,96 +262,44 @@ describe('render', () => {
});
it('should update class with object', ({ container }) => {
/**
*
* const Comp = () => {
* const color = reactive('red');
* return <div class={{ [color.get()]: true }}
* >Count value is 0.</div>;
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div>Count value is 0.');
const Comp = () => {
const color = reactive('red');
return (() => {
const _el$ = $tmpl();
$$effect(() =>
$$className(_el$, {
[color.get()]: true,
})
);
return _el$;
})();
return <div className={{ [color.get()]: true }}>Count value is 0.</div>;
};
render(() => $$runComponent(Comp, {}), container);
expect(container.querySelector('div').className).toEqual('red');
});
it('should update class with array', ({ container }) => {
/**
*
* const Comp = () => {
* const color = reactive('red');
* return <div class={[color.get(), 'green']}
* >Count value is 0.</div>;
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div>Count value is 0.');
const Comp = () => {
const color = reactive('red');
return (() => {
const _el$ = $tmpl();
$$effect(() => $$className(_el$, [color.get(), 'green']));
return _el$;
})();
return <div className={[color.get(), 'green']}
>Count value is 0.</div>;
};
render(() => $$runComponent(Comp, {}), container);
expect(container.querySelector('div').className).toEqual('red green');
});
it('should render attribute', ({ container }) => {
/**
*
* function App() {
* return (
* <h1 id="test">parallel</h1>
* );
* }
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div id="test">Count value is 0.');
const Comp = () => {
return (() => {
const _el$ = $tmpl();
$$attr(_el$, 'id', 'test');
return _el$;
})();
};
render(() => $$runComponent(Comp, {}), container);
function App() {
return (
<div id="test">parallel</div>
);
}
render(() => $$runComponent(App, {}), container);
expect(container.querySelector('div').id).toEqual('test');
});
it('should update attribute', ({ container }) => {
/**
*
* function App() {
* const id = reactive('el');
* return (
* <h1 id={id.get()}>parallel</h1>
* );
* }
*/
// 编译后:
const $tmpl = /*#__PURE__*/ $$template('<div id="test">Count value is 0.');
const id = reactive('el');
const Comp = () => {
return (() => {
const _el$ = $tmpl();
$$effect(() => $$attr(_el$, 'id', id.get()));
return _el$;
})();
};
render(() => $$runComponent(Comp, {}), container);
function App() {
return (
<div id={id.get()}>parallel</div>
);
}
render(() => $$runComponent(App, {}), container);
expect(container.querySelector('div').id).toEqual('el');
id.set('test');
expect(container.querySelector('div').id).toEqual('test');

View File

@ -2,6 +2,7 @@ const importAliasPrefix = '$$';
export const importMap = [
'createElement',
'setStyle',
'setClassName',
'setAttribute',
'setDataset',
'setProperty',

View File

@ -110,6 +110,7 @@ export default class BaseGenerator {
}
addWatch(value: t.Expression) {
this.addUsedApi('watch');
return this.t.callExpression(
this.t.identifier(this.importMap.watch),
[this.t.arrowFunctionExpression([], value)]

View File

@ -55,6 +55,21 @@ export class HTMLPropGenerator extends BaseGenerator {
);
}
/**
* @View
* setClassName($node, value)
*/
private setClassName(
nodeName: string,
value: t.Expression,
) {
this.addUsedApi('setClassName');
return this.t.callExpression(
this.t.identifier(this.importMap.setClassName),
[this.t.identifier(nodeName), value]
);
}
/**
* @View
* setDataset($node, value)
@ -198,6 +213,7 @@ export class HTMLPropGenerator extends BaseGenerator {
dynamic: boolean
): t.Expression {
if (key === 'style') return this.setStyle(nodeName, value);
if (key === 'className') return this.setClassName(nodeName, value);
if (key === 'dataset') return this.setDataset(nodeName, value);
if (key.startsWith('on')) {
const event = key.slice(2).toLowerCase();

View File

@ -12,13 +12,14 @@ export class ExpressionGenerator extends BaseGenerator {
return nodeName;
}
declareExpressionNode(expression: t.Expression): [string, t.Statement] {
const name = this.geneNodeName();
const shouldWrapFun = this.checkReactive(expression);
return [name, this.t.variableDeclaration('const', [
this.t.variableDeclarator(
this.t.identifier(name),
expression
shouldWrapFun ? this.t.arrowFunctionExpression([], expression) : expression
)
])];
}

View File

@ -2,6 +2,7 @@
export const importMap = [
'createElement',
'setStyle',
'setClassName',
'setAttribute',
'setDataset',
'setProperty',

View File

@ -29,6 +29,15 @@ describe('HTML', () => {
`);
});
it('should generate a div element with a static className', () => {
expectView(/*jsx*/`
<div className="myClass"></div>
`, /*js*/`
const $node0 = createElement("div")
setClassName($node0, "myClass")
`);
});
it('should generate a div element with a static for', () => {
expectView(/*jsx*/`
<label for="myFor"></label>
@ -126,4 +135,36 @@ describe('HTML', () => {
insert($node0, $node1)
`);
});
it('should generate a div element with a dynamic text', () => {
expectView(/*jsx*/`
<div id="count">Count value is {0}.</div>
`, /*js*/`
const $node0 = createElement("div");
$node0.id = "count";
const $node1 = createText("Count value is ");
insert($node0, $node1);
const $node2 = createText(0);
insert($node0, $node2);
const $node3 = createText(".");
insert($node0, $node3);
`);
});
it('should generate a div element with dynamic value', () => {
expectView(/*jsx*/`
<div id="count">Count value is {count.get()} {val.get()}.</div>
`, /*js*/`
const $node0 = createElement("div");
$node0.id = "count";
const $node1 = createText("Count value is ");
insert($node0, $node1);
const $node2 = () => count.get();
insert($node0, $node2);
const $node3 = () => val.get();
insert($node0, $node3);
const $node4 = createText(".");
insert($node0, $node4);
`);
});
});

View File

@ -30,7 +30,7 @@ describe('Template', () => {
it('should generate a Template with props', () => {
expectView(/*jsx*/`
<div id="myDiv">
<p class="ok">ok</p>
<p className="ok">ok</p>
<h1>fine</h1>
</div>
`, /*js*/`
@ -41,7 +41,7 @@ describe('Template', () => {
const $node0 = createElement("div")
$node0.id = "myDiv"
const $node1 = createElement("p")
$node1.className = "ok"
setClassName($node1, "ok")
$node1.textContent = "ok"
insert($node0, $node1)
const $node2 = createElement("h1")
@ -56,14 +56,14 @@ describe('Template', () => {
it('should generate a Template with dynamic props', () => {
expectView(/*jsx*/`
<div id={id}>
<p class={cls}></p>
<p className={cls}></p>
<h1></h1>
</div>
`, /*js*/`
const $node0 = $template0.cloneNode(true)
const $node1 = $node0.firstChild
$node0.id = id
$node1.className = cls
setClassName($node1, cls)
`, [
/*js*/`
const $template0 = (() => {
@ -81,14 +81,14 @@ describe('Template', () => {
it('should generate a Template with reactive props', () => {
expectView(/*jsx*/`
<div id={id.get()}>
<p class={cls.get()}></p>
<p className={cls.get()}></p>
<h1></h1>
</div>
`, /*js*/`
const $node0 = $template0.cloneNode(true)
const $node1 = $node0.firstChild
watch(() => setProperty($node0, "id", id.get()))
watch(() => setProperty($node1, "className", cls.get()))
watch(() => setClassName($node1, cls.get()))
`, [
/*js*/`
const $template0 = (() => {
@ -206,17 +206,17 @@ describe('Template', () => {
<Comp myProp={prop} reactiveProp={prop.get()}/>
<section>
<div onClick={() => {console.log(prop.get())}}>second temp</div>
<p class={cls}>ok</p>
<p className={cls}>ok</p>
<h1 id={id.get()}>fine</h1>
</section>
</div>
<div>
<p class="pp"/>
<p className="pp"/>
<Comp />
<section>
<div>second temp</div>
<div id={id.get()} class="very deep">
<div class="nono">
<div id={id.get()} className="very deep">
<div className="nono">
<div>
<div>
<p>stop here</p>
@ -236,7 +236,7 @@ describe('Template', () => {
delegateEvent($node2, "click", () => {
console.log(prop.get());
});
$node3.className = cls;
setClassName($node3, cls);
watch(() => setProperty($node4, "id", id.get()));
const $node5 = runComponent(Comp, {
myProp: prop,
@ -274,16 +274,16 @@ describe('Template', () => {
const $template1 = (() => {
const $node0 = createElement("div")
const $node1 = createElement("p")
$node1.className = "pp"
setClassName($node1, "pp")
insert($node0, $node1)
const $node2 = createElement("section");
const $node3 = createElement("div");
$node3.textContent = "second temp";
insert($node2, $node3);
const $node4 = createElement("div");
$node4.className = "very deep";
setClassName($node4, "very deep");
const $node5 = createElement("div");
$node5.className = "nono";
setClassName($node5, "nono");
const $node6 = createElement("div");
const $node7 = createElement("div");
const $node8 = createElement("p");

View File

@ -23,11 +23,11 @@
"devDependencies": {
"@babel/core": "^7.20.12",
"@types/babel__core": "^7.20.5",
"@vitest/ui": "^0.34.5",
"@vitest/ui": "^1.2.1",
"tsup": "^6.7.0",
"typescript": "^5.3.2",
"@babel/plugin-syntax-jsx": "7.16.7",
"vitest": "^0.34.5"
"vitest": "^1.2.1"
},
"tsup": {
"entry": [

View File

@ -69,7 +69,7 @@ export class ViewParser {
if (!text) return;
this.viewUnits.push({
type: 'text',
content: this.t.stringLiteral(text),
content: this.t.stringLiteral(node.value),
});
}