Compare commits

..

1 Commits

Author SHA1 Message Date
Bruno Boi 030cc2f08a wip [FIX] parser: account for CR/LF text nodes 2022-07-06 12:07:20 +02:00
98 changed files with 6408 additions and 4951 deletions
+1 -1
View File
@@ -124,5 +124,5 @@ npm install @odoo/owl
If you want to use a simple `<script>` tag, the last release can be downloaded here:
- [owl](https://github.com/odoo/owl/releases/latest)
- [owl-1.4.10](https://github.com/odoo/owl/releases/tag/v1.4.10)
+2 -7
View File
@@ -502,10 +502,6 @@ deleteTask(task) {
Notice that the `onDelete` prop is defined with a `.bind` suffix: this is a special
suffix that makes sure the function callback is bound to the component.
Notice also that we have two functions named `deleteTask`. The one in the Task
component just delegates the work to the Root component that owns the task list
via the `onDelete` property.
## 10. Using a store
Looking at the code, it is apparent that all the code handling tasks is scattered
@@ -774,11 +770,10 @@ For reference, here is the final code:
<meta charset="UTF-8" />
<title>OWL Todo App</title>
<link rel="stylesheet" href="app.css" />
</head>
<body>
<script src="owl.js"></script>
<script src="app.js"></script>
</body>
</head>
<body></body>
</html>
```
+1 -2
View File
@@ -234,8 +234,7 @@ are defined by a function instead of just the dependencies.
The `useEffect` hook takes two function: the effect function and the dependency
function. The effect function perform some task and return (optionally) a cleanup
function. The dependency function returns a list of dependencies, these dependencies
are passed as parameters in the effect function . If any of these
function. The dependency function returns a list of dependencies. If any of these
dependencies changes, then the current effect will be cleaned up and reexecuted.
Here is an example without any dependencies:
+64 -328
View File
@@ -2,394 +2,130 @@
## Content
- [Introduction](#introduction)
- [Overview](#overview)
- [`useState`](#usestate)
- [`reactive`](#reactive)
- [`Escape hatches`](#escape-hatches)
- [`Advanced usage`](#advanced-usage)
- [`markRaw`](#markraw)
- [`toRaw`](#toraw)
## Introduction
## Overview
Reactivity is a big topic in javascript frameworks. The goal is to provide a
simple way to manipulate state, in such a way that the interface updates automatically
according to state changes, and to do so in a performant manner.
simple way to manipulate state, in such a way that the interface automatically
update accordingly to state changes. Also, we obviously want this to happen in
a performant way.
To this end, Owl provides a proxy-based reactivity system, based on the `reactive` primitive.
The `reactive` function takes an object as a first argument, and an optional callback as its second
argument, it returns a proxy of the object. This proxy tracks what properties are read
through the proxy, and calls the provided callback whenever one of these properties is changed
through any reactive version of the same object. It does so in depth, by returning reactive versions
of the subobjects when they are read.
To solve this issue, Owl provides two reactivity primitives:
- `reactive`, which returns a proxy to its first argument, and tracks all read/update
operation going through it,
- `useState`: a hook, that internally uses `reactive`, and is linked to its
owner component: any read operation will be tracked (key by key), and any
updates to these tracked values will cause the component to be rerendered.
Most of the time, the `useState` hook is the best solution.
Since version 2.0, Owl applies the fine grained reactivity at the component
level: reactive objects received as props are automatically subscribed to by the
component, so Owl can track which part of these props are consumed by each
component, and is therefore able to only rerender the impacted components.
## `useState`
While the `reactive` primitive is very powerful, its usage in components follow a very standard pattern:
components want to be rerendered when part of the state which they depend on for rendering changes. To
this end, owl provides a standard hook: `useState`. To put it simply, this hook simply calls reactive
with the provided object, and the current component's render function as its callback. This will cause
it to rerender whenever any part of the state object that has been read by this component is modified.
Here is a simple example of how `useState` can be used:
Let us start by an example of how `useState` could be used:
```js
class Counter extends Component {
static template = xml`
<div t-on-click="() => this.state.value++">
<div t-on-click="increment">
<t t-esc="state.value"/>
</div>`;
setup() {
this.state = useState({ value: 0 });
}
}
```
This component reads `state.value` when it renders, subscribing it to changes to that key. Whenever
the value changes, Owl will update the component. Note that there is nothing special about the
`state` property, you can name your state variables whatever you want, and you can have multiple of
them on the same component if it makes sense to do so. This also allows `useState` to be used in custom
hooks that may require state that is specific to that hook.
### Reactive props
Since version 2.0, Owl renders are no longer "deep" by default: a component is only rerendered by its
parent if its props have changed (using a simple equality test). What if the contents of a props have
changed in a deeper property? If that prop is reactive, owl will rerender the child components that
need to be updated automatically, and only those components, it does so by reobserving reactive
objects passed as props to components. Consider the following example:
```js
class Counter extends Component {
static template = xml`
<div t-on-click="() => props.state.value++">
<t t-esc="props.state.value"/>
</div>`;
}
class Parent extends Component {
static template = xml`
<Counter state="this.state"/>
<button t-on-click="() => this.state.value = 0">Reset counter</button>
<button t-on-click="() => this.state.test++" t-esc="this.state.test"/>`;
setup() {
this.state = useState({ value: 0, test: 1 });
increment() {
this.state.value++;
}
}
```
When clicking on the counter button, only the Counter rerenders, because the Parent has never read
the "value" key in the state. When clicking on the "Reset Counter" button, the same thing happens:
only the Counter component rerenders. What matters is not _where_ the state is updated, but which
parts of the state are updated, and which components depend on them. This is achieved by Owl by
automatically calling `useState` on reactive objects passed as props to a child component.
When clicking on the last button, the parent is rerendered, but the child does not care about the
`test` key: it has not read it. The props that we give it (`this.state`) have also not changed,
as such, the parent updates but the child doesn't.
For most day-to-day operations, `useState` should cover all of your needs. If
you are curious about more advanced use cases and technical details, read on.
### Debugging subscriptions
Owl provides a way to show which reactive objects and keys a component is subscribed to: you can
look at `component.__owl__.subscriptions`. Note that this is on the internal `__owl__` field, and
should not be used in any type of production code as the name of this property or any of its properties
or methods are subject to change at any point, even in stable versions of Owl, and may become available
only in debug mode in the future.
If one were to use a simple state object, Owl would not be aware that the value
was changed and that the component should be rerendered. With the `useState`
hook, `this.state` is now a reactive object, so this component works as expected.
## `reactive`
The `reactive` function is the basic reactivity primitive. It takes an object
or an array as first argument, and optionally, a function as the second argument.
The function is called whenever any tracked value is updated.
The function will be called whenever any tracked value is updated.
```js
const obj = reactive({ a: 1 }, () => console.log("changed"));
obj.a = 2; // does not log anything: the 'a' key has not been read yet
console.log(obj.a); // logs 2 and reads the 'a' key => it is now tracked
obj.a = 3; // logs 'changed' because we updated a tracked value
obj.a = 2; // does not log anything: the 'a' key was not read
console.log(obj.a); // log 2, and reads the 'a' key => it is now tracked
obj.a = 3; // log 'changed' because we updated a tracked value
```
An important property of reactive objects is that they can be reobserved: this
will create an independent proxy that tracks another set of keys:
will create an independant proxy that tracks another set of keys:
```js
const obj1 = reactive({ a: 1, b: 2 }, () => console.log("observer 1"));
const obj2 = reactive(obj1, () => console.log("observer 2"));
console.log(obj1.a); // logs 1, and reads the 'a' key => it is now tracked by observer 1
console.log(obj2.b); // logs 2, and 'b' is now tracked by observer 2
obj2.a = 3; // only logs 'observer1', because observer2 does not track a
obj2.b = 3; // only logs 'observer2', because observer1 does not track b
console.log(obj2.a, obj1.b); // logs 3 and 3, while the object is observed independently, it is still a single object
console.log(obj1.a); // log 1, and reads the 'a' key => it is now tracked by observer 1
console.log(obj1.b); // log 2, and 'b' is now tracked by observer 1
console.log(obj2.b); // log 2, and 'b' is now tracked by observer 1
obj2.a = 3; // log 'observer1', because observer2 does not track a
obj2.b = 3; // log 'observer1' and 'observer2'
```
Because `useState` returns a normal reactive object, it is possible to call `reactive` on the result
of a `useState` to observe changes to that object while outside the context of a component, or to
call `useState` on reactive objects created outside of components. In those cases, one needs to be
careful with regards to the lifetime of those reactive objects, as holding references to these
objects may prevent garbage collection of the component and its data even if Owl has destroyed it.
Obviously, one can use `reactive` on the result of a `useState` if wanted, this
is the proper way to watch for some state changes.
### Subscriptions are ephemereal
## `markRaw`
Subscription to state changes are ephemereal, whenever an observer is notified that a state object
has changed, all of its subscriptions are cleared, meaning that if it still cares about it, it
should read the properties it cares about again. For example:
Marks an object so that it is ignored by the reactivity system. This function returns its argument.
```js
const obj = reactive({ a: 1 }, () => console.log("observer called"));
console.log(obj.a); // logs 1, and reads the 'a' key => it is now tracked by the observer
obj.a = 3; // logs 'observer1' and clears the subscriptions of the observer
obj.a = 4; // doesn't log anything, the key is no longer observed
```
This may seem counter-intuitive, but it makes perfect sense in the context of components:
```js
class DoubleCounter extends Component {
static template = xml`
<t t-esc="state.selected + ': ' + state[state.selected].value"/>
<button t-on-click="() => this.state.count1++">increment count 1</button>
<button t-on-click="() => this.state.count2++">increment count 2</button>
<button t-on-click="changeCounter">Switch counter</button>
`;
setup() {
this.state = useState({ selected: "count1", count1: 0, count2: 0 });
}
changeCounter() {
this.state.selected = this.state.selected === "count1" ? "count2" : "count1";
}
}
```
In this component, if we increment the value of the second counter, the component will not rerender,
which makes sense as rerendering will have no effect, as the second counter is not displayed. If we
toggle the component to display the second counter, we now no longer want the component to rerender
when the value of the first counter changes, and this is what happens: a component only rerenders
when there are changes to pieces of state that have been read during or after the previous render.
If a piece of state has not been read in the last render, we know that its value won't influence the
rendered output, and so we can ignore it.
### reactive `Map` and `Set`
The reactivity system has special support built-in for the standard container types `Map` and `Set`.
They behave like one would expect: reading a key subscribes the observer to that key, adding or
removing an item to them notifies observers that have used any of the iterators on that reactive
object, such as `.entries()` or `.keys()`, likewise with clearing them.
## Escape hatches
Sometimes, it is desirable to bypass the reactivity system. Creating proxies when interacting with
reactive objects is expensive, and while on the whole, the performance benefit that we get by
rerendering only the parts of the interface that need it outweighs that cost, in some cases, we want
to be able to opt out of creating them in the first place. This is the purpose of `markRaw`:
### `markRaw`
Marks an object so that it is ignored by the reactivity system, meaning that if this object is ever
part of a of a reactive object, it will be returned as is, and no keys in that object will be
observed.
```js
const someObject = markRaw({ b: 1 });
const someObject = markRaw(...);
const state = useState({
a: 1,
obj: someObject,
obj: someObject
});
console.log(state.obj.b); // attempt to subscribe to the "b" key in someObject
state.obj.b = 2; // No rerender will occur here
console.log(someObject === state.obj); // true
// here, state.obj === someObject
```
This is useful in some rare cases. One such example would be if you want to use an array of objects
that is potentially large to render a list, but those objects are known to be immutable:
```js
this.items = useState([
{ label: "some text", value: 42 },
// ... 1000 total objects
]);
```
in the template:
```xml
<t t-foreach="items" t-as="item" t-key="item.label" t-esc="item.label + item.value"/>
```
Here, on every render, we go and read one thousand keys from a reactive object, which causes
one thousand reactive objects to be created. If we know that the content of these objects
cannot change, this is wasted work. If instead all of these objects are marked as raw, we avoid
all of this work while keeping the ability to lean on the reactivity to track the presence and
identity of these objects:
```js
this.items = useState([
markRaw({ label: "some text", value: 42 }),
// ... 1000 total objects
]);
```
This is useful in some rare cases. For example, some complex and large object such
that going through the reactivity system may cause a non trivial performance slowdown.
However, use this function with caution: this is an escape hatch from the reactivity
system, and as such, using it may cause subtle and unintended issues! For example:
system, and as such, using it may cause subtle and unintended issues!
## `toRaw`
Given a reactive object, this function returns the underlying, non-reactive,
corresponding object.
```js
// This will cause a rerender
this.items.push(markRaw({ label: "another label", value: 1337 }));
// in setup
const state = useState({ value: 1 });
// THIS WILL NOT CAUSE A RENDER!
this.items[17].value = 3;
// The UI is now desynced from component's state until the next render caused by something else
// later:
const rawState = toRaw(this.state);
rawState.value = 3; // will NOT be picked up by the reactivity system!!!
```
In short: only use `markRaw` if your application is slowing down noticeably and profiling reveals
that a lot of time is spent creating useless reactive objects.
Here again, this is useful in some situations where we want to explicitely bypass
Owl, but using this function means that the responsability of coordinating
state update is given to the user code, instead of Owl. Subtle bugs may arise!
### `toRaw`
While `markRaw` marks an object so that it is never made reactive, `toRaw` takes an object and
returns the underlying non-reactive object. It can be useful in some niche cases. In particular,
because the reactivity system returns a proxy, the returned object does not compare equal to the
original object:
Also, normal (non-reactive objects) will be directly returned by `toRaw`:
```js
const obj = {};
const reactiveObj = reactive(obj);
console.log(obj === reactiveObj); // false
console.log(obj === toRaw(reactiveObj)); // true
const obj = { a: 1 };
console.log(toRaw(obj) === obj); // true
```
It can also be useful during debugging, as unfolding proxies recursively in debuggers can be confusing.
## Advanced usage
The following is a collection of small snippets that leverage the reactivity system in
"non-standard" ways to help you understand its power and where using it might make your code simpler.
### Notification manager
Showing notifications is a pretty common need in web applications, you may want to show a
notification from any other component within the application, and the notifications should stack on
top of one another regardless of which component spawned them, here is how we can leverage the
reactivity to accomplish this:
```js
let notificationId = 1;
const notifications = reactive({});
class NotificationContainer extends Component {
static template = xml`
<t t-foreach="notifications" t-as="notification" t-key="notification_key" t-esc="notification"/>
`;
setup() {
this.notifications = useState(notifications);
}
}
export function addNotification(label) {
const id = notificationId++;
notifications[id] = label;
return () => {
delete notifications[id];
};
}
```
Here, the `notifications` variable is a reactive object. Notice how we didn't give `reactive` a
callback: this is because in this case, all we care about is that adding or removing notifications
in the `addNotification` function goes through the reactivity system. The `NotificationContainer`
component reobserves this object with `useState`, and is updated whenever notifications are
added or removed.
### Store
Centralizing application state is a pretty common want/need in web applications. Because of the way
the reactivity system works, you can treat any reactive object as a store, and if you call `useState`
on it, components automatically observe only the part of the store that they're interested in:
```js
export const store = reactive({
list: [],
add(item) {
this.list.push(item);
},
});
export function useStore() {
return useState(store);
}
```
In any component:
```js
import { useStore } from "./store";
class List extends Component {
static template = xml`
<t t-foreach="store.list" t-as="item" t-key="item" t-esc="item"/>
`;
setup() {
this.store = useStore();
}
}
```
Anywhere in the application:
```js
import { store } from "./store";
// Will cause any instance of the List component in the app to update
store.add("New list item!");
```
Notice how we can make objects with methods into reactive objects, and when these methods are used
to mutate the store contents, it works as expected. And while stores are generally one-off objects,
it is entirely possible to make class instances reactive:
```js
class Store {
list = [];
add(item) {
this.list.push(item);
}
}
// Essentially equivalent to the previous code
export const store = reactive(new Store());
```
Which can be useful to unit test the class separately.
### Local storage synchronization
Sometimes, you want to persist some state accross reloads, you can do this by storing it in the
`localStorage`, but what if you want to update the `localStorage` item every time the state changes,
so that you don't have to manually synchronize the states? Well, you can use the reactivity system
to write a custom hook that will do that for you:
```js
function useStoredState(key, initialState) {
const state = JSON.parse(localStorage.getItem(key)) || initialState;
const store = (obj) => localStorage.setItem(key, JSON.stringify(obj));
const reactiveState = reactive(state, () => store(reactiveState));
store(reactiveState);
return useState(state);
}
class MyComponent extends Component {
setup() {
this.state = useStoredState("MyComponent.state", { value: 1 });
}
}
```
One important thing to notice is that both times we call `store`, we call it with `reactiveState`,
not `state`: we need `store` to read the keys through a reactive object for it to correctly
subscribe to state changes. Notice also that we call `store` the first time by hand, as otherwise it
will not be subscribed to anything, and no amount of change in the object will cause the reactive
callback to be invoked.
+2 -1
View File
@@ -1,8 +1,9 @@
{
"name": "@odoo/owl",
"version": "2.0.2",
"version": "2.0.0-beta-12",
"description": "Odoo Web Library (OWL)",
"main": "dist/owl.cjs.js",
"browser": "dist/owl.iife.js",
"module": "dist/owl.es.js",
"types": "dist/types/owl.d.ts",
"files": [
+23 -4
View File
@@ -1,9 +1,28 @@
# 🦉 OWL Roadmap 🦉
- Current version: 2.X
- Current version: 1.4.10
- Status: stable
Owl is currently stable. No (large) improvements is expected in the near future.
This roadmap is only an attempt at predicting Owl's future. Everything may
change!
### 1.x
- add chrome and firefox devtools,
- fix every bugs,
- improve documentation,
- small backward compatible improvements.
### 2.x (2020? 2021? 2022?)
- stop support for `t-set` directive to define the content of a slot
Maybe:
- reimplement vdom to use *block* system, like Vue 3, which should make Owl
much faster
- refactor `QWeb` to use an intermediate representation (some kind of AST) to
allow additional optimisations.
Note that we intend to keep maintaining owl, and as such, improvements and/or
breaking changes may require a version bump in the future.
+8 -16
View File
@@ -6,14 +6,6 @@ import dts from "rollup-plugin-dts";
let input, output;
const IIFE_FILENAME = "dist/owl.iife.js";
const CJS_FILENAME = "dist/owl.cjs.js";
const ES_FILENAME = "dist/owl.es.js";
if (pkg.module !== ES_FILENAME || pkg.main !== CJS_FILENAME) {
throw new Error("package.json has been modified. Build script should be updated accordingly");
}
const outro = `
__info__.version = '${pkg.version}';
__info__.date = '${new Date().toISOString()}';
@@ -31,19 +23,19 @@ switch (process.argv[4]) {
case "runtime":
input = "src/runtime/index.ts";
output = [
getConfigForFormat('esm', addSuffix(ES_FILENAME, 'runtime'), outro),
getConfigForFormat('cjs', addSuffix(CJS_FILENAME, 'runtime'), outro),
getConfigForFormat('iife', addSuffix(IIFE_FILENAME, 'runtime'), outro),
getConfigForFormat('iife', addSuffix(IIFE_FILENAME, 'runtime'), outro, true),
getConfigForFormat('esm', addSuffix(pkg.module, 'runtime'), outro),
getConfigForFormat('cjs', addSuffix(pkg.main, 'runtime'), outro),
getConfigForFormat('iife', addSuffix(pkg.browser, 'runtime'), outro),
getConfigForFormat('iife', addSuffix(pkg.browser, 'runtime'), outro, true),
]
break;
default:
input = "src/index.ts",
output = [
getConfigForFormat('esm', ES_FILENAME, outro),
getConfigForFormat('cjs', CJS_FILENAME, outro),
getConfigForFormat('iife', IIFE_FILENAME, outro),
getConfigForFormat('iife', IIFE_FILENAME, outro, true),
getConfigForFormat('esm', pkg.module, outro),
getConfigForFormat('cjs', pkg.main, outro),
getConfigForFormat('iife', pkg.browser, outro),
getConfigForFormat('iife', pkg.browser, outro, true),
]
}
+124 -155
View File
@@ -1,4 +1,3 @@
import { isProp } from "../runtime/blockdom/attributes";
import {
compileExpr,
compileExprToArray,
@@ -23,14 +22,13 @@ import {
ASTTif,
ASTTKey,
ASTTOut,
ASTTPortal,
ASTTranslation,
ASTTSet,
ASTTranslation,
ASTType,
Attrs,
ASTTPortal,
EventHandlers,
Attrs,
} from "./parser";
import { OwlError } from "../runtime/error_handling";
type BlockType = "block" | "text" | "multi" | "list" | "html" | "comment";
@@ -191,7 +189,7 @@ class CodeTarget {
let result: string[] = [];
result.push(`function ${this.name}(ctx, node, key = "") {`);
if (this.hasRef) {
result.push(` const refs = this.__owl__.refs;`);
result.push(` const refs = ctx.__owl__.refs;`);
for (let name in this.refInfo) {
const [id, expr] = this.refInfo[name];
result.push(` const ${id} = ${expr};`);
@@ -214,14 +212,6 @@ class CodeTarget {
result.push(`}`);
return result.join("\n ");
}
currentKey(ctx: Context) {
let key = this.loopLevel ? `key${this.loopLevel}` : "key";
if (ctx.tKeyExpr) {
key = `${ctx.tKeyExpr} + ${key}`;
}
return key;
}
}
const TRANSLATABLE_ATTRS = ["label", "title", "placeholder", "alt"];
@@ -240,7 +230,6 @@ export class CodeGenerator {
translatableAttributes: string[] = TRANSLATABLE_ATTRS;
ast: AST;
staticDefs: { id: string; expr: string }[] = [];
slotNames: Set<String> = new Set();
helpers: Set<string> = new Set();
constructor(ast: AST, options: CodeGenOptions) {
@@ -294,7 +283,7 @@ export class CodeGenerator {
for (let block of this.blocks) {
if (block.dom) {
let xmlString = block.asXmlString();
xmlString = xmlString.replace(/\\/g, "\\\\").replace(/`/g, "\\`");
xmlString = xmlString.replace(/`/g, "\\`");
if (block.dynamicTagName) {
xmlString = xmlString.replace(/^<\w+/, `<\${tag || '${block.dom.nodeName}'}`);
xmlString = xmlString.replace(/\w+>$/, `\${tag || '${block.dom.nodeName}'}>`);
@@ -373,15 +362,19 @@ export class CodeGenerator {
insertBlock(expression: string, block: BlockDescription, ctx: Context): void {
let blockExpr = block.generateExpr(expression);
const tKeyExpr = ctx.tKeyExpr;
if (block.parentVar) {
let key = this.target.currentKey(ctx);
let keyArg = `key${this.target.loopLevel}`;
if (tKeyExpr) {
keyArg = `${tKeyExpr} + ${keyArg}`;
}
this.helpers.add("withKey");
this.addLine(`${block.parentVar}[${ctx.index}] = withKey(${blockExpr}, ${key});`);
this.addLine(`${block.parentVar}[${ctx.index}] = withKey(${blockExpr}, ${keyArg});`);
return;
}
if (ctx.tKeyExpr) {
blockExpr = `toggler(${ctx.tKeyExpr}, ${blockExpr})`;
if (tKeyExpr) {
blockExpr = `toggler(${tKeyExpr}, ${blockExpr})`;
}
if (block.isRoot && !ctx.preventRoot) {
@@ -428,66 +421,78 @@ export class CodeGenerator {
.join("");
}
/**
* @returns the newly created block name, if any
*/
compileAST(ast: AST, ctx: Context): string | null {
compileAST(ast: AST, ctx: Context) {
switch (ast.type) {
case ASTType.Comment:
return this.compileComment(ast, ctx);
this.compileComment(ast, ctx);
break;
case ASTType.Text:
return this.compileText(ast, ctx);
this.compileText(ast, ctx);
break;
case ASTType.DomNode:
return this.compileTDomNode(ast, ctx);
this.compileTDomNode(ast, ctx);
break;
case ASTType.TEsc:
return this.compileTEsc(ast, ctx);
this.compileTEsc(ast, ctx);
break;
case ASTType.TOut:
return this.compileTOut(ast, ctx);
this.compileTOut(ast, ctx);
break;
case ASTType.TIf:
return this.compileTIf(ast, ctx);
this.compileTIf(ast, ctx);
break;
case ASTType.TForEach:
return this.compileTForeach(ast, ctx);
this.compileTForeach(ast, ctx);
break;
case ASTType.TKey:
return this.compileTKey(ast, ctx);
this.compileTKey(ast, ctx);
break;
case ASTType.Multi:
return this.compileMulti(ast, ctx);
this.compileMulti(ast, ctx);
break;
case ASTType.TCall:
return this.compileTCall(ast, ctx);
this.compileTCall(ast, ctx);
break;
case ASTType.TCallBlock:
return this.compileTCallBlock(ast, ctx);
this.compileTCallBlock(ast, ctx);
break;
case ASTType.TSet:
return this.compileTSet(ast, ctx);
this.compileTSet(ast, ctx);
break;
case ASTType.TComponent:
return this.compileComponent(ast, ctx);
this.compileComponent(ast, ctx);
break;
case ASTType.TDebug:
return this.compileDebug(ast, ctx);
this.compileDebug(ast, ctx);
break;
case ASTType.TLog:
return this.compileLog(ast, ctx);
this.compileLog(ast, ctx);
break;
case ASTType.TSlot:
return this.compileTSlot(ast, ctx);
this.compileTSlot(ast, ctx);
break;
case ASTType.TTranslation:
return this.compileTTranslation(ast, ctx);
this.compileTTranslation(ast, ctx);
break;
case ASTType.TPortal:
return this.compileTPortal(ast, ctx);
this.compileTPortal(ast, ctx);
}
}
compileDebug(ast: ASTDebug, ctx: Context): string | null {
compileDebug(ast: ASTDebug, ctx: Context) {
this.addLine(`debugger;`);
if (ast.content) {
return this.compileAST(ast.content, ctx);
this.compileAST(ast.content, ctx);
}
return null;
}
compileLog(ast: ASTLog, ctx: Context): string | null {
compileLog(ast: ASTLog, ctx: Context) {
this.addLine(`console.log(${compileExpr(ast.expr)});`);
if (ast.content) {
return this.compileAST(ast.content, ctx);
this.compileAST(ast.content, ctx);
}
return null;
}
compileComment(ast: ASTComment, ctx: Context): string {
compileComment(ast: ASTComment, ctx: Context) {
let { block, forceNewBlock } = ctx;
const isNewBlock = !block || forceNewBlock;
if (isNewBlock) {
@@ -500,10 +505,9 @@ export class CodeGenerator {
const text = xmlDoc.createComment(ast.value);
block!.insert(text);
}
return block!.varName;
}
compileText(ast: ASTText, ctx: Context): string {
compileText(ast: ASTText, ctx: Context) {
let { block, forceNewBlock } = ctx;
let value = ast.value;
@@ -522,7 +526,6 @@ export class CodeGenerator {
const createFn = ast.type === ASTType.Text ? xmlDoc.createTextNode : xmlDoc.createComment;
block.insert(createFn.call(xmlDoc, value));
}
return block.varName;
}
generateHandlerCode(rawEvent: string, handler: string): string {
@@ -531,7 +534,7 @@ export class CodeGenerator {
.slice(1)
.map((m) => {
if (!MODS.has(m)) {
throw new OwlError(`Unknown event modifier: '${m}'`);
throw new Error(`Unknown event modifier: '${m}'`);
}
return `"${m}"`;
});
@@ -542,7 +545,7 @@ export class CodeGenerator {
return `[${modifiersCode}${this.captureExpression(handler)}, ctx]`;
}
compileTDomNode(ast: ASTDomNode, ctx: Context): string {
compileTDomNode(ast: ASTDomNode, ctx: Context) {
let { block, forceNewBlock } = ctx;
const isNewBlock = !block || forceNewBlock || ast.dynamicTag !== null || ast.ns;
let codeIdx = this.target.code.length;
@@ -575,22 +578,13 @@ export class CodeGenerator {
attrName = key.slice(7);
attrs["block-attribute-" + idx] = attrName;
} else if (key.startsWith("t-att")) {
attrName = key === "t-att" ? null : key.slice(6);
expr = compileExpr(ast.attrs[key]);
if (attrName && isProp(ast.tag, attrName)) {
// we force a new string or new boolean to bypass the equality check in blockdom when patching same value
if (attrName === "value") {
// When the expression is falsy, fall back to an empty string
expr = `new String((${expr}) || "")`;
} else {
expr = `new Boolean(${expr})`;
}
}
const idx = block!.insertData(expr, "attr");
if (key === "t-att") {
attrs[`block-attributes`] = String(idx);
} else {
attrs[`block-attribute-${idx}`] = attrName!;
attrName = key.slice(6);
attrs[`block-attribute-${idx}`] = attrName;
}
} else if (this.translatableAttributes.includes(key)) {
attrs[key] = this.translateFn(ast.attrs[key]);
@@ -606,6 +600,39 @@ export class CodeGenerator {
}
}
// event handlers
for (let ev in ast.on) {
const name = this.generateHandlerCode(ev, ast.on[ev]);
const idx = block!.insertData(name, "hdlr");
attrs[`block-handler-${idx}`] = ev;
}
// t-ref
if (ast.ref) {
this.target.hasRef = true;
const isDynamic = INTERP_REGEXP.test(ast.ref);
if (isDynamic) {
const str = replaceDynamicParts(ast.ref, (expr) => this.captureExpression(expr, true));
const idx = block!.insertData(`(el) => refs[${str}] = el`, "ref");
attrs["block-ref"] = String(idx);
} else {
let name = ast.ref;
if (name in this.target.refInfo) {
// ref has already been defined
this.helpers.add("multiRefSetter");
const info = this.target.refInfo[name];
const index = block!.data.push(info[0]) - 1;
attrs["block-ref"] = String(index);
info[1] = `multiRefSetter(refs, \`${name}\`)`;
} else {
let id = generateId("ref");
this.target.refInfo[name] = [id, `(el) => refs[\`${name}\`] = el`];
const index = block!.data.push(id) - 1;
attrs["block-ref"] = String(index);
}
}
}
// t-model
let tModelSelectedExpr;
if (ast.model) {
@@ -652,39 +679,6 @@ export class CodeGenerator {
attrs[`block-handler-${idx}`] = eventType;
}
// event handlers
for (let ev in ast.on) {
const name = this.generateHandlerCode(ev, ast.on[ev]);
const idx = block!.insertData(name, "hdlr");
attrs[`block-handler-${idx}`] = ev;
}
// t-ref
if (ast.ref) {
this.target.hasRef = true;
const isDynamic = INTERP_REGEXP.test(ast.ref);
if (isDynamic) {
const str = replaceDynamicParts(ast.ref, (expr) => this.captureExpression(expr, true));
const idx = block!.insertData(`(el) => refs[${str}] = el`, "ref");
attrs["block-ref"] = String(idx);
} else {
let name = ast.ref;
if (name in this.target.refInfo) {
// ref has already been defined
this.helpers.add("multiRefSetter");
const info = this.target.refInfo[name];
const index = block!.data.push(info[0]) - 1;
attrs["block-ref"] = String(index);
info[1] = `multiRefSetter(refs, \`${name}\`)`;
} else {
let id = generateId("ref");
this.target.refInfo[name] = [id, `(el) => refs[\`${name}\`] = el`];
const index = block!.data.push(id) - 1;
attrs["block-ref"] = String(index);
}
}
}
const dom = xmlDoc.createElement(ast.tag);
for (const [attr, val] of Object.entries(attrs)) {
if (!(attr === "class" && val === "")) {
@@ -729,10 +723,9 @@ export class CodeGenerator {
this.addLine(`let ${block!.children.map((c) => c.varName)};`, codeIdx);
}
}
return block!.varName;
}
compileTEsc(ast: ASTTEsc, ctx: Context): string {
compileTEsc(ast: ASTTEsc, ctx: Context) {
let { block, forceNewBlock } = ctx;
let expr: string;
if (ast.expr === "0") {
@@ -753,10 +746,9 @@ export class CodeGenerator {
const text = xmlDoc.createElement(`block-text-${idx}`);
block.insert(text);
}
return block.varName;
}
compileTOut(ast: ASTTOut, ctx: Context): string {
compileTOut(ast: ASTTOut, ctx: Context) {
let { block } = ctx;
if (block) {
this.insertAnchor(block);
@@ -778,7 +770,6 @@ export class CodeGenerator {
blockStr = `safeOutput(${compileExpr(ast.expr)})`;
}
this.insertBlock(blockStr, block, ctx);
return block.varName;
}
compileTIfBranch(content: AST, block: BlockDescription, ctx: Context) {
@@ -792,7 +783,7 @@ export class CodeGenerator {
this.target.indentLevel--;
}
compileTIf(ast: ASTTif, ctx: Context, nextNode?: ASTDomNode): string {
compileTIf(ast: ASTTif, ctx: Context, nextNode?: ASTDomNode) {
let { block, forceNewBlock } = ctx;
const codeIdx = this.target.code.length;
const isNewBlock = !block || (block.type !== "multi" && forceNewBlock);
@@ -835,10 +826,9 @@ export class CodeGenerator {
const args = block!.children.map((c) => c.varName).join(", ");
this.insertBlock(`multi([${args}])`, block!, ctx)!;
}
return block.varName;
}
compileTForeach(ast: ASTTForEach, ctx: Context): string {
compileTForeach(ast: ASTTForEach, ctx: Context) {
let { block } = ctx;
if (block) {
this.insertAnchor(block);
@@ -875,11 +865,10 @@ export class CodeGenerator {
this.define(`key${this.target.loopLevel}`, ast.key ? compileExpr(ast.key) : loopVar);
if (this.dev) {
// Throw error on duplicate keys in dev mode
this.helpers.add("OwlError");
this.addLine(
`if (keys${block.id}.has(String(key${this.target.loopLevel}))) { throw new OwlError(\`Got duplicate key in t-foreach: \${key${this.target.loopLevel}}\`)}`
`if (keys${block.id}.has(key${this.target.loopLevel})) { throw new Error(\`Got duplicate key in t-foreach: \${key${this.target.loopLevel}}\`)}`
);
this.addLine(`keys${block.id}.add(String(key${this.target.loopLevel}));`);
this.addLine(`keys${block.id}.add(key${this.target.loopLevel});`);
}
let id: string;
if (ast.memo) {
@@ -916,10 +905,9 @@ export class CodeGenerator {
this.addLine(`ctx = ctx.__proto__;`);
}
this.insertBlock("l", block, ctx);
return block.varName;
}
compileTKey(ast: ASTTKey, ctx: Context): string | null {
compileTKey(ast: ASTTKey, ctx: Context) {
const tKeyExpr = generateId("tKey_");
this.define(tKeyExpr, compileExpr(ast.expr));
ctx = createContext(ctx, {
@@ -927,22 +915,20 @@ export class CodeGenerator {
block: ctx.block,
index: ctx.index,
});
return this.compileAST(ast.content, ctx);
this.compileAST(ast.content, ctx);
}
compileMulti(ast: ASTMulti, ctx: Context): string | null {
compileMulti(ast: ASTMulti, ctx: Context) {
let { block, forceNewBlock } = ctx;
const isNewBlock = !block || forceNewBlock;
let codeIdx = this.target.code.length;
if (isNewBlock) {
const n = ast.content.filter((c) => c.type !== ASTType.TSet).length;
let result: string | null = null;
if (n <= 1) {
for (let child of ast.content) {
const blockName = this.compileAST(child, ctx);
result = result || blockName;
this.compileAST(child, ctx);
}
return result;
return;
}
block = this.createBlock(block, "multi", ctx);
}
@@ -982,10 +968,9 @@ export class CodeGenerator {
const args = block!.children.map((c) => c.varName).join(", ");
this.insertBlock(`multi([${args}])`, block!, ctx)!;
}
return block!.varName;
}
compileTCall(ast: ASTTCall, ctx: Context): string {
compileTCall(ast: ASTTCall, ctx: Context) {
let { block, forceNewBlock } = ctx;
let ctxVar = ctx.ctxVar || "ctx";
if (ast.context) {
@@ -996,11 +981,12 @@ export class CodeGenerator {
this.addLine(`${ctxVar} = Object.create(${ctxVar});`);
this.addLine(`${ctxVar}[isBoundary] = 1;`);
this.helpers.add("isBoundary");
const nextId = BlockDescription.nextBlockId;
const subCtx = createContext(ctx, { preventRoot: true, ctxVar });
const bl = this.compileMulti({ type: ASTType.Multi, content: ast.body }, subCtx);
if (bl) {
this.compileAST({ type: ASTType.Multi, content: ast.body }, subCtx);
if (nextId !== BlockDescription.nextBlockId) {
this.helpers.add("zero");
this.addLine(`${ctxVar}[zero] = ${bl};`);
this.addLine(`${ctxVar}[zero] = b${nextId};`);
}
}
const isDynamic = INTERP_REGEXP.test(ast.name);
@@ -1034,10 +1020,9 @@ export class CodeGenerator {
if (ast.body && !ctx.isLast) {
this.addLine(`${ctxVar} = ${ctxVar}.__proto__;`);
}
return block.varName;
}
compileTCallBlock(ast: ASTTCallBlock, ctx: Context): string {
compileTCallBlock(ast: ASTTCallBlock, ctx: Context) {
let { block, forceNewBlock } = ctx;
if (block) {
if (!forceNewBlock) {
@@ -1046,10 +1031,9 @@ export class CodeGenerator {
}
block = this.createBlock(block, "multi", ctx);
this.insertBlock(compileExpr(ast.name), block, { ...ctx, forceNewBlock: !block });
return block.varName;
}
compileTSet(ast: ASTTSet, ctx: Context): null {
compileTSet(ast: ASTTSet, ctx: Context) {
this.target.shouldProtectScope = true;
this.helpers.add("isBoundary").add("withDefault");
const expr = ast.value ? compileExpr(ast.value || "") : "null";
@@ -1057,8 +1041,7 @@ export class CodeGenerator {
this.helpers.add("LazyValue");
const bodyAst: AST = { type: ASTType.Multi, content: ast.body };
const name = this.compileInNewTarget("value", bodyAst, ctx);
let key = this.target.currentKey(ctx);
let value = `new LazyValue(${name}, ctx, this, node, ${key})`;
let value = `new LazyValue(${name}, ctx, this, node)`;
value = ast.value ? (value ? `withDefault(${expr}, ${value})` : expr) : value;
this.addLine(`ctx[\`${ast.name}\`] = ${value};`);
} else {
@@ -1075,7 +1058,6 @@ export class CodeGenerator {
this.helpers.add("setContextValue");
this.addLine(`setContextValue(${ctx.ctxVar || "ctx"}, "${ast.name}", ${value});`);
}
return null;
}
generateComponentKey() {
@@ -1104,9 +1086,9 @@ export class CodeGenerator {
if (suffix === "bind") {
this.helpers.add("bind");
name = _name;
value = `bind(this, ${value || undefined})`;
value = `bind(ctx, ${value || undefined})`;
} else {
throw new OwlError("Invalid prop suffix");
throw new Error("Invalid prop suffix");
}
}
name = /^[a-z_]+$/i.test(name) ? name : `'${name}'`;
@@ -1127,7 +1109,7 @@ export class CodeGenerator {
return propString;
}
compileComponent(ast: ASTComponent, ctx: Context): string {
compileComponent(ast: ASTComponent, ctx: Context) {
let { block } = ctx;
// props
const hasSlotsProp = "slots" in (ast.props || {});
@@ -1148,7 +1130,7 @@ export class CodeGenerator {
const params = [];
if (slotAst.content) {
const name = this.compileInNewTarget("slot", slotAst.content, ctx, slotAst.on);
params.push(`__render: ${name}.bind(this), __ctx: ${ctxStr}`);
params.push(`__render: ${name}, __ctx: ${ctxStr}`);
}
const scope = ast.slots[slotName].scope;
if (scope) {
@@ -1193,7 +1175,7 @@ export class CodeGenerator {
}
if (this.dev) {
this.addLine(`helpers.validateProps(${expr}, ${propVar!}, this);`);
this.addLine(`helpers.validateProps(${expr}, ${propVar!}, ctx);`);
}
if (block && (ctx.forceNewBlock === false || ctx.tKeyExpr)) {
@@ -1227,7 +1209,6 @@ export class CodeGenerator {
block = this.createBlock(block, "multi", ctx);
this.insertBlock(blockExpr, block, ctx);
return block.varName;
}
wrapWithEventCatcher(expr: string, on: EventHandlers): string {
@@ -1246,43 +1227,34 @@ export class CodeGenerator {
return `${name}(${expr}, [${handlers.join(",")}])`;
}
compileTSlot(ast: ASTSlot, ctx: Context): string {
compileTSlot(ast: ASTSlot, ctx: Context) {
this.helpers.add("callSlot");
let { block } = ctx;
let blockString: string;
let slotName;
let dynamic = false;
let isMultiple = false;
if (ast.name.match(INTERP_REGEXP)) {
dynamic = true;
isMultiple = true;
slotName = interpolate(ast.name);
} else {
slotName = "'" + ast.name + "'";
isMultiple = isMultiple || this.slotNames.has(ast.name);
this.slotNames.add(ast.name);
}
const dynProps = ast.attrs ? ast.attrs["t-props"] : null;
if (ast.attrs) {
delete ast.attrs["t-props"];
}
let key = this.target.loopLevel ? `key${this.target.loopLevel}` : "key";
if (isMultiple) {
key = `${key} + \`${this.generateComponentKey()}\``;
}
const props = ast.attrs ? this.formatPropObject(ast.attrs) : [];
const scope = this.getPropString(props, dynProps);
if (ast.defaultContent) {
const name = this.compileInNewTarget("defaultContent", ast.defaultContent, ctx);
blockString = `callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope}, ${name}.bind(this))`;
blockString = `callSlot(ctx, node, key, ${slotName}, ${dynamic}, ${scope}, ${name})`;
} else {
if (dynamic) {
let name = generateId("slot");
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 {
blockString = `callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope})`;
blockString = `callSlot(ctx, node, key, ${slotName}, ${dynamic}, ${scope})`;
}
}
// event handling
@@ -1295,16 +1267,14 @@ export class CodeGenerator {
}
block = this.createBlock(block, "multi", ctx);
this.insertBlock(blockString, block, { ...ctx, forceNewBlock: false });
return block.varName;
}
compileTTranslation(ast: ASTTranslation, ctx: Context): string | null {
compileTTranslation(ast: ASTTranslation, ctx: Context) {
if (ast.content) {
return this.compileAST(ast.content, Object.assign({}, ctx, { translate: false }));
this.compileAST(ast.content, Object.assign({}, ctx, { translate: false }));
}
return null;
}
compileTPortal(ast: ASTTPortal, ctx: Context): string {
compileTPortal(ast: ASTTPortal, ctx: Context) {
if (!this.staticDefs.find((d) => d.id === "Portal")) {
this.staticDefs.push({ id: "Portal", expr: `app.Portal` });
}
@@ -1325,12 +1295,11 @@ export class CodeGenerator {
});
const target = compileExpr(ast.target);
const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}.bind(this), __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx, Portal)`;
const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}, __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx, Portal)`;
if (block) {
this.insertAnchor(block);
}
block = this.createBlock(block, "multi", ctx);
this.insertBlock(blockString, block, { ...ctx, forceNewBlock: false });
return block.varName;
}
}
+3 -5
View File
@@ -1,5 +1,3 @@
import { OwlError } from "../runtime/error_handling";
/**
* Owl QWeb Expression Parser
*
@@ -108,14 +106,14 @@ let tokenizeString: Tokenizer = function (expr) {
i++;
cur = expr[i];
if (!cur) {
throw new OwlError("Invalid expression");
throw new Error("Invalid expression");
}
s += cur;
}
i++;
}
if (expr[i] !== start) {
throw new OwlError("Invalid expression");
throw new Error("Invalid expression");
}
s += start;
if (start === "`") {
@@ -225,7 +223,7 @@ export function tokenize(expr: string): Token[] {
error = e; // Silence all errors and throw a generic error below
}
if (current.length || error) {
throw new OwlError(`Tokenizer error: could not tokenize \`${expr}\``);
throw new Error(`Tokenizer error: could not tokenize \`${expr}\``);
}
return result;
}
+20 -31
View File
@@ -1,5 +1,3 @@
import { OwlError } from "../runtime/error_handling";
// -----------------------------------------------------------------------------
// AST Type definition
// -----------------------------------------------------------------------------
@@ -260,16 +258,12 @@ function parseTNode(node: Element, ctx: ParsingContext): AST | null {
// -----------------------------------------------------------------------------
// Text and Comment Nodes
// -----------------------------------------------------------------------------
const lineBreakRE = /[\r\n]/;
const whitespaceRE = /\s+/g;
const whitespaceRE = /[^\S\r\n]+/g;
function parseTextCommentNode(node: Node, ctx: ParsingContext): AST | null {
if (node.nodeType === Node.TEXT_NODE) {
let value = node.textContent || "";
if (!ctx.inPreTag) {
if (lineBreakRE.test(value) && !value.trim()) {
return null;
}
value = value.replace(whitespaceRE, " ");
}
@@ -321,7 +315,7 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
return null;
}
if (tagName.startsWith("block-")) {
throw new OwlError(`Invalid tag name: '${tagName}'`);
throw new Error(`Invalid tag name: '${tagName}'`);
}
ctx = Object.assign({}, ctx);
if (tagName === "pre") {
@@ -342,15 +336,13 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
const value = node.getAttribute(attr)!;
if (attr.startsWith("t-on")) {
if (attr === "t-on") {
throw new OwlError("Missing event name with t-on directive");
throw new Error("Missing event name with t-on directive");
}
on = on || {};
on[attr.slice(5)] = value;
} else if (attr.startsWith("t-model")) {
if (!["input", "select", "textarea"].includes(tagName)) {
throw new OwlError(
"The t-model directive only works with <input>, <textarea> and <select>"
);
throw new Error("The t-model directive only works with <input>, <textarea> and <select>");
}
let baseExpr, expr;
@@ -363,7 +355,7 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
baseExpr = value.slice(0, index);
expr = value.slice(index + 1, -1);
} else {
throw new OwlError(`Invalid t-model expression: "${value}" (it should be assignable)`);
throw new Error(`Invalid t-model expression: "${value}" (it should be assignable)`);
}
const typeAttr = node.getAttribute("type");
@@ -394,10 +386,10 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
ctx.tModelInfo = model;
}
} else if (attr.startsWith("block-")) {
throw new OwlError(`Invalid attribute: '${attr}'`);
throw new Error(`Invalid attribute: '${attr}'`);
} else if (attr !== "t-name") {
if (attr.startsWith("t-") && !attr.startsWith("t-att")) {
throw new OwlError(`Unknown QWeb directive: '${attr}'`);
throw new Error(`Unknown QWeb directive: '${attr}'`);
}
const tModel = ctx.tModelInfo;
if (tModel && ["t-att-value", "t-attf-value"].includes(attr)) {
@@ -451,7 +443,7 @@ function parseTEscNode(node: Element, ctx: ParsingContext): AST | null {
};
}
if (ast.type === ASTType.TComponent) {
throw new OwlError("t-esc is not supported on Component nodes");
throw new Error("t-esc is not supported on Component nodes");
}
return tesc;
}
@@ -507,7 +499,7 @@ function parseTForEach(node: Element, ctx: ParsingContext): AST | null {
node.removeAttribute("t-as");
const key = node.getAttribute("t-key");
if (!key) {
throw new OwlError(
throw new Error(
`"Directive t-foreach should always be used with a t-key!" (expression: t-foreach="${collection}" t-as="${elem}")`
);
}
@@ -690,9 +682,7 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
let isDynamic = node.hasAttribute("t-component");
if (isDynamic && name !== "t") {
throw new OwlError(
`Directive 't-component' can only be used on <t> nodes (used on a <${name}>)`
);
throw new Error(`Directive 't-component' can only be used on <t> nodes (used on a <${name}>)`);
}
if (!(firstLetter === firstLetter.toUpperCase() || isDynamic)) {
@@ -719,7 +709,7 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
on[name.slice(5)] = value;
} else {
const message = directiveErrorMap.get(name.split("-").slice(0, 2).join("-"));
throw new OwlError(message || `unsupported directive on Component: ${name}`);
throw new Error(message || `unsupported directive on Component: ${name}`);
}
} else {
props = props || {};
@@ -735,7 +725,7 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
const slotNodes = Array.from(clone.querySelectorAll("[t-set-slot]"));
for (let slotNode of slotNodes) {
if (slotNode.tagName !== "t") {
throw new OwlError(
throw new Error(
`Directive 't-set-slot' can only be used on <t> nodes (used on a <${slotNode.tagName}>)`
);
}
@@ -781,9 +771,8 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
// default slot
const defaultContent = parseChildNodes(clone, ctx);
slots = slots || {};
// t-set-slot="default" has priority over content
if (defaultContent && !slots.default) {
if (defaultContent) {
slots = slots || {};
slots.default = { content: defaultContent, on, attrs: null, scope: defaultSlotScope };
}
}
@@ -911,7 +900,7 @@ function normalizeTIf(el: Element) {
let nattr = (name: string) => +!!node.getAttribute(name);
if (prevElem && (pattr("t-if") || pattr("t-elif"))) {
if (pattr("t-foreach")) {
throw new OwlError(
throw new Error(
"t-if cannot stay at the same level as t-foreach when using t-elif or t-else"
);
}
@@ -920,19 +909,19 @@ function normalizeTIf(el: Element) {
return a + b;
}) > 1
) {
throw new OwlError("Only one conditional branching directive is allowed per node");
throw new Error("Only one conditional branching directive is allowed per node");
}
// All text (with only spaces) and comment nodes (nodeType 8) between
// branch nodes are removed
let textNode;
while ((textNode = node.previousSibling) !== prevElem) {
if (textNode!.nodeValue!.trim().length && textNode!.nodeType !== 8) {
throw new OwlError("text is not allowed between branching directives");
throw new Error("text is not allowed between branching directives");
}
textNode!.remove();
}
} else {
throw new OwlError(
throw new Error(
"t-elif and t-else directives must be preceded by a t-if or t-elif directive"
);
}
@@ -953,7 +942,7 @@ function normalizeTEsc(el: Element) {
);
for (const el of elements) {
if (el.childNodes.length) {
throw new OwlError("Cannot have t-esc on a component that already has content");
throw new Error("Cannot have t-esc on a component that already has content");
}
const value = el.getAttribute("t-esc");
el.removeAttribute("t-esc");
@@ -1007,7 +996,7 @@ function parseXML(xml: string): XMLDocument {
}
}
}
throw new OwlError(msg);
throw new Error(msg);
}
return doc;
+7 -16
View File
@@ -1,12 +1,11 @@
import { Component, ComponentConstructor, Props } from "./component";
import { ComponentNode } from "./component_node";
import { nodeErrorHandlers, OwlError } from "./error_handling";
import { nodeErrorHandlers } from "./error_handling";
import { Fiber, MountOptions } from "./fibers";
import { Scheduler } from "./scheduler";
import { validateProps } from "./template_helpers";
import { TemplateSet, TemplateSetConfig } from "./template_set";
import { validateTarget } from "./utils";
import { handleError } from "./error_handling";
// reimplement dev mode stuff see last change in 0f7a8289a6fb8387c3c1af41c6664b2a8448758f
@@ -95,7 +94,9 @@ export class App<
nodeErrorHandlers.set(node, handlers);
}
handlers.unshift((e) => {
if (!isResolved) {
if (isResolved) {
console.error(e);
} else {
reject(e);
}
throw e;
@@ -151,17 +152,11 @@ export class App<
} else {
// new component
if (isStatic) {
const components = parent.constructor.components;
if (!components) {
throw new OwlError(
`Cannot find the definition of component "${name}", missing static components key in parent`
);
}
C = components[name as any];
C = parent.constructor.components[name as any];
if (!C) {
throw new OwlError(`Cannot find the definition of component "${name}"`);
throw new Error(`Cannot find the definition of component "${name}"`);
} else if (!(C.prototype instanceof Component)) {
throw new OwlError(
throw new Error(
`"${name}" is not a Component. It must inherit from the Component class`
);
}
@@ -174,10 +169,6 @@ export class App<
return node;
};
}
handleError(...args: Parameters<typeof handleError>) {
return handleError(...args);
}
}
export async function mount<
+1 -1
View File
@@ -144,7 +144,7 @@ export function updateClass(this: HTMLElement, val: any, oldVal: any) {
export function makePropSetter(name: string): Setter<HTMLElement> {
return function setProp(this: HTMLElement, value: any) {
// support 0, fallback to empty string for other falsy values
(this as any)[name] = value === 0 ? 0 : value ? value.valueOf() : "";
(this as any)[name] = value === 0 ? 0 : value || "";
};
}
+4 -18
View File
@@ -1,4 +1,3 @@
import { OwlError } from "../error_handling";
import {
attrsSetter,
attrsUpdater,
@@ -157,15 +156,6 @@ function buildTree(
: document.createElement(tagName);
}
if (el instanceof Element) {
if (!domParentTree) {
// some html elements may have side effects when setting their attributes.
// For example, setting the src attribute of an <img/> will trigger a
// request to get the corresponding image. This is something that we
// don't want at compile time. We avoid that by putting the content of
// the block in a <template/> element
const fragment = document.createElement("template").content;
fragment.appendChild(el);
}
for (let i = 0; i < attrs.length; i++) {
const attrName = attrs[i].name;
const attrValue = attrs[i].value;
@@ -255,7 +245,7 @@ function buildTree(
};
}
}
throw new OwlError("boom");
throw new Error("boom");
}
function addRef(tree: IntermediateTree) {
@@ -517,13 +507,9 @@ function createBlockClass(template: HTMLElement, ctx: BlockCtx): BlockClass {
return this.el!;
}
moveBeforeDOMNode(node: Node | null, parent = this.parentEl) {
this.parentEl = parent;
nodeInsertBefore.call(parent, this.el!, node);
}
moveBeforeVNode(other: Block | null, afterNode: Node | null) {
nodeInsertBefore.call(this.parentEl, this.el!, other ? other.el! : afterNode);
moveBefore(other: Block | null, afterNode: Node | null) {
const target = other ? other.el! : afterNode;
nodeInsertBefore.call(this.parentEl, this.el!, target);
}
toString() {
+3 -13
View File
@@ -46,7 +46,7 @@ export function createCatcher(eventsSpec: EventsSpec): Catcher {
const target = ev.target;
let currentNode: any = self.child.firstNode();
const afterNode = self.afterNode;
while (currentNode && currentNode !== afterNode) {
while (currentNode !== afterNode) {
if (currentNode.contains(target)) {
return origFn.call(this, ev);
}
@@ -56,18 +56,8 @@ export function createCatcher(eventsSpec: EventsSpec): Catcher {
}
}
moveBeforeDOMNode(node: Node | null, parent = this.parentEl) {
this.parentEl = parent;
this.child.moveBeforeDOMNode(node, parent);
parent!.insertBefore(this.afterNode!, node);
}
moveBeforeVNode(other: VCatcher | null, afterNode: Node | null) {
if (other) {
// check this with @ged-odoo for use in foreach
afterNode = other.firstNode() || afterNode;
}
this.child.moveBeforeVNode(other ? other.child : null, afterNode);
moveBefore(other: VCatcher | null, afterNode: Node | null) {
this.child.moveBefore(other ? other.child : null, afterNode);
this.parentEl!.insertBefore(this.afterNode!, afterNode);
}
+2 -2
View File
@@ -27,8 +27,8 @@ function createElementHandler(evName: string, capture: boolean = false): EventHa
}
function listener(ev: Event) {
const currentTarget = ev.currentTarget as HTMLElement;
if (!currentTarget || !currentTarget.ownerDocument.contains(currentTarget)) return;
const currentTarget = ev.currentTarget;
if (!currentTarget || !document.contains(currentTarget as HTMLElement)) return;
const data = (currentTarget as any)[eventKey];
if (!data) return;
config.mainEventHandler(data, ev, currentTarget);
+5 -9
View File
@@ -29,16 +29,12 @@ class VHtml {
}
}
moveBeforeDOMNode(node: Node | null, parent = this.parentEl) {
this.parentEl = parent;
for (let elem of this.content) {
nodeInsertBefore.call(parent, elem, node);
}
}
moveBeforeVNode(other: VHtml | null, afterNode: Node | null) {
moveBefore(other: VHtml | null, afterNode: Node | null) {
const target = other ? other.content[0] : afterNode;
this.moveBeforeDOMNode(target);
const parent = this.parentEl;
for (let elem of this.content) {
nodeInsertBefore.call(parent, elem, target);
}
}
patch(other: VHtml) {
+1 -2
View File
@@ -10,8 +10,7 @@ export { createCatcher } from "./event_catcher";
export interface VNode<T = any> {
mount(parent: HTMLElement, afterNode: Node | null): void;
moveBeforeDOMNode(node: Node | null, parent?: HTMLElement): void;
moveBeforeVNode(other: T | null, afterNode: Node | null): void;
moveBefore(other: T | null, afterNode: Node | null): void;
patch(other: T, withBeforeRemove: boolean): void;
beforeRemove(): void;
remove(): void;
+3 -12
View File
@@ -38,23 +38,14 @@ class VList {
this.parentEl = parent;
}
moveBeforeDOMNode(node: Node | null, parent = this.parentEl) {
this.parentEl = parent;
const children = this.children;
for (let i = 0, l = children.length; i < l; i++) {
children[i].moveBeforeDOMNode(node, parent);
}
parent!.insertBefore(this.anchor!, node);
}
moveBeforeVNode(other: VList | null, afterNode: Node | null) {
moveBefore(other: VList | null, afterNode: Node | null) {
if (other) {
const next = other!.children[0];
afterNode = (next ? next.firstNode() : other!.anchor) || null;
}
const children = this.children;
for (let i = 0, l = children.length; i < l; i++) {
children[i].moveBeforeVNode(null, afterNode);
children[i].moveBefore(null, afterNode);
}
this.parentEl!.insertBefore(this.anchor!, afterNode);
}
@@ -75,7 +66,7 @@ class VList {
patch: cPatch,
remove: cRemove,
beforeRemove,
moveBeforeVNode: cMoveBefore,
moveBefore: cMoveBefore,
firstNode: cFirstNode,
} = proto;
+2 -17
View File
@@ -38,22 +38,7 @@ export class VMulti {
this.parentEl = parent;
}
moveBeforeDOMNode(node: Node | null, parent = this.parentEl) {
this.parentEl = parent;
const children = this.children;
const anchors = this.anchors;
for (let i = 0, l = children.length; i < l; i++) {
let child = children[i];
if (child) {
child.moveBeforeDOMNode(node, parent);
} else {
const anchor = anchors![i];
nodeInsertBefore.call(parent, anchor, node);
}
}
}
moveBeforeVNode(other: VMulti | null, afterNode: Node | null) {
moveBefore(other: VMulti | null, afterNode: Node | null) {
if (other) {
const next = other!.children[0];
afterNode = (next ? next.firstNode() : other!.anchors![0]) || null;
@@ -64,7 +49,7 @@ export class VMulti {
for (let i = 0, l = children.length; i < l; i++) {
let child = children[i];
if (child) {
child.moveBeforeVNode(null, afterNode);
child.moveBefore(null, afterNode);
} else {
const anchor = anchors![i];
nodeInsertBefore.call(parent, anchor, afterNode);
+3 -7
View File
@@ -23,13 +23,9 @@ abstract class VSimpleNode {
this.el = node;
}
moveBeforeDOMNode(node: Node | null, parent = this.parentEl) {
this.parentEl = parent;
nodeInsertBefore.call(parent, this.el!, node);
}
moveBeforeVNode(other: VText | null, afterNode: Node | null) {
nodeInsertBefore.call(this.parentEl, this.el!, other ? other.el! : afterNode);
moveBefore(other: VText | null, afterNode: Node | null) {
const target = other ? other.el! : afterNode;
nodeInsertBefore.call(this.parentEl, this.el!, target);
}
beforeRemove() {}
+2 -6
View File
@@ -20,12 +20,8 @@ class VToggler {
this.child.mount(parent, afterNode);
}
moveBeforeDOMNode(node: Node | null, parent?: HTMLElement) {
this.child.moveBeforeDOMNode(node, parent);
}
moveBeforeVNode(other: VToggler | null, afterNode: Node | null) {
this.moveBeforeDOMNode((other && other.firstNode()) || afterNode);
moveBefore(other: VToggler | null, afterNode: Node | null) {
this.child.moveBefore(other ? other.child : null, afterNode);
}
patch(other: VToggler, withBeforeRemove: boolean) {
+19 -14
View File
@@ -1,9 +1,16 @@
import type { App, Env } from "./app";
import { BDom, VNode } from "./blockdom";
import { Component, ComponentConstructor, Props } from "./component";
import { fibersInError, OwlError } from "./error_handling";
import { fibersInError, handleError } from "./error_handling";
import { Fiber, makeChildFiber, makeRootFiber, MountFiber, MountOptions } from "./fibers";
import { clearReactivesForCallback, getSubscriptions, reactive, targets } from "./reactivity";
import {
clearReactivesForCallback,
getSubscriptions,
NonReactive,
Reactive,
reactive,
TARGET,
} from "./reactivity";
import { STATUS } from "./status";
import { batched, Callback } from "./utils";
@@ -11,7 +18,7 @@ let currentNode: ComponentNode | null = null;
export function getCurrent(): ComponentNode {
if (!currentNode) {
throw new OwlError("No active component (a hook function should only be called in 'setup')");
throw new Error("No active component (a hook function should only be called in 'setup')");
}
return currentNode;
}
@@ -45,7 +52,7 @@ const batchedRenderFunctions = new WeakMap<ComponentNode, Callback>();
* relevant changes
* @see reactive
*/
export function useState<T extends object>(state: T): T {
export function useState<T extends object>(state: T): Reactive<T> | NonReactive<T> {
const node = getCurrent();
let render = batchedRenderFunctions.get(node)!;
if (!render) {
@@ -76,6 +83,7 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
renderFn: Function;
parent: ComponentNode | null;
level: number;
childEnv: Env;
children: { [key: string]: ComponentNode } = Object.create(null);
refs: any = {};
@@ -100,6 +108,7 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
this.parent = parent;
this.props = props;
this.parentKey = parentKey;
this.level = parent ? parent.level + 1 : 0;
const defaultProps = C.defaultProps;
props = Object.assign({}, props);
if (defaultProps) {
@@ -109,7 +118,7 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
this.childEnv = env;
for (const key in props) {
const prop = props[key];
if (prop && typeof prop === "object" && targets.has(prop)) {
if (prop && typeof prop === "object" && prop[TARGET]) {
props[key] = useState(prop);
}
}
@@ -134,7 +143,7 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
try {
await Promise.all(this.willStart.map((f) => f.call(component)));
} catch (e) {
this.app.handleError({ node: this, error: e });
handleError({ node: this, error: e });
return;
}
if (this.status === STATUS.NEW && this.fiber === fiber) {
@@ -212,7 +221,7 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
cb.call(component);
}
} catch (e) {
this.app.handleError({ error: e, node: this });
handleError({ error: e, node: this });
}
}
this.status = STATUS.DESTROYED;
@@ -233,7 +242,7 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
currentNode = this;
for (const key in props) {
const prop = props[key];
if (prop && typeof prop === "object" && targets.has(prop)) {
if (prop && typeof prop === "object" && prop[TARGET]) {
props[key] = useState(prop);
}
}
@@ -299,12 +308,8 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
this.fiber = null;
}
moveBeforeDOMNode(node: Node | null, parent?: HTMLElement): void {
this.bdom!.moveBeforeDOMNode(node, parent);
}
moveBeforeVNode(other: ComponentNode<P, E> | null, afterNode: Node | null) {
this.bdom!.moveBeforeVNode(other ? other.bdom : null, afterNode);
moveBefore(other: ComponentNode | null, afterNode: Node | null) {
this.bdom!.moveBefore(other ? other.bdom : null, afterNode);
}
patch() {
+1 -14
View File
@@ -1,11 +1,6 @@
import type { ComponentNode } from "./component_node";
import type { Fiber } from "./fibers";
// Custom error class that wraps error that happen in the owl lifecycle
export class OwlError extends Error {
cause?: any;
}
// Maps fibers to thrown errors
export const fibersInError: WeakMap<Fiber, any> = new WeakMap();
export const nodeErrorHandlers: WeakMap<ComponentNode, ((error: any) => void)[]> = new WeakMap();
@@ -42,14 +37,7 @@ function _handleError(node: ComponentNode | null, error: any): boolean {
type ErrorParams = { error: any } & ({ node: ComponentNode } | { fiber: Fiber });
export function handleError(params: ErrorParams) {
let { error } = params;
// Wrap error if it wasn't wrapped by wrapError (ie when not in dev mode)
if (!(error instanceof OwlError)) {
error = Object.assign(
new OwlError(`An error occured in the owl lifecycle (see this Error's "cause" property)`),
{ cause: error }
);
}
const error = params.error;
const node = "node" in params ? params.node : params.fiber.node;
const fiber = "fiber" in params ? params.fiber : node.fiber!;
@@ -71,6 +59,5 @@ export function handleError(params: ErrorParams) {
} catch (e) {
console.error(e);
}
throw error;
}
}
+1 -2
View File
@@ -1,6 +1,5 @@
import { filterOutModifiersFromData } from "./blockdom/config";
import { STATUS } from "./status";
import { OwlError } from "./error_handling";
export const mainEventHandler = (data: any, ev: Event, currentTarget?: EventTarget | null) => {
const { data: _data, modifiers } = filterOutModifiersFromData(data);
@@ -34,7 +33,7 @@ export const mainEventHandler = (data: any, ev: Event, currentTarget?: EventTarg
if (Object.hasOwnProperty.call(data, 0)) {
const handler = data[0];
if (typeof handler !== "function") {
throw new OwlError(`Invalid handler (expected a function, received: '${handler}')`);
throw new Error(`Invalid handler (expected a function, received: '${handler}')`);
}
let node = data[1] ? data[1].__owl__ : null;
if (node ? node.status === STATUS.MOUNTED : true) {
+5 -5
View File
@@ -1,6 +1,6 @@
import { BDom, mount } from "./blockdom";
import type { ComponentNode } from "./component_node";
import { fibersInError, OwlError } from "./error_handling";
import { fibersInError, handleError } from "./error_handling";
import { STATUS } from "./status";
export function makeChildFiber(node: ComponentNode, parent: Fiber): Fiber {
@@ -43,7 +43,7 @@ export function makeRootFiber(node: ComponentNode): Fiber {
}
function throwOnRender() {
throw new OwlError("Attempted to render cancelled fiber");
throw new Error("Attempted to render cancelled fiber");
}
/**
@@ -130,7 +130,7 @@ export class Fiber {
(this.bdom as any) = true;
this.bdom = node.renderFn();
} catch (e) {
node.app.handleError({ node, error: e });
handleError({ node, error: e });
}
root.setCounter(root.counter - 1);
}
@@ -195,7 +195,7 @@ export class RootFiber extends Fiber {
}
} catch (e) {
this.locked = false;
node.app.handleError({ fiber: current || this, error: e });
handleError({ fiber: current || this, error: e });
}
}
@@ -259,7 +259,7 @@ export class MountFiber extends RootFiber {
}
}
} catch (e) {
this.node.app.handleError({ fiber: current as Fiber, error: e });
handleError({ fiber: current as Fiber, error: e });
}
}
}
+1 -2
View File
@@ -12,6 +12,7 @@ import {
comment,
} from "./blockdom";
import { mainEventHandler } from "./event_handling";
export type { Reactive } from "./reactivity";
config.shouldNormalizeDom = false;
config.mainEventHandler = mainEventHandler;
@@ -35,7 +36,6 @@ export const blockDom = {
export { App, mount } from "./app";
export { xml } from "./template_set";
export { Component } from "./component";
export type { ComponentConstructor } from "./component";
export { useComponent, useState } from "./component_node";
export { status } from "./status";
export { reactive, markRaw, toRaw } from "./reactivity";
@@ -54,6 +54,5 @@ export {
onError,
} from "./lifecycle_hooks";
export { validate } from "./validation";
export { OwlError } from "./error_handling";
export const __info__ = {};
+15 -15
View File
@@ -1,30 +1,21 @@
import { getCurrent } from "./component_node";
import { nodeErrorHandlers, OwlError } from "./error_handling";
import { nodeErrorHandlers } from "./error_handling";
const TIMEOUT = Symbol("timeout");
function wrapError(fn: (...args: any[]) => any, hookName: string) {
const error = new OwlError(`The following error occurred in ${hookName}: `) as Error & {
const error = new Error(`The following error occurred in ${hookName}: `) as Error & {
cause: any;
};
const timeoutError = new OwlError(`${hookName}'s promise hasn't resolved after 3 seconds`);
const timeoutError = new Error(`${hookName}'s promise hasn't resolved after 3 seconds`);
const node = getCurrent();
return (...args: any[]) => {
const onError = (cause: any) => {
error.cause = cause;
if (cause instanceof Error) {
error.message += `"${cause.message}"`;
} else {
error.message = `Something that is not an Error was thrown in ${hookName} (see this Error's "cause" property)`;
}
throw error;
};
try {
const result = fn(...args);
if (result instanceof Promise) {
if (hookName === "onWillStart" || hookName === "onWillUpdateProps") {
const fiber = node.fiber;
Promise.race([
result.catch(() => {}),
result,
new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)),
]).then((res) => {
if (res === TIMEOUT && node.fiber === fiber) {
@@ -32,11 +23,20 @@ function wrapError(fn: (...args: any[]) => any, hookName: string) {
}
});
}
return result.catch(onError);
return result.catch((cause) => {
error.cause = cause;
if (cause instanceof Error) {
error.message += `"${cause.message}"`;
}
throw error;
});
}
return result;
} catch (cause) {
onError(cause);
if (cause instanceof Error) {
error.message += `"${cause.message}"`;
}
throw error;
}
};
}
+32 -38
View File
@@ -1,60 +1,64 @@
import { onMounted, onWillUnmount } from "./lifecycle_hooks";
import { onWillUnmount } from "./lifecycle_hooks";
import { BDom, text, VNode } from "./blockdom";
import { Component } from "./component";
import { OwlError } from "./error_handling";
const VText: any = text("").constructor;
class VPortal extends VText implements Partial<VNode<VPortal>> {
content: BDom | null;
selector: string;
// selector: string;
realBDom: BDom | null;
target: HTMLElement | null = null;
constructor(selector: string, content: BDom) {
constructor(selector: string, realBDom: BDom) {
super("");
this.selector = selector;
this.content = content;
this.realBDom = realBDom;
}
mount(parent: HTMLElement, anchor: ChildNode) {
super.mount(parent, anchor);
this.target = document.querySelector(this.selector) as any;
if (this.target) {
this.content!.mount(this.target!, null);
} else {
this.content!.mount(parent, anchor);
if (!this.target) {
let el: any = this.el;
while (el && el.parentElement instanceof HTMLElement) {
el = el.parentElement;
}
this.target = el && el.querySelector(this.selector);
if (!this.target) {
throw new Error("invalid portal target");
}
}
this.realBDom!.mount(this.target!, null);
}
beforeRemove() {
this.content!.beforeRemove();
this.realBDom!.beforeRemove();
}
remove() {
if (this.content) {
if (this.realBDom) {
super.remove();
this.content!.remove();
this.content = null;
this.realBDom!.remove();
this.realBDom = null;
}
}
patch(other: VPortal) {
super.patch(other);
if (this.content) {
this.content.patch(other.content!, true);
if (this.realBDom) {
this.realBDom.patch(other.realBDom!, true);
} else {
this.content = other.content;
this.content!.mount(this.target!, null);
this.realBDom = other.realBDom;
this.realBDom!.mount(this.target!, null);
}
}
}
/**
* kind of similar to <t t-slot="default"/>, but it wraps it around a VPortal
* <t t-slot="default"/>
*/
export function portalTemplate(app: any, bdom: any, helpers: any) {
let { callSlot } = helpers;
return function template(ctx: any, node: any, key = ""): any {
return new VPortal(ctx.props.target, callSlot(ctx, node, key, "default", false, null));
return function template(ctx: any, node: any, key = "") {
return callSlot(ctx, node, key, "default", false, null);
};
}
@@ -68,23 +72,13 @@ export class Portal extends Component {
};
setup() {
const node: any = this.__owl__;
onMounted(() => {
const portal: VPortal = node.bdom;
if (!portal.target) {
const target: HTMLElement = document.querySelector(this.props.target);
if (target) {
portal.content!.moveBeforeDOMNode(target.firstChild, target);
} else {
throw new OwlError("invalid portal target");
}
}
});
const node = this.__owl__;
const renderFn = node.renderFn;
node.renderFn = () => new VPortal(this.props.target, renderFn());
onWillUnmount(() => {
const portal: VPortal = node.bdom;
portal.remove();
if (node.bdom) {
node.bdom.remove();
}
});
}
}
+46 -37
View File
@@ -1,17 +1,24 @@
import { Callback } from "./utils";
import { OwlError } from "./error_handling";
// Allows to get the target of a Reactive (used for making a new Reactive from the underlying object)
export const TARGET = Symbol("Target");
// Escape hatch to prevent reactivity system to turn something into a reactive
const SKIP = Symbol("Skip");
// Special key to subscribe to, to be notified of key creation/deletion
const KEYCHANGES = Symbol("Key changes");
// The following types only exist to signify places where objects are expected
// to be reactive or not, they provide no type checking benefit over "object"
type Target = object;
type Reactive<T extends Target> = T;
type Collection = Set<any> | Map<any, any> | WeakMap<any, any>;
type CollectionRawType = "Set" | "Map" | "WeakMap";
export type Reactive<T extends Target = Target> = T & {
[TARGET]: any;
};
export type NonReactive<T extends Target = Target> = T & {
[SKIP]: any;
};
const objectToString = Object.prototype.toString;
const objectHasOwnProperty = Object.prototype.hasOwnProperty;
@@ -28,7 +35,7 @@ const COLLECTION_RAWTYPES = new Set(["Set", "Map", "WeakMap"]);
* @returns the raw type of the object
*/
function rawType(obj: any) {
return objectToString.call(toRaw(obj)).slice(8, -1);
return objectToString.call(obj).slice(8, -1);
}
/**
* Checks whether a given value can be made into a reactive object.
@@ -53,16 +60,15 @@ function possiblyReactive(val: any, cb: Callback) {
return canBeMadeReactive(val) ? reactive(val, cb) : val;
}
const skipped = new WeakSet<Target>();
/**
* Mark an object or array so that it is ignored by the reactivity system
*
* @param value the value to mark
* @returns the object itself
*/
export function markRaw<T extends Target>(value: T): T {
skipped.add(value);
return value;
export function markRaw<T extends Target>(value: T): NonReactive<T> {
(value as any)[SKIP] = true;
return value as NonReactive<T>;
}
/**
@@ -71,8 +77,8 @@ export function markRaw<T extends Target>(value: T): T {
* @param value a reactive value
* @returns the underlying value
*/
export function toRaw<T extends Target, U extends Reactive<T>>(value: U | T): T {
return targets.has(value) ? (targets.get(value) as T) : value;
export function toRaw<T extends object>(value: Reactive<T>): T {
return value[TARGET] || value;
}
const targetToKeysToCallbacks = new WeakMap<Target, Map<PropertyKey, Set<Callback>>>();
@@ -157,9 +163,8 @@ export function getSubscriptions(callback: Callback) {
};
});
}
// Maps reactive objects to the underlying target
export const targets = new WeakMap<Reactive<Target>, Target>();
const reactiveCache = new WeakMap<Target, WeakMap<Callback, Reactive<Target>>>();
const reactiveCache = new WeakMap<Target, WeakMap<Callback, Reactive>>();
/**
* Creates a reactive proxy for an object. Reading data on the reactive object
* subscribes to changes to the data. Writing data on the object will cause the
@@ -174,7 +179,7 @@ const reactiveCache = new WeakMap<Target, WeakMap<Callback, Reactive<Target>>>()
* Subscriptions:
* + Reading a property on an object will subscribe you to changes in the value
* of that property.
* + Accessing an object's keys (eg with Object.keys or with `for..in`) will
* + Accessing an object keys (eg with Object.keys or with `for..in`) will
* subscribe you to the creation/deletion of keys. Checking the presence of a
* key on the object with 'in' has the same effect.
* - getOwnPropertyDescriptor does not currently subscribe you to the property.
@@ -187,16 +192,19 @@ const reactiveCache = new WeakMap<Target, WeakMap<Callback, Reactive<Target>>>()
* reactive has changed
* @returns a proxy that tracks changes to it
*/
export function reactive<T extends Target>(target: T, callback: Callback = () => {}): T {
export function reactive<T extends Target>(
target: T,
callback: Callback = () => {}
): Reactive<T> | NonReactive<T> {
if (!canBeMadeReactive(target)) {
throw new OwlError(`Cannot make the given value reactive`);
throw new Error(`Cannot make the given value reactive`);
}
if (skipped.has(target)) {
return target;
if (SKIP in target) {
return target as NonReactive<T>;
}
if (targets.has(target)) {
// target is reactive, create a reactive on the underlying object instead
return reactive(targets.get(target) as T, callback);
const originalTarget = (target as Reactive)[TARGET];
if (originalTarget) {
return reactive(originalTarget, callback);
}
if (!reactiveCache.has(target)) {
reactiveCache.set(target, new WeakMap());
@@ -209,7 +217,6 @@ export function reactive<T extends Target>(target: T, callback: Callback = () =>
: basicProxyHandler<T>(callback);
const proxy = new Proxy(target, handler as ProxyHandler<T>) as Reactive<T>;
reactivesForTarget.set(callback, proxy);
targets.set(proxy, target);
}
return reactivesForTarget.get(callback) as Reactive<T>;
}
@@ -221,29 +228,29 @@ export function reactive<T extends Target>(target: T, callback: Callback = () =>
*/
function basicProxyHandler<T extends Target>(callback: Callback): ProxyHandler<T> {
return {
get(target, key, receiver) {
get(target: any, key: PropertyKey, proxy: Reactive<T>) {
if (key === 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, receiver);
return Reflect.get(target, key, proxy);
}
observeTargetKey(target, key, callback);
return possiblyReactive(Reflect.get(target, key, receiver), callback);
return possiblyReactive(Reflect.get(target, key, proxy), callback);
},
set(target, key, value, receiver) {
const hadKey = objectHasOwnProperty.call(target, key);
const originalValue = Reflect.get(target, key, receiver);
const ret = Reflect.set(target, key, value, receiver);
if (!hadKey && objectHasOwnProperty.call(target, key)) {
set(target, key, value, proxy) {
const isNewKey = !objectHasOwnProperty.call(target, key);
const originalValue = Reflect.get(target, key, proxy);
const ret = Reflect.set(target, key, value, proxy);
if (isNewKey) {
notifyReactives(target, KEYCHANGES);
}
// While Array length may trigger the set trap, it's not actually set by this
// method but is updated behind the scenes, and the trap is not called with the
// new value. We disable the "same-value-optimization" for it because of that.
if (
originalValue !== Reflect.get(target, key, receiver) ||
(key === "length" && Array.isArray(target))
) {
if (originalValue !== value || (Array.isArray(target) && key === "length")) {
notifyReactives(target, key);
}
return ret;
@@ -436,8 +443,10 @@ function collectionsProxyHandler<T extends Collection>(
// property is read.
const specialHandlers = rawTypeToFuncHandlers[targetRawType](target, callback);
return Object.assign(basicProxyHandler(callback), {
// FIXME: probably broken when part of prototype chain since we ignore the receiver
get(target: any, key: PropertyKey) {
if (key === TARGET) {
return target;
}
if (objectHasOwnProperty.call(specialHandlers, key)) {
return (specialHandlers as any)[key];
}
+15 -27
View File
@@ -4,7 +4,6 @@ import { html } from "./blockdom/index";
import { isOptional, validateSchema } from "./validation";
import type { ComponentConstructor } from "./component";
import { markRaw } from "./reactivity";
import { OwlError } from "./error_handling";
const ObjectCreate = Object.create;
/**
@@ -29,24 +28,17 @@ function callSlot(
const slots = ctx.props.slots || {};
const { __render, __ctx, __scope } = slots[name] || {};
const slotScope = ObjectCreate(__ctx || {});
if (defaultContent) {
Object.defineProperty(slotScope, helpers.zero, {
get() {
return defaultContent(ctx, parent, key);
},
});
}
if (__scope) {
slotScope[__scope] = extra;
}
const slotBDom = __render ? __render(slotScope, parent, key) : null;
const slotBDom = __render ? __render.call(__ctx.__owl__.component, slotScope, parent, key) : null;
if (defaultContent) {
let child1: BDom | undefined = undefined;
let child2: BDom | undefined = undefined;
if (slotBDom) {
child1 = dynamic ? toggler(name, slotBDom) : slotBDom;
} else {
child2 = defaultContent(ctx, parent, key);
child2 = defaultContent.call(ctx.__owl__.component, ctx, parent, key);
}
return multi([child1, child2]);
}
@@ -54,7 +46,8 @@ function callSlot(
}
function capture(ctx: any): any {
const result = ObjectCreate(ctx);
const component = ctx.__owl__.component;
const result = ObjectCreate(component);
for (let k in ctx) {
result[k] = ctx[k];
}
@@ -77,7 +70,7 @@ function prepareList(collection: any): [any[], any[], number, any[]] {
values = Object.keys(collection);
keys = Object.values(collection);
} else {
throw new OwlError("Invalid loop expression");
throw new Error("Invalid loop expression");
}
const n = values.length;
return [keys, values, n, new Array(n)];
@@ -117,18 +110,15 @@ class LazyValue {
ctx: any;
component: any;
node: any;
key: any;
constructor(fn: any, ctx: any, component: any, node: any, key: any) {
constructor(fn: any, ctx: any, component: any, node: any) {
this.fn = fn;
this.ctx = capture(ctx);
this.component = component;
this.node = node;
this.key = key;
}
evaluate(): any {
return this.fn.call(this.component, this.ctx, this.node, this.key);
return this.fn.call(this.component, this.ctx, this.node);
}
toString() {
@@ -177,7 +167,8 @@ let boundFunctions = new WeakMap();
const WeakMapGet = WeakMap.prototype.get;
const WeakMapSet = WeakMap.prototype.set;
function bind(component: any, fn: Function): Function {
function bind(ctx: any, fn: Function): Function {
let component = ctx.__owl__.component;
let boundFnMap = WeakMapGet.call(boundFunctions, component);
if (!boundFnMap) {
boundFnMap = new WeakMap();
@@ -200,7 +191,7 @@ function multiRefSetter(refs: RefMap, name: string): RefSetter {
if (el) {
count++;
if (count > 1) {
throw new OwlError("Cannot have 2 elements with same ref name at the same time");
throw new Error("Cannot have 2 elements with same ref name at the same time");
}
}
if (count === 0 || el) {
@@ -215,11 +206,11 @@ function multiRefSetter(refs: RefMap, name: string): RefSetter {
* visit recursively the props and all the children to check if they are valid.
* This is why it is only done in 'dev' mode.
*/
export function validateProps<P>(name: string | ComponentConstructor<P>, props: P, comp?: any) {
export function validateProps<P>(name: string | ComponentConstructor<P>, props: P, parent?: any) {
const ComponentClass =
typeof name !== "string"
? name
: (comp.constructor.components[name] as ComponentConstructor<P> | undefined);
: (parent.constructor.components[name] as ComponentConstructor<P> | undefined);
if (!ComponentClass) {
// this is an error, wrong component. We silently return here instead so the
@@ -229,7 +220,7 @@ export function validateProps<P>(name: string | ComponentConstructor<P>, props:
const schema = ComponentClass.props;
if (!schema) {
if (comp.__owl__.app.warnIfNoStaticProps) {
if (parent.__owl__.app.warnIfNoStaticProps) {
console.warn(`Component '${ComponentClass.name}' does not have a static props description`);
}
return;
@@ -242,7 +233,7 @@ export function validateProps<P>(name: string | ComponentConstructor<P>, props:
: name in schema && !("*" in schema) && !isOptional(schema[name]);
for (let p in defaultProps) {
if (isMandatory(p)) {
throw new OwlError(
throw new Error(
`A default value cannot be defined for a mandatory prop (name: '${p}', component: ${ComponentClass.name})`
);
}
@@ -251,9 +242,7 @@ export function validateProps<P>(name: string | ComponentConstructor<P>, props:
const errors = validateSchema(props, schema);
if (errors.length) {
throw new OwlError(
`Invalid props for component '${ComponentClass.name}': ` + errors.join(", ")
);
throw new Error(`Invalid props for component '${ComponentClass.name}': ` + errors.join(", "));
}
}
@@ -275,5 +264,4 @@ export const helpers = {
bind,
createCatcher,
markRaw,
OwlError,
};
+4 -5
View File
@@ -3,7 +3,6 @@ import { comment, createBlock, html, list, multi, text, toggler } from "./blockd
import { getCurrent } from "./component_node";
import { Portal, portalTemplate } from "./portal";
import { helpers } from "./template_helpers";
import { OwlError } from "./error_handling";
const bdom = { text, createBlock, list, multi, html, toggler, comment };
@@ -32,7 +31,7 @@ function parseXML(xml: string): Document {
}
}
}
throw new OwlError(msg);
throw new Error(msg);
}
return doc;
}
@@ -77,7 +76,7 @@ export class TemplateSet {
if (currentAsString === newAsString) {
return;
}
throw new OwlError(`Template ${name} already defined with different content`);
throw new Error(`Template ${name} already defined with different content`);
}
this.rawTemplates[name] = template;
}
@@ -103,7 +102,7 @@ export class TemplateSet {
const componentName = getCurrent().component.constructor.name;
extraInfo = ` (for component "${componentName}")`;
} catch {}
throw new OwlError(`Missing template: "${name}"${extraInfo}`);
throw new Error(`Missing template: "${name}"${extraInfo}`);
}
const isFn = typeof rawTemplate === "function" && !(rawTemplate instanceof Element);
const templateFn = isFn ? rawTemplate : this._compileTemplate(name, rawTemplate);
@@ -120,7 +119,7 @@ export class TemplateSet {
}
_compileTemplate(name: string, template: string | Element): ReturnType<typeof compile> {
throw new OwlError(`Unable to compile a template. Please use owl full build instead`);
throw new Error(`Unable to compile a template. Please use owl full build instead`);
}
callTemplate(owner: any, subTemplate: string, ctx: any, parent: any, key: any): any {
+6 -13
View File
@@ -1,4 +1,3 @@
import { OwlError } from "./error_handling";
export type Callback = () => void;
/**
@@ -28,18 +27,12 @@ export function batched(callback: Callback): Callback {
}
export function validateTarget(target: HTMLElement) {
// Get the document and HTMLElement corresponding to the target to allow mounting in iframes
const document = target && target.ownerDocument;
if (document) {
const HTMLElement = document.defaultView!.HTMLElement;
if (target instanceof HTMLElement) {
if (!document.body.contains(target)) {
throw new OwlError("Cannot mount a component on a detached dom node");
}
return;
}
if (!(target instanceof HTMLElement)) {
throw new Error("Cannot mount component: the target is not a valid DOM element");
}
if (!document.body.contains(target)) {
throw new Error("Cannot mount a component on a detached dom node");
}
throw new OwlError("Cannot mount component: the target is not a valid DOM element");
}
export class EventBus extends EventTarget {
@@ -61,7 +54,7 @@ export function whenReady(fn?: any): Promise<void> {
export async function loadFile(url: string): Promise<string> {
const result = await fetch(url);
if (!result.ok) {
throw new OwlError("Error while fetching xml templates");
throw new Error("Error while fetching xml templates");
}
return await result.text();
}
+1 -3
View File
@@ -1,5 +1,3 @@
import { OwlError } from "./error_handling";
type BaseType =
| typeof String
| typeof Boolean
@@ -72,7 +70,7 @@ function toSchema(spec: SimplifiedSchema): NormalizedSchema {
export function validate(obj: { [key: string]: any }, spec: Schema) {
let errors = validateSchema(obj, spec);
if (errors.length) {
throw new OwlError("Invalid object: " + errors.join(", "));
throw new Error("Invalid object: " + errors.join(", "));
}
}
+19 -7
View File
@@ -347,21 +347,33 @@ exports[`Reactivity: useState useless atoms should be deleted 1`] = `
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`Quantity\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/> Total: <block-text-0/> Count: <block-text-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
Total: <block-text-0/>
Count: <block-text-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(Object.keys(ctx['state']));;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`id\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(Object.keys(ctx['state']));;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`id\`] = v_block4[i1];
const key1 = ctx['id'];
c_block2[i1] = withKey(comp1({id: ctx['id']}, key + \`__1__\${key1}\`, node, this, null), key1);
const b6 = text(\`
\`);
const b7 = comp1({id: ctx['id']}, key + \`__1__\${key1}\`, node, this, null);
const b8 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8]), key1);
}
ctx = ctx.__proto__;
const b2 = list(c_block2);
const b4 = list(c_block4);
let txt1 = ctx['total'];
let txt2 = Object.keys(ctx['state']).length;
return block1([txt1, txt2], [b2]);
const b3 = block3([txt1, txt2], [b4]);
return multi([b2, b3]);
}
}"
`;
-13
View File
@@ -29,19 +29,6 @@ exports[`app can configure an app with props 1`] = `
}"
`;
exports[`app can mount app in an iframe 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div class=\\"my-div\\"/>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
exports[`app destroy remove the widget from the DOM 1`] = `
"function anonymous(app, bdom, helpers
) {
-18
View File
@@ -76,22 +76,4 @@ describe("app", () => {
"Component 'Root' does not have a static props description"
);
});
test("can mount app in an iframe", async () => {
class SomeComponent extends Component {
static template = xml`<div class="my-div"/>`;
}
const iframe = document.createElement("iframe");
fixture.appendChild(iframe);
const app = new App(SomeComponent);
const iframeDoc = iframe.contentDocument!;
const comp = await app.mount(iframeDoc.body);
const div = iframeDoc.querySelector(".my-div");
expect(div).not.toBe(null);
expect(iframeDoc.contains(div)).toBe(true);
app.destroy();
expect(iframeDoc.contains(div)).toBe(false);
expect(status(comp)).toBe("destroyed");
});
});
@@ -342,14 +342,20 @@ exports[`attributes from object variables set previously 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><span block-attribute-0=\\"class\\"/></div>\`);
let block3 = createBlock(\`<div>
<span block-attribute-0=\\"class\\"/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"o\\", {a:'b'});
let attr1 = ctx['o'].a;
return block1([attr1]);
const b3 = block3([attr1]);
return multi([b2, b3]);
}
}"
`;
@@ -360,14 +366,19 @@ exports[`attributes from variables set previously (no external node) 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<span block-attribute-0=\\"class\\"/>\`);
let block4 = createBlock(\`<span block-attribute-0=\\"class\\"/>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"abc\\", 'def');
const b3 = text(\`
\`);
let attr1 = ctx['abc'];
return block1([attr1]);
const b4 = block4([attr1]);
return multi([b2, b3, b4]);
}
}"
`;
@@ -430,19 +441,6 @@ exports[`attributes static attributes on void elements 1`] = `
}"
`;
exports[`attributes static attributes with backslash or backtick 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div foo=\\"\\\\\\\\a\\" bar=\\"\\\\\\\\n\\" baz=\\"\\\\\`\\"/>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
exports[`attributes static attributes with backticks 1`] = `
"function anonymous(app, bdom, helpers
) {
@@ -721,32 +719,21 @@ exports[`attributes updating classes (with obj notation) 1`] = `
}"
`;
exports[`attributes updating property with falsy value 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<input block-attribute-0=\\"value\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new String((ctx['v']) || \\"\\");
return block1([attr1]);
}
}"
`;
exports[`attributes various escapes 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div foo=\\"&lt;foo\\" block-attribute-0=\\"bar\\" block-attribute-1=\\"baz\\" block-attributes=\\"2\\"/>\`);
let block3 = createBlock(\`<div foo=\\"&lt;foo\\" block-attribute-0=\\"bar\\" block-attribute-1=\\"baz\\" block-attributes=\\"2\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let attr1 = ctx['bar'];
let attr2 = \`<\${ctx['baz']}>\`;
let attr3 = ctx['qux'];
return block1([attr1, attr2, attr3]);
const b3 = block3([attr1, attr2, attr3]);
return multi([b2, b3]);
}
}"
`;
@@ -772,7 +759,7 @@ exports[`special cases for some specific html attributes/properties input of typ
let block1 = createBlock(\`<input type=\\"checkbox\\" block-attribute-0=\\"indeterminate\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new Boolean(ctx['v']);
let attr1 = ctx['v'];
return block1([attr1]);
}
}"
@@ -786,21 +773,7 @@ exports[`special cases for some specific html attributes/properties input type=
let block1 = createBlock(\`<input type=\\"checkbox\\" block-attribute-0=\\"checked\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new Boolean(ctx['flag']);
return block1([attr1]);
}
}"
`;
exports[`special cases for some specific html attributes/properties input with t-att-value (patching with same value 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<input block-attribute-0=\\"value\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new String((ctx['v']) || \\"\\");
let attr1 = ctx['flag'];
return block1([attr1]);
}
}"
@@ -814,21 +787,7 @@ exports[`special cases for some specific html attributes/properties input with t
let block1 = createBlock(\`<input block-attribute-0=\\"value\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new String((ctx['v']) || \\"\\");
return block1([attr1]);
}
}"
`;
exports[`special cases for some specific html attributes/properties input, type checkbox, with t-att-checked (patching with same value 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<input type=\\"checkbox\\" block-attribute-0=\\"checked\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new Boolean(ctx['v']);
let attr1 = ctx['v'];
return block1([attr1]);
}
}"
@@ -839,11 +798,18 @@ exports[`special cases for some specific html attributes/properties select with
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<select block-attribute-0=\\"value\\"><option value=\\"potato\\">Potato</option><option value=\\"tomato\\">Tomato</option><option value=\\"onion\\">Onion</option></select>\`);
let block3 = createBlock(\`<select block-attribute-0=\\"value\\">
<option value=\\"potato\\">Potato</option>
<option value=\\"tomato\\">Tomato</option>
<option value=\\"onion\\">Onion</option>
</select>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new String((ctx['value']) || \\"\\");
return block1([attr1]);
const b2 = text(\`
\`);
let attr1 = ctx['value'];
const b3 = block3([attr1]);
return multi([b2, b3]);
}
}"
`;
@@ -856,7 +822,7 @@ exports[`special cases for some specific html attributes/properties textarea wit
let block1 = createBlock(\`<textarea block-attribute-0=\\"value\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new String((ctx['v']) || \\"\\");
let attr1 = ctx['v'];
return block1([attr1]);
}
}"
@@ -867,10 +833,23 @@ exports[`special cases for some specific html attributes/properties various bool
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><input type=\\"checkbox\\" checked=\\"checked\\"/><input checked=\\"checked\\"/><div checked=\\"checked\\"/><div selected=\\"selected\\"/><option selected=\\"selected\\" other=\\"1\\"/><input readonly=\\"readonly\\"/><button disabled=\\"disabled\\"/></div>\`);
let block3 = createBlock(\`<div>
<input type=\\"checkbox\\" checked=\\"checked\\"/>
<input checked=\\"checked\\"/>
<div checked=\\"checked\\"/>
<div selected=\\"selected\\"/>
<option selected=\\"selected\\" other=\\"1\\"/>
<input readonly=\\"readonly\\"/>
<button disabled=\\"disabled\\"/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
const b2 = text(\`
\`);
const b3 = block3();
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -29,18 +29,23 @@ exports[`comments properly handle comments between t-if/t-else 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block2 = createBlock(\`<span>true</span>\`);
let block3 = createBlock(\`<span>owl</span>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/>
</div>\`);
let block4 = createBlock(\`<span>true</span>\`);
let block5 = createBlock(\`<span>owl</span>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (true) {
b2 = block2();
b4 = block4();
} else {
b3 = block3();
b5 = block5();
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -65,23 +65,31 @@ exports[`t-on can bind handlers with empty object (with non empty inner string)
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<ul><block-child-0/></ul>\`);
let block3 = createBlock(\`<li><a block-handler-0=\\"click\\">link</a></li>\`);
let block3 = createBlock(\`<ul>
<block-child-0/>
</ul>\`);
let block5 = createBlock(\`<li>
<a block-handler-0=\\"click\\">link</a>
</li>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(['someval']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`action\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(['someval']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`action\`] = v_block4[i1];
ctx[\`action_index\`] = i1;
const key1 = ctx['action_index'];
const v1 = ctx['activate'];
const v2 = ctx['action'];
let hdlr1 = [()=>v1(v2), ctx];
c_block2[i1] = withKey(block3([hdlr1]), key1);
c_block4[i1] = withKey(block5([hdlr1]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -106,12 +114,15 @@ exports[`t-on can bind two event handlers 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\" block-handler-1=\\"dblclick\\">Click</button>\`);
let block3 = createBlock(\`<button block-handler-0=\\"click\\" block-handler-1=\\"dblclick\\">Click</button>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let hdlr1 = [ctx['handleClick'], ctx];
let hdlr2 = [ctx['handleDblClick'], ctx];
return block1([hdlr1, hdlr2]);
const b3 = block3([hdlr1, hdlr2]);
return multi([b2, b3]);
}
}"
`;
@@ -136,18 +147,26 @@ exports[`t-on handler is bound to proper owner, part 2 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block2 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
let block6 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList([1]);;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`value\`] = v_block1[i1];
const [k_block3, v_block3, l_block3, c_block3] = prepareList([1]);;
for (let i1 = 0; i1 < l_block3; i1++) {
ctx[\`value\`] = v_block3[i1];
const key1 = ctx['value'];
const b5 = text(\`
\`);
let hdlr1 = [ctx['add'], ctx];
c_block1[i1] = withKey(block2([hdlr1]), key1);
const b6 = block6([hdlr1]);
const b7 = text(\`
\`);
c_block3[i1] = withKey(multi([b5, b6, b7]), key1);
}
return list(c_block1);
const b3 = list(c_block3);
return multi([b2, b3]);
}
}"
`;
@@ -186,18 +205,26 @@ exports[`t-on handler is bound to proper owner, part 4 1`] = `
const callTemplate_1 = app.getTemplate(\`sub\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList([1]);;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`value\`] = v_block1[i1];
const [k_block3, v_block3, l_block3, c_block3] = prepareList([1]);;
for (let i1 = 0; i1 < l_block3; i1++) {
ctx[\`value\`] = v_block3[i1];
ctx[\`value_first\`] = i1 === 0;
ctx[\`value_last\`] = i1 === v_block1.length - 1;
ctx[\`value_last\`] = i1 === v_block3.length - 1;
ctx[\`value_index\`] = i1;
ctx[\`value_value\`] = k_block1[i1];
ctx[\`value_value\`] = k_block3[i1];
const key1 = ctx['value'];
c_block1[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1);
const b5 = text(\`
\`);
const b6 = callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`);
const b7 = text(\`
\`);
c_block3[i1] = withKey(multi([b5, b6, b7]), key1);
}
return list(c_block1);
const b3 = list(c_block3);
return multi([b2, b3]);
}
}"
`;
@@ -235,7 +262,9 @@ exports[`t-on t-on modifiers (native listener) basic support for native listener
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div class=\\"myClass\\" block-handler-0=\\"click\\"><button block-handler-1=\\"click\\">Button</button></div>\`);
let block1 = createBlock(\`<div class=\\"myClass\\" block-handler-0=\\"click\\">
<button block-handler-1=\\"click\\">Button</button>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [ctx['divClicked'], ctx];
@@ -281,7 +310,9 @@ exports[`t-on t-on modifiers (native listener) t-on with .capture modifier 1`] =
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div block-handler-0=\\"click.capture\\"><button block-handler-1=\\"click\\">Button</button></div>\`);
let block1 = createBlock(\`<div block-handler-0=\\"click.capture\\">
<button block-handler-1=\\"click\\">Button</button>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [\\"capture\\", ctx['onCapture'], ctx];
@@ -296,7 +327,9 @@ exports[`t-on t-on modifiers (native listener) t-on with empty handler (only mod
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><button block-handler-0=\\"click.prevent\\">Button</button></div>\`);
let block1 = createBlock(\`<div>
<button block-handler-0=\\"click.prevent\\">Button</button>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [\\"prevent\\", , ctx];
@@ -310,7 +343,9 @@ exports[`t-on t-on modifiers (native listener) t-on with prevent and self modifi
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><button block-handler-0=\\"click.prevent.self\\"><span>Button</span></button></div>\`);
let block1 = createBlock(\`<div>
<button block-handler-0=\\"click.prevent.self\\"><span>Button</span></button>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [\\"prevent\\",\\"self\\", ctx['onClick'], ctx];
@@ -324,7 +359,11 @@ exports[`t-on t-on modifiers (native listener) t-on with prevent and/or stop mod
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><button block-handler-0=\\"click.prevent\\">Button 1</button><button block-handler-1=\\"click.stop\\">Button 2</button><button block-handler-2=\\"click.prevent.stop\\">Button 3</button></div>\`);
let block1 = createBlock(\`<div>
<button block-handler-0=\\"click.prevent\\">Button 1</button>
<button block-handler-1=\\"click.stop\\">Button 2</button>
<button block-handler-2=\\"click.prevent.stop\\">Button 3</button>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [\\"prevent\\", ctx['onClickPrevented'], ctx];
@@ -341,8 +380,12 @@ exports[`t-on t-on modifiers (native listener) t-on with prevent modifier in t-f
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<a href=\\"#\\" block-handler-0=\\"click.prevent\\"> Edit <block-text-1/></a>\`);
let block1 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block5 = createBlock(\`<a href=\\"#\\" block-handler-0=\\"click.prevent\\">
Edit <block-text-1/>
</a>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
@@ -350,12 +393,18 @@ exports[`t-on t-on modifiers (native listener) t-on with prevent modifier in t-f
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`project\`] = v_block2[i1];
const key1 = ctx['project'];
const b4 = text(\`
\`);
const v1 = ctx['onEdit'];
const v2 = ctx['project'];
let hdlr1 = [\\"prevent\\", _ev=>v1(v2.id,_ev), ctx];
let txt1 = ctx['project'].name;
c_block2[i1] = withKey(block3([hdlr1, txt1]), key1);
const b5 = block5([hdlr1, txt1]);
const b6 = text(\`
\`);
c_block2[i1] = withKey(multi([b4, b5, b6]), key1);
}
ctx = ctx.__proto__;
const b2 = list(c_block2);
return block1([], [b2]);
}
@@ -367,7 +416,9 @@ exports[`t-on t-on modifiers (native listener) t-on with self and prevent modifi
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><button block-handler-0=\\"click.self.prevent\\"><span>Button</span></button></div>\`);
let block1 = createBlock(\`<div>
<button block-handler-0=\\"click.self.prevent\\"><span>Button</span></button>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [\\"self\\",\\"prevent\\", ctx['onClick'], ctx];
@@ -381,7 +432,10 @@ exports[`t-on t-on modifiers (native listener) t-on with self modifier 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><button block-handler-0=\\"click\\"><span>Button</span></button><button block-handler-1=\\"click.self\\"><span>Button</span></button></div>\`);
let block1 = createBlock(\`<div>
<button block-handler-0=\\"click\\"><span>Button</span></button>
<button block-handler-1=\\"click.self\\"><span>Button</span></button>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [ctx['onClick'], ctx];
@@ -396,7 +450,9 @@ exports[`t-on t-on modifiers (synthetic listener) basic support for synthetic 1`
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div block-handler-0=\\"click.synthetic\\"><button block-handler-1=\\"click.synthetic\\">Button</button></div>\`);
let block1 = createBlock(\`<div block-handler-0=\\"click.synthetic\\">
<button block-handler-1=\\"click.synthetic\\">Button</button>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [\\"synthetic\\", ctx['divClicked'], ctx];
+322 -111
View File
@@ -7,74 +7,116 @@ exports[`misc complex template 1`] = `
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`SlotButton\`, true, false, false, false);
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"><div block-attribute-1=\\"class\\"><div class=\\"batch_header\\"><a block-attribute-2=\\"href\\" block-attribute-3=\\"class\\" title=\\"View Batch\\"><block-text-4/><block-child-0/><i class=\\"arrow fa fa-window-maximize\\"/></a></div><block-child-1/><div class=\\"batch_slots\\"><block-child-2/><block-child-3/></div><div class=\\"batch_commits\\"><block-child-4/></div></div></div>\`);
let block2 = createBlock(\`<i class=\\"fa fa-exclamation-triangle\\"/>\`);
let block3 = createBlock(\`<span><i class=\\"fa fa-cog fa-spin fa-fw\\"/> preparing</span>\`);
let block7 = createBlock(\`<div class=\\"slot_filler\\"/>\`);
let block9 = createBlock(\`<div class=\\"one_line\\"><a block-attribute-0=\\"href\\" block-attribute-1=\\"class\\"><block-child-0/><block-child-1/><block-child-2/><block-child-3/><block-text-2/></a><a block-attribute-3=\\"href\\" class=\\"badge badge-light\\" title=\\"View Commit on Github\\"><i class=\\"fa fa-github\\"/></a><span><block-text-4/></span></div>\`);
let block10 = createBlock(\`<i class=\\"fa fa-fw fa-hashtag\\" title=\\"This commit is a new head\\"/>\`);
let block11 = createBlock(\`<i class=\\"fa fa-fw fa-link\\" title=\\"This commit is an existing head from bundle branches\\"/>\`);
let block12 = createBlock(\`<i class=\\"fa fa-fw fa-code-fork\\" title=\\"This commit is matched from a base batch with matching merge_base\\"/>\`);
let block13 = createBlock(\`<i class=\\"fa fa-fw fa-clock-o\\" title=\\"This commit is the head of a base branch\\"/>\`);
let block3 = createBlock(\`<div block-attribute-0=\\"class\\">
<div block-attribute-1=\\"class\\">
<div class=\\"batch_header\\">
<a block-attribute-2=\\"href\\" block-attribute-3=\\"class\\" title=\\"View Batch\\">
<block-text-4/>
<block-child-0/>
<i class=\\"arrow fa fa-window-maximize\\"/>
</a>
</div>
<block-child-1/>
<div class=\\"batch_slots\\">
<block-child-2/>
<block-child-3/>
</div>
<div class=\\"batch_commits\\">
<block-child-4/>
</div>
</div>
</div>\`);
let block4 = createBlock(\`<i class=\\"fa fa-exclamation-triangle\\"/>\`);
let block7 = createBlock(\`<span><i class=\\"fa fa-cog fa-spin fa-fw\\"/> preparing</span>\`);
let block15 = createBlock(\`<div class=\\"slot_filler\\"/>\`);
let block17 = createBlock(\`<div class=\\"one_line\\">
<a block-attribute-0=\\"href\\" block-attribute-1=\\"class\\">
<block-child-0/>
<block-child-1/>
<block-child-2/>
<block-child-3/>
<block-text-2/>
</a>
<a block-attribute-3=\\"href\\" class=\\"badge badge-light\\" title=\\"View Commit on Github\\"><i class=\\"fa fa-github\\"/></a>
<span><block-text-4/></span>
</div>\`);
let block18 = createBlock(\`<i class=\\"fa fa-fw fa-hashtag\\" title=\\"This commit is a new head\\"/>\`);
let block19 = createBlock(\`<i class=\\"fa fa-fw fa-link\\" title=\\"This commit is an existing head from bundle branches\\"/>\`);
let block20 = createBlock(\`<i class=\\"fa fa-fw fa-code-fork\\" title=\\"This commit is matched from a base batch with matching merge_base\\"/>\`);
let block21 = createBlock(\`<i class=\\"fa fa-fw fa-clock-o\\" title=\\"This commit is the head of a base branch\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3,b4,b6,b8;
const b2 = text(\`
\`);
let b4,b5,b9,b14,b16;
let attr1 = \`batch_tile \${ctx['options'].more?'more':'nomore'}\`;
let attr2 = \`card bg-\${ctx['klass']}-light\`;
let attr3 = \`/runbot/batch/\${ctx['batch'].id}\`;
let attr4 = \`badge badge-\${ctx['batch'].has_warning?'warning':'light'}\`;
let txt1 = ctx['batch'].formated_age;
if (ctx['batch'].has_warning) {
b2 = block2();
b4 = block4();
}
if (ctx['batch'].state=='preparing') {
b3 = block3();
const b6 = text(\`
\`);
const b7 = block7();
const b8 = text(\`
\`);
b5 = multi([b6, b7, b8]);
}
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])));;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`slot\`] = v_block4[i1];
const [k_block9, v_block9, l_block9, c_block9] = 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_block9; i1++) {
ctx[\`slot\`] = v_block9[i1];
const key1 = ctx['slot'].id;
c_block4[i1] = withKey(comp1({class: ctx['slot_container'],slot: ctx['slot']}, key + \`__1__\${key1}\`, node, this, null), key1);
const b11 = text(\`
\`);
const b12 = comp1({class: ctx['slot_container'],slot: ctx['slot']}, key + \`__1__\${key1}\`, node, this, null);
const b13 = text(\`
\`);
c_block9[i1] = withKey(multi([b11, b12, b13]), key1);
}
ctx = ctx.__proto__;
b4 = list(c_block4);
b9 = list(c_block9);
ctx = Object.create(ctx);
const [k_block6, v_block6, l_block6, c_block6] = prepareList([1,2,3,4]);;
for (let i1 = 0; i1 < l_block6; i1++) {
ctx[\`x\`] = v_block6[i1];
const [k_block14, v_block14, l_block14, c_block14] = prepareList([1,2,3,4]);;
for (let i1 = 0; i1 < l_block14; i1++) {
ctx[\`x\`] = v_block14[i1];
const key1 = ctx['x'];
c_block6[i1] = withKey(block7(), key1);
c_block14[i1] = withKey(block15(), key1);
}
ctx = ctx.__proto__;
b6 = list(c_block6);
b14 = list(c_block14);
ctx = Object.create(ctx);
const [k_block8, v_block8, l_block8, c_block8] = prepareList(ctx['commit_links']);;
for (let i1 = 0; i1 < l_block8; i1++) {
ctx[\`commit_link\`] = v_block8[i1];
const [k_block16, v_block16, l_block16, c_block16] = prepareList(ctx['commit_links']);;
for (let i1 = 0; i1 < l_block16; i1++) {
ctx[\`commit_link\`] = v_block16[i1];
const key1 = ctx['commit_link'].id;
let b10,b11,b12,b13;
let b18,b19,b20,b21;
let attr5 = \`/runbot/commit/\${ctx['commit_link'].commit_id}\`;
let attr6 = \`badge badge-light batch_commit match_type_\${ctx['commit_link'].match_type}\`;
if (ctx['commit_link'].match_type=='new') {
b10 = block10();
b18 = block18();
}
if (ctx['commit_link'].match_type=='head') {
b11 = block11();
b19 = block19();
}
if (ctx['commit_link'].match_type=='base_match') {
b12 = block12();
b20 = block20();
}
if (ctx['commit_link'].match_type=='base_head') {
b13 = block13();
b21 = block21();
}
let txt2 = ctx['commit_link'].commit_dname;
let attr7 = 'https://%s/commit/%s'%(ctx['commit_link'].commit_remote_url,ctx['commit_link'].commit_name);
let txt3 = ctx['commit_link'].commit_subject;
c_block8[i1] = withKey(block9([attr5, attr6, txt2, attr7, txt3], [b10, b11, b12, b13]), key1);
c_block16[i1] = withKey(block17([attr5, attr6, txt2, attr7, txt3], [b18, b19, b20, b21]), key1);
}
b8 = list(c_block8);
return block1([attr1, attr2, attr3, attr4, txt1], [b2, b3, b4, b6, b8]);
ctx = ctx.__proto__;
b16 = list(c_block16);
const b3 = block3([attr1, attr2, attr3, attr4, txt1], [b4, b5, b9, b14, b16]);
return multi([b2, b3]);
}
}"
`;
@@ -90,43 +132,71 @@ exports[`misc global 1`] = `
const callTemplate_4 = app.getTemplate(\`_callee-asc\`);
const callTemplate_5 = app.getTemplate(\`_callee-asc-toto\`);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block4 = createBlock(\`<span><block-text-0/></span>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<block-child-1/>
</div>\`);
let block7 = createBlock(\`<span><block-text-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList([4,5,6]);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`value\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList([4,5,6]);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`value\`] = v_block4[i1];
ctx[\`value_first\`] = i1 === 0;
ctx[\`value_last\`] = i1 === v_block2.length - 1;
ctx[\`value_last\`] = i1 === v_block4.length - 1;
ctx[\`value_index\`] = i1;
ctx[\`value_value\`] = k_block2[i1];
ctx[\`value_value\`] = k_block4[i1];
const key1 = ctx['value'];
const b6 = text(\`
\`);
let txt1 = ctx['value'];
const b4 = block4([txt1]);
const b7 = block7([txt1]);
const b8 = text(\`
\`);
ctx = Object.create(ctx);
ctx[isBoundary] = 1;
const b10 = text(\`
\`);
ctx = Object.create(ctx);
ctx[isBoundary] = 1;
const b12 = text(\`
\`);
setContextValue(ctx, \\"foo\\", 'aaa');
const b6 = callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`);
const b13 = text(\`
\`);
const b11 = multi([b12, b13]);
ctx[zero] = b11;
const b14 = callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`);
ctx = ctx.__proto__;
const b7 = callTemplate_2.call(this, ctx, node, key + \`__2__\${key1}\`);
const b15 = text(\`
\`);
const b16 = callTemplate_2.call(this, ctx, node, key + \`__2__\${key1}\`);
const b17 = text(\`
\`);
setContextValue(ctx, \\"foo\\", 'bbb');
const b8 = callTemplate_3.call(this, ctx, node, key + \`__3__\${key1}\`);
const b5 = multi([b6, b7, b8]);
ctx[zero] = b5;
const b9 = callTemplate_4.call(this, ctx, node, key + \`__4__\${key1}\`);
const b18 = text(\`
\`);
const b19 = callTemplate_3.call(this, ctx, node, key + \`__3__\${key1}\`);
const b20 = text(\`
\`);
const b9 = multi([b10, b14, b15, b16, b17, b18, b19, b20]);
ctx[zero] = b9;
const b21 = callTemplate_4.call(this, ctx, node, key + \`__4__\${key1}\`);
ctx = ctx.__proto__;
c_block2[i1] = withKey(multi([b4, b9]), key1);
const b22 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8, b21, b22]), key1);
}
ctx = ctx.__proto__;
const b2 = list(c_block2);
const b10 = callTemplate_5.call(this, ctx, node, key + \`__5\`);
return block1([], [b2, b10]);
const b4 = list(c_block4);
const b23 = callTemplate_5.call(this, ctx, node, key + \`__5\`);
const b3 = block3([], [b4, b23]);
return multi([b2, b3]);
}
}"
`;
@@ -187,7 +257,48 @@ exports[`misc other complex template 1`] = `
const comp1 = app.createComponent(\`BundlesList\`, true, false, false, false);
const comp2 = app.createComponent(\`BundlesList\`, true, false, false, false);
let block1 = createBlock(\`<div><header><nav class=\\"navbar navbar-expand-md navbar-light bg-light\\"><a block-attribute-0=\\"href\\"><b style=\\"color:#777;\\"><block-text-1/></b></a><button type=\\"button\\" class=\\"navbar-toggler\\" data-toggle=\\"collapse\\" data-target=\\"#top_menu_collapse\\"><span class=\\"navbar-toggler-icon\\"/></button><div class=\\"collapse navbar-collapse\\" id=\\"top_menu_collapse\\" aria-expanded=\\"false\\"><ul class=\\"nav navbar-nav ml-auto text-right\\" id=\\"top_menu\\"><block-child-0/><li class=\\"nav-item divider\\"/><block-child-1/></ul><div><div class=\\"input-group input-group-sm\\"><div class=\\"input-group-prepend input-group-sm\\"><button class=\\"btn btn-default fa fa-cog\\" title=\\"Settings\\" block-handler-2=\\"click\\"/><button class=\\"btn btn-default\\" block-handler-3=\\"click\\"> More </button><block-child-2/></div><input class=\\"form-control\\" type=\\"text\\" placeholder=\\"Search\\" aria-label=\\"Search\\" name=\\"search\\" block-attribute-4=\\"value\\" block-handler-5=\\"keyup\\" block-handler-6=\\"change\\" block-ref=\\"7\\"/><div class=\\"input-group-append\\"><button class=\\"btn btn-default fa fa-eraser\\" block-handler-8=\\"click\\"/></div></div></div></div></nav></header><div class=\\"container-fluid\\" block-ref=\\"9\\"><div class=\\"row\\"><!--div class=\\"form-group col-md-6\\">
let block3 = createBlock(\`<div>
<header>
<nav class=\\"navbar navbar-expand-md navbar-light bg-light\\">
<a block-attribute-0=\\"href\\">
<b style=\\"color:#777;\\">
<block-text-1/>
</b>
</a>
<button type=\\"button\\" class=\\"navbar-toggler\\" data-toggle=\\"collapse\\" data-target=\\"#top_menu_collapse\\">
<span class=\\"navbar-toggler-icon\\"/>
</button>
<div class=\\"collapse navbar-collapse\\" id=\\"top_menu_collapse\\" aria-expanded=\\"false\\">
<ul class=\\"nav navbar-nav ml-auto text-right\\" id=\\"top_menu\\">
<block-child-0/>
<li class=\\"nav-item divider\\"/>
<block-child-1/>
</ul>
<div>
<div class=\\"input-group input-group-sm\\">
<div class=\\"input-group-prepend input-group-sm\\">
<button class=\\"btn btn-default fa fa-cog\\" title=\\"Settings\\" block-handler-2=\\"click\\"/>
<button class=\\"btn btn-default\\" block-handler-3=\\"click\\">
More
</button>
<block-child-2/>
</div>
<input class=\\"form-control\\" type=\\"text\\" placeholder=\\"Search\\" aria-label=\\"Search\\" name=\\"search\\" block-attribute-4=\\"value\\" block-handler-5=\\"keyup\\" block-handler-6=\\"change\\" block-ref=\\"7\\"/>
<div class=\\"input-group-append\\">
<button class=\\"btn btn-default fa fa-eraser\\" block-handler-8=\\"click\\"/>
</div>
</div>
</div>
</div>
</nav>
</header>
<div class=\\"container-fluid\\" block-ref=\\"9\\">
<div class=\\"row\\">
<!--div class=\\"form-group col-md-6\\">
<h5>Search options</h5>
<input class=\\"form-control\\" type=\\"text\\" name=\\"default_search\\" id=\\"default_search\\" t-att-checked=\\"default_search\\" placeholder=\\"Default search\\"/>
@@ -200,130 +311,230 @@ exports[`misc other complex template 1`] = `
<input class=\\"form-check-input\\" type=\\"checkbox\\" name=\\"display_dev\\"/>
<label class=\\"form-check-label\\" for=\\"display_dev\\">Display dev</label>
</div>
</div--><div class=\\"form-group col-md-6\\"><h5>Triggers</h5><block-child-3/></div></div></div><div class=\\"container-fluid frontend\\"><div class=\\"row\\"><div class=\\"col-md-12\\"><block-child-4/></div><div class=\\"col-md-12\\"><block-child-5/><block-child-6/><block-child-7/></div></div></div></div>\`);
let block3 = createBlock(\`<li class=\\"nav-item\\"><a class=\\"nav-link\\" href=\\"#\\" block-handler-0=\\"click\\"><block-text-1/></a></li>\`);
let block5 = createBlock(\`<li class=\\"nav-item dropdown\\"><b><a class=\\"nav-link\\" block-attribute-0=\\"href\\">Login</a></b></li>\`);
let block8 = createBlock(\`<li class=\\"nav-item\\"><a href=\\"/runbot/errors\\" class=\\"nav-link text-danger\\" block-attribute-0=\\"title\\"><i class=\\"fa fa-bug\\"/><block-text-1/></a></li>\`);
let block9 = createBlock(\`<li class=\\"nav-item divider\\"/>\`);
let block11 = createBlock(\`<li class=\\"nav-item\\"><a href=\\"/runbot/errors\\" class=\\"nav-link\\" title=\\"Random Bugs\\"><i class=\\"fa fa-bug\\"/></a></li>\`);
let block12 = createBlock(\`<li class=\\"nav-item divider\\"/>\`);
let block13 = createBlock(\`<li class=\\"nav-item dropdown\\"><a href=\\"#\\" class=\\"nav-link dropdown-toggle\\" data-toggle=\\"dropdown\\"><b><span><block-text-0/></span></b></a><div class=\\"dropdown-menu js_usermenu\\" role=\\"menu\\"><a class=\\"dropdown-item\\" id=\\"o_logout\\" role=\\"menuitem\\" block-attribute-1=\\"href\\">Logout</a><a class=\\"dropdown-item\\" role=\\"menuitem\\" block-attribute-2=\\"href\\">Web</a></div></li>\`);
let block14 = createBlock(\`<select class=\\"custom-select\\" name=\\"category\\" id=\\"category\\"><block-child-0/></select>\`);
let block16 = createBlock(\`<option block-attribute-0=\\"value\\" block-attribute-1=\\"selected\\"><block-text-2/></option>\`);
let block20 = createBlock(\`<div class=\\"form-check\\"><input class=\\"form-check-input\\" type=\\"checkbox\\" block-attribute-0=\\"name\\" block-attribute-1=\\"id\\" block-attribute-2=\\"checked\\" block-attribute-3=\\"data-trigger_id\\" block-handler-4=\\"change\\"/><label class=\\"form-check-label\\" block-attribute-5=\\"for\\"><block-text-6/></label></div>\`);
let block21 = createBlock(\`<div><button class=\\"btn btn-sm btn-default\\" block-handler-0=\\"click\\">All</button><button class=\\"btn btn-sm btn-default\\" block-handler-1=\\"click\\">None</button><button class=\\"btn btn-sm btn-info\\" block-handler-2=\\"click\\">Default</button><button class=\\"btn btn-sm btn-default\\" block-handler-3=\\"click\\">Close</button></div>\`);
let block23 = createBlock(\`<div class=\\"alert alert-warning\\" role=\\"alert\\"><block-text-0/> <!-- todo fixme--></div>\`);
let block24 = createBlock(\`<div class=\\"mb32\\"><h1>No project</h1></div>\`);
let block25 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
</div-->
<div class=\\"form-group col-md-6\\">
<h5>Triggers</h5>
<block-child-3/>
</div>
</div>
</div>
<div class=\\"container-fluid frontend\\">
<div class=\\"row\\">
<div class=\\"col-md-12\\">
<block-child-4/>
</div>
<div class=\\"col-md-12\\">
<block-child-5/>
<block-child-6/><block-child-7/>
</div>
</div>
</div>
</div>\`);
let block5 = createBlock(\`<li class=\\"nav-item\\">
<a class=\\"nav-link\\" href=\\"#\\" block-handler-0=\\"click\\">
<block-text-1/>
</a>
</li>\`);
let block10 = createBlock(\`<li class=\\"nav-item dropdown\\">
<b>
<a class=\\"nav-link\\" block-attribute-0=\\"href\\">Login</a>
</b>
</li>\`);
let block16 = createBlock(\`<li class=\\"nav-item\\">
<a href=\\"/runbot/errors\\" class=\\"nav-link text-danger\\" block-attribute-0=\\"title\\">
<i class=\\"fa fa-bug\\"/><block-text-1/>
</a>
</li>\`);
let block18 = createBlock(\`<li class=\\"nav-item divider\\"/>\`);
let block22 = createBlock(\`<li class=\\"nav-item\\">
<a href=\\"/runbot/errors\\" class=\\"nav-link\\" title=\\"Random Bugs\\"><i class=\\"fa fa-bug\\"/></a>
</li>\`);
let block24 = createBlock(\`<li class=\\"nav-item divider\\"/>\`);
let block27 = createBlock(\`<li class=\\"nav-item dropdown\\">
<a href=\\"#\\" class=\\"nav-link dropdown-toggle\\" data-toggle=\\"dropdown\\">
<b>
<span><block-text-0/></span>
</b>
</a>
<div class=\\"dropdown-menu js_usermenu\\" role=\\"menu\\">
<a class=\\"dropdown-item\\" id=\\"o_logout\\" role=\\"menuitem\\" block-attribute-1=\\"href\\">Logout</a>
<a class=\\"dropdown-item\\" role=\\"menuitem\\" block-attribute-2=\\"href\\">Web</a>
</div>
</li>\`);
let block30 = createBlock(\`<select class=\\"custom-select\\" name=\\"category\\" id=\\"category\\">
<block-child-0/>
</select>\`);
let block32 = createBlock(\`<option block-attribute-0=\\"value\\" block-attribute-1=\\"selected\\"><block-text-2/></option>\`);
let block38 = createBlock(\`<div class=\\"form-check\\">
<input class=\\"form-check-input\\" type=\\"checkbox\\" block-attribute-0=\\"name\\" block-attribute-1=\\"id\\" block-attribute-2=\\"checked\\" block-attribute-3=\\"data-trigger_id\\" block-handler-4=\\"change\\"/>
<label class=\\"form-check-label\\" block-attribute-5=\\"for\\"><block-text-6/></label>
</div>\`);
let block41 = createBlock(\`<div>
<button class=\\"btn btn-sm btn-default\\" block-handler-0=\\"click\\">All</button>
<button class=\\"btn btn-sm btn-default\\" block-handler-1=\\"click\\">None</button>
<button class=\\"btn btn-sm btn-info\\" block-handler-2=\\"click\\">Default</button>
<button class=\\"btn btn-sm btn-default\\" block-handler-3=\\"click\\">Close</button>
</div>\`);
let block44 = createBlock(\`<div class=\\"alert alert-warning\\" role=\\"alert\\">
<block-text-0/> <!-- todo fixme-->
</div>\`);
let block45 = createBlock(\`<div class=\\"mb32\\">
<h1>No project</h1>
</div>\`);
let block46 = createBlock(\`<div>
<block-child-0/>
<block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`search_input\`] = el;
const ref2 = (el) => refs[\`settings_menu\`] = el;
let b2,b4,b14,b17,b22,b23,b24,b25;
const b2 = text(\`
\`);
let b4,b6,b30,b33,b43,b44,b45,b46;
let attr1 = \`/runbot/\${ctx['project'].slug}\`;
let txt1 = ctx['project'].name;
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['projects']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`project\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['projects']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`project\`] = v_block4[i1];
const key1 = ctx['project'].id;
let hdlr1 = [ctx['selectProject'](ctx['project']), ctx];
let txt2 = ctx['project'].name;
c_block2[i1] = withKey(block3([hdlr1, txt2]), key1);
c_block4[i1] = withKey(block5([hdlr1, txt2]), key1);
}
ctx = ctx.__proto__;
b2 = list(c_block2);
b4 = list(c_block4);
if (ctx['user']) {
let b5,b6;
let b7,b8,b12,b29;
b7 = text(\`
\`);
if (ctx['user'].public) {
const b9 = text(\`
\`);
let attr2 = \`/web/login?redirect=/\`;
b5 = block5([attr2]);
const b10 = block10([attr2]);
const b11 = text(\`
\`);
b8 = multi([b9, b10, b11]);
} else {
let b7,b10,b13;
let b13,b14,b20,b26,b27,b28;
b13 = text(\`
\`);
if (ctx['nb_assigned_errors']&&ctx['nb_assigned_errors']>0) {
const b15 = text(\`
\`);
let attr3 = \`You have \${ctx['nb_assigned_errors']} random bug assigned\`;
let txt3 = ctx['nb_assigned_errors'];
const b8 = block8([attr3, txt3]);
const b9 = block9();
b7 = multi([b8, b9]);
const b16 = block16([attr3, txt3]);
const b17 = text(\`
\`);
const b18 = block18();
const b19 = text(\`
\`);
b14 = multi([b15, b16, b17, b18, b19]);
} else if (ctx['nb_build_errors']&&ctx['nb_build_errors']>0) {
const b11 = block11();
const b12 = block12();
b10 = multi([b11, b12]);
const b21 = text(\`
\`);
const b22 = block22();
const b23 = text(\`
\`);
const b24 = block24();
const b25 = text(\`
\`);
b20 = multi([b21, b22, b23, b24, b25]);
}
b26 = text(\`
\`);
let txt4 = ctx['user'].name.length>25?ctx['user'].namesubstring(0,23)+'...':ctx['user'].name;
let attr4 = \`/web/session/logout?redirect=/\`;
let attr5 = \`/web\`;
b13 = block13([txt4, attr4, attr5]);
b6 = multi([b7, b10, b13]);
b27 = block27([txt4, attr4, attr5]);
b28 = text(\`
\`);
b12 = multi([b13, b14, b20, b26, b27, b28]);
}
b4 = multi([b5, b6]);
b29 = text(\`
\`);
b6 = multi([b7, b8, b12, b29]);
}
let hdlr2 = [ctx['toggleSettingsMenu'], ctx];
let hdlr3 = [ctx['toggleMore'], ctx];
if (ctx['categories']&&ctx['categories'].length>1) {
ctx = Object.create(ctx);
const [k_block15, v_block15, l_block15, c_block15] = prepareList(ctx['categories']);;
for (let i1 = 0; i1 < l_block15; i1++) {
ctx[\`category\`] = v_block15[i1];
const [k_block31, v_block31, l_block31, c_block31] = prepareList(ctx['categories']);;
for (let i1 = 0; i1 < l_block31; i1++) {
ctx[\`category\`] = v_block31[i1];
const key1 = ctx['category'].id;
let attr6 = ctx['category'].id;
let attr7 = new Boolean(ctx['category'].id==ctx['options'].active_category_id);
let attr7 = ctx['category'].id==ctx['options'].active_category_id;
let txt5 = ctx['category'].name;
c_block15[i1] = withKey(block16([attr6, attr7, txt5]), key1);
c_block31[i1] = withKey(block32([attr6, attr7, txt5]), key1);
}
ctx = ctx.__proto__;
const b15 = list(c_block15);
b14 = block14([], [b15]);
const b31 = list(c_block31);
b30 = block30([], [b31]);
}
let attr8 = new String((ctx['search'].value) || \\"\\");
let attr8 = ctx['search'].value;
let hdlr4 = [ctx['updateFilter'], ctx];
let hdlr5 = [ctx['updateFilter'], ctx];
let hdlr6 = [ctx['clearSearch'], ctx];
if (ctx['triggers']) {
const b34 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block18, v_block18, l_block18, c_block18] = prepareList(ctx['triggers']);;
for (let i1 = 0; i1 < l_block18; i1++) {
ctx[\`trigger\`] = v_block18[i1];
const [k_block35, v_block35, l_block35, c_block35] = prepareList(ctx['triggers']);;
for (let i1 = 0; i1 < l_block35; i1++) {
ctx[\`trigger\`] = v_block35[i1];
const key1 = ctx['trigger'].id;
let b20;
let b37,b38,b39;
b37 = text(\`
\`);
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 attr10 = \`trigger_\${ctx['trigger'].id}\`;
let attr11 = new Boolean(ctx['options'].trigger_display[ctx['trigger'].id]);
let attr11 = ctx['options'].trigger_display[ctx['trigger'].id];
let attr12 = ctx['trigger'].id;
let hdlr7 = [ctx['updateTriggerDisplay'], ctx];
let attr13 = \`trigger_\${ctx['trigger'].id}\`;
let txt6 = ctx['trigger'].name;
b20 = block20([attr9, attr10, attr11, attr12, hdlr7, attr13, txt6]);
b38 = block38([attr9, attr10, attr11, attr12, hdlr7, attr13, txt6]);
}
c_block18[i1] = withKey(multi([b20]), key1);
b39 = text(\`
\`);
c_block35[i1] = withKey(multi([b37, b38, b39]), key1);
}
ctx = ctx.__proto__;
const b18 = list(c_block18);
const b35 = list(c_block35);
const b40 = text(\`
\`);
let hdlr8 = [ctx['triggerAll'], ctx];
let hdlr9 = [ctx['triggerNone'], ctx];
let hdlr10 = [ctx['triggerDefault'], ctx];
let hdlr11 = [ctx['toggleSettingsMenu'], ctx];
const b21 = block21([hdlr8, hdlr9, hdlr10, hdlr11]);
b17 = multi([b18, b21]);
const b41 = block41([hdlr8, hdlr9, hdlr10, hdlr11]);
const b42 = text(\`
\`);
b33 = multi([b34, b35, b40, b41, b42]);
}
if (ctx['load_infos']) {
b22 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
b43 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
}
if (ctx['message']) {
let txt7 = ctx['message'];
b23 = block23([txt7]);
b44 = block44([txt7]);
}
if (!ctx['project']) {
b24 = block24();
b45 = block45();
} else {
const b26 = comp1({bundles: ctx['bundles'].sticky,category_custom_views: ctx['category_custom_views'],search: ctx['search']}, key + \`__2\`, node, this, null);
const b27 = comp2({bundles: ctx['bundles'].dev,search: ctx['search']}, key + \`__3\`, node, this, null);
b25 = block25([], [b26, b27]);
const b47 = comp1({bundles: ctx['bundles'].sticky,category_custom_views: ctx['category_custom_views'],search: ctx['search']}, key + \`__2\`, node, this, null);
const b48 = comp2({bundles: ctx['bundles'].dev,search: ctx['search']}, key + \`__3\`, node, this, null);
b46 = block46([], [b47, b48]);
}
return block1([attr1, txt1, hdlr2, hdlr3, attr8, hdlr4, hdlr5, ref1, hdlr6, ref2], [b2, b4, b14, b17, b22, b23, b24, b25]);
const b3 = block3([attr1, txt1, hdlr2, hdlr3, attr8, hdlr4, hdlr5, ref1, hdlr6, ref2], [b4, b6, b30, b33, b43, b44, b45, b46]);
return multi([b2, b3]);
}
}"
`;
@@ -313,13 +313,22 @@ exports[`simple templates, mostly static template with multiple t tag with multi
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/><block-text-1/>Loading<block-text-2/></div>\`);
let block3 = createBlock(\`<div>
<block-text-0/>
<block-text-1/>
Loading<block-text-2/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['a'];
let txt2 = ctx['b'];
let txt3 = ctx['c'];
return block1([txt1, txt2, txt3]);
const b3 = block3([txt1, txt2, txt3]);
return multi([b2, b3]);
}
}"
`;
+30 -11
View File
@@ -57,17 +57,27 @@ exports[`properly support svg svg creates new block if it is within html -- 2 1`
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
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)\\"/><block-child-0/></svg>\`);
let block3 = createBlock(\`<path block-ns=\\"http://www.w3.org/2000/svg\\"/>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block4 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\">
<polygon fill=\\"#000000\\" points=\\"0 0 4 4 8 0\\" transform=\\"translate(5 7)\\"/>
<block-child-0/>
</svg>\`);
let block5 = createBlock(\`<path block-ns=\\"http://www.w3.org/2000/svg\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let b3;
const b2 = text(\`
\`);
let b5;
if (ctx['hasPath']) {
b3 = block3();
b5 = block5();
}
const b2 = block2([], [b3]);
return block1([], [b2]);
const b4 = block4([], [b5]);
const b3 = block3([], [b4]);
const b6 = text(\`
\`);
return multi([b2, b3, b6]);
}
}"
`;
@@ -77,12 +87,21 @@ exports[`properly support svg svg creates new block if it is within html 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
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 block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block4 = 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 = \\"\\") {
const b2 = block2();
return block1([], [b2]);
const b2 = text(\`
\`);
const b4 = block4();
const b3 = block3([], [b4]);
const b5 = text(\`
\`);
return multi([b2, b3, b5]);
}
}"
`;
File diff suppressed because it is too large Load Diff
@@ -55,7 +55,10 @@ exports[`debugging t-log 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div/>\`);
let block1 = createBlock(\`<div>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
+24 -13
View File
@@ -5,15 +5,24 @@ exports[`t-esc div with falsy values 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><p><block-text-0/></p><p><block-text-1/></p><p><block-text-2/></p><p><block-text-3/></p><p><block-text-4/></p></div>\`);
let block3 = createBlock(\`<div>
<p><block-text-0/></p>
<p><block-text-1/></p>
<p><block-text-2/></p>
<p><block-text-3/></p>
<p><block-text-4/></p>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['v1'];
let txt2 = ctx['v2'];
let txt3 = ctx['v3'];
let txt4 = ctx['v4'];
let txt5 = ctx['v5'];
return block1([txt1, txt2, txt3, txt4, txt5]);
const b3 = block3([txt1, txt2, txt3, txt4, txt5]);
return multi([b2, b3]);
}
}"
`;
@@ -82,16 +91,18 @@ exports[`t-esc falsy values in text nodes 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
const b2 = text(ctx['v1']);
const b3 = text(\`:\`);
const b4 = text(ctx['v2']);
const b5 = text(\`:\`);
const b6 = text(ctx['v3']);
const b7 = text(\`:\`);
const b8 = text(ctx['v4']);
const b9 = text(\`:\`);
const b10 = text(ctx['v5']);
return multi([b2, b3, b4, b5, b6, b7, b8, b9, b10]);
const b2 = text(\`
\`);
const b3 = text(ctx['v1']);
const b4 = text(\`:\`);
const b5 = text(ctx['v2']);
const b6 = text(\`:\`);
const b7 = text(ctx['v3']);
const b8 = text(\`:\`);
const b9 = text(ctx['v4']);
const b10 = text(\`:\`);
const b11 = text(ctx['v5']);
return multi([b2, b3, b4, b5, b6, b7, b8, b9, b10, b11]);
}
}"
`;
@@ -126,7 +137,7 @@ exports[`t-esc t-esc is escaped 1`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`var\`] = new LazyValue(value1, ctx, this, node, key);
ctx[\`var\`] = new LazyValue(value1, ctx, this, node);
let txt1 = ctx['var'];
return block1([txt1]);
}
@@ -6,18 +6,24 @@ exports[`t-foreach does not pollute the rendering context 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList([1]);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList([1]);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`item\`] = v_block4[i1];
const key1 = ctx['item'];
c_block2[i1] = withKey(text(ctx['item']), key1);
c_block4[i1] = withKey(text(ctx['item']), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -28,20 +34,26 @@ exports[`t-foreach iterate on items (on a element node) 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<span><block-text-0/></span>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block5 = createBlock(\`<span><block-text-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList([1,2]);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList([1,2]);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`item\`] = v_block4[i1];
const key1 = ctx['item'];
let txt1 = ctx['item'];
c_block2[i1] = withKey(block3([txt1]), key1);
c_block4[i1] = withKey(block5([txt1]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -52,27 +64,35 @@ exports[`t-foreach iterate on items 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList([3,2,1]);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList([3,2,1]);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`item\`] = v_block4[i1];
ctx[\`item_index\`] = i1;
ctx[\`item_value\`] = k_block2[i1];
ctx[\`item_value\`] = k_block4[i1];
const key1 = ctx['item'];
const b4 = text(\` [\`);
const b5 = text(ctx['item_index']);
const b6 = text(\`: \`);
const b7 = text(ctx['item']);
const b8 = text(\` \`);
const b9 = text(ctx['item_value']);
const b10 = text(\`] \`);
c_block2[i1] = withKey(multi([b4, b5, b6, b7, b8, b9, b10]), key1);
const b6 = text(\`
[\`);
const b7 = text(ctx['item_index']);
const b8 = text(\`: \`);
const b9 = text(ctx['item']);
const b10 = text(\` \`);
const b11 = text(ctx['item_value']);
const b12 = text(\`]
\`);
c_block4[i1] = withKey(multi([b6, b7, b8, b9, b10, b11, b12]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -83,27 +103,35 @@ exports[`t-foreach iterate, dict param 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['value']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['value']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`item\`] = v_block4[i1];
ctx[\`item_index\`] = i1;
ctx[\`item_value\`] = k_block2[i1];
ctx[\`item_value\`] = k_block4[i1];
const key1 = ctx['item_index'];
const b4 = text(\` [\`);
const b5 = text(ctx['item_index']);
const b6 = text(\`: \`);
const b7 = text(ctx['item']);
const b8 = text(\` \`);
const b9 = text(ctx['item_value']);
const b10 = text(\`] \`);
c_block2[i1] = withKey(multi([b4, b5, b6, b7, b8, b9, b10]), key1);
const b6 = text(\`
[\`);
const b7 = text(ctx['item_index']);
const b8 = text(\`: \`);
const b9 = text(ctx['item']);
const b10 = text(\` \`);
const b11 = text(ctx['item_value']);
const b12 = text(\`]
\`);
c_block4[i1] = withKey(multi([b6, b7, b8, b9, b10, b11, b12]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -114,32 +142,40 @@ exports[`t-foreach iterate, position 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(Array(5));;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`elem\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(Array(5));;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`elem\`] = v_block4[i1];
ctx[\`elem_first\`] = i1 === 0;
ctx[\`elem_last\`] = i1 === v_block2.length - 1;
ctx[\`elem_last\`] = i1 === v_block4.length - 1;
ctx[\`elem_index\`] = i1;
const key1 = ctx['elem'];
let b4,b5,b6,b7,b8,b9;
b4 = text(\` -\`);
let b6,b7,b8,b9,b10,b11;
b6 = text(\`
-\`);
if (ctx['elem_first']) {
b5 = text(\` first\`);
b7 = text(\` first\`);
}
if (ctx['elem_last']) {
b6 = text(\` last\`);
b8 = text(\` last\`);
}
b7 = text(\` (\`);
b8 = text(ctx['elem_index']);
b9 = text(\`) \`);
c_block2[i1] = withKey(multi([b4, b5, b6, b7, b8, b9]), key1);
b9 = text(\` (\`);
b10 = text(ctx['elem_index']);
b11 = text(\`)
\`);
c_block4[i1] = withKey(multi([b6, b7, b8, b9, b10, b11]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -150,18 +186,24 @@ exports[`t-foreach simple iteration (in a node) 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList([3,2,1]);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList([3,2,1]);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`item\`] = v_block4[i1];
const key1 = ctx['item'];
c_block2[i1] = withKey(text(ctx['item']), key1);
c_block4[i1] = withKey(text(ctx['item']), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -191,22 +233,31 @@ exports[`t-foreach simple iteration with two nodes inside 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block3 = createBlock(\`<span>a<block-text-0/></span>\`);
let block4 = createBlock(\`<span>b<block-text-0/></span>\`);
let block6 = createBlock(\`<span>a<block-text-0/></span>\`);
let block8 = createBlock(\`<span>b<block-text-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList([3,2,1]);;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`item\`] = v_block1[i1];
const [k_block3, v_block3, l_block3, c_block3] = prepareList([3,2,1]);;
for (let i1 = 0; i1 < l_block3; i1++) {
ctx[\`item\`] = v_block3[i1];
const key1 = ctx['item'];
const b5 = text(\`
\`);
let txt1 = ctx['item'];
const b3 = block3([txt1]);
const b6 = block6([txt1]);
const b7 = text(\`
\`);
let txt2 = ctx['item'];
const b4 = block4([txt2]);
c_block1[i1] = withKey(multi([b3, b4]), key1);
const b8 = block8([txt2]);
const b9 = text(\`
\`);
c_block3[i1] = withKey(multi([b5, b6, b7, b8, b9]), key1);
}
return list(c_block1);
const b3 = list(c_block3);
return multi([b2, b3]);
}
}"
`;
@@ -215,51 +266,74 @@ exports[`t-foreach t-call with body in t-foreach in t-foreach 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, isBoundary, withDefault, setContextValue, withKey } = helpers;
let { prepareList, isBoundary, withDefault, setContextValue, zero, withKey } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/><span>[<block-text-0/>][<block-text-1/>][<block-text-2/>]</span></div>\`);
let block6 = createBlock(\`<span><block-text-0/></span>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<span>[<block-text-0/>][<block-text-1/>][<block-text-2/>]</span>
</div>\`);
let block16 = createBlock(\`<span><block-text-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['numbers']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`a\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['numbers']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`a\`] = v_block4[i1];
ctx[\`a_first\`] = i1 === 0;
ctx[\`a_last\`] = i1 === v_block2.length - 1;
ctx[\`a_last\`] = i1 === v_block4.length - 1;
ctx[\`a_index\`] = i1;
ctx[\`a_value\`] = k_block2[i1];
ctx[\`a_value\`] = k_block4[i1];
const key1 = ctx['a'];
const b6 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['letters']);;
for (let i2 = 0; i2 < l_block4; i2++) {
ctx[\`b\`] = v_block4[i2];
const [k_block7, v_block7, l_block7, c_block7] = prepareList(ctx['letters']);;
for (let i2 = 0; i2 < l_block7; i2++) {
ctx[\`b\`] = v_block7[i2];
ctx[\`b_first\`] = i2 === 0;
ctx[\`b_last\`] = i2 === v_block4.length - 1;
ctx[\`b_last\`] = i2 === v_block7.length - 1;
ctx[\`b_index\`] = i2;
ctx[\`b_value\`] = k_block4[i2];
ctx[\`b_value\`] = k_block7[i2];
const key2 = ctx['b'];
const b9 = text(\`
\`);
ctx = Object.create(ctx);
ctx[isBoundary] = 1;
const b11 = text(\`
\`);
setContextValue(ctx, \\"c\\", 'x'+'_'+ctx['a']+'_'+ctx['b']);
c_block4[i2] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}__\${key2}\`), key2);
const b12 = text(\`
\`);
const b10 = multi([b11, b12]);
ctx[zero] = b10;
const b13 = callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}__\${key2}\`);
ctx = ctx.__proto__;
const b14 = text(\`
\`);
c_block7[i2] = withKey(multi([b9, b13, b14]), key2);
}
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b7 = list(c_block7);
const b15 = text(\`
\`);
let txt1 = ctx['c'];
const b6 = block6([txt1]);
c_block2[i1] = withKey(multi([b4, b6]), key1);
const b16 = block16([txt1]);
const b17 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b15, b16, b17]), key1);
}
ctx = ctx.__proto__;
const b2 = list(c_block2);
const b4 = list(c_block4);
let txt2 = ctx['a'];
let txt3 = ctx['b'];
let txt4 = ctx['c'];
return block1([txt2, txt3, txt4], [b2]);
const b3 = block3([txt2, txt3, txt4], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -270,14 +344,20 @@ exports[`t-foreach t-call with body in t-foreach in t-foreach 2`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
const b2 = text(\` [\`);
const b3 = text(ctx['a']);
const b4 = text(\`] [\`);
const b5 = text(ctx['b']);
const b6 = text(\`] [\`);
const b7 = text(ctx['c']);
const b8 = text(\`] \`);
return multi([b2, b3, b4, b5, b6, b7, b8]);
const b2 = text(\`
\`);
const b3 = text(\`
[\`);
const b4 = text(ctx['a']);
const b5 = text(\`]
[\`);
const b6 = text(ctx['b']);
const b7 = text(\`]
[\`);
const b8 = text(ctx['c']);
const b9 = text(\`]
\`);
return multi([b2, b3, b4, b5, b6, b7, b8, b9]);
}
}"
`;
@@ -289,42 +369,59 @@ exports[`t-foreach t-call without body in t-foreach in t-foreach 1`] = `
let { prepareList, withKey } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/><span>[<block-text-0/>][<block-text-1/>][<block-text-2/>]</span></div>\`);
let block6 = createBlock(\`<span><block-text-0/></span>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<span>[<block-text-0/>][<block-text-1/>][<block-text-2/>]</span>
</div>\`);
let block13 = createBlock(\`<span><block-text-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['numbers']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`a\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['numbers']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`a\`] = v_block4[i1];
ctx[\`a_first\`] = i1 === 0;
ctx[\`a_last\`] = i1 === v_block2.length - 1;
ctx[\`a_last\`] = i1 === v_block4.length - 1;
ctx[\`a_index\`] = i1;
ctx[\`a_value\`] = k_block2[i1];
ctx[\`a_value\`] = k_block4[i1];
const key1 = ctx['a'];
const b6 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['letters']);;
for (let i2 = 0; i2 < l_block4; i2++) {
ctx[\`b\`] = v_block4[i2];
const [k_block7, v_block7, l_block7, c_block7] = prepareList(ctx['letters']);;
for (let i2 = 0; i2 < l_block7; i2++) {
ctx[\`b\`] = v_block7[i2];
ctx[\`b_first\`] = i2 === 0;
ctx[\`b_last\`] = i2 === v_block4.length - 1;
ctx[\`b_last\`] = i2 === v_block7.length - 1;
ctx[\`b_index\`] = i2;
ctx[\`b_value\`] = k_block4[i2];
ctx[\`b_value\`] = k_block7[i2];
const key2 = ctx['b'];
c_block4[i2] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}__\${key2}\`), key2);
const b9 = text(\`
\`);
const b10 = callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}__\${key2}\`);
const b11 = text(\`
\`);
c_block7[i2] = withKey(multi([b9, b10, b11]), key2);
}
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b7 = list(c_block7);
const b12 = text(\`
\`);
let txt1 = ctx['c'];
const b6 = block6([txt1]);
c_block2[i1] = withKey(multi([b4, b6]), key1);
const b13 = block13([txt1]);
const b14 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b12, b13, b14]), key1);
}
ctx = ctx.__proto__;
const b2 = list(c_block2);
const b4 = list(c_block4);
let txt2 = ctx['a'];
let txt3 = ctx['b'];
let txt4 = ctx['c'];
return block1([txt2, txt3, txt4], [b2]);
const b3 = block3([txt2, txt3, txt4], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -338,15 +435,23 @@ exports[`t-foreach t-call without body in t-foreach in t-foreach 2`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
const b3 = text(\`
\`);
setContextValue(ctx, \\"c\\", 'x'+'_'+ctx['a']+'_'+ctx['b']);
const b2 = text(\` [\`);
const b3 = text(ctx['a']);
const b4 = text(\`] [\`);
const b5 = text(ctx['b']);
const b6 = text(\`] [\`);
const b7 = text(ctx['c']);
const b8 = text(\`] \`);
return multi([b2, b3, b4, b5, b6, b7, b8]);
const b4 = text(\`
[\`);
const b5 = text(ctx['a']);
const b6 = text(\`]
[\`);
const b7 = text(ctx['b']);
const b8 = text(\`]
[\`);
const b9 = text(ctx['c']);
const b10 = text(\`]
\`);
return multi([b2, b3, b4, b5, b6, b7, b8, b9, b10]);
}
}"
`;
@@ -357,30 +462,43 @@ exports[`t-foreach t-foreach in t-foreach 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['numbers']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`number\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['numbers']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`number\`] = v_block4[i1];
const key1 = ctx['number'];
const b6 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block3, v_block3, l_block3, c_block3] = prepareList(ctx['letters']);;
for (let i2 = 0; i2 < l_block3; i2++) {
ctx[\`letter\`] = v_block3[i2];
const [k_block7, v_block7, l_block7, c_block7] = prepareList(ctx['letters']);;
for (let i2 = 0; i2 < l_block7; i2++) {
ctx[\`letter\`] = v_block7[i2];
const key2 = ctx['letter'];
const b5 = text(\` [\`);
const b6 = text(ctx['number']);
const b7 = text(ctx['letter']);
const b8 = text(\`] \`);
c_block3[i2] = withKey(multi([b5, b6, b7, b8]), key2);
const b9 = text(\`
[\`);
const b10 = text(ctx['number']);
const b11 = text(ctx['letter']);
const b12 = text(\`]
\`);
c_block7[i2] = withKey(multi([b9, b10, b11, b12]), key2);
}
ctx = ctx.__proto__;
c_block2[i1] = withKey(list(c_block3), key1);
const b7 = list(c_block7);
const b13 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b13]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -391,22 +509,29 @@ exports[`t-foreach t-foreach with t-if inside (no external node) 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block3 = createBlock(\`<span><block-text-0/></span>\`);
let block6 = createBlock(\`<span><block-text-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['elems']);;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`elem\`] = v_block1[i1];
const [k_block3, v_block3, l_block3, c_block3] = prepareList(ctx['elems']);;
for (let i1 = 0; i1 < l_block3; i1++) {
ctx[\`elem\`] = v_block3[i1];
const key1 = ctx['elem'].id;
let b3;
let b5,b6,b7;
b5 = text(\`
\`);
if (ctx['elem'].id<3) {
let txt1 = ctx['elem'].text;
b3 = block3([txt1]);
b6 = block6([txt1]);
}
c_block1[i1] = withKey(multi([b3]), key1);
b7 = text(\`
\`);
c_block3[i1] = withKey(multi([b5, b6, b7]), key1);
}
return list(c_block1);
const b3 = list(c_block3);
return multi([b2, b3]);
}
}"
`;
@@ -417,24 +542,34 @@ exports[`t-foreach t-foreach with t-if inside 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block4 = createBlock(\`<span><block-text-0/></span>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block7 = createBlock(\`<span><block-text-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['elems']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`elem\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['elems']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`elem\`] = v_block4[i1];
const key1 = ctx['elem'].id;
let b4;
let b6,b7,b8;
b6 = text(\`
\`);
if (ctx['elem'].id<3) {
let txt1 = ctx['elem'].text;
b4 = block4([txt1]);
b7 = block7([txt1]);
}
c_block2[i1] = withKey(multi([b4]), key1);
b8 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -445,19 +580,30 @@ exports[`t-foreach t-key on t-foreach 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<span/>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block7 = createBlock(\`<span/>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['things']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`thing\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['things']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`thing\`] = v_block4[i1];
const key1 = ctx['thing'];
c_block2[i1] = withKey(block3(), key1);
const b6 = text(\`
\`);
const b7 = block7();
const b8 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -493,33 +639,42 @@ exports[`t-foreach with t-memo 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<p><block-text-0/><block-text-1/></p>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block5 = createBlock(\`<p>
<block-text-0/>
<block-text-1/>
</p>\`);
return function template(ctx, node, key = \\"\\") {
let cache = ctx.cache || {};
let nextCache = ctx.cache = {};
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`item\`] = v_block4[i1];
const key1 = ctx['item'].id;
const memo1 = [ctx['item'].x];
const vnode1 = cache[key1];;
if (vnode1) {
if (shallowEqual(vnode1.memo, memo1)) {
c_block2[i1] = vnode1;
c_block4[i1] = vnode1;
nextCache[key1] = vnode1;
continue;
}
}
let txt1 = ctx['item'].x;
let txt2 = ctx['item'].y;
c_block2[i1] = withKey(block3([txt1, txt2]), key1);
nextCache[key1] = Object.assign(c_block2[i1], {memo: memo1});
c_block4[i1] = withKey(block5([txt1, txt2]), key1);
nextCache[key1] = Object.assign(c_block4[i1], {memo: memo1});
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
+102 -53
View File
@@ -44,17 +44,19 @@ exports[`t-if boolean value condition elif (no outside node) 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
let b2,b3,b4,b5;
let b2,b3,b4,b5,b6;
b2 = text(\`
\`);
if (ctx['color']=='black') {
b2 = text(\`black pearl\`);
b3 = text(\`black pearl\`);
} else if (ctx['color']=='yellow') {
b3 = text(\`yellow submarine\`);
b4 = text(\`yellow submarine\`);
} else if (ctx['color']=='red') {
b4 = text(\`red is dead\`);
b5 = text(\`red is dead\`);
} else {
b5 = text(\`beer\`);
b6 = text(\`beer\`);
}
return multi([b2, b3, b4, b5]);
return multi([b2, b3, b4, b5, b6]);
}
}"
`;
@@ -64,20 +66,25 @@ exports[`t-if boolean value condition elif 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-2/><block-child-3/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/><block-child-2/><block-child-3/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3,b4,b5;
const b2 = text(\`
\`);
let b4,b5,b6,b7;
if (ctx['color']=='black') {
b2 = text(\`black pearl\`);
b4 = text(\`black pearl\`);
} else if (ctx['color']=='yellow') {
b3 = text(\`yellow submarine\`);
b5 = text(\`yellow submarine\`);
} else if (ctx['color']=='red') {
b4 = text(\`red is dead\`);
b6 = text(\`red is dead\`);
} else {
b5 = text(\`beer\`);
b7 = text(\`beer\`);
}
return block1([], [b2, b3, b4, b5]);
const b3 = block3([], [b4, b5, b6, b7]);
return multi([b2, b3]);
}
}"
`;
@@ -87,16 +94,23 @@ exports[`t-if boolean value condition else 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><span>begin</span><block-child-0/><block-child-1/><span>end</span></div>\`);
let block3 = createBlock(\`<div>
<span>begin</span>
<block-child-0/><block-child-1/>
<span>end</span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['condition']) {
b2 = text(\`ok\`);
b4 = text(\`ok\`);
} else {
b3 = text(\`ok-else\`);
b5 = text(\`ok-else\`);
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -106,16 +120,19 @@ exports[`t-if boolean value condition false else 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><span>begin</span><block-child-0/><block-child-1/><span>end</span></div>\`);
let block3 = createBlock(\`<div><span>begin</span><block-child-0/><block-child-1/><span>end</span></div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['condition']) {
b2 = text(\`fail\`);
b4 = text(\`fail\`);
} else {
b3 = text(\`fail-else\`);
b5 = text(\`fail-else\`);
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -142,35 +159,47 @@ exports[`t-if can use some boolean operators in expressions 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-2/><block-child-3/><block-child-4/><block-child-5/><block-child-6/><block-child-7/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<block-child-1/>
<block-child-2/>
<block-child-3/>
<block-child-4/>
<block-child-5/>
<block-child-6/>
<block-child-7/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3,b4,b5,b6,b7,b8,b9;
const b2 = text(\`
\`);
let b4,b5,b6,b7,b8,b9,b10,b11;
if (ctx['cond1']&&ctx['cond2']) {
b2 = text(\`and\`);
b4 = text(\`and\`);
}
if (ctx['cond1']&&ctx['cond3']) {
b3 = text(\`nope\`);
}
if (ctx['cond1']||ctx['cond3']) {
b4 = text(\`or\`);
}
if (ctx['cond3']||ctx['cond4']) {
b5 = text(\`nope\`);
}
if (ctx['cond1']||ctx['cond3']) {
b6 = text(\`or\`);
}
if (ctx['cond3']||ctx['cond4']) {
b7 = text(\`nope\`);
}
if (ctx['m']>3) {
b6 = text(\`mgt\`);
b8 = text(\`mgt\`);
}
if (ctx['n']>3) {
b7 = text(\`ngt\`);
b9 = text(\`ngt\`);
}
if (ctx['m']<3) {
b8 = text(\`mlt\`);
b10 = text(\`mlt\`);
}
if (ctx['n']<3) {
b9 = text(\`nlt\`);
b11 = text(\`nlt\`);
}
return block1([], [b2, b3, b4, b5, b6, b7, b8, b9]);
const b3 = block3([], [b4, b5, b6, b7, b8, b9, b10, b11]);
return multi([b2, b3]);
}
}"
`;
@@ -407,17 +436,23 @@ exports[`t-if t-set, then t-if 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
let b2;
const b2 = text(\`
\`);
let b4;
setContextValue(ctx, \\"title\\", 'test');
if (ctx['title']) {
b2 = text(ctx['title']);
b4 = text(ctx['title']);
}
return block1([], [b2]);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -428,19 +463,26 @@ exports[`t-if t-set, then t-if, part 2 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<span>COUCOU</span>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block4 = createBlock(\`<span>COUCOU</span>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
let b2;
const b2 = text(\`
\`);
let b4;
setContextValue(ctx, \\"y\\", true);
setContextValue(ctx, \\"x\\", ctx['y']);
if (ctx['x']) {
b2 = block2();
b4 = block4();
}
return block1([], [b2]);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -451,22 +493,29 @@ exports[`t-if t-set, then t-if, part 3 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block2 = createBlock(\`<span>AAA</span>\`);
let block3 = createBlock(\`<span>BBB</span>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/>
</div>\`);
let block4 = createBlock(\`<span>AAA</span>\`);
let block5 = createBlock(\`<span>BBB</span>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
setContextValue(ctx, \\"y\\", false);
setContextValue(ctx, \\"x\\", ctx['y']);
if (ctx['x']) {
b2 = block2();
b4 = block4();
} else if (!ctx['x']) {
b3 = block3();
b5 = block5();
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -51,7 +51,9 @@ exports[`t-key t-key directive in a list 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<ul><block-child-0/></ul>\`);
let block1 = createBlock(\`<ul>
<block-child-0/>
</ul>\`);
let block3 = createBlock(\`<li><block-text-0/></li>\`);
return function template(ctx, node, key = \\"\\") {
@@ -63,6 +65,7 @@ exports[`t-key t-key directive in a list 1`] = `
let txt1 = ctx['beer'].name;
c_block2[i1] = withKey(block3([txt1]), key1);
}
ctx = ctx.__proto__;
const b2 = list(c_block2);
return block1([], [b2]);
}
@@ -74,18 +77,26 @@ exports[`t-key t-key on sub dom node pushes a child block in its parent 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block2 = createBlock(\`<span/>\`);
let block3 = createBlock(\`<div><h1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<block-child-1/>
</div>\`);
let block4 = createBlock(\`<span/>\`);
let block5 = createBlock(\`<div><h1/></div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['hasSpan']) {
b2 = block2();
b4 = block4();
}
const tKey_1 = ctx['key'];
b3 = toggler(tKey_1, block3());
return block1([], [b2, b3]);
b5 = toggler(tKey_1, block5());
const b3 = block3([], [b4, b5]);
const b6 = text(\`
\`);
return multi([b2, b3, b6]);
}
}"
`;
+51 -20
View File
@@ -34,16 +34,27 @@ exports[`t-out multiple calls to t-out 1`] = `
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<span>coucou</span>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block6 = createBlock(\`<span>coucou</span>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
ctx[isBoundary] = 1;
const b2 = block2();
ctx[zero] = b2;
const b3 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b3]);
const b5 = text(\`
\`);
const b6 = block6();
const b7 = text(\`
\`);
const b4 = multi([b5, b6, b7]);
ctx[zero] = b4;
const b8 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
ctx = ctx.__proto__;
const b3 = block3([], [b8]);
return multi([b2, b3]);
}
}"
`;
@@ -54,12 +65,19 @@ exports[`t-out multiple calls to t-out 2`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { zero } = helpers;
let block1 = createBlock(\`<div><block-child-0/><div>Greeter</div><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<div>Greeter</div>
<block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = ctx[zero];
const b3 = ctx[zero];
return block1([], [b2, b3]);
const b2 = text(\`
\`);
const b4 = ctx[zero];
const b5 = ctx[zero];
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -161,7 +179,7 @@ exports[`t-out t-out bdom 1`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`var\`] = new LazyValue(value1, ctx, this, node, key);
ctx[\`var\`] = new LazyValue(value1, ctx, this, node);
const b3 = safeOutput(ctx['var']);
return block1([], [b3]);
}
@@ -297,10 +315,13 @@ exports[`t-out t-out switch markup on bdom 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, LazyValue, safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block1 = createBlock(\`<div>
<block-child-0/><block-child-1/>
</div>\`);
let block2 = createBlock(\`<ol>set</ol>\`);
let block3 = createBlock(\`<span><block-child-0/></span>\`);
let block5 = createBlock(\`<span><block-child-0/></span>\`);
let block10 = createBlock(\`<span><block-child-0/></span>\`);
function value1(ctx, node, key = \\"\\") {
return block2();
@@ -309,16 +330,26 @@ exports[`t-out t-out switch markup on bdom 1`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
let b3,b5;
ctx[\`bdom\`] = new LazyValue(value1, ctx, this, node, key);
let b3,b8;
ctx[\`bdom\`] = new LazyValue(value1, ctx, this, node);
if (ctx['hasBdom']) {
const b4 = safeOutput(ctx['bdom']);
b3 = block3([], [b4]);
const b4 = text(\`
\`);
const b6 = safeOutput(ctx['bdom']);
const b5 = block5([], [b6]);
const b7 = text(\`
\`);
b3 = multi([b4, b5, b7]);
} else {
const b6 = safeOutput(ctx['var']);
b5 = block5([], [b6]);
const b9 = text(\`
\`);
const b11 = safeOutput(ctx['var']);
const b10 = block10([], [b11]);
const b12 = text(\`
\`);
b8 = multi([b9, b10, b12]);
}
return block1([], [b3, b5]);
return block1([], [b3, b8]);
}
}"
`;
+49 -20
View File
@@ -8,7 +8,7 @@ exports[`t-ref can get a dynamic ref on a node 1`] = `
let block1 = createBlock(\`<div><span block-ref=\\"0\\"/></div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const v1 = ctx['id'];
let ref1 = (el) => refs[\`myspan\${v1}\`] = el;
return block1([ref1]);
@@ -24,7 +24,7 @@ exports[`t-ref can get a dynamic ref on a node, alternate syntax 1`] = `
let block1 = createBlock(\`<div><span block-ref=\\"0\\"/></div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const v1 = ctx['id'];
let ref1 = (el) => refs[\`myspan\${v1}\`] = el;
return block1([ref1]);
@@ -40,7 +40,7 @@ exports[`t-ref can get a ref on a node 1`] = `
let block1 = createBlock(\`<div><span block-ref=\\"0\\"/></div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`myspan\`] = el;
return block1([ref1]);
}
@@ -70,7 +70,7 @@ exports[`t-ref ref in a t-call 2`] = `
let block1 = createBlock(\`<div>1<span block-ref=\\"0\\"/>2</div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`name\`] = el;
return block1([ref1]);
}
@@ -82,17 +82,27 @@ exports[`t-ref ref in a t-if 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<span block-ref=\\"0\\"/>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block6 = createBlock(\`<span block-ref=\\"0\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`name\`] = el;
let b2;
const b2 = text(\`
\`);
let b4;
if (ctx['condition']) {
b2 = block2([ref1]);
const b5 = text(\`
\`);
const b6 = block6([ref1]);
const b7 = text(\`
\`);
b4 = multi([b5, b6, b7]);
}
return block1([], [b2]);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -103,22 +113,30 @@ exports[`t-ref refs in a loop 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div block-ref=\\"0\\"><block-text-1/></div>\`);
let block1 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block5 = createBlock(\`<div block-ref=\\"0\\"><block-text-1/></div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1];
const key1 = ctx['item'];
const b4 = text(\`
\`);
const tKey_1 = ctx['item'];
const v1 = ctx['item'];
let ref1 = (el) => refs[(v1)] = el;
let txt1 = ctx['item'];
c_block2[i1] = withKey(block3([ref1, txt1]), tKey_1 + key1);
const b5 = toggler(tKey_1, block5([ref1, txt1]));
const b6 = text(\`
\`);
c_block2[i1] = withKey(multi([b4, b5, b6]), key1);
}
ctx = ctx.__proto__;
const b2 = list(c_block2);
return block1([], [b2]);
}
@@ -130,18 +148,29 @@ exports[`t-ref two refs, one in a t-if 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><p block-ref=\\"0\\"/></div>\`);
let block2 = createBlock(\`<span block-ref=\\"0\\"/>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<p block-ref=\\"0\\"/>
</div>\`);
let block6 = createBlock(\`<span block-ref=\\"0\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`name\`] = el;
const ref2 = (el) => refs[\`p\`] = el;
let b2;
const b2 = text(\`
\`);
let b4;
if (ctx['condition']) {
b2 = block2([ref1]);
const b5 = text(\`
\`);
const b6 = block6([ref1]);
const b7 = text(\`
\`);
b4 = multi([b5, b6, b7]);
}
return block1([ref2], [b2]);
const b3 = block3([ref2], [b4]);
return multi([b2, b3]);
}
}"
`;
+274 -88
View File
@@ -94,20 +94,33 @@ exports[`t-set set from body literal (with t-if/t-else 1`] = `
let { isBoundary, withDefault, LazyValue } = helpers;
function value1(ctx, node, key = \\"\\") {
let b2,b3;
let b5,b6,b7,b8;
b5 = text(\`
\`);
if (ctx['condition']) {
b2 = text(\`true\`);
b6 = text(\`true\`);
} else {
b3 = text(\`false\`);
b7 = text(\`false\`);
}
return multi([b2, b3]);
b8 = text(\`
\`);
return multi([b5, b6, b7, b8]);
}
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`value\`] = new LazyValue(value1, ctx, this, node, key);
return text(ctx['value']);
const b2 = text(\`
\`);
const b3 = text(\`
\`);
ctx[\`value\`] = new LazyValue(value1, ctx, this, node);
const b9 = text(\`
\`);
const b10 = text(ctx['value']);
const b11 = text(\`
\`);
return multi([b2, b3, b9, b10, b11]);
}
}"
`;
@@ -142,7 +155,7 @@ exports[`t-set set from body lookup 1`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`stuff\`] = new LazyValue(value1, ctx, this, node, key);
ctx[\`stuff\`] = new LazyValue(value1, ctx, this, node);
let txt1 = ctx['stuff'];
return block1([txt1]);
}
@@ -173,17 +186,23 @@ exports[`t-set t-set and t-if 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
let b2;
const b2 = text(\`
\`);
let b4;
setContextValue(ctx, \\"v\\", ctx['value']);
if (ctx['v']==='ok') {
b2 = text(\`grimbergen\`);
b4 = text(\`grimbergen\`);
}
return block1([], [b2]);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -194,22 +213,35 @@ exports[`t-set t-set body is evaluated immediately 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue, LazyValue, safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<span><block-text-0/></span>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block6 = createBlock(\`<span><block-text-0/></span>\`);
function value1(ctx, node, key = \\"\\") {
const b5 = text(\`
\`);
let txt1 = ctx['v1'];
return block2([txt1]);
const b6 = block6([txt1]);
const b7 = text(\`
\`);
return multi([b5, b6, b7]);
}
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"v1\\", 'before');
ctx[\`v2\`] = new LazyValue(value1, ctx, this, node, key);
ctx[\`v2\`] = new LazyValue(value1, ctx, this, node);
setContextValue(ctx, \\"v1\\", 'after');
const b3 = safeOutput(ctx['v2']);
return block1([], [b3]);
const b8 = safeOutput(ctx['v2']);
const b3 = block3([], [b8]);
return multi([b2, b3]);
}
}"
`;
@@ -221,16 +253,26 @@ exports[`t-set t-set can't alter from within callee 1`] = `
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let block1 = createBlock(\`<div><p><block-text-0/></p><block-child-0/><p><block-text-1/></p></div>\`);
let block3 = createBlock(\`<div>
<p><block-text-0/></p>
<block-child-0/>
<p><block-text-1/></p>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 'source');
let txt1 = ctx['iter'];
const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
const b4 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
let txt2 = ctx['iter'];
return block1([txt1, txt2], [b2]);
const b3 = block3([txt1, txt2], [b4]);
const b5 = text(\`
\`);
return multi([b2, b3, b5]);
}
}"
`;
@@ -258,23 +300,39 @@ exports[`t-set t-set can't alter in t-call body 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let { isBoundary, withDefault, setContextValue, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let block1 = createBlock(\`<div><p><block-text-0/></p><block-child-0/><p><block-text-1/></p></div>\`);
let block3 = createBlock(\`<div>
<p><block-text-0/></p>
<block-child-0/>
<p><block-text-1/></p>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 'source');
let txt1 = ctx['iter'];
ctx = Object.create(ctx);
ctx[isBoundary] = 1;
const b5 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 'inCall');
const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
const b6 = text(\`
\`);
const b4 = multi([b5, b6]);
ctx[zero] = b4;
const b7 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
ctx = ctx.__proto__;
let txt2 = ctx['iter'];
return block1([txt1, txt2], [b2]);
const b3 = block3([txt1, txt2], [b7]);
const b8 = text(\`
\`);
return multi([b2, b3, b8]);
}
}"
`;
@@ -322,15 +380,22 @@ exports[`t-set t-set evaluates an expression only once 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/><block-text-1/></div>\`);
let block3 = createBlock(\`<div>
<block-text-0/>
<block-text-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"v\\", ctx['value']+' artois');
let txt1 = ctx['v'];
let txt2 = ctx['v'];
return block1([txt1, txt2]);
const b3 = block3([txt1, txt2]);
return multi([b2, b3]);
}
}"
`;
@@ -341,26 +406,42 @@ exports[`t-set t-set outside modified in t-foreach 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue, prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/><p>EndLoop: <block-text-0/></p></div>\`);
let block3 = createBlock(\`<p>InLoop: <block-text-0/></p>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<p>EndLoop: <block-text-0/></p>
</div>\`);
let block7 = createBlock(\`<p>InLoop: <block-text-0/></p>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 0);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(['a','b']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(['a','b']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`val\`] = v_block4[i1];
const key1 = ctx['val'];
const b6 = text(\`
\`);
let txt1 = ctx['iter'];
c_block2[i1] = withKey(block3([txt1]), key1);
const b7 = block7([txt1]);
const b8 = text(\`
\`);
setContextValue(ctx, \\"iter\\", ctx['iter']+1);
const b9 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8, b9]), key1);
}
ctx = ctx.__proto__;
const b2 = list(c_block2);
const b4 = list(c_block4);
let txt2 = ctx['iter'];
return block1([txt2], [b2]);
const b3 = block3([txt2], [b4]);
const b10 = text(\`
\`);
return multi([b2, b3, b10]);
}
}"
`;
@@ -371,26 +452,42 @@ exports[`t-set t-set outside modified in t-foreach increment-after operator 1`]
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue, prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/><p>EndLoop: <block-text-0/></p></div>\`);
let block3 = createBlock(\`<p>InLoop: <block-text-0/></p>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<p>EndLoop: <block-text-0/></p>
</div>\`);
let block7 = createBlock(\`<p>InLoop: <block-text-0/></p>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 0);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(['a','b']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(['a','b']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`val\`] = v_block4[i1];
const key1 = ctx['val'];
const b6 = text(\`
\`);
let txt1 = ctx['iter'];
c_block2[i1] = withKey(block3([txt1]), key1);
const b7 = block7([txt1]);
const b8 = text(\`
\`);
setContextValue(ctx, \\"iter\\", ctx['iter']++);
const b9 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8, b9]), key1);
}
ctx = ctx.__proto__;
const b2 = list(c_block2);
const b4 = list(c_block4);
let txt2 = ctx['iter'];
return block1([txt2], [b2]);
const b3 = block3([txt2], [b4]);
const b10 = text(\`
\`);
return multi([b2, b3, b10]);
}
}"
`;
@@ -401,26 +498,42 @@ exports[`t-set t-set outside modified in t-foreach increment-before operator 1`]
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue, prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/><p>EndLoop: <block-text-0/></p></div>\`);
let block3 = createBlock(\`<p>InLoop: <block-text-0/></p>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<p>EndLoop: <block-text-0/></p>
</div>\`);
let block7 = createBlock(\`<p>InLoop: <block-text-0/></p>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 0);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(['a','b']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(['a','b']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`val\`] = v_block4[i1];
const key1 = ctx['val'];
const b6 = text(\`
\`);
let txt1 = ctx['iter'];
c_block2[i1] = withKey(block3([txt1]), key1);
const b7 = block7([txt1]);
const b8 = text(\`
\`);
setContextValue(ctx, \\"iter\\", ++ctx['iter']);
const b9 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8, b9]), key1);
}
ctx = ctx.__proto__;
const b2 = list(c_block2);
const b4 = list(c_block4);
let txt2 = ctx['iter'];
return block1([txt2], [b2]);
const b3 = block3([txt2], [b4]);
const b10 = text(\`
\`);
return multi([b2, b3, b10]);
}
}"
`;
@@ -431,25 +544,35 @@ exports[`t-set t-set should reuse variable if possible 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue, prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div><span>v<block-text-0/></span></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block5 = createBlock(\`<div>
<span>v<block-text-0/></span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"v\\", 1);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['list']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`elem\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['list']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`elem\`] = v_block4[i1];
ctx[\`elem_index\`] = i1;
const key1 = ctx['elem_index'];
let txt1 = ctx['v'];
setContextValue(ctx, \\"v\\", ctx['elem']);
c_block2[i1] = withKey(block3([txt1]), key1);
c_block4[i1] = withKey(block5([txt1]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -460,20 +583,26 @@ exports[`t-set t-set with content and sub t-esc 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, LazyValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
let block3 = createBlock(\`<div>
<block-text-0/>
</div>\`);
function value1(ctx, node, key = \\"\\") {
const b3 = text(ctx['beep']);
const b4 = text(\` boop\`);
return multi([b3, b4]);
const b5 = text(ctx['beep']);
const b6 = text(\` boop\`);
return multi([b5, b6]);
}
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`setvar\`] = new LazyValue(value1, ctx, this, node, key);
const b2 = text(\`
\`);
ctx[\`setvar\`] = new LazyValue(value1, ctx, this, node);
let txt1 = ctx['setvar'];
return block1([txt1]);
const b3 = block3([txt1]);
return multi([b2, b3]);
}
}"
`;
@@ -484,24 +613,39 @@ exports[`t-set t-set with t-value (falsy) and body 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue, LazyValue, safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<span><block-text-0/></span>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block6 = createBlock(\`<span><block-text-0/></span>\`);
function value1(ctx, node, key = \\"\\") {
const b5 = text(\`
\`);
let txt1 = ctx['v1'];
return block2([txt1]);
const b6 = block6([txt1]);
const b7 = text(\`
\`);
return multi([b5, b6, b7]);
}
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"v3\\", false);
setContextValue(ctx, \\"v1\\", 'before');
ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, this, node, key));
ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, this, node));
setContextValue(ctx, \\"v1\\", 'after');
setContextValue(ctx, \\"v3\\", true);
const b3 = safeOutput(ctx['v2']);
return block1([], [b3]);
const b8 = safeOutput(ctx['v2']);
const b3 = block3([], [b8]);
return multi([b2, b3]);
}
}"
`;
@@ -512,24 +656,39 @@ exports[`t-set t-set with t-value (truthy) and body 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue, LazyValue, safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<span><block-text-0/></span>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block6 = createBlock(\`<span><block-text-0/></span>\`);
function value1(ctx, node, key = \\"\\") {
const b5 = text(\`
\`);
let txt1 = ctx['v1'];
return block2([txt1]);
const b6 = block6([txt1]);
const b7 = text(\`
\`);
return multi([b5, b6, b7]);
}
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"v3\\", 'Truthy');
setContextValue(ctx, \\"v1\\", 'before');
ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, this, node, key));
ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, this, node));
setContextValue(ctx, \\"v1\\", 'after');
setContextValue(ctx, \\"v3\\", false);
const b3 = safeOutput(ctx['v2']);
return block1([], [b3]);
const b8 = safeOutput(ctx['v2']);
const b3 = block3([], [b8]);
return multi([b2, b3]);
}
}"
`;
@@ -540,19 +699,30 @@ exports[`t-set t-set, multiple t-ifs, and a specific configuration 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<p><div><span>First div</span></div><div><block-child-0/></div></p>\`);
let block3 = createBlock(\`<p>
<div>
<span>First div</span>
</div>
<div>
<block-child-0/>
</div>
</p>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
let b2;
const b2 = text(\`
\`);
let b4;
if (ctx['flag']) {
setContextValue(ctx, \\"bouh\\", 2);
}
if (!ctx['flag']) {
b2 = text(\`Second\`);
b4 = text(\`Second\`);
}
return block1([], [b2]);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -563,18 +733,24 @@ exports[`t-set t-set, t-if, and mix of expression/body lookup, 1 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
let block3 = createBlock(\`<div>
<block-text-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
if (ctx['flag']) {
setContextValue(ctx, \\"ourvar\\", \`1\`);
} else {
setContextValue(ctx, \\"ourvar\\", 0);
}
let txt1 = ctx['ourvar'];
return block1([txt1]);
const b3 = block3([txt1]);
return multi([b2, b3]);
}
}"
`;
@@ -585,18 +761,24 @@ exports[`t-set t-set, t-if, and mix of expression/body lookup, 2 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
let block3 = createBlock(\`<div>
<block-text-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
if (ctx['flag']) {
setContextValue(ctx, \\"ourvar\\", 1);
} else {
setContextValue(ctx, \\"ourvar\\", \`0\`);
}
let txt1 = ctx['ourvar'];
return block1([txt1]);
const b3 = block3([txt1]);
return multi([b2, b3]);
}
}"
`;
@@ -610,14 +792,18 @@ exports[`t-set t-set, t-if, and mix of expression/body lookup, 3 1`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
let b2;
let b2,b3,b4;
b2 = text(\`
\`);
if (ctx['flag']) {
setContextValue(ctx, \\"ourvar\\", 1);
} else {
setContextValue(ctx, \\"ourvar\\", \`0\`);
}
b2 = text(ctx['ourvar']);
return multi([b2]);
b3 = text(\`
\`);
b4 = text(ctx['ourvar']);
return multi([b2, b3, b4]);
}
}"
`;
@@ -638,7 +824,7 @@ exports[`t-set value priority (with non text body 1`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`value\`] = withDefault(1, new LazyValue(value1, ctx, this, node, key));
ctx[\`value\`] = withDefault(1, new LazyValue(value1, ctx, this, node));
let txt1 = ctx['value'];
return block1([txt1]);
}
@@ -75,11 +75,18 @@ exports[`qweb t-tag with multiple child nodes 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = tag => createBlock(\`<\${tag || 't'}> pear <span>apple</span> strawberry </\${tag || 't'}>\`);
let block3 = tag => createBlock(\`<\${tag || 't'}>
pear
<span>apple</span>
strawberry
</\${tag || 't'}>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const tag1 = ctx['tag'];
return toggler(tag1, block1(tag1)());
const b3 = toggler(tag1, block3(tag1)());
return multi([b2, b3]);
}
}"
`;
@@ -5,10 +5,15 @@ exports[`translation support can set and remove translatable attributes 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div tomato=\\"word\\" potato=\\"mot\\" title=\\"mot\\" label=\\"word\\">text</div>\`);
let block3 = createBlock(\`<div tomato=\\"word\\" potato=\\"mot\\" title=\\"mot\\" label=\\"word\\">text</div>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
const b2 = text(\`
\`);
const b3 = block3();
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -31,10 +36,18 @@ exports[`translation support does not translate node content if disabled 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><span>mot</span><span>word</span></div>\`);
let block3 = createBlock(\`<div>
<span>mot</span>
<span>word</span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
const b2 = text(\`
\`);
const b3 = block3();
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -44,10 +57,21 @@ exports[`translation support some attributes are translated 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><p label=\\"mot\\">mot</p><p title=\\"mot\\">mot</p><p placeholder=\\"mot\\">mot</p><p alt=\\"mot\\">mot</p><p something=\\"word\\">mot</p></div>\`);
let block3 = createBlock(\`<div>
<p label=\\"mot\\">mot</p>
<p title=\\"mot\\">mot</p>
<p placeholder=\\"mot\\">mot</p>
<p alt=\\"mot\\">mot</p>
<p something=\\"word\\">mot</p>
</div>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
const b2 = text(\`
\`);
const b3 = block3();
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -57,10 +81,15 @@ exports[`translation support translation is done on the trimmed text, with extra
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div> mot </div>\`);
let block3 = createBlock(\`<div> mot </div>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
const b2 = text(\`
\`);
const b3 = block3();
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -61,7 +61,8 @@ exports[`white space handling pre inside a div with a new line 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><pre>SomeText</pre></div>\`);
let block1 = createBlock(\`<div><pre>SomeText</pre>
</div>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
@@ -87,7 +88,9 @@ exports[`white space handling whitespace only text nodes with newlines are remov
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><span>abc</span></div>\`);
let block1 = createBlock(\`<div>
<span>abc</span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
-70
View File
@@ -12,11 +12,6 @@ describe("attributes", () => {
expect(renderToString(template)).toBe(`<div foo="a" bar="b" baz="c"></div>`);
});
test("static attributes with backslash or backtick", () => {
const template = `<div foo="\\a" bar="\\n" baz="\`"/>`;
expect(renderToString(template)).toBe(`<div foo="\\a" bar="\\n" baz="\`"></div>`);
});
test("two classes", () => {
const template = `<div class="a b"/>`;
expect(renderToString(template)).toBe(`<div class="a b"></div>`);
@@ -334,35 +329,6 @@ describe("attributes", () => {
expect(fixture.innerHTML).toBe('<div value=""></div>');
});
test("updating property with falsy value", async () => {
// render input with initial value
const template = `<input t-att-value="v"></input>`;
const bnode1 = renderToBdom(template, { v: false });
const fixture = makeTestFixture();
mount(bnode1, fixture);
const input = fixture.querySelector("input")!;
expect(input.value).toBe("");
patch(bnode1, renderToBdom(template, { v: "owl" }));
expect(input.value).toBe("owl");
patch(bnode1, renderToBdom(template, { v: false }));
expect(input.value).toBe("");
patch(bnode1, renderToBdom(template, { v: "owl" }));
expect(input.value).toBe("owl");
patch(bnode1, renderToBdom(template, { v: undefined }));
expect(input.value).toBe("");
patch(bnode1, renderToBdom(template, { v: "owl" }));
expect(input.value).toBe("owl");
patch(bnode1, renderToBdom(template, { v: null }));
expect(input.value).toBe("");
});
test("changing a class with t-att-class", () => {
// render input with initial value
const template = `<div t-att-class="v"/>`;
@@ -463,42 +429,6 @@ describe("special cases for some specific html attributes/properties", () => {
expect(input.value).toBe("potato");
});
test("input with t-att-value (patching with same value", () => {
// render input with initial value
const template = `<input t-att-value="v"/>`;
const bnode1 = renderToBdom(template, { v: "zucchini" });
const fixture = makeTestFixture();
mount(bnode1, fixture);
const input = fixture.querySelector("input")!;
expect(input.value).toBe("zucchini");
// change value manually in input, to simulate user input
input.value = "tomato";
expect(input.value).toBe("tomato");
const bnode2 = renderToBdom(template, { v: "zucchini" });
patch(bnode1, bnode2);
expect(input.value).toBe("zucchini");
});
test("input, type checkbox, with t-att-checked (patching with same value", () => {
// render input with initial value
const template = `<input type="checkbox" t-att-checked="v"/>`;
const bnode1 = renderToBdom(template, { v: true });
const fixture = makeTestFixture();
mount(bnode1, fixture);
const input = fixture.querySelector("input")!;
expect(input.checked).toBe(true);
// change checked manually in input, to simulate user input
input.checked = false;
expect(input.checked).toBe(false);
const bnode2 = renderToBdom(template, { v: true });
patch(bnode1, bnode2);
expect(input.checked).toBe(true);
});
test("input of type checkbox with t-att-indeterminate", () => {
const template = `<input type="checkbox" t-att-indeterminate="v"/>`;
const bnode1 = renderToBdom(template, { v: true });
-17
View File
@@ -479,21 +479,4 @@ describe("t-call (template calling)", () => {
"<span>123lucas</span>"
);
});
test("nested t-calls with magic variable 0", () => {
const context = new TestContext();
context.addTemplate("grandchild", `grandchild<t t-out="0"/>`);
context.addTemplate("child", `<t t-out="0"/>`);
context.addTemplate(
"main",
`
<t t-call="child">
<t t-call="grandchild">
<p>Some content...</p>
</t>
</t>`
);
expect(context.renderToString("main")).toBe("grandchild<p>Some content...</p>");
});
});
+1 -2
View File
@@ -114,8 +114,7 @@ describe("t-ref", () => {
app.addTemplate("main", main);
app.addTemplate("sub", sub);
const comp = { __owl__: { refs } };
const bdom = app.getTemplate("main").call(comp, comp, {});
const bdom = app.getTemplate("main")({ __owl__: { refs } }, {});
mount(bdom, document.createElement("div"));
expect(refs.name.tagName).toBe("SPAN");
@@ -130,13 +130,16 @@ exports[`basics can be clicked on and updated 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/><button block-handler-1=\\"click\\">Inc</button></div>\`);
let block3 = createBlock(\`<div><block-text-0/><button block-handler-1=\\"click\\">Inc</button></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['state'].counter;
const v1 = ctx['state'];
let hdlr1 = [()=>v1.counter++, ctx];
return block1([txt1, hdlr1]);
const b3 = block3([txt1, hdlr1]);
return multi([b2, b3]);
}
}"
`;
@@ -485,21 +488,30 @@ exports[`basics list of two sub components inside other nodes 1`] = `
const comp1 = app.createComponent(\`SubWidget\`, true, false, false, true);
const comp2 = app.createComponent(\`SubWidget\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block5 = createBlock(\`<div>
<block-child-0/>
<block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].blips);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`blip\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state'].blips);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`blip\`] = v_block4[i1];
const key1 = ctx['blip'].id;
const b4 = comp1({}, key + \`__1__\${key1}\`, node, this, null);
const b5 = comp2({}, key + \`__2__\${key1}\`, node, this, null);
c_block2[i1] = withKey(block3([], [b4, b5]), key1);
const b6 = comp1({}, key + \`__1__\${key1}\`, node, this, null);
const b7 = comp2({}, key + \`__2__\${key1}\`, node, this, null);
c_block4[i1] = withKey(block5([], [b6, b7]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -600,13 +612,21 @@ exports[`basics reconciliation alg is not confused in some specific situation 1`
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
const comp2 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({}, key + \`__1\`, node, this, null);
const b2 = text(\`
\`);
const b4 = comp1({}, key + \`__1\`, node, this, null);
const tKey_1 = 4;
const b3 = toggler(tKey_1, comp2({}, tKey_1 + key + \`__2\`, node, this, null));
return block1([], [b2, b3]);
const b5 = toggler(tKey_1, comp2({}, tKey_1 + key + \`__2\`, node, this, null));
const b3 = block3([], [b4, b5]);
const b6 = text(\`
\`);
return multi([b2, b3, b6]);
}
}"
`;
@@ -641,13 +661,16 @@ exports[`basics rerendering a widget with a sub widget 2`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/><button block-handler-1=\\"click\\">Inc</button></div>\`);
let block3 = createBlock(\`<div><block-text-0/><button block-handler-1=\\"click\\">Inc</button></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['state'].counter;
const v1 = ctx['state'];
let hdlr1 = [()=>v1.counter++, ctx];
return block1([txt1, hdlr1]);
const b3 = block3([txt1, hdlr1]);
return multi([b2, b3]);
}
}"
`;
@@ -659,14 +682,20 @@ exports[`basics same t-keys in two different places 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
const comp2 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><div><block-child-0/></div><div><block-child-1/></div></div>\`);
let block3 = createBlock(\`<div>
<div><block-child-0/></div>
<div><block-child-1/></div>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const tKey_1 = 1;
const b2 = toggler(tKey_1, comp1({blip: '1'}, tKey_1 + key + \`__1\`, node, this, null));
const b4 = toggler(tKey_1, comp1({blip: '1'}, tKey_1 + key + \`__1\`, node, this, null));
const tKey_2 = 1;
const b3 = toggler(tKey_2, comp2({blip: '2'}, tKey_2 + key + \`__2\`, node, this, null));
return block1([], [b2, b3]);
const b5 = toggler(tKey_2, comp2({blip: '2'}, tKey_2 + key + \`__2\`, node, this, null));
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -732,23 +761,30 @@ exports[`basics sub components between t-ifs 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><span><block-child-2/></span><block-child-3/></div>\`);
let block2 = createBlock(\`<h1>hey</h1>\`);
let block3 = createBlock(\`<h2>noo</h2>\`);
let block5 = createBlock(\`<span>test</span>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/>
<span><block-child-2/></span>
<block-child-3/>
</div>\`);
let block4 = createBlock(\`<h1>hey</h1>\`);
let block5 = createBlock(\`<h2>noo</h2>\`);
let block7 = createBlock(\`<span>test</span>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3,b4,b5;
const b2 = text(\`
\`);
let b4,b5,b6,b7;
if (ctx['state'].flag) {
b2 = block2();
b4 = block4();
} else {
b3 = block3();
}
b4 = comp1({}, key + \`__1\`, node, this, null);
if (ctx['state'].flag) {
b5 = block5();
}
return block1([], [b2, b3, b4, b5]);
b6 = comp1({}, key + \`__1\`, node, this, null);
if (ctx['state'].flag) {
b7 = block7();
}
const b3 = block3([], [b4, b5, b6, b7]);
return multi([b2, b3]);
}
}"
`;
@@ -772,17 +808,22 @@ exports[`basics t-elif works with t-component 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block2 = createBlock(\`<div>somediv</div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/>
</div>\`);
let block4 = createBlock(\`<div>somediv</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['state'].flag) {
b2 = block2();
b4 = block4();
} else if (!ctx['state'].flag) {
b3 = comp1({}, key + \`__1\`, node, this, null);
b5 = comp1({}, key + \`__1\`, node, this, null);
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -806,17 +847,22 @@ exports[`basics t-else with empty string works with t-component 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block2 = createBlock(\`<div>somediv</div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/>
</div>\`);
let block4 = createBlock(\`<div>somediv</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['state'].flag) {
b2 = block2();
b4 = block4();
} else {
b3 = comp1({}, key + \`__1\`, node, this, null);
b5 = comp1({}, key + \`__1\`, node, this, null);
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -840,17 +886,22 @@ exports[`basics t-else works with t-component 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block2 = createBlock(\`<div>somediv</div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/>
</div>\`);
let block4 = createBlock(\`<div>somediv</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['state'].flag) {
b2 = block2();
b4 = block4();
} else {
b3 = comp1({}, key + \`__1\`, node, this, null);
b5 = comp1({}, key + \`__1\`, node, this, null);
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -906,16 +957,22 @@ exports[`basics t-key on a component with t-if, and a sibling component 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
const comp2 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/><block-child-0/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-0/>
<block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (false) {
const tKey_1 = 'str';
b2 = toggler(tKey_1, comp1({}, tKey_1 + key + \`__1\`, node, this, null));
b4 = toggler(tKey_1, comp1({}, tKey_1 + key + \`__1\`, node, this, null));
}
b3 = comp2({}, key + \`__2\`, node, this, null);
return block1([], [b2, b3]);
b5 = comp2({}, key + \`__2\`, node, this, null);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -939,15 +996,21 @@ exports[`basics text after a conditional component 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/><span><block-text-0/></span></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<span><block-text-0/></span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2;
const b2 = text(\`
\`);
let b4;
if (ctx['state'].hasChild) {
b2 = comp1({}, key + \`__1\`, node, this, null);
b4 = comp1({}, key + \`__1\`, node, this, null);
}
let txt1 = ctx['state'].text;
return block1([txt1], [b2]);
const b3 = block3([txt1], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -1036,12 +1099,17 @@ exports[`basics update props of component without concrete own node 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, true, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const tKey_1 = ctx['childProps'].key;
const b2 = toggler(tKey_1, comp1(Object.assign({}, ctx['childProps']), tKey_1 + key + \`__1\`, node, this, null));
return block1([], [b2]);
const b4 = toggler(tKey_1, comp1(Object.assign({}, ctx['childProps']), tKey_1 + key + \`__1\`, node, this, null));
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -1053,8 +1121,11 @@ exports[`basics update props of component without concrete own node 2`] = `
const comp1 = app.createComponent(\`Custom\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const tKey_1 = ctx['props'].subKey;
return toggler(tKey_1, comp1({key: ctx['props'].key,subKey: ctx['props'].subKey}, tKey_1 + key + \`__1\`, node, this, null));
const b3 = toggler(tKey_1, comp1({key: ctx['props'].key,subKey: ctx['props'].subKey}, tKey_1 + key + \`__1\`, node, this, null));
return multi([b2, b3]);
}
}"
`;
@@ -1064,12 +1135,17 @@ exports[`basics update props of component without concrete own node 3`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div class=\\"widget-subkey\\"><block-text-0/>__<block-text-1/></div>\`);
let block3 = createBlock(\`<div class=\\"widget-subkey\\">
<block-text-0/>__<block-text-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['props'].key;
let txt2 = ctx['props'].subKey;
return block1([txt1, txt2]);
const b3 = block3([txt1, txt2]);
return multi([b2, b3]);
}
}"
`;
@@ -1081,14 +1157,22 @@ exports[`basics updating a component with t-foreach as root 1`] = `
let { prepareList, withKey } = helpers;
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`item\`] = v_block1[i1];
const [k_block3, v_block3, l_block3, c_block3] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block3; i1++) {
ctx[\`item\`] = v_block3[i1];
const key1 = ctx['item'];
c_block1[i1] = withKey(text(ctx['item']), key1);
const b5 = text(\`
\`);
const b6 = text(ctx['item']);
const b7 = text(\`
\`);
c_block3[i1] = withKey(multi([b5, b6, b7]), key1);
}
return list(c_block1);
const b3 = list(c_block3);
return multi([b2, b3]);
}
}"
`;
@@ -1248,11 +1332,16 @@ exports[`support svg components add proper namespace to svg 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`GComp\`, true, false, false, true);
let block1 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><block-child-0/></svg>\`);
let block3 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\">
<block-child-0/>
</svg>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({}, key + \`__1\`, node, this, null);
return block1([], [b2]);
const b2 = text(\`
\`);
const b4 = comp1({}, key + \`__1\`, node, this, null);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -1262,10 +1351,15 @@ exports[`support svg components add proper namespace to svg 2`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<g block-ns=\\"http://www.w3.org/2000/svg\\"><circle cx=\\"50\\" cy=\\"50\\" r=\\"4\\" stroke=\\"green\\" stroke-width=\\"1\\" fill=\\"yellow\\"/></g>\`);
let block3 = createBlock(\`<g block-ns=\\"http://www.w3.org/2000/svg\\">
<circle cx=\\"50\\" cy=\\"50\\" r=\\"4\\" stroke=\\"green\\" stroke-width=\\"1\\" fill=\\"yellow\\"/>
</g>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
const b2 = text(\`
\`);
const b3 = block3();
return multi([b2, b3]);
}
}"
`;
@@ -1276,20 +1370,32 @@ exports[`t-out in components can render list of t-out 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, safeOutput, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].items);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state'].items);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`item\`] = v_block4[i1];
const key1 = ctx['item'];
const b4 = text(ctx['item']);
const b5 = safeOutput(ctx['item']);
c_block2[i1] = withKey(multi([b4, b5]), key1);
const b6 = text(\`
\`);
const b7 = text(ctx['item']);
const b8 = text(\`
\`);
const b9 = safeOutput(ctx['item']);
const b10 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8, b9, b10]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -1301,9 +1407,15 @@ exports[`t-out in components can switch the contents of two t-out repeatedly 1`]
let { safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") {
const b2 = safeOutput(ctx['state'].a);
const b3 = safeOutput(ctx['state'].b);
return multi([b2, b3]);
const b2 = text(\`
\`);
const b3 = safeOutput(ctx['state'].a);
const b4 = text(\`
\`);
const b5 = safeOutput(ctx['state'].b);
const b6 = text(\`
\`);
return multi([b2, b3, b4, b5, b6]);
}
}"
`;
@@ -31,14 +31,22 @@ exports[`Cascading renders after microtaskTick 2`] = `
const comp1 = app.createComponent(\`Element\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['state']);;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`elem\`] = v_block1[i1];
const [k_block3, v_block3, l_block3, c_block3] = prepareList(ctx['state']);;
for (let i1 = 0; i1 < l_block3; i1++) {
ctx[\`elem\`] = v_block3[i1];
const key1 = ctx['elem'].id;
c_block1[i1] = withKey(comp1({id: ctx['elem'].id}, key + \`__1__\${key1}\`, node, this, null), key1);
const b5 = text(\`
\`);
const b6 = comp1({id: ctx['elem'].id}, key + \`__1__\${key1}\`, node, this, null);
const b7 = text(\`
\`);
c_block3[i1] = withKey(multi([b5, b6, b7]), key1);
}
return list(c_block1);
const b3 = list(c_block3);
return multi([b2, b3]);
}
}"
`;
@@ -143,11 +151,16 @@ exports[`calling render in destroy 3`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
let block3 = createBlock(\`<div>
<block-text-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['props'].fromA;
return block1([txt1]);
const b3 = block3([txt1]);
return multi([b2, b3]);
}
}"
`;
@@ -593,13 +606,20 @@ exports[`concurrent renderings scenario 9 1`] = `
const comp1 = app.createComponent(\`ComponentB\`, true, false, false, false);
const comp2 = app.createComponent(\`ComponentC\`, true, false, false, false);
let block1 = createBlock(\`<div><block-text-0/><block-child-0/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-text-0/>
<block-child-0/>
<block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['state'].fromA;
const b2 = comp1({fromA: ctx['state'].fromA}, key + \`__1\`, node, this, null);
const b3 = comp2({fromA: ctx['state'].fromA}, key + \`__2\`, node, this, null);
return block1([txt1], [b2, b3]);
const b4 = comp1({fromA: ctx['state'].fromA}, key + \`__1\`, node, this, null);
const b5 = comp2({fromA: ctx['state'].fromA}, key + \`__2\`, node, this, null);
const b3 = block3([txt1], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -761,15 +781,21 @@ exports[`concurrent renderings scenario 13 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
const comp2 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
b2 = comp1({}, key + \`__1\`, node, this, null);
const b2 = text(\`
\`);
let b4,b5;
b4 = comp1({}, key + \`__1\`, node, this, null);
if (ctx['state'].bool) {
b3 = comp2({}, key + \`__2\`, node, this, null);
b5 = comp2({}, key + \`__2\`, node, this, null);
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -823,13 +849,20 @@ exports[`concurrent renderings scenario 14 3`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<p><span><block-text-0/></span><span><block-text-1/></span><span><block-text-2/></span></p>\`);
let block3 = createBlock(\`<p>
<span><block-text-0/></span>
<span><block-text-1/></span>
<span><block-text-2/></span>
</p>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['props'].fromA;
let txt2 = ctx['props'].fromB;
let txt3 = ctx['state'].fromC;
return block1([txt1, txt2, txt3]);
const b3 = block3([txt1, txt2, txt3]);
return multi([b2, b3]);
}
}"
`;
@@ -869,13 +902,20 @@ exports[`concurrent renderings scenario 15 3`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<p><span><block-text-0/></span><span><block-text-1/></span><span><block-text-2/></span></p>\`);
let block3 = createBlock(\`<p>
<span><block-text-0/></span>
<span><block-text-1/></span>
<span><block-text-2/></span>
</p>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['props'].fromA;
let txt2 = ctx['props'].fromB;
let txt3 = ctx['state'].fromC;
return block1([txt1, txt2, txt3]);
const b3 = block3([txt1, txt2, txt3]);
return multi([b2, b3]);
}
}"
`;
@@ -911,17 +951,20 @@ exports[`concurrent renderings scenario 16 3`] = `
const comp1 = app.createComponent(\`D\`, true, false, false, true);
return function template(ctx, node, key = \\"\\") {
let b2,b3,b4,b5,b6,b7,b8;
b2 = text(ctx['props'].fromA);
b3 = text(\`:\`);
b4 = text(ctx['props'].fromB);
b5 = text(\`:\`);
b6 = text(ctx['state'].fromC);
b7 = text(\`: \`);
let b2,b3,b4,b5,b6,b7,b8,b9;
b2 = text(\`
\`);
b3 = text(ctx['props'].fromA);
b4 = text(\`:\`);
b5 = text(ctx['props'].fromB);
b6 = text(\`:\`);
b7 = text(ctx['state'].fromC);
b8 = text(\`:
\`);
if (ctx['state'].fromC===13) {
b8 = comp1({}, key + \`__1\`, node, this, null);
b9 = comp1({}, key + \`__1\`, node, this, null);
}
return multi([b2, b3, b4, b5, b6, b7, b8]);
return multi([b2, b3, b4, b5, b6, b7, b8, b9]);
}
}"
`;
@@ -945,14 +988,18 @@ exports[`creating two async components, scenario 1 1`] = `
const comp2 = app.createComponent(\`ChildB\`, true, false, false, true);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
let b2,b3,b4,b5;
b2 = text(\`
\`);
if (ctx['state'].flagA) {
b2 = comp1({}, key + \`__1\`, node, this, null);
b3 = comp1({}, key + \`__1\`, node, this, null);
}
b4 = text(\`
\`);
if (ctx['state'].flagB) {
b3 = comp2({}, key + \`__2\`, node, this, null);
b5 = comp2({}, key + \`__2\`, node, this, null);
}
return multi([b2, b3]);
return multi([b2, b3, b4, b5]);
}
}"
`;
@@ -991,15 +1038,21 @@ exports[`creating two async components, scenario 2 1`] = `
const comp1 = app.createComponent(\`ChildA\`, true, false, false, false);
const comp2 = app.createComponent(\`ChildB\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
b2 = comp1({val: ctx['state'].valA}, key + \`__1\`, node, this, null);
const b2 = text(\`
\`);
let b4,b5;
b4 = comp1({val: ctx['state'].valA}, key + \`__1\`, node, this, null);
if (ctx['state'].flagB) {
b3 = comp2({val: ctx['state'].valB}, key + \`__2\`, node, this, null);
b5 = comp2({val: ctx['state'].valB}, key + \`__2\`, node, this, null);
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -1039,15 +1092,21 @@ exports[`creating two async components, scenario 3 (patching in the same frame)
const comp1 = app.createComponent(\`ChildA\`, true, false, false, false);
const comp2 = app.createComponent(\`ChildB\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
b2 = comp1({val: ctx['state'].valA}, key + \`__1\`, node, this, null);
const b2 = text(\`
\`);
let b4,b5;
b4 = comp1({val: ctx['state'].valA}, key + \`__1\`, node, this, null);
if (ctx['state'].flagB) {
b3 = comp2({val: ctx['state'].valB}, key + \`__2\`, node, this, null);
b5 = comp2({val: ctx['state'].valB}, key + \`__2\`, node, this, null);
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -1475,11 +1534,19 @@ exports[`destroyed component causes other soon to be destroyed component to rere
return function template(ctx, node, key = \\"\\") {
let b2,b3;
b2 = text(\` A \`);
b2 = text(\`
A
\`);
if (ctx['state'].flag) {
const b4 = comp1({value: ctx['state'].valueB}, key + \`__1\`, node, this, null);
const b5 = comp2({value: ctx['state'].valueC}, key + \`__2\`, node, this, null);
b3 = multi([b4, b5]);
const b4 = text(\`
\`);
const b5 = comp1({value: ctx['state'].valueB}, key + \`__1\`, node, this, null);
const b6 = text(\`
\`);
const b7 = comp2({value: ctx['state'].valueC}, key + \`__2\`, node, this, null);
const b8 = text(\`
\`);
b3 = multi([b4, b5, b6, b7, b8]);
}
return multi([b2, b3]);
}
@@ -1542,14 +1609,19 @@ exports[`destroying/recreating a subwidget with different props (if start is not
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2;
const b2 = text(\`
\`);
let b4;
if (ctx['state'].val>1) {
b2 = comp1({val: ctx['state'].val}, key + \`__1\`, node, this, null);
b4 = comp1({val: ctx['state'].val}, key + \`__1\`, node, this, null);
}
return block1([], [b2]);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -1597,14 +1669,17 @@ exports[`properly behave when destroyed/unmounted while rendering 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
let b2;
const b2 = text(\`
\`);
let b4;
if (ctx['state'].flag) {
b2 = comp1({val: ctx['state'].val}, key + \`__1\`, node, this, null);
b4 = comp1({val: ctx['state'].val}, key + \`__1\`, node, this, null);
}
return block1([], [b2]);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -1643,15 +1718,21 @@ exports[`rendering component again in next microtick 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><button block-handler-0=\\"click\\">Click</button><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<button block-handler-0=\\"click\\">Click</button>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2;
const b2 = text(\`
\`);
let b4;
let hdlr1 = [ctx['onClick'], ctx];
if (ctx['env'].config.flag) {
b2 = comp1({}, key + \`__1\`, node, this, null);
b4 = comp1({}, key + \`__1\`, node, this, null);
}
return block1([hdlr1], [b2]);
const b3 = block3([hdlr1], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -1773,12 +1854,16 @@ exports[`t-foreach with dynamic async component 1`] = `
ctx[\`arr\`] = v_block1[i1];
ctx[\`arr_index\`] = i1;
const key1 = ctx['arr_index'];
let b3;
let b3,b4,b5;
b3 = text(\`
\`);
if (ctx['arr']) {
const Comp1 = ctx['myComp'];
b3 = toggler(Comp1, comp1({key: ctx['arr'][0]}, key + \`__1__\${key1}\`, node, this, Comp1));
b4 = toggler(Comp1, comp1({key: ctx['arr'][0]}, key + \`__1__\${key1}\`, node, this, Comp1));
}
c_block1[i1] = withKey(multi([b3]), key1);
b5 = text(\`
\`);
c_block1[i1] = withKey(multi([b3, b4, b5]), key1);
}
return list(c_block1);
}
@@ -20,7 +20,7 @@ exports[`basics display a nice error if it cannot find component (in dev mode) 1
return function template(ctx, node, key = \\"\\") {
const props1 = {};
helpers.validateProps(\`SomeMispelledComponent\`, props1, this);
helpers.validateProps(\`SomeMispelledComponent\`, props1, ctx);
return comp1(props1, key + \`__1\`, node, this, null);
}
}"
@@ -38,21 +38,6 @@ exports[`basics display a nice error if it cannot find component 1`] = `
}"
`;
exports[`basics display a nice error if the components key is missing with subcomponents 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`MissingChild\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({}, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
}"
`;
exports[`basics no component catching error lead to full app destruction 1`] = `
"function anonymous(app, bdom, helpers
) {
@@ -88,16 +73,26 @@ exports[`basics simple catchError 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Boom\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['error']) {
b2 = text(\`Error\`);
b4 = text(\`Error\`);
} else {
b3 = comp1({}, key + \`__1\`, node, this, null);
const b6 = text(\`
\`);
const b7 = comp1({}, key + \`__1\`, node, this, null);
const b8 = text(\`
\`);
b5 = multi([b6, b7, b8]);
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -116,72 +111,6 @@ exports[`basics simple catchError 2`] = `
}"
`;
exports[`can catch errors Errors have the right cause 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['state'].value);
}
}"
`;
exports[`can catch errors Errors in owl lifecycle are wrapped in dev mode: async hook 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['state'].value);
}
}"
`;
exports[`can catch errors Errors in owl lifecycle are wrapped out of dev mode: async hook 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['state'].value);
}
}"
`;
exports[`can catch errors Errors in owl lifecycle are wrapped outside dev mode: sync hook 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['state'].value);
}
}"
`;
exports[`can catch errors Thrown values that are not errors are wrapped in dev mode 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['state'].value);
}
}"
`;
exports[`can catch errors Thrown values that are not errors are wrapped outside dev mode 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['state'].value);
}
}"
`;
exports[`can catch errors an error in onWillDestroy 1`] = `
"function anonymous(app, bdom, helpers
) {
@@ -189,12 +118,16 @@ exports[`can catch errors an error in onWillDestroy 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
b2 = text(ctx['state'].value);
let b2,b3,b4,b5;
b2 = text(\`
\`);
b3 = text(ctx['state'].value);
b4 = text(\`
\`);
if (ctx['state'].hasChild) {
b3 = comp1({}, key + \`__1\`, node, this, null);
b5 = comp1({}, key + \`__1\`, node, this, null);
}
return multi([b2, b3]);
return multi([b2, b3, b4, b5]);
}
}"
`;
@@ -219,12 +152,16 @@ exports[`can catch errors an error in onWillDestroy, variation 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
b2 = text(ctx['state'].value);
let b2,b3,b4,b5;
b2 = text(\`
\`);
b3 = text(ctx['state'].value);
b4 = text(\`
\`);
if (ctx['state'].hasChild) {
b3 = comp1({}, key + \`__1\`, node, this, null);
b5 = comp1({}, key + \`__1\`, node, this, null);
}
return multi([b2, b3]);
return multi([b2, b3, b4, b5]);
}
}"
`;
@@ -261,15 +198,20 @@ exports[`can catch errors can catch an error in a component render function 1`]
const comp1 = app.createComponent(\`ErrorComponent\`, true, false, false, false);
const comp2 = app.createComponent(\`ErrorBoundary\`, true, true, false, true);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
function slot1(ctx, node, key = \\"\\") {
return comp1({flag: ctx['state'].flag}, key + \`__1\`, node, this, null);
}
return function template(ctx, node, key = \\"\\") {
const b3 = comp2({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__2\`, node, this, null);
return block1([], [b3]);
const b2 = text(\`
\`);
const b5 = comp2({slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, this, null);
const b3 = block3([], [b5]);
return multi([b2, b3]);
}
}"
`;
@@ -280,16 +222,21 @@ exports[`can catch errors can catch an error in a component render function 2`]
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { callSlot } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/><block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['state'].error) {
b2 = text(\`Error handled\`);
b4 = text(\`Error handled\`);
} else {
b3 = callSlot(ctx, node, key, 'default', false, {});
b5 = callSlot(ctx, node, key, 'default', false, {});
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -316,14 +263,16 @@ exports[`can catch errors can catch an error in the constructor call of a compon
const comp1 = app.createComponent(\`ErrorComponent\`, true, false, false, true);
const comp2 = app.createComponent(\`ErrorBoundary\`, true, true, false, true);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block1 = createBlock(\`<div>
<block-child-0/>
</div>\`);
function slot1(ctx, node, key = \\"\\") {
return comp1({}, key + \`__1\`, node, this, null);
}
return function template(ctx, node, key = \\"\\") {
const b3 = comp2({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__2\`, node, this, null);
const b3 = comp2({slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, this, null);
return block1([], [b3]);
}
}"
@@ -335,7 +284,9 @@ exports[`can catch errors can catch an error in the constructor call of a compon
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { callSlot } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-1/></div>\`);
let block1 = createBlock(\`<div>
<block-child-0/><block-child-1/><block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
@@ -358,7 +309,9 @@ exports[`can catch errors can catch an error in the constructor call of a compon
const comp2 = app.createComponent(\`ErrorComponent\`, true, false, false, true);
const comp3 = app.createComponent(\`ErrorBoundary\`, true, true, false, true);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block1 = createBlock(\`<div>
<block-child-0/>
</div>\`);
function slot1(ctx, node, key = \\"\\") {
const b3 = comp1({}, key + \`__1\`, node, this, null);
@@ -367,7 +320,7 @@ exports[`can catch errors can catch an error in the constructor call of a compon
}
return function template(ctx, node, key = \\"\\") {
const b5 = comp3({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__3\`, node, this, null);
const b5 = comp3({slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__3\`, node, this, null);
return block1([], [b5]);
}
}"
@@ -379,7 +332,9 @@ exports[`can catch errors can catch an error in the constructor call of a compon
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { callSlot } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-1/></div>\`);
let block1 = createBlock(\`<div>
<block-child-0/><block-child-1/><block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
@@ -440,15 +395,20 @@ exports[`can catch errors can catch an error in the initial call of a component
const comp1 = app.createComponent(\`ErrorComponent\`, true, false, false, true);
const comp2 = app.createComponent(\`ErrorBoundary\`, true, true, false, true);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
function slot1(ctx, node, key = \\"\\") {
return comp1({}, key + \`__1\`, node, this, null);
}
return function template(ctx, node, key = \\"\\") {
const b3 = comp2({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__2\`, node, this, null);
return block1([], [b3]);
const b2 = text(\`
\`);
const b5 = comp2({slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, this, null);
const b3 = block3([], [b5]);
return multi([b2, b3]);
}
}"
`;
@@ -459,16 +419,21 @@ exports[`can catch errors can catch an error in the initial call of a component
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { callSlot } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/><block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['state'].error) {
b2 = text(\`Error handled\`);
b4 = text(\`Error handled\`);
} else {
b3 = callSlot(ctx, node, key, 'default', false, {});
b5 = callSlot(ctx, node, key, 'default', false, {});
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -495,18 +460,23 @@ exports[`can catch errors can catch an error in the initial call of a component
const comp1 = app.createComponent(\`ErrorComponent\`, true, false, false, true);
const comp2 = app.createComponent(\`ErrorBoundary\`, true, true, false, true);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
function slot1(ctx, node, key = \\"\\") {
return comp1({}, key + \`__1\`, node, this, null);
}
return function template(ctx, node, key = \\"\\") {
let b3;
const b2 = text(\`
\`);
let b5;
if (ctx['state'].flag) {
b3 = comp2({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__2\`, node, this, null);
b5 = comp2({slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, this, null);
}
return block1([], [b3]);
const b3 = block3([], [b5]);
return multi([b2, b3]);
}
}"
`;
@@ -517,16 +487,21 @@ exports[`can catch errors can catch an error in the initial call of a component
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { callSlot } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/><block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['state'].error) {
b2 = text(\`Error handled\`);
b4 = text(\`Error handled\`);
} else {
b3 = callSlot(ctx, node, key, 'default', false, {});
b5 = callSlot(ctx, node, key, 'default', false, {});
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -578,7 +553,9 @@ exports[`can catch errors can catch an error in the mounted call (in child of ch
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Boom\`, true, false, false, true);
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 = \\"\\") {
let b2,b3;
@@ -611,7 +588,9 @@ exports[`can catch errors can catch an error in the mounted call (in root compon
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`ErrorComponent\`, true, false, false, true);
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 = \\"\\") {
let b2,b3;
@@ -646,14 +625,16 @@ exports[`can catch errors can catch an error in the mounted call 1`] = `
const comp1 = app.createComponent(\`ErrorComponent\`, true, false, false, true);
const comp2 = app.createComponent(\`ErrorBoundary\`, true, true, false, true);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block1 = createBlock(\`<div>
<block-child-0/>
</div>\`);
function slot1(ctx, node, key = \\"\\") {
return comp1({}, key + \`__1\`, node, this, null);
}
return function template(ctx, node, key = \\"\\") {
const b3 = comp2({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__2\`, node, this, null);
const b3 = comp2({slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, this, null);
return block1([], [b3]);
}
}"
@@ -665,7 +646,9 @@ exports[`can catch errors can catch an error in the mounted call 2`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { callSlot } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-1/></div>\`);
let block1 = createBlock(\`<div>
<block-child-0/><block-child-1/><block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
@@ -700,16 +683,22 @@ exports[`can catch errors can catch an error in the willPatch call 1`] = `
const comp1 = app.createComponent(\`ErrorComponent\`, true, false, false, false);
const comp2 = app.createComponent(\`ErrorBoundary\`, true, true, false, true);
let block1 = createBlock(\`<div><span><block-text-0/></span><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<span><block-text-0/></span>
<block-child-0/>
</div>\`);
function slot1(ctx, node, key = \\"\\") {
return comp1({message: ctx['state'].message}, key + \`__1\`, node, this, null);
}
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['state'].message;
const b3 = comp2({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__2\`, node, this, null);
return block1([txt1], [b3]);
const b5 = comp2({slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, this, null);
const b3 = block3([txt1], [b5]);
return multi([b2, b3]);
}
}"
`;
@@ -720,16 +709,21 @@ exports[`can catch errors can catch an error in the willPatch call 2`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { callSlot } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/><block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['state'].error) {
b2 = text(\`Error handled\`);
b4 = text(\`Error handled\`);
} else {
b3 = callSlot(ctx, node, key, 'default', false, {});
b5 = callSlot(ctx, node, key, 'default', false, {});
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -763,7 +757,7 @@ exports[`can catch errors can catch an error in the willStart call 1`] = `
}
return function template(ctx, node, key = \\"\\") {
const b3 = comp2({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__2\`, node, this, null);
const b3 = comp2({slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__2\`, node, this, null);
return block1([], [b3]);
}
}"
@@ -775,16 +769,21 @@ exports[`can catch errors can catch an error in the willStart call 2`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { callSlot } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/><block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['state'].error) {
b2 = text(\`Error handled\`);
b4 = text(\`Error handled\`);
} else {
b3 = callSlot(ctx, node, key, 'default', false, {});
b5 = callSlot(ctx, node, key, 'default', false, {});
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -811,7 +810,9 @@ exports[`can catch errors can catch an error origination from a child's willStar
const comp2 = app.createComponent(\`ErrorComponent\`, true, false, false, true);
const comp3 = app.createComponent(\`ErrorBoundary\`, true, true, false, true);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block1 = createBlock(\`<div>
<block-child-0/>
</div>\`);
function slot1(ctx, node, key = \\"\\") {
const b3 = comp1({}, key + \`__1\`, node, this, null);
@@ -820,7 +821,7 @@ exports[`can catch errors can catch an error origination from a child's willStar
}
return function template(ctx, node, key = \\"\\") {
const b5 = comp3({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__3\`, node, this, null);
const b5 = comp3({slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__3\`, node, this, null);
return block1([], [b5]);
}
}"
@@ -832,7 +833,9 @@ exports[`can catch errors can catch an error origination from a child's willStar
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { callSlot } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-1/></div>\`);
let block1 = createBlock(\`<div>
<block-child-0/><block-child-1/><block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
@@ -878,16 +881,26 @@ exports[`can catch errors catchError in catchError 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['error']) {
b2 = text(\`Error\`);
b4 = text(\`Error\`);
} else {
b3 = comp1({}, key + \`__1\`, node, this, null);
const b6 = text(\`
\`);
const b7 = comp1({}, key + \`__1\`, node, this, null);
const b8 = text(\`
\`);
b5 = multi([b6, b7, b8]);
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
return multi([b2, b3]);
}
}"
`;
@@ -898,11 +911,16 @@ exports[`can catch errors catchError in catchError 2`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Boom\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({}, key + \`__1\`, node, this, null);
return block1([], [b2]);
const b2 = text(\`
\`);
const b4 = comp1({}, key + \`__1\`, node, this, null);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -930,21 +948,34 @@ exports[`can catch errors catching error, rethrow, render parent -- a main comp
const comp2 = app.createComponent(\`ErrorHandler\`, true, true, false, false);
function slot1(ctx, node, key = \\"\\") {
const b7 = text(\`
\`);
const Comp1 = ctx['cp'].Comp;
return toggler(Comp1, comp1({}, key + \`__1\`, node, this, Comp1));
const b8 = toggler(Comp1, comp1({}, key + \`__1\`, node, this, Comp1));
const b9 = text(\`
\`);
return multi([b7, b8, b9]);
}
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(Object.values(ctx['state'].cps));;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`cp\`] = v_block1[i1];
const [k_block3, v_block3, l_block3, c_block3] = prepareList(Object.values(ctx['state'].cps));;
for (let i1 = 0; i1 < l_block3; i1++) {
ctx[\`cp\`] = v_block3[i1];
const key1 = ctx['cp'].id;
const b5 = text(\`
\`);
const v1 = ctx['cp'];
const ctx1 = capture(ctx);
c_block1[i1] = withKey(comp2({onError: ()=>this.cleanUp(v1.id),slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx1}})}, key + \`__2__\${key1}\`, node, this, null), key1);
const b10 = comp2({onError: ()=>this.cleanUp(v1.id),slots: markRaw({'default': {__render: slot1, __ctx: ctx1}})}, key + \`__2__\${key1}\`, node, this, null);
const b11 = text(\`
\`);
c_block3[i1] = withKey(multi([b5, b10, b11]), key1);
}
return list(c_block1);
const b3 = list(c_block3);
return multi([b2, b3]);
}
}"
`;
@@ -1008,21 +1039,37 @@ exports[`can catch errors catching in child makes parent render 1`] = `
const comp2 = app.createComponent(\`Catch\`, true, true, false, false);
function slot1(ctx, node, key = \\"\\") {
const b7 = text(\`
\`);
const Comp1 = ctx['elem'][1];
return toggler(Comp1, comp1({id: ctx['elem'][0]}, key + \`__1\`, node, this, Comp1));
const b8 = toggler(Comp1, comp1({id: ctx['elem'][0]}, key + \`__1\`, node, this, Comp1));
const b9 = text(\`
\`);
return multi([b7, b8, b9]);
}
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(Object.entries(this.elements));;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`elem\`] = v_block1[i1];
const [k_block3, v_block3, l_block3, c_block3] = prepareList(Object.entries(this.elements));;
for (let i1 = 0; i1 < l_block3; i1++) {
ctx[\`elem\`] = v_block3[i1];
const key1 = ctx['elem'][0];
const b5 = text(\`
\`);
const v1 = ctx['elem'];
const ctx1 = capture(ctx);
c_block1[i1] = withKey(comp2({onError: (_error)=>this.onError(v1[0],_error),slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx1}})}, key + \`__2__\${key1}\`, node, this, null), key1);
const b10 = comp2({onError: (_error)=>this.onError(v1[0],_error),slots: markRaw({'default': {__render: slot1, __ctx: ctx1}})}, key + \`__2__\${key1}\`, node, this, null);
const b11 = text(\`
\`);
c_block3[i1] = withKey(multi([b5, b10, b11]), key1);
}
return list(c_block1);
ctx = ctx.__proto__;
const b3 = list(c_block3);
const b12 = text(\`
\`);
return multi([b2, b3, b12]);
}
}"
`;
@@ -1075,7 +1122,10 @@ exports[`can catch errors error in mounted on a component with a sibling (proper
const comp2 = app.createComponent(\`ErrorComponent\`, true, false, false, true);
const comp3 = app.createComponent(\`ErrorBoundary\`, true, true, false, true);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block1 = createBlock(\`<div>
<block-child-0/>
<block-child-1/>
</div>\`);
function slot1(ctx, node, key = \\"\\") {
return comp2({}, key + \`__2\`, node, this, null);
@@ -1083,7 +1133,7 @@ exports[`can catch errors error in mounted on a component with a sibling (proper
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({}, key + \`__1\`, node, this, null);
const b4 = comp3({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__3\`, node, this, null);
const b4 = comp3({slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__3\`, node, this, null);
return block1([], [b2, b4]);
}
}"
@@ -1106,7 +1156,9 @@ exports[`can catch errors error in mounted on a component with a sibling (proper
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { callSlot } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-1/></div>\`);
let block1 = createBlock(\`<div>
<block-child-0/><block-child-1/><block-child-1/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
@@ -1150,16 +1202,28 @@ exports[`can catch errors onError in class inheritance is called if rethrown 2`]
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
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 = \\"\\") {
let b2,b3;
let b2,b6;
if (!ctx['state'].error) {
b2 = text(this.will.crash);
const b3 = text(\`
\`);
const b4 = text(this.will.crash);
const b5 = text(\`
\`);
b2 = multi([b3, b4, b5]);
} else {
b3 = text(ctx['state'].error);
const b7 = text(\`
\`);
const b8 = text(ctx['state'].error);
const b9 = text(\`
\`);
b6 = multi([b7, b8, b9]);
}
return block1([], [b2, b3]);
return block1([], [b2, b6]);
}
}"
`;
@@ -1181,16 +1245,28 @@ exports[`can catch errors onError in class inheritance is not called if no rethr
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
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 = \\"\\") {
let b2,b3;
let b2,b6;
if (!ctx['state'].error) {
b2 = text(this.will.crash);
const b3 = text(\`
\`);
const b4 = text(this.will.crash);
const b5 = text(\`
\`);
b2 = multi([b3, b4, b5]);
} else {
b3 = text(ctx['state'].error);
const b7 = text(\`
\`);
const b8 = text(ctx['state'].error);
const b9 = text(\`
\`);
b6 = multi([b7, b8, b9]);
}
return block1([], [b2, b3]);
return block1([], [b2, b6]);
}
}"
`;
@@ -1377,16 +1453,3 @@ exports[`errors and promises errors in rerender 1`] = `
}
}"
`;
exports[`errors and promises wrapped errors in async code are correctly caught 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div>abc</div>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
@@ -58,34 +58,26 @@ exports[`event handling handler receive the event as argument 2`] = `
}"
`;
exports[`event handling handler works when app is mounted in an iframe 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<span block-handler-0=\\"click\\">click me</span>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [ctx['inc'], ctx];
return block1([hdlr1]);
}
}"
`;
exports[`event handling input blur event is not called if component is destroyed 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/><textarea/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<textarea/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2;
const b2 = text(\`
\`);
let b4;
if (ctx['state'].cond) {
b2 = comp1({}, key + \`__1\`, node, this, null);
b4 = comp1({}, key + \`__1\`, node, this, null);
}
return block1([], [b2]);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -110,22 +102,33 @@ exports[`event handling objects from scope are properly captured by t-on 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div class=\\"item\\" block-handler-0=\\"click\\"/>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block7 = createBlock(\`<div class=\\"item\\" block-handler-0=\\"click\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`item\`] = v_block4[i1];
const key1 = ctx['item'];
const b6 = text(\`
\`);
const v1 = ctx['onClick'];
const v2 = ctx['item'];
let hdlr1 = [_ev=>v1(v2.val,_ev), ctx];
c_block2[i1] = withKey(block3([hdlr1]), key1);
const b7 = block7([hdlr1]);
const b8 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -135,12 +138,15 @@ exports[`event handling support for callable expression in event handler 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/><input type=\\"text\\" block-handler-1=\\"input\\"/></div>\`);
let block3 = createBlock(\`<div><block-text-0/><input type=\\"text\\" block-handler-1=\\"input\\"/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['state'].value;
let hdlr1 = [ctx['obj'].onInput, ctx];
return block1([txt1, hdlr1]);
const b3 = block3([txt1, hdlr1]);
return multi([b2, b3]);
}
}"
`;
@@ -151,22 +157,33 @@ exports[`event handling t-on with handler bound to dynamic argument on a t-forea
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div class=\\"item\\" block-handler-0=\\"click\\"/>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block7 = createBlock(\`<div class=\\"item\\" block-handler-0=\\"click\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`item\`] = v_block4[i1];
const key1 = ctx['item'];
const b6 = text(\`
\`);
const v1 = ctx['onClick'];
const v2 = ctx['item'];
let hdlr1 = [_ev=>v1(v2,_ev), ctx];
c_block2[i1] = withKey(block3([hdlr1]), key1);
const b7 = block7([hdlr1]);
const b8 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -34,14 +34,24 @@ exports[`basics can select a sub widget 1`] = `
const comp2 = app.createComponent(\`OtherChild\`, true, false, false, true);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
let b2,b3,b4,b5,b6,b7,b8;
b2 = text(\`
\`);
b3 = text(\`
\`);
if (ctx['env'].options.flag) {
b2 = comp1({}, key + \`__1\`, node, this, null);
b4 = comp1({}, key + \`__1\`, node, this, null);
}
b5 = text(\`
\`);
if (!ctx['env'].options.flag) {
b3 = comp2({}, key + \`__2\`, node, this, null);
b6 = comp2({}, key + \`__2\`, node, this, null);
}
return multi([b2, b3]);
b7 = text(\`
\`);
b8 = text(\`
\`);
return multi([b2, b3, b4, b5, b6, b7, b8]);
}
}"
`;
@@ -80,14 +90,24 @@ exports[`basics can select a sub widget, part 2 1`] = `
const comp2 = app.createComponent(\`OtherChild\`, true, false, false, true);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
let b2,b3,b4,b5,b6,b7,b8;
b2 = text(\`
\`);
b3 = text(\`
\`);
if (ctx['state'].flag) {
b2 = comp1({}, key + \`__1\`, node, this, null);
b4 = comp1({}, key + \`__1\`, node, this, null);
}
b5 = text(\`
\`);
if (!ctx['state'].flag) {
b3 = comp2({}, key + \`__2\`, node, this, null);
b6 = comp2({}, key + \`__2\`, node, this, null);
}
return multi([b2, b3]);
b7 = text(\`
\`);
b8 = text(\`
\`);
return multi([b2, b3, b4, b5, b6, b7, b8]);
}
}"
`;
@@ -135,12 +155,17 @@ exports[`basics sub widget is interactive 2`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<span><button block-handler-0=\\"click\\">click</button>child<block-text-1/></span>\`);
let block3 = createBlock(\`<span>
<button block-handler-0=\\"click\\">click</button>child<block-text-1/>
</span>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let hdlr1 = [ctx['inc'], ctx];
let txt1 = ctx['state'].val;
return block1([hdlr1, txt1]);
const b3 = block3([hdlr1, txt1]);
return multi([b2, b3]);
}
}"
`;
@@ -5,18 +5,24 @@ exports[`hooks autofocus hook input in a t-if 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><input block-ref=\\"0\\"/><block-child-0/></div>\`);
let block2 = createBlock(\`<input block-ref=\\"0\\"/>\`);
let block3 = createBlock(\`<div>
<input block-ref=\\"0\\"/>
<block-child-0/>
</div>\`);
let block4 = createBlock(\`<input block-ref=\\"0\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`input1\`] = el;
const ref2 = (el) => refs[\`input2\`] = el;
let b2;
const b2 = text(\`
\`);
let b4;
if (ctx['state'].flag) {
b2 = block2([ref2]);
b4 = block4([ref2]);
}
return block1([ref1], [b2]);
const b3 = block3([ref1], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -26,13 +32,19 @@ exports[`hooks autofocus hook simple input 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><input block-ref=\\"0\\"/><input block-ref=\\"1\\"/></div>\`);
let block3 = createBlock(\`<div>
<input block-ref=\\"0\\"/>
<input block-ref=\\"1\\"/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`input1\`] = el;
const ref2 = (el) => refs[\`input2\`] = el;
return block1([ref1, ref2]);
const b2 = text(\`
\`);
const b3 = block3([ref1, ref2]);
return multi([b2, b3]);
}
}"
`;
@@ -265,16 +277,23 @@ exports[`hooks useEffect hook effect can depend on stuff in dom 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block2 = createBlock(\`<div block-ref=\\"0\\"/>\`);
let block5 = createBlock(\`<div block-ref=\\"0\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`div\`] = el;
let b2;
let b2,b3;
b2 = text(\`
\`);
if (ctx['state'].value) {
b2 = block2([ref1]);
const b4 = text(\`
\`);
const b5 = block5([ref1]);
const b6 = text(\`
\`);
b3 = multi([b4, b5, b6]);
}
return multi([b2]);
return multi([b2, b3]);
}
}"
`;
@@ -357,7 +376,7 @@ exports[`hooks useRef hook: basic use 1`] = `
let block1 = createBlock(\`<div><button block-ref=\\"0\\"><block-text-1/></button></div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`button\`] = el;
let txt1 = ctx['value'];
return block1([ref1, txt1]);
@@ -51,17 +51,22 @@ exports[`lifecycle hooks component semantics 3`] = `
const comp2 = app.createComponent(\`E\`, true, false, false, true);
const comp3 = app.createComponent(\`F\`, true, false, false, true);
let block1 = createBlock(\`<div>C<block-child-0/><block-child-1/><block-child-2/></div>\`);
let block3 = createBlock(\`<div>C<block-child-0/>
<block-child-1/><block-child-2/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3,b4;
b2 = comp1({}, key + \`__1\`, node, this, null);
const b2 = text(\`
\`);
let b4,b5,b6;
b4 = comp1({}, key + \`__1\`, node, this, null);
if (ctx['state'].flag) {
b3 = comp2({}, key + \`__2\`, node, this, null);
b5 = comp2({}, key + \`__2\`, node, this, null);
} else {
b4 = comp3({}, key + \`__3\`, node, this, null);
b6 = comp3({}, key + \`__3\`, node, this, null);
}
return block1([], [b2, b3, b4]);
const b3 = block3([], [b4, b5, b6]);
return multi([b2, b3]);
}
}"
`;
@@ -111,15 +116,21 @@ exports[`lifecycle hooks components are unmounted and destroyed if no longer in
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block2 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2;
let b2,b3,b5;
b2 = text(\`
\`);
if (ctx['state'].flag) {
const b3 = comp1({n: ctx['state'].n}, key + \`__1\`, node, this, null);
b2 = block2([], [b3]);
const b4 = comp1({n: ctx['state'].n}, key + \`__1\`, node, this, null);
b3 = block3([], [b4]);
}
return multi([b2]);
b5 = text(\`
\`);
return multi([b2, b3, b5]);
}
}"
`;
@@ -550,7 +561,10 @@ exports[`lifecycle hooks onWillRender 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
return comp1({someValue: ctx['state'].value}, key + \`__1\`, node, this, null);
const b2 = text(\`
\`);
const b3 = comp1({someValue: ctx['state'].value}, key + \`__1\`, node, this, null);
return multi([b2, b3]);
}
}"
`;
@@ -704,7 +718,7 @@ exports[`lifecycle hooks timeout in onWillUpdateProps emits a warning 1`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {prop: ctx['state'].prop};
helpers.validateProps(\`Child\`, props1, this);
helpers.validateProps(\`Child\`, props1, ctx);
return comp1(props1, key + \`__1\`, node, this, null);
}
}"
@@ -727,11 +741,16 @@ exports[`lifecycle hooks willPatch, patched hook are called on subsubcomponents,
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({n: ctx['state'].n}, key + \`__1\`, node, this, null);
return block1([], [b2]);
const b2 = text(\`
\`);
const b4 = comp1({n: ctx['state'].n}, key + \`__1\`, node, this, null);
const b3 = block3([], [b4]);
const b5 = text(\`
\`);
return multi([b2, b3, b5]);
}
}"
`;
@@ -742,11 +761,16 @@ exports[`lifecycle hooks willPatch, patched hook are called on subsubcomponents,
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`ChildChild\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({n: ctx['props'].n}, key + \`__1\`, node, this, null);
return block1([], [b2]);
const b2 = text(\`
\`);
const b4 = comp1({n: ctx['props'].n}, key + \`__1\`, node, this, null);
const b3 = block3([], [b4]);
const b5 = text(\`
\`);
return multi([b2, b3, b5]);
}
}"
`;
@@ -756,11 +780,16 @@ exports[`lifecycle hooks willPatch, patched hook are called on subsubcomponents,
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
let block3 = createBlock(\`<div><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['props'].n;
return block1([txt1]);
const b3 = block3([txt1]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -822,17 +851,32 @@ exports[`lifecycle hooks willStart, mounted on subwidget rendered after main is
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block3 = createBlock(\`<div/>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/>
</div>\`);
let block10 = createBlock(\`<div/>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b8;
if (ctx['state'].ok) {
b2 = comp1({}, key + \`__1\`, node, this, null);
const b5 = text(\`
\`);
const b6 = comp1({}, key + \`__1\`, node, this, null);
const b7 = text(\`
\`);
b4 = multi([b5, b6, b7]);
} else {
b3 = block3();
const b9 = text(\`
\`);
const b10 = block10();
const b11 = text(\`
\`);
b8 = multi([b9, b10, b11]);
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b8]);
return multi([b2, b3]);
}
}"
`;
@@ -37,16 +37,27 @@ exports[`basics arrow functions as prop correctly capture their scope 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`item\`] = v_block1[i1];
const [k_block3, v_block3, l_block3, c_block3] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block3; i1++) {
ctx[\`item\`] = v_block3[i1];
const key1 = ctx['item'].val;
const b5 = text(\`
\`);
const v1 = ctx['onClick'];
const v2 = ctx['item'];
c_block1[i1] = withKey(comp1({onClick: _ev=>v1(v2.val,_ev)}, key + \`__1__\${key1}\`, node, this, null), key1);
const b6 = comp1({onClick: _ev=>v1(v2.val,_ev)}, key + \`__1__\${key1}\`, node, this, null);
const b7 = text(\`
\`);
c_block3[i1] = withKey(multi([b5, b6, b7]), key1);
}
return list(c_block1);
ctx = ctx.__proto__;
const b3 = list(c_block3);
const b8 = text(\`
\`);
return multi([b2, b3, b8]);
}
}"
`;
@@ -153,19 +164,25 @@ exports[`basics t-set with a body expression can be passed in props, and then t-
let { isBoundary, withDefault, LazyValue } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<p>43</p>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block4 = createBlock(\`<p>43</p>\`);
function value1(ctx, node, key = \\"\\") {
return block2();
return block4();
}
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`abc\`] = new LazyValue(value1, ctx, this, node, key);
const b3 = comp1({val: ctx['abc']}, key + \`__1\`, node, this, null);
return block1([], [b3]);
const b2 = text(\`
\`);
ctx[\`abc\`] = new LazyValue(value1, ctx, this, node);
const b5 = comp1({val: ctx['abc']}, key + \`__1\`, node, this, null);
const b3 = block3([], [b5]);
return multi([b2, b3]);
}
}"
`;
@@ -176,12 +193,18 @@ exports[`basics t-set with a body expression can be passed in props, and then t-
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-text-0/><block-child-0/></span>\`);
let block3 = createBlock(\`<span>
<block-text-0/>
<block-child-0/>
</span>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['props'].val;
const b2 = safeOutput(ctx['props'].val);
return block1([txt1], [b2]);
const b4 = safeOutput(ctx['props'].val);
const b3 = block3([txt1], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -193,14 +216,20 @@ exports[`basics t-set with a body expression can be used as textual prop 1`] = `
let { isBoundary, withDefault, setContextValue } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"abc\\", \`42\`);
const b2 = comp1({val: ctx['abc']}, key + \`__1\`, node, this, null);
return block1([], [b2]);
const b4 = comp1({val: ctx['abc']}, key + \`__1\`, node, this, null);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -226,14 +255,20 @@ exports[`basics t-set works 1`] = `
let { isBoundary, withDefault, setContextValue } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"val\\", 42);
const b2 = comp1({val: ctx['val']}, key + \`__1\`, node, this, null);
return block1([], [b2]);
const b4 = comp1({val: ctx['val']}, key + \`__1\`, node, this, null);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -283,7 +318,7 @@ exports[`bound functions is referentially equal after update 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
return comp1({val: ctx['state'].val,fn: bind(this, ctx['someFunction'])}, key + \`__1\`, node, this, null);
return comp1({val: ctx['state'].val,fn: bind(ctx, ctx['someFunction'])}, key + \`__1\`, node, this, null);
}
}"
`;
@@ -307,7 +342,7 @@ exports[`can bind function prop with bind suffix 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
return comp1({doSomething: bind(this, ctx['doSomething'])}, key + \`__1\`, node, this, null);
return comp1({doSomething: bind(ctx, ctx['doSomething'])}, key + \`__1\`, node, this, null);
}
}"
`;
@@ -8,7 +8,7 @@ exports[`default props a default prop cannot be defined on a mandatory prop 1`]
return function template(ctx, node, key = \\"\\") {
const props1 = {};
helpers.validateProps(\`Child\`, props1, this);
helpers.validateProps(\`Child\`, props1, ctx);
return comp1(props1, key + \`__1\`, node, this, null);
}
}"
@@ -24,7 +24,7 @@ exports[`default props can set default boolean values 1`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -61,7 +61,7 @@ exports[`default props can set default values 1`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -92,7 +92,7 @@ exports[`default props default values are also set whenever component is updated
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['state'].p};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -121,7 +121,7 @@ exports[`props validation can specify that additional props are allowed (array)
return function template(ctx, node, key = \\"\\") {
const props1 = {message: 'm',otherProp: 'o'};
helpers.validateProps(\`Child\`, props1, this);
helpers.validateProps(\`Child\`, props1, ctx);
return comp1(props1, key + \`__1\`, node, this, null);
}
}"
@@ -148,7 +148,7 @@ exports[`props validation can specify that additional props are allowed (object)
return function template(ctx, node, key = \\"\\") {
const props1 = {message: 'm',otherProp: 'o'};
helpers.validateProps(\`Child\`, props1, this);
helpers.validateProps(\`Child\`, props1, ctx);
return comp1(props1, key + \`__1\`, node, this, null);
}
}"
@@ -177,7 +177,7 @@ exports[`props validation can validate a prop with multiple types 1`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -207,7 +207,7 @@ exports[`props validation can validate a prop with multiple types 3`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -237,7 +237,7 @@ exports[`props validation can validate a prop with multiple types 5`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -254,7 +254,7 @@ exports[`props validation can validate an array with given primitive type 1`] =
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -284,7 +284,7 @@ exports[`props validation can validate an array with given primitive type 3`] =
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -314,7 +314,7 @@ exports[`props validation can validate an array with given primitive type 5`] =
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -331,7 +331,7 @@ exports[`props validation can validate an array with given primitive type 6`] =
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -348,7 +348,7 @@ exports[`props validation can validate an array with multiple sub element types
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -378,7 +378,7 @@ exports[`props validation can validate an array with multiple sub element types
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -408,7 +408,7 @@ exports[`props validation can validate an array with multiple sub element types
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -438,7 +438,7 @@ exports[`props validation can validate an array with multiple sub element types
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -455,7 +455,7 @@ exports[`props validation can validate an object with simple shape 1`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -485,7 +485,7 @@ exports[`props validation can validate an object with simple shape 3`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -502,7 +502,7 @@ exports[`props validation can validate an object with simple shape 4`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -519,7 +519,7 @@ exports[`props validation can validate an object with simple shape 5`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -536,7 +536,7 @@ exports[`props validation can validate an optional props 1`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -566,7 +566,7 @@ exports[`props validation can validate an optional props 3`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -596,7 +596,7 @@ exports[`props validation can validate an optional props 5`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -613,7 +613,7 @@ exports[`props validation can validate recursively complicated prop def 1`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -643,7 +643,7 @@ exports[`props validation can validate recursively complicated prop def 3`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -673,47 +673,13 @@ exports[`props validation can validate recursively complicated prop def 5`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
}"
`;
exports[`props validation can validate through slots 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { markRaw } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
const comp2 = app.createComponent(\`Wrapper\`, true, true, false, true);
function slot1(ctx, node, key = \\"\\") {
const props1 = {};
helpers.validateProps(\`Child\`, props1, this);
return comp1(props1, key + \`__1\`, node, this, null);
}
return function template(ctx, node, key = \\"\\") {
const props2 = {slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx}})};
helpers.validateProps(\`Wrapper\`, props2, this);
return comp2(props2, key + \`__2\`, node, this, null);
}
}"
`;
exports[`props validation can validate through slots 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { callSlot } = helpers;
return function template(ctx, node, key = \\"\\") {
return callSlot(ctx, node, key, 'default', false, {});
}
}"
`;
exports[`props validation default values are applied before validating props at update 1`] = `
"function anonymous(app, bdom, helpers
) {
@@ -724,7 +690,7 @@ exports[`props validation default values are applied before validating props at
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['state'].p};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -755,7 +721,7 @@ exports[`props validation missing required boolean prop causes an error 1`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -772,7 +738,7 @@ exports[`props validation mix of optional and mandatory 1`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {};
helpers.validateProps(\`Child\`, props1, this);
helpers.validateProps(\`Child\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -789,7 +755,7 @@ exports[`props validation props are validated in dev mode (code snapshot) 1`] =
return function template(ctx, node, key = \\"\\") {
const props1 = {message: 1};
helpers.validateProps(\`Child\`, props1, this);
helpers.validateProps(\`Child\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -820,7 +786,7 @@ exports[`props validation props are validated whenever component is updated 1`]
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['state'].p};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -851,7 +817,7 @@ exports[`props validation props: list of strings 1`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -868,7 +834,7 @@ exports[`props validation validate simple types 1`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -885,7 +851,7 @@ exports[`props validation validate simple types 2`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -915,7 +881,7 @@ exports[`props validation validate simple types 4`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -932,7 +898,7 @@ exports[`props validation validate simple types 5`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -949,7 +915,7 @@ exports[`props validation validate simple types 6`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -979,7 +945,7 @@ exports[`props validation validate simple types 8`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -996,7 +962,7 @@ exports[`props validation validate simple types 9`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1013,7 +979,7 @@ exports[`props validation validate simple types 10`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1043,7 +1009,7 @@ exports[`props validation validate simple types 12`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1060,7 +1026,7 @@ exports[`props validation validate simple types 13`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1077,7 +1043,7 @@ exports[`props validation validate simple types 14`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1107,7 +1073,7 @@ exports[`props validation validate simple types 16`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1124,7 +1090,7 @@ exports[`props validation validate simple types 17`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1141,7 +1107,7 @@ exports[`props validation validate simple types 18`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1171,7 +1137,7 @@ exports[`props validation validate simple types 20`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1188,7 +1154,7 @@ exports[`props validation validate simple types 21`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1205,7 +1171,7 @@ exports[`props validation validate simple types 22`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1235,7 +1201,7 @@ exports[`props validation validate simple types 24`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1252,7 +1218,7 @@ exports[`props validation validate simple types, alternate form 1`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1269,7 +1235,7 @@ exports[`props validation validate simple types, alternate form 2`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1299,7 +1265,7 @@ exports[`props validation validate simple types, alternate form 4`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1316,7 +1282,7 @@ exports[`props validation validate simple types, alternate form 5`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1333,7 +1299,7 @@ exports[`props validation validate simple types, alternate form 6`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1363,7 +1329,7 @@ exports[`props validation validate simple types, alternate form 8`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1380,7 +1346,7 @@ exports[`props validation validate simple types, alternate form 9`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1397,7 +1363,7 @@ exports[`props validation validate simple types, alternate form 10`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1427,7 +1393,7 @@ exports[`props validation validate simple types, alternate form 12`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1444,7 +1410,7 @@ exports[`props validation validate simple types, alternate form 13`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1461,7 +1427,7 @@ exports[`props validation validate simple types, alternate form 14`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1491,7 +1457,7 @@ exports[`props validation validate simple types, alternate form 16`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1508,7 +1474,7 @@ exports[`props validation validate simple types, alternate form 17`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1525,7 +1491,7 @@ exports[`props validation validate simple types, alternate form 18`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1555,7 +1521,7 @@ exports[`props validation validate simple types, alternate form 20`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1572,7 +1538,7 @@ exports[`props validation validate simple types, alternate form 21`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1589,7 +1555,7 @@ exports[`props validation validate simple types, alternate form 22`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1619,7 +1585,7 @@ exports[`props validation validate simple types, alternate form 24`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {p: ctx['p']};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -1636,7 +1602,7 @@ exports[`props validation validation is only done in dev mode 1`] = `
return function template(ctx, node, key = \\"\\") {
const props1 = {};
helpers.validateProps(\`SubComp\`, props1, this);
helpers.validateProps(\`SubComp\`, props1, ctx);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
return block1([], [b2]);
}
@@ -99,11 +99,16 @@ exports[`reactivity in lifecycle change state while mounting component 1`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
let block3 = createBlock(\`<div><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['state'].val;
return block1([txt1]);
const b3 = block3([txt1]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -114,14 +119,21 @@ exports[`reactivity in lifecycle state changes in willUnmount do not trigger rer
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2;
const b2 = text(\`
\`);
let b4;
if (ctx['state'].flag) {
b2 = comp1({val: ctx['state'].val}, key + \`__1\`, node, this, null);
b4 = comp1({val: ctx['state'].val}, key + \`__1\`, node, this, null);
}
return block1([], [b2]);
const b3 = block3([], [b4]);
const b5 = text(\`
\`);
return multi([b2, b3, b5]);
}
}"
`;
@@ -131,12 +143,17 @@ exports[`reactivity in lifecycle state changes in willUnmount do not trigger rer
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/><block-text-1/></span>\`);
let block3 = createBlock(\`<span><block-text-0/><block-text-1/></span>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['props'].val;
let txt2 = ctx['state'].n;
return block1([txt1, txt2]);
const b3 = block3([txt1, txt2]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -8,7 +8,7 @@ exports[`refs basic use 1`] = `
let block1 = createBlock(\`<div block-ref=\\"0\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`div\`] = el;
return block1([ref1]);
}
@@ -21,19 +21,31 @@ exports[`refs can use 2 refs with same name in a t-if/t-else situation 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { multiRefSetter } = helpers;
let block2 = createBlock(\`<div block-ref=\\"0\\"/>\`);
let block3 = createBlock(\`<span block-ref=\\"0\\"/>\`);
let block5 = createBlock(\`<div block-ref=\\"0\\"/>\`);
let block9 = createBlock(\`<span block-ref=\\"0\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = multiRefSetter(refs, \`coucou\`);
let b2,b3;
let b2,b3,b7;
b2 = text(\`
\`);
if (ctx['state'].value) {
b2 = block2([ref1]);
const b4 = text(\`
\`);
const b5 = block5([ref1]);
const b6 = text(\`
\`);
b3 = multi([b4, b5, b6]);
} else {
b3 = block3([ref1]);
const b8 = text(\`
\`);
const b9 = block9([ref1]);
const b10 = text(\`
\`);
b7 = multi([b8, b9, b10]);
}
return multi([b2, b3]);
return multi([b2, b3, b7]);
}
}"
`;
@@ -44,17 +56,23 @@ exports[`refs refs and recursive templates 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Test\`, true, false, false, false);
let block1 = createBlock(\`<p block-ref=\\"0\\"><block-text-1/><block-child-0/></p>\`);
let block3 = createBlock(\`<p block-ref=\\"0\\">
<block-text-1/>
<block-child-0/>
</p>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`root\`] = el;
let b2;
const b2 = text(\`
\`);
let b4;
let txt1 = ctx['props'].tree.value;
if (ctx['props'].tree.child) {
b2 = comp1({tree: ctx['props'].tree.child}, key + \`__1\`, node, this, null);
b4 = comp1({tree: ctx['props'].tree.child}, key + \`__1\`, node, this, null);
}
return block1([ref1, txt1], [b2]);
const b3 = block3([ref1, txt1], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -66,21 +84,37 @@ exports[`refs refs are properly bound in slots 1`] = `
let { capture, markRaw } = helpers;
const comp1 = app.createComponent(\`Dialog\`, true, true, false, true);
let block1 = createBlock(\`<div><span class=\\"counter\\"><block-text-0/></span><block-child-0/></div>\`);
let block2 = createBlock(\`<button block-handler-0=\\"click\\" block-ref=\\"1\\">do something</button>\`);
let block3 = createBlock(\`<div>
<span class=\\"counter\\"><block-text-0/></span>
<block-child-0/>
</div>\`);
let block4 = createBlock(\`<button block-handler-0=\\"click\\" block-ref=\\"1\\">do something</button>\`);
function slot1(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`myButton\`] = el;
let hdlr1 = [ctx['doSomething'], ctx];
return block2([hdlr1, ref1]);
return block4([hdlr1, ref1]);
}
function slot2(ctx, node, key = \\"\\") {
const b6 = text(\`
\`);
const b7 = text(\`
\`);
return multi([b6, b7]);
}
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['state'].val;
const ctx1 = capture(ctx);
const b3 = comp1({slots: markRaw({'footer': {__render: slot1.bind(this), __ctx: ctx1}})}, key + \`__1\`, node, this, null);
return block1([txt1], [b3]);
const b8 = comp1({slots: markRaw({'footer': {__render: slot1, __ctx: ctx1}, 'default': {__render: slot2, __ctx: ctx1}})}, key + \`__1\`, node, this, null);
const b3 = block3([txt1], [b8]);
const b9 = text(\`
\`);
return multi([b2, b3, b9]);
}
}"
`;
@@ -106,15 +140,19 @@ exports[`refs throws if there are 2 same refs at the same time 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { multiRefSetter } = helpers;
let block2 = createBlock(\`<div block-ref=\\"0\\"/>\`);
let block3 = createBlock(\`<span block-ref=\\"0\\"/>\`);
let block3 = createBlock(\`<div block-ref=\\"0\\"/>\`);
let block5 = createBlock(\`<span block-ref=\\"0\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const ref1 = multiRefSetter(refs, \`coucou\`);
const b2 = block2([ref1]);
const b2 = text(\`
\`);
const b3 = block3([ref1]);
return multi([b2, b3]);
const b4 = text(\`
\`);
const b5 = block5([ref1]);
return multi([b2, b3, b4, b5]);
}
}"
`;
@@ -7,9 +7,15 @@ exports[`children, default props and renderings 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
return function template(ctx, node, key = \\"\\") {
const b2 = text(ctx['state'].value);
const b3 = comp1({}, key + \`__1\`, node, this, null);
return multi([b2, b3]);
const b2 = text(\`
\`);
const b3 = text(ctx['state'].value);
const b4 = text(\`
\`);
const b5 = comp1({}, key + \`__1\`, node, this, null);
const b6 = text(\`
\`);
return multi([b2, b3, b4, b5, b6]);
}
}"
`;
@@ -69,9 +75,15 @@ exports[`rendering semantics can force a render to update sub tree 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
return function template(ctx, node, key = \\"\\") {
const b2 = text(ctx['state'].value);
const b3 = comp1({}, key + \`__1\`, node, this, null);
return multi([b2, b3]);
const b2 = text(\`
\`);
const b3 = text(ctx['state'].value);
const b4 = text(\`
\`);
const b5 = comp1({}, key + \`__1\`, node, this, null);
const b6 = text(\`
\`);
return multi([b2, b3, b4, b5, b6]);
}
}"
`;
@@ -94,9 +106,15 @@ exports[`rendering semantics can render a parent without rendering child 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
return function template(ctx, node, key = \\"\\") {
const b2 = text(ctx['state'].value);
const b3 = comp1({}, key + \`__1\`, node, this, null);
return multi([b2, b3]);
const b2 = text(\`
\`);
const b3 = text(ctx['state'].value);
const b4 = text(\`
\`);
const b5 = comp1({}, key + \`__1\`, node, this, null);
const b6 = text(\`
\`);
return multi([b2, b3, b4, b5, b6]);
}
}"
`;
@@ -119,7 +137,12 @@ exports[`rendering semantics props are reactive (nested prop) 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
return comp1({a: ctx['state']}, key + \`__1\`, node, this, null);
const b2 = text(\`
\`);
const b3 = comp1({a: ctx['state']}, key + \`__1\`, node, this, null);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -142,7 +165,12 @@ exports[`rendering semantics props are reactive 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
return comp1({a: ctx['state']}, key + \`__1\`, node, this, null);
const b2 = text(\`
\`);
const b3 = comp1({a: ctx['state']}, key + \`__1\`, node, this, null);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -165,9 +193,15 @@ exports[`rendering semantics render need a boolean = true to be 'deep' 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
return function template(ctx, node, key = \\"\\") {
const b2 = text(ctx['state'].value);
const b3 = comp1({}, key + \`__1\`, node, this, null);
return multi([b2, b3]);
const b2 = text(\`
\`);
const b3 = text(ctx['state'].value);
const b4 = text(\`
\`);
const b5 = comp1({}, key + \`__1\`, node, this, null);
const b6 = text(\`
\`);
return multi([b2, b3, b4, b5, b6]);
}
}"
`;
@@ -255,7 +289,12 @@ exports[`rendering semantics works as expected for dynamic number of props 1`] =
const comp1 = app.createComponent(\`Child\`, true, false, true, false);
return function template(ctx, node, key = \\"\\") {
return comp1(Object.assign({}, ctx['state']), key + \`__1\`, node, this, null);
const b2 = text(\`
\`);
const b3 = comp1(Object.assign({}, ctx['state']), key + \`__1\`, node, this, null);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
File diff suppressed because it is too large Load Diff
@@ -124,10 +124,15 @@ exports[`style and class handling can set style and class inside component 1`] =
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div style=\\"font-weight:bold;\\" class=\\"some-class\\">world</div>\`);
let block3 = createBlock(\`<div style=\\"font-weight:bold;\\" class=\\"some-class\\">world</div>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
const b2 = text(\`
\`);
const b3 = block3();
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -452,11 +457,16 @@ exports[`style and class handling t-att-class is properly added/removed on widge
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({class: {b:ctx['state'].b}}, key + \`__1\`, node, this, null);
return block1([], [b2]);
const b2 = text(\`
\`);
const b4 = comp1({class: {b:ctx['state'].b}}, key + \`__1\`, node, this, null);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
+102 -194
View File
@@ -8,12 +8,17 @@ exports[`t-call dynamic t-call 1`] = `
const call = app.callTemplate.bind(app);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
ctx[isBoundary] = 1;
const b1 = text(\` owl \`);
ctx[zero] = b1;
const b3 = text(\`
owl
\`);
ctx[zero] = b3;
const template1 = (ctx['current'].template);
return call(this, template1, ctx, node, key + \`__1\`);
const b4 = call(this, template1, ctx, node, key + \`__1\`);
return multi([b2, b4]);
}
}"
`;
@@ -90,13 +95,16 @@ exports[`t-call handlers are properly bound through a dynamic t-call 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const call = app.callTemplate.bind(app);
let block1 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`);
let block3 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const template1 = ('__template__999');
const b2 = call(this, template1, ctx, node, key + \`__1\`);
const b4 = call(this, template1, ctx, node, key + \`__1\`);
let txt1 = ctx['counter'];
return block1([txt1], [b2]);
const b3 = block3([txt1], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -121,12 +129,15 @@ exports[`t-call handlers are properly bound through a t-call 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`__template__999\`);
let block1 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`);
let block3 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
const b2 = text(\`
\`);
const b4 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
let txt1 = ctx['counter'];
return block1([txt1], [b2]);
const b3 = block3([txt1], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -259,16 +270,22 @@ exports[`t-call recursive t-call binding this -- static t-call 1`] = `
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`recursive\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
ctx = Object.create(ctx);
ctx[isBoundary] = 1;
setContextValue(ctx, \\"level\\", 0);
const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
return block1([], [b2]);
const b4 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
ctx = ctx.__proto__;
const b3 = block3([], [b4]);
const b5 = text(\`
\`);
return multi([b2, b3, b5]);
}
}"
`;
@@ -277,27 +294,43 @@ exports[`t-call recursive t-call binding this -- static t-call 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let { isBoundary, withDefault, setContextValue, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`recursive\`);
let block3 = createBlock(\`<div block-handler-0=\\"click.stop\\"><block-text-1/></div>\`);
let block5 = createBlock(\`<div block-handler-0=\\"click.stop\\"><block-text-1/></div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
let b2;
let b2,b3,b12;
b2 = text(\`
\`);
if (ctx['level']<2) {
const b4 = text(\`
\`);
let hdlr1 = [\\"stop\\", ctx['onClicked'].bind(this), ctx];
let txt1 = ctx['level'];
const b3 = block3([hdlr1, txt1]);
const b5 = block5([hdlr1, txt1]);
const b6 = text(\`
\`);
ctx = Object.create(ctx);
ctx[isBoundary] = 1;
const b8 = text(\`
\`);
setContextValue(ctx, \\"level\\", ctx['level']+1);
const b4 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
const b9 = text(\`
\`);
const b7 = multi([b8, b9]);
ctx[zero] = b7;
const b10 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
ctx = ctx.__proto__;
b2 = multi([b3, b4]);
const b11 = text(\`
\`);
b3 = multi([b4, b5, b6, b10, b11]);
}
return multi([b2]);
b12 = text(\`
\`);
return multi([b2, b3, b12]);
}
}"
`;
@@ -309,17 +342,24 @@ exports[`t-call sub components in two t-calls 1`] = `
const callTemplate_1 = app.getTemplate(\`sub\`);
const callTemplate_2 = app.getTemplate(\`sub\`);
let block3 = createBlock(\`<div><block-child-0/></div>\`);
let block7 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
let b2,b3,b7;
b2 = text(\`
\`);
if (ctx['state'].val===1) {
b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
const b4 = text(\`
\`);
const b5 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
const b6 = text(\`
\`);
b3 = multi([b4, b5, b6]);
} else {
const b4 = callTemplate_2.call(this, ctx, node, key + \`__2\`);
b3 = block3([], [b4]);
const b8 = callTemplate_2.call(this, ctx, node, key + \`__2\`);
b7 = block7([], [b8]);
}
return multi([b2, b3]);
return multi([b2, b3, b7]);
}
}"
`;
@@ -357,22 +397,33 @@ exports[`t-call t-call in t-foreach and children component 1`] = `
let { prepareList, withKey } = helpers;
const callTemplate_1 = app.getTemplate(\`__template__999\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(['a','b','c']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(['a','b','c']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`val\`] = v_block4[i1];
ctx[\`val_first\`] = i1 === 0;
ctx[\`val_last\`] = i1 === v_block2.length - 1;
ctx[\`val_last\`] = i1 === v_block4.length - 1;
ctx[\`val_index\`] = i1;
ctx[\`val_value\`] = k_block2[i1];
ctx[\`val_value\`] = k_block4[i1];
const key1 = ctx['val'];
c_block2[i1] = withKey(callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`), key1);
const b6 = text(\`
\`);
const b7 = callTemplate_1.call(this, ctx, node, key + \`__1__\${key1}\`);
const b8 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -410,8 +461,11 @@ exports[`t-call t-call with t-call-context and subcomponent 1`] = `
const callTemplate_1 = app.getTemplate(\`someTemplate\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let ctx1 = ctx['subctx'];
return callTemplate_1.call(this, ctx1, node, key + \`__1\`);
const b3 = callTemplate_1.call(this, ctx1, node, key + \`__1\`);
return multi([b2, b3]);
}
}"
`;
@@ -424,9 +478,15 @@ exports[`t-call t-call with t-call-context and subcomponent 2`] = `
const comp2 = app.createComponent(\`Child\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({name: ctx['aab']}, key + \`__1\`, node, this, null);
const b3 = comp2({name: ctx['lpe']}, key + \`__2\`, node, this, null);
return multi([b2, b3]);
const b2 = text(\`
\`);
const b3 = comp1({name: ctx['aab']}, key + \`__1\`, node, this, null);
const b4 = text(\`
\`);
const b5 = comp2({name: ctx['lpe']}, key + \`__2\`, node, this, null);
const b6 = text(\`
\`);
return multi([b2, b3, b4, b5, b6]);
}
}"
`;
@@ -444,51 +504,6 @@ exports[`t-call t-call with t-call-context and subcomponent 3`] = `
}"
`;
exports[`t-call t-call with t-call-context and subcomponent, in dev mode 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`someTemplate\`);
return function template(ctx, node, key = \\"\\") {
let ctx1 = ctx['subctx'];
return callTemplate_1.call(this, ctx1, node, key + \`__1\`);
}
}"
`;
exports[`t-call t-call with t-call-context and subcomponent, in dev mode 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
const comp2 = app.createComponent(\`Child\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
const props1 = {name: ctx['aab']};
helpers.validateProps(\`Child\`, props1, this);
const b2 = comp1(props1, key + \`__1\`, node, this, null);
const props2 = {name: ctx['lpe']};
helpers.validateProps(\`Child\`, props2, this);
const b3 = comp2(props2, key + \`__2\`, node, this, null);
return multi([b2, b3]);
}
}"
`;
exports[`t-call t-call with t-call-context and subcomponent, in dev mode 3`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`child\`);
const b3 = text(ctx['props'].name);
return multi([b2, b3]);
}
}"
`;
exports[`t-call t-call with t-call-context, simple use 1`] = `
"function anonymous(app, bdom, helpers
) {
@@ -496,8 +511,11 @@ exports[`t-call t-call with t-call-context, simple use 1`] = `
const callTemplate_1 = app.getTemplate(\`someTemplate\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let ctx1 = ctx['subctx'];
return callTemplate_1.call(this, ctx1, node, key + \`__1\`);
const b3 = callTemplate_1.call(this, ctx1, node, key + \`__1\`);
return multi([b2, b3]);
}
}"
`;
@@ -514,113 +532,3 @@ exports[`t-call t-call with t-call-context, simple use 2`] = `
}
}"
`;
exports[`t-call t-call-context: ComponentNode is not looked up in the context 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`someTemplate\`);
return function template(ctx, node, key = \\"\\") {
let ctx1 = {method:function(){}};
return callTemplate_1.call(this, ctx1, node, key + \`__1\`);
}
}"
`;
exports[`t-call t-call-context: ComponentNode is not looked up in the context 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { bind, capture, isBoundary, withDefault, setContextValue, markRaw } = helpers;
const comp1 = app.createComponent(\`Child\`, true, true, false, false);
let block2 = createBlock(\`<div block-ref=\\"0\\">outside slot</div>\`);
let block4 = createBlock(\`<div block-ref=\\"0\\">I'm the default slot</div>\`);
let block5 = createBlock(\`<div><block-text-0/></div>\`);
let block6 = createBlock(\`<div><block-text-0/></div>\`);
function slot1(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const ref2 = (el) => refs[\`myRef2\`] = el;
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b4 = block4([ref2]);
setContextValue(ctx, \\"test\\", 3);
let txt1 = this.__owl__.name;
const b5 = block5([txt1]);
let txt2 = ctx['test'];
const b6 = block6([txt2]);
return multi([b4, b5, b6]);
}
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const ref1 = (el) => refs[\`myRef\`] = el;
const b2 = block2([ref1]);
const ctx1 = capture(ctx);
const b7 = comp1({prop: bind(this, ctx['method']),slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx1}})}, key + \`__1\`, node, this, null);
return multi([b2, b7]);
}
}"
`;
exports[`t-call t-call-context: ComponentNode is not looked up in the context 3`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { callSlot } = helpers;
return function template(ctx, node, key = \\"\\") {
return callSlot(ctx, node, key, 'default', false, {});
}
}"
`;
exports[`t-call t-call-context: slots don't make component available again when context is captured 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`template\`);
return function template(ctx, node, key = \\"\\") {
let ctx1 = {};
return callTemplate_1.call(this, ctx1, node, key + \`__1\`);
}
}"
`;
exports[`t-call t-call-context: slots don't make component available again when context is captured 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue, capture, markRaw } = helpers;
const comp1 = app.createComponent(\`Child\`, true, true, false, true);
function slot1(ctx, node, key = \\"\\") {
return text(ctx['someValue']);
}
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
setContextValue(ctx, \\"dummy\\", 0);
const ctx1 = capture(ctx);
const props1 = {slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx1}})};
helpers.validateProps(\`Child\`, props1, this);
return comp1(props1, key + \`__1\`, node, this, null);
}
}"
`;
exports[`t-call t-call-context: slots don't make component available again when context is captured 3`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { callSlot } = helpers;
return function template(ctx, node, key = \\"\\") {
return callSlot(ctx, node, key, 'default', false, {});
}
}"
`;
@@ -6,12 +6,17 @@ exports[`t-component can switch between dynamic components without the need for
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(null, false, false, false, true);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const Comp1 = ctx['constructor'].components[ctx['state'].child];
const b2 = toggler(Comp1, comp1({}, key + \`__1\`, node, this, Comp1));
return block1([], [b2]);
const b4 = toggler(Comp1, comp1({}, key + \`__1\`, node, this, Comp1));
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -143,13 +148,16 @@ exports[`t-component modifying a sub widget 2`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/><button block-handler-1=\\"click\\">Inc</button></div>\`);
let block3 = createBlock(\`<div><block-text-0/><button block-handler-1=\\"click\\">Inc</button></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['state'].counter;
const v1 = ctx['state'];
let hdlr1 = [()=>v1.counter++, ctx];
return block1([txt1, hdlr1]);
const b3 = block3([txt1, hdlr1]);
return multi([b2, b3]);
}
}"
`;
@@ -7,20 +7,35 @@ exports[`list of components components in a node in a t-foreach 1`] = `
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><ul><block-child-0/></ul></div>\`);
let block3 = createBlock(\`<li><block-child-0/></li>\`);
let block3 = createBlock(\`<div>
<ul>
<block-child-0/>
</ul>
</div>\`);
let block7 = createBlock(\`<li>
<block-child-0/>
</li>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`item\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`item\`] = v_block4[i1];
const key1 = 'li_'+ctx['item'];
const b4 = comp1({item: ctx['item']}, key + \`__1__\${key1}\`, node, this, null);
c_block2[i1] = withKey(block3([], [b4]), key1);
const b6 = text(\`
\`);
const b8 = comp1({item: ctx['item']}, key + \`__1__\${key1}\`, node, this, null);
const b7 = block7([], [b8]);
const b9 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b9]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -43,23 +58,34 @@ exports[`list of components crash on duplicate key in dev mode 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, OwlError, withKey } = helpers;
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList([1,2]);;
const keys1 = new Set();
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`item\`] = v_block1[i1];
const [k_block3, v_block3, l_block3, c_block3] = prepareList([1,2]);;
const keys3 = new Set();
for (let i1 = 0; i1 < l_block3; i1++) {
ctx[\`item\`] = v_block3[i1];
const key1 = 'child';
if (keys1.has(String(key1))) { throw new OwlError(\`Got duplicate key in t-foreach: \${key1}\`)}
keys1.add(String(key1));
if (keys3.has(key1)) { throw new Error(\`Got duplicate key in t-foreach: \${key1}\`)}
keys3.add(key1);
const b5 = text(\`
\`);
const props1 = {};
helpers.validateProps(\`Child\`, props1, this);
c_block1[i1] = withKey(comp1(props1, key + \`__1__\${key1}\`, node, this, null), key1);
helpers.validateProps(\`Child\`, props1, ctx);
const b6 = comp1(props1, key + \`__1__\${key1}\`, node, this, null);
const b7 = text(\`
\`);
c_block3[i1] = withKey(multi([b5, b6, b7]), key1);
}
return list(c_block1);
ctx = ctx.__proto__;
const b3 = list(c_block3);
const b8 = text(\`
\`);
return multi([b2, b3, b8]);
}
}"
`;
@@ -75,42 +101,6 @@ exports[`list of components crash on duplicate key in dev mode 2`] = `
}"
`;
exports[`list of components crash when using object as keys that serialize to the same string 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, OwlError, withKey } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList([{},{}]);;
const keys1 = new Set();
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`item\`] = v_block1[i1];
const key1 = ctx['item'];
if (keys1.has(String(key1))) { throw new OwlError(\`Got duplicate key in t-foreach: \${key1}\`)}
keys1.add(String(key1));
const props1 = {};
helpers.validateProps(\`Child\`, props1, this);
c_block1[i1] = withKey(comp1(props1, key + \`__1__\${key1}\`, node, this, null), key1);
}
return list(c_block1);
}
}"
`;
exports[`list of components crash when using object as keys that serialize to the same string 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(\`\`);
}
}"
`;
exports[`list of components list of sub components inside other nodes 1`] = `
"function anonymous(app, bdom, helpers
) {
@@ -118,20 +108,28 @@ exports[`list of components list of sub components inside other nodes 1`] = `
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`SubComponent\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block5 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].blips);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`blip\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state'].blips);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`blip\`] = v_block4[i1];
const key1 = ctx['blip'].id;
const b4 = comp1({}, key + \`__1__\${key1}\`, node, this, null);
c_block2[i1] = withKey(block3([], [b4]), key1);
const b6 = comp1({}, key + \`__1__\${key1}\`, node, this, null);
c_block4[i1] = withKey(block5([], [b6]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -149,58 +147,6 @@ exports[`list of components list of sub components inside other nodes 2`] = `
}"
`;
exports[`list of components order is correct when slots are not of same type 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { capture, markRaw } = helpers;
const comp1 = app.createComponent(\`Child\`, true, true, false, true);
let block2 = createBlock(\`<div>A</div>\`);
function slot1(ctx, node, key = \\"\\") {
let b2;
if (!ctx['state'].active) {
b2 = block2();
}
return multi([b2]);
}
function slot2(ctx, node, key = \\"\\") {
return text(\`B\`);
}
function slot3(ctx, node, key = \\"\\") {
return text(\`C\`);
}
return function template(ctx, node, key = \\"\\") {
const ctx1 = capture(ctx);
return comp1({slots: markRaw({'a': {__render: slot1.bind(this), __ctx: ctx1, active: !ctx['state'].active}, 'b': {__render: slot2.bind(this), __ctx: ctx1, active: true}, 'c': {__render: slot3.bind(this), __ctx: ctx1, active: ctx['state'].active}})}, key + \`__1\`, node, this, null);
}
}"
`;
exports[`list of components order is correct when slots are not of same type 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, callSlot, withKey } = helpers;
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['slotNames']);;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`slotName\`] = v_block1[i1];
const key1 = ctx['slotName'];
const slot1 = (ctx['slotName']);
c_block1[i1] = withKey(toggler(slot1, callSlot(ctx, node, key1 + \`__1__\${key1}\`, slot1, true, {})), key1);
}
return list(c_block1);
}
}"
`;
exports[`list of components reconciliation alg works for t-foreach in t-foreach 1`] = `
"function anonymous(app, bdom, helpers
) {
@@ -208,28 +154,44 @@ exports[`list of components reconciliation alg works for t-foreach in t-foreach
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].s);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`section\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state'].s);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`section\`] = v_block4[i1];
ctx[\`section_index\`] = i1;
const key1 = ctx['section_index'];
const b6 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block3, v_block3, l_block3, c_block3] = prepareList(ctx['section'].blips);;
for (let i2 = 0; i2 < l_block3; i2++) {
ctx[\`blip\`] = v_block3[i2];
const [k_block7, v_block7, l_block7, c_block7] = prepareList(ctx['section'].blips);;
for (let i2 = 0; i2 < l_block7; i2++) {
ctx[\`blip\`] = v_block7[i2];
ctx[\`blip_index\`] = i2;
const key2 = ctx['blip_index'];
c_block3[i2] = withKey(comp1({blip: ctx['blip']}, key + \`__1__\${key1}__\${key2}\`, node, this, null), key2);
const b9 = text(\`
\`);
const b10 = comp1({blip: ctx['blip']}, key + \`__1__\${key1}__\${key2}\`, node, this, null);
const b11 = text(\`
\`);
c_block7[i2] = withKey(multi([b9, b10, b11]), key2);
}
ctx = ctx.__proto__;
c_block2[i1] = withKey(list(c_block3), key1);
const b7 = list(c_block7);
const b12 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b12]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -255,30 +217,40 @@ exports[`list of components reconciliation alg works for t-foreach in t-foreach,
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<p><block-child-0/></p>\`);
let block5 = createBlock(\`<p><block-child-0/></p>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block5 = createBlock(\`<p>
<block-child-0/>
</p>\`);
let block7 = createBlock(\`<p>
<block-child-0/>
</p>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].rows);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`row\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state'].rows);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`row\`] = v_block4[i1];
const key1 = ctx['row'];
ctx = Object.create(ctx);
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state'].cols);;
for (let i2 = 0; i2 < l_block4; i2++) {
ctx[\`col\`] = v_block4[i2];
const [k_block6, v_block6, l_block6, c_block6] = prepareList(ctx['state'].cols);;
for (let i2 = 0; i2 < l_block6; i2++) {
ctx[\`col\`] = v_block6[i2];
const key2 = ctx['col'];
const b6 = comp1({row: ctx['row'],col: ctx['col']}, key + \`__1__\${key1}__\${key2}\`, node, this, null);
c_block4[i2] = withKey(block5([], [b6]), key2);
const b8 = comp1({row: ctx['row'],col: ctx['col']}, key + \`__1__\${key1}__\${key2}\`, node, this, null);
c_block6[i2] = withKey(block7([], [b8]), key2);
}
ctx = ctx.__proto__;
const b4 = list(c_block4);
c_block2[i1] = withKey(block3([], [b4]), key1);
const b6 = list(c_block6);
c_block4[i1] = withKey(block5([], [b6]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -305,14 +277,22 @@ exports[`list of components simple list 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['state'].elems);;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`elem\`] = v_block1[i1];
const [k_block3, v_block3, l_block3, c_block3] = prepareList(ctx['state'].elems);;
for (let i1 = 0; i1 < l_block3; i1++) {
ctx[\`elem\`] = v_block3[i1];
const key1 = ctx['elem'].id;
c_block1[i1] = withKey(comp1({value: ctx['elem'].value}, key + \`__1__\${key1}\`, node, this, null), key1);
const b5 = text(\`
\`);
const b6 = comp1({value: ctx['elem'].value}, key + \`__1__\${key1}\`, node, this, null);
const b7 = text(\`
\`);
c_block3[i1] = withKey(multi([b5, b6, b7]), key1);
}
return list(c_block1);
const b3 = list(c_block3);
return multi([b2, b3]);
}
}"
`;
@@ -338,18 +318,29 @@ exports[`list of components sub components rendered in a loop 1`] = `
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].numbers);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`number\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state'].numbers);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`number\`] = v_block4[i1];
const key1 = ctx['number'];
c_block2[i1] = withKey(comp1({n: ctx['number']}, key + \`__1__\${key1}\`, node, this, null), key1);
const b6 = text(\`
\`);
const b7 = comp1({n: ctx['number']}, key + \`__1__\${key1}\`, node, this, null);
const b8 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -375,18 +366,29 @@ exports[`list of components sub components with some state rendered in a loop 1`
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].numbers);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`number\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state'].numbers);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`number\`] = v_block4[i1];
const key1 = ctx['number'];
c_block2[i1] = withKey(comp1({}, key + \`__1__\${key1}\`, node, this, null), key1);
const b6 = text(\`
\`);
const b7 = comp1({}, key + \`__1__\${key1}\`, node, this, null);
const b8 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -412,7 +414,9 @@ exports[`list of components switch component position 1`] = `
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<span><block-child-0/></span>\`);
let block1 = createBlock(\`<span>
<block-child-0/>
</span>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
@@ -420,8 +424,14 @@ exports[`list of components switch component position 1`] = `
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`c\`] = v_block2[i1];
const key1 = ctx['c'];
c_block2[i1] = withKey(comp1({key: ctx['c']}, key + \`__1__\${key1}\`, node, this, null), key1);
const b4 = text(\`
\`);
const b5 = comp1({key: ctx['c']}, key + \`__1__\${key1}\`, node, this, null);
const b6 = text(\`
\`);
c_block2[i1] = withKey(multi([b4, b5, b6]), key1);
}
ctx = ctx.__proto__;
const b2 = list(c_block2);
return block1([], [b2]);
}
@@ -449,19 +459,30 @@ exports[`list of components t-foreach with t-component, and update 1`] = `
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(Array(2));;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`n\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(Array(2));;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`n\`] = v_block4[i1];
ctx[\`n_index\`] = i1;
const key1 = ctx['n_index'];
c_block2[i1] = withKey(comp1({val: ctx['n_index']}, key + \`__1__\${key1}\`, node, this, null), key1);
const b6 = text(\`
\`);
const b7 = comp1({val: ctx['n_index']}, key + \`__1__\${key1}\`, node, this, null);
const b8 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -471,12 +492,18 @@ exports[`list of components t-foreach with t-component, and update 2`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/><block-text-1/></span>\`);
let block3 = createBlock(\`<span>
<block-text-0/>
<block-text-1/>
</span>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['state'].val;
let txt2 = ctx['props'].val;
return block1([txt1, txt2]);
const b3 = block3([txt1, txt2]);
return multi([b2, b3]);
}
}"
`;
@@ -7,7 +7,9 @@ exports[`t-key t-foreach with t-key switch component position 1`] = `
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<span><block-child-0/></span>\`);
let block1 = createBlock(\`<span>
<block-child-0/>
</span>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
@@ -15,9 +17,15 @@ exports[`t-key t-foreach with t-key switch component position 1`] = `
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`c\`] = v_block2[i1];
const key1 = ctx['c'];
const b4 = text(\`
\`);
const tKey_1 = ctx['key1'];
c_block2[i1] = withKey(comp1({key: ctx['c']+ctx['key1']}, tKey_1 + key + \`__1__\${key1}\`, node, this, null), tKey_1 + key1);
const b5 = toggler(tKey_1, comp1({key: ctx['c']+ctx['key1']}, tKey_1 + key + \`__1__\${key1}\`, node, this, null));
const b6 = text(\`
\`);
c_block2[i1] = withKey(multi([b4, b5, b6]), key1);
}
ctx = ctx.__proto__;
const b2 = list(c_block2);
return block1([], [b2]);
}
@@ -102,7 +110,10 @@ exports[`t-key t-key on multiple Components 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
const comp2 = app.createComponent(\`Child\`, true, false, false, false);
let block1 = createBlock(\`<span><block-child-0/><block-child-1/></span>\`);
let block1 = createBlock(\`<span>
<block-child-0/>
<block-child-1/>
</span>\`);
return function template(ctx, node, key = \\"\\") {
const tKey_1 = ctx['key1'];
@@ -136,7 +147,10 @@ exports[`t-key t-key on multiple Components with t-call 1 1`] = `
const callTemplate_1 = app.getTemplate(\`calledTemplate\`);
const callTemplate_2 = app.getTemplate(\`calledTemplate\`);
let block1 = createBlock(\`<span><block-child-0/><block-child-1/></span>\`);
let block1 = createBlock(\`<span>
<block-child-0/>
<block-child-1/>
</span>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
@@ -150,6 +164,7 @@ exports[`t-key t-key on multiple Components with t-call 1 1`] = `
ctx[isBoundary] = 1;
setContextValue(ctx, \\"key\\", ctx['key2']);
const b3 = callTemplate_2.call(this, ctx, node, key + \`__2\`);
ctx = ctx.__proto__;
return block1([], [b2, b3]);
}
}"
@@ -162,8 +177,13 @@ exports[`t-key t-key on multiple Components with t-call 1 2`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const tKey_1 = ctx['key'];
return toggler(tKey_1, comp1({key: ctx['key']}, tKey_1 + key + \`__1\`, node, this, null));
const b3 = toggler(tKey_1, comp1({key: ctx['key']}, tKey_1 + key + \`__1\`, node, this, null));
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -188,7 +208,9 @@ exports[`t-key t-key on multiple Components with t-call 2 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`calledTemplate\`);
let block1 = createBlock(\`<span><block-child-0/></span>\`);
let block1 = createBlock(\`<span>
<block-child-0/>
</span>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
@@ -205,11 +227,15 @@ exports[`t-key t-key on multiple Components with t-call 2 2`] = `
const comp2 = app.createComponent(\`Child\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const tKey_1 = ctx['key1'];
const b2 = toggler(tKey_1, comp1({key: ctx['key1']}, tKey_1 + key + \`__1\`, node, this, null));
const b3 = toggler(tKey_1, comp1({key: ctx['key1']}, tKey_1 + key + \`__1\`, node, this, null));
const tKey_2 = ctx['key2'];
const b3 = toggler(tKey_2, comp2({key: ctx['key2']}, tKey_2 + key + \`__2\`, node, this, null));
return multi([b2, b3]);
const b4 = toggler(tKey_2, comp2({key: ctx['key2']}, tKey_2 + key + \`__2\`, node, this, null));
const b5 = text(\`
\`);
return multi([b2, b3, b4, b5]);
}
}"
`;
@@ -6,15 +6,23 @@ exports[`t-model directive .lazy modifier 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input block-attribute-0=\\"value\\" block-handler-1=\\"change\\"/><span><block-text-2/></span></div>\`);
let block3 = createBlock(\`<div>
<input block-attribute-0=\\"value\\" block-handler-1=\\"change\\"/>
<span><block-text-2/></span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const bExpr1 = ctx['state'];
const expr1 = 'text';
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
let txt1 = ctx['state'].text;
return block1([attr1, hdlr1, txt1]);
const b3 = block3([attr1, hdlr1, txt1]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -25,15 +33,23 @@ exports[`t-model directive .number modifier 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/><span><block-text-2/></span></div>\`);
let block3 = createBlock(\`<div>
<input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>
<span><block-text-2/></span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const bExpr1 = ctx['state'];
const expr1 = 'number';
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = toNumber(ev.target.value); }];
let txt1 = ctx['state'].number;
return block1([attr1, hdlr1, txt1]);
const b3 = block3([attr1, hdlr1, txt1]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -44,15 +60,23 @@ exports[`t-model directive .trim modifier 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/><span><block-text-2/></span></div>\`);
let block3 = createBlock(\`<div>
<input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>
<span><block-text-2/></span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const bExpr1 = ctx['state'];
const expr1 = 'text';
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value.trim(); }];
let txt1 = ctx['state'].text;
return block1([attr1, hdlr1, txt1]);
const b3 = block3([attr1, hdlr1, txt1]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -63,15 +87,21 @@ exports[`t-model directive basic use, on an input 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/><span><block-text-2/></span></div>\`);
let block3 = createBlock(\`<div>
<input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>
<span><block-text-2/></span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const bExpr1 = ctx['state'];
const expr1 = 'text';
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
let txt1 = ctx['state'].text;
return block1([attr1, hdlr1, txt1]);
const b3 = block3([attr1, hdlr1, txt1]);
return multi([b2, b3]);
}
}"
`;
@@ -82,15 +112,21 @@ exports[`t-model directive basic use, on an input with bracket expression 1`] =
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/><span><block-text-2/></span></div>\`);
let block3 = createBlock(\`<div>
<input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>
<span><block-text-2/></span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const bExpr1 = ctx['state'];
const expr1 = 'text';
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
let txt1 = ctx['state'].text;
return block1([attr1, hdlr1, txt1]);
const b3 = block3([attr1, hdlr1, txt1]);
return multi([b2, b3]);
}
}"
`;
@@ -101,7 +137,10 @@ exports[`t-model directive basic use, on another key in component 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/><span><block-text-2/></span></div>\`);
let block1 = createBlock(\`<div>
<input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>
<span><block-text-2/></span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const bExpr1 = ctx['some'];
@@ -120,15 +159,22 @@ exports[`t-model directive can also define t-on directive on same event, part 1
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input block-attribute-0=\\"value\\" block-handler-1=\\"input\\" block-handler-2=\\"input\\"/></div>\`);
let block3 = createBlock(\`<div>
<input block-handler-0=\\"input\\" block-attribute-1=\\"value\\" block-handler-2=\\"input\\"/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let hdlr1 = [ctx['onInput'], ctx];
const bExpr1 = ctx['state'];
const expr1 = 'text';
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
let hdlr2 = [ctx['onInput'], ctx];
return block1([attr1, hdlr1, hdlr2]);
let hdlr2 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
const b3 = block3([hdlr1, attr1, hdlr2]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -139,25 +185,34 @@ exports[`t-model directive can also define t-on directive on same event, part 2
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input type=\\"radio\\" id=\\"one\\" value=\\"One\\" block-attribute-0=\\"checked\\" block-handler-1=\\"click\\" block-handler-2=\\"click\\"/><input type=\\"radio\\" id=\\"two\\" value=\\"Two\\" block-attribute-3=\\"checked\\" block-handler-4=\\"click\\" block-handler-5=\\"click\\"/><input type=\\"radio\\" id=\\"three\\" value=\\"Three\\" block-attribute-6=\\"checked\\" block-handler-7=\\"click\\" block-handler-8=\\"click\\"/></div>\`);
let block3 = createBlock(\`<div>
<input type=\\"radio\\" id=\\"one\\" value=\\"One\\" block-handler-0=\\"click\\" block-attribute-1=\\"checked\\" block-handler-2=\\"click\\"/>
<input type=\\"radio\\" id=\\"two\\" value=\\"Two\\" block-handler-3=\\"click\\" block-attribute-4=\\"checked\\" block-handler-5=\\"click\\"/>
<input type=\\"radio\\" id=\\"three\\" value=\\"Three\\" block-handler-6=\\"click\\" block-attribute-7=\\"checked\\" block-handler-8=\\"click\\"/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let hdlr1 = [ctx['onClick'], ctx];
const bExpr1 = ctx['state'];
const expr1 = 'choice';
let attr1 = bExpr1[expr1] === 'One';
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
let hdlr2 = [ctx['onClick'], ctx];
let hdlr2 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
let hdlr3 = [ctx['onClick'], ctx];
const bExpr2 = ctx['state'];
const expr2 = 'choice';
let attr2 = bExpr2[expr2] === 'Two';
let hdlr3 = [(ev) => { bExpr2[expr2] = ev.target.value; }];
let hdlr4 = [ctx['onClick'], ctx];
let hdlr4 = [(ev) => { bExpr2[expr2] = ev.target.value; }];
let hdlr5 = [ctx['onClick'], ctx];
const bExpr3 = ctx['state'];
const expr3 = 'choice';
let attr3 = bExpr3[expr3] === 'Three';
let hdlr5 = [(ev) => { bExpr3[expr3] = ev.target.value; }];
let hdlr6 = [ctx['onClick'], ctx];
return block1([attr1, hdlr1, hdlr2, attr2, hdlr3, hdlr4, attr3, hdlr5, hdlr6]);
let hdlr6 = [(ev) => { bExpr3[expr3] = ev.target.value; }];
const b3 = block3([hdlr1, attr1, hdlr2, hdlr3, attr2, hdlr4, hdlr5, attr3, hdlr6]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -168,17 +223,25 @@ exports[`t-model directive following a scope protecting directive (e.g. t-set) 1
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue, toNumber } = helpers;
let block1 = createBlock(\`<div><input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/></div>\`);
let block3 = createBlock(\`<div>
<input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"admiral\\", 'Bruno');
const bExpr1 = ctx['state'];
const expr1 = 'text';
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
return block1([attr1, hdlr1]);
const b3 = block3([attr1, hdlr1]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -189,23 +252,36 @@ exports[`t-model directive in a t-foreach 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, toNumber, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<input type=\\"checkbox\\" block-attribute-0=\\"checked\\" block-handler-1=\\"input\\"/>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block7 = createBlock(\`<input type=\\"checkbox\\" block-attribute-0=\\"checked\\" block-handler-1=\\"input\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`thing\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`thing\`] = v_block4[i1];
const key1 = ctx['thing'].id;
const b6 = text(\`
\`);
const bExpr1 = ctx['thing'];
const expr1 = 'f';
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.checked; }];
c_block2[i1] = withKey(block3([attr1, hdlr1]), key1);
const b7 = block7([attr1, hdlr1]);
const b8 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
const b9 = text(\`
\`);
return multi([b2, b3, b9]);
}
}"
`;
@@ -216,24 +292,37 @@ exports[`t-model directive in a t-foreach, part 2 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, toNumber, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block7 = createBlock(\`<input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`thing\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`thing\`] = v_block4[i1];
ctx[\`thing_index\`] = i1;
const key1 = ctx['thing_index'];
const b6 = text(\`
\`);
const bExpr1 = ctx['state'];
const expr1 = ctx['thing_index'];
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
c_block2[i1] = withKey(block3([attr1, hdlr1]), key1);
const b7 = block7([attr1, hdlr1]);
const b8 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
const b9 = text(\`
\`);
return multi([b2, b3, b9]);
}
}"
`;
@@ -244,24 +333,37 @@ exports[`t-model directive in a t-foreach, part 3 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, toNumber, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block7 = createBlock(\`<input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['names']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`name\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['names']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`name\`] = v_block4[i1];
ctx[\`name_index\`] = i1;
const key1 = ctx['name_index'];
const b6 = text(\`
\`);
const bExpr1 = ctx['state'].values;
const expr1 = ctx['name'];
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
c_block2[i1] = withKey(block3([attr1, hdlr1]), key1);
const b7 = block7([attr1, hdlr1]);
const b8 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
const b9 = text(\`
\`);
return multi([b2, b3, b9]);
}
}"
`;
@@ -272,7 +374,14 @@ exports[`t-model directive on a select 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><select block-attribute-0=\\"value\\" block-handler-1=\\"change\\"><option value=\\"\\">Please select one</option><option value=\\"red\\">Red</option><option value=\\"blue\\">Blue</option></select><span>Choice: <block-text-2/></span></div>\`);
let block1 = createBlock(\`<div>
<select block-attribute-0=\\"value\\" block-handler-1=\\"change\\">
<option value=\\"\\">Please select one</option>
<option value=\\"red\\">Red</option>
<option value=\\"blue\\">Blue</option>
</select>
<span>Choice: <block-text-2/></span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const bExpr1 = ctx['state'];
@@ -291,14 +400,25 @@ exports[`t-model directive on a select, initial state 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><select block-attribute-0=\\"value\\" block-handler-1=\\"change\\"><option value=\\"\\">Please select one</option><option value=\\"red\\">Red</option><option value=\\"blue\\">Blue</option></select></div>\`);
let block3 = createBlock(\`<div>
<select block-attribute-0=\\"value\\" block-handler-1=\\"change\\">
<option value=\\"\\">Please select one</option>
<option value=\\"red\\">Red</option>
<option value=\\"blue\\">Blue</option>
</select>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const bExpr1 = ctx['state'];
const expr1 = 'color';
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
return block1([attr1, hdlr1]);
const b3 = block3([attr1, hdlr1]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -309,15 +429,23 @@ exports[`t-model directive on a sub state key 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/><span><block-text-2/></span></div>\`);
let block3 = createBlock(\`<div>
<input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>
<span><block-text-2/></span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const bExpr1 = ctx['state'].something;
const expr1 = 'text';
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
let txt1 = ctx['state'].something.text;
return block1([attr1, hdlr1, txt1]);
const b3 = block3([attr1, hdlr1, txt1]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -328,7 +456,11 @@ exports[`t-model directive on an input type=radio 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input type=\\"radio\\" id=\\"one\\" value=\\"One\\" block-attribute-0=\\"checked\\" block-handler-1=\\"click\\"/><input type=\\"radio\\" id=\\"two\\" value=\\"Two\\" block-attribute-2=\\"checked\\" block-handler-3=\\"click\\"/><span>Choice: <block-text-4/></span></div>\`);
let block1 = createBlock(\`<div>
<input type=\\"radio\\" id=\\"one\\" value=\\"One\\" block-attribute-0=\\"checked\\" block-handler-1=\\"click\\"/>
<input type=\\"radio\\" id=\\"two\\" value=\\"Two\\" block-attribute-2=\\"checked\\" block-handler-3=\\"click\\"/>
<span>Choice: <block-text-4/></span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const bExpr1 = ctx['state'];
@@ -351,7 +483,10 @@ exports[`t-model directive on an input type=radio, with initial value 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input type=\\"radio\\" id=\\"one\\" value=\\"One\\" block-attribute-0=\\"checked\\" block-handler-1=\\"click\\"/><input type=\\"radio\\" id=\\"two\\" value=\\"Two\\" block-attribute-2=\\"checked\\" block-handler-3=\\"click\\"/></div>\`);
let block1 = createBlock(\`<div>
<input type=\\"radio\\" id=\\"one\\" value=\\"One\\" block-attribute-0=\\"checked\\" block-handler-1=\\"click\\"/>
<input type=\\"radio\\" id=\\"two\\" value=\\"Two\\" block-attribute-2=\\"checked\\" block-handler-3=\\"click\\"/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const bExpr1 = ctx['state'];
@@ -373,7 +508,12 @@ exports[`t-model directive on an input, type=checkbox 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input type=\\"checkbox\\" block-attribute-0=\\"checked\\" block-handler-1=\\"input\\"/><span><block-child-0/><block-child-1/></span></div>\`);
let block1 = createBlock(\`<div>
<input type=\\"checkbox\\" block-attribute-0=\\"checked\\" block-handler-1=\\"input\\"/>
<span>
<block-child-0/><block-child-1/>
</span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
@@ -397,7 +537,10 @@ exports[`t-model directive on an textarea 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><textarea block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/><span><block-text-2/></span></div>\`);
let block1 = createBlock(\`<div>
<textarea block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>
<span><block-text-2/></span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const bExpr1 = ctx['state'];
@@ -410,25 +553,6 @@ exports[`t-model directive on an textarea 1`] = `
}"
`;
exports[`t-model directive t-model is applied before t-on-input 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input block-attribute-0=\\"value\\" block-handler-1=\\"input\\" block-handler-2=\\"input\\"/></div>\`);
return function template(ctx, node, key = \\"\\") {
const bExpr1 = ctx['state'];
const expr1 = 'text';
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
let hdlr2 = [ctx['onInput'], ctx];
return block1([attr1, hdlr1, hdlr2]);
}
}"
`;
exports[`t-model directive t-model on an input with an undefined value 1`] = `
"function anonymous(app, bdom, helpers
) {
@@ -453,9 +577,17 @@ exports[`t-model directive t-model on select with static options 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><select block-attribute-0=\\"value\\" block-handler-1=\\"change\\"><option value=\\"a\\"><block-text-2/></option><option value=\\"b\\"><block-text-3/></option><option value=\\"c\\"><block-text-4/></option></select></div>\`);
let block3 = createBlock(\`<div>
<select block-attribute-0=\\"value\\" block-handler-1=\\"change\\">
<option value=\\"a\\"><block-text-2/></option>
<option value=\\"b\\"><block-text-3/></option>
<option value=\\"c\\"><block-text-4/></option>
</select>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const bExpr1 = ctx['state'];
const expr1 = 'model';
let attr1 = bExpr1[expr1];
@@ -463,7 +595,10 @@ exports[`t-model directive t-model on select with static options 1`] = `
let txt1 = 'a';
let txt2 = 'b';
let txt3 = 'c';
return block1([attr1, hdlr1, txt1, txt2, txt3]);
const b3 = block3([attr1, hdlr1, txt1, txt2, txt3]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -474,9 +609,16 @@ exports[`t-model directive t-model with dynamic values on select options -- 2 1`
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><select block-handler-0=\\"change\\"><option block-attribute-1=\\"value\\" block-attribute-2=\\"selected\\"><block-text-3/></option><option block-attribute-4=\\"value\\" block-attribute-5=\\"selected\\"><block-text-6/></option></select></div>\`);
let block3 = createBlock(\`<div>
<select block-handler-0=\\"change\\">
<option block-attribute-1=\\"value\\" block-attribute-2=\\"selected\\"><block-text-3/></option>
<option block-attribute-4=\\"value\\" block-attribute-5=\\"selected\\"><block-text-6/></option>
</select>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const bExpr1 = ctx['state'];
const expr1 = 'model';
const bValue1 = bExpr1[expr1];
@@ -487,7 +629,10 @@ exports[`t-model directive t-model with dynamic values on select options -- 2 1`
let attr3 = (ctx['options'][1]);
let attr4 = bValue1 === (ctx['options'][1]);
let txt2 = ctx['options'][1];
return block1([hdlr1, attr1, attr2, txt1, attr3, attr4, txt2]);
const b3 = block3([hdlr1, attr1, attr2, txt1, attr3, attr4, txt2]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -498,9 +643,16 @@ exports[`t-model directive t-model with dynamic values on select options -- 3 1`
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><select block-handler-0=\\"change\\"><option block-attribute-1=\\"value\\" block-attribute-2=\\"selected\\"><block-text-3/></option><option value=\\"b\\" block-attribute-4=\\"selected\\"><block-text-5/></option></select></div>\`);
let block3 = createBlock(\`<div>
<select block-handler-0=\\"change\\">
<option block-attribute-1=\\"value\\" block-attribute-2=\\"selected\\"><block-text-3/></option>
<option value=\\"b\\" block-attribute-4=\\"selected\\"><block-text-5/></option>
</select>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const bExpr1 = ctx['state'];
const expr1 = 'model';
const bValue1 = bExpr1[expr1];
@@ -510,7 +662,10 @@ exports[`t-model directive t-model with dynamic values on select options -- 3 1`
let txt1 = ctx['options'][0];
let attr3 = bValue1 === \\"b\\";
let txt2 = ctx['options'][1];
return block1([hdlr1, attr1, attr2, txt1, attr3, txt2]);
const b3 = block3([hdlr1, attr1, attr2, txt1, attr3, txt2]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -521,9 +676,16 @@ exports[`t-model directive t-model with dynamic values on select options 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><select block-handler-0=\\"change\\"><option block-attribute-1=\\"value\\" block-attribute-2=\\"selected\\"><block-text-3/></option><option block-attribute-4=\\"value\\" block-attribute-5=\\"selected\\"><block-text-6/></option></select></div>\`);
let block3 = createBlock(\`<div>
<select block-handler-0=\\"change\\">
<option block-attribute-1=\\"value\\" block-attribute-2=\\"selected\\"><block-text-3/></option>
<option block-attribute-4=\\"value\\" block-attribute-5=\\"selected\\"><block-text-6/></option>
</select>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const bExpr1 = ctx['state'];
const expr1 = 'model';
const bValue1 = bExpr1[expr1];
@@ -534,7 +696,10 @@ exports[`t-model directive t-model with dynamic values on select options 1`] = `
let attr3 = ctx['options'][1];
let attr4 = bValue1 === ctx['options'][1];
let txt2 = ctx['options'][1];
return block1([hdlr1, attr1, attr2, txt1, attr3, attr4, txt2]);
const b3 = block3([hdlr1, attr1, attr2, txt1, attr3, attr4, txt2]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -545,26 +710,41 @@ exports[`t-model directive t-model with dynamic values on select options in fore
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber, prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><select block-handler-0=\\"change\\"><block-child-0/></select></div>\`);
let block3 = createBlock(\`<option block-attribute-0=\\"value\\" block-attribute-1=\\"selected\\"><block-text-2/></option>\`);
let block3 = createBlock(\`<div>
<select block-handler-0=\\"change\\">
<block-child-0/>
</select>
</div>\`);
let block7 = createBlock(\`<option block-attribute-0=\\"value\\" block-attribute-1=\\"selected\\"><block-text-2/></option>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const bExpr1 = ctx['state'];
const expr1 = 'model';
const bValue1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['options']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`v\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['options']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`v\`] = v_block4[i1];
const key1 = ctx['v'];
const b6 = text(\`
\`);
let attr1 = ctx['v'];
let attr2 = bValue1 === ctx['v'];
let txt1 = ctx['v'];
c_block2[i1] = withKey(block3([attr1, attr2, txt1]), key1);
const b7 = block7([attr1, attr2, txt1]);
const b8 = text(\`
\`);
c_block4[i1] = withKey(multi([b6, b7, b8]), key1);
}
const b2 = list(c_block2);
return block1([hdlr1], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([hdlr1], [b4]);
const b9 = text(\`
\`);
return multi([b2, b3, b9]);
}
}"
`;
@@ -575,27 +755,35 @@ exports[`t-model directive two inputs in a div alternating with a t-if 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block2 = createBlock(\`<input class=\\"a\\" block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>\`);
let block3 = createBlock(\`<input class=\\"b\\" block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<block-child-1/>
</div>\`);
let block4 = createBlock(\`<input class=\\"a\\" block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>\`);
let block5 = createBlock(\`<input class=\\"b\\" block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let b2,b3;
const b2 = text(\`
\`);
let b4,b5;
if (ctx['state'].flag) {
const bExpr1 = ctx['state'];
const expr1 = 'text1';
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
b2 = block2([attr1, hdlr1]);
b4 = block4([attr1, hdlr1]);
}
if (!ctx['state'].flag) {
const bExpr2 = ctx['state'];
const expr2 = 'text2';
let attr2 = bExpr2[expr2];
let hdlr2 = [(ev) => { bExpr2[expr2] = ev.target.value; }];
b3 = block3([attr2, hdlr2]);
b5 = block5([attr2, hdlr2]);
}
return block1([], [b2, b3]);
const b3 = block3([], [b4, b5]);
const b6 = text(\`
\`);
return multi([b2, b3, b6]);
}
}"
`;
@@ -606,15 +794,23 @@ exports[`t-model directive with expression having a changing key 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { toNumber } = helpers;
let block1 = createBlock(\`<div><input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/><span><block-text-2/></span></div>\`);
let block3 = createBlock(\`<div>
<input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>
<span><block-text-2/></span>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const bExpr1 = ctx['state'].something;
const expr1 = ctx['text'].key;
let attr1 = bExpr1[expr1];
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
let txt1 = ctx['state'].something[ctx['text'].key];
return block1([attr1, hdlr1, txt1]);
const b3 = block3([attr1, hdlr1, txt1]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
+167 -102
View File
@@ -6,26 +6,38 @@ exports[`t-on t-on expression captured in t-foreach 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue, prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div><button block-handler-0=\\"click\\">expr</button></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block5 = createBlock(\`<div>
<button block-handler-0=\\"click\\">expr</button>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 0);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['arr']);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['arr']);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`val\`] = v_block4[i1];
const key1 = ctx['val'];
const v1 = ctx['otherState'];
const v2 = ctx['iter'];
let hdlr1 = [()=>v1.vals.push(v2+'_'+v2), ctx];
setContextValue(ctx, \\"iter\\", ctx['iter']+1);
c_block2[i1] = withKey(block3([hdlr1]), key1);
c_block4[i1] = withKey(block5([hdlr1]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
const b6 = text(\`
\`);
return multi([b2, b3, b6]);
}
}"
`;
@@ -36,14 +48,21 @@ exports[`t-on t-on expression in t-foreach 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div><block-text-0/>: <block-text-1/><button block-handler-2=\\"click\\">Expr</button></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block5 = createBlock(\`<div>
<block-text-0/>: <block-text-1/>
<button block-handler-2=\\"click\\">Expr</button>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].values);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state'].values);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`val\`] = v_block4[i1];
ctx[\`val_index\`] = i1;
const key1 = ctx['val'];
let txt1 = ctx['val_index'];
@@ -51,10 +70,14 @@ exports[`t-on t-on expression in t-foreach 1`] = `
const v1 = ctx['otherState'];
const v2 = ctx['val'];
let hdlr1 = [()=>v1.vals.push(v2), ctx];
c_block2[i1] = withKey(block3([txt1, txt2, hdlr1]), key1);
c_block4[i1] = withKey(block5([txt1, txt2, hdlr1]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
const b6 = text(\`
\`);
return multi([b2, b3, b6]);
}
}"
`;
@@ -65,17 +88,26 @@ exports[`t-on t-on expression in t-foreach with t-set 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue, prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div><block-text-0/>: <block-text-1/><button block-handler-2=\\"click\\">Expr</button></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block5 = createBlock(\`<div>
<block-text-0/>: <block-text-1/>
<button block-handler-2=\\"click\\">Expr</button>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"bossa\\", 'nova');
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].values);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state'].values);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`val\`] = v_block4[i1];
ctx[\`val_index\`] = i1;
const key1 = ctx['val'];
setContextValue(ctx, \\"bossa\\", ctx['bossa']+'_'+ctx['val_index']);
@@ -85,10 +117,14 @@ exports[`t-on t-on expression in t-foreach with t-set 1`] = `
const v2 = ctx['val'];
const v3 = ctx['bossa'];
let hdlr1 = [()=>v1.vals.push(v2+'_'+v3), ctx];
c_block2[i1] = withKey(block3([txt1, txt2, hdlr1]), key1);
c_block4[i1] = withKey(block5([txt1, txt2, hdlr1]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
const b6 = text(\`
\`);
return multi([b2, b3, b6]);
}
}"
`;
@@ -99,24 +135,35 @@ exports[`t-on t-on method call in t-foreach 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div><block-text-0/>: <block-text-1/><button block-handler-2=\\"click\\">meth call</button></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
let block5 = createBlock(\`<div>
<block-text-0/>: <block-text-1/>
<button block-handler-2=\\"click\\">meth call</button>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].values);;
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`val\`] = v_block2[i1];
const [k_block4, v_block4, l_block4, c_block4] = prepareList(ctx['state'].values);;
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`val\`] = v_block4[i1];
ctx[\`val_index\`] = i1;
const key1 = ctx['val'];
let txt1 = ctx['val_index'];
let txt2 = ctx['val']+'';
const v1 = ctx['val'];
let hdlr1 = [()=>this.addVal(v1), ctx];
c_block2[i1] = withKey(block3([txt1, txt2, hdlr1]), key1);
c_block4[i1] = withKey(block5([txt1, txt2, hdlr1]), key1);
}
const b2 = list(c_block2);
return block1([], [b2]);
ctx = ctx.__proto__;
const b4 = list(c_block4);
const b3 = block3([], [b4]);
const b6 = text(\`
\`);
return multi([b2, b3, b6]);
}
}"
`;
@@ -129,13 +176,19 @@ exports[`t-on t-on on component next to t-on on div 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
const catcher1 = createCatcher({\\"click\\":0});
let block1 = createBlock(\`<div><block-child-0/><p block-handler-0=\\"click\\">dec</p></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
<p block-handler-0=\\"click\\">dec</p>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const hdlr1 = [ctx['increment'], ctx];
const b2 = catcher1(comp1({value: ctx['state'].value}, key + \`__1\`, node, this, null), [hdlr1]);
const b4 = catcher1(comp1({value: ctx['state'].value}, key + \`__1\`, node, this, null), [hdlr1]);
let hdlr2 = [ctx['decrement'], ctx];
return block1([hdlr2], [b2]);
const b3 = block3([hdlr2], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -192,16 +245,24 @@ exports[`t-on t-on on components and t-foreach 1`] = `
const catcher1 = createCatcher({\\"click\\":0});
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(['John','Raoul','Gérald']);;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`name\`] = v_block1[i1];
const [k_block3, v_block3, l_block3, c_block3] = prepareList(['John','Raoul','Gérald']);;
for (let i1 = 0; i1 < l_block3; i1++) {
ctx[\`name\`] = v_block3[i1];
const key1 = ctx['name'];
const b5 = text(\`
\`);
const v1 = ctx['name'];
const hdlr1 = [()=>this.log(v1), ctx];
c_block1[i1] = withKey(catcher1(comp1({value: ctx['name']}, key + \`__1__\${key1}\`, node, this, null), [hdlr1]), key1);
const b6 = catcher1(comp1({value: ctx['name']}, key + \`__1__\${key1}\`, node, this, null), [hdlr1]);
const b7 = text(\`
\`);
c_block3[i1] = withKey(multi([b5, b6, b7]), key1);
}
return list(c_block1);
const b3 = list(c_block3);
return multi([b2, b3]);
}
}"
`;
@@ -228,12 +289,19 @@ exports[`t-on t-on on components, variation 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
const catcher1 = createCatcher({\\"click\\":0});
let block1 = createBlock(\`<div><span/><block-child-0/><p/></div>\`);
let block3 = createBlock(\`<div>
<span/>
<block-child-0/>
<p/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const hdlr1 = [ctx['increment'], ctx];
const b2 = catcher1(comp1({value: ctx['state'].value}, key + \`__1\`, node, this, null), [hdlr1]);
return block1([], [b2]);
const b4 = catcher1(comp1({value: ctx['state'].value}, key + \`__1\`, node, this, null), [hdlr1]);
const b3 = block3([], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -292,10 +360,15 @@ exports[`t-on t-on on components, with a handler update 1`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"name\\", ctx['state'].name);
const b3 = text(\`
\`);
const v1 = ctx['name'];
const hdlr1 = [()=>this.log(v1), ctx];
return catcher1(comp1({value: ctx['name']}, key + \`__1\`, node, this, null), [hdlr1]);
const b4 = catcher1(comp1({value: ctx['name']}, key + \`__1\`, node, this, null), [hdlr1]);
return multi([b2, b3, b4]);
}
}"
`;
@@ -353,14 +426,22 @@ exports[`t-on t-on on slot, with 'prevent' modifier 1`] = `
let { markRaw } = helpers;
const comp1 = app.createComponent(\`Child\`, true, true, false, true);
let block1 = createBlock(\`<button>button</button>\`);
let block5 = createBlock(\`<button>button</button>\`);
function slot1(ctx, node, key = \\"\\") {
return block1();
const b4 = text(\`
\`);
const b5 = block5();
const b6 = text(\`
\`);
return multi([b4, b5, b6]);
}
return function template(ctx, node, key = \\"\\") {
return comp1({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__1\`, node, this, null);
const b2 = text(\`
\`);
const b7 = comp1({slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__1\`, node, this, null);
return multi([b2, b7]);
}
}"
`;
@@ -387,23 +468,39 @@ exports[`t-on t-on on t-set-slots 1`] = `
const catcher1 = createCatcher({\\"click\\":0});
const comp1 = app.createComponent(\`Child\`, true, true, false, true);
let block6 = createBlock(\`<p>something</p>\`);
let block7 = createBlock(\`<p>paragraph</p>\`);
let block7 = createBlock(\`<p>something</p>\`);
let block9 = createBlock(\`<p>paragraph</p>\`);
function slot1(ctx, node, key = \\"\\") {
const b6 = block6();
const b6 = text(\`
\`);
const b7 = block7();
const b8 = text(\`
\`);
const b9 = block9();
const b10 = text(\`
\`);
const hdlr1 = [()=>this.state.count++, ctx];
return catcher1(multi([b6, b7]), [hdlr1]);
return catcher1(multi([b6, b7, b8, b9, b10]), [hdlr1]);
}
function slot2(ctx, node, key = \\"\\") {
const b12 = text(\`
\`);
const b13 = text(\`
\`);
return multi([b12, b13]);
}
return function template(ctx, node, key = \\"\\") {
const b2 = text(\` [\`);
const b2 = text(\`
[\`);
const b3 = text(ctx['state'].count);
const b4 = text(\`] \`);
const b4 = text(\`]
\`);
const ctx1 = capture(ctx);
const b8 = comp1({slots: markRaw({'myslot': {__render: slot1.bind(this), __ctx: ctx1}})}, key + \`__1\`, node, this, null);
return multi([b2, b3, b4, b8]);
const b14 = comp1({slots: markRaw({'myslot': {__render: slot1, __ctx: ctx1}, 'default': {__render: slot2, __ctx: ctx1}})}, key + \`__1\`, node, this, null);
return multi([b2, b3, b4, b14]);
}
}"
`;
@@ -427,14 +524,22 @@ exports[`t-on t-on on t-slots 1`] = `
let { markRaw } = helpers;
const comp1 = app.createComponent(\`Child\`, true, true, false, true);
let block1 = createBlock(\`<p>something</p>\`);
let block5 = createBlock(\`<p>something</p>\`);
function slot1(ctx, node, key = \\"\\") {
return block1();
const b4 = text(\`
\`);
const b5 = block5();
const b6 = text(\`
\`);
return multi([b4, b5, b6]);
}
return function template(ctx, node, key = \\"\\") {
return comp1({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__1\`, node, this, null);
const b2 = text(\`
\`);
const b7 = comp1({slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__1\`, node, this, null);
return multi([b2, b7]);
}
}"
`;
@@ -447,54 +552,14 @@ exports[`t-on t-on on t-slots 2`] = `
const catcher1 = createCatcher({\\"click\\":0});
return function template(ctx, node, key = \\"\\") {
const b2 = text(\` [\`);
const b2 = text(\`
[\`);
const b3 = text(ctx['state'].count);
const b4 = text(\`] \`);
const b4 = text(\`]
\`);
const hdlr1 = [()=>this.state.count++, ctx];
const b5 = catcher1(callSlot(ctx, node, key, 'default', false, {}), [hdlr1]);
return multi([b2, b3, b4, b5]);
}
}"
`;
exports[`t-on t-on when first component child is an empty component 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { createCatcher } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
const catcher1 = createCatcher({\\"click\\":0});
let block1 = createBlock(\`<div block-handler-0=\\"click\\"><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [ctx['push'], ctx];
const hdlr2 = [()=>{}, ctx];
const b2 = catcher1(comp1({list: ctx['list']}, key + \`__1\`, node, this, null), [hdlr2]);
return block1([hdlr1], [b2]);
}
}"
`;
exports[`t-on t-on when first component child is an empty component 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block2 = createBlock(\`<span><block-text-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['props'].list);;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`c\`] = v_block1[i1];
ctx[\`c_index\`] = i1;
const key1 = ctx['c_index'];
let txt1 = ctx['c'];
c_block1[i1] = withKey(block2([txt1]), key1);
}
return list(c_block1);
}
}"
`;
@@ -1,39 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components in t-out simple list 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, isBoundary, withDefault, LazyValue, safeOutput, withKey } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
function value1(ctx, node, key = \\"\\") {
return comp1({}, key + \`__1\`, node, this, null);
}
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList([1,2]);;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`n\`] = v_block1[i1];
const key1 = ctx['n'];
ctx[\`blabla\`] = new LazyValue(value1, ctx, this, node, key1);
c_block1[i1] = withKey(safeOutput(ctx['blabla']), key1);
}
return list(c_block1);
}
}"
`;
exports[`components in t-out simple list 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(\`child\`);
}
}"
`;
@@ -6,11 +6,18 @@ exports[`t-props basic use 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, true, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1(Object.assign({}, ctx['some'].obj), key + \`__1\`, node, this, null);
return block1([], [b2]);
const b2 = text(\`
\`);
const b4 = comp1(Object.assign({}, ctx['some'].obj), key + \`__1\`, node, this, null);
const b3 = block3([], [b4]);
const b5 = text(\`
\`);
return multi([b2, b3, b5]);
}
}"
`;
@@ -20,11 +27,18 @@ exports[`t-props basic use 2`] = `
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
let block3 = createBlock(\`<span>
<block-text-0/>
</span>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
let txt1 = ctx['props'].a+ctx['props'].b;
return block1([txt1]);
const b3 = block3([txt1]);
const b4 = text(\`
\`);
return multi([b2, b3, b4]);
}
}"
`;
@@ -119,11 +133,18 @@ exports[`t-props t-props with props 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, true, false);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/>
</div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1(Object.assign({}, ctx['childProps'], {a: 1,b: 2}), key + \`__1\`, node, this, null);
return block1([], [b2]);
const b2 = text(\`
\`);
const b4 = comp1(Object.assign({}, ctx['childProps'], {a: 1,b: 2}), key + \`__1\`, node, this, null);
const b3 = block3([], [b4]);
const b5 = text(\`
\`);
return multi([b2, b3, b5]);
}
}"
`;
+190 -45
View File
@@ -7,24 +7,36 @@ exports[`t-set slot setted value (with t-set) not accessible with t-esc 1`] = `
let { isBoundary, withDefault, setContextValue, capture, markRaw } = helpers;
const comp1 = app.createComponent(\`Childcomp\`, true, true, false, true);
let block1 = createBlock(\`<div><p><block-text-0/></p><block-child-0/><p><block-text-1/></p></div>\`);
let block3 = createBlock(\`<div>
<p><block-text-0/></p>
<block-child-0/>
<p><block-text-1/></p>
</div>\`);
function slot1(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b5 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 'inCall');
return text('');
const b6 = text(\`
\`);
return multi([b5, b6]);
}
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 'source');
let txt1 = ctx['iter'];
const ctx1 = capture(ctx);
const b2 = comp1({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx1}})}, key + \`__1\`, node, this, null);
const b7 = comp1({slots: markRaw({'default': {__render: slot1, __ctx: ctx1}})}, key + \`__1\`, node, this, null);
let txt2 = ctx['iter'];
return block1([txt1, txt2], [b2]);
const b3 = block3([txt1, txt2], [b7]);
return multi([b2, b3]);
}
}"
`;
@@ -59,19 +71,33 @@ exports[`t-set slots with a t-set with a component in body 1`] = `
function slot1(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`v\`] = new LazyValue(value1, ctx, this, node, key);
const b3 = text(\` in slot \`);
const b4 = safeOutput(ctx['v']);
return multi([b3, b4]);
const b4 = text(\`
\`);
ctx[\`v\`] = new LazyValue(value1, ctx, this, node);
const b9 = text(\`
in slot
\`);
const b10 = safeOutput(ctx['v']);
const b11 = text(\`
\`);
return multi([b4, b9, b10, b11]);
}
function value1(ctx, node, key = \\"\\") {
return comp1({}, key + \`__1\`, node, this, null);
const b6 = text(\`
\`);
const b7 = comp1({}, key + \`__1\`, node, this, null);
const b8 = text(\`
\`);
return multi([b6, b7, b8]);
}
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const ctx1 = capture(ctx);
return comp2({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx1}})}, key + \`__2\`, node, this, null);
const b12 = comp2({slots: markRaw({'default': {__render: slot1, __ctx: ctx1}})}, key + \`__2\`, node, this, null);
return multi([b2, b12]);
}
}"
`;
@@ -109,26 +135,41 @@ exports[`t-set slots with an t-set with a component in body 1`] = `
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
const comp2 = app.createComponent(\`Blorg\`, true, true, false, true);
let block4 = createBlock(\`<div>coffee</div>\`);
let block9 = createBlock(\`<div>coffee</div>\`);
function slot1(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`v\`] = new LazyValue(value1, ctx, this, node, key);
const b5 = text(\` tea \`);
const b6 = safeOutput(ctx['v']);
return multi([b5, b6]);
const b4 = text(\`
\`);
ctx[\`v\`] = new LazyValue(value1, ctx, this, node);
const b11 = text(\`
tea
\`);
const b12 = safeOutput(ctx['v']);
const b13 = text(\`
\`);
return multi([b4, b11, b12, b13]);
}
function value1(ctx, node, key = \\"\\") {
const b3 = comp1({}, key + \`__1\`, node, this, null);
const b4 = block4();
return multi([b3, b4]);
const b6 = text(\`
\`);
const b7 = comp1({}, key + \`__1\`, node, this, null);
const b8 = text(\`
\`);
const b9 = block9();
const b10 = text(\`
\`);
return multi([b6, b7, b8, b9, b10]);
}
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const ctx1 = capture(ctx);
return comp2({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx1}})}, key + \`__2\`, node, this, null);
const b14 = comp2({slots: markRaw({'default': {__render: slot1, __ctx: ctx1}})}, key + \`__2\`, node, this, null);
return multi([b2, b14]);
}
}"
`;
@@ -169,17 +210,30 @@ exports[`t-set slots with an unused t-set with a component in body 1`] = `
function slot1(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`v\`] = new LazyValue(value1, ctx, this, node, key);
return text(\` in slot \`);
const b4 = text(\`
\`);
ctx[\`v\`] = new LazyValue(value1, ctx, this, node);
const b9 = text(\`
in slot
\`);
return multi([b4, b9]);
}
function value1(ctx, node, key = \\"\\") {
return comp1({}, key + \`__1\`, node, this, null);
const b6 = text(\`
\`);
const b7 = comp1({}, key + \`__1\`, node, this, null);
const b8 = text(\`
\`);
return multi([b6, b7, b8]);
}
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`
\`);
const ctx1 = capture(ctx);
return comp2({slots: markRaw({'default': {__render: slot1.bind(this), __ctx: ctx1}})}, key + \`__2\`, node, this, null);
const b10 = comp2({slots: markRaw({'default': {__render: slot1, __ctx: ctx1}})}, key + \`__2\`, node, this, null);
return multi([b2, b10]);
}
}"
`;
@@ -204,15 +258,22 @@ exports[`t-set t-set can't alter component even if key in component 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><p><block-text-0/></p><p><block-text-1/></p></div>\`);
let block3 = createBlock(\`<div>
<p><block-text-0/></p>
<p><block-text-1/></p>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
let txt1 = ctx['iter'];
setContextValue(ctx, \\"iter\\", 5);
let txt2 = ctx['iter'];
return block1([txt1, txt2]);
const b3 = block3([txt1, txt2]);
return multi([b2, b3]);
}
}"
`;
@@ -223,15 +284,22 @@ exports[`t-set t-set can't alter component if key not in component 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><p><block-text-0/></p><p><block-text-1/></p></div>\`);
let block3 = createBlock(\`<div>
<p><block-text-0/></p>
<p><block-text-1/></p>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
let txt1 = ctx['iter'];
setContextValue(ctx, \\"iter\\", 5);
let txt2 = ctx['iter'];
return block1([txt1, txt2]);
const b3 = block3([txt1, txt2]);
return multi([b2, b3]);
}
}"
`;
@@ -242,21 +310,44 @@ exports[`t-set t-set in t-if 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><p><block-text-0/></p></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/><block-child-2/>
<p><block-text-0/></p>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
let b4,b7,b10;
setContextValue(ctx, \\"flag\\", ctx['state'].flag);
if (ctx['flag']==='if') {
const b5 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 2);
const b6 = text(\`
\`);
b4 = multi([b5, b6]);
} else if (ctx['flag']==='elif') {
const b8 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 3);
const b9 = text(\`
\`);
b7 = multi([b8, b9]);
} else {
const b11 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 4);
const b12 = text(\`
\`);
b10 = multi([b11, b12]);
}
let txt1 = ctx['iter'];
return block1([txt1]);
const b3 = block3([txt1], [b4, b7, b10]);
return multi([b2, b3]);
}
}"
`;
@@ -268,16 +359,24 @@ exports[`t-set t-set not altered by child comp 1`] = `
let { isBoundary, withDefault, setContextValue } = helpers;
const comp1 = app.createComponent(\`Childcomp\`, true, false, false, true);
let block1 = createBlock(\`<div><p><block-text-0/></p><block-child-0/><p><block-text-1/></p></div>\`);
let block3 = createBlock(\`<div>
<p><block-text-0/></p>
<block-child-0/>
<p><block-text-1/></p>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 'source');
let txt1 = ctx['iter'];
const b2 = comp1({}, key + \`__1\`, node, this, null);
const b4 = comp1({}, key + \`__1\`, node, this, null);
let txt2 = ctx['iter'];
return block1([txt1, txt2], [b2]);
const b3 = block3([txt1, txt2], [b4]);
return multi([b2, b3]);
}
}"
`;
@@ -307,22 +406,46 @@ exports[`t-set t-set outside modified in t-if 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><p><block-text-0/></p></div>\`);
let block3 = createBlock(\`<div>
<block-child-0/><block-child-1/><block-child-2/>
<p><block-text-0/></p>
</div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
const b2 = text(\`
\`);
let b4,b7,b10;
setContextValue(ctx, \\"iter\\", 0);
setContextValue(ctx, \\"flag\\", ctx['state'].flag);
if (ctx['flag']==='if') {
const b5 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 2);
const b6 = text(\`
\`);
b4 = multi([b5, b6]);
} else if (ctx['flag']==='elif') {
const b8 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 3);
const b9 = text(\`
\`);
b7 = multi([b8, b9]);
} else {
const b11 = text(\`
\`);
setContextValue(ctx, \\"iter\\", 4);
const b12 = text(\`
\`);
b10 = multi([b11, b12]);
}
let txt1 = ctx['iter'];
return block1([txt1]);
const b3 = block3([txt1], [b4, b7, b10]);
return multi([b2, b3]);
}
}"
`;
@@ -334,18 +457,29 @@ exports[`t-set t-set with a component in body 1`] = `
let { isBoundary, withDefault, LazyValue, safeOutput } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let block1 = createBlock(\`<div><div><block-child-0/></div></div>\`);
let block3 = createBlock(\`<div>
<div><block-child-0/></div>
</div>\`);
function value1(ctx, node, key = \\"\\") {
return comp1({}, key + \`__1\`, node, this, null);
const b5 = text(\`
\`);
const b6 = comp1({}, key + \`__1\`, node, this, null);
const b7 = text(\`
\`);
return multi([b5, b6, b7]);
}
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`v\`] = new LazyValue(value1, ctx, this, node, key);
const b3 = safeOutput(ctx['v']);
return block1([], [b3]);
const b2 = text(\`
\`);
ctx[\`v\`] = new LazyValue(value1, ctx, this, node);
const b8 = safeOutput(ctx['v']);
const b3 = block3([], [b8]);
return multi([b2, b3]);
}
}"
`;
@@ -367,19 +501,30 @@ exports[`t-set t-set with something in body 1`] = `
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, LazyValue, safeOutput } = helpers;
let block1 = createBlock(\`<div><div><block-child-0/></div></div>\`);
let block2 = createBlock(\`<p>coucou</p>\`);
let block3 = createBlock(\`<div>
<div><block-child-0/></div>
</div>\`);
let block6 = createBlock(\`<p>coucou</p>\`);
function value1(ctx, node, key = \\"\\") {
return block2();
const b5 = text(\`
\`);
const b6 = block6();
const b7 = text(\`
\`);
return multi([b5, b6, b7]);
}
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`v\`] = new LazyValue(value1, ctx, this, node, key);
const b3 = safeOutput(ctx['v']);
return block1([], [b3]);
const b2 = text(\`
\`);
ctx[\`v\`] = new LazyValue(value1, ctx, this, node);
const b8 = safeOutput(ctx['v']);
const b3 = block3([], [b8]);
return multi([b2, b3]);
}
}"
`;
+7 -14
View File
@@ -1,12 +1,5 @@
import { App, Component, mount, status, toRaw, useState, xml } from "../../src";
import {
elem,
makeTestFixture,
nextAppError,
nextTick,
snapshotEverything,
useLogLifecycle,
} from "../helpers";
import { elem, makeTestFixture, nextTick, snapshotEverything, useLogLifecycle } from "../helpers";
import { markup } from "../../src/runtime/utils";
let fixture: HTMLElement;
@@ -215,14 +208,14 @@ describe("basics", () => {
static template = xml`<div/>`;
}
let error: Error;
const app = new App(Test);
const prom = app.mount(fixture);
const prom = mount(Test, fixture);
await Promise.resolve();
fixture.remove();
prom.catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow(
"Cannot mount a component on a detached dom node"
);
try {
await prom;
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe("Cannot mount a component on a detached dom node");
expect(console.warn).toBeCalledTimes(1);
+84 -260
View File
@@ -1,4 +1,4 @@
import { App, Component, mount, onWillDestroy } from "../../src";
import { Component, mount, onWillDestroy } from "../../src";
import {
onError,
onMounted,
@@ -18,9 +18,7 @@ import {
nextMicroTick,
snapshotEverything,
useLogLifecycle,
nextAppError,
} from "../helpers";
import { OwlError } from "../../src/runtime/error_handling";
let fixture: HTMLElement;
@@ -60,10 +58,9 @@ describe("basics", () => {
parent.state.flag = true;
parent.render();
await expect(nextAppError(parent.__owl__.app)).resolves.toThrow(
"An error occured in the owl lifecycle"
);
await nextTick();
expect(fixture.innerHTML).toBe("");
expect(mockConsoleError).toBeCalledTimes(1);
expect(mockConsoleWarn).toBeCalledTimes(1);
});
@@ -73,13 +70,12 @@ describe("basics", () => {
static template = xml`<SomeMispelledComponent />`;
static components = { SomeComponent };
}
const app = new App(Parent);
let error: Error;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow(
'Cannot find the definition of component "SomeMispelledComponent"'
);
await mountProm;
try {
await mount(Parent, fixture);
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe('Cannot find the definition of component "SomeMispelledComponent"');
expect(console.error).toBeCalledTimes(0);
@@ -93,13 +89,12 @@ describe("basics", () => {
static template = xml`<SomeMispelledComponent />`;
static components = { SomeComponent };
}
const app = new App(Parent, { test: true });
let error: Error;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow(
'Cannot find the definition of component "SomeMispelledComponent"'
);
await mountProm;
try {
await mount(Parent, fixture, { test: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe('Cannot find the definition of component "SomeMispelledComponent"');
expect(console.error).toBeCalledTimes(0);
@@ -113,33 +108,16 @@ describe("basics", () => {
static template = xml`<SomeComponent />`;
static components = { SomeComponent: notAComponentConstructor };
}
const app = new App(Parent as typeof Component);
let error: Error;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow(
'"SomeComponent" is not a Component. It must inherit from the Component class'
);
await mountProm;
expect(error!).toBeDefined();
expect(error!.message).toBe(
'"SomeComponent" is not a Component. It must inherit from the Component class'
);
});
test("display a nice error if the components key is missing with subcomponents", async () => {
class Parent extends Component {
static template = xml`<div><MissingChild /></div>`;
try {
// @ts-expect-error
await mount(Parent, fixture);
} catch (e) {
error = e as Error;
}
const app = new App(Parent as typeof Component);
let error: Error;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow(
'Cannot find the definition of component "MissingChild", missing static components key in parent'
);
await mountProm;
expect(error!).toBeDefined();
expect(error!.message).toBe(
'Cannot find the definition of component "MissingChild", missing static components key in parent'
'"SomeComponent" is not a Component. It must inherit from the Component class'
);
});
@@ -177,26 +155,26 @@ describe("basics", () => {
describe("errors and promises", () => {
test("a rendering error will reject the mount promise", async () => {
// we do not catch error in willPatch anymore
class Root extends Component {
class App extends Component {
static template = xml`<div><t t-esc="this.will.crash"/></div>`;
}
const app = new App(Root);
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle");
await mountProm;
let error: Error;
try {
await mount(App, fixture);
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.cause).toBeDefined();
const regexp =
/Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g;
expect(error!.cause.message).toMatch(regexp);
expect(error!.message).toMatch(regexp);
expect(mockConsoleError).toBeCalledTimes(0);
expect(mockConsoleError).toBeCalledTimes(0);
});
test("an error in mounted call will reject the mount promise", async () => {
class Root extends Component {
class App extends Component {
static template = xml`<div>abc</div>`;
setup() {
onMounted(() => {
@@ -205,21 +183,21 @@ describe("errors and promises", () => {
}
}
const app = new App(Root);
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle");
await mountProm;
let error: Error;
try {
await mount(App, fixture);
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.cause).toBeDefined();
expect(error!.cause.message).toBe("boom");
expect(error!.message).toBe("boom");
expect(fixture.innerHTML).toBe("");
expect(mockConsoleError).toBeCalledTimes(0);
expect(mockConsoleWarn).toBeCalledTimes(1);
});
test("an error in onMounted callback will have the component's setup in its stack trace", async () => {
class Root extends Component {
class App extends Component {
static template = xml`<div>abc</div>`;
setup() {
onMounted(() => {
@@ -228,13 +206,14 @@ describe("errors and promises", () => {
}
}
const app = new App(Root, { test: true });
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occurred in onMounted");
await mountProm;
let error: Error;
try {
await mount(App, fixture, { test: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.stack).toContain("Root.setup");
expect(error!.stack).toContain("App.setup");
expect(error!.stack).toContain("error_handling.test.ts");
expect(fixture.innerHTML).toBe("");
expect(mockConsoleError).toBeCalledTimes(0);
@@ -242,7 +221,7 @@ describe("errors and promises", () => {
});
test("errors in onWillRender/onRender aren't wrapped more than once", async () => {
class Root extends Component {
class App extends Component {
static template = xml`<div>abc</div>`;
setup() {
onWillRender(() => {
@@ -254,11 +233,12 @@ describe("errors and promises", () => {
}
}
const app = new App(Root, { test: true });
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occurred in onWillRender");
await mountProm;
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"`
@@ -284,29 +264,6 @@ describe("errors and promises", () => {
expect(error!.message).toBe("Tokenizer error: could not tokenize `{ 'invalid: 5 }`");
});
test("wrapped errors in async code are correctly caught", async () => {
class Root extends Component {
static template = xml`<div>abc</div>`;
setup() {
onWillStart(async () => {
await Promise.resolve();
throw new Error("boom in onWillStart");
});
}
}
const app = new App(Root, { test: true });
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occurred in onWillStart");
await mountProm;
expect(error!).toBeDefined();
expect(error!.message).toBe(
`The following error occurred in onWillStart: "boom in onWillStart"`
);
await new Promise((r) => setTimeout(r, 0)); // wait for the rejection event to bubble
});
test("an error in willPatch call will reject the render promise", async () => {
class Root extends Component {
static template = xml`<div><t t-esc="val"/></div>`;
@@ -358,21 +315,21 @@ describe("errors and promises", () => {
class Child extends Component {
static template = xml`<div><t t-esc="this.will.crash"/></div>`;
}
class Parent extends Component {
class App extends Component {
static template = xml`<div><Child/></div>`;
static components = { Child };
}
const app = new App(Parent);
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle");
await mountProm;
let error: Error;
try {
await mount(App, fixture);
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.cause).toBeDefined();
const regexp =
/Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g;
expect(error!.cause.message).toMatch(regexp);
expect(error!.message).toMatch(regexp);
expect(mockConsoleError).toBeCalledTimes(0);
expect(mockConsoleWarn).toBeCalledTimes(1);
});
@@ -382,7 +339,7 @@ describe("errors and promises", () => {
static template = xml`<div><t t-if="flag" t-esc="this.will.crash"/></div>`;
flag = false;
setup() {
onError(({ cause }) => (error = cause));
onError((e) => (error = e));
}
}
@@ -409,16 +366,16 @@ describe("errors and promises", () => {
static components = { Child };
}
const app = new App(Parent);
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle");
await mountProm;
let error: Error;
try {
await mount(Parent, fixture);
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.cause).toBeDefined();
const regexp =
/Cannot read properties of undefined \(reading 'y'\)|Cannot read property 'y' of undefined/g;
expect(error!.cause.message).toMatch(regexp);
expect(error!.message).toMatch(regexp);
expect(mockConsoleError).toBeCalledTimes(0);
expect(mockConsoleWarn).toBeCalledTimes(1);
});
@@ -439,12 +396,13 @@ describe("errors and promises", () => {
}
}
const app = new App(Example, { test: true });
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occurred in onMounted");
await mountProm;
expect(error!.message).toBe(`The following error occurred in onMounted: "Error in mounted"`);
try {
await mount(Example, fixture, { test: true });
} catch (e) {
expect((e as Error).message).toBe(
`The following error occurred in onMounted: "Error in mounted"`
);
}
// 1 additional error is logged because the destruction of the app causes
// the onWillUnmount hook to be called and to fail
expect(mockConsoleError).toBeCalledTimes(1);
@@ -461,10 +419,9 @@ describe("errors and promises", () => {
root.state = "boom";
root.render();
await expect(nextAppError(root.__owl__.app)).resolves.toThrow(
"error occured in the owl lifecycle"
);
await nextTick();
expect(fixture.innerHTML).toBe("");
expect(mockConsoleError).toBeCalledTimes(1);
expect(mockConsoleWarn).toBeCalledTimes(1);
});
});
@@ -514,150 +471,17 @@ describe("can catch errors", () => {
});
}
}
const app = new App(Root, { test: true });
let error: OwlError;
const crashProm = expect(nextAppError(app)).resolves.toThrow("error occurred in onWillStart");
await app.mount(fixture).catch((e: Error) => (error = e));
await crashProm;
expect(error!.message).toBe(
let e: Error;
try {
await mount(Root, fixture, { test: true });
} catch (error) {
e = error as Error;
}
expect(e!.message).toBe(
`The following error occurred in onWillStart: "No active component (a hook function should only be called in 'setup')"`
);
});
test("Errors have the right cause", async () => {
const err = new Error("test error");
class Root extends Component {
static template = xml`<t t-esc="state.value"/>`;
state = useState({ value: 1 });
setup() {
onMounted(() => {
throw err;
});
}
}
const app = new App(Root, { test: true });
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occurred in onMounted");
await mountProm;
expect(error!.message).toBe(`The following error occurred in onMounted: "test error"`);
expect(error!.cause).toBe(err);
});
test("Errors in owl lifecycle are wrapped in dev mode: async hook", async () => {
const err = new Error("test error");
class Root extends Component {
static template = xml`<t t-esc="state.value"/>`;
state = useState({ value: 1 });
setup() {
onWillStart(async () => {
await nextMicroTick();
throw err;
});
}
}
const app = new App(Root, { test: true });
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occurred in onWillStart");
await mountProm;
expect(error!.message).toBe(`The following error occurred in onWillStart: "test error"`);
expect(error!.cause).toBe(err);
});
test("Errors in owl lifecycle are wrapped outside dev mode: sync hook", async () => {
const err = new Error("test error");
class Root extends Component {
static template = xml`<t t-esc="state.value"/>`;
state = useState({ value: 1 });
setup() {
onMounted(() => {
throw err;
});
}
}
const app = new App(Root);
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle");
await mountProm;
expect(error!.message).toBe(
`An error occured in the owl lifecycle (see this Error's "cause" property)`
);
expect(error!.cause).toBe(err);
});
test("Errors in owl lifecycle are wrapped out of dev mode: async hook", async () => {
const err = new Error("test error");
class Root extends Component {
static template = xml`<t t-esc="state.value"/>`;
state = useState({ value: 1 });
setup() {
onWillStart(async () => {
await nextMicroTick();
throw err;
});
}
}
const app = new App(Root);
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle");
await mountProm;
expect(error!.message).toBe(
`An error occured in the owl lifecycle (see this Error's "cause" property)`
);
expect(error!.cause).toBe(err);
});
test("Thrown values that are not errors are wrapped in dev mode", async () => {
class Root extends Component {
static template = xml`<t t-esc="state.value"/>`;
state = useState({ value: 1 });
setup() {
onMounted(() => {
throw "This is not an error";
});
}
}
const app = new App(Root, { test: true });
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("not an Error was thrown in onMounted");
await mountProm;
expect(error!.message).toBe(
`Something that is not an Error was thrown in onMounted (see this Error's "cause" property)`
);
expect(error!.cause).toBe("This is not an error");
});
test("Thrown values that are not errors are wrapped outside dev mode", async () => {
class Root extends Component {
static template = xml`<t t-esc="state.value"/>`;
state = useState({ value: 1 });
setup() {
onMounted(() => {
throw "This is not an error";
});
}
}
const app = new App(Root);
let error: OwlError;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle");
await mountProm;
expect(error!.message).toBe(
`An error occured in the owl lifecycle (see this Error's "cause" property)`
);
expect(error!.cause).toBe("This is not an error");
});
test("can catch an error in the initial call of a component render function (parent mounted)", async () => {
class ErrorComponent extends Component {
static template = xml`<div>hey<t t-esc="state.this.will.crash"/></div>`;
@@ -1356,8 +1180,8 @@ describe("can catch errors", () => {
class Catch extends Component {
static template = xml`<t t-slot="default" />`;
setup() {
onError(({ cause }) => {
this.props.onError(cause);
onError((error) => {
this.props.onError(error);
});
}
}
-18
View File
@@ -171,22 +171,4 @@ describe("event handling", () => {
// input is removed when component is destroyed => nothing should happen
expect([]).toBeLogged();
});
test("handler works when app is mounted in an iframe", async () => {
let clickCount = 0;
class Parent extends Component {
static template = xml`<span t-on-click="inc">click me</span>`;
inc() {
clickCount++;
}
}
const iframe = document.createElement("iframe");
fixture.appendChild(iframe);
const iframeDoc = iframe.contentDocument!;
await mount(Parent, iframeDoc.body);
expect(clickCount).toBe(0);
iframeDoc.querySelector("span")!.click();
expect(clickCount).toBe(1);
});
});
+6 -15
View File
@@ -17,16 +17,8 @@ import {
useChildSubEnv,
useSubEnv,
xml,
OwlError,
} from "../../src/index";
import {
elem,
logStep,
makeTestFixture,
nextAppError,
nextTick,
snapshotEverything,
} from "../helpers";
import { elem, logStep, makeTestFixture, nextTick, snapshotEverything } from "../helpers";
let fixture: HTMLElement;
@@ -658,12 +650,11 @@ describe("hooks", () => {
}
}
let error: OwlError;
const app = new App(MyComponent);
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle");
await mountProm;
expect(error!.cause.message).toBe("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;
+111 -124
View File
@@ -1,6 +1,6 @@
import { makeTestFixture, nextAppError, nextTick, snapshotEverything } from "../helpers";
import { Component, onError, xml, mount, OwlError } from "../../src";
import { App, DEV_MSG } from "../../src/runtime/app";
import { makeTestFixture, nextTick, snapshotEverything } from "../helpers";
import { Component, onError, xml, mount } from "../../src";
import { DEV_MSG } from "../../src/runtime/app";
import { validateProps } from "../../src/runtime/template_helpers";
import { Schema } from "../../src/runtime/validation";
@@ -48,14 +48,13 @@ describe("props validation", () => {
static components = { SubComp };
static template = xml`<div><SubComp /></div>`;
}
let error: Error | undefined;
const app = new App(Parent, { test: true });
let error: OwlError | undefined;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow(
"Invalid props for component 'SubComp': 'message' is missing"
);
await mountProm;
try {
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe("Invalid props for component 'SubComp': 'message' is missing");
error = undefined;
@@ -78,13 +77,12 @@ describe("props validation", () => {
static template = xml`<div><SubComp /></div>`;
}
const app = new App(Parent, { test: true });
let error: OwlError | undefined;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow(
"Invalid props for component 'SubComp': 'message' is missing"
);
await mountProm;
let error: Error;
try {
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe("Invalid props for component 'SubComp': 'message' is missing");
});
@@ -128,12 +126,14 @@ describe("props validation", () => {
};
(Parent as any).components = { SubComp };
let error: Error | undefined;
props = {};
let app = new App(Parent, { test: true });
let error: OwlError | undefined;
let mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component '_a'");
await mountProm;
try {
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
`Invalid props for component '_a': 'p' is undefined (should be a ${test.type.name.toLowerCase()})`
@@ -147,10 +147,11 @@ describe("props validation", () => {
}
expect(error!).toBeUndefined();
props = { p: test.ko };
app = new App(Parent, { test: true });
mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component '_a'");
await mountProm;
try {
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
`Invalid props for component '_a': 'p' is not a ${test.type.name.toLowerCase()}`
@@ -180,12 +181,13 @@ describe("props validation", () => {
static template = xml`<div>hey</div>`;
};
(Parent as any).components = { SubComp };
let error: Error | undefined;
props = {};
let app = new App(Parent, { test: true });
let error: OwlError | undefined;
let mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component '_a'");
await mountProm;
try {
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
`Invalid props for component '_a': 'p' is undefined (should be a ${test.type.name.toLowerCase()})`
@@ -199,10 +201,11 @@ describe("props validation", () => {
}
expect(error!).toBeUndefined();
props = { p: test.ko };
app = new App(Parent, { test: true });
mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component '_a'");
await mountProm;
try {
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
`Invalid props for component '_a': 'p' is not a ${test.type.name.toLowerCase()}`
@@ -224,25 +227,26 @@ describe("props validation", () => {
}
let error: Error;
let props: { p?: any };
props = { p: "string" };
try {
props = { p: "string" };
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeUndefined();
props = { p: true };
try {
props = { p: true };
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeUndefined();
props = { p: 1 };
const app = new App(Parent, { test: true });
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'");
await mountProm;
try {
props = { p: 1 };
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
"Invalid props for component 'SubComp': 'p' is not a string or boolean"
@@ -263,25 +267,26 @@ describe("props validation", () => {
}
let error: Error;
let props: { p?: any };
props = { p: "key" };
try {
props = { p: "key" };
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeUndefined();
props = {};
try {
props = {};
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeUndefined();
props = { p: 1 };
const app = new App(Parent, { test: true });
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'");
await mountProm;
try {
props = { p: 1 };
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe("Invalid props for component 'SubComp': 'p' is not a string");
});
@@ -314,18 +319,20 @@ describe("props validation", () => {
error = e as Error;
}
expect(error!).toBeUndefined();
props = { p: [1] };
let app = new App(Parent, { test: true });
let mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'");
await mountProm;
try {
props = { p: [1] };
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
error = undefined;
app = new App(Parent, { test: true });
mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'");
await mountProm;
expect(error!).toBeDefined();
try {
props = { p: ["string", 1] };
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
});
test("can validate an array with multiple sub element types", async () => {
@@ -363,11 +370,12 @@ describe("props validation", () => {
error = e as Error;
}
expect(error!).toBeUndefined();
props = { p: [true, 1] };
const app = new App(Parent, { test: true });
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'");
await mountProm;
try {
props = { p: [true, 1] };
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
"Invalid props for component 'SubComp': 'p[1]' is not a string or boolean"
@@ -397,30 +405,33 @@ describe("props validation", () => {
error = e as Error;
}
expect(error!).toBeUndefined();
props = { p: { id: 1, url: "url", extra: true } };
let app = new App(Parent, { test: true });
let mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'");
await mountProm;
try {
props = { p: { id: 1, url: "url", extra: true } };
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
"Invalid props for component 'SubComp': 'p' has not the correct shape (unknown key 'extra')"
);
props = { p: { id: "1", url: "url" } };
app = new App(Parent, { test: true });
mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'");
await mountProm;
try {
props = { p: { id: "1", url: "url" } };
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
"Invalid props for component 'SubComp': 'p' has not the correct shape ('id' is not a number)"
);
error = undefined;
props = { p: { id: 1 } };
app = new App(Parent, { test: true });
mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'");
await mountProm;
try {
props = { p: { id: 1 } };
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
"Invalid props for component 'SubComp': 'p' has not the correct shape ('url' is missing (should be a string))"
@@ -463,11 +474,12 @@ describe("props validation", () => {
error = e as Error;
}
expect(error!).toBeUndefined();
props = { p: { id: 1, url: [12, true] } };
const app = new App(Parent, { test: true });
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'");
await mountProm;
try {
props = { p: { id: 1, url: [12, true] } };
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
"Invalid props for component 'SubComp': 'p' has not the correct shape ('url' is not a boolean or list of numbers)"
@@ -674,10 +686,11 @@ describe("props validation", () => {
static components = { SubComp };
}
let error: Error;
const app = new App(Parent, { test: true });
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'");
await mountProm;
try {
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe("Invalid props for component 'SubComp': 'p' is missing");
});
@@ -741,10 +754,11 @@ describe("props validation", () => {
static template = xml`<div><Child/></div>`;
}
let error: Error;
const app = new App(Parent, { test: true });
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'Child'");
await mountProm;
try {
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
"Invalid props for component 'Child': 'mandatory' is missing (should be a number)"
@@ -780,32 +794,6 @@ describe("props validation", () => {
// we just check that it doesn't throw
await expect(mount(Parent, fixture, { dev: true })).resolves.toEqual(expect.anything());
});
test("can validate through slots", async () => {
class Child extends Component {
static props = ["message"];
static template = xml`<div>hey</div>`;
}
class Wrapper extends Component {
static template = xml`<t t-slot="default"/>`;
}
class Parent extends Component {
static components = { Child, Wrapper };
static template = xml`<Wrapper><Child /></Wrapper>`;
}
const app = new App(Parent, { test: true });
let error: OwlError | undefined;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow(
"Invalid props for component 'Child': 'message' is missing"
);
await mountProm;
expect(error!).toBeDefined();
expect(error!.message).toBe("Invalid props for component 'Child': 'message' is missing");
});
});
//------------------------------------------------------------------------------
@@ -871,12 +859,11 @@ describe("default props", () => {
static template = xml`<Child/>`;
}
let error: Error;
const app = new App(Parent, { test: true });
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow(
"default value cannot be defined for a mandatory prop"
);
await mountProm;
try {
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
"A default value cannot be defined for a mandatory prop (name: 'mandatory', component: Child)"
+5 -10
View File
@@ -1,5 +1,5 @@
import { App, Component, mount, onMounted, useRef, useState } from "../../src/index";
import { logStep, makeTestFixture, nextAppError, nextTick, snapshotEverything } from "../helpers";
import { Component, mount, onMounted, useRef, useState } from "../../src/index";
import { logStep, makeTestFixture, nextTick, snapshotEverything } from "../helpers";
import { xml } from "../../src/index";
snapshotEverything();
@@ -94,14 +94,9 @@ describe("refs", () => {
ref = useRef("coucou");
}
const app = new App(Test, { test: true });
const mountProm = expect(app.mount(fixture)).rejects.toThrowError(
"Cannot have 2 elements with same ref name at the same time"
);
await expect(nextAppError(app)).resolves.toThrow(
"Cannot have 2 elements with same ref name at the same time"
);
await mountProm;
await expect(async () => {
await mount(Test, fixture);
}).rejects.toThrowError("Cannot have 2 elements with same ref name at the same time");
expect(console.warn).toBeCalledTimes(1);
console.warn = consoleWarn;
});
+8 -135
View File
@@ -1,5 +1,5 @@
import { App, Component, mount, onMounted, useState, xml } from "../../src/index";
import { children, makeTestFixture, nextAppError, nextTick, snapshotEverything } from "../helpers";
import { children, makeTestFixture, nextTick, snapshotEverything } from "../helpers";
snapshotEverything();
let originalconsoleWarn = console.warn;
@@ -45,23 +45,6 @@ describe("slots", () => {
expect(fixture.innerHTML).toBe("some text");
});
test("t-set-slot=default has priority over rest of the content", async () => {
class Child extends Component {
static template = xml`<t t-slot="default"/>`;
}
class Parent extends Component {
static template = xml`<Child>
some text
<t t-set-slot="default">some other text</t>
</Child>`;
static components = { Child };
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("some other text");
});
test("simple slot with slot scope", async () => {
let child: any;
class Child extends Component {
@@ -221,12 +204,13 @@ describe("slots", () => {
static components = { Child };
}
let error: Error;
const app = new App(Parent);
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle");
await mountProm;
expect(error!).not.toBeNull();
let error = null;
try {
await mount(Parent, fixture);
} catch (e) {
error = e;
}
expect(error).not.toBeNull();
expect(mockConsoleWarn).toBeCalledTimes(1);
});
@@ -1835,115 +1819,4 @@ describe("slots", () => {
await nextTick();
expect(fixture.innerHTML).toBe("<button>inc</button>[B][C][A][sub1] [sub2334]");
});
test("slot in multiple locations", async () => {
class Child extends Component {
static template = xml`<div>child</div>`;
}
class Slotter extends Component {
static components = { Child };
static template = xml`
<t t-if="props.location === 1">
<p><t t-slot="default"/></p>
</t>
<t t-if="props.location === 2">
<t t-slot="default"/>
</t>
`;
}
class Parent extends Component {
static components = { Child, Slotter };
static template = xml`
<Slotter location="state.location">
hello <Child/>
</Slotter>`;
state = useState({ location: 1 });
}
const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<p> hello <div>child</div></p>");
parent.state.location = 2;
await nextTick();
expect(fixture.innerHTML).toBe(" hello <div>child</div>");
});
test("dynamic slot in multiple locations", async () => {
class Child extends Component {
static template = xml`<div>child</div>`;
}
class Slotter extends Component {
static components = { Child };
static template = xml`
<t t-if="props.location === 1">
<p><t t-slot="{{'coffee'}}"/></p>
</t>
<t t-if="props.location === 2">
<t t-slot="{{'coffee'}}"/>
</t>
`;
}
class Parent extends Component {
static components = { Child, Slotter };
static template = xml`
<Slotter location="state.location">
<t t-set-slot="coffee">hello <Child/></t>
</Slotter>`;
state = useState({ location: 1 });
}
const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<p>hello <div>child</div></p>");
parent.state.location = 2;
await nextTick();
expect(fixture.innerHTML).toBe("hello <div>child</div>");
});
test("slot in t-foreach locations", async () => {
class Child extends Component {
static template = xml`<div>child</div>`;
}
class Slotter extends Component {
static components = { Child };
static template = xml`
<t t-foreach="props.list" t-as="elem" t-key="elem_index">
<p><t t-esc="elem"/><t t-slot="default"/></p>
</t>
`;
}
class Parent extends Component {
static components = { Child, Slotter };
static template = xml`
<Slotter list="state.list">
hello <Child/>
</Slotter>`;
state = useState({ list: [1] });
}
const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<p>1 hello <div>child</div></p>");
parent.state.list.push(2);
await nextTick();
expect(fixture.innerHTML).toBe(
"<p>1 hello <div>child</div></p><p>2 hello <div>child</div></p>"
);
});
test("default content is available as 0", async () => {
class Dialog extends Component {
static template = xml`<t t-slot="default">default content</t>`;
}
class Parent extends Component {
static template = xml`<Dialog>Before - <t t-out="0"/> - After</Dialog>`;
static components = { Dialog };
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("Before - default content - After");
});
});
+10 -11
View File
@@ -1,6 +1,5 @@
import { OwlError } from "../../src/runtime/error_handling";
import { App, Component, mount, onMounted, useState, xml } from "../../src";
import { makeTestFixture, nextAppError, nextTick, snapshotEverything } from "../helpers";
import { Component, mount, onMounted, useState, xml } from "../../src";
import { makeTestFixture, nextTick, snapshotEverything } from "../helpers";
snapshotEverything();
let fixture: HTMLElement;
@@ -343,20 +342,20 @@ describe("style and class handling", () => {
class Child extends Component {
static template = xml`<div t-att-class="props.class" t-esc="this.will.crash"/>`;
}
class Parent extends Component {
class ParentWidget extends Component {
static template = xml`<Child class="'a'"/>`;
static components = { Child };
}
let error: OwlError;
const app = new App(Parent);
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle");
await mountProm;
let error: Error;
try {
await mount(ParentWidget, fixture);
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.cause).toBeDefined();
const regexp =
/Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g;
expect(error!.cause.message).toMatch(regexp);
expect(error!.message).toMatch(regexp);
expect(fixture.innerHTML).toBe("");
expect(mockConsoleWarn).toBeCalledTimes(1);
});
-96
View File
@@ -287,100 +287,4 @@ describe("t-call", () => {
});
expect(fixture.innerHTML).toBe("childaaronchildlucas");
});
test("t-call with t-call-context and subcomponent, in dev mode", async () => {
class Child extends Component {
static template = xml`child<t t-esc="props.name"/>`;
static props = ["name"];
}
class Root extends Component {
static template = xml`
<t t-call="someTemplate" t-call-context="subctx"/>`;
static components = { Child };
subctx = { aab: "aaron", lpe: "lucas" };
}
await mount(Root, fixture, {
test: true,
templates: `
<templates>
<t t-name="someTemplate">
<Child name="aab"/>
<Child name="lpe"/>
</t>
</templates>`,
});
expect(fixture.innerHTML).toBe("childaaronchildlucas");
});
test("t-call-context: ComponentNode is not looked up in the context", async () => {
let child: any;
class Child extends Component {
static template = xml`<t t-slot="default"/>`;
static props = ["name"];
setup() {
child = this;
}
}
class Root extends Component {
static template = xml`
<t t-call="someTemplate" t-call-context="{method: function(){}}"/>`;
static components = { Child };
}
// The following things need a reference to the ComponentNode, historically
// we used to do this with ctx.__owl__, but this cannot work inside t-call-context
// - t-ref: node.refs[refName] = something
// - t-set: caused a call to capture, which used to use node.component
// - .bind: used to bind to node.component
const root = await mount(Root, fixture, {
templates: `
<templates>
<t t-name="someTemplate">
<div t-ref="myRef">outside slot</div>
<Child prop.bind="method">
<div t-ref="myRef2">I'm the default slot</div>
<t t-set="test" t-value="3"/>
<div t-esc="this.__owl__.name"/>
<div t-esc="test"/>
</Child>
</t>
</templates>`,
});
expect(fixture.innerHTML).toBe(
"<div>outside slot</div><div>I'm the default slot</div><div>Root</div><div>3</div>"
);
expect(Object.keys(child.__owl__.refs)).toEqual([]);
expect(Object.keys(root.__owl__.refs)).toEqual(["myRef", "myRef2"]);
});
test("t-call-context: slots don't make component available again when context is captured", async () => {
class Child extends Component {
static template = xml`<t t-slot="default"/>`;
}
class Root extends Component {
static template = xml`<t t-call="template" t-call-context="{}"/>`;
static components = { Child };
someValue = "Hello";
}
await mount(Root, fixture, {
test: true,
templates: `
<templates>
<t t-name="template">
<t t-set="dummy" t-value="0"/>
<Child>
<t t-esc="someValue"/>
</Child>
</t>
</templates>`,
});
expect(fixture.innerHTML).toBe("");
});
});
+5 -74
View File
@@ -1,11 +1,5 @@
import { App, Component, mount, onMounted, useState, xml } from "../../src/index";
import {
makeTestFixture,
nextAppError,
nextTick,
snapshotEverything,
useLogLifecycle,
} from "../helpers";
import { Component, mount, onMounted, useState, xml } from "../../src/index";
import { makeTestFixture, nextTick, snapshotEverything, useLogLifecycle } from "../helpers";
snapshotEverything();
@@ -321,73 +315,10 @@ describe("list of components", () => {
`;
static components = { Child };
}
const app = new App(Parent, { test: true });
const mountProm = expect(app.mount(fixture)).rejects.toThrow(
"Got duplicate key in t-foreach: child"
);
await expect(nextAppError(app)).resolves.toThrow("Got duplicate key in t-foreach: child");
await mountProm;
await expect(async () => {
await mount(Parent, fixture, { dev: true });
}).rejects.toThrowError("Got duplicate key in t-foreach: child");
console.info = consoleInfo;
expect(mockConsoleWarn).toBeCalledTimes(1);
});
test("crash when using object as keys that serialize to the same string", async () => {
const consoleInfo = console.info;
console.info = jest.fn();
class Child extends Component {
static template = xml``;
}
class Parent extends Component {
static template = xml`
<t t-foreach="[{}, {}]" t-as="item" t-key="item">
<Child/>
</t>
`;
static components = { Child };
}
const app = new App(Parent, { test: true });
const mountProm = expect(app.mount(fixture)).rejects.toThrow(
"Got duplicate key in t-foreach: [object Object]"
);
await expect(nextAppError(app)).resolves.toThrow(
"Got duplicate key in t-foreach: [object Object]"
);
await mountProm;
console.info = consoleInfo;
expect(mockConsoleWarn).toBeCalledTimes(1);
});
test("order is correct when slots are not of same type", async () => {
class Child extends Component {
static template = xml`
<t t-slot="{{ slotName }}" t-foreach="slotNames" t-as="slotName" t-key="slotName"/>
`;
get slotNames() {
return Object.entries(this.props.slots)
.filter((entry: any) => entry[1].active)
.map((entry) => entry[0]);
}
}
class Parent extends Component {
static template = xml`
<Child>
<t t-set-slot="a" active="!state.active"><div t-if="!state.active">A</div></t>
<t t-set-slot="b" active="true">B</t>
<t t-set-slot="c" active="state.active">C</t>
</Child>
`;
static components = { Child };
state = useState({ active: false });
}
const parent = await mount(Parent, fixture);
expect(fixture.textContent).toBe("AB");
parent.state.active = true;
await nextTick();
expect(fixture.textContent).toBe("BC");
});
});
-19
View File
@@ -625,23 +625,4 @@ describe("t-model directive", () => {
await mount(Test, fixture);
expect(fixture.querySelector("select")!.value).toEqual("b");
});
test("t-model is applied before t-on-input", async () => {
expect.assertions(3);
class SomeComponent extends Component {
static template = xml`
<div>
<input t-model="state['text']" t-on-input="onInput"/>
</div>
`;
state = useState({ text: "", other: "" });
onInput(ev: InputEvent) {
expect(this.state.text).toBe("Beam me up, Scotty");
expect((ev.target as HTMLInputElement).value).toBe("Beam me up, Scotty");
}
}
await mount(SomeComponent, fixture);
const input = fixture.querySelector("input")!;
await editInput(input, "Beam me up, Scotty");
});
});
-24
View File
@@ -41,30 +41,6 @@ describe("t-on", () => {
expect(steps).toEqual(["click"]);
});
test("t-on when first component child is an empty component", async () => {
class Child extends Component {
static template = xml`
<span t-foreach="props.list" t-as="c" t-key="c_index" t-esc="c"/>
`;
}
class Parent extends Component {
static template = xml`
<div t-on-click="push"><Child list="list" t-on-click="() => {}"/></div>
`;
static components = { Child };
list = useState([] as string[]);
push() {
this.list.push("foo");
}
}
const parent = await mount(Parent, fixture);
const el = elem(parent);
expect(el.innerHTML).toBe("");
el.click();
await nextTick();
expect(el.innerHTML).toBe("<span>foo</span>");
});
test("t-on expression in t-foreach", async () => {
class Comp extends Component {
static template = xml`
-36
View File
@@ -1,36 +0,0 @@
import { Component, mount, xml } from "../../src/index";
import { makeTestFixture, snapshotEverything } from "../helpers";
snapshotEverything();
// -----------------------------------------------------------------------------
// t-out
// -----------------------------------------------------------------------------
describe("components in t-out", () => {
let fixture: HTMLElement;
beforeEach(() => {
fixture = makeTestFixture();
});
test("simple list", async () => {
class Child extends Component {
static template = xml`child`;
}
class Parent extends Component {
static template = xml`
<t t-foreach="[1,2]" t-as="n" t-key="n">
<t t-set="blabla">
<Child />
</t>
<t t-out="blabla"/>
</t>`;
static components = { Child };
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("childchild");
});
});
+2 -17
View File
@@ -19,7 +19,6 @@ import { helpers } from "../src/runtime/template_helpers";
import { TemplateSet, globalTemplates } from "../src/runtime/template_set";
import { BDom } from "../src/runtime/blockdom";
import { compile } from "../src/compiler";
import { OwlError } from "../src/runtime/error_handling";
const mount = blockDom.mount;
@@ -96,7 +95,7 @@ export function renderToBdom(template: string, context: any = {}, node?: any): B
createComponent() {},
createDynamicComponent() {},
};
return fn(app as any, blockDom, helpers).call(context, context, node);
return fn(app as any, blockDom, helpers)(context, node);
}
export function renderToString(template: string, context: any = {}, node?: any): string {
@@ -222,7 +221,7 @@ export async function editInput(input: HTMLInputElement | HTMLTextAreaElement, v
afterEach(() => {
if (steps.length) {
steps.splice(0);
throw new OwlError("Remaining steps! Should be checked by a .toBeLogged() assertion!");
throw new Error("Remaining steps! Should be checked by a .toBeLogged() assertion!");
}
});
@@ -261,20 +260,6 @@ expect.extend({
},
});
export function nextAppError(app: any) {
const { handleError } = app;
return new Promise((resolve) => {
app.handleError = (...args: Parameters<typeof handleError>) => {
try {
handleError.call(app, ...args);
} catch (e: any) {
app.handleError = handleError;
resolve(e);
}
};
});
}
declare global {
namespace jest {
interface Matchers<R> {
File diff suppressed because it is too large Load Diff
+20 -61
View File
@@ -1,4 +1,3 @@
import { OwlError } from "../../src/runtime/error_handling";
import {
App,
Component,
@@ -12,7 +11,7 @@ import {
} from "../../src";
import { xml } from "../../src/";
import { DEV_MSG } from "../../src/runtime/app";
import { elem, makeTestFixture, nextAppError, nextTick, snapshotEverything } from "../helpers";
import { elem, makeTestFixture, nextTick, snapshotEverything } from "../helpers";
let fixture: HTMLElement;
let originalconsoleWarn = console.warn;
@@ -269,14 +268,15 @@ describe("Portal", () => {
}
let error: Error;
const app = new App(Parent);
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("invalid portal target");
await mountProm;
try {
await mount(Parent, fixture);
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe("invalid portal target");
expect(fixture.innerHTML).toBe(``);
expect(fixture.innerHTML).toBe(`<div></div>`);
expect(mockConsoleWarn).toBeCalledTimes(1);
});
@@ -499,7 +499,7 @@ describe("Portal", () => {
</div>`;
state = { error: false };
setup() {
onError(({ cause }) => (error = cause));
onError((e) => (error = e));
}
}
addOutsideDiv(fixture);
@@ -874,48 +874,6 @@ describe("Portal", () => {
await nextTick();
expect(fixture.innerHTML).toBe('<div id="outside"></div><div></div>');
});
test("Child and Portal", async () => {
class Child extends Component {
static template = xml`
<span>child</span>
<t t-portal="'.portal'"><span>portal</span></t>`;
}
class Parent extends Component {
static template = xml`
<t>
<Child/>
<div class="portal"></div>
</t>`;
static components = { Child };
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe(
'<span>child</span><div class="portal"><span>portal</span></div>'
);
});
test("portal and Child", async () => {
class Child extends Component {
static template = xml`
<span>child</span>
<t t-portal="'.portal'"><span>portal</span></t>`;
}
class Parent extends Component {
static template = xml`
<t>
<div class="portal"></div>
<Child/>
</t>`;
static components = { Child };
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe(
'<div class="portal"><span>portal</span></div><span>child</span>'
);
});
});
describe("Portal: UI/UX", () => {
@@ -1000,14 +958,14 @@ describe("Portal: Props validation", () => {
</t>
</div>`;
}
let error: OwlError;
const app = new App(Parent);
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle");
await mountProm;
let error: Error;
try {
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.cause).toBeDefined();
expect(error!.cause.message).toBe(`' ' is not a valid selector`);
expect(error!.message).toBe(`' ' is not a valid selector`);
});
test("target must be a valid selector 2", async () => {
@@ -1020,10 +978,11 @@ describe("Portal: Props validation", () => {
</div>`;
}
let error: Error;
const app = new App(Parent);
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow("invalid portal target");
await mountProm;
try {
await mount(Parent, fixture, { dev: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(`invalid portal target`);
});
+3 -69
View File
@@ -9,7 +9,7 @@ import {
markRaw,
toRaw,
} from "../src";
import { reactive, getSubscriptions } from "../src/runtime/reactivity";
import { reactive, Reactive } from "../src/runtime/reactivity";
import { batched } from "../src/runtime/utils";
import {
makeDeferred,
@@ -1020,32 +1020,6 @@ describe("Reactivity", () => {
expect(n3).toBe(2);
});
test("reactive inside other: reading the inner reactive from outer doesn't affect the inner's subscriptions", async () => {
const getObservedKeys = (obj: any) => getSubscriptions(obj).flatMap(({ keys }) => keys);
let n1 = 0;
let n2 = 0;
const innerCb = () => n1++;
const outerCb = () => n2++;
const inner = createReactive({ a: 1 }, innerCb);
const outer = createReactive({ b: inner }, outerCb);
expect(n1).toBe(0);
expect(n2).toBe(0);
expect(getObservedKeys(innerCb)).toEqual([]);
expect(getObservedKeys(outerCb)).toEqual([]);
outer.b.a;
expect(getObservedKeys(innerCb)).toEqual([]);
expect(getObservedKeys(outerCb)).toEqual(["b", "a"]);
expect(n1).toBe(0);
expect(n2).toBe(0);
outer.b.a = 2;
expect(getObservedKeys(innerCb)).toEqual([]);
expect(getObservedKeys(outerCb)).toEqual([]);
expect(n1).toBe(0);
expect(n2).toBe(1);
});
// test("notification is not done after unregistration", async () => {
// let n = 0;
// const observer = () => n++;
@@ -1168,46 +1142,6 @@ describe("Reactivity", () => {
expect(() => state.a).not.toThrow();
expect(state.a).toBe(obj.a);
});
test("writing on object with reactive in prototype chain doesn't notify", async () => {
let n = 0;
const state = createReactive({ val: 0 }, () => n++);
const nonReactive = Object.create(state);
nonReactive.val++;
expect(n).toBe(0);
expect(toRaw(state)).toEqual({ val: 0 });
expect(toRaw(nonReactive)).toEqual({ val: 1 });
state.val++;
expect(n).toBe(1);
expect(toRaw(state)).toEqual({ val: 1 });
expect(toRaw(nonReactive)).toEqual({ val: 1 });
});
test("creating key on object with reactive in prototype chain doesn't notify", async () => {
let n = 0;
const parent = createReactive({}, () => n++);
const child = Object.create(parent);
Object.keys(parent); // Subscribe to key changes
child.val = 0;
expect(n).toBe(0);
});
test("reactive of object with reactive in prototype chain is not the object from the prototype chain", async () => {
const cb = () => {};
const parent = createReactive({ val: 0 }, cb);
const child = createReactive(Object.create(parent), cb);
expect(child).not.toBe(parent);
});
test("can create reactive of object with non-reactive in prototype chain", async () => {
let n = 0;
const parent = markRaw({ val: 0 });
const child = createReactive(Object.create(parent), () => n++);
child.val++;
expect(n).toBe(1);
expect(parent).toEqual({ val: 0 });
expect(child).toEqual({ val: 1 });
});
});
describe("Collections", () => {
@@ -1765,12 +1699,12 @@ describe("toRaw", () => {
const obj = { value: 1 };
const reactiveObj = reactive(obj);
expect(reactiveObj).not.toBe(obj);
expect(toRaw(reactiveObj)).toBe(obj);
expect(toRaw(reactiveObj as Reactive<typeof obj>)).toBe(obj);
});
test("giving a non reactive to toRaw return the object itself", () => {
const obj = { value: 1 };
expect(toRaw(obj)).toBe(obj);
expect(toRaw(obj as Reactive<typeof obj>)).toBe(obj);
});
});
+3 -1
View File
@@ -72,8 +72,10 @@ async function startRelease() {
}
// ---------------------------------------------------------------------------
log(`Step 3/${STEPS}: updating package.json...`);
log(`Step 3/${STEPS}: updating package.json, readme.md and roadmap.md...`);
await replaceInFile("./package.json", current, next);
await replaceInFile("./README.md", current, next);
await replaceInFile("./roadmap.md", current, next);
// ---------------------------------------------------------------------------
log(`Step 4/${STEPS}: creating git commit...`);