mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b1e79677cb | |||
| 89d6b8b7dd | |||
| 9c2523e3ce | |||
| d8201b8955 | |||
| dfead2836e | |||
| 0e0ac5329a |
@@ -948,7 +948,7 @@ export class CodeGenerator {
|
||||
let propString = propStr;
|
||||
if (ast.dynamicProps) {
|
||||
if (!props.length) {
|
||||
propString = `${compileExpr(ast.dynamicProps)}`;
|
||||
propString = `Object.assign({}, ${compileExpr(ast.dynamicProps)})`;
|
||||
} else {
|
||||
propString = `Object.assign({}, ${compileExpr(ast.dynamicProps)}, ${propStr})`;
|
||||
}
|
||||
@@ -1012,7 +1012,7 @@ export class CodeGenerator {
|
||||
keyArg = `${ctx.tKeyExpr} + ${keyArg}`;
|
||||
}
|
||||
const blockArgs = `${expr}, ${propString}, ${keyArg}, node, ctx`;
|
||||
let blockExpr = `component(${blockArgs})`;
|
||||
let blockExpr = `component(${blockArgs}${hasSlot ? ", true" : ""})`;
|
||||
if (Object.keys(extraArgs).length) {
|
||||
this.shouldDefineAssign = true;
|
||||
const content = Object.keys(extraArgs).map((k) => `${k}: ${extraArgs[k]}`);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import type { Env } from "../app/app";
|
||||
import type { ComponentNode } from "./component_node";
|
||||
|
||||
export type Props = { [key: string]: any };
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Component Class
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -26,7 +28,7 @@ export class Component {
|
||||
|
||||
setup() {}
|
||||
|
||||
render(): Promise<void> {
|
||||
return this.__owl__.render();
|
||||
render(deep: boolean = false): Promise<void> {
|
||||
return this.__owl__.render(deep);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import type { App, Env } from "../app/app";
|
||||
import { BDom, VNode } from "../blockdom";
|
||||
import { Component } from "./component";
|
||||
import { clearReactivesForCallback, Reactive, reactive } from "../reactivity";
|
||||
import { batched, Callback } from "../utils";
|
||||
import { Component, Props } from "./component";
|
||||
import { fibersInError, handleError } from "./error_handling";
|
||||
import {
|
||||
Fiber,
|
||||
makeChildFiber,
|
||||
@@ -8,20 +11,68 @@ import {
|
||||
MountFiber,
|
||||
MountOptions,
|
||||
RootFiber,
|
||||
__internal__destroyed,
|
||||
__internal__destroyed
|
||||
} from "./fibers";
|
||||
import { handleError, fibersInError } from "./error_handling";
|
||||
import { applyDefaultProps } from "./props_validation";
|
||||
import { STATUS } from "./status";
|
||||
import { applyStyles } from "./style";
|
||||
|
||||
let currentNode: ComponentNode | null = null;
|
||||
|
||||
export function getCurrent(): ComponentNode | null {
|
||||
return currentNode;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Integration with reactivity system (useState)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const batchedRenderFunctions = new WeakMap<ComponentNode, Callback>();
|
||||
/**
|
||||
* Creates a reactive object that will be observed by the current component.
|
||||
* Reading data from the returned object (eg during rendering) will cause the
|
||||
* component to subscribe to that data and be rerendered when it changes.
|
||||
*
|
||||
* @param state the state to observe
|
||||
* @returns a reactive object that will cause the component to re-render on
|
||||
* relevant changes
|
||||
* @see reactive
|
||||
*/
|
||||
export function useState<T extends object>(state: T): Reactive<T> {
|
||||
if (!batchedRenderFunctions.has(currentNode!)) {
|
||||
batchedRenderFunctions.set(
|
||||
currentNode!,
|
||||
batched(() => currentNode!.render())
|
||||
);
|
||||
}
|
||||
const render = batchedRenderFunctions.get(currentNode!)!;
|
||||
const reactiveState = reactive(state, render);
|
||||
|
||||
// manual implementation of onWillUnmount to break cyclic dependency
|
||||
currentNode!.willUnmount.unshift( clearReactivesForCallback.bind(null, render))
|
||||
return reactiveState;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// component function (used in compiled template code)
|
||||
// -----------------------------------------------------------------------------
|
||||
function arePropsDifferent(props1: Props, props2: Props): boolean {
|
||||
for (let k in props1) {
|
||||
if (props1[k] !== props2[k]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export function component(
|
||||
name: string | typeof Component,
|
||||
props: any,
|
||||
key: string,
|
||||
ctx: ComponentNode,
|
||||
parent: any
|
||||
parent: any,
|
||||
hasSlots: boolean = false
|
||||
): ComponentNode {
|
||||
console.warn('asdf')
|
||||
let node: any = ctx.children[key];
|
||||
let isDynamic = typeof name !== "string";
|
||||
|
||||
@@ -39,7 +90,11 @@ export function component(
|
||||
|
||||
const parentFiber = ctx.fiber!;
|
||||
if (node) {
|
||||
node.updateAndRender(props, parentFiber);
|
||||
console.warn('coucou');
|
||||
if (hasSlots || parentFiber.deep || arePropsDifferent(node.component.props, props)) {
|
||||
console.warn('coucou3');
|
||||
node.updateAndRender(props, parentFiber);
|
||||
}
|
||||
} else {
|
||||
// new component
|
||||
let C;
|
||||
@@ -61,15 +116,9 @@ export function component(
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Component VNode
|
||||
// Component VNode class
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
let currentNode: ComponentNode | null = null;
|
||||
|
||||
export function getCurrent(): ComponentNode | null {
|
||||
return currentNode;
|
||||
}
|
||||
|
||||
type LifecycleHook = Function;
|
||||
|
||||
export class ComponentNode<T extends typeof Component = typeof Component>
|
||||
@@ -106,6 +155,9 @@ export class ComponentNode<T extends typeof Component = typeof Component>
|
||||
applyDefaultProps(props, C);
|
||||
const env = (parent && parent.childEnv) || app.env;
|
||||
this.childEnv = env;
|
||||
// if (props) {
|
||||
// props = useState(props);
|
||||
// }
|
||||
this.component = new C(props, env, this) as any;
|
||||
this.renderFn = app.getTemplate(C.template).bind(this.component, this.component, this);
|
||||
if (C.style) {
|
||||
@@ -137,7 +189,7 @@ export class ComponentNode<T extends typeof Component = typeof Component>
|
||||
}
|
||||
}
|
||||
|
||||
async render() {
|
||||
async render(deep: boolean = false) {
|
||||
let fiber = this.fiber;
|
||||
if (fiber && !fiber.bdom && !fibersInError.has(fiber)) {
|
||||
return fiber.root.promise;
|
||||
@@ -147,6 +199,7 @@ export class ComponentNode<T extends typeof Component = typeof Component>
|
||||
return;
|
||||
}
|
||||
fiber = makeRootFiber(this);
|
||||
fiber.deep = deep;
|
||||
this.app.scheduler.addFiber(fiber);
|
||||
await Promise.resolve();
|
||||
if (this.status === STATUS.DESTROYED) {
|
||||
@@ -241,6 +294,10 @@ export class ComponentNode<T extends typeof Component = typeof Component>
|
||||
}
|
||||
|
||||
patch() {
|
||||
if (!this.fiber) {
|
||||
// component was not rendered => no need to do anything
|
||||
return;
|
||||
}
|
||||
this.bdom!.patch(this!.fiber!.bdom!, false);
|
||||
this.fiber!.appliedToDom = true;
|
||||
this.fiber = null;
|
||||
|
||||
@@ -67,6 +67,7 @@ export class Fiber {
|
||||
parent: Fiber | null;
|
||||
children: Fiber[] = [];
|
||||
appliedToDom = false;
|
||||
deep: boolean = false;
|
||||
|
||||
constructor(node: ComponentNode, parent: Fiber | null) {
|
||||
this.node = node;
|
||||
|
||||
+2
-1
@@ -34,6 +34,7 @@ import type { AppConfig } from "./app/app";
|
||||
import { App } from "./app/app";
|
||||
import { Component } from "./component/component";
|
||||
import { getCurrent } from "./component/component_node";
|
||||
export { useState } from "./component/component_node";
|
||||
|
||||
export { App, Component };
|
||||
|
||||
@@ -55,7 +56,7 @@ export { status } from "./component/status";
|
||||
export { Portal } from "./portal";
|
||||
export { Memo } from "./memo";
|
||||
export { css, xml } from "./tags";
|
||||
export { useState, reactive } from "./reactivity";
|
||||
export { reactive } from "./reactivity";
|
||||
export { useEffect, useEnv, useExternalListener, useRef, useSubEnv } from "./hooks";
|
||||
export { EventBus, whenReady, loadFile, markup } from "./utils";
|
||||
|
||||
|
||||
+3
-53
@@ -1,5 +1,4 @@
|
||||
import { onWillUnmount } from "./component/lifecycle_hooks";
|
||||
import { ComponentNode, getCurrent } from "./component/component_node";
|
||||
import { Callback } from "./utils";
|
||||
|
||||
// Allows to get the target of a Reactive (used for making a new Reactive from the underlying object)
|
||||
const TARGET = Symbol("Target");
|
||||
@@ -8,8 +7,7 @@ const KEYCHANGES = Symbol("Key changes");
|
||||
|
||||
type ObjectKey = string | number | symbol;
|
||||
type Target = object;
|
||||
type Callback = () => void;
|
||||
type Reactive<T extends Target = Target> = T & {
|
||||
export type Reactive<T extends Target = Target> = T & {
|
||||
[TARGET]: any;
|
||||
};
|
||||
|
||||
@@ -81,7 +79,7 @@ const callbacksToTargets = new WeakMap<Callback, Set<Target>>();
|
||||
*
|
||||
* @param callback the callback for which the reactives need to be cleared
|
||||
*/
|
||||
function clearReactivesForCallback(callback: Callback): void {
|
||||
export function clearReactivesForCallback(callback: Callback): void {
|
||||
const targetsToClear = callbacksToTargets.get(callback);
|
||||
if (!targetsToClear) {
|
||||
return;
|
||||
@@ -190,51 +188,3 @@ export function reactive<T extends Target>(target: T, callback: Callback): React
|
||||
return reactivesForTarget.get(callback) as Reactive<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a batched version of a callback so that all calls to it in the same
|
||||
* microtick will only call the original callback once.
|
||||
*
|
||||
* @param callback the callback to batch
|
||||
* @returns a batched version of the original callback
|
||||
*/
|
||||
export function batched(callback: Callback): Callback {
|
||||
let called = false;
|
||||
return async () => {
|
||||
// This await blocks all calls to the callback here, then releases them sequentially
|
||||
// in the next microtick. This line decides the granularity of the batch.
|
||||
await Promise.resolve();
|
||||
if (!called) {
|
||||
called = true;
|
||||
callback();
|
||||
// wait for all calls in this microtick to fall through before resetting "called"
|
||||
// so that only the first call to the batched function calls the original callback
|
||||
await Promise.resolve();
|
||||
called = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const batchedRenderFunctions = new WeakMap<ComponentNode, Callback>();
|
||||
/**
|
||||
* Creates a reactive object that will be observed by the current component.
|
||||
* Reading data from the returned object (eg during rendering) will cause the
|
||||
* component to subscribe to that data and be rerendered when it changes.
|
||||
*
|
||||
* @param state the state to observe
|
||||
* @returns a reactive object that will cause the component to re-render on
|
||||
* relevant changes
|
||||
* @see reactive
|
||||
*/
|
||||
export function useState<T extends object>(state: T): Reactive<T> {
|
||||
const node = getCurrent()!;
|
||||
if (!batchedRenderFunctions.has(node)) {
|
||||
batchedRenderFunctions.set(
|
||||
node,
|
||||
batched(() => node.render())
|
||||
);
|
||||
}
|
||||
const render = batchedRenderFunctions.get(node)!;
|
||||
const reactiveState = reactive(state, render);
|
||||
onWillUnmount(() => clearReactivesForCallback(render));
|
||||
return reactiveState;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
export type Callback = () => void;
|
||||
|
||||
/**
|
||||
* Creates a batched version of a callback so that all calls to it in the same
|
||||
* microtick will only call the original callback once.
|
||||
*
|
||||
* @param callback the callback to batch
|
||||
* @returns a batched version of the original callback
|
||||
*/
|
||||
export function batched(callback: Callback): Callback {
|
||||
let called = false;
|
||||
return async () => {
|
||||
// This await blocks all calls to the callback here, then releases them sequentially
|
||||
// in the next microtick. This line decides the granularity of the batch.
|
||||
await Promise.resolve();
|
||||
if (!called) {
|
||||
called = true;
|
||||
callback();
|
||||
// wait for all calls in this microtick to fall through before resetting "called"
|
||||
// so that only the first call to the batched function calls the original callback
|
||||
await Promise.resolve();
|
||||
called = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export class EventBus extends EventTarget {
|
||||
trigger(name: string, payload?: any) {
|
||||
this.dispatchEvent(new CustomEvent(name, { detail: payload }));
|
||||
|
||||
@@ -1020,7 +1020,7 @@ exports[`basics update props of component without concrete own node 3`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const tKey_1 = ctx['childProps'].key;
|
||||
let b2 = toggler(tKey_1, component(\`Child\`, ctx['childProps'], tKey_1 + key + \`__2\`, node, ctx));
|
||||
let b2 = toggler(tKey_1, component(\`Child\`, Object.assign({}, ctx['childProps']), tKey_1 + key + \`__2\`, node, ctx));
|
||||
return block1([], [b2]);
|
||||
}
|
||||
}"
|
||||
|
||||
@@ -1067,7 +1067,7 @@ exports[`properly behave when destroyed/unmounted while rendering 2`] = `
|
||||
let block1 = createBlock(\`<div><block-child-0/></div>\`);
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b2 = component(\`SubChild\`, {}, key + \`__1\`, node, ctx);
|
||||
let b2 = component(\`SubChild\`, {val: ctx['props'].val}, key + \`__1\`, node, ctx);
|
||||
return block1([], [b2]);
|
||||
}
|
||||
}"
|
||||
|
||||
@@ -126,7 +126,7 @@ exports[`can catch errors can catch an error in a component render function 3`]
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -230,7 +230,7 @@ exports[`can catch errors can catch an error in the constructor call of a compon
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b5 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b5 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b5]);
|
||||
}
|
||||
}"
|
||||
@@ -250,7 +250,7 @@ exports[`can catch errors can catch an error in the constructor call of a compon
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -305,7 +305,7 @@ exports[`can catch errors can catch an error in the initial call of a component
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -362,7 +362,7 @@ exports[`can catch errors can catch an error in the initial call of a component
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3;
|
||||
if (ctx['state'].flag) {
|
||||
b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
return block1([], [b3]);
|
||||
}
|
||||
@@ -417,7 +417,7 @@ exports[`can catch errors can catch an error in the mounted call 3`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -473,7 +473,7 @@ exports[`can catch errors can catch an error in the willPatch call 3`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let d1 = ctx['state'].message;
|
||||
let b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([d1], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -527,7 +527,7 @@ exports[`can catch errors can catch an error in the willStart call 3`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -597,7 +597,7 @@ exports[`can catch errors can catch an error origination from a child's willStar
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b5 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b5 = assign(component(\`ErrorBoundary\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b5]);
|
||||
}
|
||||
}"
|
||||
|
||||
@@ -555,7 +555,7 @@ exports[`lifecycle hooks onWillRender 2`] = `
|
||||
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers;
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return component(\`Child\`, {}, key + \`__1\`, node, ctx);
|
||||
return component(\`Child\`, {someValue: ctx['state'].value}, key + \`__1\`, node, ctx);
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
@@ -53,7 +53,7 @@ exports[`refs refs are properly bound in slots 2`] = `
|
||||
const refs = ctx.__owl__.refs;
|
||||
let d1 = ctx['state'].val;
|
||||
const ctx2 = capture(ctx);
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'footer': slot3(ctx2)}});
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'footer': slot3(ctx2)}});
|
||||
return block1([d1], [b3]);
|
||||
}
|
||||
}"
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`rendering semantics blabla 1`] = `
|
||||
"function anonymous(bdom, helpers
|
||||
) {
|
||||
let { text, createBlock, list, multi, html, toggler, component } = bdom;
|
||||
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers;
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return text(ctx['props'].a.b);
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`rendering semantics blabla 2`] = `
|
||||
"function anonymous(bdom, helpers
|
||||
) {
|
||||
let { text, createBlock, list, multi, html, toggler, component } = bdom;
|
||||
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers;
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return component(\`Child\`, {a: ctx['state']}, key + \`__1\`, node, ctx);
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`rendering semantics can force a render to update sub tree 1`] = `
|
||||
"function anonymous(bdom, helpers
|
||||
) {
|
||||
let { text, createBlock, list, multi, html, toggler, component } = bdom;
|
||||
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers;
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return text(\`child\`);
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`rendering semantics can force a render to update sub tree 2`] = `
|
||||
"function anonymous(bdom, helpers
|
||||
) {
|
||||
let { text, createBlock, list, multi, html, toggler, component } = bdom;
|
||||
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers;
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b2 = text(ctx['state'].value);
|
||||
let b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
|
||||
return multi([b2, b3]);
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`rendering semantics can render a parent without rendering child 1`] = `
|
||||
"function anonymous(bdom, helpers
|
||||
) {
|
||||
let { text, createBlock, list, multi, html, toggler, component } = bdom;
|
||||
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers;
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return text(\`child\`);
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`rendering semantics can render a parent without rendering child 2`] = `
|
||||
"function anonymous(bdom, helpers
|
||||
) {
|
||||
let { text, createBlock, list, multi, html, toggler, component } = bdom;
|
||||
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers;
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b2 = text(ctx['state'].value);
|
||||
let b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
|
||||
return multi([b2, b3]);
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -37,7 +37,7 @@ exports[`slots can define and call slots 2`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b4 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'header': slot3(ctx2), 'footer': slot4(ctx2)}});
|
||||
let b4 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'header': slot3(ctx2), 'footer': slot4(ctx2)}});
|
||||
return block1([], [b4]);
|
||||
}
|
||||
}"
|
||||
@@ -74,7 +74,7 @@ exports[`slots can render node with t-ref and Component in same slot 2`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const refs = ctx.__owl__.refs;
|
||||
return assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
return assign(component(\`Child\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -117,7 +117,7 @@ exports[`slots content is the default slot (variation) 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
return assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -152,7 +152,7 @@ exports[`slots content is the default slot 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -226,7 +226,7 @@ exports[`slots default content is not rendered if named slot is provided 2`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'header': slot3(ctx2)}});
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'header': slot3(ctx2)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -265,7 +265,7 @@ exports[`slots default content is not rendered if slot is provided 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -310,7 +310,7 @@ exports[`slots default slot next to named slot, with default content 2`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'footer': slot3(ctx2)}});
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'footer': slot3(ctx2)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -340,7 +340,7 @@ exports[`slots default slot work with text nodes (variation) 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
return assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -374,7 +374,7 @@ exports[`slots default slot work with text nodes 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -422,7 +422,7 @@ exports[`slots dynamic t-slot call 2`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b6 = assign(component(\`Toggler\`, {}, key + \`__1\`, node, ctx), {slots: {'slot1': slot3(ctx2), 'slot2': slot4(ctx2)}});
|
||||
let b6 = assign(component(\`Toggler\`, {}, key + \`__1\`, node, ctx, true), {slots: {'slot1': slot3(ctx2), 'slot2': slot4(ctx2)}});
|
||||
return block1([], [b6]);
|
||||
}
|
||||
}"
|
||||
@@ -473,7 +473,7 @@ exports[`slots dynamic t-slot call with default 2`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b6 = assign(component(\`Toggler\`, {}, key + \`__1\`, node, ctx), {slots: {'slot1': slot3(ctx2), 'slot2': slot4(ctx2)}});
|
||||
let b6 = assign(component(\`Toggler\`, {}, key + \`__1\`, node, ctx, true), {slots: {'slot1': slot3(ctx2), 'slot2': slot4(ctx2)}});
|
||||
return block1([], [b6]);
|
||||
}
|
||||
}"
|
||||
@@ -505,7 +505,7 @@ exports[`slots fun: two calls to the same slot 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
return assign(component(\`Child\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -574,7 +574,7 @@ exports[`slots multiple roots are allowed in a default slot 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b5 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b5 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b5]);
|
||||
}
|
||||
}"
|
||||
@@ -614,7 +614,7 @@ exports[`slots multiple roots are allowed in a named slot 2`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b5 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'content': slot3(ctx2)}});
|
||||
let b5 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'content': slot3(ctx2)}});
|
||||
return block1([], [b5]);
|
||||
}
|
||||
}"
|
||||
@@ -668,7 +668,7 @@ exports[`slots multiple slots containing components 3`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
return assign(component(\`B\`, {}, key + \`__1\`, node, ctx), {slots: {'s1': slot3(ctx2), 's2': slot5(ctx2)}});
|
||||
return assign(component(\`B\`, {}, key + \`__1\`, node, ctx, true), {slots: {'s1': slot3(ctx2), 's2': slot5(ctx2)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -707,7 +707,7 @@ exports[`slots named slot inside slot 2`] = `
|
||||
|
||||
const slot4 = ctx => (node, key) => {
|
||||
const ctx6 = capture(ctx);
|
||||
return assign(component(\`Child\`, {}, key + \`__5\`, node, ctx), {slots: {'brol': slot7(ctx6)}});
|
||||
return assign(component(\`Child\`, {}, key + \`__5\`, node, ctx, true), {slots: {'brol': slot7(ctx6)}});
|
||||
}
|
||||
|
||||
const slot7 = ctx => (node, key) => {
|
||||
@@ -717,7 +717,7 @@ exports[`slots named slot inside slot 2`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b5 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'brol': slot3(ctx2), 'default': slot4(ctx2)}});
|
||||
let b5 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx, true), {slots: {'brol': slot3(ctx2), 'default': slot4(ctx2)}});
|
||||
return block1([], [b5]);
|
||||
}
|
||||
}"
|
||||
@@ -757,7 +757,7 @@ exports[`slots named slot inside slot, part 3 2`] = `
|
||||
|
||||
const slot4 = ctx => (node, key) => {
|
||||
const ctx6 = capture(ctx);
|
||||
return assign(component(\`Child\`, {}, key + \`__5\`, node, ctx), {slots: {'brol': slot7(ctx6)}});
|
||||
return assign(component(\`Child\`, {}, key + \`__5\`, node, ctx, true), {slots: {'brol': slot7(ctx6)}});
|
||||
}
|
||||
|
||||
const slot7 = ctx => (node, key) => {
|
||||
@@ -767,7 +767,7 @@ exports[`slots named slot inside slot, part 3 2`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b5 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'brol': slot3(ctx2), 'default': slot4(ctx2)}});
|
||||
let b5 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx, true), {slots: {'brol': slot3(ctx2), 'default': slot4(ctx2)}});
|
||||
return block1([], [b5]);
|
||||
}
|
||||
}"
|
||||
@@ -850,7 +850,7 @@ exports[`slots named slots inside slot, again 2`] = `
|
||||
|
||||
const slot4 = ctx => (node, key) => {
|
||||
const ctx6 = capture(ctx);
|
||||
return assign(component(\`Child\`, {}, key + \`__5\`, node, ctx), {slots: {'brol2': slot7(ctx6)}});
|
||||
return assign(component(\`Child\`, {}, key + \`__5\`, node, ctx, true), {slots: {'brol2': slot7(ctx6)}});
|
||||
}
|
||||
|
||||
const slot7 = ctx => (node, key) => {
|
||||
@@ -860,7 +860,7 @@ exports[`slots named slots inside slot, again 2`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b5 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'brol1': slot3(ctx2), 'default': slot4(ctx2)}});
|
||||
let b5 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx, true), {slots: {'brol1': slot3(ctx2), 'default': slot4(ctx2)}});
|
||||
return block1([], [b5]);
|
||||
}
|
||||
}"
|
||||
@@ -920,7 +920,7 @@ exports[`slots nested slots in same template 4`] = `
|
||||
let block1 = createBlock(\`<span id=\\"parent\\"><block-child-0/></span>\`);
|
||||
|
||||
const slot2 = ctx => (node, key) => {
|
||||
return assign(component(\`Child2\`, {}, key + \`__3\`, node, ctx), {slots: {'default': slot4(ctx)}});
|
||||
return assign(component(\`Child2\`, {}, key + \`__3\`, node, ctx, true), {slots: {'default': slot4(ctx)}});
|
||||
}
|
||||
|
||||
const slot4 = ctx => (node, key) => {
|
||||
@@ -928,7 +928,7 @@ exports[`slots nested slots in same template 4`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b4 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b4 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b4]);
|
||||
}
|
||||
}"
|
||||
@@ -976,7 +976,7 @@ exports[`slots nested slots: evaluation context and parented relationship 3`] =
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return assign(component(\`GrandChild\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
return assign(component(\`GrandChild\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -993,7 +993,7 @@ exports[`slots nested slots: evaluation context and parented relationship 4`] =
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
return assign(component(\`Child\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -1052,7 +1052,7 @@ exports[`slots simple default slot 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
return assign(component(\`Child\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -1081,7 +1081,7 @@ exports[`slots simple default slot, variation 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
return assign(component(\`Child\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -1131,7 +1131,7 @@ exports[`slots slot and (inline) t-call 3`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot3(ctx2)}});
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot3(ctx2)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -1182,7 +1182,7 @@ exports[`slots slot and t-call 3`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot3(ctx2)}});
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot3(ctx2)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -1217,7 +1217,7 @@ exports[`slots slot and t-esc 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -1270,7 +1270,7 @@ exports[`slots slot are properly rendered if inner props are changed 3`] = `
|
||||
const v1 = ctx['inc'];
|
||||
let d1 = [v1, ctx];
|
||||
let d2 = ctx['state'].val;
|
||||
let b3 = assign(component(\`GenericComponent\`, {}, key + \`__2\`, node, ctx), {slots: {'default': slot3(ctx)}});
|
||||
let b3 = assign(component(\`GenericComponent\`, {}, key + \`__2\`, node, ctx, true), {slots: {'default': slot3(ctx)}});
|
||||
return block1([d1, d2], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -1307,7 +1307,7 @@ exports[`slots slot content is bound to caller 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
return assign(component(\`Child\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -1350,7 +1350,7 @@ exports[`slots slot preserves properly parented relationship 3`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -1408,7 +1408,7 @@ exports[`slots slot preserves properly parented relationship, even through t-cal
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b3 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot3(ctx2)}});
|
||||
let b3 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot3(ctx2)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -1441,7 +1441,7 @@ exports[`slots slots and wrapper components 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return assign(component(\`Link\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
return assign(component(\`Link\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -1480,7 +1480,7 @@ exports[`slots slots are rendered with proper context 2`] = `
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let d1 = ctx['state'].val;
|
||||
const ctx2 = capture(ctx);
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'footer': slot3(ctx2)}});
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'footer': slot3(ctx2)}});
|
||||
return block1([d1], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -1525,7 +1525,7 @@ exports[`slots slots are rendered with proper context, part 2 2`] = `
|
||||
ctx[\`user\`] = v_block2[i1];
|
||||
let key1 = ctx['user'].id;
|
||||
const ctx2 = capture(ctx);
|
||||
let b7 = assign(component(\`Link\`, {to: '/user/'+ctx['user'].id}, key + \`__1__\${key1}\`, node, ctx), {slots: {'default': slot3(ctx2)}});
|
||||
let b7 = assign(component(\`Link\`, {to: '/user/'+ctx['user'].id}, key + \`__1__\${key1}\`, node, ctx, true), {slots: {'default': slot3(ctx2)}});
|
||||
c_block2[i1] = withKey(block3([], [b7]), key1);
|
||||
}
|
||||
let b2 = list(c_block2);
|
||||
@@ -1574,7 +1574,7 @@ exports[`slots slots are rendered with proper context, part 3 2`] = `
|
||||
let key1 = ctx['user'].id;
|
||||
setContextValue(ctx, \\"userdescr\\", 'User '+ctx['user'].name);
|
||||
const ctx2 = capture(ctx);
|
||||
let b5 = assign(component(\`Link\`, {to: '/user/'+ctx['user'].id}, key + \`__1__\${key1}\`, node, ctx), {slots: {'default': slot3(ctx2)}});
|
||||
let b5 = assign(component(\`Link\`, {to: '/user/'+ctx['user'].id}, key + \`__1__\${key1}\`, node, ctx, true), {slots: {'default': slot3(ctx2)}});
|
||||
c_block2[i1] = withKey(block3([], [b5]), key1);
|
||||
}
|
||||
let b2 = list(c_block2);
|
||||
@@ -1617,7 +1617,7 @@ exports[`slots slots are rendered with proper context, part 4 2`] = `
|
||||
ctx[isBoundary] = 1
|
||||
setContextValue(ctx, \\"userdescr\\", 'User '+ctx['state'].user.name);
|
||||
const ctx2 = capture(ctx);
|
||||
let b3 = assign(component(\`Link\`, {to: '/user/'+ctx['state'].user.id}, key + \`__1\`, node, ctx), {slots: {'default': slot3(ctx2)}});
|
||||
let b3 = assign(component(\`Link\`, {to: '/user/'+ctx['state'].user.id}, key + \`__1\`, node, ctx, true), {slots: {'default': slot3(ctx2)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -1652,7 +1652,7 @@ exports[`slots slots in slots, with vars 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`B\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`B\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -1678,7 +1678,7 @@ exports[`slots slots in slots, with vars 3`] = `
|
||||
ctx[isBoundary] = 1
|
||||
setContextValue(ctx, \\"test\\", ctx['state'].name);
|
||||
const ctx2 = capture(ctx);
|
||||
let b3 = assign(component(\`A\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot3(ctx2)}});
|
||||
let b3 = assign(component(\`A\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot3(ctx2)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -1721,7 +1721,7 @@ exports[`slots slots in t-foreach and re-rendering 2`] = `
|
||||
ctx[\`n_index\`] = i1;
|
||||
let key1 = ctx['n_index'];
|
||||
const ctx2 = capture(ctx);
|
||||
c_block2[i1] = withKey(assign(component(\`Child\`, {}, key + \`__1__\${key1}\`, node, ctx), {slots: {'default': slot3(ctx2)}}), key1);
|
||||
c_block2[i1] = withKey(assign(component(\`Child\`, {}, key + \`__1__\${key1}\`, node, ctx, true), {slots: {'default': slot3(ctx2)}}), key1);
|
||||
}
|
||||
let b2 = list(c_block2);
|
||||
return block1([], [b2]);
|
||||
@@ -1775,7 +1775,7 @@ exports[`slots slots in t-foreach in t-foreach 2`] = `
|
||||
ctx[\`node2\`] = v_block6[i2];
|
||||
let key2 = ctx['node2'].key;
|
||||
const ctx2 = capture(ctx);
|
||||
c_block6[i2] = withKey(assign(component(\`Child\`, {}, key + \`__1__\${key1}__\${key2}\`, node, ctx), {slots: {'default': slot3(ctx2)}}), key2);
|
||||
c_block6[i2] = withKey(assign(component(\`Child\`, {}, key + \`__1__\${key1}__\${key2}\`, node, ctx, true), {slots: {'default': slot3(ctx2)}}), key2);
|
||||
}
|
||||
ctx = ctx.__proto__;
|
||||
let b6 = list(c_block6);
|
||||
@@ -1828,7 +1828,7 @@ exports[`slots slots in t-foreach with t-set and re-rendering 2`] = `
|
||||
let key1 = ctx['n_index'];
|
||||
setContextValue(ctx, \\"dummy\\", ctx['n_index']);
|
||||
const ctx2 = capture(ctx);
|
||||
c_block2[i1] = withKey(assign(component(\`Child\`, {}, key + \`__1__\${key1}\`, node, ctx), {slots: {'default': slot3(ctx2)}}), key1);
|
||||
c_block2[i1] = withKey(assign(component(\`Child\`, {}, key + \`__1__\${key1}\`, node, ctx, true), {slots: {'default': slot3(ctx2)}}), key1);
|
||||
}
|
||||
let b2 = list(c_block2);
|
||||
return block1([], [b2]);
|
||||
@@ -1867,7 +1867,7 @@ exports[`slots t-debug on a t-set-slot (defining a slot) 2`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'content': slot3(ctx2)}});
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'content': slot3(ctx2)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -1906,7 +1906,7 @@ exports[`slots t-set t-value in a slot 2`] = `
|
||||
ctx = Object.create(ctx);
|
||||
ctx[isBoundary] = 1
|
||||
const ctx2 = capture(ctx);
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot3(ctx2)}});
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot3(ctx2)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -1968,7 +1968,7 @@ exports[`slots t-slot in recursive templates 2`] = `
|
||||
ctx = Object.create(ctx);
|
||||
ctx[isBoundary] = 1
|
||||
const ctx2 = capture(ctx);
|
||||
return assign(component(\`Wrapper\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot3(ctx2)}});
|
||||
return assign(component(\`Wrapper\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot3(ctx2)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -2027,7 +2027,7 @@ exports[`slots t-slot nested within another slot 4`] = `
|
||||
let block1 = createBlock(\`<span id=\\"c2\\"><block-child-0/></span>\`);
|
||||
|
||||
const slot2 = ctx => (node, key) => {
|
||||
return assign(component(\`Portal\`, {}, key + \`__3\`, node, ctx), {slots: {'default': slot4(ctx)}});
|
||||
return assign(component(\`Portal\`, {}, key + \`__3\`, node, ctx, true), {slots: {'default': slot4(ctx)}});
|
||||
}
|
||||
|
||||
const slot4 = ctx => (node, key) => {
|
||||
@@ -2035,7 +2035,7 @@ exports[`slots t-slot nested within another slot 4`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b4 = assign(component(\`Modal\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b4 = assign(component(\`Modal\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b4]);
|
||||
}
|
||||
}"
|
||||
@@ -2055,7 +2055,7 @@ exports[`slots t-slot nested within another slot 5`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -2090,7 +2090,7 @@ exports[`slots t-slot scope context 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return assign(component(\`Wrapper\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
return assign(component(\`Wrapper\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -2109,7 +2109,7 @@ exports[`slots t-slot scope context 3`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
return assign(component(\`Dialog\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -2174,7 +2174,7 @@ exports[`slots t-slot within dynamic t-call 4`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx2 = capture(ctx);
|
||||
let b3 = assign(component(\`Slotted\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot3(ctx2)}});
|
||||
let b3 = assign(component(\`Slotted\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot3(ctx2)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -2221,7 +2221,7 @@ exports[`slots template can just return a slot 3`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`SlotComponent\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`SlotComponent\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
|
||||
@@ -24,7 +24,7 @@ exports[`t-props basic use 2`] = `
|
||||
let block1 = createBlock(\`<div><block-child-0/></div>\`);
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b2 = component(\`Child\`, ctx['some'].obj, key + \`__1\`, node, ctx);
|
||||
let b2 = component(\`Child\`, Object.assign({}, ctx['some'].obj), key + \`__1\`, node, ctx);
|
||||
return block1([], [b2]);
|
||||
}
|
||||
}"
|
||||
@@ -85,7 +85,7 @@ exports[`t-props t-props only 2`] = `
|
||||
let block1 = createBlock(\`<div><div><block-child-0/></div></div>\`);
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b2 = component(\`Comp\`, ctx['state'], key + \`__1\`, node, ctx);
|
||||
let b2 = component(\`Comp\`, Object.assign({}, ctx['state']), key + \`__1\`, node, ctx);
|
||||
return block1([], [b2]);
|
||||
}
|
||||
}"
|
||||
|
||||
@@ -38,7 +38,7 @@ exports[`t-set slot setted value (with t-set) not accessible with t-esc 2`] = `
|
||||
setContextValue(ctx, \\"iter\\", 'source');
|
||||
let d1 = ctx['iter'];
|
||||
const ctx2 = capture(ctx);
|
||||
let b2 = assign(component(\`Childcomp\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot3(ctx2)}});
|
||||
let b2 = assign(component(\`Childcomp\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot3(ctx2)}});
|
||||
let d2 = ctx['iter'];
|
||||
return block1([d1, d2], [b2]);
|
||||
}
|
||||
|
||||
@@ -419,7 +419,7 @@ describe("basics", () => {
|
||||
expect(fixture.innerHTML).toBe("<div><span></span></div>");
|
||||
});
|
||||
|
||||
test("child can be updated", async () => {
|
||||
test.only("child can be updated", async () => {
|
||||
class Child extends Component {
|
||||
static template = xml`<t t-esc="props.value"/>`;
|
||||
}
|
||||
|
||||
@@ -543,7 +543,7 @@ test("properly behave when destroyed/unmounted while rendering ", async () => {
|
||||
}
|
||||
|
||||
class Child extends Component {
|
||||
static template = xml`<div><SubChild /></div>`;
|
||||
static template = xml`<div><SubChild val="props.val"/></div>`;
|
||||
static components = { SubChild };
|
||||
setup() {
|
||||
useLogLifecycle(steps);
|
||||
@@ -1900,18 +1900,13 @@ test("concurrent renderings scenario 13", async () => {
|
||||
"Child:willPatch",
|
||||
"Child:patched",
|
||||
"Parent:willRender",
|
||||
"Child:willUpdateProps",
|
||||
"Child:setup",
|
||||
"Child:willStart",
|
||||
"Parent:rendered",
|
||||
"Child:willRender",
|
||||
"Child:rendered",
|
||||
"Child:willRender",
|
||||
"Child:rendered",
|
||||
"Parent:willPatch",
|
||||
"Child:willPatch",
|
||||
"Child:mounted",
|
||||
"Child:patched",
|
||||
"Parent:patched",
|
||||
"Child:willRender",
|
||||
"Child:rendered",
|
||||
|
||||
@@ -899,8 +899,9 @@ describe("lifecycle hooks", () => {
|
||||
|
||||
class Parent extends Component {
|
||||
static template = xml`
|
||||
<Child />`;
|
||||
<Child someValue="state.value" />`;
|
||||
static components = { Child };
|
||||
state = useState({ value: 1 });
|
||||
setup() {
|
||||
useLogLifecycle(steps);
|
||||
}
|
||||
@@ -910,7 +911,7 @@ describe("lifecycle hooks", () => {
|
||||
|
||||
expect(fixture.innerHTML).toBe("<button>1</button>");
|
||||
|
||||
parent.render(); // to block child render
|
||||
parent.state.value++; // to block child render
|
||||
await nextTick();
|
||||
|
||||
fixture.querySelector("button")!.click();
|
||||
@@ -1063,22 +1064,18 @@ describe("lifecycle hooks", () => {
|
||||
steps.splice(0);
|
||||
c!.state.flag = false;
|
||||
await nextTick();
|
||||
expect(fixture.innerHTML).toBe(`<div>A<div>B</div><div>C<div>D</div><div>F</div></div></div>`);
|
||||
expect(steps).toEqual([
|
||||
"C:willRender",
|
||||
"D:willUpdateProps",
|
||||
"F:setup",
|
||||
"F:willStart",
|
||||
"C:rendered",
|
||||
"D:willRender",
|
||||
"D:rendered",
|
||||
"F:willRender",
|
||||
"F:rendered",
|
||||
"C:willPatch",
|
||||
"D:willPatch",
|
||||
"E:willUnmount",
|
||||
"E:destroyed",
|
||||
"F:mounted",
|
||||
"D:patched",
|
||||
"C:patched",
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
import { Component, mount, onRendered, useState } from "../../src";
|
||||
import { xml } from "../../src/tags";
|
||||
import { makeTestFixture, snapshotEverything, nextTick } from "../helpers";
|
||||
|
||||
let fixture: HTMLElement;
|
||||
|
||||
snapshotEverything();
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = makeTestFixture();
|
||||
});
|
||||
|
||||
describe("rendering semantics", () => {
|
||||
test("can render a parent without rendering child", async () => {
|
||||
let childN = 0;
|
||||
let parentN = 0;
|
||||
class Child extends Component {
|
||||
static template = xml`child`;
|
||||
setup() {
|
||||
onRendered(() => childN++);
|
||||
}
|
||||
}
|
||||
|
||||
class Parent extends Component {
|
||||
static template = xml`
|
||||
<t t-esc="state.value"/>
|
||||
<Child/>
|
||||
`;
|
||||
static components = { Child };
|
||||
|
||||
state = useState({ value: "A" });
|
||||
setup() {
|
||||
onRendered(() => parentN++);
|
||||
}
|
||||
}
|
||||
|
||||
const parent = await mount(Parent, fixture);
|
||||
|
||||
expect(fixture.innerHTML).toBe("Achild");
|
||||
expect(parentN).toBe(1);
|
||||
expect(childN).toBe(1);
|
||||
|
||||
parent.state.value = "B";
|
||||
await nextTick();
|
||||
expect(fixture.innerHTML).toBe("Bchild");
|
||||
expect(parentN).toBe(2);
|
||||
expect(childN).toBe(1);
|
||||
});
|
||||
|
||||
test("can force a render to update sub tree", async () => {
|
||||
let childN = 0;
|
||||
let parentN = 0;
|
||||
class Child extends Component {
|
||||
static template = xml`child`;
|
||||
setup() {
|
||||
onRendered(() => childN++);
|
||||
}
|
||||
}
|
||||
|
||||
class Parent extends Component {
|
||||
static template = xml`
|
||||
<t t-esc="state.value"/>
|
||||
<Child/>
|
||||
`;
|
||||
static components = { Child };
|
||||
|
||||
state = { value: "A" };
|
||||
setup() {
|
||||
onRendered(() => parentN++);
|
||||
}
|
||||
}
|
||||
|
||||
const parent = await mount(Parent, fixture);
|
||||
|
||||
expect(fixture.innerHTML).toBe("Achild");
|
||||
expect(parentN).toBe(1);
|
||||
expect(childN).toBe(1);
|
||||
|
||||
parent.state.value = "B";
|
||||
parent.render(true);
|
||||
await nextTick();
|
||||
expect(fixture.innerHTML).toBe("Bchild");
|
||||
expect(parentN).toBe(2);
|
||||
expect(childN).toBe(2);
|
||||
});
|
||||
|
||||
test("blabla", async () => {
|
||||
class Child extends Component {
|
||||
static template = xml`<t t-esc="props.a.b"/>`;
|
||||
|
||||
}
|
||||
|
||||
class Parent extends Component {
|
||||
static template = xml`
|
||||
<Child a="state"/>
|
||||
`;
|
||||
static components = { Child };
|
||||
|
||||
state = useState({ b: 1 });
|
||||
}
|
||||
|
||||
const parent = await mount(Parent, fixture);
|
||||
|
||||
expect(fixture.innerHTML).toBe("1");
|
||||
|
||||
parent.state.b = 3;
|
||||
await nextTick();
|
||||
expect(fixture.innerHTML).toBe("3");
|
||||
});
|
||||
});
|
||||
@@ -65,7 +65,7 @@ describe("t-props", () => {
|
||||
`;
|
||||
setup() {
|
||||
expect(this.props).toEqual({ a: 1, b: 2 });
|
||||
expect(this.props).toBe(props);
|
||||
expect(this.props).not.toBe(props);
|
||||
}
|
||||
}
|
||||
class Parent extends Component {
|
||||
|
||||
@@ -30,7 +30,7 @@ exports[`Memo if no prop change, prevent renderings from above 2`] = `
|
||||
let b2 = text(ctx['state'].a);
|
||||
let b3 = text(ctx['state'].b);
|
||||
let b4 = text(ctx['state'].c);
|
||||
let b9 = assign(component(\`Memo\`, {a: ctx['state'].a,b: ctx['state'].b}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b9 = assign(component(\`Memo\`, {a: ctx['state'].a,b: ctx['state'].b}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return multi([b2, b3, b4, b9]);
|
||||
}
|
||||
}"
|
||||
@@ -61,7 +61,7 @@ exports[`Memo if no props, prevent renderings from above 2`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b2 = component(\`Child\`, {value: ctx['state'].value}, key + \`__1\`, node, ctx);
|
||||
let b4 = assign(component(\`Memo\`, {}, key + \`__2\`, node, ctx), {slots: {'default': slot3(ctx)}});
|
||||
let b4 = assign(component(\`Memo\`, {}, key + \`__2\`, node, ctx, true), {slots: {'default': slot3(ctx)}});
|
||||
return multi([b2, b4]);
|
||||
}
|
||||
}"
|
||||
@@ -80,7 +80,7 @@ exports[`Memo if no props, prevent renderings from above (work with simple html)
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b2 = text(ctx['state'].value);
|
||||
let b4 = assign(component(\`Memo\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b4 = assign(component(\`Memo\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return multi([b2, b4]);
|
||||
}
|
||||
}"
|
||||
|
||||
@@ -28,7 +28,7 @@ exports[`Portal Portal composed with t-slot 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
return assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -47,7 +47,7 @@ exports[`Portal Portal composed with t-slot 3`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -68,7 +68,7 @@ exports[`Portal basic use of portal 1`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -106,7 +106,7 @@ exports[`Portal conditional use of Portal (with sub Component) 2`] = `
|
||||
let b2,b4;
|
||||
b2 = block2();
|
||||
if (ctx['state'].hasPortal) {
|
||||
b4 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
b4 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
return multi([b2, b4]);
|
||||
}
|
||||
@@ -131,7 +131,7 @@ exports[`Portal conditional use of Portal 1`] = `
|
||||
let b2,b4;
|
||||
b2 = block2();
|
||||
if (ctx['state'].hasPortal) {
|
||||
b4 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
b4 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
return multi([b2, b4]);
|
||||
}
|
||||
@@ -169,7 +169,7 @@ exports[`Portal lifecycle hooks of portal sub component are properly called 2`]
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3;
|
||||
if (ctx['state'].hasChild) {
|
||||
b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
}
|
||||
return block1([], [b3]);
|
||||
}
|
||||
@@ -196,7 +196,7 @@ exports[`Portal portal could have dynamically no content 1`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b4 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b4 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b4]);
|
||||
}
|
||||
}"
|
||||
@@ -231,7 +231,7 @@ exports[`Portal portal destroys on crash 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -266,7 +266,7 @@ exports[`Portal portal with child and props 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -295,7 +295,7 @@ exports[`Portal portal with dynamic body 1`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b5 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b5 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b5]);
|
||||
}
|
||||
}"
|
||||
@@ -319,7 +319,7 @@ exports[`Portal portal with many children 1`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b5 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b5 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b5]);
|
||||
}
|
||||
}"
|
||||
@@ -343,7 +343,7 @@ exports[`Portal portal with no content 1`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b4 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b4 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b4]);
|
||||
}
|
||||
}"
|
||||
@@ -363,7 +363,7 @@ exports[`Portal portal with only text as content 1`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -384,7 +384,7 @@ exports[`Portal portal with target not in dom 1`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Portal\`, {target: '#does-not-exist'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Portal\`, {target: '#does-not-exist'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -418,7 +418,7 @@ exports[`Portal portal's parent's env is not polluted 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -439,7 +439,7 @@ exports[`Portal with target in template (after portal) 1`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Portal\`, {target: '#local-target'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Portal\`, {target: '#local-target'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -460,7 +460,7 @@ exports[`Portal with target in template (before portal) 1`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Portal\`, {target: '#local-target'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Portal\`, {target: '#local-target'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -481,7 +481,7 @@ exports[`Portal: Props validation target is mandatory 1`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Portal\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Portal\`, {}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -502,7 +502,7 @@ exports[`Portal: Props validation target is not list 1`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Portal\`, {target: ['body']}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Portal\`, {target: ['body']}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
@@ -537,7 +537,7 @@ exports[`Portal: UI/UX focus is kept across re-renders 2`] = `
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
|
||||
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx, true), {slots: {'default': slot2(ctx)}});
|
||||
return block1([], [b3]);
|
||||
}
|
||||
}"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Component, mount, onWillRender, onWillStart, onWillUpdateProps, useState } from "../src";
|
||||
import { batched, reactive } from "../src/reactivity";
|
||||
import { reactive } from "../src/reactivity";
|
||||
import { xml } from "../src/tags";
|
||||
import { batched } from "../src/utils";
|
||||
import {
|
||||
makeDeferred,
|
||||
makeTestFixture,
|
||||
@@ -1509,7 +1510,7 @@ describe("Reactivity: useState", () => {
|
||||
expect([...steps]).toEqual(["list"]);
|
||||
await nextTick();
|
||||
expect(fixture.innerHTML).toBe("<div><div>3</div> Total: 3 Count: 1</div>");
|
||||
expect([...steps]).toEqual(["list", "quantity1"]);
|
||||
expect([...steps]).toEqual(["list"]);
|
||||
steps.clear();
|
||||
|
||||
secondQuantity.quantity = 2;
|
||||
|
||||
+19
-1
@@ -1,4 +1,5 @@
|
||||
import { EventBus } from "../src/utils";
|
||||
import { batched, EventBus } from "../src/utils";
|
||||
import { nextMicroTick } from "./helpers";
|
||||
|
||||
describe("event bus behaviour", () => {
|
||||
test("can subscribe and be notified", () => {
|
||||
@@ -33,3 +34,20 @@ describe("event bus behaviour", () => {
|
||||
bus.trigger("event", "hello world");
|
||||
});
|
||||
});
|
||||
|
||||
describe("batched", () => {
|
||||
test("callback is called only once after operations", async () => {
|
||||
let n = 0;
|
||||
let fn = batched(() => n++);
|
||||
|
||||
expect(n).toBe(0);
|
||||
fn();
|
||||
fn();
|
||||
expect(n).toBe(0);
|
||||
|
||||
await nextMicroTick();
|
||||
expect(n).toBe(1);
|
||||
await nextMicroTick();
|
||||
expect(n).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user