mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] component: cancel previous mounting operations if necessary
closes #626
This commit is contained in:
+44
-12
@@ -1,5 +1,5 @@
|
||||
import { h, VNode } from "../vdom/index";
|
||||
import { Component } from "./component";
|
||||
import { Component, MountPosition } from "./component";
|
||||
import { scheduler } from "./scheduler";
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,8 @@ export class Fiber {
|
||||
// scheduler.
|
||||
counter: number = 0;
|
||||
|
||||
inserter: (el: HTMLElement) => void | null;
|
||||
target: HTMLElement | DocumentFragment | null;
|
||||
position: MountPosition | null;
|
||||
|
||||
scope: any;
|
||||
|
||||
@@ -61,10 +62,17 @@ export class Fiber {
|
||||
|
||||
error?: Error;
|
||||
|
||||
constructor(parent: Fiber | null, component: Component, force: boolean, inserter) {
|
||||
constructor(
|
||||
parent: Fiber | null,
|
||||
component: Component,
|
||||
force: boolean,
|
||||
target: HTMLElement | DocumentFragment | null,
|
||||
position: MountPosition | null
|
||||
) {
|
||||
this.component = component;
|
||||
this.force = force;
|
||||
this.inserter = inserter;
|
||||
this.target = target;
|
||||
this.position = position;
|
||||
|
||||
const __owl__ = component.__owl__;
|
||||
this.scope = __owl__.scope;
|
||||
@@ -179,7 +187,7 @@ export class Fiber {
|
||||
complete() {
|
||||
let component = this.component;
|
||||
this.isCompleted = true;
|
||||
if (!this.inserter && !component.__owl__.isMounted) {
|
||||
if (!this.target && !component.__owl__.isMounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -208,17 +216,41 @@ export class Fiber {
|
||||
for (let i = patchLen - 1; i >= 0; i--) {
|
||||
const fiber = patchQueue[i];
|
||||
component = fiber.component;
|
||||
component.__patch(fiber.vnode!);
|
||||
if (!fiber.shouldPatch && (!fiber.inserter || i !== 0)) {
|
||||
component.__owl__.pvnode!.elm = component.__owl__.vnode!.elm;
|
||||
if (fiber.target && i === 0) {
|
||||
let target;
|
||||
if (fiber.position === "self") {
|
||||
target = fiber.target;
|
||||
if ((target as HTMLElement).tagName.toLowerCase() !== fiber.vnode!.sel) {
|
||||
throw new Error(
|
||||
`Cannot attach '${component.constructor.name}' to target node (not same tag name)`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
target = component.__owl__.vnode || document.createElement(fiber.vnode!.sel!);
|
||||
}
|
||||
component.__patch(target!, fiber.vnode!);
|
||||
} else {
|
||||
if (fiber.shouldPatch) {
|
||||
component.__patch(component.__owl__.vnode!, fiber.vnode!);
|
||||
} else {
|
||||
component.__patch(document.createElement(fiber.vnode!.sel!), fiber.vnode!);
|
||||
component.__owl__.pvnode!.elm = component.__owl__.vnode!.elm;
|
||||
}
|
||||
}
|
||||
component.__owl__.currentFiber = null;
|
||||
}
|
||||
|
||||
// insert into the DOM (mount case)
|
||||
let inDOM = false;
|
||||
if (this.inserter) {
|
||||
this.inserter(this.component.el!);
|
||||
if (this.target) {
|
||||
switch (this.position) {
|
||||
case "first-child":
|
||||
this.target.prepend(this.component.el!);
|
||||
break;
|
||||
case "last-child":
|
||||
this.target.appendChild(this.component.el!);
|
||||
break;
|
||||
}
|
||||
inDOM = document.body.contains(this.component.el);
|
||||
this.component.env.qweb.trigger("dom-appended");
|
||||
}
|
||||
@@ -227,12 +259,12 @@ export class Fiber {
|
||||
for (let i = patchLen - 1; i >= 0; i--) {
|
||||
const fiber = patchQueue[i];
|
||||
component = fiber.component;
|
||||
if (fiber.shouldPatch && !this.inserter) {
|
||||
if (fiber.shouldPatch && !this.target) {
|
||||
component.patched();
|
||||
if (component.__owl__.patchedCB) {
|
||||
component.__owl__.patchedCB();
|
||||
}
|
||||
} else if (this.inserter ? inDOM : true) {
|
||||
} else if (this.target ? inDOM : true) {
|
||||
component.__callMounted();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user