mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] component: various issues while mounting manually components
The initial problem solved by this commit is that it was possible to get into a situation where a mounting/rendering was started, then the component was updated, but then another mounting operation begins, and it tries to reuse the previous rendering operation, which is no longer uptodate. The underlying issue is that Owl did not track properly the various internal state change of a component. These issue should be solved by the introduction of the status enum, which currently tracks 6 possible states: - CREATED - WILLSTARTED - RENDERED - MOUNTED - UNMOUNTED - DESTROYED This status number replaces the isMounted and isDestroyed boolean flags. It has the advantage of making sure that the component is in a consistent state (it is no longer possible to be destroyed and mounted, for example) Another advantage is that it gives us an easy way to track the fact that a component has been rendered, but is not in the DOM. This is a subtle situation where some various events can happen, and we need to be able to react to that case. Note that there is a change of behaviour: if a component is mounted in a specific target, then before the mounting is complete, the component is mounted in another target, we no longer reject the first mounting operation.
This commit is contained in:
+83
-79
@@ -44,6 +44,15 @@ interface MountOptions {
|
||||
position?: MountPosition;
|
||||
}
|
||||
|
||||
export const enum STATUS {
|
||||
CREATED,
|
||||
WILLSTARTED, // willstart has been called
|
||||
RENDERED, // first render is completed (so, vnode is now defined)
|
||||
MOUNTED, // is ready, and in DOM. It has a valid el
|
||||
UNMOUNTED, // has a valid el, but is not in DOM
|
||||
DESTROYED,
|
||||
}
|
||||
|
||||
/**
|
||||
* This is mostly an internal detail of implementation. The Meta interface is
|
||||
* useful to typecheck and describe the internal keys used by Owl to manage the
|
||||
@@ -56,8 +65,7 @@ interface Internal<T extends Env> {
|
||||
depth: number;
|
||||
vnode: VNode | null;
|
||||
pvnode: VNode | null;
|
||||
isMounted: boolean;
|
||||
isDestroyed: boolean;
|
||||
status: STATUS;
|
||||
|
||||
// parent and children keys are obviously useful to setup the parent-children
|
||||
// relationship.
|
||||
@@ -164,16 +172,18 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
this.env.browser = browser;
|
||||
}
|
||||
this.env.qweb.on("update", this, () => {
|
||||
if (this.__owl__.isMounted) {
|
||||
this.render(true);
|
||||
}
|
||||
if (this.__owl__.isDestroyed) {
|
||||
// this is unlikely to happen, but if a root widget is destroyed,
|
||||
// we want to remove our subscription. The usual way to do that
|
||||
// would be to perform some check in the destroy method, but since
|
||||
// it is very performance sensitive, and since this is a rare event,
|
||||
// we simply do it lazily
|
||||
this.env.qweb.off("update", this);
|
||||
switch (this.__owl__.status) {
|
||||
case STATUS.MOUNTED:
|
||||
this.render(true);
|
||||
break;
|
||||
case STATUS.DESTROYED:
|
||||
// this is unlikely to happen, but if a root widget is destroyed,
|
||||
// we want to remove our subscription. The usual way to do that
|
||||
// would be to perform some check in the destroy method, but since
|
||||
// it is very performance sensitive, and since this is a rare event,
|
||||
// we simply do it lazily
|
||||
this.env.qweb.off("update", this);
|
||||
break;
|
||||
}
|
||||
});
|
||||
depth = 0;
|
||||
@@ -186,8 +196,7 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
depth: depth,
|
||||
vnode: null,
|
||||
pvnode: null,
|
||||
isMounted: false,
|
||||
isDestroyed: false,
|
||||
status: STATUS.CREATED,
|
||||
parent: parent || null,
|
||||
children: {},
|
||||
cmap: {},
|
||||
@@ -317,49 +326,49 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
* Note that a component can be mounted an unmounted several times
|
||||
*/
|
||||
async mount(target: HTMLElement | DocumentFragment, options: MountOptions = {}): Promise<void> {
|
||||
const position = options.position || "last-child";
|
||||
const __owl__ = this.__owl__;
|
||||
if (__owl__.isMounted) {
|
||||
if (position !== "self" && this.el!.parentNode !== target) {
|
||||
// in this situation, we are trying to mount a component on a different
|
||||
// target. In this case, we need to unmount first, otherwise it will
|
||||
// not work.
|
||||
this.unmount();
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
if (__owl__.isDestroyed) {
|
||||
throw new Error("Cannot mount a destroyed component");
|
||||
}
|
||||
if (__owl__.currentFiber) {
|
||||
const currentFiber = __owl__.currentFiber;
|
||||
if (!currentFiber.target && !currentFiber.position) {
|
||||
// this means we have a pending rendering, but it was a render operation,
|
||||
// not a mount operation. We can simply update the fiber with the target
|
||||
// and the position
|
||||
currentFiber.target = target;
|
||||
currentFiber.position = position;
|
||||
return scheduler.addFiber(currentFiber);
|
||||
} else if (currentFiber.target === target && currentFiber.position === position) {
|
||||
return scheduler.addFiber(currentFiber);
|
||||
} else {
|
||||
scheduler.rejectFiber(currentFiber, "Mounting operation cancelled");
|
||||
}
|
||||
}
|
||||
if (!(target instanceof HTMLElement || target instanceof DocumentFragment)) {
|
||||
let message = `Component '${this.constructor.name}' cannot be mounted: the target is not a valid DOM node.`;
|
||||
message += `\nMaybe the DOM is not ready yet? (in that case, you can use owl.utils.whenReady)`;
|
||||
throw new Error(message);
|
||||
}
|
||||
const fiber = new Fiber(null, this, true, target, position);
|
||||
fiber.shouldPatch = false;
|
||||
if (!__owl__.vnode) {
|
||||
this.__prepareAndRender(fiber, () => {});
|
||||
} else {
|
||||
this.__render(fiber);
|
||||
const position = options.position || "last-child";
|
||||
const __owl__ = this.__owl__;
|
||||
const currentFiber = __owl__.currentFiber;
|
||||
|
||||
switch (__owl__.status) {
|
||||
case STATUS.CREATED: {
|
||||
const fiber = new Fiber(null, this, true, target, position);
|
||||
fiber.shouldPatch = false;
|
||||
this.__prepareAndRender(fiber, () => {});
|
||||
return scheduler.addFiber(fiber);
|
||||
}
|
||||
case STATUS.WILLSTARTED:
|
||||
case STATUS.RENDERED:
|
||||
currentFiber.target = target;
|
||||
currentFiber.position = position;
|
||||
return scheduler.addFiber(currentFiber);
|
||||
|
||||
case STATUS.UNMOUNTED: {
|
||||
const fiber = new Fiber(null, this, true, target, position);
|
||||
fiber.shouldPatch = false;
|
||||
this.__render(fiber);
|
||||
return scheduler.addFiber(fiber);
|
||||
}
|
||||
|
||||
case STATUS.MOUNTED: {
|
||||
if (position !== "self" && this.el!.parentNode !== target) {
|
||||
const fiber = new Fiber(null, this, true, target, position);
|
||||
fiber.shouldPatch = false;
|
||||
this.__render(fiber);
|
||||
return scheduler.addFiber(fiber);
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
case STATUS.DESTROYED:
|
||||
throw new Error("Cannot mount a destroyed component");
|
||||
}
|
||||
return scheduler.addFiber(fiber);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -367,7 +376,7 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
* to call willUnmount calls and remove the component from the DOM.
|
||||
*/
|
||||
unmount() {
|
||||
if (this.__owl__.isMounted) {
|
||||
if (this.__owl__.status === STATUS.MOUNTED) {
|
||||
this.__callWillUnmount();
|
||||
this.el!.remove();
|
||||
}
|
||||
@@ -394,11 +403,11 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
// if we aren't mounted at this point, it implies that there is a
|
||||
// currentFiber that is already rendered (isRendered is true), so we are
|
||||
// about to be mounted
|
||||
const isMounted = __owl__.isMounted;
|
||||
const status = __owl__.status;
|
||||
const fiber = new Fiber(null, this, force, null, null);
|
||||
Promise.resolve().then(() => {
|
||||
if (__owl__.isMounted || !isMounted) {
|
||||
if (fiber.isCompleted) {
|
||||
if (__owl__.status === STATUS.MOUNTED || status !== STATUS.MOUNTED) {
|
||||
if (fiber.isCompleted || fiber.isRendered) {
|
||||
return;
|
||||
}
|
||||
this.__render(fiber);
|
||||
@@ -424,7 +433,7 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
*/
|
||||
destroy() {
|
||||
const __owl__ = this.__owl__;
|
||||
if (!__owl__.isDestroyed) {
|
||||
if (__owl__.status !== STATUS.DESTROYED) {
|
||||
const el = this.el;
|
||||
this.__destroy(__owl__.parent);
|
||||
if (el) {
|
||||
@@ -469,13 +478,12 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
*/
|
||||
__destroy(parent: Component | null) {
|
||||
const __owl__ = this.__owl__;
|
||||
const isMounted = __owl__.isMounted;
|
||||
if (isMounted) {
|
||||
if (__owl__.status === STATUS.MOUNTED) {
|
||||
if (__owl__.willUnmountCB) {
|
||||
__owl__.willUnmountCB();
|
||||
}
|
||||
this.willUnmount();
|
||||
__owl__.isMounted = false;
|
||||
__owl__.status = STATUS.UNMOUNTED;
|
||||
}
|
||||
const children = __owl__.children;
|
||||
for (let key in children) {
|
||||
@@ -486,7 +494,7 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
delete parent.__owl__.children[id];
|
||||
__owl__.parent = null;
|
||||
}
|
||||
__owl__.isDestroyed = true;
|
||||
__owl__.status = STATUS.DESTROYED;
|
||||
delete __owl__.vnode;
|
||||
if (__owl__.currentFiber) {
|
||||
__owl__.currentFiber.isCompleted = true;
|
||||
@@ -496,7 +504,7 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
__callMounted() {
|
||||
const __owl__ = this.__owl__;
|
||||
|
||||
__owl__.isMounted = true;
|
||||
__owl__.status = STATUS.MOUNTED;
|
||||
__owl__.currentFiber = null;
|
||||
this.mounted();
|
||||
if (__owl__.mountedCB) {
|
||||
@@ -510,7 +518,7 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
__owl__.willUnmountCB();
|
||||
}
|
||||
this.willUnmount();
|
||||
__owl__.isMounted = false;
|
||||
__owl__.status = STATUS.UNMOUNTED;
|
||||
if (__owl__.currentFiber) {
|
||||
__owl__.currentFiber.isCompleted = true;
|
||||
__owl__.currentFiber.root.counter = 0;
|
||||
@@ -518,7 +526,7 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
const children = __owl__.children;
|
||||
for (let id in children) {
|
||||
const comp = children[id];
|
||||
if (comp.__owl__.isMounted) {
|
||||
if (comp.__owl__.status === STATUS.MOUNTED) {
|
||||
comp.__callWillUnmount();
|
||||
}
|
||||
}
|
||||
@@ -639,18 +647,25 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
}
|
||||
return p._template;
|
||||
}
|
||||
|
||||
async __prepareAndRender(fiber: Fiber, cb: CallableFunction) {
|
||||
try {
|
||||
await Promise.all([this.willStart(), this.__owl__.willStartCB && this.__owl__.willStartCB()]);
|
||||
const proms = Promise.all([
|
||||
this.willStart(),
|
||||
this.__owl__.willStartCB && this.__owl__.willStartCB(),
|
||||
]);
|
||||
this.__owl__.status = STATUS.WILLSTARTED;
|
||||
await proms;
|
||||
if (this.__owl__.status === <any>STATUS.DESTROYED) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
} catch (e) {
|
||||
fiber.handleError(e);
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (this.__owl__.isDestroyed) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (!fiber.isCompleted) {
|
||||
this.__render(fiber);
|
||||
this.__owl__.status = STATUS.RENDERED;
|
||||
cb();
|
||||
}
|
||||
}
|
||||
@@ -673,7 +688,7 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
for (let childKey in __owl__.children) {
|
||||
const child = __owl__.children[childKey];
|
||||
const childOwl = child.__owl__;
|
||||
if (!childOwl.isMounted && childOwl.parentLastFiberId < fiber.id) {
|
||||
if (childOwl.status !== STATUS.MOUNTED && childOwl.parentLastFiberId < fiber.id) {
|
||||
// we only do here a "soft" destroy, meaning that we leave the child
|
||||
// dom node alone, without removing it. Most of the time, it does not
|
||||
// matter, because the child component is already unmounted. However,
|
||||
@@ -720,17 +735,6 @@ export class Component<Props extends {} = any, T extends Env = Env> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only called by qweb t-component directive (when t-keepalive is set)
|
||||
*/
|
||||
__remount() {
|
||||
const __owl__ = this.__owl__;
|
||||
if (!__owl__.isMounted) {
|
||||
__owl__.isMounted = true;
|
||||
this.mounted();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply default props (only top level).
|
||||
*
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { QWeb } from "../qweb/index";
|
||||
import { INTERP_REGEXP } from "../qweb/compilation_context";
|
||||
import { makeHandlerCode, MODS_CODE } from "../qweb/extensions";
|
||||
import { STATUS } from "./component";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// t-component
|
||||
@@ -361,7 +362,7 @@ QWeb.addDirective({
|
||||
// need to update component
|
||||
let styleCode = "";
|
||||
if (tattStyle) {
|
||||
styleCode = `.then(()=>{if (w${componentID}.__owl__.isDestroyed) {return};w${componentID}.el.style=${tattStyle};});`;
|
||||
styleCode = `.then(()=>{if (w${componentID}.__owl__.status === ${STATUS.DESTROYED}) {return};w${componentID}.el.style=${tattStyle};});`;
|
||||
}
|
||||
ctx.addLine(
|
||||
`w${componentID}.__updateProps(props${componentID}, extra.fiber, ${scope})${styleCode};`
|
||||
|
||||
+16
-7
@@ -1,5 +1,5 @@
|
||||
import { h, VNode } from "../vdom/index";
|
||||
import { Component, MountPosition } from "./component";
|
||||
import { Component, MountPosition, STATUS } from "./component";
|
||||
import { scheduler } from "./scheduler";
|
||||
|
||||
/**
|
||||
@@ -107,6 +107,8 @@ export class Fiber {
|
||||
*/
|
||||
_reuseFiber(oldFiber: Fiber) {
|
||||
oldFiber.cancel(); // cancel children fibers
|
||||
oldFiber.target = this.target || oldFiber.target;
|
||||
oldFiber.position = this.position || oldFiber.position;
|
||||
oldFiber.isCompleted = false; // keep the root fiber alive
|
||||
oldFiber.isRendered = false; // the fiber has to be re-rendered
|
||||
if (oldFiber.child) {
|
||||
@@ -188,8 +190,8 @@ export class Fiber {
|
||||
complete() {
|
||||
let component = this.component;
|
||||
this.isCompleted = true;
|
||||
const { isMounted, isDestroyed } = component.__owl__;
|
||||
if (isDestroyed) {
|
||||
const status = component.__owl__.status;
|
||||
if (status === STATUS.DESTROYED) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,7 +205,7 @@ export class Fiber {
|
||||
const patchLen = patchQueue.length;
|
||||
|
||||
// call willPatch hook on each fiber of patchQueue
|
||||
if (isMounted) {
|
||||
if (status === STATUS.MOUNTED) {
|
||||
for (let i = 0; i < patchLen; i++) {
|
||||
const fiber = patchQueue[i];
|
||||
if (fiber.shouldPatch) {
|
||||
@@ -253,8 +255,9 @@ export class Fiber {
|
||||
component.__owl__.pvnode!.elm = component.__owl__.vnode!.elm;
|
||||
}
|
||||
}
|
||||
if (fiber === component.__owl__.currentFiber) {
|
||||
component.__owl__.currentFiber = null;
|
||||
const compOwl = component.__owl__;
|
||||
if (fiber === compOwl.currentFiber) {
|
||||
compOwl.currentFiber = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +277,7 @@ export class Fiber {
|
||||
}
|
||||
|
||||
// call patched/mounted hook on each fiber of (reversed) patchQueue
|
||||
if (isMounted || inDOM) {
|
||||
if (status === STATUS.MOUNTED || inDOM) {
|
||||
for (let i = patchLen - 1; i >= 0; i--) {
|
||||
const fiber = patchQueue[i];
|
||||
component = fiber.component;
|
||||
@@ -287,6 +290,12 @@ export class Fiber {
|
||||
component.__callMounted();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = patchLen - 1; i >= 0; i--) {
|
||||
const fiber = patchQueue[i];
|
||||
component = fiber.component;
|
||||
component.__owl__.status = STATUS.UNMOUNTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { STATUS } from "../component/component";
|
||||
import { VNode } from "../vdom/index";
|
||||
import { INTERP_REGEXP } from "./compilation_context";
|
||||
import { QWeb } from "./qweb";
|
||||
@@ -76,7 +77,7 @@ export function makeHandlerCode(
|
||||
code = ctx.captureExpression(value);
|
||||
}
|
||||
const modCode = mods.map((mod) => modcodes[mod]).join("");
|
||||
let handler = `function (e) {if (context.__owl__.isDestroyed){return}${modCode}${code}}`;
|
||||
let handler = `function (e) {if (context.__owl__.status === ${STATUS.DESTROYED}){return}${modCode}${code}}`;
|
||||
if (putInCache) {
|
||||
const key = ctx.generateTemplateKey(event);
|
||||
ctx.addLine(`extra.handlers[${key}] = extra.handlers[${key}] || ${handler};`);
|
||||
|
||||
@@ -20,7 +20,7 @@ exports[`class and style attributes with t-component dynamic t-att-style is prop
|
||||
w2 = false;
|
||||
}
|
||||
if (w2) {
|
||||
w2.__updateProps(props2, extra.fiber, undefined).then(()=>{if (w2.__owl__.isDestroyed) {return};w2.el.style=_4;});;
|
||||
w2.__updateProps(props2, extra.fiber, undefined).then(()=>{if (w2.__owl__.status === 5) {return};w2.el.style=_4;});;
|
||||
let pvnode = w2.__owl__.pvnode;
|
||||
c1.push(pvnode);
|
||||
} else {
|
||||
|
||||
@@ -444,7 +444,7 @@ exports[`composition t-ref on a node, and t-on-click 2`] = `
|
||||
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
||||
w2 = new W2(parent, props2);
|
||||
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('click', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['doSomething'](e);});}});});
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('click', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['doSomething'](e);});}});});
|
||||
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w2.__owl__.pvnode = pvnode;
|
||||
@@ -579,7 +579,7 @@ exports[`other directives with t-component t-on expression captured in t-foreach
|
||||
c6.push(vn7);
|
||||
const otherState_8 = scope['otherState'];
|
||||
const iter_8 = scope.iter;
|
||||
p7.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}otherState_8.vals.push(iter_8+'_'+iter_8)};
|
||||
p7.on['click'] = function (e) {if (context.__owl__.status === 5){return}otherState_8.vals.push(iter_8+'_'+iter_8)};
|
||||
c7.push({text: \`expr\`});
|
||||
utils.getScope(scope, 'iter').iter = scope.iter+1;
|
||||
}
|
||||
@@ -630,7 +630,7 @@ exports[`other directives with t-component t-on expression in t-foreach 1`] = `
|
||||
c6.push(vn9);
|
||||
const otherState_10 = scope['otherState'];
|
||||
const val_10 = scope['val'];
|
||||
p9.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}otherState_10.vals.push(val_10)};
|
||||
p9.on['click'] = function (e) {if (context.__owl__.status === 5){return}otherState_10.vals.push(val_10)};
|
||||
c9.push({text: \`Expr\`});
|
||||
}
|
||||
scope = _origScope5;
|
||||
@@ -684,7 +684,7 @@ exports[`other directives with t-component t-on expression in t-foreach with t-s
|
||||
const otherState_10 = scope['otherState'];
|
||||
const val_10 = scope['val'];
|
||||
const bossa_10 = scope.bossa;
|
||||
p9.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}otherState_10.vals.push(val_10+'_'+bossa_10)};
|
||||
p9.on['click'] = function (e) {if (context.__owl__.status === 5){return}otherState_10.vals.push(val_10+'_'+bossa_10)};
|
||||
c9.push({text: \`Expr\`});
|
||||
}
|
||||
scope = _origScope5;
|
||||
@@ -734,7 +734,7 @@ exports[`other directives with t-component t-on method call in t-foreach 1`] = `
|
||||
let vn9 = h('button', p9, c9);
|
||||
c6.push(vn9);
|
||||
let args10 = [scope['val']];
|
||||
p9.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['addVal'](...args10, e);};
|
||||
p9.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['addVal'](...args10, e);};
|
||||
c9.push({text: \`meth call\`});
|
||||
}
|
||||
scope = _origScope5;
|
||||
@@ -770,7 +770,7 @@ exports[`other directives with t-component t-on with .capture modifier 1`] = `
|
||||
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
||||
w2 = new W2(parent, props2);
|
||||
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('click', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['capture'](e);}, true);}});});
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('click', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['capture'](e);}, true);}});});
|
||||
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w2.__owl__.pvnode = pvnode;
|
||||
@@ -812,7 +812,7 @@ exports[`other directives with t-component t-on with getter as handler 1`] = `
|
||||
if (!W3) {throw new Error('Cannot find the definition of component \\"' + componentKey3 + '\\"')}
|
||||
w3 = new W3(parent, props3);
|
||||
parent.__owl__.cmap['__4__'] = w3.__owl__.id;
|
||||
let fiber = w3.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['handler'](e);});}});});
|
||||
let fiber = w3.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['handler'](e);});}});});
|
||||
let pvnode = h('dummy', {key: '__4__', hook: {remove() {},destroy(vn) {w3.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w3.__owl__.pvnode = pvnode;
|
||||
@@ -851,7 +851,7 @@ exports[`other directives with t-component t-on with handler bound to argument 1
|
||||
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
||||
w2 = new W2(parent, props2);
|
||||
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
|
||||
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w2.__owl__.pvnode = pvnode;
|
||||
@@ -890,7 +890,7 @@ exports[`other directives with t-component t-on with handler bound to empty obje
|
||||
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
||||
w2 = new W2(parent, props2);
|
||||
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
|
||||
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w2.__owl__.pvnode = pvnode;
|
||||
@@ -929,7 +929,7 @@ exports[`other directives with t-component t-on with handler bound to empty obje
|
||||
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
||||
w2 = new W2(parent, props2);
|
||||
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
|
||||
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w2.__owl__.pvnode = pvnode;
|
||||
@@ -968,7 +968,7 @@ exports[`other directives with t-component t-on with handler bound to object 1`]
|
||||
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
||||
w2 = new W2(parent, props2);
|
||||
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv'](...args4, e);});}});});
|
||||
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w2.__owl__.pvnode = pvnode;
|
||||
@@ -1011,7 +1011,7 @@ exports[`other directives with t-component t-on with inline statement 1`] = `
|
||||
if (!W3) {throw new Error('Cannot find the definition of component \\"' + componentKey3 + '\\"')}
|
||||
w3 = new W3(parent, props3);
|
||||
parent.__owl__.cmap['__4__'] = w3.__owl__.id;
|
||||
let fiber = w3.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}state_5.counter++});}});});
|
||||
let fiber = w3.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}state_5.counter++});}});});
|
||||
let pvnode = h('dummy', {key: '__4__', hook: {remove() {},destroy(vn) {w3.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w3.__owl__.pvnode = pvnode;
|
||||
@@ -1049,7 +1049,7 @@ exports[`other directives with t-component t-on with no handler (only modifiers)
|
||||
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
||||
w2 = new W2(parent, props2);
|
||||
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv'](e);});}});});
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv'](e);});}});});
|
||||
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w2.__owl__.pvnode = pvnode;
|
||||
@@ -1087,7 +1087,7 @@ exports[`other directives with t-component t-on with prevent and self modifiers
|
||||
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
||||
w2 = new W2(parent, props2);
|
||||
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();if (e.target !== vn.elm) {return}utils.getComponent(context)['onEv'](e);});}});});
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}e.preventDefault();if (e.target !== vn.elm) {return}utils.getComponent(context)['onEv'](e);});}});});
|
||||
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w2.__owl__.pvnode = pvnode;
|
||||
@@ -1125,7 +1125,7 @@ exports[`other directives with t-component t-on with self and prevent modifiers
|
||||
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
||||
w2 = new W2(parent, props2);
|
||||
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}if (e.target !== vn.elm) {return}e.preventDefault();utils.getComponent(context)['onEv'](e);});}});});
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}if (e.target !== vn.elm) {return}e.preventDefault();utils.getComponent(context)['onEv'](e);});}});});
|
||||
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w2.__owl__.pvnode = pvnode;
|
||||
@@ -1163,7 +1163,7 @@ exports[`other directives with t-component t-on with self modifier 1`] = `
|
||||
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
||||
w2 = new W2(parent, props2);
|
||||
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv1'](e);});vn.elm.addEventListener('ev-2', function (e) {if (context.__owl__.isDestroyed){return}if (e.target !== vn.elm) {return}utils.getComponent(context)['onEv2'](e);});}});});
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv1'](e);});vn.elm.addEventListener('ev-2', function (e) {if (context.__owl__.status === 5){return}if (e.target !== vn.elm) {return}utils.getComponent(context)['onEv2'](e);});}});});
|
||||
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w2.__owl__.pvnode = pvnode;
|
||||
@@ -1201,7 +1201,7 @@ exports[`other directives with t-component t-on with stop and/or prevent modifie
|
||||
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
||||
w2 = new W2(parent, props2);
|
||||
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {if (context.__owl__.isDestroyed){return}e.stopPropagation();utils.getComponent(context)['onEv1'](e);});vn.elm.addEventListener('ev-2', function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();utils.getComponent(context)['onEv2'](e);});vn.elm.addEventListener('ev-3', function (e) {if (context.__owl__.isDestroyed){return}e.stopPropagation();e.preventDefault();utils.getComponent(context)['onEv3'](e);});}});});
|
||||
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev-1', function (e) {if (context.__owl__.status === 5){return}e.stopPropagation();utils.getComponent(context)['onEv1'](e);});vn.elm.addEventListener('ev-2', function (e) {if (context.__owl__.status === 5){return}e.preventDefault();utils.getComponent(context)['onEv2'](e);});vn.elm.addEventListener('ev-3', function (e) {if (context.__owl__.status === 5){return}e.stopPropagation();e.preventDefault();utils.getComponent(context)['onEv3'](e);});}});});
|
||||
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w2.__owl__.pvnode = pvnode;
|
||||
@@ -1555,7 +1555,7 @@ exports[`random stuff/miscellaneous t-on with handler bound to dynamic argument
|
||||
if (!W6) {throw new Error('Cannot find the definition of component \\"' + componentKey6 + '\\"')}
|
||||
w6 = new W6(parent, props6);
|
||||
parent.__owl__.cmap[k7] = w6.__owl__.id;
|
||||
let fiber = w6.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onEv'](...args8, e);});}});});
|
||||
let fiber = w6.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onEv'](...args8, e);});}});});
|
||||
let pvnode = h('dummy', {key: k7, hook: {remove() {},destroy(vn) {w6.destroy();}}});
|
||||
c1.push(pvnode);
|
||||
w6.__owl__.pvnode = pvnode;
|
||||
@@ -1580,7 +1580,7 @@ exports[`t-call handlers are properly bound through a t-call 1`] = `
|
||||
let vn3 = h('p', p3, c3);
|
||||
c2.push(vn3);
|
||||
let k4 = \`click__4__\${key0}__\`;
|
||||
extra.handlers[k4] = extra.handlers[k4] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['update'](e);};
|
||||
extra.handlers[k4] = extra.handlers[k4] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['update'](e);};
|
||||
p3.on['click'] = extra.handlers[k4];
|
||||
c3.push({text: \`lucas\`});
|
||||
}"
|
||||
@@ -1599,7 +1599,7 @@ exports[`t-call handlers with arguments are properly bound through a t-call 1`]
|
||||
let vn3 = h('p', p3, c3);
|
||||
c2.push(vn3);
|
||||
let args4 = [scope['a']];
|
||||
p3.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['update'](...args4, e);};
|
||||
p3.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['update'](...args4, e);};
|
||||
c3.push({text: \`lucas\`});
|
||||
}"
|
||||
`;
|
||||
|
||||
@@ -229,7 +229,7 @@ exports[`t-slot directive dynamic t-slot call 1`] = `
|
||||
let h = this.h;
|
||||
let c10 = [], p10 = {key:10,on:{}};
|
||||
let vn10 = h('button', p10, c10);
|
||||
extra.handlers['click__11__'] = extra.handlers['click__11__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['toggle'](e);};
|
||||
extra.handlers['click__11__'] = extra.handlers['click__11__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['toggle'](e);};
|
||||
p10.on['click'] = extra.handlers['click__11__'];
|
||||
const slot12 = this.constructor.slots[context.__owl__.slotId + '_' + (scope['current'].slot)];
|
||||
if (slot12) {
|
||||
@@ -301,7 +301,7 @@ exports[`t-slot directive refs are properly bound in slots 1`] = `
|
||||
let c9 = [], p9 = {key:9,on:{}};
|
||||
let vn9 = h('button', p9, c9);
|
||||
c8.push(vn9);
|
||||
extra.handlers['click__10__'] = extra.handlers['click__10__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['doSomething'](e);};
|
||||
extra.handlers['click__10__'] = extra.handlers['click__10__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['doSomething'](e);};
|
||||
p9.on['click'] = extra.handlers['click__10__'];
|
||||
const ref11 = \`myButton\`;
|
||||
p9.hook = {
|
||||
@@ -326,7 +326,7 @@ exports[`t-slot directive slots are rendered with proper context 1`] = `
|
||||
let c9 = [], p9 = {key:9,on:{}};
|
||||
let vn9 = h('button', p9, c9);
|
||||
c8.push(vn9);
|
||||
extra.handlers['click__10__'] = extra.handlers['click__10__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['doSomething'](e);};
|
||||
extra.handlers['click__10__'] = extra.handlers['click__10__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['doSomething'](e);};
|
||||
p9.on['click'] = extra.handlers['click__10__'];
|
||||
c9.push({text: \`do something\`});
|
||||
}"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, Env } from "../../src/component/component";
|
||||
import { Component, Env, STATUS } from "../../src/component/component";
|
||||
import { useState } from "../../src/hooks";
|
||||
import { xml } from "../../src/tags";
|
||||
import { makeDeferred, makeTestEnv, makeTestFixture, nextMicroTick, nextTick } from "../helpers";
|
||||
@@ -40,14 +40,14 @@ describe("async rendering", () => {
|
||||
}
|
||||
}
|
||||
const w = new W();
|
||||
expect(w.__owl__.status).toBe(STATUS.CREATED);
|
||||
w.mount(fixture);
|
||||
expect(w.__owl__.isDestroyed).toBe(false);
|
||||
expect(w.__owl__.isMounted).toBe(false);
|
||||
expect(w.__owl__.status).toBe(STATUS.WILLSTARTED);
|
||||
w.destroy();
|
||||
expect(w.__owl__.status).toBe(STATUS.DESTROYED);
|
||||
def.resolve();
|
||||
await nextTick();
|
||||
expect(w.__owl__.isDestroyed).toBe(true);
|
||||
expect(w.__owl__.isMounted).toBe(false);
|
||||
expect(w.__owl__.status).toBe(STATUS.DESTROYED);
|
||||
});
|
||||
|
||||
test("destroying/recreating a subwidget with different props (if start is not over)", async () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, Env, mount } from "../../src/component/component";
|
||||
import { Component, Env, mount, STATUS } from "../../src/component/component";
|
||||
import { EventBus } from "../../src/core/event_bus";
|
||||
import { useRef, useState } from "../../src/hooks";
|
||||
import { QWeb } from "../../src/qweb/qweb";
|
||||
@@ -1035,8 +1035,7 @@ describe("destroy method", () => {
|
||||
expect(document.contains(widget.el)).toBe(true);
|
||||
widget.destroy();
|
||||
expect(document.contains(widget.el)).toBe(false);
|
||||
expect(widget.__owl__.isMounted).toBe(false);
|
||||
expect(widget.__owl__.isDestroyed).toBe(true);
|
||||
expect(widget.__owl__.status).toBe(STATUS.DESTROYED);
|
||||
});
|
||||
|
||||
test("destroying a parent also destroys its children", async () => {
|
||||
@@ -1045,9 +1044,9 @@ describe("destroy method", () => {
|
||||
|
||||
const child = children(parent)[0];
|
||||
|
||||
expect(child.__owl__.isDestroyed).toBe(false);
|
||||
expect(child.__owl__.status).toBe(STATUS.MOUNTED);
|
||||
parent.destroy();
|
||||
expect(child.__owl__.isDestroyed).toBe(true);
|
||||
expect(child.__owl__.status).toBe(STATUS.DESTROYED);
|
||||
});
|
||||
|
||||
test("destroy remove the parent/children link", async () => {
|
||||
@@ -1073,17 +1072,15 @@ describe("destroy method", () => {
|
||||
}
|
||||
expect(fixture.innerHTML).toBe("");
|
||||
const widget = new DelayedWidget();
|
||||
expect(widget.__owl__.status).toBe(STATUS.CREATED);
|
||||
widget.mount(fixture);
|
||||
expect(widget.__owl__.isMounted).toBe(false);
|
||||
expect(widget.__owl__.isDestroyed).toBe(false);
|
||||
expect(widget.__owl__.status).toBe(STATUS.WILLSTARTED);
|
||||
widget.destroy();
|
||||
expect(widget.__owl__.isMounted).toBe(false);
|
||||
expect(widget.__owl__.isDestroyed).toBe(true);
|
||||
expect(widget.__owl__.status).toBe(STATUS.DESTROYED);
|
||||
def.resolve();
|
||||
await nextTick();
|
||||
|
||||
expect(widget.__owl__.isMounted).toBe(false);
|
||||
expect(widget.__owl__.isDestroyed).toBe(true);
|
||||
expect(widget.__owl__.status).toBe(STATUS.DESTROYED);
|
||||
expect(widget.__owl__.vnode).toBe(undefined);
|
||||
expect(fixture.innerHTML).toBe("");
|
||||
expect(isRendered).toBe(false);
|
||||
@@ -1539,7 +1536,7 @@ describe("composition", () => {
|
||||
parent.state.flag = true;
|
||||
await nextTick();
|
||||
expect(children(parent)[0]).toBe(child);
|
||||
expect(child.__owl__.isDestroyed).toBe(false);
|
||||
expect(child.__owl__.status).toBe(STATUS.MOUNTED);
|
||||
expect(normalize(fixture.innerHTML)).toBe(
|
||||
normalize(`
|
||||
<div>
|
||||
@@ -2287,7 +2284,7 @@ describe("other directives with t-component", () => {
|
||||
el.click();
|
||||
expect(steps).toEqual(["click"]);
|
||||
parent.unmount();
|
||||
expect(child.__owl__.isMounted).toBe(false);
|
||||
expect(child.__owl__.status).toBe(STATUS.UNMOUNTED);
|
||||
el.click();
|
||||
expect(steps).toEqual(["click", "click"]);
|
||||
});
|
||||
@@ -2361,7 +2358,7 @@ describe("other directives with t-component", () => {
|
||||
expect(steps).toEqual(["click"]);
|
||||
parent.state.flag = false;
|
||||
await nextTick();
|
||||
expect(child.__owl__.isDestroyed).toBe(true);
|
||||
expect(child.__owl__.status).toBe(STATUS.DESTROYED);
|
||||
el.click();
|
||||
expect(steps).toEqual(["click"]);
|
||||
});
|
||||
@@ -2396,7 +2393,7 @@ describe("other directives with t-component", () => {
|
||||
expect(steps).toEqual(["click"]);
|
||||
parent.state.flag = false;
|
||||
await nextTick();
|
||||
expect(child.__owl__.isDestroyed).toBe(true);
|
||||
expect(child.__owl__.status).toBe(STATUS.DESTROYED);
|
||||
el.click();
|
||||
expect(steps).toEqual(["click"]);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, Env } from "../../src/component/component";
|
||||
import { Component, Env, STATUS } from "../../src/component/component";
|
||||
import { useState } from "../../src/hooks";
|
||||
import { xml } from "../../src/tags";
|
||||
import { makeTestEnv, makeTestFixture, nextTick } from "../helpers";
|
||||
@@ -108,7 +108,7 @@ describe("component error handling (catchError)", () => {
|
||||
|
||||
expect(console.error).toBeCalledTimes(0);
|
||||
console.error = consoleError;
|
||||
expect(app.__owl__.isDestroyed).toBe(true);
|
||||
expect(app.__owl__.status).toBe(STATUS.DESTROYED);
|
||||
expect(handler).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
|
||||
@@ -404,6 +404,40 @@ describe("unmounting and remounting", () => {
|
||||
expect(fixture.innerHTML).toBe("<div>P2<span>C2</span></div>");
|
||||
});
|
||||
|
||||
test("change state while component is mounted in a fragment", async () => {
|
||||
class Child1 extends Component {
|
||||
static template = xml`<span>C1</span>`;
|
||||
}
|
||||
|
||||
class Child2 extends Component {
|
||||
static template = xml`<span>C2</span>`;
|
||||
}
|
||||
|
||||
class Parent extends Component {
|
||||
static components = { Child1, Child2 };
|
||||
static template = xml`
|
||||
<div>
|
||||
<Child1 t-if="child == 'c1'"/>
|
||||
<Child2 t-if="child == 'c2'"/>
|
||||
</div>`;
|
||||
child: string | false = false;
|
||||
}
|
||||
|
||||
const fragment = document.createDocumentFragment();
|
||||
const parent = new Parent();
|
||||
await parent.mount(fragment);
|
||||
expect(parent.el.outerHTML).toBe("<div></div>");
|
||||
|
||||
parent.child = "c1";
|
||||
parent.render();
|
||||
await Promise.resolve();
|
||||
|
||||
parent.child = "c2";
|
||||
await parent.mount(fixture);
|
||||
|
||||
expect(fixture.innerHTML).toBe("<div><span>C2</span></div>");
|
||||
});
|
||||
|
||||
test("unmount component during a re-rendering", async () => {
|
||||
const def = makeDeferred();
|
||||
class Child extends Component {
|
||||
@@ -490,17 +524,17 @@ describe("unmounting and remounting", () => {
|
||||
// one full tick.
|
||||
await nextMicroTick();
|
||||
await nextMicroTick();
|
||||
expect(steps).toEqual(["1 catch"]);
|
||||
expect(steps).toEqual([]);
|
||||
await nextTick();
|
||||
expect(fixture.innerHTML).toBe("<div></div><span></span>");
|
||||
|
||||
def.resolve();
|
||||
await nextTick();
|
||||
expect(steps).toEqual(["1 catch", "2 resolved"]);
|
||||
expect(steps).toEqual(["2 resolved"]);
|
||||
expect(fixture.innerHTML).toBe("<div></div><span><div>Hey</div></span>");
|
||||
});
|
||||
|
||||
test("widget can be mounted on same target, another situation", async () => {
|
||||
test("component can be mounted on same target, another situation", async () => {
|
||||
const def = makeDeferred();
|
||||
const steps: string[] = [];
|
||||
|
||||
@@ -528,8 +562,8 @@ describe("unmounting and remounting", () => {
|
||||
|
||||
def.resolve();
|
||||
await nextTick();
|
||||
expect(steps).toEqual(["1 resolved", "2 resolved"]);
|
||||
expect(fixture.innerHTML).toBe("<div>Hey</div>");
|
||||
expect(steps).toEqual(["1 resolved", "2 resolved"]);
|
||||
});
|
||||
|
||||
test("mounting a destroyed widget", async () => {
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import { Env, Component } from "../src/component/component";
|
||||
import { Env, Component, STATUS } from "../src/component/component";
|
||||
import { scheduler } from "../src/component/scheduler";
|
||||
import { EvalContext, QWeb } from "../src/qweb/qweb";
|
||||
import { CompilationContext } from "../src/qweb/compilation_context";
|
||||
@@ -92,7 +92,7 @@ export function renderToDOM(
|
||||
if (!context.__owl__) {
|
||||
// we add `__owl__` to better simulate a component as context. This is
|
||||
// particularly important for event handlers added with the `t-on` directive.
|
||||
context.__owl__ = { isMounted: true };
|
||||
context.__owl__ = { status: STATUS.MOUNTED };
|
||||
}
|
||||
const vnode = qweb.render(template, context, extra);
|
||||
|
||||
|
||||
@@ -2727,7 +2727,7 @@ exports[`t-on can bind event handler 1`] = `
|
||||
let h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
let vn1 = h('button', p1, c1);
|
||||
extra.handlers['click__2__'] = extra.handlers['click__2__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['add'](e);};
|
||||
extra.handlers['click__2__'] = extra.handlers['click__2__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['add'](e);};
|
||||
p1.on['click'] = extra.handlers['click__2__'];
|
||||
c1.push({text: \`Click\`});
|
||||
return vn1;
|
||||
@@ -2744,7 +2744,7 @@ exports[`t-on can bind handlers with arguments 1`] = `
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
let vn1 = h('button', p1, c1);
|
||||
let args2 = [5];
|
||||
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['add'](...args2, e);};
|
||||
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['add'](...args2, e);};
|
||||
c1.push({text: \`Click\`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -2760,7 +2760,7 @@ exports[`t-on can bind handlers with empty object (with non empty inner string)
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
let vn1 = h('button', p1, c1);
|
||||
let args2 = [{}];
|
||||
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['doSomething'](...args2, e);};
|
||||
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['doSomething'](...args2, e);};
|
||||
c1.push({text: \`Click\`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -2776,7 +2776,7 @@ exports[`t-on can bind handlers with empty object 1`] = `
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
let vn1 = h('button', p1, c1);
|
||||
let args2 = [{}];
|
||||
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['doSomething'](...args2, e);};
|
||||
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['doSomething'](...args2, e);};
|
||||
c1.push({text: \`Click\`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -2815,7 +2815,7 @@ exports[`t-on can bind handlers with loop variable as argument 1`] = `
|
||||
let vn7 = h('a', p7, c7);
|
||||
c6.push(vn7);
|
||||
let args8 = [scope['action']];
|
||||
p7.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['activate'](...args8, e);};
|
||||
p7.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['activate'](...args8, e);};
|
||||
c7.push({text: \`link\`});
|
||||
}
|
||||
scope = _origScope5;
|
||||
@@ -2833,7 +2833,7 @@ exports[`t-on can bind handlers with object arguments 1`] = `
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
let vn1 = h('button', p1, c1);
|
||||
let args2 = [{val:5}];
|
||||
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['add'](...args2, e);};
|
||||
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['add'](...args2, e);};
|
||||
c1.push({text: \`Click\`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -2847,9 +2847,9 @@ exports[`t-on can bind two event handlers 1`] = `
|
||||
let h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
let vn1 = h('button', p1, c1);
|
||||
extra.handlers['click__2__'] = extra.handlers['click__2__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['handleClick'](e);};
|
||||
extra.handlers['click__2__'] = extra.handlers['click__2__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['handleClick'](e);};
|
||||
p1.on['click'] = extra.handlers['click__2__'];
|
||||
extra.handlers['dblclick__3__'] = extra.handlers['dblclick__3__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['handleDblClick'](e);};
|
||||
extra.handlers['dblclick__3__'] = extra.handlers['dblclick__3__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['handleDblClick'](e);};
|
||||
p1.on['dblclick'] = extra.handlers['dblclick__3__'];
|
||||
c1.push({text: \`Click\`});
|
||||
return vn1;
|
||||
@@ -2864,7 +2864,7 @@ exports[`t-on handler is bound to proper owner 1`] = `
|
||||
let h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
let vn1 = h('button', p1, c1);
|
||||
extra.handlers['click__2__'] = extra.handlers['click__2__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['add'](e);};
|
||||
extra.handlers['click__2__'] = extra.handlers['click__2__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['add'](e);};
|
||||
p1.on['click'] = extra.handlers['click__2__'];
|
||||
c1.push({text: \`Click\`});
|
||||
return vn1;
|
||||
@@ -2883,7 +2883,7 @@ exports[`t-on t-on combined with t-esc 1`] = `
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
let vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onClick'](e);};
|
||||
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onClick'](e);};
|
||||
p2.on['click'] = extra.handlers['click__3__'];
|
||||
let _4 = scope['text'];
|
||||
if (_4 != null) {
|
||||
@@ -2905,7 +2905,7 @@ exports[`t-on t-on combined with t-raw 1`] = `
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
let vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onClick'](e);};
|
||||
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onClick'](e);};
|
||||
p2.on['click'] = extra.handlers['click__3__'];
|
||||
let _4 = scope['html'];
|
||||
if (_4 != null) {
|
||||
@@ -2923,12 +2923,12 @@ exports[`t-on t-on with .capture modifier 1`] = `
|
||||
let h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
let vn1 = h('div', p1, c1);
|
||||
extra.handlers['!click__2__'] = extra.handlers['!click__2__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onCapture'](e);};
|
||||
extra.handlers['!click__2__'] = extra.handlers['!click__2__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onCapture'](e);};
|
||||
p1.on['!click'] = extra.handlers['!click__2__'];
|
||||
let c3 = [], p3 = {key:3,on:{}};
|
||||
let vn3 = h('button', p3, c3);
|
||||
c1.push(vn3);
|
||||
extra.handlers['click__4__'] = extra.handlers['click__4__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['doSomething'](e);};
|
||||
extra.handlers['click__4__'] = extra.handlers['click__4__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['doSomething'](e);};
|
||||
p3.on['click'] = extra.handlers['click__4__'];
|
||||
c3.push({text: \`Button\`});
|
||||
return vn1;
|
||||
@@ -2946,7 +2946,7 @@ exports[`t-on t-on with empty handler (only modifiers) 1`] = `
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
let vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
p2.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();};
|
||||
p2.on['click'] = function (e) {if (context.__owl__.status === 5){return}e.preventDefault();};
|
||||
c2.push({text: \`Button\`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -2961,7 +2961,7 @@ exports[`t-on t-on with inline statement (function call) 1`] = `
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
let vn1 = h('button', p1, c1);
|
||||
const state_2 = scope['state'];
|
||||
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}state_2.incrementCounter(2)};
|
||||
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}state_2.incrementCounter(2)};
|
||||
c1.push({text: \`Click\`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -2976,7 +2976,7 @@ exports[`t-on t-on with inline statement 1`] = `
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
let vn1 = h('button', p1, c1);
|
||||
const state_2 = scope['state'];
|
||||
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}state_2.counter++};
|
||||
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}state_2.counter++};
|
||||
c1.push({text: \`Click\`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -2991,7 +2991,7 @@ exports[`t-on t-on with inline statement, part 2 1`] = `
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
let vn1 = h('button', p1, c1);
|
||||
const state_2 = scope['state'];
|
||||
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}state_2.flag=!state_2.flag};
|
||||
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}state_2.flag=!state_2.flag};
|
||||
c1.push({text: \`Toggle\`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -3007,7 +3007,7 @@ exports[`t-on t-on with inline statement, part 3 1`] = `
|
||||
let vn1 = h('button', p1, c1);
|
||||
const state_2 = scope['state'];
|
||||
const someFunction_2 = scope['someFunction'];
|
||||
p1.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}state_2.n=someFunction_2(3)};
|
||||
p1.on['click'] = function (e) {if (context.__owl__.status === 5){return}state_2.n=someFunction_2(3)};
|
||||
c1.push({text: \`Toggle\`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -3024,7 +3024,7 @@ exports[`t-on t-on with prevent and self modifiers (order matters) 1`] = `
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
let vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();if (e.target !== this.elm) {return}utils.getComponent(context)['onClick'](e);};
|
||||
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.status === 5){return}e.preventDefault();if (e.target !== this.elm) {return}utils.getComponent(context)['onClick'](e);};
|
||||
p2.on['click'] = extra.handlers['click__3__'];
|
||||
let c4 = [], p4 = {key:4};
|
||||
let vn4 = h('span', p4, c4);
|
||||
@@ -3045,19 +3045,19 @@ exports[`t-on t-on with prevent and/or stop modifiers 1`] = `
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
let vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();utils.getComponent(context)['onClickPrevented'](e);};
|
||||
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.status === 5){return}e.preventDefault();utils.getComponent(context)['onClickPrevented'](e);};
|
||||
p2.on['click'] = extra.handlers['click__3__'];
|
||||
c2.push({text: \`Button 1\`});
|
||||
let c4 = [], p4 = {key:4,on:{}};
|
||||
let vn4 = h('button', p4, c4);
|
||||
c1.push(vn4);
|
||||
extra.handlers['click__5__'] = extra.handlers['click__5__'] || function (e) {if (context.__owl__.isDestroyed){return}e.stopPropagation();utils.getComponent(context)['onClickStopped'](e);};
|
||||
extra.handlers['click__5__'] = extra.handlers['click__5__'] || function (e) {if (context.__owl__.status === 5){return}e.stopPropagation();utils.getComponent(context)['onClickStopped'](e);};
|
||||
p4.on['click'] = extra.handlers['click__5__'];
|
||||
c4.push({text: \`Button 2\`});
|
||||
let c6 = [], p6 = {key:6,on:{}};
|
||||
let vn6 = h('button', p6, c6);
|
||||
c1.push(vn6);
|
||||
extra.handlers['click__7__'] = extra.handlers['click__7__'] || function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();e.stopPropagation();utils.getComponent(context)['onClickPreventedAndStopped'](e);};
|
||||
extra.handlers['click__7__'] = extra.handlers['click__7__'] || function (e) {if (context.__owl__.status === 5){return}e.preventDefault();e.stopPropagation();utils.getComponent(context)['onClickPreventedAndStopped'](e);};
|
||||
p6.on['click'] = extra.handlers['click__7__'];
|
||||
c6.push({text: \`Button 3\`});
|
||||
return vn1;
|
||||
@@ -3097,7 +3097,7 @@ exports[`t-on t-on with prevent modifier in t-foreach 1`] = `
|
||||
let vn7 = h('a', p7, c7);
|
||||
c1.push(vn7);
|
||||
let args8 = [scope['project'].id];
|
||||
p7.on['click'] = function (e) {if (context.__owl__.isDestroyed){return}e.preventDefault();utils.getComponent(context)['onEdit'](...args8, e);};
|
||||
p7.on['click'] = function (e) {if (context.__owl__.status === 5){return}e.preventDefault();utils.getComponent(context)['onEdit'](...args8, e);};
|
||||
c7.push({text: \` Edit \`});
|
||||
let _9 = scope['project'].name;
|
||||
if (_9 != null) {
|
||||
@@ -3121,7 +3121,7 @@ exports[`t-on t-on with self and prevent modifiers (order matters) 1`] = `
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
let vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.isDestroyed){return}if (e.target !== this.elm) {return}e.preventDefault();utils.getComponent(context)['onClick'](e);};
|
||||
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.status === 5){return}if (e.target !== this.elm) {return}e.preventDefault();utils.getComponent(context)['onClick'](e);};
|
||||
p2.on['click'] = extra.handlers['click__3__'];
|
||||
let c4 = [], p4 = {key:4};
|
||||
let vn4 = h('span', p4, c4);
|
||||
@@ -3142,7 +3142,7 @@ exports[`t-on t-on with self modifier 1`] = `
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
let vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['onClick'](e);};
|
||||
extra.handlers['click__3__'] = extra.handlers['click__3__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['onClick'](e);};
|
||||
p2.on['click'] = extra.handlers['click__3__'];
|
||||
let c4 = [], p4 = {key:4};
|
||||
let vn4 = h('span', p4, c4);
|
||||
@@ -3151,7 +3151,7 @@ exports[`t-on t-on with self modifier 1`] = `
|
||||
let c5 = [], p5 = {key:5,on:{}};
|
||||
let vn5 = h('button', p5, c5);
|
||||
c1.push(vn5);
|
||||
extra.handlers['click__6__'] = extra.handlers['click__6__'] || function (e) {if (context.__owl__.isDestroyed){return}if (e.target !== this.elm) {return}utils.getComponent(context)['onClickSelf'](e);};
|
||||
extra.handlers['click__6__'] = extra.handlers['click__6__'] || function (e) {if (context.__owl__.status === 5){return}if (e.target !== this.elm) {return}utils.getComponent(context)['onClickSelf'](e);};
|
||||
p5.on['click'] = extra.handlers['click__6__'];
|
||||
let c7 = [], p7 = {key:7};
|
||||
let vn7 = h('span', p7, c7);
|
||||
|
||||
@@ -11,7 +11,7 @@ exports[`Link component can render simple cases 1`] = `
|
||||
let _6 = scope['href'];
|
||||
let c7 = [], p7 = {key:7,attrs:{href: _6},class:_5,on:{}};
|
||||
let vn7 = h('a', p7, c7);
|
||||
extra.handlers['click__8__'] = extra.handlers['click__8__'] || function (e) {if (context.__owl__.isDestroyed){return}utils.getComponent(context)['navigate'](e);};
|
||||
extra.handlers['click__8__'] = extra.handlers['click__8__'] || function (e) {if (context.__owl__.status === 5){return}utils.getComponent(context)['navigate'](e);};
|
||||
p7.on['click'] = extra.handlers['click__8__'];
|
||||
const slot9 = this.constructor.slots[context.__owl__.slotId + '_' + 'default'];
|
||||
if (slot9) {
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@
|
||||
component.render = function(...args) {
|
||||
const __owl__ = component.__owl__;
|
||||
let msg = `render`;
|
||||
if (!__owl__.isMounted && !__owl__.currentFiber) {
|
||||
if (__owl__.status !== 3 /* mounted */ && !__owl__.currentFiber) {
|
||||
msg += ` (warning: component is not mounted)`;
|
||||
}
|
||||
log(msg);
|
||||
|
||||
Reference in New Issue
Block a user