Compare commits

..

20 Commits

Author SHA1 Message Date
Géry Debongnie 55dbc01a1b [REL] v2.0.0-beta-4
# v2.0.0-beta.4

- fix: useEffect properly handle errors in effect function
- imp: reactivity: add missing support for forEach method
- imp: component: add name property on nodes for debug purposes
- imp: component: emit warning when async hooks take too long
- fix: blockdom: t-att- correcltly sets the value to zero
- fix: reactivity: do not crash when reading reactive frozen objects
- fix: utils: fix calls to batched callback from within the callback
- imp: component: wait for parent rendering to be complete before rendering child
2022-03-29 15:49:50 +02:00
Géry Debongnie e3b1566943 [IMP] component: wait for parent rendering to be complete before doing child
This is a breaking semantic change.  With this commit, the UI is frozen
whenever owl is waiting for a parent to change

Also, this allows Owl not to render components that will be removed
later.
2022-03-29 15:45:27 +02:00
Géry Debongnie 828be28653 [REF] component: introduce RootFiber.setCounter and update scheduler
The goal is to be able to execute code whenever a root fiber is ready,
and before the next animation frame
2022-03-29 15:45:27 +02:00
Samuel Degueldre d80fad760c [FIX] utils: fix calls to batched callback from within the callback
Previously, calling the batched function from within the callback being
batched would fail as it would be treated as part of the same batch.
This commit fixes that by scheduling the reset of the "called" flag
before calling the callback. This means that all microtasks that were
already in the microtask queue when a batch is about to run are treated
as part of the batch, and all microtasks that will be added by the
callback are not.
2022-03-29 09:13:00 +02:00
Samuel Degueldre 7611ea6033 [FIX] reactivity: do not crash when reading reactive frozen objects
This crash was caused by the fact that Proxies *must* return the value of the
property on the target when that property is non-writeable and
non-configurable. Since the reactivity system always attempts to proxify the
value from the target, this crashes.

This commit fixes that by not proxifying such values. This however means that
from that point on, we have escaped the reactivity system and will not
subscribe to any changes in that object or its children.
2022-03-28 13:15:00 +02:00
NsL01 c7d515a6b3 [FIX] doc: fix minor errors in todo app tutorial 2022-03-25 10:34:00 +01:00
Samuel Degueldre d277039b14 [FIX] blockdom: t-att- correcltly sets the value to zero
In 3536f41f00 we added a fallback when setting a
property to a falsy value so that the property was set to the empty string. The
objective being to not get the string "undefined"/"null"/"false" as property
value. However, using t-att- to set a property to 0 is perfectly reasonable and
in fact quite common.
2022-03-18 14:24:54 +01:00
Samuel Degueldre 77ff5ee895 [IMP] component: emit warning when async hooks take too long
This commit adds a warning when an async hook
(onWillUpdateProps/onWillStart) takes longer than 3 seconds, as these
hooks block the rendering and patching of the application, it is rarely
desirable and often a sign of a deadlock. This warning will contain the
stack trace of the call to the hook to help in debugging.
2022-03-14 09:51:47 +01:00
Géry Debongnie 47c6d6cc3c [IMP] component: add name property on nodes for debug purposes
also, improves the implementation of subscriptions
2022-03-11 15:14:55 +01:00
Samuel Degueldre 0625b5883a [IMP] reactivity: add missing support for forEach method 2022-03-11 14:02:42 +01:00
Géry Debongnie 53ab54b1ec [FIX] useEffect: properly handle errors in effect function
Before this commit, if the effect function would throw, then the cleanup
function would not be properly assigned, which caused additional errors
later, when the cleanup code would try to call it.

closes #1149
2022-03-08 15:23:49 +01:00
Samuel Degueldre 4770b91faa [IMP] doc: document dev mode 2022-03-08 14:45:44 +01:00
Samuel Degueldre c356351de2 [REL] v2.0.0-beta.3
# 2.0.0-beta.3

- improve error message for tokenization errors
- fix a bug where errors during rendering were incorrectly reported
- add support for t-on on components and slots (t-slot and t-set-slot)
2022-03-08 12:47:36 +01:00
Géry Debongnie f04423da23 [FIX] playground: properly set dev flag in examples 2022-03-08 12:24:57 +01:00
Géry Debongnie b3062d29f1 [REF] parser: make AST definition more consistent 2022-03-08 12:24:57 +01:00
Géry Debongnie 56086242bb [IMP] compiler: add support for t-on- on t-slots and t-set-slots 2022-03-08 12:24:57 +01:00
Géry Debongnie 998ecbb337 [REF] compiler: introduce define helper, slightly refactor code 2022-03-08 12:24:57 +01:00
Géry Debongnie 50355e6a3d [IMP] component: add support for t-on on compnents 2022-03-08 12:24:57 +01:00
Samuel Degueldre 67f86a4ab8 [FIX] components: wrap onWillRender/onRendered hooks instead of renderFn
Previously, we were wrapping the entire renderFn in a try/catch, causing
errors during template execution to be caught and wrapped by
onWillRender/onRendered which is undesirable. Now we only wrap the hook
that's being registered.
2022-03-08 10:18:15 +01:00
Samuel Degueldre 14d2328c88 [IMP] compiler: improve error message for tokenization errors 2022-03-08 10:18:15 +01:00
78 changed files with 2955 additions and 1343 deletions
-36
View File
@@ -44,7 +44,6 @@ All changes are documented here in no particular order.
- breaking: style/class on components are now regular props ([details](#10-styleclass-on-components-are-now-regular-props)) - breaking: style/class on components are now regular props ([details](#10-styleclass-on-components-are-now-regular-props))
- new: components can use the `.bind` suffix to bind function props ([doc](doc/reference/props.md#binding-function-props)) - new: components can use the `.bind` suffix to bind function props ([doc](doc/reference/props.md#binding-function-props))
- breaking: `t-on` does not accept expressions, only functions ([details](#30-t-on-does-not-accept-expressions-only-functions)) - breaking: `t-on` does not accept expressions, only functions ([details](#30-t-on-does-not-accept-expressions-only-functions))
- breaking: `t-on` does not work on components any more ([details](#12-t-on-does-not-work-on-components-any-more))
- new: an error is thrown if an handler defined in a `t-on-` directive is not a function (failed silently previously in some cases) - new: an error is thrown if an handler defined in a `t-on-` directive is not a function (failed silently previously in some cases)
- breaking: `t-component` no longer accepts strings ([details](#17-t-component-no-longer-accepts-strings)) - breaking: `t-component` no longer accepts strings ([details](#17-t-component-no-longer-accepts-strings))
- new: the `this` variable in template expressions is now bound to the component - new: the `this` variable in template expressions is now bound to the component
@@ -313,41 +312,6 @@ Documentation:
- [Mounting a component](doc/reference/app.md#mount-helper) - [Mounting a component](doc/reference/app.md#mount-helper)
### 12. `t-on` does not work on components any more
In owl 1, it was possible to bind an event listener on a component tag in a
template:
```xml
<SomeComponent t-on-some-event="doSomething"/>
```
This does not work any more.
Rationale: with the support of fragments, there is no longer a canonical html
element that we can refer. So, this makes it difficult to implement correctly
and efficiently. Also, we noticed in practice that the event system was an issue
in some cases, when components need to communicate before they are mounted. In
those cases, the better solution is to directly use a callback. Also, another
conceptual issue with this is that it kind of breaks the component encapsulation.
The child component kind of leak its own implementation to the outside world.
Migration: a quick fix that may work in some cases is to simply bind the event
handler on a parent htmlelement. A better way to do it, if possible, is to change
the component API to accept explicitely a callback as props.
```xml
<SomeComponent onSomeEvent="doSomething"/>
<!-- or alternatively: -->
<SomeComponent onSomeEvent.bind="doSomething"/>
```
Note that one of the example above uses the `.bind` suffix, to bind the function
prop to the component. Most of the time, binding the function is necessary, and
using the `.bind` suffix is very helpful in that case.
Documentation: [Binding function props](doc/reference/props.md#binding-function-props)
### 13. Portal does no longer transfer DOM events ### 13. Portal does no longer transfer DOM events
In Owl 1, a Portal component would listen to events emitted on its portalled In Owl 1, a Portal component would listen to events emitted on its portalled
+1
View File
@@ -82,6 +82,7 @@ Are you new to Owl? This is the place to start!
- [Component](doc/reference/component.md) - [Component](doc/reference/component.md)
- [Component Lifecycle](doc/reference/component.md#lifecycle) - [Component Lifecycle](doc/reference/component.md#lifecycle)
- [Concurrency Model](doc/reference/concurrency_model.md) - [Concurrency Model](doc/reference/concurrency_model.md)
- [Dev mode](doc/reference/app.md#dev-mode)
- [Dynamic sub components](doc/reference/component.md#dynamic-sub-components) - [Dynamic sub components](doc/reference/component.md#dynamic-sub-components)
- [Environment](doc/reference/environment.md) - [Environment](doc/reference/environment.md)
- [Error Handling](doc/reference/error_handling.md) - [Error Handling](doc/reference/error_handling.md)
+2 -2
View File
@@ -240,7 +240,7 @@ class Task extends Component {
static template = xml /* xml */` static template = xml /* xml */`
<div class="task" t-att-class="props.task.isCompleted ? 'done' : ''"> <div class="task" t-att-class="props.task.isCompleted ? 'done' : ''">
<input type="checkbox" t-att-checked="props.task.isCompleted"/> <input type="checkbox" t-att-checked="props.task.isCompleted"/>
<span><t t-esc="props.task.title"/></span> <span><t t-esc="props.task.text"/></span>
</div>`; </div>`;
static props = ["task"]; static props = ["task"];
} }
@@ -743,7 +743,7 @@ the user experience.
```xml ```xml
<input type="checkbox" t-att-checked="props.task.isCompleted" <input type="checkbox" t-att-checked="props.task.isCompleted"
t-att-id="props.task.id" t-att-id="props.task.id"
t-on-click="dispatch('toggleTask', props.task.id)"/> t-on-click="() => store.toggleTask(props.task)"/>
<label t-att-for="props.task.id"><t t-esc="props.task.text"/></label> <label t-att-for="props.task.id"><t t-esc="props.task.text"/></label>
``` ```
+13 -4
View File
@@ -51,11 +51,10 @@ The `config` object is an object with some of the following keys:
- **`env (object)`**: if given, this will be the shared `env` given to each component - **`env (object)`**: if given, this will be the shared `env` given to each component
- **`props (object)`**: the props given to the root component - **`props (object)`**: the props given to the root component
- **`dev (boolean, default=false)`**: if `true`, the application is rendered in `dev` - **`dev (boolean, default=false)`**: if `true`, the application is rendered in
mode, which activates some additional checks (in particular, the props validation [`dev` mode](#dev-mode);
code is only performed in dev mode)
- **`test (boolean, default=false)`**: `test` mode is the same as `dev` mode, except - **`test (boolean, default=false)`**: `test` mode is the same as `dev` mode, except
that Owll will not log a message to warn that Owl is in `dev` mode. that Owl will not log a message to warn that Owl is in `dev` mode.
- **`translatableAttributes (string[])`**: a list of additional attributes that should - **`translatableAttributes (string[])`**: a list of additional attributes that should
be translated (see [translations](translations.md)) be translated (see [translations](translations.md))
- **`translateFn (function)`**: a function that will be called by owl to translate - **`translateFn (function)`**: a function that will be called by owl to translate
@@ -110,3 +109,13 @@ const { loadFile, mount } = owl;
mount(Root, document.body, { env }); mount(Root, document.body, { env });
})(); })();
``` ```
## Dev mode
Dev mode activates some additional checks and developer amenities:
- [Props validation](./props.md#props-validation) is performed
- [t-foreach](./templates.md#loops) loops check for key unicity
- Lifecycle hooks are wrapped to report their errors in a more developer-friendly way
- onWillStart and onWillUpdateProps will emit a warning in the console when they
take longer than 3 seconds in an effort to ease debugging the presence of deadlocks
+17
View File
@@ -5,6 +5,7 @@
- [Event Handling](#event-handling) - [Event Handling](#event-handling)
- [Modifiers](#modifiers) - [Modifiers](#modifiers)
- [Synthetic Events](#synthetic-events) - [Synthetic Events](#synthetic-events)
- [On Components](#on-components)
## Event Handling ## Event Handling
@@ -100,3 +101,19 @@ To enable it, one can just use the `.synthetic` suffix:
</t> </t>
</div> </div>
``` ```
## On Components
The `t-on` directive also works on a child component:
```xml
<div>
in some template
<Child t-on-click="dosomething"/>
</div>
```
This will catch all click events on any html element contained in the `Child`
sub component. Note that if the child component is reduced to one (or more) text
nodes, then clicking on it will not call the handler, since the event will be
dispatched by the browser on the parent element (a `div` in this case).
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@odoo/owl", "name": "@odoo/owl",
"version": "2.0.0-beta.2", "version": "2.0.0-beta-4",
"description": "Odoo Web Library (OWL)", "description": "Odoo Web Library (OWL)",
"main": "dist/owl.cjs.js", "main": "dist/owl.cjs.js",
"browser": "dist/owl.iife.js", "browser": "dist/owl.iife.js",
+1
View File
@@ -101,6 +101,7 @@ export class App<
destroy() { destroy() {
if (this.root) { if (this.root) {
this.scheduler.flush();
this.root.destroy(); this.root.destroy();
} }
} }
+3 -2
View File
@@ -1,4 +1,4 @@
import { BDom, multi, text, toggler } from "../blockdom"; import { BDom, multi, text, toggler, createCatcher } from "../blockdom";
import { validateProps } from "../component/props_validation"; import { validateProps } from "../component/props_validation";
import { Markup } from "../utils"; import { Markup } from "../utils";
import { html } from "../blockdom/index"; import { html } from "../blockdom/index";
@@ -27,7 +27,7 @@ function callSlot(
const { __render, __ctx, __scope } = slots[name] || {}; const { __render, __ctx, __scope } = slots[name] || {};
const slotScope = Object.create(__ctx || {}); const slotScope = Object.create(__ctx || {});
if (__scope) { if (__scope) {
slotScope[__scope] = extra || {}; slotScope[__scope] = extra;
} }
const slotBDom = __render ? __render.call(__ctx.__owl__.component, slotScope, parent, key) : null; const slotBDom = __render ? __render.call(__ctx.__owl__.component, slotScope, parent, key) : null;
if (defaultContent) { if (defaultContent) {
@@ -199,4 +199,5 @@ export const helpers = {
LazyValue, LazyValue,
safeOutput, safeOutput,
bind, bind,
createCatcher,
}; };
+2 -1
View File
@@ -139,7 +139,8 @@ export function updateClass(this: HTMLElement, val: any, oldVal: any) {
export function makePropSetter(name: string): Setter<HTMLElement> { export function makePropSetter(name: string): Setter<HTMLElement> {
return function setProp(this: HTMLElement, value: any) { return function setProp(this: HTMLElement, value: any) {
(this as any)[name] = value || ""; // support 0, fallback to empty string for other falsy values
(this as any)[name] = value === 0 ? 0 : value || "";
}; };
} }
+89
View File
@@ -0,0 +1,89 @@
import { createEventHandler } from "./events";
import type { VNode } from "./index";
type EventsSpec = { [name: string]: number };
type Catcher = (child: VNode, handlers: any[]) => VNode;
export function createCatcher(eventsSpec: EventsSpec): Catcher {
let setupFns: any[] = [];
let removeFns: any[] = [];
for (let name in eventsSpec) {
let index = eventsSpec[name];
let { setup, remove } = createEventHandler(name);
setupFns[index] = setup;
removeFns[index] = remove;
}
let n = setupFns.length;
class VCatcher {
child: VNode;
handlers: any[];
parentEl?: HTMLElement | undefined;
afterNode: Node | null = null;
constructor(child: VNode, handlers: any[]) {
this.child = child;
this.handlers = handlers;
}
mount(parent: HTMLElement, afterNode: Node | null) {
this.parentEl = parent;
this.afterNode = afterNode;
this.child.mount(parent, afterNode);
for (let i = 0; i < n; i++) {
let origFn = this.handlers[i][0];
const self = this;
this.handlers[i][0] = function (ev: any) {
const target = ev.target;
let currentNode: any = self.child.firstNode();
const afterNode = self.afterNode;
while (currentNode !== afterNode) {
if (currentNode.contains(target)) {
return origFn.call(this, ev);
}
currentNode = currentNode.nextSibling;
}
};
setupFns[i].call(parent, this.handlers[i]);
}
}
moveBefore(other: VCatcher | null, afterNode: Node | null) {
this.afterNode = null;
this.child.moveBefore(other ? other.child : null, afterNode);
}
patch(other: VCatcher, withBeforeRemove: boolean) {
if (this === other) {
return;
}
this.handlers = other.handlers;
this.child.patch(other.child, withBeforeRemove);
}
beforeRemove() {
this.child.beforeRemove();
}
remove() {
for (let i = 0; i < n; i++) {
removeFns[i].call(this.parentEl!);
}
this.child.remove();
}
firstNode(): Node | undefined {
return this.child.firstNode();
}
toString(): string {
return this.child.toString();
}
}
return function (child: VNode, handlers: any[]): VNode<VCatcher> {
return new VCatcher(child, handlers);
};
}
+12 -2
View File
@@ -5,6 +5,7 @@ type EventHandlerSetter = (this: HTMLElement, data: any) => void;
interface EventHandlerCreator { interface EventHandlerCreator {
setup: EventHandlerSetter; setup: EventHandlerSetter;
update: EventHandlerSetter; update: EventHandlerSetter;
remove: (this: HTMLElement) => void;
} }
export function createEventHandler(rawEvent: string): EventHandlerCreator { export function createEventHandler(rawEvent: string): EventHandlerCreator {
@@ -38,11 +39,15 @@ function createElementHandler(evName: string, capture: boolean = false): EventHa
this.addEventListener(evName, listener, { capture }); this.addEventListener(evName, listener, { capture });
} }
function remove(this: HTMLElement) {
delete (this as any)[eventKey];
this.removeEventListener(evName, listener, { capture });
}
function update(this: HTMLElement, data: any) { function update(this: HTMLElement, data: any) {
(this as any)[eventKey] = data; (this as any)[eventKey] = data;
} }
return { setup, update }; return { setup, update, remove };
} }
// Synthetic handler: a form of event delegation that allows placing only one // Synthetic handler: a form of event delegation that allows placing only one
@@ -60,7 +65,12 @@ function createSyntheticHandler(evName: string, capture: boolean = false): Event
_data[currentId] = data; _data[currentId] = data;
(this as any)[eventKey] = _data; (this as any)[eventKey] = _data;
} }
return { setup, update: setup };
function remove(this: HTMLElement) {
delete (this as any)[eventKey];
}
return { setup, update: setup, remove };
} }
function nativeToSyntheticEvent(eventKey: string, event: Event) { function nativeToSyntheticEvent(eventKey: string, event: Event) {
+1
View File
@@ -6,6 +6,7 @@ export { list } from "./list";
export { multi } from "./multi"; export { multi } from "./multi";
export { text, comment } from "./text"; export { text, comment } from "./text";
export { html } from "./html"; export { html } from "./html";
export { createCatcher } from "./event_catcher";
export interface VNode<T = any> { export interface VNode<T = any> {
mount(parent: HTMLElement, afterNode: Node | null): void; mount(parent: HTMLElement, afterNode: Node | null): void;
+81 -48
View File
@@ -20,6 +20,8 @@ import {
ASTTranslation, ASTTranslation,
ASTType, ASTType,
ASTTPortal, ASTTPortal,
EventHandlers,
Attrs,
} from "./parser"; } from "./parser";
type BlockType = "block" | "text" | "multi" | "list" | "html" | "comment"; type BlockType = "block" | "text" | "multi" | "list" | "html" | "comment";
@@ -157,9 +159,11 @@ class CodeTarget {
// maps ref name to [id, expr] // maps ref name to [id, expr]
refInfo: { [name: string]: [string, string] } = {}; refInfo: { [name: string]: [string, string] } = {};
shouldProtectScope: boolean = false; shouldProtectScope: boolean = false;
on: EventHandlers | null;
constructor(name: string) { constructor(name: string, on?: EventHandlers | null) {
this.name = name; this.name = name;
this.on = on || null;
} }
addLine(line: string, idx?: number) { addLine(line: string, idx?: number) {
@@ -216,7 +220,7 @@ export class CodeGenerator {
translateFn: (s: string) => string; translateFn: (s: string) => string;
translatableAttributes: string[] = TRANSLATABLE_ATTRS; translatableAttributes: string[] = TRANSLATABLE_ATTRS;
ast: AST; ast: AST;
staticCalls: { id: string; template: string }[] = []; staticDefs: { id: string; expr: string }[] = [];
helpers: Set<string> = new Set(); helpers: Set<string> = new Set();
constructor(ast: AST, options: CodeGenOptions) { constructor(ast: AST, options: CodeGenOptions) {
@@ -262,8 +266,8 @@ export class CodeGenerator {
mainCode.push(`// Template name: "${this.templateName}"`); mainCode.push(`// Template name: "${this.templateName}"`);
} }
for (let { id, template } of this.staticCalls) { for (let { id, expr } of this.staticDefs) {
mainCode.push(`const ${id} = getTemplate(${template});`); mainCode.push(`const ${id} = ${expr};`);
} }
// define all blocks // define all blocks
@@ -303,20 +307,23 @@ export class CodeGenerator {
return code; return code;
} }
compileInNewTarget(prefix: string, ast: AST, ctx: Context): string { compileInNewTarget(prefix: string, ast: AST, ctx: Context, on?: EventHandlers | null): string {
const name = this.generateId(prefix); const name = this.generateId(prefix);
const initialTarget = this.target; const initialTarget = this.target;
const target = new CodeTarget(name); const target = new CodeTarget(name, on);
this.targets.push(target); this.targets.push(target);
this.target = target; this.target = target;
const subCtx: Context = createContext(ctx); this.compileAST(ast, createContext(ctx));
this.compileAST(ast, subCtx);
this.target = initialTarget; this.target = initialTarget;
return name; return name;
} }
addLine(line: string) { addLine(line: string, idx?: number) {
this.target.addLine(line); this.target.addLine(line, idx);
}
define(varName: string, expr: string) {
this.addLine(`const ${varName} = ${expr};`);
} }
generateId(prefix: string = ""): string { generateId(prefix: string = ""): string {
@@ -368,9 +375,12 @@ export class CodeGenerator {
} }
if (block.isRoot && !ctx.preventRoot) { if (block.isRoot && !ctx.preventRoot) {
if (this.target.on) {
blockExpr = this.wrapWithEventCatcher(blockExpr, this.target.on);
}
this.addLine(`return ${blockExpr};`); this.addLine(`return ${blockExpr};`);
} else { } else {
this.addLine(`let ${block.varName} = ${blockExpr};`); this.define(block.varName, blockExpr);
} }
} }
@@ -399,7 +409,7 @@ export class CodeGenerator {
if (!mapping.has(tok.varName)) { if (!mapping.has(tok.varName)) {
const varId = this.generateId("v"); const varId = this.generateId("v");
mapping.set(tok.varName, varId); mapping.set(tok.varName, varId);
this.addLine(`const ${varId} = ${tok.value};`); this.define(varId, tok.value);
} }
tok.value = mapping.get(tok.varName)!; tok.value = mapping.get(tok.varName)!;
} }
@@ -544,12 +554,12 @@ export class CodeGenerator {
this.blocks.push(block); this.blocks.push(block);
if (ast.dynamicTag) { if (ast.dynamicTag) {
const tagExpr = this.generateId("tag"); const tagExpr = this.generateId("tag");
this.addLine(`let ${tagExpr} = ${compileExpr(ast.dynamicTag)};`); this.define(tagExpr, compileExpr(ast.dynamicTag));
block.dynamicTagName = tagExpr; block.dynamicTagName = tagExpr;
} }
} }
// attributes // attributes
const attrs: { [key: string]: string } = {}; const attrs: Attrs = {};
const nameSpace = ast.ns || ctx.nameSpace; const nameSpace = ast.ns || ctx.nameSpace;
if (nameSpace && isNewBlock) { if (nameSpace && isNewBlock) {
// specific namespace uri // specific namespace uri
@@ -639,11 +649,11 @@ export class CodeGenerator {
const baseExpression = compileExpr(baseExpr); const baseExpression = compileExpr(baseExpr);
const bExprId = this.generateId("bExpr"); const bExprId = this.generateId("bExpr");
this.addLine(`const ${bExprId} = ${baseExpression};`); this.define(bExprId, baseExpression);
const expression = compileExpr(expr); const expression = compileExpr(expr);
const exprId = this.generateId("expr"); const exprId = this.generateId("expr");
this.addLine(`const ${exprId} = ${expression};`); this.define(exprId, expression);
const fullExpression = `${bExprId}[${exprId}]`; const fullExpression = `${bExprId}[${exprId}]`;
@@ -654,7 +664,7 @@ export class CodeGenerator {
} else if (hasDynamicChildren) { } else if (hasDynamicChildren) {
const bValueId = this.generateId("bValue"); const bValueId = this.generateId("bValue");
tModelSelectedExpr = `${bValueId}`; tModelSelectedExpr = `${bValueId}`;
this.addLine(`let ${tModelSelectedExpr} = ${fullExpression}`); this.define(tModelSelectedExpr, fullExpression);
} else { } else {
idx = block!.insertData(`${fullExpression}`, "attr"); idx = block!.insertData(`${fullExpression}`, "attr");
attrs[`block-attribute-${idx}`] = targetAttr; attrs[`block-attribute-${idx}`] = targetAttr;
@@ -704,13 +714,13 @@ export class CodeGenerator {
const children = block!.children.slice(); const children = block!.children.slice();
let current = children.shift(); let current = children.shift();
for (let i = codeIdx; i < code.length; i++) { for (let i = codeIdx; i < code.length; i++) {
if (code[i].trimStart().startsWith(`let ${current!.varName} `)) { if (code[i].trimStart().startsWith(`const ${current!.varName} `)) {
code[i] = code[i].replace(`let ${current!.varName}`, current!.varName); code[i] = code[i].replace(`const ${current!.varName}`, current!.varName);
current = children.shift(); current = children.shift();
if (!current) break; if (!current) break;
} }
} }
this.target.addLine(`let ${block!.children.map((c) => c.varName)};`, codeIdx); this.addLine(`let ${block!.children.map((c) => c.varName)};`, codeIdx);
} }
} }
} }
@@ -799,13 +809,13 @@ export class CodeGenerator {
const children = block!.children.slice(); const children = block!.children.slice();
let current = children.shift(); let current = children.shift();
for (let i = codeIdx; i < code.length; i++) { for (let i = codeIdx; i < code.length; i++) {
if (code[i].trimStart().startsWith(`let ${current!.varName} `)) { if (code[i].trimStart().startsWith(`const ${current!.varName} `)) {
code[i] = code[i].replace(`let ${current!.varName}`, current!.varName); code[i] = code[i].replace(`const ${current!.varName}`, current!.varName);
current = children.shift(); current = children.shift();
if (!current) break; if (!current) break;
} }
} }
this.target.addLine(`let ${block!.children.map((c) => c.varName)};`, codeIdx); this.addLine(`let ${block!.children.map((c) => c.varName)};`, codeIdx);
} }
// note: this part is duplicated from end of compilemulti: // note: this part is duplicated from end of compilemulti:
@@ -828,12 +838,10 @@ export class CodeGenerator {
const l = `l_block${block.id}`; const l = `l_block${block.id}`;
const c = `c_block${block.id}`; const c = `c_block${block.id}`;
this.helpers.add("prepareList"); this.helpers.add("prepareList");
this.addLine( this.define(`[${keys}, ${vals}, ${l}, ${c}]`, `prepareList(${compileExpr(ast.collection)});`);
`const [${keys}, ${vals}, ${l}, ${c}] = prepareList(${compileExpr(ast.collection)});`
);
// Throw errors on duplicate keys in dev mode // Throw errors on duplicate keys in dev mode
if (this.dev) { if (this.dev) {
this.addLine(`const keys${block.id} = new Set();`); this.define(`keys${block.id}`, `new Set()`);
} }
this.addLine(`for (let ${loopVar} = 0; ${loopVar} < ${l}; ${loopVar}++) {`); this.addLine(`for (let ${loopVar} = 0; ${loopVar} < ${l}; ${loopVar}++) {`);
this.target.indentLevel++; this.target.indentLevel++;
@@ -850,7 +858,7 @@ export class CodeGenerator {
if (!ast.hasNoValue) { if (!ast.hasNoValue) {
this.addLine(`ctx[\`${ast.elem}_value\`] = ${keys}[${loopVar}];`); this.addLine(`ctx[\`${ast.elem}_value\`] = ${keys}[${loopVar}];`);
} }
this.addLine(`let key${this.target.loopLevel} = ${ast.key ? compileExpr(ast.key) : loopVar};`); this.define(`key${this.target.loopLevel}`, ast.key ? compileExpr(ast.key) : loopVar);
if (this.dev) { if (this.dev) {
// Throw error on duplicate keys in dev mode // Throw error on duplicate keys in dev mode
this.addLine( this.addLine(
@@ -862,8 +870,8 @@ export class CodeGenerator {
if (ast.memo) { if (ast.memo) {
this.target.hasCache = true; this.target.hasCache = true;
id = this.generateId(); id = this.generateId();
this.addLine(`let memo${id} = ${compileExpr(ast.memo)}`); this.define(`memo${id}`, compileExpr(ast.memo));
this.addLine(`let vnode${id} = cache[key${this.target.loopLevel}];`); this.define(`vnode${id}`, `cache[key${this.target.loopLevel}];`);
this.addLine(`if (vnode${id}) {`); this.addLine(`if (vnode${id}) {`);
this.target.indentLevel++; this.target.indentLevel++;
this.addLine(`if (shallowEqual(vnode${id}.memo, memo${id})) {`); this.addLine(`if (shallowEqual(vnode${id}.memo, memo${id})) {`);
@@ -897,7 +905,7 @@ export class CodeGenerator {
compileTKey(ast: ASTTKey, ctx: Context) { compileTKey(ast: ASTTKey, ctx: Context) {
const tKeyExpr = this.generateId("tKey_"); const tKeyExpr = this.generateId("tKey_");
this.addLine(`const ${tKeyExpr} = ${compileExpr(ast.expr)};`); this.define(tKeyExpr, compileExpr(ast.expr));
ctx = createContext(ctx, { ctx = createContext(ctx, {
tKeyExpr, tKeyExpr,
block: ctx.block, block: ctx.block,
@@ -943,13 +951,13 @@ export class CodeGenerator {
const children = block!.children.slice(); const children = block!.children.slice();
let current = children.shift(); let current = children.shift();
for (let i = codeIdx; i < code.length; i++) { for (let i = codeIdx; i < code.length; i++) {
if (code[i].trimStart().startsWith(`let ${current!.varName} `)) { if (code[i].trimStart().startsWith(`const ${current!.varName} `)) {
code[i] = code[i].replace(`let ${current!.varName}`, current!.varName); code[i] = code[i].replace(`const ${current!.varName}`, current!.varName);
current = children.shift(); current = children.shift();
if (!current) break; if (!current) break;
} }
} }
this.target.addLine(`let ${block!.children.map((c) => c.varName)};`, codeIdx); this.addLine(`let ${block!.children.map((c) => c.varName)};`, codeIdx);
} }
} }
@@ -982,7 +990,7 @@ export class CodeGenerator {
const key = `key + \`${this.generateComponentKey()}\``; const key = `key + \`${this.generateComponentKey()}\``;
if (isDynamic) { if (isDynamic) {
const templateVar = this.generateId("template"); const templateVar = this.generateId("template");
this.addLine(`const ${templateVar} = ${subTemplate};`); this.define(templateVar, subTemplate);
block = this.createBlock(block, "multi", ctx); block = this.createBlock(block, "multi", ctx);
this.helpers.add("call"); this.helpers.add("call");
this.insertBlock(`call(this, ${templateVar}, ctx, node, ${key})`, block!, { this.insertBlock(`call(this, ${templateVar}, ctx, node, ${key})`, block!, {
@@ -992,7 +1000,7 @@ export class CodeGenerator {
} else { } else {
const id = this.generateId(`callTemplate_`); const id = this.generateId(`callTemplate_`);
this.helpers.add("getTemplate"); this.helpers.add("getTemplate");
this.staticCalls.push({ id, template: subTemplate }); this.staticDefs.push({ id, expr: `getTemplate(${subTemplate})` });
block = this.createBlock(block, "multi", ctx); block = this.createBlock(block, "multi", ctx);
this.insertBlock(`${id}.call(this, ctx, node, ${key})`, block!, { this.insertBlock(`${id}.call(this, ctx, node, ${key})`, block!, {
...ctx, ...ctx,
@@ -1087,29 +1095,27 @@ export class CodeGenerator {
compileComponent(ast: ASTComponent, ctx: Context) { compileComponent(ast: ASTComponent, ctx: Context) {
let { block } = ctx; let { block } = ctx;
// props // props
const hasSlotsProp = "slots" in ast.props; const hasSlotsProp = "slots" in (ast.props || {});
const props: string[] = []; const props: string[] = [];
const propExpr = this.formatPropObject(ast.props); const propExpr = this.formatPropObject(ast.props || {});
if (propExpr) { if (propExpr) {
props.push(propExpr); props.push(propExpr);
} }
// slots // slots
const hasSlot = !!Object.keys(ast.slots).length;
let slotDef: string = ""; let slotDef: string = "";
if (hasSlot) { if (ast.slots) {
let ctxStr = "ctx"; let ctxStr = "ctx";
if (this.target.loopLevel || !this.hasSafeContext) { if (this.target.loopLevel || !this.hasSafeContext) {
ctxStr = this.generateId("ctx"); ctxStr = this.generateId("ctx");
this.helpers.add("capture"); this.helpers.add("capture");
this.addLine(`const ${ctxStr} = capture(ctx);`); this.define(ctxStr, `capture(ctx)`);
} }
let slotStr: string[] = []; let slotStr: string[] = [];
for (let slotName in ast.slots) { for (let slotName in ast.slots) {
const slotAst = ast.slots[slotName].content; const slotAst = ast.slots[slotName];
const name = this.compileInNewTarget("slot", slotAst, ctx); const name = this.compileInNewTarget("slot", slotAst.content, ctx, slotAst.on);
const params = [`__render: ${name}, __ctx: ${ctxStr}`]; const params = [`__render: ${name}, __ctx: ${ctxStr}`];
const scope = ast.slots[slotName].scope; const scope = ast.slots[slotName].scope;
if (scope) { if (scope) {
@@ -1141,7 +1147,7 @@ export class CodeGenerator {
let propVar: string; let propVar: string;
if ((slotDef && (ast.dynamicProps || hasSlotsProp)) || this.dev) { if ((slotDef && (ast.dynamicProps || hasSlotsProp)) || this.dev) {
propVar = this.generateId("props"); propVar = this.generateId("props");
this.addLine(`const ${propVar!} = ${propString};`); this.define(propVar!, propString);
propString = propVar!; propString = propVar!;
} }
@@ -1155,7 +1161,7 @@ export class CodeGenerator {
let expr: string; let expr: string;
if (ast.isDynamic) { if (ast.isDynamic) {
expr = this.generateId("Comp"); expr = this.generateId("Comp");
this.addLine(`let ${expr} = ${compileExpr(ast.name)};`); this.define(expr, compileExpr(ast.name));
} else { } else {
expr = `\`${ast.name}\``; expr = `\`${ast.name}\``;
} }
@@ -1178,10 +1184,32 @@ export class CodeGenerator {
if (ast.isDynamic) { if (ast.isDynamic) {
blockExpr = `toggler(${expr}, ${blockExpr})`; blockExpr = `toggler(${expr}, ${blockExpr})`;
} }
// event handling
if (ast.on) {
blockExpr = this.wrapWithEventCatcher(blockExpr, ast.on);
}
block = this.createBlock(block, "multi", ctx); block = this.createBlock(block, "multi", ctx);
this.insertBlock(blockExpr, block, ctx); this.insertBlock(blockExpr, block, ctx);
} }
wrapWithEventCatcher(expr: string, on: EventHandlers): string {
this.helpers.add("createCatcher");
let name = this.generateId("catcher");
let spec: any = {};
let handlers: any[] = [];
for (let ev in on) {
let handlerId = this.generateId("hdlr");
let idx = handlers.push(handlerId) - 1;
spec[ev] = idx;
const handler = this.generateHandlerCode(ev, on[ev]);
this.define(handlerId, handler);
}
this.staticDefs.push({ id: name, expr: `createCatcher(${JSON.stringify(spec)})` });
return `${name}(${expr}, [${handlers.join(",")}])`;
}
compileTSlot(ast: ASTSlot, ctx: Context) { compileTSlot(ast: ASTSlot, ctx: Context) {
this.helpers.add("callSlot"); this.helpers.add("callSlot");
let { block } = ctx; let { block } = ctx;
@@ -1202,12 +1230,17 @@ export class CodeGenerator {
} else { } else {
if (dynamic) { if (dynamic) {
let name = this.generateId("slot"); let name = this.generateId("slot");
this.addLine(`const ${name} = ${slotName};`); this.define(name, slotName);
blockString = `toggler(${name}, callSlot(ctx, node, key, ${name}), ${dynamic}, ${scope})`; blockString = `toggler(${name}, callSlot(ctx, node, key, ${name}), ${dynamic}, ${scope})`;
} else { } else {
blockString = `callSlot(ctx, node, key, ${slotName}, ${dynamic}, ${scope})`; blockString = `callSlot(ctx, node, key, ${slotName}, ${dynamic}, ${scope})`;
} }
} }
// event handling
if (ast.on) {
blockString = this.wrapWithEventCatcher(blockString, ast.on);
}
if (block) { if (block) {
this.insertAnchor(block); this.insertAnchor(block);
} }
@@ -1230,7 +1263,7 @@ export class CodeGenerator {
if (this.target.loopLevel || !this.hasSafeContext) { if (this.target.loopLevel || !this.hasSafeContext) {
ctxStr = this.generateId("ctx"); ctxStr = this.generateId("ctx");
this.helpers.add("capture"); this.helpers.add("capture");
this.addLine(`const ${ctxStr} = capture(ctx);`); this.define(ctxStr, `capture(ctx);`);
} }
const blockString = `component(Portal, {target: ${ast.target},slots: {'default': {__render: ${name}, __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx)`; const blockString = `component(Portal, {target: ${ast.target},slots: {'default': {__render: ${name}, __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx)`;
if (block) { if (block) {
+19 -13
View File
@@ -199,24 +199,30 @@ const TOKENIZERS = [
export function tokenize(expr: string): Token[] { export function tokenize(expr: string): Token[] {
const result: Token[] = []; const result: Token[] = [];
let token: boolean | Token = true; let token: boolean | Token = true;
let error: any;
let current = expr;
while (token) { try {
expr = expr.trim(); while (token) {
if (expr) { current = current.trim();
for (let tokenizer of TOKENIZERS) { if (current) {
token = tokenizer(expr); for (let tokenizer of TOKENIZERS) {
if (token) { token = tokenizer(current);
result.push(token); if (token) {
expr = expr.slice(token.size || token.value.length); result.push(token);
break; current = current.slice(token.size || token.value.length);
break;
}
} }
} else {
token = false;
} }
} else {
token = false;
} }
} catch (e) {
error = e; // Silence all errors and throw a generic error below
} }
if (expr.length) { if (current.length || error) {
throw new Error(`Tokenizer error: could not tokenize "${expr}"`); throw new Error(`Tokenizer error: could not tokenize \`${expr}\``);
} }
return result; return result;
} }
+64 -33
View File
@@ -2,6 +2,9 @@
// AST Type definition // AST Type definition
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
export type EventHandlers = { [eventName: string]: string };
export type Attrs = { [attrs: string]: string };
export const enum ASTType { export const enum ASTType {
Text, Text,
Comment, Comment,
@@ -34,25 +37,25 @@ export interface ASTComment {
} }
interface TModelInfo { interface TModelInfo {
hasDynamicChildren?: boolean;
baseExpr: string; baseExpr: string;
expr: string; expr: string;
targetAttr: string; targetAttr: string;
specialInitTargetAttr: string | null;
eventType: "change" | "click" | "input"; eventType: "change" | "click" | "input";
shouldTrim: boolean; shouldTrim: boolean;
shouldNumberize: boolean; shouldNumberize: boolean;
hasDynamicChildren: boolean;
specialInitTargetAttr: string | null;
} }
export interface ASTDomNode { export interface ASTDomNode {
type: ASTType.DomNode; type: ASTType.DomNode;
tag: string; tag: string;
dynamicTag: string | null;
attrs: { [key: string]: string };
content: AST[]; content: AST[];
attrs: Attrs | null;
ref: string | null; ref: string | null;
on: { [key: string]: string }; on: EventHandlers | null;
model?: TModelInfo | null; model: TModelInfo | null;
dynamicTag: string | null;
ns: string | null; ns: string | null;
} }
@@ -93,13 +96,13 @@ export interface ASTTForEach {
type: ASTType.TForEach; type: ASTType.TForEach;
collection: string; collection: string;
elem: string; elem: string;
key: string | null;
body: AST; body: AST;
memo: string; memo: string;
hasNoFirst: boolean; hasNoFirst: boolean;
hasNoLast: boolean; hasNoLast: boolean;
hasNoIndex: boolean; hasNoIndex: boolean;
hasNoValue: boolean; hasNoValue: boolean;
key: string | null;
} }
export interface ASTTKey { export interface ASTTKey {
@@ -114,19 +117,28 @@ export interface ASTTCall {
body: AST[] | null; body: AST[] | null;
} }
interface SlotDefinition {
content: AST;
scope: string | null;
on: EventHandlers | null;
attrs: Attrs | null;
}
export interface ASTComponent { export interface ASTComponent {
type: ASTType.TComponent; type: ASTType.TComponent;
name: string; name: string;
isDynamic: boolean; isDynamic: boolean;
dynamicProps: string | null; dynamicProps: string | null;
props: { [name: string]: string }; on: EventHandlers | null;
slots: { [name: string]: { content: AST; attrs?: { [key: string]: string }; scope?: string } }; props: { [name: string]: string } | null;
slots: { [name: string]: SlotDefinition } | null;
} }
export interface ASTSlot { export interface ASTSlot {
type: ASTType.TSlot; type: ASTType.TSlot;
name: string; name: string;
attrs: { [key: string]: string }; attrs: Attrs | null;
on: EventHandlers | null;
defaultContent: AST | null; defaultContent: AST | null;
} }
@@ -319,8 +331,8 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
node.removeAttribute("t-ref"); node.removeAttribute("t-ref");
const nodeAttrsNames = node.getAttributeNames(); const nodeAttrsNames = node.getAttributeNames();
const attrs: ASTDomNode["attrs"] = {}; let attrs: ASTDomNode["attrs"] = null;
const on: ASTDomNode["on"] = {}; let on: EventHandlers | null = null;
let model: TModelInfo | null = null; let model: TModelInfo | null = null;
for (let attr of nodeAttrsNames) { for (let attr of nodeAttrsNames) {
@@ -329,6 +341,7 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
if (attr === "t-on") { if (attr === "t-on") {
throw new Error("Missing event name with t-on directive"); throw new Error("Missing event name with t-on directive");
} }
on = on || {};
on[attr.slice(5)] = value; on[attr.slice(5)] = value;
} else if (attr.startsWith("t-model")) { } else if (attr.startsWith("t-model")) {
if (!["input", "select", "textarea"].includes(tagName)) { if (!["input", "select", "textarea"].includes(tagName)) {
@@ -366,6 +379,7 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
targetAttr: isCheckboxInput ? "checked" : "value", targetAttr: isCheckboxInput ? "checked" : "value",
specialInitTargetAttr: isRadioInput ? "checked" : null, specialInitTargetAttr: isRadioInput ? "checked" : null,
eventType, eventType,
hasDynamicChildren: false,
shouldTrim: hasTrimMod && (isOtherInput || isTextarea), shouldTrim: hasTrimMod && (isOtherInput || isTextarea),
shouldNumberize: hasNumberMod && (isOtherInput || isTextarea), shouldNumberize: hasNumberMod && (isOtherInput || isTextarea),
}; };
@@ -384,6 +398,7 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
if (tModel && ["t-att-value", "t-attf-value"].includes(attr)) { if (tModel && ["t-att-value", "t-attf-value"].includes(attr)) {
tModel.hasDynamicChildren = true; tModel.hasDynamicChildren = true;
} }
attrs = attrs || {};
attrs[attr] = value; attrs[attr] = value;
} }
} }
@@ -554,7 +569,7 @@ function parseTCall(node: Element, ctx: ParsingContext): AST | null {
if (ast && ast.type === ASTType.TComponent) { if (ast && ast.type === ASTType.TComponent) {
return { return {
...ast, ...ast,
slots: { default: { content: tcall } }, slots: { default: { content: tcall, scope: null, on: null, attrs: null } },
}; };
} }
} }
@@ -650,7 +665,6 @@ function parseTSetNode(node: Element, ctx: ParsingContext): AST | null {
// Error messages when trying to use an unsupported directive on a component // Error messages when trying to use an unsupported directive on a component
const directiveErrorMap = new Map([ const directiveErrorMap = new Map([
["t-on", "t-on is no longer supported on components. Consider passing a callback in props."],
[ [
"t-ref", "t-ref",
"t-ref is no longer supported on components. Consider exposing only the public part of the component's API through a callback prop.", "t-ref is no longer supported on components. Consider exposing only the public part of the component's API through a callback prop.",
@@ -684,19 +698,26 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
const defaultSlotScope = node.getAttribute("t-slot-scope"); const defaultSlotScope = node.getAttribute("t-slot-scope");
node.removeAttribute("t-slot-scope"); node.removeAttribute("t-slot-scope");
let on: ASTComponent["on"] = null;
const props: ASTComponent["props"] = {}; let props: ASTComponent["props"] = null;
for (let name of node.getAttributeNames()) { for (let name of node.getAttributeNames()) {
const value = node.getAttribute(name)!; const value = node.getAttribute(name)!;
if (name.startsWith("t-")) { if (name.startsWith("t-")) {
const message = directiveErrorMap.get(name.split("-").slice(0, 2).join("-")); if (name.startsWith("t-on-")) {
throw new Error(message || `unsupported directive on Component: ${name}`); on = on || {};
on[name.slice(5)] = value;
} else {
const message = directiveErrorMap.get(name.split("-").slice(0, 2).join("-"));
throw new Error(message || `unsupported directive on Component: ${name}`);
}
} else { } else {
props = props || {};
props[name] = value; props[name] = value;
} }
} }
const slots: ASTComponent["slots"] = {}; let slots: ASTComponent["slots"] | null = null;
if (node.hasChildNodes()) { if (node.hasChildNodes()) {
const clone = <Element>node.cloneNode(true); const clone = <Element>node.cloneNode(true);
@@ -729,33 +750,35 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
slotNode.remove(); slotNode.remove();
const slotAst = parseNode(slotNode, ctx); const slotAst = parseNode(slotNode, ctx);
if (slotAst) { if (slotAst) {
const slotInfo: any = { content: slotAst }; let on: SlotDefinition["on"] = null;
const attrs: { [key: string]: string } = {}; let attrs: Attrs | null = null;
let scope: string | null = null;
for (let attributeName of slotNode.getAttributeNames()) { for (let attributeName of slotNode.getAttributeNames()) {
const value = slotNode.getAttribute(attributeName)!; const value = slotNode.getAttribute(attributeName)!;
if (attributeName === "t-slot-scope") { if (attributeName === "t-slot-scope") {
slotInfo.scope = value; scope = value;
continue; continue;
} else if (attributeName.startsWith("t-on-")) {
on = on || {};
on[attributeName.slice(5)] = value;
} else {
attrs = attrs || {};
attrs[attributeName] = value;
} }
attrs[attributeName] = value;
} }
if (Object.keys(attrs).length) { slots = slots || {};
slotInfo.attrs = attrs; slots[name] = { content: slotAst, on, attrs, scope };
}
slots[name] = slotInfo;
} }
} }
// default slot // default slot
const defaultContent = parseChildNodes(clone, ctx); const defaultContent = parseChildNodes(clone, ctx);
if (defaultContent) { if (defaultContent) {
slots.default = { content: defaultContent }; slots = slots || {};
if (defaultSlotScope) { slots.default = { content: defaultContent, on, attrs: null, scope: defaultSlotScope };
slots.default.scope = defaultSlotScope;
}
} }
} }
return { type: ASTType.TComponent, name, isDynamic, dynamicProps, props, slots }; return { type: ASTType.TComponent, name, isDynamic, dynamicProps, props, slots, on };
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -768,15 +791,23 @@ function parseTSlot(node: Element, ctx: ParsingContext): AST | null {
} }
const name = node.getAttribute("t-slot")!; const name = node.getAttribute("t-slot")!;
node.removeAttribute("t-slot"); node.removeAttribute("t-slot");
const attrs: { [key: string]: string } = {}; let attrs: Attrs | null = null;
let on: ASTComponent["on"] = null;
for (let attributeName of node.getAttributeNames()) { for (let attributeName of node.getAttributeNames()) {
const value = node.getAttribute(attributeName)!; const value = node.getAttribute(attributeName)!;
attrs[attributeName] = value; if (attributeName.startsWith("t-on-")) {
on = on || {};
on[attributeName.slice(5)] = value;
} else {
attrs = attrs || {};
attrs[attributeName] = value;
}
} }
return { return {
type: ASTType.TSlot, type: ASTType.TSlot,
name, name,
attrs, attrs,
on,
defaultContent: parseChildNodes(node, ctx), defaultContent: parseChildNodes(node, ctx),
}; };
} }
+19 -29
View File
@@ -2,23 +2,16 @@ import type { App, Env } from "../app/app";
import { BDom, VNode } from "../blockdom"; import { BDom, VNode } from "../blockdom";
import { import {
clearReactivesForCallback, clearReactivesForCallback,
getSubscriptions,
NonReactive,
Reactive, Reactive,
reactive, reactive,
TARGET, TARGET,
NonReactive,
getSubscriptions,
} from "../reactivity"; } from "../reactivity";
import { batched, Callback } from "../utils"; import { batched, Callback } from "../utils";
import { Component, ComponentConstructor } from "./component"; import { Component, ComponentConstructor } from "./component";
import { fibersInError, handleError } from "./error_handling"; import { fibersInError, handleError } from "./error_handling";
import { import { Fiber, makeChildFiber, makeRootFiber, MountFiber, MountOptions } from "./fibers";
Fiber,
makeChildFiber,
makeRootFiber,
MountFiber,
MountOptions,
RootFiber,
} from "./fibers";
import { applyDefaultProps } from "./props_validation"; import { applyDefaultProps } from "./props_validation";
import { STATUS } from "./status"; import { STATUS } from "./status";
@@ -58,13 +51,6 @@ export function useState<T extends object>(state: T): Reactive<T> | NonReactive<
batchedRenderFunctions.set(node, render); batchedRenderFunctions.set(node, render);
// manual implementation of onWillDestroy to break cyclic dependency // manual implementation of onWillDestroy to break cyclic dependency
node.willDestroy.push(clearReactivesForCallback.bind(null, render)); node.willDestroy.push(clearReactivesForCallback.bind(null, render));
if (node.app.dev) {
Object.defineProperty(node, "subscriptions", {
get() {
return getSubscriptions(render);
},
});
}
} }
return reactive(state, render); return reactive(state, render);
} }
@@ -133,6 +119,7 @@ export function component<P extends object>(
node.initiateRender(new Fiber(node, parentFiber)); node.initiateRender(new Fiber(node, parentFiber));
} }
parentFiber.root!.reachedChildren.add(node);
return node; return node;
} }
@@ -200,7 +187,7 @@ export class ComponentNode<P extends object = any, E = any> implements VNode<Com
return; return;
} }
if (this.status === STATUS.NEW && this.fiber === fiber) { if (this.status === STATUS.NEW && this.fiber === fiber) {
this._render(fiber); fiber.render();
} }
} }
@@ -245,16 +232,7 @@ export class ComponentNode<P extends object = any, E = any> implements VNode<Com
// embedded in a rendering coming from above, so the fiber will be rendered // embedded in a rendering coming from above, so the fiber will be rendered
// in the next microtick anyway, so we should not render it again. // in the next microtick anyway, so we should not render it again.
if (this.fiber === fiber && (current || !fiber.parent)) { if (this.fiber === fiber && (current || !fiber.parent)) {
this._render(fiber); fiber.render();
}
}
_render(fiber: Fiber | RootFiber) {
try {
fiber.bdom = this.renderFn();
fiber.root!.counter--;
} catch (e) {
handleError({ node: this, error: e });
} }
} }
@@ -298,7 +276,7 @@ export class ComponentNode<P extends object = any, E = any> implements VNode<Com
return; return;
} }
component.props = props; component.props = props;
this._render(fiber); fiber.render();
const parentRoot = parentFiber.root!; const parentRoot = parentFiber.root!;
if (this.willPatch.length) { if (this.willPatch.length) {
parentRoot.willPatch.push(fiber); parentRoot.willPatch.push(fiber);
@@ -394,4 +372,16 @@ export class ComponentNode<P extends object = any, E = any> implements VNode<Com
} }
} }
} }
// ---------------------------------------------------------------------------
// Some debug helpers
// ---------------------------------------------------------------------------
get name(): string {
return this.component.constructor.name;
}
get subscriptions(): ReturnType<typeof getSubscriptions> {
const render = batchedRenderFunctions.get(this);
return render ? getSubscriptions(render) : [];
}
} }
+2 -1
View File
@@ -30,7 +30,8 @@ function _handleError(node: ComponentNode | null, error: any, isFirstRound = fal
if (stopped) { if (stopped) {
if (isFirstRound && fiber && fiber.node.fiber) { if (isFirstRound && fiber && fiber.node.fiber) {
fiber.root!.counter--; const root = fiber.root!;
root.setCounter(root.counter - 1);
} }
return true; return true;
} }
+67 -2
View File
@@ -8,6 +8,10 @@ export function makeChildFiber(node: ComponentNode, parent: Fiber): Fiber {
if (current) { if (current) {
cancelFibers(current.children); cancelFibers(current.children);
current.root = null; current.root = null;
if (current instanceof RootFiber && current.delayedRenders.length) {
let root = parent.root!;
root.delayedRenders = root.delayedRenders.concat(current.delayedRenders);
}
} }
return new Fiber(node, parent); return new Fiber(node, parent);
} }
@@ -16,9 +20,12 @@ export function makeRootFiber(node: ComponentNode): Fiber {
let current = node.fiber; let current = node.fiber;
if (current) { if (current) {
let root = current.root!; let root = current.root!;
root.counter = root.counter + 1 - cancelFibers(current.children); root.setCounter(root.counter + 1 - cancelFibers(current.children));
current.children = []; current.children = [];
current.bdom = null; current.bdom = null;
if (current === root) {
root.reachedChildren = new WeakSet();
}
if (fibersInError.has(current)) { if (fibersInError.has(current)) {
fibersInError.delete(current); fibersInError.delete(current);
fibersInError.delete(root); fibersInError.delete(root);
@@ -74,13 +81,53 @@ export class Fiber {
if (parent) { if (parent) {
this.deep = parent.deep; this.deep = parent.deep;
const root = parent.root!; const root = parent.root!;
root.counter++; root.setCounter(root.counter + 1);
this.root = root; this.root = root;
parent.children.push(this); parent.children.push(this);
} else { } else {
this.root = this as any; this.root = this as any;
} }
} }
render() {
// if some parent has a fiber => register in followup
let prev = this.root!.node;
let current = prev.parent;
while (current) {
if (current.fiber) {
let root = current.fiber.root!;
if (root.counter) {
root.delayedRenders.push(this);
return;
} else {
if (!root.reachedChildren.has(prev)) {
// is dead
this.node.app.scheduler.shouldClear = true;
return;
}
current = root.node;
}
}
prev = current;
current = current.parent;
}
// there are no current rendering from above => we can render
this._render();
}
_render() {
const node = this.node;
const root = this.root;
if (root) {
try {
this.bdom = node.renderFn();
root.setCounter(root.counter - 1);
} catch (e) {
handleError({ node, error: e });
}
}
}
} }
export class RootFiber extends Fiber { export class RootFiber extends Fiber {
@@ -94,6 +141,9 @@ export class RootFiber extends Fiber {
// i.e.: render triggered in onWillUnmount or in willPatch will be delayed // i.e.: render triggered in onWillUnmount or in willPatch will be delayed
locked: boolean = false; locked: boolean = false;
delayedRenders: Fiber[] = [];
reachedChildren: WeakSet<ComponentNode> = new WeakSet();
complete() { complete() {
const node = this.node; const node = this.node;
this.locked = true; this.locked = true;
@@ -144,6 +194,21 @@ export class RootFiber extends Fiber {
handleError({ fiber: current || this, error: e }); handleError({ fiber: current || this, error: e });
} }
} }
setCounter(newValue: number) {
this.counter = newValue;
if (newValue === 0) {
if (this.delayedRenders.length) {
for (let f of this.delayedRenders) {
if (f.root) {
f.render();
}
}
this.delayedRenders = [];
}
this.node.app.scheduler.flush();
}
}
} }
type Position = "first-child" | "last-child"; type Position = "first-child" | "last-child";
+22 -6
View File
@@ -1,14 +1,28 @@
import { getCurrent } from "./component_node"; import { getCurrent } from "./component_node";
import { nodeErrorHandlers } from "./error_handling"; import { nodeErrorHandlers } from "./error_handling";
const TIMEOUT = Symbol("timeout");
function wrapError(fn: (...args: any[]) => any, hookName: string) { function wrapError(fn: (...args: any[]) => any, hookName: string) {
const error = new Error(`The following error occurred in ${hookName}: `) as Error & { const error = new Error(`The following error occurred in ${hookName}: `) as Error & {
cause: any; cause: any;
}; };
const timeoutError = new Error(`${hookName}'s promise hasn't resolved after 3 seconds`);
const node = getCurrent();
return (...args: any[]) => { return (...args: any[]) => {
try { try {
const result = fn(...args); const result = fn(...args);
if (result instanceof Promise) { if (result instanceof Promise) {
if (hookName === "onWillStart" || hookName === "onWillUpdateProps") {
const fiber = node.fiber;
Promise.race([
result,
new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)),
]).then((res) => {
if (res === TIMEOUT && node.fiber === fiber) {
console.warn(timeoutError);
}
});
}
return result.catch((cause) => { return result.catch((cause) => {
error.cause = cause; error.cause = cause;
if (cause instanceof Error) { if (cause instanceof Error) {
@@ -77,21 +91,23 @@ export function onWillRender(fn: () => void | any) {
const node = getCurrent(); const node = getCurrent();
const renderFn = node.renderFn; const renderFn = node.renderFn;
const decorate = node.app.dev ? wrapError : (fn: any) => fn; const decorate = node.app.dev ? wrapError : (fn: any) => fn;
node.renderFn = decorate(() => { fn = decorate(fn.bind(node.component), "onWillRender");
fn.call(node.component); node.renderFn = () => {
fn();
return renderFn(); return renderFn();
}, "onWillRender"); };
} }
export function onRendered(fn: () => void | any) { export function onRendered(fn: () => void | any) {
const node = getCurrent(); const node = getCurrent();
const renderFn = node.renderFn; const renderFn = node.renderFn;
const decorate = node.app.dev ? wrapError : (fn: any) => fn; const decorate = node.app.dev ? wrapError : (fn: any) => fn;
node.renderFn = decorate(() => { fn = decorate(fn.bind(node.component), "onRendered");
node.renderFn = () => {
const result = renderFn(); const result = renderFn();
fn.call(node.component); fn();
return result; return result;
}, "onRendered"); };
} }
type OnErrorCallback = (error: any) => void | any; type OnErrorCallback = (error: any) => void | any;
+34 -42
View File
@@ -11,27 +11,16 @@ export class Scheduler {
// interactions with other code, such as test frameworks that override them // interactions with other code, such as test frameworks that override them
static requestAnimationFrame = window.requestAnimationFrame.bind(window); static requestAnimationFrame = window.requestAnimationFrame.bind(window);
tasks: Set<RootFiber> = new Set(); tasks: Set<RootFiber> = new Set();
isRunning: boolean = false;
requestAnimationFrame: Window["requestAnimationFrame"]; requestAnimationFrame: Window["requestAnimationFrame"];
frame: number = 0;
shouldClear: boolean = false;
constructor() { constructor() {
this.requestAnimationFrame = Scheduler.requestAnimationFrame; this.requestAnimationFrame = Scheduler.requestAnimationFrame;
} }
start() {
this.isRunning = true;
this.scheduleTasks();
}
stop() {
this.isRunning = false;
}
addFiber(fiber: Fiber) { addFiber(fiber: Fiber) {
this.tasks.add(fiber.root!); this.tasks.add(fiber.root!);
if (!this.isRunning) {
this.start();
}
} }
/** /**
@@ -39,39 +28,42 @@ export class Scheduler {
* Other tasks are left unchanged. * Other tasks are left unchanged.
*/ */
flush() { flush() {
this.tasks.forEach((fiber) => { if (this.frame === 0) {
if (fiber.root !== fiber) { this.frame = this.requestAnimationFrame(() => {
this.tasks.delete(fiber); this.frame = 0;
return; this.tasks.forEach((fiber) => this.processFiber(fiber));
} if (this.shouldClear) {
const hasError = fibersInError.has(fiber); this.shouldClear = false;
if (hasError && fiber.counter !== 0) { for (let task of this.tasks) {
this.tasks.delete(fiber); if (task.node.status === STATUS.DESTROYED) {
return; this.tasks.delete(task);
} }
if (fiber.node.status === STATUS.DESTROYED) { }
this.tasks.delete(fiber);
return;
}
if (fiber.counter === 0) {
if (!hasError) {
fiber.complete();
} }
this.tasks.delete(fiber); });
}
});
if (this.tasks.size === 0) {
this.stop();
} }
} }
scheduleTasks() { processFiber(fiber: RootFiber) {
this.requestAnimationFrame(() => { if (fiber.root !== fiber) {
this.flush(); this.tasks.delete(fiber);
if (this.isRunning) { return;
this.scheduleTasks(); }
const hasError = fibersInError.has(fiber);
if (hasError && fiber.counter !== 0) {
this.tasks.delete(fiber);
return;
}
if (fiber.node.status === STATUS.DESTROYED) {
this.tasks.delete(fiber);
return;
}
if (fiber.counter === 0) {
if (!hasError) {
fiber.complete();
} }
}); this.tasks.delete(fiber);
}
} }
} }
+7 -6
View File
@@ -57,7 +57,6 @@ export function useChildSubEnv(envExtension: Env) {
// useEffect // useEffect
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
const NO_OP = () => {};
/** /**
* @param {...any} dependencies the dependencies computed by computeDependencies * @param {...any} dependencies the dependencies computed by computeDependencies
* @returns {void|(()=>void)} a cleanup function that reverses the side * @returns {void|(()=>void)} a cleanup function that reverses the side
@@ -78,11 +77,11 @@ type Effect = (...dependencies: any[]) => void | (() => void);
* NaN !== NaN, which will cause the effect to rerun on every patch. * NaN !== NaN, which will cause the effect to rerun on every patch.
*/ */
export function useEffect(effect: Effect, computeDependencies: () => any[] = () => [NaN]) { export function useEffect(effect: Effect, computeDependencies: () => any[] = () => [NaN]) {
let cleanup: () => void; let cleanup: (() => void) | void;
let dependencies: any[]; let dependencies: any[];
onMounted(() => { onMounted(() => {
dependencies = computeDependencies(); dependencies = computeDependencies();
cleanup = effect(...dependencies) || NO_OP; cleanup = effect(...dependencies);
}); });
onPatched(() => { onPatched(() => {
@@ -90,12 +89,14 @@ export function useEffect(effect: Effect, computeDependencies: () => any[] = ()
const shouldReapply = newDeps.some((val, i) => val !== dependencies[i]); const shouldReapply = newDeps.some((val, i) => val !== dependencies[i]);
if (shouldReapply) { if (shouldReapply) {
dependencies = newDeps; dependencies = newDeps;
cleanup(); if (cleanup) {
cleanup = effect(...dependencies) || NO_OP; cleanup();
}
cleanup = effect(...dependencies);
} }
}); });
onWillUnmount(() => cleanup()); onWillUnmount(() => cleanup && cleanup());
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
+29
View File
@@ -232,6 +232,11 @@ function basicProxyHandler<T extends Target>(callback: Callback): ProxyHandler<T
if (key === TARGET) { if (key === TARGET) {
return target; return target;
} }
// non-writable non-configurable properties cannot be made reactive
const desc = Object.getOwnPropertyDescriptor(target, key);
if (desc && !desc.writable && !desc.configurable) {
return Reflect.get(target, key, proxy);
}
observeTargetKey(target, key, callback); observeTargetKey(target, key, callback);
return possiblyReactive(Reflect.get(target, key, proxy), callback); return possiblyReactive(Reflect.get(target, key, proxy), callback);
}, },
@@ -308,6 +313,28 @@ function makeIteratorObserver(
} }
}; };
} }
/**
* Creates a forEach function that will delegate to forEach on the underlying
* collection while observing key changes, and keys as they're iterated over,
* and making the passed keys/values reactive.
*
* @param target @see reactive
* @param callback @see reactive
*/
function makeForEachObserver(target: any, callback: Callback) {
return function forEach(forEachCb: (val: any, key: any, target: any) => void, thisArg: any) {
observeTargetKey(target, KEYCHANGES, callback);
target.forEach(function (val: any, key: any, targetObj: any) {
observeTargetKey(target, key, callback);
forEachCb.call(
thisArg,
possiblyReactive(val, callback),
possiblyReactive(key, callback),
possiblyReactive(targetObj, callback)
);
}, thisArg);
};
}
/** /**
* Creates a function that will delegate to an underlying method, and check if * Creates a function that will delegate to an underlying method, and check if
* that method has modified the presence or value of a key, and notify the * that method has modified the presence or value of a key, and notify the
@@ -370,6 +397,7 @@ const rawTypeToFuncHandlers = {
values: makeIteratorObserver("values", target, callback), values: makeIteratorObserver("values", target, callback),
entries: makeIteratorObserver("entries", target, callback), entries: makeIteratorObserver("entries", target, callback),
[Symbol.iterator]: makeIteratorObserver(Symbol.iterator, target, callback), [Symbol.iterator]: makeIteratorObserver(Symbol.iterator, target, callback),
forEach: makeForEachObserver(target, callback),
clear: makeClearNotifier(target), clear: makeClearNotifier(target),
get size() { get size() {
observeTargetKey(target, KEYCHANGES, callback); observeTargetKey(target, KEYCHANGES, callback);
@@ -385,6 +413,7 @@ const rawTypeToFuncHandlers = {
values: makeIteratorObserver("values", target, callback), values: makeIteratorObserver("values", target, callback),
entries: makeIteratorObserver("entries", target, callback), entries: makeIteratorObserver("entries", target, callback),
[Symbol.iterator]: makeIteratorObserver(Symbol.iterator, target, callback), [Symbol.iterator]: makeIteratorObserver(Symbol.iterator, target, callback),
forEach: makeForEachObserver(target, callback),
clear: makeClearNotifier(target), clear: makeClearNotifier(target),
get size() { get size() {
observeTargetKey(target, KEYCHANGES, callback); observeTargetKey(target, KEYCHANGES, callback);
+6 -4
View File
@@ -15,11 +15,13 @@ export function batched(callback: Callback): Callback {
await Promise.resolve(); await Promise.resolve();
if (!called) { if (!called) {
called = true; called = true;
callback();
// wait for all calls in this microtick to fall through before resetting "called" // wait for all calls in this microtick to fall through before resetting "called"
// so that only the first call to the batched function calls the original callback // so that only the first call to the batched function calls the original callback.
await Promise.resolve(); // Schedule this before calling the callback so that calls to the batched function
called = false; // within the callback will proceed only after resetting called to false, and have
// a chance to execute the callback again
Promise.resolve().then(() => (called = false));
callback();
} }
}; };
} }
+11 -11
View File
@@ -131,7 +131,7 @@ exports[`Reactivity: useState parent and children subscribed to same context 1`]
let block1 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
let txt1 = ctx['contextObj'].b; let txt1 = ctx['contextObj'].b;
return block1([txt1], [b2]); return block1([txt1], [b2]);
} }
@@ -223,8 +223,8 @@ exports[`Reactivity: useState two components are updated in parallel 1`] = `
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`); let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
let b3 = component(\`Child\`, {}, key + \`__2\`, node, ctx); const b3 = component(\`Child\`, {}, key + \`__2\`, node, ctx);
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
}" }"
@@ -252,8 +252,8 @@ exports[`Reactivity: useState two components can subscribe to same context 1`] =
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`); let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
let b3 = component(\`Child\`, {}, key + \`__2\`, node, ctx); const b3 = component(\`Child\`, {}, key + \`__2\`, node, ctx);
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
}" }"
@@ -281,8 +281,8 @@ exports[`Reactivity: useState two independent components on different levels are
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`); let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
let b3 = component(\`Parent\`, {}, key + \`__2\`, node, ctx); const b3 = component(\`Parent\`, {}, key + \`__2\`, node, ctx);
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
}" }"
@@ -310,7 +310,7 @@ exports[`Reactivity: useState two independent components on different levels are
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -340,14 +340,14 @@ exports[`Reactivity: useState useless atoms should be deleted 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(Object.keys(ctx['state'])); const [k_block2, v_block2, l_block2, c_block2] = prepareList(Object.keys(ctx['state']));;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`id\`] = v_block2[i1]; ctx[\`id\`] = v_block2[i1];
let key1 = ctx['id']; const key1 = ctx['id'];
c_block2[i1] = withKey(component(\`Quantity\`, {id: ctx['id']}, key + \`__1__\${key1}\`, node, ctx), key1); c_block2[i1] = withKey(component(\`Quantity\`, {id: ctx['id']}, key + \`__1__\${key1}\`, node, ctx), key1);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b2 = list(c_block2); const b2 = list(c_block2);
let txt1 = ctx['total']; let txt1 = ctx['total'];
let txt2 = Object.keys(ctx['state']).length; let txt2 = Object.keys(ctx['state']).length;
return block1([txt1, txt2], [b2]); return block1([txt1, txt2], [b2]);
+13 -1
View File
@@ -169,13 +169,25 @@ describe("properties", () => {
expect(input.value).toBe("potato"); expect(input.value).toBe("potato");
}); });
test("input with value attribute, and undefined given", () => { test("input with value attribute, and falsy value given", () => {
const block = createBlock(`<input block-attribute-0="value"/>`); const block = createBlock(`<input block-attribute-0="value"/>`);
const tree = block([undefined]); const tree = block([undefined]);
mount(tree, fixture); mount(tree, fixture);
const input = fixture.querySelector("input")!; const input = fixture.querySelector("input")!;
expect(input.value).toBe(""); expect(input.value).toBe("");
patch(tree, block([null]));
expect(input.value).toBe("");
patch(tree, block([0]));
expect(input.value).toBe("0");
patch(tree, block([""]));
expect(input.value).toBe("");
patch(tree, block([false]));
expect(input.value).toBe("");
}); });
test("input type=checkbox with checked attribute", () => { test("input type=checkbox with checked attribute", () => {
+54
View File
@@ -0,0 +1,54 @@
import { config, createBlock, createCatcher, mount } from "../../src/blockdom";
import { makeTestFixture } from "./helpers";
import { mainEventHandler } from "../../src/component/handler";
//------------------------------------------------------------------------------
// Setup and helpers
//------------------------------------------------------------------------------
let fixture: HTMLElement;
config.mainEventHandler = mainEventHandler;
beforeEach(() => {
fixture = makeTestFixture();
});
afterEach(() => {
fixture.remove();
});
test("simple event catcher", async () => {
const catcher = createCatcher({ click: 0 });
const block = createBlock("<div></div>");
let n = 0;
let ctx = {};
let handler = [() => n++, ctx];
const tree = catcher(block(), [handler]);
mount(tree, fixture);
expect(fixture.innerHTML).toBe("<div></div>");
expect(fixture.firstChild).toBeInstanceOf(HTMLDivElement);
expect(n).toBe(0);
(fixture.firstChild as HTMLDivElement).click();
expect(n).toBe(1);
});
test("do not catch events outside of itself", async () => {
const catcher = createCatcher({ click: 0 });
const childBlock = createBlock("<div></div>");
const parentBlock = createBlock("<button><block-child-0/></button>");
let n = 0;
let ctx = {};
let handler = [() => n++, ctx];
const tree = parentBlock([], [catcher(childBlock(), [handler])]);
mount(tree, fixture);
expect(fixture.innerHTML).toBe("<button><div></div></button>");
expect(n).toBe(0);
fixture.querySelector("div")!.click();
expect(n).toBe(1);
fixture.querySelector("button")!.click();
expect(n).toBe(1);
});
@@ -70,17 +70,17 @@ exports[`t-on can bind handlers with empty object (with non empty inner string)
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(['someval']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(['someval']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`action\`] = v_block2[i1]; ctx[\`action\`] = v_block2[i1];
ctx[\`action_index\`] = i1; ctx[\`action_index\`] = i1;
let key1 = ctx['action_index']; const key1 = ctx['action_index'];
const v1 = ctx['activate']; const v1 = ctx['activate'];
const v2 = ctx['action']; const v2 = ctx['action'];
let hdlr1 = [()=>v1(v2), ctx]; let hdlr1 = [()=>v1(v2), ctx];
c_block2[i1] = withKey(block3([hdlr1]), key1); c_block2[i1] = withKey(block3([hdlr1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -140,10 +140,10 @@ exports[`t-on handler is bound to proper owner, part 2 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList([1]); const [k_block1, v_block1, l_block1, c_block1] = prepareList([1]);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`value\`] = v_block1[i1]; ctx[\`value\`] = v_block1[i1];
let key1 = ctx['value']; const key1 = ctx['value'];
let hdlr1 = [ctx['add'], ctx]; let hdlr1 = [ctx['add'], ctx];
c_block1[i1] = withKey(block2([hdlr1]), key1); c_block1[i1] = withKey(block2([hdlr1]), key1);
} }
@@ -188,14 +188,14 @@ exports[`t-on handler is bound to proper owner, part 4 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList([1]); const [k_block1, v_block1, l_block1, c_block1] = prepareList([1]);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`value\`] = v_block1[i1]; ctx[\`value\`] = v_block1[i1];
ctx[\`value_first\`] = i1 === 0; ctx[\`value_first\`] = i1 === 0;
ctx[\`value_last\`] = i1 === v_block1.length - 1; ctx[\`value_last\`] = i1 === v_block1.length - 1;
ctx[\`value_index\`] = i1; ctx[\`value_index\`] = i1;
ctx[\`value_value\`] = k_block1[i1]; ctx[\`value_value\`] = k_block1[i1];
let key1 = ctx['value']; const key1 = ctx['value'];
c_block1[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1); c_block1[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1);
} }
return list(c_block1); return list(c_block1);
@@ -271,7 +271,7 @@ exports[`t-on t-on modifiers (native listener) t-on combined with t-out 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let hdlr1 = [ctx['onClick'], ctx]; let hdlr1 = [ctx['onClick'], ctx];
let b2 = safeOutput(ctx['html']); const b2 = safeOutput(ctx['html']);
return block1([hdlr1], [b2]); return block1([hdlr1], [b2]);
} }
}" }"
@@ -347,17 +347,17 @@ exports[`t-on t-on modifiers (native listener) t-on with prevent modifier in t-f
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['projects']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['projects']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`project\`] = v_block2[i1]; ctx[\`project\`] = v_block2[i1];
let key1 = ctx['project']; const key1 = ctx['project'];
const v1 = ctx['onEdit']; const v1 = ctx['onEdit'];
const v2 = ctx['project']; const v2 = ctx['project'];
let hdlr1 = [\\"prevent\\", _ev=>v1(v2.id,_ev), ctx]; let hdlr1 = [\\"prevent\\", _ev=>v1(v2.id,_ev), ctx];
let txt1 = ctx['project'].name; let txt1 = ctx['project'].name;
c_block2[i1] = withKey(block3([hdlr1, txt1]), key1); c_block2[i1] = withKey(block3([hdlr1, txt1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -478,7 +478,7 @@ exports[`t-on t-on with t-call 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -508,7 +508,7 @@ exports[`t-on t-on, with arguments and t-call 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
+34 -34
View File
@@ -30,28 +30,28 @@ exports[`misc complex template 1`] = `
b3 = block3(); b3 = block3();
} }
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['batch'].slot_ids.filter(_slot=>_slot.build_id.id&&!_slot.trigger_id.manual&&(ctx['options'].trigger_display[_slot.trigger_id.id]))); const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['batch'].slot_ids.filter(_slot=>_slot.build_id.id&&!_slot.trigger_id.manual&&(ctx['options'].trigger_display[_slot.trigger_id.id])));;
for (let i1 = 0; i1 < l_block4; i1++) { for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`slot\`] = v_block4[i1]; ctx[\`slot\`] = v_block4[i1];
let key1 = ctx['slot'].id; const key1 = ctx['slot'].id;
c_block4[i1] = withKey(component(\`SlotButton\`, {class: ctx['slot_container'], slot: ctx['slot']}, key + \`__1__\${key1}\`, node, ctx), key1); c_block4[i1] = withKey(component(\`SlotButton\`, {class: ctx['slot_container'], slot: ctx['slot']}, key + \`__1__\${key1}\`, node, ctx), key1);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
b4 = list(c_block4); b4 = list(c_block4);
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block6, v_block6, l_block6, c_block6] = prepareList([1,2,3,4]); const [k_block6, v_block6, l_block6, c_block6] = prepareList([1,2,3,4]);;
for (let i1 = 0; i1 < l_block6; i1++) { for (let i1 = 0; i1 < l_block6; i1++) {
ctx[\`x\`] = v_block6[i1]; ctx[\`x\`] = v_block6[i1];
let key1 = ctx['x']; const key1 = ctx['x'];
c_block6[i1] = withKey(block7(), key1); c_block6[i1] = withKey(block7(), key1);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
b6 = list(c_block6); b6 = list(c_block6);
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block8, v_block8, l_block8, c_block8] = prepareList(ctx['commit_links']); const [k_block8, v_block8, l_block8, c_block8] = prepareList(ctx['commit_links']);;
for (let i1 = 0; i1 < l_block8; i1++) { for (let i1 = 0; i1 < l_block8; i1++) {
ctx[\`commit_link\`] = v_block8[i1]; ctx[\`commit_link\`] = v_block8[i1];
let key1 = ctx['commit_link'].id; const key1 = ctx['commit_link'].id;
let b10,b11,b12,b13; let b10,b11,b12,b13;
let attr5 = \`/runbot/commit/\${ctx['commit_link'].commit_id}\`; let attr5 = \`/runbot/commit/\${ctx['commit_link'].commit_id}\`;
let attr6 = \`badge badge-light batch_commit match_type_\${ctx['commit_link'].match_type}\`; let attr6 = \`badge badge-light batch_commit match_type_\${ctx['commit_link'].match_type}\`;
@@ -96,35 +96,35 @@ exports[`misc global 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList([4,5,6]); const [k_block2, v_block2, l_block2, c_block2] = prepareList([4,5,6]);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`value\`] = v_block2[i1]; ctx[\`value\`] = v_block2[i1];
ctx[\`value_first\`] = i1 === 0; ctx[\`value_first\`] = i1 === 0;
ctx[\`value_last\`] = i1 === v_block2.length - 1; ctx[\`value_last\`] = i1 === v_block2.length - 1;
ctx[\`value_index\`] = i1; ctx[\`value_index\`] = i1;
ctx[\`value_value\`] = k_block2[i1]; ctx[\`value_value\`] = k_block2[i1];
let key1 = ctx['value']; const key1 = ctx['value'];
let txt1 = ctx['value']; let txt1 = ctx['value'];
let b4 = block4([txt1]); const b4 = block4([txt1]);
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"foo\\", 'aaa'); setContextValue(ctx, \\"foo\\", 'aaa');
let b6 = callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`); const b6 = callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`);
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b7 = callTemplate_2.call(this, ctx, node, key + \`__2__\${key1}\`); const b7 = callTemplate_2.call(this, ctx, node, key + \`__2__\${key1}\`);
setContextValue(ctx, \\"foo\\", 'bbb'); setContextValue(ctx, \\"foo\\", 'bbb');
let b8 = callTemplate_3.call(this, ctx, node, key + \`__3__\${key1}\`); const b8 = callTemplate_3.call(this, ctx, node, key + \`__3__\${key1}\`);
let b5 = multi([b6, b7, b8]); const b5 = multi([b6, b7, b8]);
ctx[zero] = b5; ctx[zero] = b5;
let b9 = callTemplate_4.call(this, ctx, node, key + \`__4__\${key1}\`); const b9 = callTemplate_4.call(this, ctx, node, key + \`__4__\${key1}\`);
ctx = ctx.__proto__; ctx = ctx.__proto__;
c_block2[i1] = withKey(multi([b4, b9]), key1); c_block2[i1] = withKey(multi([b4, b9]), key1);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b2 = list(c_block2); const b2 = list(c_block2);
let b10 = callTemplate_5.call(this, ctx, node, key + \`__5\`); const b10 = callTemplate_5.call(this, ctx, node, key + \`__5\`);
return block1([], [b2, b10]); return block1([], [b2, b10]);
} }
}" }"
@@ -155,7 +155,7 @@ exports[`misc global 3`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let attr1 = 'agüero'; let attr1 = 'agüero';
let b2 = ctx[zero]; const b2 = ctx[zero];
return block1([attr1], [b2]); return block1([attr1], [b2]);
} }
}" }"
@@ -170,8 +170,8 @@ exports[`misc global 4`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = text(\`toto default\`); const b3 = text(\`toto default\`);
let b2 = withDefault(safeOutput(ctx['toto']), b3); const b2 = withDefault(safeOutput(ctx['toto']), b3);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -221,10 +221,10 @@ exports[`misc other complex template 1`] = `
let attr1 = \`/runbot/\${ctx['project'].slug}\`; let attr1 = \`/runbot/\${ctx['project'].slug}\`;
let txt1 = ctx['project'].name; let txt1 = ctx['project'].name;
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['projects']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['projects']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`project\`] = v_block2[i1]; ctx[\`project\`] = v_block2[i1];
let key1 = ctx['project'].id; const key1 = ctx['project'].id;
let hdlr1 = [ctx['selectProject'](ctx['project']), ctx]; let hdlr1 = [ctx['selectProject'](ctx['project']), ctx];
let txt2 = ctx['project'].name; let txt2 = ctx['project'].name;
c_block2[i1] = withKey(block3([hdlr1, txt2]), key1); c_block2[i1] = withKey(block3([hdlr1, txt2]), key1);
@@ -241,12 +241,12 @@ exports[`misc other complex template 1`] = `
if (ctx['nb_assigned_errors']&&ctx['nb_assigned_errors']>0) { if (ctx['nb_assigned_errors']&&ctx['nb_assigned_errors']>0) {
let attr3 = \`You have \${ctx['nb_assigned_errors']} random bug assigned\`; let attr3 = \`You have \${ctx['nb_assigned_errors']} random bug assigned\`;
let txt3 = ctx['nb_assigned_errors']; let txt3 = ctx['nb_assigned_errors'];
let b8 = block8([attr3, txt3]); const b8 = block8([attr3, txt3]);
let b9 = block9(); const b9 = block9();
b7 = multi([b8, b9]); b7 = multi([b8, b9]);
} else if (ctx['nb_build_errors']&&ctx['nb_build_errors']>0) { } else if (ctx['nb_build_errors']&&ctx['nb_build_errors']>0) {
let b11 = block11(); const b11 = block11();
let b12 = block12(); const b12 = block12();
b10 = multi([b11, b12]); b10 = multi([b11, b12]);
} }
let txt4 = ctx['user'].name.length>25?ctx['user'].namesubstring(0,23)+'...':ctx['user'].name; let txt4 = ctx['user'].name.length>25?ctx['user'].namesubstring(0,23)+'...':ctx['user'].name;
@@ -261,17 +261,17 @@ exports[`misc other complex template 1`] = `
let hdlr3 = [ctx['toggleMore'], ctx]; let hdlr3 = [ctx['toggleMore'], ctx];
if (ctx['categories']&&ctx['categories'].length>1) { if (ctx['categories']&&ctx['categories'].length>1) {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block15, v_block15, l_block15, c_block15] = prepareList(ctx['categories']); const [k_block15, v_block15, l_block15, c_block15] = prepareList(ctx['categories']);;
for (let i1 = 0; i1 < l_block15; i1++) { for (let i1 = 0; i1 < l_block15; i1++) {
ctx[\`category\`] = v_block15[i1]; ctx[\`category\`] = v_block15[i1];
let key1 = ctx['category'].id; const key1 = ctx['category'].id;
let attr6 = ctx['category'].id; let attr6 = ctx['category'].id;
let attr7 = ctx['category'].id==ctx['options'].active_category_id; let attr7 = ctx['category'].id==ctx['options'].active_category_id;
let txt5 = ctx['category'].name; let txt5 = ctx['category'].name;
c_block15[i1] = withKey(block16([attr6, attr7, txt5]), key1); c_block15[i1] = withKey(block16([attr6, attr7, txt5]), key1);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b15 = list(c_block15); const b15 = list(c_block15);
b14 = block14([], [b15]); b14 = block14([], [b15]);
} }
let attr8 = ctx['search'].value; let attr8 = ctx['search'].value;
@@ -280,10 +280,10 @@ exports[`misc other complex template 1`] = `
let hdlr6 = [ctx['clearSearch'], ctx]; let hdlr6 = [ctx['clearSearch'], ctx];
if (ctx['triggers']) { if (ctx['triggers']) {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block18, v_block18, l_block18, c_block18] = prepareList(ctx['triggers']); const [k_block18, v_block18, l_block18, c_block18] = prepareList(ctx['triggers']);;
for (let i1 = 0; i1 < l_block18; i1++) { for (let i1 = 0; i1 < l_block18; i1++) {
ctx[\`trigger\`] = v_block18[i1]; ctx[\`trigger\`] = v_block18[i1];
let key1 = ctx['trigger'].id; const key1 = ctx['trigger'].id;
let b20; let b20;
if (!ctx['trigger'].manual&&ctx['trigger'].project_id===ctx['project'].id&&ctx['trigger'].category_id===ctx['options'].active_category_id) { if (!ctx['trigger'].manual&&ctx['trigger'].project_id===ctx['project'].id&&ctx['trigger'].category_id===ctx['options'].active_category_id) {
let attr9 = \`trigger_\${ctx['trigger'].id}\`; let attr9 = \`trigger_\${ctx['trigger'].id}\`;
@@ -298,12 +298,12 @@ exports[`misc other complex template 1`] = `
c_block18[i1] = withKey(multi([b20]), key1); c_block18[i1] = withKey(multi([b20]), key1);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b18 = list(c_block18); const b18 = list(c_block18);
let hdlr8 = [ctx['triggerAll'], ctx]; let hdlr8 = [ctx['triggerAll'], ctx];
let hdlr9 = [ctx['triggerNone'], ctx]; let hdlr9 = [ctx['triggerNone'], ctx];
let hdlr10 = [ctx['triggerDefault'], ctx]; let hdlr10 = [ctx['triggerDefault'], ctx];
let hdlr11 = [ctx['toggleSettingsMenu'], ctx]; let hdlr11 = [ctx['toggleSettingsMenu'], ctx];
let b21 = block21([hdlr8, hdlr9, hdlr10, hdlr11]); const b21 = block21([hdlr8, hdlr9, hdlr10, hdlr11]);
b17 = multi([b18, b21]); b17 = multi([b18, b21]);
} }
if (ctx['load_infos']) { if (ctx['load_infos']) {
@@ -316,8 +316,8 @@ exports[`misc other complex template 1`] = `
if (!ctx['project']) { if (!ctx['project']) {
b24 = block24(); b24 = block24();
} else { } else {
let b26 = component(\`BundlesList\`, {bundles: ctx['bundles'].sticky, category_custom_views: ctx['category_custom_views'], search: ctx['search']}, key + \`__2\`, node, ctx); const b26 = component(\`BundlesList\`, {bundles: ctx['bundles'].sticky, category_custom_views: ctx['category_custom_views'], search: ctx['search']}, key + \`__2\`, node, ctx);
let b27 = component(\`BundlesList\`, {bundles: ctx['bundles'].dev, search: ctx['search']}, key + \`__3\`, node, ctx); const b27 = component(\`BundlesList\`, {bundles: ctx['bundles'].dev, search: ctx['search']}, key + \`__3\`, node, ctx);
b25 = block25([], [b26, b27]); b25 = block25([], [b26, b27]);
} }
return block1([attr1, txt1, hdlr2, hdlr3, attr8, hdlr4, hdlr5, ref1, hdlr6, ref2], [b2, b4, b14, b17, b22, b23, b24, b25]); return block1([attr1, txt1, hdlr2, hdlr3, attr8, hdlr4, hdlr5, ref1, hdlr6, ref2], [b2, b4, b14, b17, b22, b23, b24, b25]);
@@ -10,14 +10,14 @@ exports[`memory t-foreach does not leak stuff in global scope 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList([3,2,1]); const [k_block2, v_block2, l_block2, c_block2] = prepareList([3,2,1]);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1]; ctx[\`item\`] = v_block2[i1];
ctx[\`item_index\`] = i1; ctx[\`item_index\`] = i1;
let key1 = ctx['item_index']; const key1 = ctx['item_index'];
c_block2[i1] = withKey(text(ctx['item']), key1); c_block2[i1] = withKey(text(ctx['item']), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -211,8 +211,8 @@ exports[`simple templates, mostly static multiple root nodes 1`] = `
let block3 = createBlock(\`<span>hey</span>\`); let block3 = createBlock(\`<span>hey</span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = block2(); const b2 = block2();
let b3 = block3(); const b3 = block3();
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -246,8 +246,8 @@ exports[`simple templates, mostly static static text and dynamic text (no t tag)
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(\`hello \`); const b2 = text(\`hello \`);
let b3 = text(ctx['text']); const b3 = text(ctx['text']);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -259,8 +259,8 @@ exports[`simple templates, mostly static static text and dynamic text 1`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(\`hello \`); const b2 = text(\`hello \`);
let b3 = text(ctx['text']); const b3 = text(ctx['text']);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -347,8 +347,8 @@ exports[`simple templates, mostly static two t-escs next to each other 1`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(ctx['text1']); const b2 = text(ctx['text1']);
let b3 = text(ctx['text2']); const b3 = text(ctx['text2']);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -360,8 +360,8 @@ exports[`simple templates, mostly static two t-escs next to each other 2`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(ctx['text1']); const b2 = text(ctx['text1']);
let b3 = text(ctx['text2']); const b3 = text(ctx['text2']);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -66,7 +66,7 @@ exports[`properly support svg svg creates new block if it is within html -- 2 1`
if (ctx['hasPath']) { if (ctx['hasPath']) {
b3 = block3(); b3 = block3();
} }
let b2 = block2([], [b3]); const b2 = block2([], [b3]);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -81,7 +81,7 @@ exports[`properly support svg svg creates new block if it is within html 1`] = `
let block2 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><polygon fill=\\"#000000\\" points=\\"0 0 4 4 8 0\\" transform=\\"translate(5 7)\\"/></svg>\`); let block2 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><polygon fill=\\"#000000\\" points=\\"0 0 4 4 8 0\\" transform=\\"translate(5 7)\\"/></svg>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = block2(); const b2 = block2();
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -97,7 +97,7 @@ exports[`properly support svg svg namespace added to sub templates if root tag i
let block1 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><block-child-0/></svg>\`); let block1 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><block-child-0/></svg>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -10,7 +10,7 @@ exports[`t-call (template calling) basic caller 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -69,12 +69,12 @@ exports[`t-call (template calling) call with several sub nodes on same line 1`]
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b3 = block3(); const b3 = block3();
let b4 = text(\` \`); const b4 = text(\` \`);
let b5 = block5(); const b5 = block5();
let b2 = multi([b3, b4, b5]); const b2 = multi([b3, b4, b5]);
ctx[zero] = b2; ctx[zero] = b2;
let b6 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b6 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b6]); return block1([], [b6]);
} }
}" }"
@@ -89,7 +89,7 @@ exports[`t-call (template calling) call with several sub nodes on same line 2`]
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = ctx[zero]; const b2 = ctx[zero];
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -109,12 +109,12 @@ exports[`t-call (template calling) cascading t-call t-out='0' 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b3 = block3(); const b3 = block3();
let b4 = text(\` \`); const b4 = text(\` \`);
let b5 = block5(); const b5 = block5();
let b2 = multi([b3, b4, b5]); const b2 = multi([b3, b4, b5]);
ctx[zero] = b2; ctx[zero] = b2;
let b6 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b6 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b6]); return block1([], [b6]);
} }
}" }"
@@ -133,11 +133,11 @@ exports[`t-call (template calling) cascading t-call t-out='0' 2`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b3 = block3(); const b3 = block3();
let b4 = ctx[zero]; const b4 = ctx[zero];
let b2 = multi([b3, b4]); const b2 = multi([b3, b4]);
ctx[zero] = b2; ctx[zero] = b2;
let b5 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b5 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b5]); return block1([], [b5]);
} }
}" }"
@@ -156,11 +156,11 @@ exports[`t-call (template calling) cascading t-call t-out='0' 3`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b3 = block3(); const b3 = block3();
let b4 = ctx[zero]; const b4 = ctx[zero];
let b2 = multi([b3, b4]); const b2 = multi([b3, b4]);
ctx[zero] = b2; ctx[zero] = b2;
let b5 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b5 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b5]); return block1([], [b5]);
} }
}" }"
@@ -175,7 +175,7 @@ exports[`t-call (template calling) cascading t-call t-out='0' 4`] = `
let block1 = createBlock(\`<div><span>cascade 2</span><block-child-0/></div>\`); let block1 = createBlock(\`<div><span>cascade 2</span><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = ctx[zero]; const b2 = ctx[zero];
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -194,10 +194,10 @@ exports[`t-call (template calling) cascading t-call t-out='0', without external
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b2 = block2(); const b2 = block2();
let b3 = text(\` \`); const b3 = text(\` \`);
let b4 = block4(); const b4 = block4();
let b1 = multi([b2, b3, b4]); const b1 = multi([b2, b3, b4]);
ctx[zero] = b1; ctx[zero] = b1;
return callTemplate_1.call(this, ctx, node, key + \`__1\`); return callTemplate_1.call(this, ctx, node, key + \`__1\`);
} }
@@ -216,9 +216,9 @@ exports[`t-call (template calling) cascading t-call t-out='0', without external
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b2 = block2(); const b2 = block2();
let b3 = ctx[zero]; const b3 = ctx[zero];
let b1 = multi([b2, b3]); const b1 = multi([b2, b3]);
ctx[zero] = b1; ctx[zero] = b1;
return callTemplate_1.call(this, ctx, node, key + \`__1\`); return callTemplate_1.call(this, ctx, node, key + \`__1\`);
} }
@@ -237,9 +237,9 @@ exports[`t-call (template calling) cascading t-call t-out='0', without external
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b2 = block2(); const b2 = block2();
let b3 = ctx[zero]; const b3 = ctx[zero];
let b1 = multi([b2, b3]); const b1 = multi([b2, b3]);
ctx[zero] = b1; ctx[zero] = b1;
return callTemplate_1.call(this, ctx, node, key + \`__1\`); return callTemplate_1.call(this, ctx, node, key + \`__1\`);
} }
@@ -255,8 +255,8 @@ exports[`t-call (template calling) cascading t-call t-out='0', without external
let block2 = createBlock(\`<span>cascade 2</span>\`); let block2 = createBlock(\`<span>cascade 2</span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = block2(); const b2 = block2();
let b3 = ctx[zero]; const b3 = ctx[zero];
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -272,7 +272,7 @@ exports[`t-call (template calling) dynamic t-call 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const template1 = (ctx['template']); const template1 = (ctx['template']);
let b2 = call(this, template1, ctx, node, key + \`__1\`); const b2 = call(this, template1, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -319,7 +319,7 @@ exports[`t-call (template calling) inherit context 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"foo\\", 1); setContextValue(ctx, \\"foo\\", 1);
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -370,7 +370,7 @@ exports[`t-call (template calling) recursive template, part 2 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"node\\", ctx['root']); setContextValue(ctx, \\"node\\", ctx['root']);
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -390,21 +390,21 @@ exports[`t-call (template calling) recursive template, part 2 2`] = `
ctx[isBoundary] = 1 ctx[isBoundary] = 1
let txt1 = ctx['node'].val; let txt1 = ctx['node'].val;
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['node'].children||[]); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['node'].children||[]);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`subtree\`] = v_block2[i1]; ctx[\`subtree\`] = v_block2[i1];
ctx[\`subtree_first\`] = i1 === 0; ctx[\`subtree_first\`] = i1 === 0;
ctx[\`subtree_last\`] = i1 === v_block2.length - 1; ctx[\`subtree_last\`] = i1 === v_block2.length - 1;
ctx[\`subtree_index\`] = i1; ctx[\`subtree_index\`] = i1;
ctx[\`subtree_value\`] = k_block2[i1]; ctx[\`subtree_value\`] = k_block2[i1];
let key1 = ctx['subtree_index']; const key1 = ctx['subtree_index'];
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"node\\", ctx['subtree']); setContextValue(ctx, \\"node\\", ctx['subtree']);
c_block2[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1); c_block2[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1);
ctx = ctx.__proto__; ctx = ctx.__proto__;
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([txt1], [b2]); return block1([txt1], [b2]);
} }
}" }"
@@ -425,7 +425,7 @@ exports[`t-call (template calling) recursive template, part 3 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"node\\", ctx['root']); setContextValue(ctx, \\"node\\", ctx['root']);
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -445,21 +445,21 @@ exports[`t-call (template calling) recursive template, part 3 2`] = `
ctx[isBoundary] = 1 ctx[isBoundary] = 1
let txt1 = ctx['node'].val; let txt1 = ctx['node'].val;
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['node'].children||[]); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['node'].children||[]);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`subtree\`] = v_block2[i1]; ctx[\`subtree\`] = v_block2[i1];
ctx[\`subtree_first\`] = i1 === 0; ctx[\`subtree_first\`] = i1 === 0;
ctx[\`subtree_last\`] = i1 === v_block2.length - 1; ctx[\`subtree_last\`] = i1 === v_block2.length - 1;
ctx[\`subtree_index\`] = i1; ctx[\`subtree_index\`] = i1;
ctx[\`subtree_value\`] = k_block2[i1]; ctx[\`subtree_value\`] = k_block2[i1];
let key1 = ctx['subtree_index']; const key1 = ctx['subtree_index'];
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"node\\", ctx['subtree']); setContextValue(ctx, \\"node\\", ctx['subtree']);
c_block2[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1); c_block2[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1);
ctx = ctx.__proto__; ctx = ctx.__proto__;
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([txt1], [b2]); return block1([txt1], [b2]);
} }
}" }"
@@ -481,7 +481,7 @@ exports[`t-call (template calling) recursive template, part 4: with t-set recurs
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"recursive_idx\\", 1); setContextValue(ctx, \\"recursive_idx\\", 1);
setContextValue(ctx, \\"node\\", ctx['root']); setContextValue(ctx, \\"node\\", ctx['root']);
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -503,21 +503,21 @@ exports[`t-call (template calling) recursive template, part 4: with t-set recurs
let txt1 = ctx['node'].val; let txt1 = ctx['node'].val;
let txt2 = ctx['recursive_idx']; let txt2 = ctx['recursive_idx'];
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['node'].children||[]); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['node'].children||[]);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`subtree\`] = v_block2[i1]; ctx[\`subtree\`] = v_block2[i1];
ctx[\`subtree_first\`] = i1 === 0; ctx[\`subtree_first\`] = i1 === 0;
ctx[\`subtree_last\`] = i1 === v_block2.length - 1; ctx[\`subtree_last\`] = i1 === v_block2.length - 1;
ctx[\`subtree_index\`] = i1; ctx[\`subtree_index\`] = i1;
ctx[\`subtree_value\`] = k_block2[i1]; ctx[\`subtree_value\`] = k_block2[i1];
let key1 = ctx['subtree_index']; const key1 = ctx['subtree_index'];
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"node\\", ctx['subtree']); setContextValue(ctx, \\"node\\", ctx['subtree']);
c_block2[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1); c_block2[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1);
ctx = ctx.__proto__; ctx = ctx.__proto__;
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([txt1, txt2], [b2]); return block1([txt1, txt2], [b2]);
} }
}" }"
@@ -538,7 +538,7 @@ exports[`t-call (template calling) scoped parameters 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"foo\\", 42); setContextValue(ctx, \\"foo\\", 42);
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
ctx = ctx.__proto__; ctx = ctx.__proto__;
let txt1 = ctx['foo']; let txt1 = ctx['foo'];
return block1([txt1], [b2]); return block1([txt1], [b2]);
@@ -573,7 +573,7 @@ exports[`t-call (template calling) scoped parameters, part 2 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"foo\\", 42); setContextValue(ctx, \\"foo\\", 42);
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
ctx = ctx.__proto__; ctx = ctx.__proto__;
let txt1 = ctx['foo']; let txt1 = ctx['foo'];
return block1([txt1], [b2]); return block1([txt1], [b2]);
@@ -602,7 +602,7 @@ exports[`t-call (template calling) t-call allowed on a non t node 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -633,7 +633,7 @@ exports[`t-call (template calling) t-call with body content as root of a templat
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b1 = block1(); const b1 = block1();
ctx[zero] = b1; ctx[zero] = b1;
return callTemplate_1.call(this, ctx, node, key + \`__1\`); return callTemplate_1.call(this, ctx, node, key + \`__1\`);
} }
@@ -649,7 +649,7 @@ exports[`t-call (template calling) t-call with body content as root of a templat
let block1 = createBlock(\`<foo><block-child-0/></foo>\`); let block1 = createBlock(\`<foo><block-child-0/></foo>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = ctx[zero]; const b2 = ctx[zero];
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -702,7 +702,7 @@ exports[`t-call (template calling) t-call with t-set inside and body text conten
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"val\\", \`yip yip\`); setContextValue(ctx, \\"val\\", \`yip yip\`);
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -735,14 +735,14 @@ exports[`t-call (template calling) t-call with t-set inside and outside 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['list']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['list']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`v\`] = v_block2[i1]; ctx[\`v\`] = v_block2[i1];
ctx[\`v_first\`] = i1 === 0; ctx[\`v_first\`] = i1 === 0;
ctx[\`v_last\`] = i1 === v_block2.length - 1; ctx[\`v_last\`] = i1 === v_block2.length - 1;
ctx[\`v_index\`] = i1; ctx[\`v_index\`] = i1;
ctx[\`v_value\`] = k_block2[i1]; ctx[\`v_value\`] = k_block2[i1];
let key1 = ctx['v_index']; const key1 = ctx['v_index'];
setContextValue(ctx, \\"val\\", ctx['v'].val); setContextValue(ctx, \\"val\\", ctx['v'].val);
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
@@ -750,7 +750,7 @@ exports[`t-call (template calling) t-call with t-set inside and outside 1`] = `
c_block2[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1); c_block2[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1);
ctx = ctx.__proto__; ctx = ctx.__proto__;
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -783,7 +783,7 @@ exports[`t-call (template calling) t-call with t-set inside and outside. 2 1`] =
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"w\\", 'fromwrapper'); setContextValue(ctx, \\"w\\", 'fromwrapper');
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -802,14 +802,14 @@ exports[`t-call (template calling) t-call with t-set inside and outside. 2 2`] =
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['list']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['list']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`v\`] = v_block2[i1]; ctx[\`v\`] = v_block2[i1];
ctx[\`v_first\`] = i1 === 0; ctx[\`v_first\`] = i1 === 0;
ctx[\`v_last\`] = i1 === v_block2.length - 1; ctx[\`v_last\`] = i1 === v_block2.length - 1;
ctx[\`v_index\`] = i1; ctx[\`v_index\`] = i1;
ctx[\`v_value\`] = k_block2[i1]; ctx[\`v_value\`] = k_block2[i1];
let key1 = ctx['v_index']; const key1 = ctx['v_index'];
setContextValue(ctx, \\"val\\", ctx['v'].val); setContextValue(ctx, \\"val\\", ctx['v'].val);
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
@@ -817,7 +817,7 @@ exports[`t-call (template calling) t-call with t-set inside and outside. 2 2`] =
c_block2[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1); c_block2[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1);
ctx = ctx.__proto__; ctx = ctx.__proto__;
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -832,8 +832,8 @@ exports[`t-call (template calling) t-call with t-set inside and outside. 2 3`] =
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['val3']; let txt1 = ctx['val3'];
let b2 = block2([txt1]); const b2 = block2([txt1]);
let b3 = text(ctx['w']); const b3 = text(ctx['w']);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -908,7 +908,7 @@ exports[`t-call (template calling) t-esc inside t-call, with t-set outside 1`] =
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"v\\", \`Hi\`); setContextValue(ctx, \\"v\\", \`Hi\`);
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -938,7 +938,7 @@ exports[`t-call (template calling) with unused body 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b1 = text(\`WHEEE\`); const b1 = text(\`WHEEE\`);
ctx[zero] = b1; ctx[zero] = b1;
return callTemplate_1.call(this, ctx, node, key + \`__1\`); return callTemplate_1.call(this, ctx, node, key + \`__1\`);
} }
@@ -999,7 +999,7 @@ exports[`t-call (template calling) with used body 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b1 = text(\`ok\`); const b1 = text(\`ok\`);
ctx[zero] = b1; ctx[zero] = b1;
return callTemplate_1.call(this, ctx, node, key + \`__1\`); return callTemplate_1.call(this, ctx, node, key + \`__1\`);
} }
@@ -1036,7 +1036,7 @@ exports[`t-call (template calling) with used setbody 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"foo\\", 'ok'); setContextValue(ctx, \\"foo\\", 'ok');
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -44,7 +44,7 @@ exports[`debugging t-debug on sub template 2`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
+11 -11
View File
@@ -82,15 +82,15 @@ exports[`t-esc falsy values in text nodes 1`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(ctx['v1']); const b2 = text(ctx['v1']);
let b3 = text(\`:\`); const b3 = text(\`:\`);
let b4 = text(ctx['v2']); const b4 = text(ctx['v2']);
let b5 = text(\`:\`); const b5 = text(\`:\`);
let b6 = text(ctx['v3']); const b6 = text(ctx['v3']);
let b7 = text(\`:\`); const b7 = text(\`:\`);
let b8 = text(ctx['v4']); const b8 = text(ctx['v4']);
let b9 = text(\`:\`); const b9 = text(\`:\`);
let b10 = text(ctx['v5']); const b10 = text(ctx['v5']);
return multi([b2, b3, b4, b5, b6, b7, b8, b9, b10]); return multi([b2, b3, b4, b5, b6, b7, b8, b9, b10]);
} }
}" }"
@@ -160,9 +160,9 @@ exports[`t-esc t-esc=0 is escaped 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b2 = block2(); const b2 = block2();
ctx[zero] = b2; ctx[zero] = b2;
let b3 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b3 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -10,13 +10,13 @@ exports[`t-foreach does not pollute the rendering context 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList([1]); const [k_block2, v_block2, l_block2, c_block2] = prepareList([1]);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1]; ctx[\`item\`] = v_block2[i1];
let key1 = ctx['item']; const key1 = ctx['item'];
c_block2[i1] = withKey(text(ctx['item']), key1); c_block2[i1] = withKey(text(ctx['item']), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -33,14 +33,14 @@ exports[`t-foreach iterate on items (on a element node) 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList([1,2]); const [k_block2, v_block2, l_block2, c_block2] = prepareList([1,2]);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1]; ctx[\`item\`] = v_block2[i1];
let key1 = ctx['item']; const key1 = ctx['item'];
let txt1 = ctx['item']; let txt1 = ctx['item'];
c_block2[i1] = withKey(block3([txt1]), key1); c_block2[i1] = withKey(block3([txt1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -56,22 +56,22 @@ exports[`t-foreach iterate on items 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList([3,2,1]); const [k_block2, v_block2, l_block2, c_block2] = prepareList([3,2,1]);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1]; ctx[\`item\`] = v_block2[i1];
ctx[\`item_index\`] = i1; ctx[\`item_index\`] = i1;
ctx[\`item_value\`] = k_block2[i1]; ctx[\`item_value\`] = k_block2[i1];
let key1 = ctx['item']; const key1 = ctx['item'];
let b4 = text(\` [\`); const b4 = text(\` [\`);
let b5 = text(ctx['item_index']); const b5 = text(ctx['item_index']);
let b6 = text(\`: \`); const b6 = text(\`: \`);
let b7 = text(ctx['item']); const b7 = text(ctx['item']);
let b8 = text(\` \`); const b8 = text(\` \`);
let b9 = text(ctx['item_value']); const b9 = text(ctx['item_value']);
let b10 = text(\`] \`); const b10 = text(\`] \`);
c_block2[i1] = withKey(multi([b4, b5, b6, b7, b8, b9, b10]), key1); c_block2[i1] = withKey(multi([b4, b5, b6, b7, b8, b9, b10]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -87,22 +87,22 @@ exports[`t-foreach iterate, dict param 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['value']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['value']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1]; ctx[\`item\`] = v_block2[i1];
ctx[\`item_index\`] = i1; ctx[\`item_index\`] = i1;
ctx[\`item_value\`] = k_block2[i1]; ctx[\`item_value\`] = k_block2[i1];
let key1 = ctx['item_index']; const key1 = ctx['item_index'];
let b4 = text(\` [\`); const b4 = text(\` [\`);
let b5 = text(ctx['item_index']); const b5 = text(ctx['item_index']);
let b6 = text(\`: \`); const b6 = text(\`: \`);
let b7 = text(ctx['item']); const b7 = text(ctx['item']);
let b8 = text(\` \`); const b8 = text(\` \`);
let b9 = text(ctx['item_value']); const b9 = text(ctx['item_value']);
let b10 = text(\`] \`); const b10 = text(\`] \`);
c_block2[i1] = withKey(multi([b4, b5, b6, b7, b8, b9, b10]), key1); c_block2[i1] = withKey(multi([b4, b5, b6, b7, b8, b9, b10]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -118,13 +118,13 @@ exports[`t-foreach iterate, position 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(Array(5)); const [k_block2, v_block2, l_block2, c_block2] = prepareList(Array(5));;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`elem\`] = v_block2[i1]; ctx[\`elem\`] = v_block2[i1];
ctx[\`elem_first\`] = i1 === 0; ctx[\`elem_first\`] = i1 === 0;
ctx[\`elem_last\`] = i1 === v_block2.length - 1; ctx[\`elem_last\`] = i1 === v_block2.length - 1;
ctx[\`elem_index\`] = i1; ctx[\`elem_index\`] = i1;
let key1 = ctx['elem']; const key1 = ctx['elem'];
let b4,b5,b6,b7,b8,b9; let b4,b5,b6,b7,b8,b9;
b4 = text(\` -\`); b4 = text(\` -\`);
if (ctx['elem_first']) { if (ctx['elem_first']) {
@@ -138,7 +138,7 @@ exports[`t-foreach iterate, position 1`] = `
b9 = text(\`) \`); b9 = text(\`) \`);
c_block2[i1] = withKey(multi([b4, b5, b6, b7, b8, b9]), key1); c_block2[i1] = withKey(multi([b4, b5, b6, b7, b8, b9]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -154,13 +154,13 @@ exports[`t-foreach simple iteration (in a node) 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList([3,2,1]); const [k_block2, v_block2, l_block2, c_block2] = prepareList([3,2,1]);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1]; ctx[\`item\`] = v_block2[i1];
let key1 = ctx['item']; const key1 = ctx['item'];
c_block2[i1] = withKey(text(ctx['item']), key1); c_block2[i1] = withKey(text(ctx['item']), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -174,10 +174,10 @@ exports[`t-foreach simple iteration 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList([3,2,1]); const [k_block1, v_block1, l_block1, c_block1] = prepareList([3,2,1]);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`item\`] = v_block1[i1]; ctx[\`item\`] = v_block1[i1];
let key1 = ctx['item']; const key1 = ctx['item'];
c_block1[i1] = withKey(text(ctx['item']), key1); c_block1[i1] = withKey(text(ctx['item']), key1);
} }
return list(c_block1); return list(c_block1);
@@ -196,14 +196,14 @@ exports[`t-foreach simple iteration with two nodes inside 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList([3,2,1]); const [k_block1, v_block1, l_block1, c_block1] = prepareList([3,2,1]);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`item\`] = v_block1[i1]; ctx[\`item\`] = v_block1[i1];
let key1 = ctx['item']; const key1 = ctx['item'];
let txt1 = ctx['item']; let txt1 = ctx['item'];
let b3 = block3([txt1]); const b3 = block3([txt1]);
let txt2 = ctx['item']; let txt2 = ctx['item'];
let b4 = block4([txt2]); const b4 = block4([txt2]);
c_block1[i1] = withKey(multi([b3, b4]), key1); c_block1[i1] = withKey(multi([b3, b4]), key1);
} }
return list(c_block1); return list(c_block1);
@@ -225,23 +225,23 @@ exports[`t-foreach t-call with body in t-foreach in t-foreach 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['numbers']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['numbers']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`a\`] = v_block2[i1]; ctx[\`a\`] = v_block2[i1];
ctx[\`a_first\`] = i1 === 0; ctx[\`a_first\`] = i1 === 0;
ctx[\`a_last\`] = i1 === v_block2.length - 1; ctx[\`a_last\`] = i1 === v_block2.length - 1;
ctx[\`a_index\`] = i1; ctx[\`a_index\`] = i1;
ctx[\`a_value\`] = k_block2[i1]; ctx[\`a_value\`] = k_block2[i1];
let key1 = ctx['a']; const key1 = ctx['a'];
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['letters']); const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['letters']);;
for (let i2 = 0; i2 < l_block4; i2++) { for (let i2 = 0; i2 < l_block4; i2++) {
ctx[\`b\`] = v_block4[i2]; ctx[\`b\`] = v_block4[i2];
ctx[\`b_first\`] = i2 === 0; ctx[\`b_first\`] = i2 === 0;
ctx[\`b_last\`] = i2 === v_block4.length - 1; ctx[\`b_last\`] = i2 === v_block4.length - 1;
ctx[\`b_index\`] = i2; ctx[\`b_index\`] = i2;
ctx[\`b_value\`] = k_block4[i2]; ctx[\`b_value\`] = k_block4[i2];
let key2 = ctx['b']; const key2 = ctx['b'];
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"c\\", 'x'+'_'+ctx['a']+'_'+ctx['b']); setContextValue(ctx, \\"c\\", 'x'+'_'+ctx['a']+'_'+ctx['b']);
@@ -249,13 +249,13 @@ exports[`t-foreach t-call with body in t-foreach in t-foreach 1`] = `
ctx = ctx.__proto__; ctx = ctx.__proto__;
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b4 = list(c_block4); const b4 = list(c_block4);
let txt1 = ctx['c']; let txt1 = ctx['c'];
let b6 = block6([txt1]); const b6 = block6([txt1]);
c_block2[i1] = withKey(multi([b4, b6]), key1); c_block2[i1] = withKey(multi([b4, b6]), key1);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b2 = list(c_block2); const b2 = list(c_block2);
let txt2 = ctx['a']; let txt2 = ctx['a'];
let txt3 = ctx['b']; let txt3 = ctx['b'];
let txt4 = ctx['c']; let txt4 = ctx['c'];
@@ -270,13 +270,13 @@ exports[`t-foreach t-call with body in t-foreach in t-foreach 2`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(\` [\`); const b2 = text(\` [\`);
let b3 = text(ctx['a']); const b3 = text(ctx['a']);
let b4 = text(\`] [\`); const b4 = text(\`] [\`);
let b5 = text(ctx['b']); const b5 = text(ctx['b']);
let b6 = text(\`] [\`); const b6 = text(\`] [\`);
let b7 = text(ctx['c']); const b7 = text(ctx['c']);
let b8 = text(\`] \`); const b8 = text(\`] \`);
return multi([b2, b3, b4, b5, b6, b7, b8]); return multi([b2, b3, b4, b5, b6, b7, b8]);
} }
}" }"
@@ -294,33 +294,33 @@ exports[`t-foreach t-call without body in t-foreach in t-foreach 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['numbers']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['numbers']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`a\`] = v_block2[i1]; ctx[\`a\`] = v_block2[i1];
ctx[\`a_first\`] = i1 === 0; ctx[\`a_first\`] = i1 === 0;
ctx[\`a_last\`] = i1 === v_block2.length - 1; ctx[\`a_last\`] = i1 === v_block2.length - 1;
ctx[\`a_index\`] = i1; ctx[\`a_index\`] = i1;
ctx[\`a_value\`] = k_block2[i1]; ctx[\`a_value\`] = k_block2[i1];
let key1 = ctx['a']; const key1 = ctx['a'];
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['letters']); const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['letters']);;
for (let i2 = 0; i2 < l_block4; i2++) { for (let i2 = 0; i2 < l_block4; i2++) {
ctx[\`b\`] = v_block4[i2]; ctx[\`b\`] = v_block4[i2];
ctx[\`b_first\`] = i2 === 0; ctx[\`b_first\`] = i2 === 0;
ctx[\`b_last\`] = i2 === v_block4.length - 1; ctx[\`b_last\`] = i2 === v_block4.length - 1;
ctx[\`b_index\`] = i2; ctx[\`b_index\`] = i2;
ctx[\`b_value\`] = k_block4[i2]; ctx[\`b_value\`] = k_block4[i2];
let key2 = ctx['b']; const key2 = ctx['b'];
c_block4[i2] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}__\${key2}\`), key2); c_block4[i2] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}__\${key2}\`), key2);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b4 = list(c_block4); const b4 = list(c_block4);
let txt1 = ctx['c']; let txt1 = ctx['c'];
let b6 = block6([txt1]); const b6 = block6([txt1]);
c_block2[i1] = withKey(multi([b4, b6]), key1); c_block2[i1] = withKey(multi([b4, b6]), key1);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b2 = list(c_block2); const b2 = list(c_block2);
let txt2 = ctx['a']; let txt2 = ctx['a'];
let txt3 = ctx['b']; let txt3 = ctx['b'];
let txt4 = ctx['c']; let txt4 = ctx['c'];
@@ -339,13 +339,13 @@ exports[`t-foreach t-call without body in t-foreach in t-foreach 2`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"c\\", 'x'+'_'+ctx['a']+'_'+ctx['b']); setContextValue(ctx, \\"c\\", 'x'+'_'+ctx['a']+'_'+ctx['b']);
let b2 = text(\` [\`); const b2 = text(\` [\`);
let b3 = text(ctx['a']); const b3 = text(ctx['a']);
let b4 = text(\`] [\`); const b4 = text(\`] [\`);
let b5 = text(ctx['b']); const b5 = text(ctx['b']);
let b6 = text(\`] [\`); const b6 = text(\`] [\`);
let b7 = text(ctx['c']); const b7 = text(ctx['c']);
let b8 = text(\`] \`); const b8 = text(\`] \`);
return multi([b2, b3, b4, b5, b6, b7, b8]); return multi([b2, b3, b4, b5, b6, b7, b8]);
} }
}" }"
@@ -361,25 +361,25 @@ exports[`t-foreach t-foreach in t-foreach 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['numbers']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['numbers']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`number\`] = v_block2[i1]; ctx[\`number\`] = v_block2[i1];
let key1 = ctx['number']; const key1 = ctx['number'];
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block3, v_block3, l_block3, c_block3] = prepareList(ctx['letters']); const [k_block3, v_block3, l_block3, c_block3] = prepareList(ctx['letters']);;
for (let i2 = 0; i2 < l_block3; i2++) { for (let i2 = 0; i2 < l_block3; i2++) {
ctx[\`letter\`] = v_block3[i2]; ctx[\`letter\`] = v_block3[i2];
let key2 = ctx['letter']; const key2 = ctx['letter'];
let b5 = text(\` [\`); const b5 = text(\` [\`);
let b6 = text(ctx['number']); const b6 = text(ctx['number']);
let b7 = text(ctx['letter']); const b7 = text(ctx['letter']);
let b8 = text(\`] \`); const b8 = text(\`] \`);
c_block3[i2] = withKey(multi([b5, b6, b7, b8]), key2); c_block3[i2] = withKey(multi([b5, b6, b7, b8]), key2);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
c_block2[i1] = withKey(list(c_block3), key1); c_block2[i1] = withKey(list(c_block3), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -395,10 +395,10 @@ exports[`t-foreach t-foreach with t-if inside (no external node) 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['elems']); const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['elems']);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`elem\`] = v_block1[i1]; ctx[\`elem\`] = v_block1[i1];
let key1 = ctx['elem'].id; const key1 = ctx['elem'].id;
let b3; let b3;
if (ctx['elem'].id<3) { if (ctx['elem'].id<3) {
let txt1 = ctx['elem'].text; let txt1 = ctx['elem'].text;
@@ -422,10 +422,10 @@ exports[`t-foreach t-foreach with t-if inside 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['elems']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['elems']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`elem\`] = v_block2[i1]; ctx[\`elem\`] = v_block2[i1];
let key1 = ctx['elem'].id; const key1 = ctx['elem'].id;
let b4; let b4;
if (ctx['elem'].id<3) { if (ctx['elem'].id<3) {
let txt1 = ctx['elem'].text; let txt1 = ctx['elem'].text;
@@ -433,7 +433,7 @@ exports[`t-foreach t-foreach with t-if inside 1`] = `
} }
c_block2[i1] = withKey(multi([b4]), key1); c_block2[i1] = withKey(multi([b4]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -450,13 +450,13 @@ exports[`t-foreach t-key on t-foreach 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['things']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['things']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`thing\`] = v_block2[i1]; ctx[\`thing\`] = v_block2[i1];
let key1 = ctx['thing']; const key1 = ctx['thing'];
c_block2[i1] = withKey(block3(), key1); c_block2[i1] = withKey(block3(), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -473,15 +473,15 @@ exports[`t-foreach throws error if invalid loop expression 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['abc']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['abc']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1]; ctx[\`item\`] = v_block2[i1];
ctx[\`item_index\`] = i1; ctx[\`item_index\`] = i1;
let key1 = ctx['item']; const key1 = ctx['item'];
const tKey_1 = ctx['item_index']; const tKey_1 = ctx['item_index'];
c_block2[i1] = withKey(block3(), tKey_1 + key1); c_block2[i1] = withKey(block3(), tKey_1 + key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -500,12 +500,12 @@ exports[`t-foreach with t-memo 1`] = `
let cache = ctx.cache || {}; let cache = ctx.cache || {};
let nextCache = ctx.cache = {}; let nextCache = ctx.cache = {};
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1]; ctx[\`item\`] = v_block2[i1];
let key1 = ctx['item'].id; const key1 = ctx['item'].id;
let memo1 = [ctx['item'].x] const memo1 = [ctx['item'].x];
let vnode1 = cache[key1]; const vnode1 = cache[key1];;
if (vnode1) { if (vnode1) {
if (shallowEqual(vnode1.memo, memo1)) { if (shallowEqual(vnode1.memo, memo1)) {
c_block2[i1] = vnode1; c_block2[i1] = vnode1;
@@ -518,7 +518,7 @@ exports[`t-foreach with t-memo 1`] = `
c_block2[i1] = withKey(block3([txt1, txt2]), key1); c_block2[i1] = withKey(block3([txt1, txt2]), key1);
nextCache[key1] = Object.assign(c_block2[i1], {memo: memo1}); nextCache[key1] = Object.assign(c_block2[i1], {memo: memo1});
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
+10 -10
View File
@@ -29,8 +29,8 @@ exports[`t-if a t-if with two inner nodes 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2; let b2;
if (ctx['condition']) { if (ctx['condition']) {
let b3 = block3(); const b3 = block3();
let b4 = block4(); const b4 = block4();
b2 = multi([b3, b4]); b2 = multi([b3, b4]);
} }
return multi([b2]); return multi([b2]);
@@ -187,8 +187,8 @@ exports[`t-if div containing a t-if with two inner nodes 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2; let b2;
if (ctx['condition']) { if (ctx['condition']) {
let b3 = block3(); const b3 = block3();
let b4 = block4(); const b4 = block4();
b2 = multi([b3, b4]); b2 = multi([b3, b4]);
} }
return block1([], [b2]); return block1([], [b2]);
@@ -208,8 +208,8 @@ exports[`t-if dynamic content after t-if with two children nodes 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2; let b2;
if (ctx['condition']) { if (ctx['condition']) {
let b3 = block3(); const b3 = block3();
let b4 = block4(); const b4 = block4();
b2 = multi([b3, b4]); b2 = multi([b3, b4]);
} }
let txt1 = ctx['text']; let txt1 = ctx['text'];
@@ -318,8 +318,8 @@ exports[`t-if t-if and t-else with two nodes 1`] = `
if (ctx['condition']) { if (ctx['condition']) {
b2 = text(\`1\`); b2 = text(\`1\`);
} else { } else {
let b4 = block4(); const b4 = block4();
let b5 = block5(); const b5 = block5();
b3 = multi([b4, b5]); b3 = multi([b4, b5]);
} }
return multi([b2, b3]); return multi([b2, b3]);
@@ -526,8 +526,8 @@ exports[`t-if two t-ifs next to each other 1`] = `
b2 = block2([txt1]); b2 = block2([txt1]);
} }
if (ctx['condition']) { if (ctx['condition']) {
let b4 = block4(); const b4 = block4();
let b5 = block5(); const b5 = block5();
b3 = multi([b4, b5]); b3 = multi([b4, b5]);
} }
return block1([], [b2, b3]); return block1([], [b2, b3]);
@@ -56,14 +56,14 @@ exports[`t-key t-key directive in a list 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['beers']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['beers']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`beer\`] = v_block2[i1]; ctx[\`beer\`] = v_block2[i1];
let key1 = ctx['beer'].id; const key1 = ctx['beer'].id;
let txt1 = ctx['beer'].name; let txt1 = ctx['beer'].name;
c_block2[i1] = withKey(block3([txt1]), key1); c_block2[i1] = withKey(block3([txt1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
+32 -32
View File
@@ -9,7 +9,7 @@ exports[`t-out literal 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput('ok'); const b2 = safeOutput('ok');
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -40,9 +40,9 @@ exports[`t-out multiple calls to t-out 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b2 = block2(); const b2 = block2();
ctx[zero] = b2; ctx[zero] = b2;
let b3 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b3 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -57,8 +57,8 @@ exports[`t-out multiple calls to t-out 2`] = `
let block1 = createBlock(\`<div><block-child-0/><div>Greeter</div><block-child-1/></div>\`); let block1 = createBlock(\`<div><block-child-0/><div>Greeter</div><block-child-1/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = ctx[zero]; const b2 = ctx[zero];
let b3 = ctx[zero]; const b3 = ctx[zero];
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
}" }"
@@ -73,7 +73,7 @@ exports[`t-out not escaping 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -92,9 +92,9 @@ exports[`t-out t-out 0 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b2 = block2(); const b2 = block2();
ctx[zero] = b2; ctx[zero] = b2;
let b3 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b3 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -109,7 +109,7 @@ exports[`t-out t-out 0 2`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = ctx[zero]; const b2 = ctx[zero];
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -124,7 +124,7 @@ exports[`t-out t-out and another sibling node 1`] = `
let block1 = createBlock(\`<span><span>hello</span><block-child-0/></span>\`); let block1 = createBlock(\`<span><span>hello</span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -147,7 +147,7 @@ exports[`t-out t-out bdom 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
ctx[\`var\`] = new LazyValue(value1, ctx, node); ctx[\`var\`] = new LazyValue(value1, ctx, node);
let b3 = safeOutput(ctx['var']); const b3 = safeOutput(ctx['var']);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -162,7 +162,7 @@ exports[`t-out t-out block 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['bdom']); const b2 = safeOutput(ctx['bdom']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -177,7 +177,7 @@ exports[`t-out t-out escaped 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -192,7 +192,7 @@ exports[`t-out t-out markedup 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -207,8 +207,8 @@ exports[`t-out t-out on a node with a body, as a default 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = text(\`nope\`); const b3 = text(\`nope\`);
let b2 = withDefault(safeOutput(ctx['var']), b3); const b2 = withDefault(safeOutput(ctx['var']), b3);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -224,8 +224,8 @@ exports[`t-out t-out on a node with a dom node in body, as a default 1`] = `
let block3 = createBlock(\`<div>nope</div>\`); let block3 = createBlock(\`<div>nope</div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = block3(); const b3 = block3();
let b2 = withDefault(safeOutput(ctx['var']), b3); const b2 = withDefault(safeOutput(ctx['var']), b3);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -240,7 +240,7 @@ exports[`t-out t-out switch escaped 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -255,7 +255,7 @@ exports[`t-out t-out switch escaped on markup 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -270,7 +270,7 @@ exports[`t-out t-out switch markup 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -297,10 +297,10 @@ exports[`t-out t-out switch markup on bdom 1`] = `
let b3,b5; let b3,b5;
ctx[\`bdom\`] = new LazyValue(value1, ctx, node); ctx[\`bdom\`] = new LazyValue(value1, ctx, node);
if (ctx['hasBdom']) { if (ctx['hasBdom']) {
let b4 = safeOutput(ctx['bdom']); const b4 = safeOutput(ctx['bdom']);
b3 = block3([], [b4]); b3 = block3([], [b4]);
} else { } else {
let b6 = safeOutput(ctx['var']); const b6 = safeOutput(ctx['var']);
b5 = block5([], [b6]); b5 = block5([], [b6]);
} }
return block1([], [b3, b5]); return block1([], [b3, b5]);
@@ -317,7 +317,7 @@ exports[`t-out t-out switch markup on escaped 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -344,7 +344,7 @@ exports[`t-out t-out with arbitrary object 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -359,7 +359,7 @@ exports[`t-out t-out with arbitrary object 2 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -374,7 +374,7 @@ exports[`t-out t-out with comment 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -401,7 +401,7 @@ exports[`t-out variable 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -416,7 +416,7 @@ exports[`t-out with a String class 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -431,7 +431,7 @@ exports[`t-out with an extended String class 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -446,7 +446,7 @@ exports[`t-raw is deprecated should warn 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -461,7 +461,7 @@ exports[`t-raw is deprecated t-out is actually called in t-raw's place 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['var']); const b2 = safeOutput(ctx['var']);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -41,7 +41,7 @@ exports[`t-ref ref in a t-call 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -94,17 +94,17 @@ exports[`t-ref refs in a loop 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const refs = ctx.__owl__.refs; const refs = ctx.__owl__.refs;
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1]; ctx[\`item\`] = v_block2[i1];
let key1 = ctx['item']; const key1 = ctx['item'];
const tKey_1 = ctx['item']; const tKey_1 = ctx['item'];
const v1 = ctx['item']; const v1 = ctx['item'];
let ref1 = (el) => refs[\`\${v1}\`] = el; let ref1 = (el) => refs[\`\${v1}\`] = el;
let txt1 = ctx['item']; let txt1 = ctx['item'];
c_block2[i1] = withKey(block3([ref1, txt1]), tKey_1 + key1); c_block2[i1] = withKey(block3([ref1, txt1]), tKey_1 + key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
+19 -19
View File
@@ -208,7 +208,7 @@ exports[`t-set t-set body is evaluated immediately 1`] = `
setContextValue(ctx, \\"v1\\", 'before'); setContextValue(ctx, \\"v1\\", 'before');
ctx[\`v2\`] = new LazyValue(value1, ctx, node); ctx[\`v2\`] = new LazyValue(value1, ctx, node);
setContextValue(ctx, \\"v1\\", 'after'); setContextValue(ctx, \\"v1\\", 'after');
let b3 = safeOutput(ctx['v2']); const b3 = safeOutput(ctx['v2']);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -228,7 +228,7 @@ exports[`t-set t-set can't alter from within callee 1`] = `
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"iter\\", 'source'); setContextValue(ctx, \\"iter\\", 'source');
let txt1 = ctx['iter']; let txt1 = ctx['iter'];
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
let txt2 = ctx['iter']; let txt2 = ctx['iter'];
return block1([txt1, txt2], [b2]); return block1([txt1, txt2], [b2]);
} }
@@ -271,7 +271,7 @@ exports[`t-set t-set can't alter in t-call body 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"iter\\", 'inCall'); setContextValue(ctx, \\"iter\\", 'inCall');
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
ctx = ctx.__proto__; ctx = ctx.__proto__;
let txt2 = ctx['iter']; let txt2 = ctx['iter'];
return block1([txt1, txt2], [b2]); return block1([txt1, txt2], [b2]);
@@ -349,16 +349,16 @@ exports[`t-set t-set outside modified in t-foreach 1`] = `
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"iter\\", 0); setContextValue(ctx, \\"iter\\", 0);
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(['a','b']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(['a','b']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1]; ctx[\`val\`] = v_block2[i1];
let key1 = ctx['val']; const key1 = ctx['val'];
let txt1 = ctx['iter']; let txt1 = ctx['iter'];
c_block2[i1] = withKey(block3([txt1]), key1); c_block2[i1] = withKey(block3([txt1]), key1);
setContextValue(ctx, \\"iter\\", ctx['iter']+1); setContextValue(ctx, \\"iter\\", ctx['iter']+1);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b2 = list(c_block2); const b2 = list(c_block2);
let txt2 = ctx['iter']; let txt2 = ctx['iter'];
return block1([txt2], [b2]); return block1([txt2], [b2]);
} }
@@ -379,16 +379,16 @@ exports[`t-set t-set outside modified in t-foreach increment-after operator 1`]
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"iter\\", 0); setContextValue(ctx, \\"iter\\", 0);
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(['a','b']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(['a','b']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1]; ctx[\`val\`] = v_block2[i1];
let key1 = ctx['val']; const key1 = ctx['val'];
let txt1 = ctx['iter']; let txt1 = ctx['iter'];
c_block2[i1] = withKey(block3([txt1]), key1); c_block2[i1] = withKey(block3([txt1]), key1);
setContextValue(ctx, \\"iter\\", ctx['iter']++); setContextValue(ctx, \\"iter\\", ctx['iter']++);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b2 = list(c_block2); const b2 = list(c_block2);
let txt2 = ctx['iter']; let txt2 = ctx['iter'];
return block1([txt2], [b2]); return block1([txt2], [b2]);
} }
@@ -409,16 +409,16 @@ exports[`t-set t-set outside modified in t-foreach increment-before operator 1`]
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"iter\\", 0); setContextValue(ctx, \\"iter\\", 0);
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(['a','b']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(['a','b']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1]; ctx[\`val\`] = v_block2[i1];
let key1 = ctx['val']; const key1 = ctx['val'];
let txt1 = ctx['iter']; let txt1 = ctx['iter'];
c_block2[i1] = withKey(block3([txt1]), key1); c_block2[i1] = withKey(block3([txt1]), key1);
setContextValue(ctx, \\"iter\\", ++ctx['iter']); setContextValue(ctx, \\"iter\\", ++ctx['iter']);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b2 = list(c_block2); const b2 = list(c_block2);
let txt2 = ctx['iter']; let txt2 = ctx['iter'];
return block1([txt2], [b2]); return block1([txt2], [b2]);
} }
@@ -439,16 +439,16 @@ exports[`t-set t-set should reuse variable if possible 1`] = `
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"v\\", 1); setContextValue(ctx, \\"v\\", 1);
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['list']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['list']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`elem\`] = v_block2[i1]; ctx[\`elem\`] = v_block2[i1];
ctx[\`elem_index\`] = i1; ctx[\`elem_index\`] = i1;
let key1 = ctx['elem_index']; const key1 = ctx['elem_index'];
let txt1 = ctx['v']; let txt1 = ctx['v'];
setContextValue(ctx, \\"v\\", ctx['elem']); setContextValue(ctx, \\"v\\", ctx['elem']);
c_block2[i1] = withKey(block3([txt1]), key1); c_block2[i1] = withKey(block3([txt1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -463,8 +463,8 @@ exports[`t-set t-set with content and sub t-esc 1`] = `
let block1 = createBlock(\`<div><block-text-0/></div>\`); let block1 = createBlock(\`<div><block-text-0/></div>\`);
function value1(ctx, node, key = \\"\\") { function value1(ctx, node, key = \\"\\") {
let b3 = text(ctx['beep']); const b3 = text(ctx['beep']);
let b4 = text(\` boop\`); const b4 = text(\` boop\`);
return multi([b3, b4]); return multi([b3, b4]);
} }
@@ -500,7 +500,7 @@ exports[`t-set t-set with t-value (falsy) and body 1`] = `
ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, node)); ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, node));
setContextValue(ctx, \\"v1\\", 'after'); setContextValue(ctx, \\"v1\\", 'after');
setContextValue(ctx, \\"v3\\", true); setContextValue(ctx, \\"v3\\", true);
let b3 = safeOutput(ctx['v2']); const b3 = safeOutput(ctx['v2']);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -528,7 +528,7 @@ exports[`t-set t-set with t-value (truthy) and body 1`] = `
ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, node)); ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, node));
setContextValue(ctx, \\"v1\\", 'after'); setContextValue(ctx, \\"v1\\", 'after');
setContextValue(ctx, \\"v3\\", false); setContextValue(ctx, \\"v3\\", false);
let b3 = safeOutput(ctx['v2']); const b3 = safeOutput(ctx['v2']);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
+13 -13
View File
@@ -8,7 +8,7 @@ exports[`qweb t-tag can fallback if falsy tag 1`] = `
let block1 = tag => createBlock(\`<\${tag || 'fallback'}/>\`); let block1 = tag => createBlock(\`<\${tag || 'fallback'}/>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let tag1 = ctx['tag']; const tag1 = ctx['tag'];
return toggler(tag1, block1(tag1)()); return toggler(tag1, block1(tag1)());
} }
}" }"
@@ -22,7 +22,7 @@ exports[`qweb t-tag can update 1`] = `
let block1 = tag => createBlock(\`<\${tag || 't'}/>\`); let block1 = tag => createBlock(\`<\${tag || 't'}/>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let tag1 = ctx['tag']; const tag1 = ctx['tag'];
return toggler(tag1, block1(tag1)()); return toggler(tag1, block1(tag1)());
} }
}" }"
@@ -36,7 +36,7 @@ exports[`qweb t-tag simple usecases 1`] = `
let block1 = tag => createBlock(\`<\${tag || 't'}/>\`); let block1 = tag => createBlock(\`<\${tag || 't'}/>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let tag1 = 'div'; const tag1 = 'div';
return toggler(tag1, block1(tag1)()); return toggler(tag1, block1(tag1)());
} }
}" }"
@@ -50,7 +50,7 @@ exports[`qweb t-tag simple usecases 2`] = `
let block1 = tag => createBlock(\`<\${tag || 't'}>text</\${tag || 't'}>\`); let block1 = tag => createBlock(\`<\${tag || 't'}>text</\${tag || 't'}>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let tag1 = ctx['tag']; const tag1 = ctx['tag'];
return toggler(tag1, block1(tag1)()); return toggler(tag1, block1(tag1)());
} }
}" }"
@@ -64,7 +64,7 @@ exports[`qweb t-tag with multiple attributes 1`] = `
let block1 = tag => createBlock(\`<\${tag || 't'} class=\\"blueberry\\" taste=\\"raspberry\\">gooseberry</\${tag || 't'}>\`); let block1 = tag => createBlock(\`<\${tag || 't'} class=\\"blueberry\\" taste=\\"raspberry\\">gooseberry</\${tag || 't'}>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let tag1 = ctx['tag']; const tag1 = ctx['tag'];
return toggler(tag1, block1(tag1)()); return toggler(tag1, block1(tag1)());
} }
}" }"
@@ -78,7 +78,7 @@ exports[`qweb t-tag with multiple child nodes 1`] = `
let block1 = tag => createBlock(\`<\${tag || 't'}> pear <span>apple</span> strawberry </\${tag || 't'}>\`); let block1 = tag => createBlock(\`<\${tag || 't'}> pear <span>apple</span> strawberry </\${tag || 't'}>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let tag1 = ctx['tag']; const tag1 = ctx['tag'];
return toggler(tag1, block1(tag1)()); return toggler(tag1, block1(tag1)());
} }
}" }"
@@ -93,9 +93,9 @@ exports[`qweb t-tag with multiple t-tag in same template 1`] = `
let block2 = tag => createBlock(\`<\${tag || 't'}>baz</\${tag || 't'}>\`); let block2 = tag => createBlock(\`<\${tag || 't'}>baz</\${tag || 't'}>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let tag1 = ctx['outer']; const tag1 = ctx['outer'];
let tag2 = ctx['inner']; const tag2 = ctx['inner'];
let b2 = toggler(tag2, block2(tag2)()); const b2 = toggler(tag2, block2(tag2)());
return toggler(tag1, block1(tag1)([], [b2])); return toggler(tag1, block1(tag1)([], [b2]));
} }
}" }"
@@ -110,10 +110,10 @@ exports[`qweb t-tag with multiple t-tag in same template, part 2 1`] = `
let block3 = tag => createBlock(\`<\${tag || 't'}>baz</\${tag || 't'}>\`); let block3 = tag => createBlock(\`<\${tag || 't'}>baz</\${tag || 't'}>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let tag1 = ctx['brother']; const tag1 = ctx['brother'];
let b2 = toggler(tag1, block2(tag1)()); const b2 = toggler(tag1, block2(tag1)());
let tag2 = ctx['brother']; const tag2 = ctx['brother'];
let b3 = toggler(tag2, block3(tag2)()); const b3 = toggler(tag2, block3(tag2)());
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -50,7 +50,7 @@ exports[`loading templates can load a few templates from a xml string 1`] = `
let block1 = createBlock(\`<ul><block-child-0/></ul>\`); let block1 = createBlock(\`<ul><block-child-0/></ul>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -65,8 +65,8 @@ exports[`loading templates can load a few templates from a xml string 2`] = `
let block3 = createBlock(\`<li>foo</li>\`); let block3 = createBlock(\`<li>foo</li>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = block2(); const b2 = block2();
let b3 = block3(); const b3 = block3();
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -82,7 +82,7 @@ exports[`loading templates can load a few templates from an XMLDocument 1`] = `
let block1 = createBlock(\`<ul><block-child-0/></ul>\`); let block1 = createBlock(\`<ul><block-child-0/></ul>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -97,8 +97,8 @@ exports[`loading templates can load a few templates from an XMLDocument 2`] = `
let block3 = createBlock(\`<li>foo</li>\`); let block3 = createBlock(\`<li>foo</li>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = block2(); const b2 = block2();
let b3 = block3(); const b3 = block3();
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
+5 -5
View File
@@ -65,14 +65,14 @@ describe("tokenizer", () => {
}); });
test("strings", () => { test("strings", () => {
expect(() => tokenize("'")).toThrow("Invalid expression"); expect(() => tokenize("'")).toThrow("Tokenizer error: could not tokenize `'`");
expect(() => tokenize("'\\")).toThrow("Invalid expression"); expect(() => tokenize("'\\")).toThrow("Tokenizer error: could not tokenize `'\\`");
expect(() => tokenize("'\\'")).toThrow("Invalid expression"); expect(() => tokenize("'\\'")).toThrow("Tokenizer error: could not tokenize `'\\'`");
expect(tokenize("'hello ged'")).toEqual([{ type: "VALUE", value: "'hello ged'" }]); expect(tokenize("'hello ged'")).toEqual([{ type: "VALUE", value: "'hello ged'" }]);
expect(tokenize("'hello \\'ged\\''")).toEqual([{ type: "VALUE", value: "'hello \\'ged\\''" }]); expect(tokenize("'hello \\'ged\\''")).toEqual([{ type: "VALUE", value: "'hello \\'ged\\''" }]);
expect(() => tokenize('"')).toThrow("Invalid expression"); expect(() => tokenize('"')).toThrow('Tokenizer error: could not tokenize `"`');
expect(() => tokenize('"\\"')).toThrow("Invalid expression"); expect(() => tokenize('"\\"')).toThrow('Tokenizer error: could not tokenize `"\\"`');
expect(tokenize('"hello ged"')).toEqual([{ type: "VALUE", value: '"hello ged"' }]); expect(tokenize('"hello ged"')).toEqual([{ type: "VALUE", value: '"hello ged"' }]);
expect(tokenize('"hello ged"}')).toEqual([ expect(tokenize('"hello ged"}')).toEqual([
{ type: "VALUE", value: '"hello ged"' }, { type: "VALUE", value: '"hello ged"' },
+267 -145
View File
@@ -42,8 +42,8 @@ describe("qweb parser", () => {
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
content: [], content: [],
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -69,8 +69,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
content: [], content: [],
@@ -83,8 +83,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
content: [{ type: ASTType.Text, value: "some text" }], content: [{ type: ASTType.Text, value: "some text" }],
@@ -97,8 +97,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -108,8 +108,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "span", tag: "span",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -127,8 +127,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -138,8 +138,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "span", tag: "span",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -155,8 +155,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -180,8 +180,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -200,8 +200,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -222,8 +222,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -245,8 +245,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "span", tag: "span",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -262,7 +262,7 @@ describe("qweb parser", () => {
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: { class: "abc" }, attrs: { class: "abc" },
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -294,7 +294,7 @@ describe("qweb parser", () => {
dynamicTag: null, dynamicTag: null,
model: null, model: null,
ns: null, ns: null,
on: {}, on: null,
ref: null, ref: null,
tag: "circle", tag: "circle",
type: 2, type: 2,
@@ -303,7 +303,7 @@ describe("qweb parser", () => {
dynamicTag: null, dynamicTag: null,
model: null, model: null,
ns: "http://www.w3.org/2000/svg", ns: "http://www.w3.org/2000/svg",
on: {}, on: null,
ref: null, ref: null,
tag: "svg", tag: "svg",
type: 2, type: 2,
@@ -311,7 +311,7 @@ describe("qweb parser", () => {
expect( expect(
parse(`<g><circle cx="50" cy="50" r="4" stroke="green" stroke-width="1" fill="yellow"/></g>`) parse(`<g><circle cx="50" cy="50" r="4" stroke="green" stroke-width="1" fill="yellow"/></g>`)
).toEqual({ ).toEqual({
attrs: {}, attrs: null,
content: [ content: [
{ {
attrs: { attrs: {
@@ -326,7 +326,7 @@ describe("qweb parser", () => {
dynamicTag: null, dynamicTag: null,
model: null, model: null,
ns: null, ns: null,
on: {}, on: null,
ref: null, ref: null,
tag: "circle", tag: "circle",
type: 2, type: 2,
@@ -335,7 +335,7 @@ describe("qweb parser", () => {
dynamicTag: null, dynamicTag: null,
model: null, model: null,
ns: "http://www.w3.org/2000/svg", ns: "http://www.w3.org/2000/svg",
on: {}, on: null,
ref: null, ref: null,
tag: "g", tag: "g",
type: 2, type: 2,
@@ -347,16 +347,16 @@ describe("qweb parser", () => {
type: 2, type: 2,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
content: [ content: [
{ {
type: 2, type: 2,
tag: "pre", tag: "pre",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
content: [], content: [],
model: null, model: null,
@@ -390,8 +390,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "span", tag: "span",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -412,8 +412,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -454,8 +454,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -468,8 +468,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -488,8 +488,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -529,8 +529,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -606,8 +606,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -625,8 +625,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "h1", tag: "h1",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -638,8 +638,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "h2", tag: "h2",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -684,8 +684,8 @@ describe("qweb parser", () => {
body: [ body: [
{ {
type: ASTType.DomNode, type: ASTType.DomNode,
attrs: {}, attrs: null,
on: {}, on: null,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
ref: null, ref: null,
@@ -704,8 +704,8 @@ describe("qweb parser", () => {
body: [ body: [
{ {
type: ASTType.DomNode, type: ASTType.DomNode,
attrs: {}, attrs: null,
on: {}, on: null,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
ref: null, ref: null,
@@ -741,8 +741,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -810,8 +810,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -852,8 +852,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "span", tag: "span",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -886,8 +886,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "span", tag: "span",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -920,7 +920,7 @@ describe("qweb parser", () => {
"t-att-selected": "category.id==options.active_category_id", "t-att-selected": "category.id==options.active_category_id",
"t-att-value": "category.id", "t-att-value": "category.id",
}, },
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -939,8 +939,8 @@ describe("qweb parser", () => {
parse(`<div><t t-foreach="list" t-as="item" t-key="item_index"><t t-esc="item"/></t></div>`) parse(`<div><t t-foreach="list" t-as="item" t-key="item_index"><t t-esc="item"/></t></div>`)
).toEqual({ ).toEqual({
type: ASTType.DomNode, type: ASTType.DomNode,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
tag: "div", tag: "div",
@@ -983,10 +983,10 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "span", tag: "span",
dynamicTag: null, dynamicTag: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
attrs: {}, attrs: null,
ns: null, ns: null,
content: [{ type: ASTType.TEsc, expr: "item", defaultValue: "" }], content: [{ type: ASTType.TEsc, expr: "item", defaultValue: "" }],
}, },
@@ -1009,8 +1009,9 @@ describe("qweb parser", () => {
isDynamic: false, isDynamic: false,
name: "Comp", name: "Comp",
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
slots: {}, slots: null,
on: null,
}, },
memo: "", memo: "",
hasNoFirst: true, hasNoFirst: true,
@@ -1085,8 +1086,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -1123,7 +1124,7 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "button", tag: "button",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: { click: "add" }, on: { click: "add" },
ref: null, ref: null,
model: null, model: null,
@@ -1141,8 +1142,8 @@ describe("qweb parser", () => {
type: 2, type: 2,
tag: "select", tag: "select",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
content: [ content: [
{ {
@@ -1150,7 +1151,7 @@ describe("qweb parser", () => {
tag: "option", tag: "option",
dynamicTag: null, dynamicTag: null,
attrs: { value: "1" }, attrs: { value: "1" },
on: {}, on: null,
ref: null, ref: null,
content: [], content: [],
model: null, model: null,
@@ -1161,6 +1162,7 @@ describe("qweb parser", () => {
baseExpr: "state", baseExpr: "state",
expr: "'model'", expr: "'model'",
targetAttr: "value", targetAttr: "value",
hasDynamicChildren: false,
specialInitTargetAttr: null, specialInitTargetAttr: null,
eventType: "change", eventType: "change",
shouldTrim: false, shouldTrim: false,
@@ -1177,8 +1179,8 @@ describe("qweb parser", () => {
type: 2, type: 2,
tag: "select", tag: "select",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
content: [ content: [
{ {
@@ -1186,7 +1188,7 @@ describe("qweb parser", () => {
tag: "option", tag: "option",
dynamicTag: null, dynamicTag: null,
attrs: { "t-att-value": "valueVar" }, attrs: { "t-att-value": "valueVar" },
on: {}, on: null,
ref: null, ref: null,
content: [], content: [],
model: null, model: null,
@@ -1216,8 +1218,9 @@ describe("qweb parser", () => {
type: ASTType.TComponent, type: ASTType.TComponent,
name: "MyComponent", name: "MyComponent",
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
slots: {}, on: null,
slots: null,
isDynamic: false, isDynamic: false,
}); });
}); });
@@ -1229,7 +1232,8 @@ describe("qweb parser", () => {
dynamicProps: null, dynamicProps: null,
props: { a: "1", b: "'b'" }, props: { a: "1", b: "'b'" },
isDynamic: false, isDynamic: false,
slots: {}, on: null,
slots: null,
}); });
}); });
@@ -1240,14 +1244,21 @@ describe("qweb parser", () => {
dynamicProps: "state", dynamicProps: "state",
props: { a: "1" }, props: { a: "1" },
isDynamic: false, isDynamic: false,
slots: {}, on: null,
slots: null,
}); });
}); });
test("component with event handler", async () => { test("component with event handler", async () => {
expect(() => parse(`<MyComponent t-on-click="someMethod"/>`)).toThrow( expect(parse(`<MyComponent t-on-click="someMethod"/>`)).toEqual({
"t-on is no longer supported on components. Consider passing a callback in props." type: ASTType.TComponent,
); name: "MyComponent",
dynamicProps: null,
props: null,
isDynamic: false,
on: { click: "someMethod" },
slots: null,
});
}); });
test("component with t-ref", async () => { test("component with t-ref", async () => {
@@ -1279,9 +1290,17 @@ describe("qweb parser", () => {
type: ASTType.TComponent, type: ASTType.TComponent,
name: "MyComponent", name: "MyComponent",
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
isDynamic: false, isDynamic: false,
slots: { default: { content: { type: ASTType.Text, value: "foo" } } }, on: null,
slots: {
default: {
content: { type: ASTType.Text, value: "foo" },
attrs: null,
on: null,
scope: null,
},
},
}); });
}); });
@@ -1292,10 +1311,16 @@ describe("qweb parser", () => {
type: ASTType.TComponent, type: ASTType.TComponent,
name: "MyComponent", name: "MyComponent",
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
isDynamic: false, isDynamic: false,
on: null,
slots: { slots: {
default: { content: { type: ASTType.Text, value: "foo" }, attrs: { param: "param" } }, default: {
content: { type: ASTType.Text, value: "foo" },
attrs: { param: "param" },
on: null,
scope: null,
},
}, },
}); });
}); });
@@ -1306,7 +1331,8 @@ describe("qweb parser", () => {
name: "MyComponent", name: "MyComponent",
isDynamic: false, isDynamic: false,
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
on: null,
slots: { slots: {
default: { default: {
content: { content: {
@@ -1316,26 +1342,29 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "span", tag: "span",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
content: [], content: [],
ref: null, ref: null,
model: null, model: null,
on: {}, on: null,
ns: null, ns: null,
}, },
{ {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
content: [], content: [],
ref: null, ref: null,
model: null, model: null,
on: {}, on: null,
ns: null, ns: null,
}, },
], ],
}, },
attrs: null,
on: null,
scope: null,
}, },
}, },
}); });
@@ -1347,8 +1376,11 @@ describe("qweb parser", () => {
name: "MyComponent", name: "MyComponent",
isDynamic: false, isDynamic: false,
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
slots: { name: { content: { type: ASTType.Text, value: "foo" } } }, on: null,
slots: {
name: { content: { type: ASTType.Text, value: "foo" }, attrs: null, on: null, scope: null },
},
}); });
}); });
@@ -1358,8 +1390,37 @@ describe("qweb parser", () => {
name: "MyComponent", name: "MyComponent",
isDynamic: false, isDynamic: false,
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
slots: { name: { content: { type: ASTType.Text, value: "foo" }, attrs: { param: "param" } } }, on: null,
slots: {
name: {
content: { type: ASTType.Text, value: "foo" },
attrs: { param: "param" },
on: null,
scope: null,
},
},
});
});
test("a component with a named slot with t-on", async () => {
expect(
parse(`<MyComponent><t t-set-slot="name" t-on-click="doStuff">foo</t></MyComponent>`)
).toEqual({
type: ASTType.TComponent,
name: "MyComponent",
isDynamic: false,
dynamicProps: null,
props: null,
on: null,
slots: {
name: {
content: { type: ASTType.Text, value: "foo" },
on: { click: "doStuff" },
attrs: null,
scope: null,
},
},
}); });
}); });
@@ -1374,11 +1435,17 @@ describe("qweb parser", () => {
type: ASTType.TComponent, type: ASTType.TComponent,
name: "MyComponent", name: "MyComponent",
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
isDynamic: false, isDynamic: false,
on: null,
slots: { slots: {
default: { content: { type: ASTType.Text, value: " " } }, default: {
name: { content: { type: ASTType.Text, value: "foo" } }, content: { type: ASTType.Text, value: " " },
attrs: null,
on: null,
scope: null,
},
name: { content: { type: ASTType.Text, value: "foo" }, attrs: null, on: null, scope: null },
}, },
}); });
}); });
@@ -1393,11 +1460,12 @@ describe("qweb parser", () => {
type: ASTType.TComponent, type: ASTType.TComponent,
name: "MyComponent", name: "MyComponent",
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
isDynamic: false, isDynamic: false,
on: null,
slots: { slots: {
a: { content: { type: ASTType.Text, value: "foo" } }, a: { content: { type: ASTType.Text, value: "foo" }, attrs: null, on: null, scope: null },
b: { content: { type: ASTType.Text, value: "bar" } }, b: { content: { type: ASTType.Text, value: "bar" }, attrs: null, on: null, scope: null },
}, },
}); });
}); });
@@ -1407,9 +1475,10 @@ describe("qweb parser", () => {
type: ASTType.TComponent, type: ASTType.TComponent,
name: "myComponent", name: "myComponent",
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
isDynamic: true, isDynamic: true,
slots: {}, on: null,
slots: null,
}); });
}); });
@@ -1420,7 +1489,8 @@ describe("qweb parser", () => {
dynamicProps: null, dynamicProps: null,
props: { a: "1", b: "'b'" }, props: { a: "1", b: "'b'" },
isDynamic: true, isDynamic: true,
slots: {}, on: null,
slots: null,
}); });
}); });
@@ -1431,7 +1501,8 @@ describe("qweb parser", () => {
dynamicProps: "state", dynamicProps: "state",
props: { a: "1" }, props: { a: "1" },
isDynamic: true, isDynamic: true,
slots: {}, on: null,
slots: null,
}); });
}); });
@@ -1452,9 +1523,17 @@ describe("qweb parser", () => {
type: ASTType.TComponent, type: ASTType.TComponent,
name: "MyComponent", name: "MyComponent",
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
isDynamic: false, isDynamic: false,
slots: { default: { content: { body: null, name: "subTemplate", type: ASTType.TCall } } }, on: null,
slots: {
default: {
content: { body: null, name: "subTemplate", type: ASTType.TCall },
attrs: null,
scope: null,
on: null,
},
},
}); });
}); });
@@ -1470,17 +1549,29 @@ describe("qweb parser", () => {
type: ASTType.TComponent, type: ASTType.TComponent,
name: "MyComponent", name: "MyComponent",
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
isDynamic: false, isDynamic: false,
on: null,
slots: { slots: {
default: { default: {
attrs: null,
on: null,
scope: null,
content: { content: {
type: ASTType.TComponent, type: ASTType.TComponent,
isDynamic: false, isDynamic: false,
name: "Child", name: "Child",
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
slots: { brol: { content: { type: ASTType.Text, value: "coucou" } } }, on: null,
slots: {
brol: {
content: { type: ASTType.Text, value: "coucou" },
attrs: null,
scope: null,
on: null,
},
},
}, },
}, },
}, },
@@ -1499,17 +1590,29 @@ describe("qweb parser", () => {
type: ASTType.TComponent, type: ASTType.TComponent,
name: "MyComponent", name: "MyComponent",
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
isDynamic: false, isDynamic: false,
on: null,
slots: { slots: {
default: { default: {
attrs: null,
on: null,
scope: null,
content: { content: {
type: ASTType.TComponent, type: ASTType.TComponent,
isDynamic: false, isDynamic: false,
name: "Child", name: "Child",
dynamicProps: null, dynamicProps: null,
props: {}, props: null,
slots: { brol: { content: { type: ASTType.Text, value: "coucou" } } }, on: null,
slots: {
brol: {
content: { type: ASTType.Text, value: "coucou" },
attrs: null,
on: null,
scope: null,
},
},
}, },
}, },
}, },
@@ -1524,7 +1627,8 @@ describe("qweb parser", () => {
expect(parse(`<t t-slot="default"/>`)).toEqual({ expect(parse(`<t t-slot="default"/>`)).toEqual({
type: ASTType.TSlot, type: ASTType.TSlot,
name: "default", name: "default",
attrs: {}, attrs: null,
on: null,
defaultContent: null, defaultContent: null,
}); });
}); });
@@ -1533,11 +1637,22 @@ describe("qweb parser", () => {
expect(parse(`<t t-slot="header">default content</t>`)).toEqual({ expect(parse(`<t t-slot="header">default content</t>`)).toEqual({
type: ASTType.TSlot, type: ASTType.TSlot,
name: "header", name: "header",
attrs: {}, attrs: null,
on: null,
defaultContent: { type: ASTType.Text, value: "default content" }, defaultContent: { type: ASTType.Text, value: "default content" },
}); });
}); });
test("t-slot with t-on-", async () => {
expect(parse(`<t t-slot="default" t-on-click.prevent="doSomething"/>`)).toEqual({
type: ASTType.TSlot,
name: "default",
attrs: null,
on: { "click.prevent": "doSomething" },
defaultContent: null,
});
});
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// t-debug // t-debug
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -1549,8 +1664,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -1567,8 +1682,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
ns: null, ns: null,
@@ -1586,8 +1701,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: "name", ref: "name",
model: null, model: null,
ns: null, ns: null,
@@ -1600,8 +1715,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: "name", ref: "name",
model: null, model: null,
ns: null, ns: null,
@@ -1616,8 +1731,8 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
tag: "div", tag: "div",
dynamicTag: null, dynamicTag: null,
attrs: {}, attrs: null,
on: {}, on: null,
ref: "name", ref: "name",
model: null, model: null,
ns: null, ns: null,
@@ -1652,14 +1767,14 @@ describe("qweb parser", () => {
).toEqual({ ).toEqual({
body: { body: {
content: { content: {
attrs: {}, attrs: null,
content: [ content: [
{ {
type: ASTType.Text, type: ASTType.Text,
value: "word", value: "word",
}, },
], ],
on: {}, on: null,
ref: null, ref: null,
model: null, model: null,
tag: "div", tag: "div",
@@ -1687,9 +1802,9 @@ describe("qweb parser", () => {
test("t-model", async () => { test("t-model", async () => {
expect(parse(`<input t-model="state.stuff" />`)).toEqual({ expect(parse(`<input t-model="state.stuff" />`)).toEqual({
type: ASTType.DomNode, type: ASTType.DomNode,
attrs: {}, attrs: null,
content: [], content: [],
on: {}, on: null,
ref: null, ref: null,
tag: "input", tag: "input",
dynamicTag: null, dynamicTag: null,
@@ -1700,15 +1815,16 @@ describe("qweb parser", () => {
eventType: "input", eventType: "input",
shouldNumberize: false, shouldNumberize: false,
shouldTrim: false, shouldTrim: false,
hasDynamicChildren: false,
targetAttr: "value", targetAttr: "value",
specialInitTargetAttr: null, specialInitTargetAttr: null,
}, },
}); });
expect(parse(`<input t-model="state['stuff']" />`)).toEqual({ expect(parse(`<input t-model="state['stuff']" />`)).toEqual({
type: ASTType.DomNode, type: ASTType.DomNode,
attrs: {}, attrs: null,
content: [], content: [],
on: {}, on: null,
ref: null, ref: null,
tag: "input", tag: "input",
dynamicTag: null, dynamicTag: null,
@@ -1721,13 +1837,14 @@ describe("qweb parser", () => {
shouldTrim: false, shouldTrim: false,
targetAttr: "value", targetAttr: "value",
specialInitTargetAttr: null, specialInitTargetAttr: null,
hasDynamicChildren: false,
}, },
}); });
expect(parse(`<input t-model.lazy.trim.number="state.stuff" />`)).toEqual({ expect(parse(`<input t-model.lazy.trim.number="state.stuff" />`)).toEqual({
type: ASTType.DomNode, type: ASTType.DomNode,
attrs: {}, attrs: null,
content: [], content: [],
on: {}, on: null,
ref: null, ref: null,
tag: "input", tag: "input",
dynamicTag: null, dynamicTag: null,
@@ -1739,15 +1856,16 @@ describe("qweb parser", () => {
shouldNumberize: true, shouldNumberize: true,
shouldTrim: true, shouldTrim: true,
targetAttr: "value", targetAttr: "value",
hasDynamicChildren: false,
specialInitTargetAttr: null, specialInitTargetAttr: null,
}, },
}); });
}); });
expect(parse(`<textarea t-model="state.stuff" />`)).toEqual({ expect(parse(`<textarea t-model="state.stuff" />`)).toEqual({
type: ASTType.DomNode, type: ASTType.DomNode,
attrs: {}, attrs: null,
content: [], content: [],
on: {}, on: null,
ref: null, ref: null,
tag: "textarea", tag: "textarea",
dynamicTag: null, dynamicTag: null,
@@ -1759,6 +1877,7 @@ describe("qweb parser", () => {
shouldNumberize: false, shouldNumberize: false,
shouldTrim: false, shouldTrim: false,
targetAttr: "value", targetAttr: "value",
hasDynamicChildren: false,
specialInitTargetAttr: null, specialInitTargetAttr: null,
}, },
}); });
@@ -1766,7 +1885,7 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
attrs: { type: "checkbox" }, attrs: { type: "checkbox" },
content: [], content: [],
on: {}, on: null,
ref: null, ref: null,
tag: "input", tag: "input",
dynamicTag: null, dynamicTag: null,
@@ -1778,6 +1897,7 @@ describe("qweb parser", () => {
shouldNumberize: false, shouldNumberize: false,
shouldTrim: false, shouldTrim: false,
targetAttr: "checked", targetAttr: "checked",
hasDynamicChildren: false,
specialInitTargetAttr: null, specialInitTargetAttr: null,
}, },
}); });
@@ -1785,7 +1905,7 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
attrs: { type: "radio" }, attrs: { type: "radio" },
content: [], content: [],
on: {}, on: null,
ref: null, ref: null,
tag: "input", tag: "input",
dynamicTag: null, dynamicTag: null,
@@ -1797,6 +1917,7 @@ describe("qweb parser", () => {
shouldNumberize: false, shouldNumberize: false,
shouldTrim: false, shouldTrim: false,
targetAttr: "value", targetAttr: "value",
hasDynamicChildren: false,
specialInitTargetAttr: "checked", specialInitTargetAttr: "checked",
}, },
}); });
@@ -1804,7 +1925,7 @@ describe("qweb parser", () => {
type: ASTType.DomNode, type: ASTType.DomNode,
attrs: { type: "radio" }, attrs: { type: "radio" },
content: [], content: [],
on: {}, on: null,
ref: null, ref: null,
tag: "input", tag: "input",
dynamicTag: null, dynamicTag: null,
@@ -1816,6 +1937,7 @@ describe("qweb parser", () => {
shouldNumberize: false, shouldNumberize: false,
shouldTrim: false, shouldTrim: false,
targetAttr: "value", targetAttr: "value",
hasDynamicChildren: false,
specialInitTargetAttr: "checked", specialInitTargetAttr: "checked",
}, },
}); });
@@ -1826,9 +1948,9 @@ describe("qweb parser", () => {
test("t-tag", async () => { test("t-tag", async () => {
expect(parse(`<div t-tag="theTag" />`)).toEqual({ expect(parse(`<div t-tag="theTag" />`)).toEqual({
type: ASTType.DomNode, type: ASTType.DomNode,
attrs: {}, attrs: null,
content: [], content: [],
on: {}, on: null,
ref: null, ref: null,
tag: "div", tag: "div",
dynamicTag: "theTag", dynamicTag: "theTag",
@@ -6,7 +6,7 @@ exports[`basics GrandChild display is controlled by its GrandParent 1`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let Comp1 = ctx['myComp']; const Comp1 = ctx['myComp'];
return toggler(Comp1, component(Comp1, {displayGrandChild: ctx['displayGrandChild']}, key + \`__1\`, node, ctx)); return toggler(Comp1, component(Comp1, {displayGrandChild: ctx['displayGrandChild']}, key + \`__1\`, node, ctx));
} }
}" }"
@@ -49,9 +49,9 @@ exports[`basics Multi root component 1`] = `
let block4 = createBlock(\`<span>2</span>\`); let block4 = createBlock(\`<span>2</span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = block2(); const b2 = block2();
let b3 = text(\`text\`); const b3 = text(\`text\`);
let b4 = block4(); const b4 = block4();
return multi([b2, b3, b4]); return multi([b2, b3, b4]);
} }
}" }"
@@ -102,7 +102,7 @@ exports[`basics a component inside a component 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -145,7 +145,7 @@ exports[`basics can handle empty props 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {val: undefined}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {val: undefined}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -236,8 +236,8 @@ exports[`basics can mount a simple component with multiple roots 1`] = `
let block3 = createBlock(\`<div/>\`); let block3 = createBlock(\`<div/>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = block2(); const b2 = block2();
let b3 = block3(); const b3 = block3();
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -477,15 +477,15 @@ exports[`basics list of two sub components inside other nodes 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].blips); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].blips);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`blip\`] = v_block2[i1]; ctx[\`blip\`] = v_block2[i1];
let key1 = ctx['blip'].id; const key1 = ctx['blip'].id;
let b4 = component(\`SubWidget\`, {}, key + \`__1__\${key1}\`, node, ctx); const b4 = component(\`SubWidget\`, {}, key + \`__1__\${key1}\`, node, ctx);
let b5 = component(\`SubWidget\`, {}, key + \`__2__\${key1}\`, node, ctx); const b5 = component(\`SubWidget\`, {}, key + \`__2__\${key1}\`, node, ctx);
c_block2[i1] = withKey(block3([], [b4, b5]), key1); c_block2[i1] = withKey(block3([], [b4, b5]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -560,9 +560,9 @@ exports[`basics reconciliation alg is not confused in some specific situation 1`
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`); let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
const tKey_1 = 4; const tKey_1 = 4;
let b3 = toggler(tKey_1, component(\`Child\`, {}, tKey_1 + key + \`__2\`, node, ctx)); const b3 = toggler(tKey_1, component(\`Child\`, {}, tKey_1 + key + \`__2\`, node, ctx));
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
}" }"
@@ -617,9 +617,9 @@ exports[`basics same t-keys in two different places 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const tKey_1 = 1; const tKey_1 = 1;
let b2 = toggler(tKey_1, component(\`Child\`, {blip: '1'}, tKey_1 + key + \`__1\`, node, ctx)); const b2 = toggler(tKey_1, component(\`Child\`, {blip: '1'}, tKey_1 + key + \`__1\`, node, ctx));
const tKey_2 = 1; const tKey_2 = 1;
let b3 = toggler(tKey_2, component(\`Child\`, {blip: '2'}, tKey_2 + key + \`__2\`, node, ctx)); const b3 = toggler(tKey_2, component(\`Child\`, {blip: '2'}, tKey_2 + key + \`__2\`, node, ctx));
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
}" }"
@@ -952,8 +952,8 @@ exports[`basics two child components 1`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
let b3 = component(\`Child\`, {}, key + \`__2\`, node, ctx); const b3 = component(\`Child\`, {}, key + \`__2\`, node, ctx);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -981,7 +981,7 @@ exports[`basics update props of component without concrete own node 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const tKey_1 = ctx['childProps'].key; const tKey_1 = ctx['childProps'].key;
let b2 = toggler(tKey_1, component(\`Child\`, Object.assign({}, ctx['childProps']), tKey_1 + key + \`__1\`, node, ctx)); const b2 = toggler(tKey_1, component(\`Child\`, Object.assign({}, ctx['childProps']), tKey_1 + key + \`__1\`, node, ctx));
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1022,10 +1022,10 @@ exports[`basics updating a component with t-foreach as root 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['items']); const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`item\`] = v_block1[i1]; ctx[\`item\`] = v_block1[i1];
let key1 = ctx['item']; const key1 = ctx['item'];
c_block1[i1] = withKey(text(ctx['item']), key1); c_block1[i1] = withKey(text(ctx['item']), key1);
} }
return list(c_block1); return list(c_block1);
@@ -1071,16 +1071,16 @@ exports[`basics widget after a t-foreach 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(Array(2)); const [k_block2, v_block2, l_block2, c_block2] = prepareList(Array(2));;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`elem\`] = v_block2[i1]; ctx[\`elem\`] = v_block2[i1];
ctx[\`elem_index\`] = i1; ctx[\`elem_index\`] = i1;
let key1 = ctx['elem_index']; const key1 = ctx['elem_index'];
c_block2[i1] = withKey(text(\`txt\`), key1); c_block2[i1] = withKey(text(\`txt\`), key1);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b2 = list(c_block2); const b2 = list(c_block2);
let b4 = component(\`SomeComponent\`, {}, key + \`__1\`, node, ctx); const b4 = component(\`SomeComponent\`, {}, key + \`__1\`, node, ctx);
return block1([], [b2, b4]); return block1([], [b2, b4]);
} }
}" }"
@@ -1187,7 +1187,7 @@ exports[`support svg components add proper namespace to svg 1`] = `
let block1 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><block-child-0/></svg>\`); let block1 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><block-child-0/></svg>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`GComp\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`GComp\`, {}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1216,15 +1216,15 @@ exports[`t-out in components can render list of t-out 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].items); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].items);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1]; ctx[\`item\`] = v_block2[i1];
let key1 = ctx['item']; const key1 = ctx['item'];
let b4 = text(ctx['item']); const b4 = text(ctx['item']);
let b5 = safeOutput(ctx['item']); const b5 = safeOutput(ctx['item']);
c_block2[i1] = withKey(multi([b4, b5]), key1); c_block2[i1] = withKey(multi([b4, b5]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1237,8 +1237,8 @@ exports[`t-out in components can switch the contents of two t-out repeatedly 1`]
let { safeOutput } = helpers; let { safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['state'].a); const b2 = safeOutput(ctx['state'].a);
let b3 = safeOutput(ctx['state'].b); const b3 = safeOutput(ctx['state'].b);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -1253,7 +1253,7 @@ exports[`t-out in components update properly on state changes 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = safeOutput(ctx['state'].value); const b2 = safeOutput(ctx['state'].value);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -7,16 +7,16 @@ exports[`Cascading renders after microtaskTick 1`] = `
let { prepareList, withKey } = helpers; let { prepareList, withKey } = helpers;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
let b3 = text(\` _ \`); const b3 = text(\` _ \`);
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state']); const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state']);;
for (let i1 = 0; i1 < l_block4; i1++) { for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`elem\`] = v_block4[i1]; ctx[\`elem\`] = v_block4[i1];
let key1 = ctx['elem'].id; const key1 = ctx['elem'].id;
c_block4[i1] = withKey(text(ctx['elem'].id), key1); c_block4[i1] = withKey(text(ctx['elem'].id), key1);
} }
let b4 = list(c_block4); const b4 = list(c_block4);
return multi([b2, b3, b4]); return multi([b2, b3, b4]);
} }
}" }"
@@ -30,10 +30,10 @@ exports[`Cascading renders after microtaskTick 2`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['state']); const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['state']);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`elem\`] = v_block1[i1]; ctx[\`elem\`] = v_block1[i1];
let key1 = ctx['elem'].id; const key1 = ctx['elem'].id;
c_block1[i1] = withKey(component(\`Element\`, {id: ctx['elem'].id}, key + \`__1__\${key1}\`, node, ctx), key1); c_block1[i1] = withKey(component(\`Element\`, {id: ctx['elem'].id}, key + \`__1__\${key1}\`, node, ctx), key1);
} }
return list(c_block1); return list(c_block1);
@@ -169,7 +169,7 @@ exports[`concurrent renderings scenario 1 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -183,7 +183,7 @@ exports[`concurrent renderings scenario 1 2`] = `
let block1 = createBlock(\`<p><block-child-0/></p>\`); let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentC\`, {fromA: ctx['props'].fromA, fromB: ctx['state'].fromB}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentC\`, {fromA: ctx['props'].fromA, fromB: ctx['state'].fromB}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -213,7 +213,7 @@ exports[`concurrent renderings scenario 2 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['state'].fromA; let txt1 = ctx['state'].fromA;
let b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx);
return block1([txt1], [b2]); return block1([txt1], [b2]);
} }
}" }"
@@ -227,7 +227,7 @@ exports[`concurrent renderings scenario 2 2`] = `
let block1 = createBlock(\`<p><block-child-0/></p>\`); let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentC\`, {fromA: ctx['props'].fromA, fromB: ctx['state'].fromB}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentC\`, {fromA: ctx['props'].fromA, fromB: ctx['state'].fromB}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -256,7 +256,7 @@ exports[`concurrent renderings scenario 2bis 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -270,7 +270,7 @@ exports[`concurrent renderings scenario 2bis 2`] = `
let block1 = createBlock(\`<p><block-child-0/></p>\`); let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentC\`, {fromA: ctx['props'].fromA, fromB: ctx['state'].fromB}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentC\`, {fromA: ctx['props'].fromA, fromB: ctx['state'].fromB}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -299,7 +299,7 @@ exports[`concurrent renderings scenario 3 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -313,7 +313,7 @@ exports[`concurrent renderings scenario 3 2`] = `
let block1 = createBlock(\`<p><block-child-0/></p>\`); let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentC\`, {fromA: ctx['props'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentC\`, {fromA: ctx['props'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -327,7 +327,7 @@ exports[`concurrent renderings scenario 3 3`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentD\`, {fromA: ctx['props'].fromA, fromC: ctx['state'].fromC}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentD\`, {fromA: ctx['props'].fromA, fromC: ctx['state'].fromC}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -356,7 +356,7 @@ exports[`concurrent renderings scenario 4 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -370,7 +370,7 @@ exports[`concurrent renderings scenario 4 2`] = `
let block1 = createBlock(\`<p><block-child-0/></p>\`); let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentC\`, {fromA: ctx['props'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentC\`, {fromA: ctx['props'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -384,7 +384,7 @@ exports[`concurrent renderings scenario 4 3`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentD\`, {fromA: ctx['props'].fromA, fromC: ctx['state'].fromC}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentD\`, {fromA: ctx['props'].fromA, fromC: ctx['state'].fromC}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -413,7 +413,7 @@ exports[`concurrent renderings scenario 5 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -441,7 +441,7 @@ exports[`concurrent renderings scenario 6 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -469,7 +469,7 @@ exports[`concurrent renderings scenario 7 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -498,7 +498,7 @@ exports[`concurrent renderings scenario 8 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -528,8 +528,8 @@ exports[`concurrent renderings scenario 9 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['state'].fromA; let txt1 = ctx['state'].fromA;
let b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentB\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx);
let b3 = component(\`ComponentC\`, {fromA: ctx['state'].fromA}, key + \`__2\`, node, ctx); const b3 = component(\`ComponentC\`, {fromA: ctx['state'].fromA}, key + \`__2\`, node, ctx);
return block1([txt1], [b2, b3]); return block1([txt1], [b2, b3]);
} }
}" }"
@@ -557,7 +557,7 @@ exports[`concurrent renderings scenario 9 3`] = `
let block1 = createBlock(\`<p><block-child-0/></p>\`); let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentD\`, {fromA: ctx['props'].fromA, fromC: ctx['state'].fromC}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentD\`, {fromA: ctx['props'].fromA, fromC: ctx['state'].fromC}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -586,7 +586,7 @@ exports[`concurrent renderings scenario 10 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentB\`, {value: ctx['state'].value}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentB\`, {value: ctx['state'].value}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -631,7 +631,7 @@ exports[`concurrent renderings scenario 11 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {val: ctx['state'].valA}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {val: ctx['state'].valA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -660,7 +660,7 @@ exports[`concurrent renderings scenario 12 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {val: ctx['val']}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {val: ctx['val']}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -720,7 +720,7 @@ exports[`concurrent renderings scenario 14 1`] = `
let block1 = createBlock(\`<p><block-child-0/></p>\`); let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`B\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`B\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -734,7 +734,7 @@ exports[`concurrent renderings scenario 14 2`] = `
let block1 = createBlock(\`<p><block-child-0/></p>\`); let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`C\`, {fromB: ctx['state'].fromB, fromA: ctx['props'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`C\`, {fromB: ctx['state'].fromB, fromA: ctx['props'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -764,7 +764,7 @@ exports[`concurrent renderings scenario 15 1`] = `
let block1 = createBlock(\`<p><block-child-0/></p>\`); let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`B\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`B\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -778,7 +778,7 @@ exports[`concurrent renderings scenario 15 2`] = `
let block1 = createBlock(\`<p><block-child-0/></p>\`); let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`C\`, {fromB: ctx['state'].fromB, fromA: ctx['props'].fromA}, key + \`__1\`, node, ctx); const b2 = component(\`C\`, {fromB: ctx['state'].fromB, fromA: ctx['props'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1008,9 +1008,9 @@ exports[`delay willUpdateProps 2`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(ctx['props'].value); const b2 = text(ctx['props'].value);
let b3 = text(\`_\`); const b3 = text(\`_\`);
let b4 = text(ctx['state'].int); const b4 = text(ctx['state'].int);
return multi([b2, b3, b4]); return multi([b2, b3, b4]);
} }
}" }"
@@ -1033,8 +1033,8 @@ exports[`delay willUpdateProps with rendering grandchild 2`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`DelayedChild\`, {value: ctx['props'].state.value}, key + \`__1\`, node, ctx); const b2 = component(\`DelayedChild\`, {value: ctx['props'].state.value}, key + \`__1\`, node, ctx);
let b3 = component(\`ReactiveChild\`, {}, key + \`__2\`, node, ctx); const b3 = component(\`ReactiveChild\`, {}, key + \`__2\`, node, ctx);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -1046,9 +1046,9 @@ exports[`delay willUpdateProps with rendering grandchild 3`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(ctx['props'].value); const b2 = text(ctx['props'].value);
let b3 = text(\`_\`); const b3 = text(\`_\`);
let b4 = text(ctx['state'].int); const b4 = text(ctx['state'].int);
return multi([b2, b3, b4]); return multi([b2, b3, b4]);
} }
}" }"
@@ -1067,6 +1067,184 @@ exports[`delay willUpdateProps with rendering grandchild 4`] = `
}" }"
`; `;
exports[`delayed rendering, but then initial rendering is cancelled by yet another render 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return component(\`B\`, {value: ctx['state'].value}, key + \`__1\`, node, ctx);
}
}"
`;
exports[`delayed rendering, but then initial rendering is cancelled by yet another render 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return component(\`C\`, {value: ctx['state'].someValue+ctx['props'].value}, key + \`__1\`, node, ctx);
}
}"
`;
exports[`delayed rendering, but then initial rendering is cancelled by yet another render 3`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block3 = createBlock(\`<p><block-text-0/></p>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = component(\`D\`, {}, key + \`__1\`, node, ctx);
let txt1 = ctx['props'].value;
const b3 = block3([txt1]);
return multi([b2, b3]);
}
}"
`;
exports[`delayed rendering, but then initial rendering is cancelled by yet another render 4`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\"><block-text-1/></button>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [ctx['increment'], ctx];
let txt1 = ctx['state'].val;
return block1([hdlr1, txt1]);
}
}"
`;
exports[`delayed rendering, reusing fiber and stuff 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return component(\`B\`, {value: ctx['state'].value}, key + \`__1\`, node, ctx);
}
}"
`;
exports[`delayed rendering, reusing fiber and stuff 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
const b2 = text(ctx['props'].value);
const b3 = component(\`C\`, {}, key + \`__1\`, node, ctx);
return multi([b2, b3]);
}
}"
`;
exports[`delayed rendering, reusing fiber and stuff 3`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\"><block-text-1/></button>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [ctx['increment'], ctx];
let txt1 = ctx['state'].val;
return block1([hdlr1, txt1]);
}
}"
`;
exports[`delayed rendering, reusing fiber then component is destroyed and stuff 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
let b2,b3;
b2 = text(\`A\`);
if (ctx['state'].value<15) {
b3 = component(\`B\`, {value: ctx['state'].value}, key + \`__1\`, node, ctx);
}
return multi([b2, b3]);
}
}"
`;
exports[`delayed rendering, reusing fiber then component is destroyed and stuff 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
const b2 = text(ctx['props'].value);
const b3 = component(\`C\`, {}, key + \`__1\`, node, ctx);
return multi([b2, b3]);
}
}"
`;
exports[`delayed rendering, reusing fiber then component is destroyed and stuff 3`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\"><block-text-1/></button>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [ctx['increment'], ctx];
let txt1 = ctx['state'].val;
return block1([hdlr1, txt1]);
}
}"
`;
exports[`delayed rendering, then component is destroyed and stuff 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return component(\`B\`, {value: ctx['state'].value}, key + \`__1\`, node, ctx);
}
}"
`;
exports[`delayed rendering, then component is destroyed and stuff 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
let b2,b3;
b2 = text(ctx['props'].value);
if (ctx['props'].value<10) {
b3 = component(\`C\`, {}, key + \`__1\`, node, ctx);
}
return multi([b2, b3]);
}
}"
`;
exports[`delayed rendering, then component is destroyed and stuff 3`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\"><block-text-1/></button>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [ctx['increment'], ctx];
let txt1 = ctx['state'].val;
return block1([hdlr1, txt1]);
}
}"
`;
exports[`destroying/recreating a subcomponent, other scenario 1`] = ` exports[`destroying/recreating a subcomponent, other scenario 1`] = `
"function anonymous(bdom, helpers "function anonymous(bdom, helpers
) { ) {
@@ -1172,7 +1350,7 @@ exports[`properly behave when destroyed/unmounted while rendering 2`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`SubChild\`, {val: ctx['props'].val}, key + \`__1\`, node, ctx); const b2 = component(\`SubChild\`, {val: ctx['props'].val}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1252,14 +1430,14 @@ exports[`t-foreach with dynamic async component 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['list']); const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['list']);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`arr\`] = v_block1[i1]; ctx[\`arr\`] = v_block1[i1];
ctx[\`arr_index\`] = i1; ctx[\`arr_index\`] = i1;
let key1 = ctx['arr_index']; const key1 = ctx['arr_index'];
let b3; let b3;
if (ctx['arr']) { if (ctx['arr']) {
let Comp1 = ctx['myComp']; const Comp1 = ctx['myComp'];
b3 = toggler(Comp1, component(Comp1, {key: ctx['arr'][0]}, key + \`__1__\${key1}\`, node, ctx)); b3 = toggler(Comp1, component(Comp1, {key: ctx['arr'][0]}, key + \`__1__\${key1}\`, node, ctx));
} }
c_block1[i1] = withKey(multi([b3]), key1); c_block1[i1] = withKey(multi([b3]), key1);
@@ -1292,8 +1470,8 @@ exports[`t-key on dom node having a component 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const tKey_1 = ctx['key']; const tKey_1 = ctx['key'];
let Comp1 = ctx['myComp']; const Comp1 = ctx['myComp'];
let b2 = toggler(tKey_1, toggler(Comp1, component(Comp1, {key: ctx['key']}, tKey_1 + key + \`__1\`, node, ctx))); const b2 = toggler(tKey_1, toggler(Comp1, component(Comp1, {key: ctx['key']}, tKey_1 + key + \`__1\`, node, ctx)));
return toggler(tKey_1, block1([], [b2])); return toggler(tKey_1, block1([], [b2]));
} }
}" }"
@@ -1317,7 +1495,7 @@ exports[`t-key on dynamic async component (toggler is never patched) 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const tKey_1 = ctx['key']; const tKey_1 = ctx['key'];
let Comp1 = ctx['myComp']; const Comp1 = ctx['myComp'];
return toggler(tKey_1, toggler(Comp1, component(Comp1, {key: ctx['key']}, tKey_1 + key + \`__1\`, node, ctx))); return toggler(tKey_1, toggler(Comp1, component(Comp1, {key: ctx['key']}, tKey_1 + key + \`__1\`, node, ctx)));
} }
}" }"
@@ -1400,7 +1578,7 @@ exports[`update a sub-component twice in the same frame 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ChildA\`, {val: ctx['state'].valA}, key + \`__1\`, node, ctx); const b2 = component(\`ChildA\`, {val: ctx['state'].valA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1428,7 +1606,7 @@ exports[`update a sub-component twice in the same frame, 2 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ChildA\`, {val: ctx['state'].valA}, key + \`__1\`, node, ctx); const b2 = component(\`ChildA\`, {val: ctx['state'].valA}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -32,7 +32,7 @@ exports[`basics no component catching error lead to full app destruction 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ErrorComponent\`, {flag: ctx['state'].flag}, key + \`__1\`, node, ctx); const b2 = component(\`ErrorComponent\`, {flag: ctx['state'].flag}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -109,7 +109,7 @@ exports[`can catch errors can catch an error in a component render function 1`]
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx); const b3 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -128,7 +128,7 @@ exports[`can catch errors can catch an error in a component render function 2`]
if (ctx['state'].error) { if (ctx['state'].error) {
b2 = text(\`Error handled\`); b2 = text(\`Error handled\`);
} else { } else {
b3 = callSlot(ctx, node, key, 'default', false, {}); b3 = callSlot(ctx, node, key, 'default', false, null);
} }
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
@@ -162,7 +162,7 @@ exports[`can catch errors can catch an error in the constructor call of a compon
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx); const b3 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -181,7 +181,7 @@ exports[`can catch errors can catch an error in the constructor call of a compon
if (ctx['state'].error) { if (ctx['state'].error) {
b2 = text(\`Error handled\`); b2 = text(\`Error handled\`);
} else { } else {
b3 = callSlot(ctx, node, key, 'default', false, {}); b3 = callSlot(ctx, node, key, 'default', false, null);
} }
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
@@ -197,13 +197,13 @@ exports[`can catch errors can catch an error in the constructor call of a compon
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
function slot1(ctx, node, key = \\"\\") { function slot1(ctx, node, key = \\"\\") {
let b3 = component(\`ClassicCompoent\`, {}, key + \`__1\`, node, ctx); const b3 = component(\`ClassicCompoent\`, {}, key + \`__1\`, node, ctx);
let b4 = component(\`ErrorComponent\`, {}, key + \`__2\`, node, ctx); const b4 = component(\`ErrorComponent\`, {}, key + \`__2\`, node, ctx);
return multi([b3, b4]); return multi([b3, b4]);
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b5 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__3\`, node, ctx); const b5 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__3\`, node, ctx);
return block1([], [b5]); return block1([], [b5]);
} }
}" }"
@@ -222,7 +222,7 @@ exports[`can catch errors can catch an error in the constructor call of a compon
if (ctx['state'].error) { if (ctx['state'].error) {
b2 = text(\`Error handled\`); b2 = text(\`Error handled\`);
} else { } else {
b3 = callSlot(ctx, node, key, 'default', false, {}); b3 = callSlot(ctx, node, key, 'default', false, null);
} }
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
@@ -281,7 +281,7 @@ exports[`can catch errors can catch an error in the initial call of a component
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx); const b3 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -300,7 +300,7 @@ exports[`can catch errors can catch an error in the initial call of a component
if (ctx['state'].error) { if (ctx['state'].error) {
b2 = text(\`Error handled\`); b2 = text(\`Error handled\`);
} else { } else {
b3 = callSlot(ctx, node, key, 'default', false, {}); b3 = callSlot(ctx, node, key, 'default', false, null);
} }
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
@@ -356,7 +356,7 @@ exports[`can catch errors can catch an error in the initial call of a component
if (ctx['state'].error) { if (ctx['state'].error) {
b2 = text(\`Error handled\`); b2 = text(\`Error handled\`);
} else { } else {
b3 = callSlot(ctx, node, key, 'default', false, {}); b3 = callSlot(ctx, node, key, 'default', false, null);
} }
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
@@ -396,7 +396,7 @@ exports[`can catch errors can catch an error in the mounted call (in child of ch
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`C\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`C\`, {}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -479,7 +479,7 @@ exports[`can catch errors can catch an error in the mounted call 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx); const b3 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -498,7 +498,7 @@ exports[`can catch errors can catch an error in the mounted call 2`] = `
if (ctx['state'].error) { if (ctx['state'].error) {
b2 = text(\`Error handled\`); b2 = text(\`Error handled\`);
} else { } else {
b3 = callSlot(ctx, node, key, 'default', false, {}); b3 = callSlot(ctx, node, key, 'default', false, null);
} }
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
@@ -532,7 +532,7 @@ exports[`can catch errors can catch an error in the willPatch call 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['state'].message; let txt1 = ctx['state'].message;
let b3 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx); const b3 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx);
return block1([txt1], [b3]); return block1([txt1], [b3]);
} }
}" }"
@@ -551,7 +551,7 @@ exports[`can catch errors can catch an error in the willPatch call 2`] = `
if (ctx['state'].error) { if (ctx['state'].error) {
b2 = text(\`Error handled\`); b2 = text(\`Error handled\`);
} else { } else {
b3 = callSlot(ctx, node, key, 'default', false, {}); b3 = callSlot(ctx, node, key, 'default', false, null);
} }
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
@@ -585,7 +585,7 @@ exports[`can catch errors can catch an error in the willStart call 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx); const b3 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -604,7 +604,7 @@ exports[`can catch errors can catch an error in the willStart call 2`] = `
if (ctx['state'].error) { if (ctx['state'].error) {
b2 = text(\`Error handled\`); b2 = text(\`Error handled\`);
} else { } else {
b3 = callSlot(ctx, node, key, 'default', false, {}); b3 = callSlot(ctx, node, key, 'default', false, null);
} }
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
@@ -633,13 +633,13 @@ exports[`can catch errors can catch an error origination from a child's willStar
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
function slot1(ctx, node, key = \\"\\") { function slot1(ctx, node, key = \\"\\") {
let b3 = component(\`ClassicCompoent\`, {}, key + \`__1\`, node, ctx); const b3 = component(\`ClassicCompoent\`, {}, key + \`__1\`, node, ctx);
let b4 = component(\`ErrorComponent\`, {}, key + \`__2\`, node, ctx); const b4 = component(\`ErrorComponent\`, {}, key + \`__2\`, node, ctx);
return multi([b3, b4]); return multi([b3, b4]);
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b5 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__3\`, node, ctx); const b5 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__3\`, node, ctx);
return block1([], [b5]); return block1([], [b5]);
} }
}" }"
@@ -658,7 +658,7 @@ exports[`can catch errors can catch an error origination from a child's willStar
if (ctx['state'].error) { if (ctx['state'].error) {
b2 = text(\`Error handled\`); b2 = text(\`Error handled\`);
} else { } else {
b3 = callSlot(ctx, node, key, 'default', false, {}); b3 = callSlot(ctx, node, key, 'default', false, null);
} }
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
@@ -718,7 +718,7 @@ exports[`can catch errors catchError in catchError 2`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Boom\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Boom\`, {}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -745,16 +745,16 @@ exports[`can catch errors catching error, rethrow, render parent -- a main comp
let { prepareList, capture, markRaw, withKey } = helpers; let { prepareList, capture, markRaw, withKey } = helpers;
function slot1(ctx, node, key = \\"\\") { function slot1(ctx, node, key = \\"\\") {
let Comp1 = ctx['cp'].Comp; const Comp1 = ctx['cp'].Comp;
return toggler(Comp1, component(Comp1, {}, key + \`__1\`, node, ctx)); return toggler(Comp1, component(Comp1, {}, key + \`__1\`, node, ctx));
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(Object.values(ctx['state'].cps)); const [k_block1, v_block1, l_block1, c_block1] = prepareList(Object.values(ctx['state'].cps));;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`cp\`] = v_block1[i1]; ctx[\`cp\`] = v_block1[i1];
let key1 = ctx['cp'].id; const key1 = ctx['cp'].id;
const v1 = ctx['cp']; const v1 = ctx['cp'];
const ctx1 = capture(ctx); const ctx1 = capture(ctx);
c_block1[i1] = withKey(component(\`ErrorHandler\`, {onError: ()=>this.cleanUp(v1.id),slots: markRaw({'default': {__render: slot1, __ctx: ctx1}})}, key + \`__2__\${key1}\`, node, ctx), key1); c_block1[i1] = withKey(component(\`ErrorHandler\`, {onError: ()=>this.cleanUp(v1.id),slots: markRaw({'default': {__render: slot1, __ctx: ctx1}})}, key + \`__2__\${key1}\`, node, ctx), key1);
@@ -771,7 +771,7 @@ exports[`can catch errors catching error, rethrow, render parent -- a main comp
let { callSlot } = helpers; let { callSlot } = helpers;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
return callSlot(ctx, node, key, 'default', false, {}); return callSlot(ctx, node, key, 'default', false, null);
} }
}" }"
`; `;
@@ -820,16 +820,16 @@ exports[`can catch errors catching in child makes parent render 1`] = `
let { prepareList, capture, markRaw, withKey } = helpers; let { prepareList, capture, markRaw, withKey } = helpers;
function slot1(ctx, node, key = \\"\\") { function slot1(ctx, node, key = \\"\\") {
let Comp1 = ctx['elem'][1]; const Comp1 = ctx['elem'][1];
return toggler(Comp1, component(Comp1, {id: ctx['elem'][0]}, key + \`__1\`, node, ctx)); return toggler(Comp1, component(Comp1, {id: ctx['elem'][0]}, key + \`__1\`, node, ctx));
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(Object.entries(this.elements)); const [k_block1, v_block1, l_block1, c_block1] = prepareList(Object.entries(this.elements));;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`elem\`] = v_block1[i1]; ctx[\`elem\`] = v_block1[i1];
let key1 = ctx['elem'][0]; const key1 = ctx['elem'][0];
const v1 = ctx['elem']; const v1 = ctx['elem'];
const ctx1 = capture(ctx); const ctx1 = capture(ctx);
c_block1[i1] = withKey(component(\`Catch\`, {onError: (_error)=>this.onError(v1[0],_error),slots: markRaw({'default': {__render: slot1, __ctx: ctx1}})}, key + \`__2__\${key1}\`, node, ctx), key1); c_block1[i1] = withKey(component(\`Catch\`, {onError: (_error)=>this.onError(v1[0],_error),slots: markRaw({'default': {__render: slot1, __ctx: ctx1}})}, key + \`__2__\${key1}\`, node, ctx), key1);
@@ -846,7 +846,7 @@ exports[`can catch errors catching in child makes parent render 2`] = `
let { callSlot } = helpers; let { callSlot } = helpers;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
return callSlot(ctx, node, key, 'default', false, {}); return callSlot(ctx, node, key, 'default', false, null);
} }
}" }"
`; `;
@@ -891,8 +891,8 @@ exports[`can catch errors error in mounted on a component with a sibling (proper
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`OK\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`OK\`, {}, key + \`__1\`, node, ctx);
let b4 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__3\`, node, ctx); const b4 = component(\`ErrorBoundary\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__3\`, node, ctx);
return block1([], [b2, b4]); return block1([], [b2, b4]);
} }
}" }"
@@ -922,7 +922,7 @@ exports[`can catch errors error in mounted on a component with a sibling (proper
if (ctx['state'].error) { if (ctx['state'].error) {
b2 = text(\`Error handled\`); b2 = text(\`Error handled\`);
} else { } else {
b3 = callSlot(ctx, node, key, 'default', false, {}); b3 = callSlot(ctx, node, key, 'default', false, null);
} }
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
@@ -1010,7 +1010,7 @@ exports[`errors and promises a rendering error in a sub component will reject th
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1052,7 +1052,7 @@ exports[`errors and promises a rendering error will reject the render promise (w
let block1 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
let txt1 = ctx['x'].y; let txt1 = ctx['x'].y;
return block1([txt1], [b2]); return block1([txt1], [b2]);
} }
@@ -1156,6 +1156,19 @@ exports[`errors and promises errors in mounted and in willUnmount 1`] = `
}" }"
`; `;
exports[`errors and promises errors in onWillRender/onRender aren't wrapped more than once 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>abc</div>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
exports[`errors and promises errors in rerender 1`] = ` exports[`errors and promises errors in rerender 1`] = `
"function anonymous(bdom, helpers "function anonymous(bdom, helpers
) { ) {
@@ -37,7 +37,7 @@ exports[`event handling handler receive the event as argument 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let hdlr1 = [ctx['inc'], ctx]; let hdlr1 = [ctx['inc'], ctx];
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
let txt1 = ctx['state'].value; let txt1 = ctx['state'].value;
return block1([hdlr1, txt1], [b2]); return block1([hdlr1, txt1], [b2]);
} }
@@ -99,16 +99,16 @@ exports[`event handling objects from scope are properly captured by t-on 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1]; ctx[\`item\`] = v_block2[i1];
let key1 = ctx['item']; const key1 = ctx['item'];
const v1 = ctx['onClick']; const v1 = ctx['onClick'];
const v2 = ctx['item']; const v2 = ctx['item'];
let hdlr1 = [_ev=>v1(v2.val,_ev), ctx]; let hdlr1 = [_ev=>v1(v2.val,_ev), ctx];
c_block2[i1] = withKey(block3([hdlr1]), key1); c_block2[i1] = withKey(block3([hdlr1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -140,16 +140,16 @@ exports[`event handling t-on with handler bound to dynamic argument on a t-forea
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1]; ctx[\`item\`] = v_block2[i1];
let key1 = ctx['item']; const key1 = ctx['item'];
const v1 = ctx['onClick']; const v1 = ctx['onClick'];
const v2 = ctx['item']; const v2 = ctx['item'];
let hdlr1 = [_ev=>v1(v2,_ev), ctx]; let hdlr1 = [_ev=>v1(v2,_ev), ctx];
c_block2[i1] = withKey(block3([hdlr1]), key1); c_block2[i1] = withKey(block3([hdlr1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -147,7 +147,7 @@ exports[`basics top level sub widget with a parent 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ComponentB\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`ComponentB\`, {}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -109,8 +109,8 @@ exports[`hooks parent and child env (with useChildSubEnv then useSubEnv) 1`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(ctx['env'].val); const b2 = text(ctx['env'].val);
let b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -140,8 +140,8 @@ exports[`hooks parent and child env (with useChildSubEnv) 1`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(ctx['env'].val); const b2 = text(ctx['env'].val);
let b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -167,8 +167,8 @@ exports[`hooks parent and child env (with useSubEnv) 1`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(ctx['env'].val); const b2 = text(ctx['env'].val);
let b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -301,6 +301,19 @@ exports[`hooks useEffect hook effect with empty dependency list never reruns 1`]
}" }"
`; `;
exports[`hooks useEffect hook properly behaves when the effect function throws 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div/>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
exports[`hooks useExternalListener 1`] = ` exports[`hooks useExternalListener 1`] = `
"function anonymous(bdom, helpers "function anonymous(bdom, helpers
) { ) {
@@ -21,8 +21,8 @@ exports[`lifecycle hooks component semantics 1`] = `
let block1 = createBlock(\`<div>A<block-child-0/><block-child-1/></div>\`); let block1 = createBlock(\`<div>A<block-child-0/><block-child-1/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`B\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`B\`, {}, key + \`__1\`, node, ctx);
let b3 = component(\`C\`, {}, key + \`__2\`, node, ctx); const b3 = component(\`C\`, {}, key + \`__2\`, node, ctx);
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
}" }"
@@ -110,7 +110,7 @@ exports[`lifecycle hooks components are unmounted and destroyed if no longer in
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2; let b2;
if (ctx['state'].flag) { if (ctx['state'].flag) {
let b3 = component(\`Child\`, {n: ctx['state'].n}, key + \`__1\`, node, ctx); const b3 = component(\`Child\`, {n: ctx['state'].n}, key + \`__1\`, node, ctx);
b2 = block2([], [b3]); b2 = block2([], [b3]);
} }
return multi([b2]); return multi([b2]);
@@ -196,7 +196,7 @@ exports[`lifecycle hooks hooks are called in proper order in widget creation/des
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -245,7 +245,7 @@ exports[`lifecycle hooks lifecycle semantics 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {a: ctx['state'].a}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {a: ctx['state'].a}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -458,7 +458,7 @@ exports[`lifecycle hooks mounted hook is called on subcomponents, in proper orde
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -502,7 +502,7 @@ exports[`lifecycle hooks mounted hook is called on subsubcomponents, in proper o
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ChildChild\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`ChildChild\`, {}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -555,7 +555,7 @@ exports[`lifecycle hooks patched hook is called after updateProps 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {a: ctx['state'].a}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {a: ctx['state'].a}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -658,6 +658,43 @@ exports[`lifecycle hooks sub widget (inside sub node): hooks are correctly calle
}" }"
`; `;
exports[`lifecycle hooks timeout in onWillStart emits a warning 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span/>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
exports[`lifecycle hooks timeout in onWillUpdateProps emits a warning 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
const props1 = {prop: ctx['state'].prop};
helpers.validateProps(\`Child\`, props1, ctx);
return component(\`Child\`, props1, key + \`__1\`, node, ctx);
}
}"
`;
exports[`lifecycle hooks timeout in onWillUpdateProps emits a warning 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(\`\`);
}
}"
`;
exports[`lifecycle hooks willPatch, patched hook are called on subsubcomponents, in proper order 1`] = ` exports[`lifecycle hooks willPatch, patched hook are called on subsubcomponents, in proper order 1`] = `
"function anonymous(bdom, helpers "function anonymous(bdom, helpers
) { ) {
@@ -666,7 +703,7 @@ exports[`lifecycle hooks willPatch, patched hook are called on subsubcomponents,
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {n: ctx['state'].n}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {n: ctx['state'].n}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -680,7 +717,7 @@ exports[`lifecycle hooks willPatch, patched hook are called on subsubcomponents,
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`ChildChild\`, {n: ctx['props'].n}, key + \`__1\`, node, ctx); const b2 = component(\`ChildChild\`, {n: ctx['props'].n}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -8,7 +8,7 @@ exports[`basics accept ES6-like syntax for props (with getters) 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {greetings: ctx['greetings']}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {greetings: ctx['greetings']}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -36,10 +36,10 @@ exports[`basics arrow functions as prop correctly capture their scope 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['items']); const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`item\`] = v_block1[i1]; ctx[\`item\`] = v_block1[i1];
let key1 = ctx['item'].val; const key1 = ctx['item'].val;
const v1 = ctx['onClick']; const v1 = ctx['onClick'];
const v2 = ctx['item']; const v2 = ctx['item'];
c_block1[i1] = withKey(component(\`Child\`, {onClick: _ev=>v1(v2.val,_ev)}, key + \`__1__\${key1}\`, node, ctx), key1); c_block1[i1] = withKey(component(\`Child\`, {onClick: _ev=>v1(v2.val,_ev)}, key + \`__1__\${key1}\`, node, ctx), key1);
@@ -71,7 +71,7 @@ exports[`basics explicit object prop 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {value: ctx['state'].val}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {value: ctx['state'].val}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -158,7 +158,7 @@ exports[`basics t-set with a body expression can be passed in props, and then t-
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
ctx[\`abc\`] = new LazyValue(value1, ctx, node); ctx[\`abc\`] = new LazyValue(value1, ctx, node);
let b3 = component(\`Child\`, {val: ctx['abc']}, key + \`__1\`, node, ctx); const b3 = component(\`Child\`, {val: ctx['abc']}, key + \`__1\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -174,7 +174,7 @@ exports[`basics t-set with a body expression can be passed in props, and then t-
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['props'].val; let txt1 = ctx['props'].val;
let b2 = safeOutput(ctx['props'].val); const b2 = safeOutput(ctx['props'].val);
return block1([txt1], [b2]); return block1([txt1], [b2]);
} }
}" }"
@@ -192,7 +192,7 @@ exports[`basics t-set with a body expression can be used as textual prop 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"abc\\", \`42\`); setContextValue(ctx, \\"abc\\", \`42\`);
let b2 = component(\`Child\`, {val: ctx['abc']}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {val: ctx['abc']}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -224,7 +224,7 @@ exports[`basics t-set works 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"val\\", 42); setContextValue(ctx, \\"val\\", 42);
let b2 = component(\`Child\`, {val: ctx['val']}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {val: ctx['val']}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -23,7 +23,7 @@ exports[`default props can set default boolean values 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {}; const props1 = {};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -59,7 +59,7 @@ exports[`default props can set default values 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {}; const props1 = {};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -89,7 +89,7 @@ exports[`default props default values are also set whenever component is updated
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['state'].p}; const props1 = {p: ctx['state'].p};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -171,7 +171,7 @@ exports[`props validation can validate a prop with multiple types 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -200,7 +200,7 @@ exports[`props validation can validate a prop with multiple types 3`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -229,7 +229,7 @@ exports[`props validation can validate a prop with multiple types 5`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -245,7 +245,7 @@ exports[`props validation can validate an array with given primitive type 1`] =
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -274,7 +274,7 @@ exports[`props validation can validate an array with given primitive type 3`] =
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -303,7 +303,7 @@ exports[`props validation can validate an array with given primitive type 5`] =
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -319,7 +319,7 @@ exports[`props validation can validate an array with given primitive type 6`] =
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -335,7 +335,7 @@ exports[`props validation can validate an array with multiple sub element types
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -364,7 +364,7 @@ exports[`props validation can validate an array with multiple sub element types
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -393,7 +393,7 @@ exports[`props validation can validate an array with multiple sub element types
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -422,7 +422,7 @@ exports[`props validation can validate an array with multiple sub element types
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -438,7 +438,7 @@ exports[`props validation can validate an object with simple shape 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -467,7 +467,7 @@ exports[`props validation can validate an object with simple shape 3`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -483,7 +483,7 @@ exports[`props validation can validate an object with simple shape 4`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -499,7 +499,7 @@ exports[`props validation can validate an object with simple shape 5`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -515,7 +515,7 @@ exports[`props validation can validate an optional props 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -544,7 +544,7 @@ exports[`props validation can validate an optional props 3`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -573,7 +573,7 @@ exports[`props validation can validate an optional props 5`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -589,7 +589,7 @@ exports[`props validation can validate recursively complicated prop def 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -618,7 +618,7 @@ exports[`props validation can validate recursively complicated prop def 3`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -647,7 +647,7 @@ exports[`props validation can validate recursively complicated prop def 5`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -663,7 +663,7 @@ exports[`props validation default values are applied before validating props at
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['state'].p}; const props1 = {p: ctx['state'].p};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -693,7 +693,7 @@ exports[`props validation missing required boolean prop causes an error 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {}; const props1 = {};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -709,7 +709,7 @@ exports[`props validation mix of optional and mandatory 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {}; const props1 = {};
helpers.validateProps(\`Child\`, props1, ctx); helpers.validateProps(\`Child\`, props1, ctx);
let b2 = component(\`Child\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -725,7 +725,7 @@ exports[`props validation props are validated in dev mode (code snapshot) 1`] =
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {message: 1}; const props1 = {message: 1};
helpers.validateProps(\`Child\`, props1, ctx); helpers.validateProps(\`Child\`, props1, ctx);
let b2 = component(\`Child\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -755,7 +755,7 @@ exports[`props validation props are validated whenever component is updated 1`]
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['state'].p}; const props1 = {p: ctx['state'].p};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -785,7 +785,7 @@ exports[`props validation props: list of strings 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {}; const props1 = {};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -801,7 +801,7 @@ exports[`props validation validate simple types 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -817,7 +817,7 @@ exports[`props validation validate simple types 2`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -846,7 +846,7 @@ exports[`props validation validate simple types 4`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -862,7 +862,7 @@ exports[`props validation validate simple types 5`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -878,7 +878,7 @@ exports[`props validation validate simple types 6`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -907,7 +907,7 @@ exports[`props validation validate simple types 8`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -923,7 +923,7 @@ exports[`props validation validate simple types 9`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -939,7 +939,7 @@ exports[`props validation validate simple types 10`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -968,7 +968,7 @@ exports[`props validation validate simple types 12`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -984,7 +984,7 @@ exports[`props validation validate simple types 13`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1000,7 +1000,7 @@ exports[`props validation validate simple types 14`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1029,7 +1029,7 @@ exports[`props validation validate simple types 16`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1045,7 +1045,7 @@ exports[`props validation validate simple types 17`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1061,7 +1061,7 @@ exports[`props validation validate simple types 18`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1090,7 +1090,7 @@ exports[`props validation validate simple types 20`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1106,7 +1106,7 @@ exports[`props validation validate simple types 21`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1122,7 +1122,7 @@ exports[`props validation validate simple types 22`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1151,7 +1151,7 @@ exports[`props validation validate simple types 24`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1167,7 +1167,7 @@ exports[`props validation validate simple types, alternate form 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1183,7 +1183,7 @@ exports[`props validation validate simple types, alternate form 2`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1212,7 +1212,7 @@ exports[`props validation validate simple types, alternate form 4`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1228,7 +1228,7 @@ exports[`props validation validate simple types, alternate form 5`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1244,7 +1244,7 @@ exports[`props validation validate simple types, alternate form 6`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1273,7 +1273,7 @@ exports[`props validation validate simple types, alternate form 8`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1289,7 +1289,7 @@ exports[`props validation validate simple types, alternate form 9`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1305,7 +1305,7 @@ exports[`props validation validate simple types, alternate form 10`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1334,7 +1334,7 @@ exports[`props validation validate simple types, alternate form 12`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1350,7 +1350,7 @@ exports[`props validation validate simple types, alternate form 13`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1366,7 +1366,7 @@ exports[`props validation validate simple types, alternate form 14`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1395,7 +1395,7 @@ exports[`props validation validate simple types, alternate form 16`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1411,7 +1411,7 @@ exports[`props validation validate simple types, alternate form 17`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1427,7 +1427,7 @@ exports[`props validation validate simple types, alternate form 18`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1456,7 +1456,7 @@ exports[`props validation validate simple types, alternate form 20`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1472,7 +1472,7 @@ exports[`props validation validate simple types, alternate form 21`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1488,7 +1488,7 @@ exports[`props validation validate simple types, alternate form 22`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1517,7 +1517,7 @@ exports[`props validation validate simple types, alternate form 24`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']}; const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1533,7 +1533,7 @@ exports[`props validation validation is only done in dev mode 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const props1 = {}; const props1 = {};
helpers.validateProps(\`SubComp\`, props1, ctx); helpers.validateProps(\`SubComp\`, props1, ctx);
let b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, props1, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1547,7 +1547,7 @@ exports[`props validation validation is only done in dev mode 2`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`SubComp\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`SubComp\`, {}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -1,5 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`reactivity in lifecycle Child component doesn't render when state they depend on changes but their parent is about to unmount them 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
let b2;
if (ctx['state'].renderChild) {
b2 = component(\`Child\`, {state: ctx['state']}, key + \`__1\`, node, ctx);
}
return multi([b2]);
}
}"
`;
exports[`reactivity in lifecycle Child component doesn't render when state they depend on changes but their parent is about to unmount them 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['props'].state.content.a);
}
}"
`;
exports[`reactivity in lifecycle can use a state hook 1`] = ` exports[`reactivity in lifecycle can use a state hook 1`] = `
"function anonymous(bdom, helpers "function anonymous(bdom, helpers
) { ) {
@@ -77,7 +77,7 @@ exports[`refs refs are properly bound in slots 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['state'].val; let txt1 = ctx['state'].val;
const ctx1 = capture(ctx); const ctx1 = capture(ctx);
let b3 = component(\`Dialog\`, {slots: markRaw({'footer': {__render: slot1, __ctx: ctx1}})}, key + \`__1\`, node, ctx); const b3 = component(\`Dialog\`, {slots: markRaw({'footer': {__render: slot1, __ctx: ctx1}})}, key + \`__1\`, node, ctx);
return block1([txt1], [b3]); return block1([txt1], [b3]);
} }
}" }"
@@ -92,7 +92,7 @@ exports[`refs refs are properly bound in slots 2`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callSlot(ctx, node, key, 'footer', false, {}); const b2 = callSlot(ctx, node, key, 'footer', false, null);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -110,8 +110,8 @@ exports[`refs throws if there are 2 same refs at the same time 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const refs = ctx.__owl__.refs; const refs = ctx.__owl__.refs;
const ref1 = multiRefSetter(refs, \`coucou\`); const ref1 = multiRefSetter(refs, \`coucou\`);
let b2 = block2([ref1]); const b2 = block2([ref1]);
let b3 = block3([ref1]); const b3 = block3([ref1]);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -17,8 +17,8 @@ exports[`force render in case of existing render 2`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`C\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`C\`, {}, key + \`__1\`, node, ctx);
let b3 = text(ctx['props'].val); const b3 = text(ctx['props'].val);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -41,8 +41,8 @@ exports[`rendering semantics can force a render to update sub tree 1`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(ctx['state'].value); const b2 = text(ctx['state'].value);
let b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -65,8 +65,8 @@ exports[`rendering semantics can render a parent without rendering child 1`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(ctx['state'].value); const b2 = text(ctx['state'].value);
let b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -133,9 +133,9 @@ exports[`rendering semantics render with deep=true followed by render with deep=
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(\`parent\`); const b2 = text(\`parent\`);
let b3 = text(ctx['state'].value); const b3 = text(ctx['state'].value);
let b4 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b4 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
return multi([b2, b3, b4]); return multi([b2, b3, b4]);
} }
}" }"
@@ -147,8 +147,8 @@ exports[`rendering semantics render with deep=true followed by render with deep=
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(\`child\`); const b2 = text(\`child\`);
let b3 = text(ctx['env'].getValue()); const b3 = text(ctx['env'].getValue());
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -160,8 +160,8 @@ exports[`rendering semantics rendering is atomic (for one subtree) 1`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(ctx['state'].obj.val); const b2 = text(ctx['state'].obj.val);
let b3 = component(\`B\`, {obj: ctx['state'].obj}, key + \`__1\`, node, ctx); const b3 = component(\`B\`, {obj: ctx['state'].obj}, key + \`__1\`, node, ctx);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
File diff suppressed because it is too large Load Diff
@@ -20,9 +20,9 @@ exports[`style and class handling can set class on multi root component 2`] = `
let block3 = createBlock(\`<span block-attribute-0=\\"class\\">b</span>\`); let block3 = createBlock(\`<span block-attribute-0=\\"class\\">b</span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = block2(); const b2 = block2();
let attr1 = ctx['props'].class; let attr1 = ctx['props'].class;
let b3 = block3([attr1]); const b3 = block3([attr1]);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -205,7 +205,7 @@ exports[`style and class handling class with extra whitespaces (variation) 1`] =
let block1 = createBlock(\`<p><block-child-0/></p>\`); let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {class: 'a b c d'}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {class: 'a b c d'}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -310,7 +310,7 @@ exports[`style and class handling empty class attribute is not added on widget r
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {class: undefined}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {class: undefined}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -438,7 +438,7 @@ exports[`style and class handling t-att-class is properly added/removed on widge
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {class: {b:ctx['state'].b}}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {class: {b:ctx['state'].b}}, key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -9,7 +9,7 @@ exports[`t-call dynamic t-call 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
let b1 = text(\` owl \`); const b1 = text(\` owl \`);
ctx[zero] = b1; ctx[zero] = b1;
const template1 = (ctx['current'].template); const template1 = (ctx['current'].template);
return call(this, template1, ctx, node, key + \`__1\`); return call(this, template1, ctx, node, key + \`__1\`);
@@ -48,9 +48,9 @@ exports[`t-call dynamic t-call: key is propagated 1`] = `
let { call } = helpers; let { call } = helpers;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
const template1 = (ctx['sub']); const template1 = (ctx['sub']);
let b3 = call(this, template1, ctx, node, key + \`__2\`); const b3 = call(this, template1, ctx, node, key + \`__2\`);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -91,7 +91,7 @@ exports[`t-call handlers are properly bound through a dynamic t-call 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const template1 = ('__template__999'); const template1 = ('__template__999');
let b2 = call(this, template1, ctx, node, key + \`__1\`); const b2 = call(this, template1, ctx, node, key + \`__1\`);
let txt1 = ctx['counter']; let txt1 = ctx['counter'];
return block1([txt1], [b2]); return block1([txt1], [b2]);
} }
@@ -122,7 +122,7 @@ exports[`t-call handlers are properly bound through a t-call 1`] = `
let block1 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
let txt1 = ctx['counter']; let txt1 = ctx['counter'];
return block1([txt1], [b2]); return block1([txt1], [b2]);
} }
@@ -153,7 +153,7 @@ exports[`t-call handlers with arguments are properly bound through a t-call 1`]
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -184,7 +184,7 @@ exports[`t-call parent is set within t-call 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -266,7 +266,7 @@ exports[`t-call recursive t-call binding this -- static t-call 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"level\\", 0); setContextValue(ctx, \\"level\\", 0);
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -288,11 +288,11 @@ exports[`t-call recursive t-call binding this -- static t-call 2`] = `
if (ctx['level']<2) { if (ctx['level']<2) {
let hdlr1 = [\\"stop\\", ctx['onClicked'].bind(this), ctx]; let hdlr1 = [\\"stop\\", ctx['onClicked'].bind(this), ctx];
let txt1 = ctx['level']; let txt1 = ctx['level'];
let b3 = block3([hdlr1, txt1]); const b3 = block3([hdlr1, txt1]);
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"level\\", ctx['level']+1); setContextValue(ctx, \\"level\\", ctx['level']+1);
let b4 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b4 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
ctx = ctx.__proto__; ctx = ctx.__proto__;
b2 = multi([b3, b4]); b2 = multi([b3, b4]);
} }
@@ -316,7 +316,7 @@ exports[`t-call sub components in two t-calls 1`] = `
if (ctx['state'].val===1) { if (ctx['state'].val===1) {
b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
} else { } else {
let b4 = callTemplate_2.call(this, ctx, node, key + \`__2\`); const b4 = callTemplate_2.call(this, ctx, node, key + \`__2\`);
b3 = block3([], [b4]); b3 = block3([], [b4]);
} }
return multi([b2, b3]); return multi([b2, b3]);
@@ -360,17 +360,17 @@ exports[`t-call t-call in t-foreach and children component 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(['a','b','c']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(['a','b','c']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1]; ctx[\`val\`] = v_block2[i1];
ctx[\`val_first\`] = i1 === 0; ctx[\`val_first\`] = i1 === 0;
ctx[\`val_last\`] = i1 === v_block2.length - 1; ctx[\`val_last\`] = i1 === v_block2.length - 1;
ctx[\`val_index\`] = i1; ctx[\`val_index\`] = i1;
ctx[\`val_value\`] = k_block2[i1]; ctx[\`val_value\`] = k_block2[i1];
let key1 = ctx['val']; const key1 = ctx['val'];
c_block2[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1); c_block2[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -8,7 +8,7 @@ exports[`t-call-block simple t-call-block with static text 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = ctx['myBlock'](); const b2 = ctx['myBlock']();
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -8,8 +8,8 @@ exports[`t-component can switch between dynamic components without the need for
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let Comp1 = ctx['constructor'].components[ctx['state'].child]; const Comp1 = ctx['constructor'].components[ctx['state'].child];
let b2 = toggler(Comp1, component(Comp1, {}, key + \`__1\`, node, ctx)); const b2 = toggler(Comp1, component(Comp1, {}, key + \`__1\`, node, ctx));
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -48,7 +48,7 @@ exports[`t-component can use dynamic components (the class) if given (with diffe
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const tKey_1 = ctx['state'].child; const tKey_1 = ctx['state'].child;
let Comp1 = ctx['myComponent']; const Comp1 = ctx['myComponent'];
return toggler(tKey_1, toggler(Comp1, component(Comp1, {}, tKey_1 + key + \`__1\`, node, ctx))); return toggler(tKey_1, toggler(Comp1, component(Comp1, {}, tKey_1 + key + \`__1\`, node, ctx)));
} }
}" }"
@@ -87,7 +87,7 @@ exports[`t-component can use dynamic components (the class) if given 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const tKey_1 = ctx['state'].child; const tKey_1 = ctx['state'].child;
let Comp1 = ctx['myComponent']; const Comp1 = ctx['myComponent'];
return toggler(tKey_1, toggler(Comp1, component(Comp1, {}, tKey_1 + key + \`__1\`, node, ctx))); return toggler(tKey_1, toggler(Comp1, component(Comp1, {}, tKey_1 + key + \`__1\`, node, ctx)));
} }
}" }"
@@ -127,8 +127,8 @@ exports[`t-component modifying a sub widget 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let Comp1 = ctx['Counter']; const Comp1 = ctx['Counter'];
let b2 = toggler(Comp1, component(Comp1, {}, key + \`__1\`, node, ctx)); const b2 = toggler(Comp1, component(Comp1, {}, key + \`__1\`, node, ctx));
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -156,7 +156,7 @@ exports[`t-component switching dynamic component 1`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let Comp1 = ctx['Child']; const Comp1 = ctx['Child'];
return toggler(Comp1, component(Comp1, {}, key + \`__1\`, node, ctx)); return toggler(Comp1, component(Comp1, {}, key + \`__1\`, node, ctx));
} }
}" }"
@@ -192,7 +192,7 @@ exports[`t-component t-component works in simple case 1`] = `
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let Comp1 = ctx['Child']; const Comp1 = ctx['Child'];
return toggler(Comp1, component(Comp1, {}, key + \`__1\`, node, ctx)); return toggler(Comp1, component(Comp1, {}, key + \`__1\`, node, ctx));
} }
}" }"
@@ -11,14 +11,14 @@ exports[`list of components components in a node in a t-foreach 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1]; ctx[\`item\`] = v_block2[i1];
let key1 = 'li_'+ctx['item']; const key1 = 'li_'+ctx['item'];
let b4 = component(\`Child\`, {item: ctx['item']}, key + \`__1__\${key1}\`, node, ctx); const b4 = component(\`Child\`, {item: ctx['item']}, key + \`__1__\${key1}\`, node, ctx);
c_block2[i1] = withKey(block3([], [b4]), key1); c_block2[i1] = withKey(block3([], [b4]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -46,11 +46,11 @@ exports[`list of components crash on duplicate key in dev mode 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList([1,2]); const [k_block1, v_block1, l_block1, c_block1] = prepareList([1,2]);;
const keys1 = new Set(); const keys1 = new Set();
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`item\`] = v_block1[i1]; ctx[\`item\`] = v_block1[i1];
let key1 = 'child'; const key1 = 'child';
if (keys1.has(key1)) { throw new Error(\`Got duplicate key in t-foreach: \${key1}\`)} if (keys1.has(key1)) { throw new Error(\`Got duplicate key in t-foreach: \${key1}\`)}
keys1.add(key1); keys1.add(key1);
const props1 = {}; const props1 = {};
@@ -84,14 +84,14 @@ exports[`list of components list of sub components inside other nodes 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].blips); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].blips);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`blip\`] = v_block2[i1]; ctx[\`blip\`] = v_block2[i1];
let key1 = ctx['blip'].id; const key1 = ctx['blip'].id;
let b4 = component(\`SubComponent\`, {}, key + \`__1__\${key1}\`, node, ctx); const b4 = component(\`SubComponent\`, {}, key + \`__1__\${key1}\`, node, ctx);
c_block2[i1] = withKey(block3([], [b4]), key1); c_block2[i1] = withKey(block3([], [b4]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -120,23 +120,23 @@ exports[`list of components reconciliation alg works for t-foreach in t-foreach
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].s); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].s);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`section\`] = v_block2[i1]; ctx[\`section\`] = v_block2[i1];
ctx[\`section_index\`] = i1; ctx[\`section_index\`] = i1;
let key1 = ctx['section_index']; const key1 = ctx['section_index'];
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block3, v_block3, l_block3, c_block3] = prepareList(ctx['section'].blips); const [k_block3, v_block3, l_block3, c_block3] = prepareList(ctx['section'].blips);;
for (let i2 = 0; i2 < l_block3; i2++) { for (let i2 = 0; i2 < l_block3; i2++) {
ctx[\`blip\`] = v_block3[i2]; ctx[\`blip\`] = v_block3[i2];
ctx[\`blip_index\`] = i2; ctx[\`blip_index\`] = i2;
let key2 = ctx['blip_index']; const key2 = ctx['blip_index'];
c_block3[i2] = withKey(component(\`Child\`, {blip: ctx['blip']}, key + \`__1__\${key1}__\${key2}\`, node, ctx), key2); c_block3[i2] = withKey(component(\`Child\`, {blip: ctx['blip']}, key + \`__1__\${key1}__\${key2}\`, node, ctx), key2);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
c_block2[i1] = withKey(list(c_block3), key1); c_block2[i1] = withKey(list(c_block3), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -168,23 +168,23 @@ exports[`list of components reconciliation alg works for t-foreach in t-foreach,
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].rows); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].rows);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`row\`] = v_block2[i1]; ctx[\`row\`] = v_block2[i1];
let key1 = ctx['row']; const key1 = ctx['row'];
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state'].cols); const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state'].cols);;
for (let i2 = 0; i2 < l_block4; i2++) { for (let i2 = 0; i2 < l_block4; i2++) {
ctx[\`col\`] = v_block4[i2]; ctx[\`col\`] = v_block4[i2];
let key2 = ctx['col']; const key2 = ctx['col'];
let b6 = component(\`Child\`, {row: ctx['row'], col: ctx['col']}, key + \`__1__\${key1}__\${key2}\`, node, ctx); const b6 = component(\`Child\`, {row: ctx['row'], col: ctx['col']}, key + \`__1__\${key1}__\${key2}\`, node, ctx);
c_block4[i2] = withKey(block5([], [b6]), key2); c_block4[i2] = withKey(block5([], [b6]), key2);
} }
ctx = ctx.__proto__; ctx = ctx.__proto__;
let b4 = list(c_block4); const b4 = list(c_block4);
c_block2[i1] = withKey(block3([], [b4]), key1); c_block2[i1] = withKey(block3([], [b4]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -212,10 +212,10 @@ exports[`list of components simple list 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['state'].elems); const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['state'].elems);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`elem\`] = v_block1[i1]; ctx[\`elem\`] = v_block1[i1];
let key1 = ctx['elem'].id; const key1 = ctx['elem'].id;
c_block1[i1] = withKey(component(\`Child\`, {value: ctx['elem'].value}, key + \`__1__\${key1}\`, node, ctx), key1); c_block1[i1] = withKey(component(\`Child\`, {value: ctx['elem'].value}, key + \`__1__\${key1}\`, node, ctx), key1);
} }
return list(c_block1); return list(c_block1);
@@ -247,13 +247,13 @@ exports[`list of components sub components rendered in a loop 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].numbers); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].numbers);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`number\`] = v_block2[i1]; ctx[\`number\`] = v_block2[i1];
let key1 = ctx['number']; const key1 = ctx['number'];
c_block2[i1] = withKey(component(\`Child\`, {n: ctx['number']}, key + \`__1__\${key1}\`, node, ctx), key1); c_block2[i1] = withKey(component(\`Child\`, {n: ctx['number']}, key + \`__1__\${key1}\`, node, ctx), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -283,13 +283,13 @@ exports[`list of components sub components with some state rendered in a loop 1`
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].numbers); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].numbers);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`number\`] = v_block2[i1]; ctx[\`number\`] = v_block2[i1];
let key1 = ctx['number']; const key1 = ctx['number'];
c_block2[i1] = withKey(component(\`Child\`, {}, key + \`__1__\${key1}\`, node, ctx), key1); c_block2[i1] = withKey(component(\`Child\`, {}, key + \`__1__\${key1}\`, node, ctx), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -319,13 +319,13 @@ exports[`list of components switch component position 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['clist']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['clist']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`c\`] = v_block2[i1]; ctx[\`c\`] = v_block2[i1];
let key1 = ctx['c']; const key1 = ctx['c'];
c_block2[i1] = withKey(component(\`Child\`, {key: ctx['c']}, key + \`__1__\${key1}\`, node, ctx), key1); c_block2[i1] = withKey(component(\`Child\`, {key: ctx['c']}, key + \`__1__\${key1}\`, node, ctx), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -355,14 +355,14 @@ exports[`list of components t-foreach with t-component, and update 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(Array(2)); const [k_block2, v_block2, l_block2, c_block2] = prepareList(Array(2));;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`n\`] = v_block2[i1]; ctx[\`n\`] = v_block2[i1];
ctx[\`n_index\`] = i1; ctx[\`n_index\`] = i1;
let key1 = ctx['n_index']; const key1 = ctx['n_index'];
c_block2[i1] = withKey(component(\`Child\`, {val: ctx['n_index']}, key + \`__1__\${key1}\`, node, ctx), key1); c_block2[i1] = withKey(component(\`Child\`, {val: ctx['n_index']}, key + \`__1__\${key1}\`, node, ctx), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -10,14 +10,14 @@ exports[`t-key t-foreach with t-key switch component position 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['clist']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['clist']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`c\`] = v_block2[i1]; ctx[\`c\`] = v_block2[i1];
let key1 = ctx['c']; const key1 = ctx['c'];
const tKey_1 = ctx['key1']; const tKey_1 = ctx['key1'];
c_block2[i1] = withKey(component(\`Child\`, {key: ctx['c']+ctx['key1']}, tKey_1 + key + \`__1__\${key1}\`, node, ctx), tKey_1 + key1); c_block2[i1] = withKey(component(\`Child\`, {key: ctx['c']+ctx['key1']}, tKey_1 + key + \`__1__\${key1}\`, node, ctx), tKey_1 + key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -72,7 +72,7 @@ exports[`t-key t-key on Component as a function 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const tKey_1 = ctx['key']; const tKey_1 = ctx['key'];
let b2 = toggler(tKey_1, component(\`Child\`, {key: ctx['key']}, tKey_1 + key + \`__1\`, node, ctx)); const b2 = toggler(tKey_1, component(\`Child\`, {key: ctx['key']}, tKey_1 + key + \`__1\`, node, ctx));
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -101,9 +101,9 @@ exports[`t-key t-key on multiple Components 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const tKey_1 = ctx['key1']; const tKey_1 = ctx['key1'];
let b2 = toggler(tKey_1, component(\`Child\`, {key: ctx['key1']}, tKey_1 + key + \`__1\`, node, ctx)); const b2 = toggler(tKey_1, component(\`Child\`, {key: ctx['key1']}, tKey_1 + key + \`__1\`, node, ctx));
const tKey_2 = ctx['key2']; const tKey_2 = ctx['key2'];
let b3 = toggler(tKey_2, component(\`Child\`, {key: ctx['key2']}, tKey_2 + key + \`__2\`, node, ctx)); const b3 = toggler(tKey_2, component(\`Child\`, {key: ctx['key2']}, tKey_2 + key + \`__2\`, node, ctx));
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
}" }"
@@ -139,12 +139,12 @@ exports[`t-key t-key on multiple Components with t-call 1 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"key\\", ctx['key1']); setContextValue(ctx, \\"key\\", ctx['key1']);
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
ctx = ctx.__proto__; ctx = ctx.__proto__;
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1; ctx[isBoundary] = 1;
setContextValue(ctx, \\"key\\", ctx['key2']); setContextValue(ctx, \\"key\\", ctx['key2']);
let b3 = callTemplate_2.call(this, ctx, node, key + \`__2\`); const b3 = callTemplate_2.call(this, ctx, node, key + \`__2\`);
return block1([], [b2, b3]); return block1([], [b2, b3]);
} }
}" }"
@@ -186,7 +186,7 @@ exports[`t-key t-key on multiple Components with t-call 2 1`] = `
let block1 = createBlock(\`<span><block-child-0/></span>\`); let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`); const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -199,9 +199,9 @@ exports[`t-key t-key on multiple Components with t-call 2 2`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const tKey_1 = ctx['key1']; const tKey_1 = ctx['key1'];
let b2 = toggler(tKey_1, component(\`Child\`, {key: ctx['key1']}, tKey_1 + key + \`__1\`, node, ctx)); const b2 = toggler(tKey_1, component(\`Child\`, {key: ctx['key1']}, tKey_1 + key + \`__1\`, node, ctx));
const tKey_2 = ctx['key2']; const tKey_2 = ctx['key2'];
let b3 = toggler(tKey_2, component(\`Child\`, {key: ctx['key2']}, tKey_2 + key + \`__2\`, node, ctx)); const b3 = toggler(tKey_2, component(\`Child\`, {key: ctx['key2']}, tKey_2 + key + \`__2\`, node, ctx));
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -194,17 +194,17 @@ exports[`t-model directive in a t-foreach 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`thing\`] = v_block2[i1]; ctx[\`thing\`] = v_block2[i1];
let key1 = ctx['thing'].id; const key1 = ctx['thing'].id;
const bExpr1 = ctx['thing']; const bExpr1 = ctx['thing'];
const expr1 = 'f'; const expr1 = 'f';
let attr1 = bExpr1[expr1]; let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.checked; }]; let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.checked; }];
c_block2[i1] = withKey(block3([attr1, hdlr1]), key1); c_block2[i1] = withKey(block3([attr1, hdlr1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -221,18 +221,18 @@ exports[`t-model directive in a t-foreach, part 2 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`thing\`] = v_block2[i1]; ctx[\`thing\`] = v_block2[i1];
ctx[\`thing_index\`] = i1; ctx[\`thing_index\`] = i1;
let key1 = ctx['thing_index']; const key1 = ctx['thing_index'];
const bExpr1 = ctx['state']; const bExpr1 = ctx['state'];
const expr1 = ctx['thing_index']; const expr1 = ctx['thing_index'];
let attr1 = bExpr1[expr1]; let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }]; let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
c_block2[i1] = withKey(block3([attr1, hdlr1]), key1); c_block2[i1] = withKey(block3([attr1, hdlr1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -249,18 +249,18 @@ exports[`t-model directive in a t-foreach, part 3 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['names']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['names']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`name\`] = v_block2[i1]; ctx[\`name\`] = v_block2[i1];
ctx[\`name_index\`] = i1; ctx[\`name_index\`] = i1;
let key1 = ctx['name_index']; const key1 = ctx['name_index'];
const bExpr1 = ctx['state'].values; const bExpr1 = ctx['state'].values;
const expr1 = ctx['name']; const expr1 = ctx['name'];
let attr1 = bExpr1[expr1]; let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }]; let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
c_block2[i1] = withKey(block3([attr1, hdlr1]), key1); c_block2[i1] = withKey(block3([attr1, hdlr1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -460,7 +460,7 @@ exports[`t-model directive t-model with dynamic values on select options -- 2 1`
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const bExpr1 = ctx['state']; const bExpr1 = ctx['state'];
const expr1 = 'model'; const expr1 = 'model';
let bValue1 = bExpr1[expr1] const bValue1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }]; let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
let attr1 = ctx['options'][0]; let attr1 = ctx['options'][0];
let attr2 = bValue1 === ctx['options'][0]; let attr2 = bValue1 === ctx['options'][0];
@@ -484,7 +484,7 @@ exports[`t-model directive t-model with dynamic values on select options -- 3 1`
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const bExpr1 = ctx['state']; const bExpr1 = ctx['state'];
const expr1 = 'model'; const expr1 = 'model';
let bValue1 = bExpr1[expr1] const bValue1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }]; let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
let attr1 = ctx['options'][0]; let attr1 = ctx['options'][0];
let attr2 = bValue1 === ctx['options'][0]; let attr2 = bValue1 === ctx['options'][0];
@@ -507,7 +507,7 @@ exports[`t-model directive t-model with dynamic values on select options 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const bExpr1 = ctx['state']; const bExpr1 = ctx['state'];
const expr1 = 'model'; const expr1 = 'model';
let bValue1 = bExpr1[expr1] const bValue1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }]; let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
let attr1 = ctx['options'][0]; let attr1 = ctx['options'][0];
let attr2 = bValue1 === ctx['options'][0]; let attr2 = bValue1 === ctx['options'][0];
@@ -532,19 +532,19 @@ exports[`t-model directive t-model with dynamic values on select options in fore
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
const bExpr1 = ctx['state']; const bExpr1 = ctx['state'];
const expr1 = 'model'; const expr1 = 'model';
let bValue1 = bExpr1[expr1] const bValue1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }]; let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['options']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['options']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`v\`] = v_block2[i1]; ctx[\`v\`] = v_block2[i1];
let key1 = ctx['v']; const key1 = ctx['v'];
let attr1 = ctx['v']; let attr1 = ctx['v'];
let attr2 = bValue1 === ctx['v']; let attr2 = bValue1 === ctx['v'];
let txt1 = ctx['v']; let txt1 = ctx['v'];
c_block2[i1] = withKey(block3([attr1, attr2, txt1]), key1); c_block2[i1] = withKey(block3([attr1, attr2, txt1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([hdlr1], [b2]); return block1([hdlr1], [b2]);
} }
}" }"
+147 -12
View File
@@ -14,17 +14,17 @@ exports[`t-on t-on expression captured in t-foreach 1`] = `
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"iter\\", 0); setContextValue(ctx, \\"iter\\", 0);
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['arr']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['arr']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1]; ctx[\`val\`] = v_block2[i1];
let key1 = ctx['val']; const key1 = ctx['val'];
const v1 = ctx['otherState']; const v1 = ctx['otherState'];
const v2 = ctx['iter']; const v2 = ctx['iter'];
let hdlr1 = [()=>v1.vals.push(v2+'_'+v2), ctx]; let hdlr1 = [()=>v1.vals.push(v2+'_'+v2), ctx];
setContextValue(ctx, \\"iter\\", ctx['iter']+1); setContextValue(ctx, \\"iter\\", ctx['iter']+1);
c_block2[i1] = withKey(block3([hdlr1]), key1); c_block2[i1] = withKey(block3([hdlr1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -41,11 +41,11 @@ exports[`t-on t-on expression in t-foreach 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].values); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].values);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1]; ctx[\`val\`] = v_block2[i1];
ctx[\`val_index\`] = i1; ctx[\`val_index\`] = i1;
let key1 = ctx['val']; const key1 = ctx['val'];
let txt1 = ctx['val_index']; let txt1 = ctx['val_index'];
let txt2 = ctx['val']+''; let txt2 = ctx['val']+'';
const v1 = ctx['otherState']; const v1 = ctx['otherState'];
@@ -53,7 +53,7 @@ exports[`t-on t-on expression in t-foreach 1`] = `
let hdlr1 = [()=>v1.vals.push(v2), ctx]; let hdlr1 = [()=>v1.vals.push(v2), ctx];
c_block2[i1] = withKey(block3([txt1, txt2, hdlr1]), key1); c_block2[i1] = withKey(block3([txt1, txt2, hdlr1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -73,11 +73,11 @@ exports[`t-on t-on expression in t-foreach with t-set 1`] = `
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"bossa\\", 'nova'); setContextValue(ctx, \\"bossa\\", 'nova');
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].values); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].values);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1]; ctx[\`val\`] = v_block2[i1];
ctx[\`val_index\`] = i1; ctx[\`val_index\`] = i1;
let key1 = ctx['val']; const key1 = ctx['val'];
setContextValue(ctx, \\"bossa\\", ctx['bossa']+'_'+ctx['val_index']); setContextValue(ctx, \\"bossa\\", ctx['bossa']+'_'+ctx['val_index']);
let txt1 = ctx['val_index']; let txt1 = ctx['val_index'];
let txt2 = ctx['val']+''; let txt2 = ctx['val']+'';
@@ -87,7 +87,7 @@ exports[`t-on t-on expression in t-foreach with t-set 1`] = `
let hdlr1 = [()=>v1.vals.push(v2+'_'+v3), ctx]; let hdlr1 = [()=>v1.vals.push(v2+'_'+v3), ctx];
c_block2[i1] = withKey(block3([txt1, txt2, hdlr1]), key1); c_block2[i1] = withKey(block3([txt1, txt2, hdlr1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -104,23 +104,82 @@ exports[`t-on t-on method call in t-foreach 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].values); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].values);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1]; ctx[\`val\`] = v_block2[i1];
ctx[\`val_index\`] = i1; ctx[\`val_index\`] = i1;
let key1 = ctx['val']; const key1 = ctx['val'];
let txt1 = ctx['val_index']; let txt1 = ctx['val_index'];
let txt2 = ctx['val']+''; let txt2 = ctx['val']+'';
const v1 = ctx['val']; const v1 = ctx['val'];
let hdlr1 = [()=>this.addVal(v1), ctx]; let hdlr1 = [()=>this.addVal(v1), ctx];
c_block2[i1] = withKey(block3([txt1, txt2, hdlr1]), key1); c_block2[i1] = withKey(block3([txt1, txt2, hdlr1]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
`; `;
exports[`t-on t-on on components 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { createCatcher } = helpers;
const catcher1 = createCatcher({\\"click\\":0});
return function template(ctx, node, key = \\"\\") {
const hdlr1 = [ctx['increment'], ctx];
return catcher1(component(\`Child\`, {value: ctx['state'].value}, key + \`__1\`, node, ctx), [hdlr1]);
}
}"
`;
exports[`t-on t-on on components 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button><block-text-0/></button>\`);
return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['props'].value;
return block1([txt1]);
}
}"
`;
exports[`t-on t-on on components, variation 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { createCatcher } = helpers;
const catcher1 = createCatcher({\\"click\\":0});
let block1 = createBlock(\`<div><span/><block-child-0/><p/></div>\`);
return function template(ctx, node, key = \\"\\") {
const hdlr1 = [ctx['increment'], ctx];
const b2 = catcher1(component(\`Child\`, {value: ctx['state'].value}, key + \`__1\`, node, ctx), [hdlr1]);
return block1([], [b2]);
}
}"
`;
exports[`t-on t-on on components, variation 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button><block-text-0/></button>\`);
return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['props'].value;
return block1([txt1]);
}
}"
`;
exports[`t-on t-on on destroyed components 1`] = ` exports[`t-on t-on on destroyed components 1`] = `
"function anonymous(bdom, helpers "function anonymous(bdom, helpers
) { ) {
@@ -151,3 +210,79 @@ exports[`t-on t-on on destroyed components 2`] = `
} }
}" }"
`; `;
exports[`t-on t-on on t-set-slots 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { capture, createCatcher, markRaw } = helpers;
const catcher1 = createCatcher({\\"click\\":0});
let block6 = createBlock(\`<p>something</p>\`);
let block7 = createBlock(\`<p>paragraph</p>\`);
function slot1(ctx, node, key = \\"\\") {
const b6 = block6();
const b7 = block7();
const hdlr1 = [()=>this.state.count++, ctx];
return catcher1(multi([b6, b7]), [hdlr1]);
}
return function template(ctx, node, key = \\"\\") {
const b2 = text(\` [\`);
const b3 = text(ctx['state'].count);
const b4 = text(\`] \`);
const ctx1 = capture(ctx);
const b8 = component(\`Child\`, {slots: markRaw({'myslot': {__render: slot1, __ctx: ctx1}})}, key + \`__1\`, node, ctx);
return multi([b2, b3, b4, b8]);
}
}"
`;
exports[`t-on t-on on t-set-slots 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { callSlot } = helpers;
return function template(ctx, node, key = \\"\\") {
return callSlot(ctx, node, key, 'myslot', false, null);
}
}"
`;
exports[`t-on t-on on t-slots 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { markRaw } = helpers;
let block1 = createBlock(\`<p>something</p>\`);
function slot1(ctx, node, key = \\"\\") {
return block1();
}
return function template(ctx, node, key = \\"\\") {
return component(\`Child\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__1\`, node, ctx);
}
}"
`;
exports[`t-on t-on on t-slots 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { callSlot, createCatcher } = helpers;
const catcher1 = createCatcher({\\"click\\":0});
return function template(ctx, node, key = \\"\\") {
const b2 = text(\` [\`);
const b3 = text(ctx['state'].count);
const b4 = text(\`] \`);
const hdlr1 = [()=>this.state.count++, ctx];
const b5 = catcher1(callSlot(ctx, node, key, 'default', false, null), [hdlr1]);
return multi([b2, b3, b4, b5]);
}
}"
`;
@@ -8,7 +8,7 @@ exports[`t-props basic use 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, Object.assign({}, ctx['some'].obj), key + \`__1\`, node, ctx); const b2 = component(\`Child\`, Object.assign({}, ctx['some'].obj), key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -60,7 +60,7 @@ exports[`t-props t-props and other props 1`] = `
let block1 = createBlock(\`<div><div><block-child-0/></div></div>\`); let block1 = createBlock(\`<div><div><block-child-0/></div></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Comp\`, Object.assign({}, ctx['state1'], {a: ctx['a']}), key + \`__1\`, node, ctx); const b2 = component(\`Comp\`, Object.assign({}, ctx['state1'], {a: ctx['a']}), key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -89,7 +89,7 @@ exports[`t-props t-props only 1`] = `
let block1 = createBlock(\`<div><div><block-child-0/></div></div>\`); let block1 = createBlock(\`<div><div><block-child-0/></div></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Comp\`, Object.assign({}, ctx['state']), key + \`__1\`, node, ctx); const b2 = component(\`Comp\`, Object.assign({}, ctx['state']), key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -117,7 +117,7 @@ exports[`t-props t-props with props 1`] = `
let block1 = createBlock(\`<div><block-child-0/></div>\`); let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, Object.assign({}, ctx['childProps'], {a: 1, b: 2}), key + \`__1\`, node, ctx); const b2 = component(\`Child\`, Object.assign({}, ctx['childProps'], {a: 1, b: 2}), key + \`__1\`, node, ctx);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -21,7 +21,7 @@ exports[`t-set slot setted value (with t-set) not accessible with t-esc 1`] = `
setContextValue(ctx, \\"iter\\", 'source'); setContextValue(ctx, \\"iter\\", 'source');
let txt1 = ctx['iter']; let txt1 = ctx['iter'];
const ctx1 = capture(ctx); const ctx1 = capture(ctx);
let b2 = component(\`Childcomp\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx1}})}, key + \`__1\`, node, ctx); const b2 = component(\`Childcomp\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx1}})}, key + \`__1\`, node, ctx);
let txt2 = ctx['iter']; let txt2 = ctx['iter'];
return block1([txt1, txt2], [b2]); return block1([txt1, txt2], [b2]);
} }
@@ -57,8 +57,8 @@ exports[`t-set slots with a t-set with a component in body 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
ctx[\`v\`] = new LazyValue(value1, ctx, node); ctx[\`v\`] = new LazyValue(value1, ctx, node);
let b3 = text(\` in slot \`); const b3 = text(\` in slot \`);
let b4 = safeOutput(ctx['v']); const b4 = safeOutput(ctx['v']);
return multi([b3, b4]); return multi([b3, b4]);
} }
@@ -80,8 +80,8 @@ exports[`t-set slots with a t-set with a component in body 2`] = `
let { callSlot } = helpers; let { callSlot } = helpers;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(\`Child \`); const b2 = text(\`Child \`);
let b3 = callSlot(ctx, node, key, 'default', false, {}); const b3 = callSlot(ctx, node, key, 'default', false, null);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -110,14 +110,14 @@ exports[`t-set slots with an t-set with a component in body 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
ctx[\`v\`] = new LazyValue(value1, ctx, node); ctx[\`v\`] = new LazyValue(value1, ctx, node);
let b5 = text(\` tea \`); const b5 = text(\` tea \`);
let b6 = safeOutput(ctx['v']); const b6 = safeOutput(ctx['v']);
return multi([b5, b6]); return multi([b5, b6]);
} }
function value1(ctx, node, key = \\"\\") { function value1(ctx, node, key = \\"\\") {
let b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
let b4 = block4(); const b4 = block4();
return multi([b3, b4]); return multi([b3, b4]);
} }
@@ -135,8 +135,8 @@ exports[`t-set slots with an t-set with a component in body 2`] = `
let { callSlot } = helpers; let { callSlot } = helpers;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(\`Blorg \`); const b2 = text(\`Blorg \`);
let b3 = callSlot(ctx, node, key, 'default', false, {}); const b3 = callSlot(ctx, node, key, 'default', false, null);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -184,8 +184,8 @@ exports[`t-set slots with an unused t-set with a component in body 2`] = `
let { callSlot } = helpers; let { callSlot } = helpers;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = text(\`Child \`); const b2 = text(\`Child \`);
let b3 = callSlot(ctx, node, key, 'default', false, {}); const b3 = callSlot(ctx, node, key, 'default', false, null);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -267,7 +267,7 @@ exports[`t-set t-set not altered by child comp 1`] = `
ctx[isBoundary] = 1 ctx[isBoundary] = 1
setContextValue(ctx, \\"iter\\", 'source'); setContextValue(ctx, \\"iter\\", 'source');
let txt1 = ctx['iter']; let txt1 = ctx['iter'];
let b2 = component(\`Childcomp\`, {}, key + \`__1\`, node, ctx); const b2 = component(\`Childcomp\`, {}, key + \`__1\`, node, ctx);
let txt2 = ctx['iter']; let txt2 = ctx['iter'];
return block1([txt1, txt2], [b2]); return block1([txt1, txt2], [b2]);
} }
@@ -335,7 +335,7 @@ exports[`t-set t-set with a component in body 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
ctx[\`v\`] = new LazyValue(value1, ctx, node); ctx[\`v\`] = new LazyValue(value1, ctx, node);
let b3 = safeOutput(ctx['v']); const b3 = safeOutput(ctx['v']);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -369,7 +369,7 @@ exports[`t-set t-set with something in body 1`] = `
ctx = Object.create(ctx); ctx = Object.create(ctx);
ctx[isBoundary] = 1 ctx[isBoundary] = 1
ctx[\`v\`] = new LazyValue(value1, ctx, node); ctx[\`v\`] = new LazyValue(value1, ctx, node);
let b3 = safeOutput(ctx['v']); const b3 = safeOutput(ctx['v']);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
+373 -36
View File
@@ -3,6 +3,7 @@ import {
Component, Component,
mount, mount,
onMounted, onMounted,
onRendered,
onWillStart, onWillStart,
onWillUnmount, onWillUnmount,
onWillUpdateProps, onWillUpdateProps,
@@ -1079,11 +1080,7 @@ test("concurrent renderings scenario 3", async () => {
stateC.fromC = "d"; stateC.fromC = "d";
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<div><p><span><i>1c</i></span></p></div>"); expect(fixture.innerHTML).toBe("<div><p><span><i>1c</i></span></p></div>");
expect([ expect([]).toBeLogged();
"ComponentC:willRender",
"ComponentD:willUpdateProps",
"ComponentC:rendered",
]).toBeLogged();
defB.resolve(); // resolve rendering initiated in A (still blocked in D) defB.resolve(); // resolve rendering initiated in A (still blocked in D)
await nextTick(); await nextTick();
@@ -1099,14 +1096,7 @@ test("concurrent renderings scenario 3", async () => {
defsD[0].resolve(); // resolve rendering initiated in C (should be ignored) defsD[0].resolve(); // resolve rendering initiated in C (should be ignored)
await nextTick(); await nextTick();
expect(ComponentD.prototype.someValue).toBeCalledTimes(1);
expect(fixture.innerHTML).toBe("<div><p><span><i>1c</i></span></p></div>");
expect([]).toBeLogged();
defsD[1].resolve(); // completely resolve rendering initiated in A
await nextTick();
expect(fixture.innerHTML).toBe("<div><p><span><i>2d</i></span></p></div>"); expect(fixture.innerHTML).toBe("<div><p><span><i>2d</i></span></p></div>");
expect(ComponentD.prototype.someValue).toBeCalledTimes(2);
expect([ expect([
"ComponentD:willRender", "ComponentD:willRender",
"ComponentD:rendered", "ComponentD:rendered",
@@ -1119,6 +1109,7 @@ test("concurrent renderings scenario 3", async () => {
"ComponentB:patched", "ComponentB:patched",
"ComponentA:patched", "ComponentA:patched",
]).toBeLogged(); ]).toBeLogged();
expect(ComponentD.prototype.someValue).toBeCalledTimes(2);
}); });
test("concurrent renderings scenario 4", async () => { test("concurrent renderings scenario 4", async () => {
@@ -1207,11 +1198,7 @@ test("concurrent renderings scenario 4", async () => {
stateC.fromC = "d"; stateC.fromC = "d";
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<div><p><span><i>1c</i></span></p></div>"); expect(fixture.innerHTML).toBe("<div><p><span><i>1c</i></span></p></div>");
expect([ expect([]).toBeLogged();
"ComponentC:willRender",
"ComponentD:willUpdateProps",
"ComponentC:rendered",
]).toBeLogged();
defB.resolve(); // resolve rendering initiated in A (still blocked in D) defB.resolve(); // resolve rendering initiated in A (still blocked in D)
await nextTick(); await nextTick();
@@ -1227,6 +1214,12 @@ test("concurrent renderings scenario 4", async () => {
defsD[1].resolve(); // completely resolve rendering initiated in A defsD[1].resolve(); // completely resolve rendering initiated in A
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<div><p><span><i>1c</i></span></p></div>");
expect(ComponentD.prototype.someValue).toBeCalledTimes(1);
expect([]).toBeLogged();
defsD[0].resolve(); // resolve rendering initiated in C (should be ignored)
await nextTick();
expect(fixture.innerHTML).toBe("<div><p><span><i>2d</i></span></p></div>"); expect(fixture.innerHTML).toBe("<div><p><span><i>2d</i></span></p></div>");
expect(ComponentD.prototype.someValue).toBeCalledTimes(2); expect(ComponentD.prototype.someValue).toBeCalledTimes(2);
expect([ expect([
@@ -1241,12 +1234,6 @@ test("concurrent renderings scenario 4", async () => {
"ComponentB:patched", "ComponentB:patched",
"ComponentA:patched", "ComponentA:patched",
]).toBeLogged(); ]).toBeLogged();
defsD[0].resolve(); // resolve rendering initiated in C (should be ignored)
await nextTick();
expect(fixture.innerHTML).toBe("<div><p><span><i>2d</i></span></p></div>");
expect(ComponentD.prototype.someValue).toBeCalledTimes(2);
expect([]).toBeLogged();
}); });
test("concurrent renderings scenario 5", async () => { test("concurrent renderings scenario 5", async () => {
@@ -2714,13 +2701,7 @@ test("delay willUpdateProps", async () => {
parent.render(); parent.render();
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("0_0"); expect(fixture.innerHTML).toBe("0_0");
expect([ expect(["Parent:willRender", "Child:willUpdateProps", "Parent:rendered"]).toBeLogged();
"Child:willRender",
"Child:rendered",
"Parent:willRender",
"Child:willUpdateProps",
"Parent:rendered",
]).toBeLogged();
promise = makeDeferred(); promise = makeDeferred();
const prom2 = promise; const prom2 = promise;
@@ -2837,13 +2818,9 @@ test("delay willUpdateProps with rendering grandchild", async () => {
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("0_0<div></div>"); expect(fixture.innerHTML).toBe("0_0<div></div>");
expect([ expect([
"DelayedChild:willRender",
"DelayedChild:rendered",
"GrandParent:willRender", "GrandParent:willRender",
"Parent:willUpdateProps", "Parent:willUpdateProps",
"GrandParent:rendered", "GrandParent:rendered",
"ReactiveChild:willRender",
"ReactiveChild:rendered",
"Parent:willRender", "Parent:willRender",
"DelayedChild:willUpdateProps", "DelayedChild:willUpdateProps",
"ReactiveChild:willUpdateProps", "ReactiveChild:willUpdateProps",
@@ -2864,8 +2841,6 @@ test("delay willUpdateProps with rendering grandchild", async () => {
"GrandParent:willRender", "GrandParent:willRender",
"Parent:willUpdateProps", "Parent:willUpdateProps",
"GrandParent:rendered", "GrandParent:rendered",
"ReactiveChild:willRender",
"ReactiveChild:rendered",
"Parent:willRender", "Parent:willRender",
"DelayedChild:willUpdateProps", "DelayedChild:willUpdateProps",
"ReactiveChild:willUpdateProps", "ReactiveChild:willUpdateProps",
@@ -3254,6 +3229,368 @@ test("rendering parent twice, with different props on child and stuff", async ()
]).toBeLogged(); ]).toBeLogged();
}); });
test("delayed rendering, but then initial rendering is cancelled by yet another render", async () => {
const promC = makeDeferred();
let stateB: any = null;
class D extends Component {
static template = xml`<button t-on-click="increment"><t t-esc="state.val"/></button>`;
state = useState({ val: 1 });
setup() {
useLogLifecycle();
}
increment() {
this.state.val++;
}
}
class C extends Component {
static template = xml`<D/><p><t t-esc="props.value"/></p>`;
static components = { D };
setup() {
useLogLifecycle();
onWillUpdateProps(() => promC);
}
}
class B extends Component {
static template = xml`<C value="state.someValue + props.value"/>`;
static components = { C };
state = useState({ someValue: 3 });
setup() {
useLogLifecycle();
stateB = this.state;
}
}
class A extends Component {
static template = xml`<B value="state.value"/>`;
static components = { B };
state = useState({ value: 33 });
setup() {
useLogLifecycle();
}
}
const parent = await mount(A, fixture);
expect(fixture.innerHTML).toBe("<button>1</button><p>36</p>");
expect([
"A:setup",
"A:willStart",
"A:willRender",
"B:setup",
"B:willStart",
"A:rendered",
"B:willRender",
"C:setup",
"C:willStart",
"B:rendered",
"C:willRender",
"D:setup",
"D:willStart",
"C:rendered",
"D:willRender",
"D:rendered",
"D:mounted",
"C:mounted",
"B:mounted",
"A:mounted",
]).toBeLogged();
// update B and C, but render is blocked by C willupdateProps
stateB.someValue = 5;
await nextTick();
expect(["B:willRender", "C:willUpdateProps", "B:rendered"]).toBeLogged();
// update D => render should be delayed, because B is currently rendering
fixture.querySelector("button")!.click();
await nextTick();
expect([]).toBeLogged();
// update A => render should go to B and cancel it
parent.state.value = 34;
await nextTick();
expect([
"A:willRender",
"B:willUpdateProps",
"A:rendered",
"B:willRender",
"C:willUpdateProps",
"B:rendered",
]).toBeLogged();
promC.resolve();
await nextTick();
expect([
"C:willRender",
"C:rendered",
"D:willRender",
"D:rendered",
"D:willPatch",
"D:patched",
"A:willPatch",
"B:willPatch",
"C:willPatch",
"C:patched",
"B:patched",
"A:patched",
]).toBeLogged();
expect(fixture.innerHTML).toBe("<button>2</button><p>39</p>");
});
test("delayed rendering, reusing fiber and stuff", async () => {
let prom1 = makeDeferred();
let prom2 = makeDeferred();
class C extends Component {
static template = xml`<button t-on-click="increment"><t t-esc="state.val"/></button>`;
state = useState({ val: 1 });
setup() {
useLogLifecycle();
}
increment() {
this.state.val++;
}
}
class B extends Component {
static template = xml`<t t-esc="props.value"/><C />`;
static components = { C };
setup() {
useLogLifecycle();
let flag = false;
onWillUpdateProps(() => {
flag = true;
return prom1;
});
onRendered(async () => {
if (flag) {
await nextMicroTick();
prom2.resolve();
}
});
}
}
class A extends Component {
static template = xml`<B value="state.value"/>`;
static components = { B };
state = useState({ value: 33 });
setup() {
useLogLifecycle();
}
}
const parent = await mount(A, fixture);
expect(fixture.innerHTML).toBe("33<button>1</button>");
expect([
"A:setup",
"A:willStart",
"A:willRender",
"B:setup",
"B:willStart",
"A:rendered",
"B:willRender",
"C:setup",
"C:willStart",
"B:rendered",
"C:willRender",
"C:rendered",
"C:mounted",
"B:mounted",
"A:mounted",
]).toBeLogged();
// initiate a render in A, but is blocked in B
parent.state.value = 34;
await nextTick();
expect(["A:willRender", "B:willUpdateProps", "A:rendered"]).toBeLogged();
// initiate a render in C => delayed because of render in A
fixture.querySelector("button")!.click();
await nextTick();
expect([]).toBeLogged();
// wait for render in A to be completed
prom1.resolve();
await prom2;
expect(["B:willRender", "B:rendered", "C:willRender", "C:rendered"]).toBeLogged();
// initiate a new render in A => fiber will be reused
parent.state.value = 355;
await nextTick();
expect(fixture.innerHTML).toBe("355<button>2</button>");
expect([
"A:willRender",
"B:willUpdateProps",
"A:rendered",
"B:willRender",
"B:rendered",
"A:willPatch",
"B:willPatch",
"B:patched",
"A:patched",
"C:willPatch",
"C:patched",
]).toBeLogged();
});
test("delayed rendering, then component is destroyed and stuff", async () => {
let prom1 = makeDeferred();
class C extends Component {
static template = xml`<button t-on-click="increment"><t t-esc="state.val"/></button>`;
state = useState({ val: 1 });
setup() {
useLogLifecycle();
}
increment() {
this.state.val++;
}
}
class B extends Component {
static template = xml`<t t-esc="props.value"/><t t-if="props.value lt 10"><C /></t>`;
static components = { C };
setup() {
useLogLifecycle();
onWillUpdateProps(() => prom1);
}
}
class A extends Component {
static template = xml`<B value="state.value"/>`;
static components = { B };
state = useState({ value: 3 });
setup() {
useLogLifecycle();
}
}
const parent = await mount(A, fixture);
expect(fixture.innerHTML).toBe("3<button>1</button>");
expect([
"A:setup",
"A:willStart",
"A:willRender",
"B:setup",
"B:willStart",
"A:rendered",
"B:willRender",
"C:setup",
"C:willStart",
"B:rendered",
"C:willRender",
"C:rendered",
"C:mounted",
"B:mounted",
"A:mounted",
]).toBeLogged();
// initiate a render in C (so will be first task)
fixture.querySelector("button")!.click();
// initiate a render in A, but is blocked in B. the render will destroy c. also,
// it blocks the render C
parent.state.value = 34;
await nextTick();
expect(["A:willRender", "B:willUpdateProps", "A:rendered"]).toBeLogged();
// wait for render in A to be completed
prom1.resolve();
await nextTick();
expect(fixture.innerHTML).toBe("34");
expect([
"B:willRender",
"B:rendered",
"A:willPatch",
"B:willPatch",
"C:willUnmount",
"C:willDestroy",
"B:patched",
"A:patched",
]).toBeLogged();
await nextTick();
});
test("delayed rendering, reusing fiber then component is destroyed and stuff", async () => {
let prom1 = makeDeferred();
class C extends Component {
static template = xml`<button t-on-click="increment"><t t-esc="state.val"/></button>`;
state = useState({ val: 1 });
setup() {
useLogLifecycle();
}
increment() {
this.state.val++;
}
}
class B extends Component {
static template = xml`<t t-esc="props.value"/><C />`;
static components = { C };
setup() {
useLogLifecycle();
onWillUpdateProps(() => prom1);
}
}
class A extends Component {
static template = xml`A<t t-if="state.value lt 15"><B value="state.value"/></t>`;
static components = { B };
state = useState({ value: 3 });
setup() {
useLogLifecycle();
}
}
const parent = await mount(A, fixture);
expect(fixture.innerHTML).toBe("A3<button>1</button>");
expect([
"A:setup",
"A:willStart",
"A:willRender",
"B:setup",
"B:willStart",
"A:rendered",
"B:willRender",
"C:setup",
"C:willStart",
"B:rendered",
"C:willRender",
"C:rendered",
"C:mounted",
"B:mounted",
"A:mounted",
]).toBeLogged();
// initiate a render in A, but is blocked in B
parent.state.value = 5;
await nextTick();
expect(["A:willRender", "B:willUpdateProps", "A:rendered"]).toBeLogged();
// initiate a render in C (will be delayed because of render in A)
fixture.querySelector("button")!.click();
await nextTick();
expect([]).toBeLogged();
// initiate a render in A, that will destroy B
parent.state.value = 23;
await nextTick();
expect(fixture.innerHTML).toBe("A");
expect([
"A:willRender",
"A:rendered",
"A:willPatch",
"B:willUnmount",
"C:willUnmount",
"C:willDestroy",
"B:willDestroy",
"A:patched",
]).toBeLogged();
});
// test.skip("components with shouldUpdate=false", async () => { // test.skip("components with shouldUpdate=false", async () => {
// const state = { p: 1, cc: 10 }; // const state = { p: 1, cc: 10 };
+46
View File
@@ -5,6 +5,8 @@ import {
onPatched, onPatched,
onWillPatch, onWillPatch,
onWillStart, onWillStart,
onWillRender,
onRendered,
onWillUnmount, onWillUnmount,
useState, useState,
xml, xml,
@@ -199,6 +201,50 @@ describe("errors and promises", () => {
expect(mockConsoleWarn).toBeCalledTimes(1); expect(mockConsoleWarn).toBeCalledTimes(1);
}); });
test("errors in onWillRender/onRender aren't wrapped more than once", async () => {
class App extends Component {
static template = xml`<div>abc</div>`;
setup() {
onWillRender(() => {
throw new Error("boom in onWillRender");
});
onRendered(() => {
throw new Error("boom in onRendered");
});
}
}
let error: Error;
try {
await mount(App, fixture, { test: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
`The following error occurred in onWillRender: "boom in onWillRender"`
);
});
test("error while rendering component isn't wrapped by onWillRender/onRendered", async () => {
class App extends Component {
static template = xml`<div t-att-class="{ 'invalid: 5 }">abc</div>`;
setup() {
onWillRender(() => {});
onRendered(() => {});
}
}
let error: Error;
try {
await mount(App, fixture, { test: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe("Tokenizer error: could not tokenize `{ 'invalid: 5 }`");
});
test("an error in willPatch call will reject the render promise", async () => { test("an error in willPatch call will reject the render promise", async () => {
class Root extends Component { class Root extends Component {
static template = xml`<div><t t-esc="val"/></div>`; static template = xml`<div><t t-esc="val"/></div>`;
+30
View File
@@ -632,5 +632,35 @@ describe("hooks", () => {
"cleaning up for 1", "cleaning up for 1",
]); ]);
}); });
test("properly behaves when the effect function throws", async () => {
let originalconsoleError = console.error;
let originalconsoleWarn = console.warn;
console.error = jest.fn(() => {});
console.warn = jest.fn(() => {});
class MyComponent extends Component {
static template = xml`<div/>`;
setup() {
useEffect(
() => {
throw new Error("Intentional error");
},
() => []
);
}
}
try {
await mount(MyComponent, fixture);
} catch (e: any) {
expect(e.message).toBe("Intentional error");
}
// no console.error because the error has been caught in this test
expect(console.error).toHaveBeenCalledTimes(0);
console.error = originalconsoleError;
// 1 console.warn because app is destroyed
expect(console.warn).toHaveBeenCalledTimes(1);
console.warn = originalconsoleWarn;
});
}); });
}); });
+78
View File
@@ -14,6 +14,7 @@ import {
logStep, logStep,
makeDeferred, makeDeferred,
makeTestFixture, makeTestFixture,
nextMicroTick,
nextTick, nextTick,
snapshotEverything, snapshotEverything,
useLogLifecycle, useLogLifecycle,
@@ -104,6 +105,83 @@ describe("lifecycle hooks", () => {
await mount(Test, fixture); await mount(Test, fixture);
}); });
test("timeout in onWillStart emits a warning", async () => {
const { warn } = console;
let warnArgs: any[];
console.warn = jest.fn((...args) => (warnArgs = args));
const { setTimeout } = window;
let timeoutCbs: any = {};
let timeoutId = 0;
window.setTimeout = ((cb: any) => {
timeoutCbs[++timeoutId] = cb;
return timeoutId;
}) as any;
class Test extends Component {
static template = xml`<span/>`;
setup() {
onWillStart(() => new Promise(() => {}));
}
}
mount(Test, fixture, { test: true });
nextTick();
for (const id in timeoutCbs) {
timeoutCbs[id]();
delete timeoutCbs[id];
}
await nextMicroTick();
await nextMicroTick();
expect(console.warn).toHaveBeenCalledTimes(1);
expect(warnArgs![0]!.message).toBe("onWillStart's promise hasn't resolved after 3 seconds");
console.warn = warn;
window.setTimeout = setTimeout;
});
test("timeout in onWillUpdateProps emits a warning", async () => {
class Child extends Component {
static template = xml``;
setup() {
onWillUpdateProps(() => new Promise(() => {}));
}
}
class Parent extends Component {
static template = xml`<Child prop="state.prop"/>`;
static components = { Child };
state = useState({ prop: 1 });
}
const parent = await mount(Parent, fixture, { test: true });
const { warn } = console;
let warnArgs: any[];
console.warn = jest.fn((...args) => (warnArgs = args));
const { setTimeout } = window;
let timeoutCbs: any = {};
let timeoutId = 0;
window.setTimeout = ((cb: any) => {
timeoutCbs[++timeoutId] = cb;
return timeoutId;
}) as any;
parent.state.prop = 2;
let tick = nextTick();
for (const id in timeoutCbs) {
timeoutCbs[id]();
delete timeoutCbs[id];
}
await tick;
tick = nextTick();
for (const id in timeoutCbs) {
timeoutCbs[id]();
delete timeoutCbs[id];
}
await tick;
expect(console.warn).toHaveBeenCalledTimes(1);
expect(warnArgs![0]!.message).toBe(
"onWillUpdateProps's promise hasn't resolved after 3 seconds"
);
console.warn = warn;
window.setTimeout = setTimeout;
});
test("mounted hook is called if mounted in DOM", async () => { test("mounted hook is called if mounted in DOM", async () => {
let mounted = false; let mounted = false;
class Test extends Component { class Test extends Component {
+45 -1
View File
@@ -8,7 +8,7 @@ import {
useState, useState,
xml, xml,
} from "../../src"; } from "../../src";
import { makeTestFixture, nextTick, snapshotEverything } from "../helpers"; import { makeTestFixture, nextTick, snapshotEverything, useLogLifecycle } from "../helpers";
let fixture: HTMLElement; let fixture: HTMLElement;
@@ -155,4 +155,48 @@ describe("reactivity in lifecycle", () => {
expect(steps).toEqual([2]); expect(steps).toEqual([2]);
expect(fixture.innerHTML).toBe("<div>2</div>"); expect(fixture.innerHTML).toBe("<div>2</div>");
}); });
test("Child component doesn't render when state they depend on changes but their parent is about to unmount them", async () => {
class Child extends Component {
static template = xml`<t t-esc="props.state.content.a"/>`;
setup() {
useLogLifecycle();
}
}
class Parent extends Component {
static template = xml`<Child t-if="state.renderChild" state="state"/>`;
static components = { Child };
state: any = useState({ renderChild: true, content: { a: 2 } });
setup() {
useLogLifecycle();
}
}
const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("2");
expect([
"Parent:setup",
"Parent:willStart",
"Parent:willRender",
"Child:setup",
"Child:willStart",
"Parent:rendered",
"Child:willRender",
"Child:rendered",
"Child:mounted",
"Parent:mounted",
]).toBeLogged();
parent.state.content = null;
parent.state.renderChild = false;
await nextTick();
expect([
"Parent:willRender",
"Parent:rendered",
"Parent:willPatch",
"Child:willUnmount",
"Child:willDestroy",
"Parent:patched",
]).toBeLogged();
});
}); });
+103
View File
@@ -142,4 +142,107 @@ describe("t-on", () => {
buttons[1].click(); buttons[1].click();
expect(comp.otherState.vals).toStrictEqual(["0_0", "1_1"]); expect(comp.otherState.vals).toStrictEqual(["0_0", "1_1"]);
}); });
test("t-on on components", async () => {
class Child extends Component {
static template = xml`<button t-esc="props.value"/>`;
}
class Parent extends Component {
static template = xml`<Child t-on-click="increment" value="state.value"/>`;
static components = { Child };
state = useState({ value: 1 });
increment() {
this.state.value++;
}
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<button>1</button>");
fixture.querySelector("button")!.click();
await nextTick();
expect(fixture.innerHTML).toBe("<button>2</button>");
});
test("t-on on components, variation", async () => {
class Child extends Component {
static template = xml`<button t-esc="props.value"/>`;
}
class Parent extends Component {
static template = xml`
<div>
<span/>
<Child t-on-click="increment" value="state.value"/>
<p/>
</div>`;
static components = { Child };
state = useState({ value: 1 });
increment() {
this.state.value++;
}
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<div><span></span><button>1</button><p></p></div>");
fixture.querySelector("span")!.click();
await nextTick();
expect(fixture.innerHTML).toBe("<div><span></span><button>1</button><p></p></div>");
fixture.querySelector("button")!.click();
await nextTick();
expect(fixture.innerHTML).toBe("<div><span></span><button>2</button><p></p></div>");
fixture.querySelector("p")!.click();
await nextTick();
expect(fixture.innerHTML).toBe("<div><span></span><button>2</button><p></p></div>");
});
test("t-on on t-slots", async () => {
class Child extends Component {
static template = xml`
[<t t-esc="state.count"/>]
<t t-slot="default" t-on-click="() => this.state.count++"/>`;
state = useState({ count: 0 });
}
class Parent extends Component {
static template = xml`
<Child>
<p>something</p>
</Child>`;
static components = { Child };
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe(" [0] <p>something</p>");
fixture.querySelector("p")!.click();
await nextTick();
expect(fixture.innerHTML).toBe(" [1] <p>something</p>");
});
test("t-on on t-set-slots", async () => {
class Child extends Component {
static template = xml`<t t-slot="myslot"/>`;
}
class Parent extends Component {
static template = xml`
[<t t-esc="state.count"/>]
<Child>
<t t-set-slot="myslot" t-on-click="() => this.state.count++">
<p>something</p>
<p>paragraph</p>
</t>
</Child>`;
static components = { Child };
state = useState({ count: 0 });
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe(" [0] <p>something</p><p>paragraph</p>");
fixture.querySelector("p")!.click();
await nextTick();
expect(fixture.innerHTML).toBe(" [1] <p>something</p><p>paragraph</p>");
});
}); });
+1 -1
View File
@@ -49,7 +49,7 @@ export async function nextTick(): Promise<void> {
interface Deferred extends Promise<any> { interface Deferred extends Promise<any> {
resolve(val?: any): void; resolve(val?: any): void;
reject(): void; reject(val?: any): void;
} }
export function makeDeferred(): Deferred { export function makeDeferred(): Deferred {
+60 -60
View File
@@ -7,18 +7,18 @@ exports[`Portal Add and remove portals 1`] = `
let { prepareList, Portal, capture, withKey } = helpers; let { prepareList, Portal, capture, withKey } = helpers;
function slot1(ctx, node, key = \\"\\") { function slot1(ctx, node, key = \\"\\") {
let b3 = text(\` Portal\`); const b3 = text(\` Portal\`);
let b4 = text(ctx['portalId']); const b4 = text(ctx['portalId']);
return multi([b3, b4]); return multi([b3, b4]);
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['portalIds']); const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['portalIds']);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`portalId\`] = v_block1[i1]; ctx[\`portalId\`] = v_block1[i1];
let key1 = ctx['portalId']; const key1 = ctx['portalId'];
const ctx1 = capture(ctx); const ctx1 = capture(ctx);;
c_block1[i1] = withKey(component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx), key1); c_block1[i1] = withKey(component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx), key1);
} }
return list(c_block1); return list(c_block1);
@@ -41,11 +41,11 @@ exports[`Portal Add and remove portals on div 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['portalIds']); const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['portalIds']);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`portalId\`] = v_block1[i1]; ctx[\`portalId\`] = v_block1[i1];
let key1 = ctx['portalId']; const key1 = ctx['portalId'];
const ctx1 = capture(ctx); const ctx1 = capture(ctx);;
c_block1[i1] = withKey(component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx), key1); c_block1[i1] = withKey(component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx), key1);
} }
return list(c_block1); return list(c_block1);
@@ -62,20 +62,20 @@ exports[`Portal Add and remove portals with t-foreach 1`] = `
let block2 = createBlock(\`<div><block-text-0/><block-child-0/></div>\`); let block2 = createBlock(\`<div><block-text-0/><block-child-0/></div>\`);
function slot1(ctx, node, key = \\"\\") { function slot1(ctx, node, key = \\"\\") {
let b4 = text(\` Portal\`); const b4 = text(\` Portal\`);
let b5 = text(ctx['portalId']); const b5 = text(ctx['portalId']);
return multi([b4, b5]); return multi([b4, b5]);
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['portalIds']); const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['portalIds']);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`portalId\`] = v_block1[i1]; ctx[\`portalId\`] = v_block1[i1];
let key1 = ctx['portalId']; const key1 = ctx['portalId'];
let txt1 = ctx['portalId']; let txt1 = ctx['portalId'];
const ctx1 = capture(ctx); const ctx1 = capture(ctx);;
let b6 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx); const b6 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx);
c_block1[i1] = withKey(block2([txt1], [b6]), key1); c_block1[i1] = withKey(block2([txt1], [b6]), key1);
} }
return list(c_block1); return list(c_block1);
@@ -92,20 +92,20 @@ exports[`Portal Add and remove portals with t-foreach and destroy 1`] = `
let block2 = createBlock(\`<div><block-text-0/><block-child-0/></div>\`); let block2 = createBlock(\`<div><block-text-0/><block-child-0/></div>\`);
function slot1(ctx, node, key = \\"\\") { function slot1(ctx, node, key = \\"\\") {
let b4 = text(\` Portal\`); const b4 = text(\` Portal\`);
let b5 = text(ctx['portalId']); const b5 = text(ctx['portalId']);
return multi([b4, b5]); return multi([b4, b5]);
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['portalIds']); const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['portalIds']);;
for (let i1 = 0; i1 < l_block1; i1++) { for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`portalId\`] = v_block1[i1]; ctx[\`portalId\`] = v_block1[i1];
let key1 = ctx['portalId']; const key1 = ctx['portalId'];
let txt1 = ctx['portalId']; let txt1 = ctx['portalId'];
const ctx1 = capture(ctx); const ctx1 = capture(ctx);;
let b6 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx); const b6 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx);
c_block1[i1] = withKey(block2([txt1], [b6]), key1); c_block1[i1] = withKey(block2([txt1], [b6]), key1);
} }
return list(c_block1); return list(c_block1);
@@ -123,23 +123,23 @@ exports[`Portal Add and remove portals with t-foreach inside div 1`] = `
let block3 = createBlock(\`<div><block-text-0/><block-child-0/></div>\`); let block3 = createBlock(\`<div><block-text-0/><block-child-0/></div>\`);
function slot1(ctx, node, key = \\"\\") { function slot1(ctx, node, key = \\"\\") {
let b5 = text(\` Portal\`); const b5 = text(\` Portal\`);
let b6 = text(ctx['portalId']); const b6 = text(ctx['portalId']);
return multi([b5, b6]); return multi([b5, b6]);
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['portalIds']); const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['portalIds']);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`portalId\`] = v_block2[i1]; ctx[\`portalId\`] = v_block2[i1];
let key1 = ctx['portalId']; const key1 = ctx['portalId'];
let txt1 = ctx['portalId']; let txt1 = ctx['portalId'];
const ctx1 = capture(ctx); const ctx1 = capture(ctx);;
let b7 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx); const b7 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx);
c_block2[i1] = withKey(block3([txt1], [b7]), key1); c_block2[i1] = withKey(block3([txt1], [b7]), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -158,7 +158,7 @@ exports[`Portal Portal composed with t-slot 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(\`Child\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx); const b3 = component(\`Child\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -171,7 +171,7 @@ exports[`Portal Portal composed with t-slot 2`] = `
let { Portal, callSlot } = helpers; let { Portal, callSlot } = helpers;
function slot1(ctx, node, key = \\"\\") { function slot1(ctx, node, key = \\"\\") {
return callSlot(ctx, node, key, 'default', false, {}); return callSlot(ctx, node, key, 'default', false, null);
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
@@ -208,7 +208,7 @@ exports[`Portal basic use of portal 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -228,7 +228,7 @@ exports[`Portal basic use of portal in dev mode 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -248,7 +248,7 @@ exports[`Portal basic use of portal on div 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -345,14 +345,14 @@ exports[`Portal conditional use of Portal with child and div 2`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList([1]); const [k_block2, v_block2, l_block2, c_block2] = prepareList([1]);;
for (let i1 = 0; i1 < l_block2; i1++) { for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`elem\`] = v_block2[i1]; ctx[\`elem\`] = v_block2[i1];
let key1 = ctx['elem']; const key1 = ctx['elem'];
const ctx1 = capture(ctx); const ctx1 = capture(ctx);;
c_block2[i1] = withKey(component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx), key1); c_block2[i1] = withKey(component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx), key1);
} }
let b2 = list(c_block2); const b2 = list(c_block2);
return block1([], [b2]); return block1([], [b2]);
} }
}" }"
@@ -368,7 +368,7 @@ exports[`Portal conditional use of Portal with child and div, variation 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2; let b2;
if (ctx['state'].hasPortal) { if (ctx['state'].hasPortal) {
let b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx); const b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
b2 = block2([], [b3]); b2 = block2([], [b3]);
} }
return multi([b2]); return multi([b2]);
@@ -390,16 +390,16 @@ exports[`Portal conditional use of Portal with child and div, variation 2`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2 = block2(); const b2 = block2();
ctx = Object.create(ctx); ctx = Object.create(ctx);
const [k_block3, v_block3, l_block3, c_block3] = prepareList([1]); const [k_block3, v_block3, l_block3, c_block3] = prepareList([1]);;
for (let i1 = 0; i1 < l_block3; i1++) { for (let i1 = 0; i1 < l_block3; i1++) {
ctx[\`elem\`] = v_block3[i1]; ctx[\`elem\`] = v_block3[i1];
let key1 = ctx['elem']; const key1 = ctx['elem'];
const ctx1 = capture(ctx); const ctx1 = capture(ctx);;
c_block3[i1] = withKey(component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx), key1); c_block3[i1] = withKey(component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx), key1);
} }
let b3 = list(c_block3); const b3 = list(c_block3);
return multi([b2, b3]); return multi([b2, b3]);
} }
}" }"
@@ -421,7 +421,7 @@ exports[`Portal conditional use of Portal with div 1`] = `
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b2; let b2;
if (ctx['state'].hasPortal) { if (ctx['state'].hasPortal) {
let b4 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b4 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
b2 = block2([], [b4]); b2 = block2([], [b4]);
} }
return multi([b2]); return multi([b2]);
@@ -484,7 +484,7 @@ exports[`Portal portal could have dynamically no content 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b4 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b4 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b4]); return block1([], [b4]);
} }
}" }"
@@ -503,7 +503,7 @@ exports[`Portal portal destroys on crash 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__2\`, node, ctx); const b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__2\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -536,7 +536,7 @@ exports[`Portal portal with child and props 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__2\`, node, ctx); const b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__2\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -578,7 +578,7 @@ exports[`Portal portal with dynamic body 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b5 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b5 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b5]); return block1([], [b5]);
} }
}" }"
@@ -595,13 +595,13 @@ exports[`Portal portal with many children 1`] = `
let block4 = createBlock(\`<p>2</p>\`); let block4 = createBlock(\`<p>2</p>\`);
function slot1(ctx, node, key = \\"\\") { function slot1(ctx, node, key = \\"\\") {
let b3 = block3(); const b3 = block3();
let b4 = block4(); const b4 = block4();
return multi([b3, b4]); return multi([b3, b4]);
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b5 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b5 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b5]); return block1([], [b5]);
} }
}" }"
@@ -624,7 +624,7 @@ exports[`Portal portal with no content 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b4 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b4 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b4]); return block1([], [b4]);
} }
}" }"
@@ -643,7 +643,7 @@ exports[`Portal portal with only text as content 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -663,7 +663,7 @@ exports[`Portal portal with target not in dom 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: '#does-not-exist',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b3 = component(Portal, {target: '#does-not-exist',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -682,7 +682,7 @@ exports[`Portal portal's parent's env is not polluted 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__2\`, node, ctx); const b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__2\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -735,7 +735,7 @@ exports[`Portal simple catchError with portal 2`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -755,7 +755,7 @@ exports[`Portal with target in template (after portal) 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: '#local-target',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b3 = component(Portal, {target: '#local-target',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -775,7 +775,7 @@ exports[`Portal with target in template (before portal) 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: '#local-target',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b3 = component(Portal, {target: '#local-target',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -795,7 +795,7 @@ exports[`Portal: Props validation target must be a valid selector 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: ' ',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b3 = component(Portal, {target: ' ',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -815,7 +815,7 @@ exports[`Portal: Props validation target must be a valid selector 2 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: 'aa',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); const b3 = component(Portal, {target: 'aa',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
@@ -834,7 +834,7 @@ exports[`Portal: UI/UX focus is kept across re-renders 1`] = `
} }
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
let b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__2\`, node, ctx); const b3 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__2\`, node, ctx);
return block1([], [b3]); return block1([], [b3]);
} }
}" }"
+104
View File
@@ -208,6 +208,46 @@ describe("Reactivity", () => {
expect(n).toBe(1); // two operations but only one notification expect(n).toBe(1); // two operations but only one notification
}); });
test("batched: modifying the reactive in the callback doesn't break reactivity", async () => {
let n = 0;
let obj = { a: 1 };
const state = createReactive(
obj,
batched(() => {
state.a; // subscribe to a
state.a = 2;
n++;
})
);
expect(n).toBe(0);
state.a = 2;
expect(n).toBe(0);
await nextMicroTick();
expect(n).toBe(0); // key has not be read yet
state.a = state.a + 5; // key is read and then modified
expect(n).toBe(0);
await nextMicroTick();
expect(n).toBe(1);
// the write a = 2 inside the batched callback triggered another notification, wait for it
await nextMicroTick();
expect(n).toBe(2);
// Should now be stable as we're writing the same value again
await nextMicroTick();
expect(n).toBe(2);
// Do it again to check it's not broken
state.a = state.a + 5; // key is read and then modified
expect(n).toBe(2);
await nextMicroTick();
expect(n).toBe(3);
// the write a = 2 inside the batched callback triggered another notification, wait for it
await nextMicroTick();
expect(n).toBe(4);
// Should now be stable as we're writing the same value again
await nextMicroTick();
expect(n).toBe(4);
});
test("setting property to same value does not trigger callback", async () => { test("setting property to same value does not trigger callback", async () => {
let n = 0; let n = 0;
const state = createReactive({ a: 1 }, () => n++); const state = createReactive({ a: 1 }, () => n++);
@@ -1095,6 +1135,13 @@ describe("Reactivity", () => {
expect(n).toBe(1); expect(n).toBe(1);
expect(state.k).toEqual({ n: 2 }); expect(state.k).toEqual({ n: 2 });
}); });
test("can access properties on reactive of frozen objects", async () => {
const obj = Object.freeze({ a: {} });
const state = createReactive(obj);
expect(() => state.a).not.toThrow();
expect(state.a).toBe(obj.a);
});
}); });
describe("Collections", () => { describe("Collections", () => {
@@ -1245,6 +1292,33 @@ describe("Collections", () => {
reactiveObj.a = 1; // setting same value again shouldn't notify reactiveObj.a = 1; // setting same value again shouldn't notify
expect(observer).toHaveBeenCalledTimes(1); expect(observer).toHaveBeenCalledTimes(1);
}); });
test("iterating with forEach returns reactives", async () => {
const keyObj = { a: 2 };
const thisArg = {};
const observer = jest.fn();
const state = reactive(new Set([keyObj]), observer);
let reactiveKeyObj: any, reactiveValObj: any, thisObj: any, mapObj: any;
state.forEach(function (this: any, val, key, map) {
[reactiveValObj, reactiveKeyObj, mapObj, thisObj] = [val, key, map, this];
}, thisArg);
expect(reactiveKeyObj).not.toBe(keyObj);
expect(reactiveValObj).not.toBe(keyObj);
expect(mapObj).toBe(state); // third argument should be the reactive
expect(thisObj).toBe(thisArg); // thisArg should not be made reactive
expect(toRaw(reactiveKeyObj as any)).toBe(keyObj);
expect(toRaw(reactiveValObj as any)).toBe(keyObj);
expect(reactiveKeyObj).toBe(reactiveValObj); // reactiveKeyObj and reactiveValObj should be the same object
reactiveKeyObj!.a = 0;
reactiveValObj!.a = 0;
expect(observer).toHaveBeenCalledTimes(0);
reactiveKeyObj!.a; // observe key "a" in key sub-reactive;
reactiveKeyObj!.a = 1;
expect(observer).toHaveBeenCalledTimes(1);
reactiveKeyObj!.a = 1; // setting same value again shouldn't notify
reactiveValObj!.a = 1;
expect(observer).toHaveBeenCalledTimes(1);
});
}); });
describe("WeakSet", () => { describe("WeakSet", () => {
@@ -1467,6 +1541,36 @@ describe("Collections", () => {
reactiveValObj.a = 1; reactiveValObj.a = 1;
expect(observer).toHaveBeenCalledTimes(2); expect(observer).toHaveBeenCalledTimes(2);
}); });
test("iterating with forEach returns reactives", async () => {
const keyObj = { a: 2 };
const valObj = { a: 2 };
const thisArg = {};
const observer = jest.fn();
const state = reactive(new Map([[keyObj, valObj]]), observer);
let reactiveKeyObj: any, reactiveValObj: any, thisObj: any, mapObj: any;
state.forEach(function (this: any, val, key, map) {
[reactiveValObj, reactiveKeyObj, mapObj, thisObj] = [val, key, map, this];
}, thisArg);
expect(reactiveKeyObj).not.toBe(keyObj);
expect(reactiveValObj).not.toBe(valObj);
expect(mapObj).toBe(state); // third argument should be the reactive
expect(thisObj).toBe(thisArg); // thisArg should not be made reactive
expect(toRaw(reactiveKeyObj as any)).toBe(keyObj);
expect(toRaw(reactiveValObj as any)).toBe(valObj);
reactiveKeyObj!.a = 0;
reactiveValObj!.a = 0;
expect(observer).toHaveBeenCalledTimes(0);
reactiveKeyObj!.a; // observe key "a" in key sub-reactive;
reactiveKeyObj!.a = 1;
expect(observer).toHaveBeenCalledTimes(1);
reactiveValObj!.a; // observe key "a" in val sub-reactive;
reactiveValObj!.a = 1;
expect(observer).toHaveBeenCalledTimes(2);
reactiveKeyObj!.a = 1; // setting same value again shouldn't notify
reactiveValObj!.a = 1;
expect(observer).toHaveBeenCalledTimes(2);
});
}); });
describe("WeakMap", () => { describe("WeakMap", () => {
+20
View File
@@ -50,4 +50,24 @@ describe("batched", () => {
await nextMicroTick(); await nextMicroTick();
expect(n).toBe(1); expect(n).toBe(1);
}); });
test("calling batched function from within the callback is not treated as part of the original batch", async () => {
let n = 0;
let fn = batched(() => {
n++;
if (n === 1) {
fn();
}
});
expect(n).toBe(0);
fn();
expect(n).toBe(0);
await nextMicroTick(); // First batch
expect(n).toBe(1);
await nextMicroTick(); // Second batch initiated from within the callback
expect(n).toBe(2);
await nextMicroTick();
expect(n).toBe(2);
});
}); });
+4 -4
View File
@@ -24,8 +24,7 @@ class Root extends Component {
} }
} }
// dev=false for benchmarking. we don't want to benchmark dev code! mount(Root, document.body, { templates: TEMPLATES, dev: true });`;
mount(Root, document.body, { templates: TEMPLATES, dev: false });`;
const COMPONENTS_XML = /*xml*/` const COMPONENTS_XML = /*xml*/`
<templates> <templates>
@@ -934,7 +933,7 @@ const env = {
ui: createUI() ui: createUI()
}; };
mount(Root, document.body, { templates: TEMPLATES, env }); mount(Root, document.body, { templates: TEMPLATES, env, dev: true });
`; `;
const RESPONSIVE_XML = /*xml*/` const RESPONSIVE_XML = /*xml*/`
@@ -1741,7 +1740,8 @@ class Root extends Component {
} }
mount(Root, document.body, { templates: TEMPLATES, dev: true }); // dev=false for benchmarking. we don't want to benchmark dev code!
mount(Root, document.body, { templates: TEMPLATES, dev: false });
`; `;