[FIX] component: cancel previous mounting operations if necessary

closes #626
This commit is contained in:
Géry Debongnie
2020-02-16 09:46:47 +01:00
committed by aab-odoo
parent 03585d8fea
commit f7728b93bd
8 changed files with 156 additions and 61 deletions
+44 -12
View File
@@ -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();
}
}