mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] portal: portal as a Directive
Before this commit, portal was a Component, now is a directive. This commit also clean some unused code, and fix an issue on the clean optimization when a portal is found in a condition or a loop.
This commit is contained in:
committed by
Aaron Bohy
parent
c221721d7f
commit
90167c5436
@@ -47,7 +47,7 @@ const cache: { [key: string]: BlockType } = {};
|
||||
* @param str
|
||||
* @returns a new block type, that can build concrete blocks
|
||||
*/
|
||||
export function createBlock(str: string): BlockType {
|
||||
export function createBlock(str: string, deepRemove: boolean = false): BlockType {
|
||||
if (str in cache) {
|
||||
return cache[str];
|
||||
}
|
||||
@@ -67,7 +67,7 @@ export function createBlock(str: string): BlockType {
|
||||
|
||||
// step 3: build the final block class
|
||||
const template = tree.el as HTMLElement;
|
||||
const Block = buildBlock(template, context);
|
||||
const Block = buildBlock(template, context, deepRemove);
|
||||
cache[str] = Block;
|
||||
return Block;
|
||||
}
|
||||
@@ -422,7 +422,7 @@ function updateCtx(ctx: BlockCtx, tree: IntermediateTree) {
|
||||
// building the concrete block class
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function buildBlock(template: HTMLElement, ctx: BlockCtx): BlockType {
|
||||
function buildBlock(template: HTMLElement, ctx: BlockCtx, deepRemove: boolean): BlockType {
|
||||
let B = createBlockClass(template, ctx);
|
||||
|
||||
if (ctx.cbRefs.length) {
|
||||
@@ -447,6 +447,14 @@ function buildBlock(template: HTMLElement, ctx: BlockCtx): BlockType {
|
||||
}
|
||||
};
|
||||
B.prototype.beforeRemove = VMulti.prototype.beforeRemove;
|
||||
if (deepRemove) {
|
||||
const blockRemove = B.prototype.remove;
|
||||
const vMultiRemove = VMulti.prototype.remove;
|
||||
B.prototype.remove = function () {
|
||||
blockRemove.call(this);
|
||||
vMultiRemove.call(this);
|
||||
};
|
||||
}
|
||||
return (data?: any[], children: (VNode | undefined)[] = []) => new B(data, children);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,11 @@ class VList {
|
||||
anchor: Node | undefined;
|
||||
parentEl?: HTMLElement | undefined;
|
||||
isOnlyChild?: boolean | undefined;
|
||||
deepRemove: boolean;
|
||||
|
||||
constructor(children: VNode[]) {
|
||||
constructor(children: VNode[], deepRemove: boolean) {
|
||||
this.children = children;
|
||||
this.deepRemove = deepRemove;
|
||||
}
|
||||
|
||||
mount(parent: HTMLElement, afterNode: Node | null) {
|
||||
@@ -75,7 +77,7 @@ class VList {
|
||||
const parent = this.parentEl!;
|
||||
|
||||
// fast path: no new child => only remove
|
||||
if (ch2.length === 0 && isOnlyChild) {
|
||||
if (ch2.length === 0 && isOnlyChild && !this.deepRemove) {
|
||||
if (withBeforeRemove) {
|
||||
for (let i = 0, l = ch1.length; i < l; i++) {
|
||||
beforeRemove.call(ch1[i]);
|
||||
@@ -98,7 +100,6 @@ class VList {
|
||||
let endVn2 = ch2[endIdx2];
|
||||
|
||||
let mapping: any = undefined;
|
||||
// let noFullRemove = this.hasNoComponent;
|
||||
|
||||
while (startIdx1 <= endIdx1 && startIdx2 <= endIdx2) {
|
||||
// -------------------------------------------------------------------
|
||||
@@ -202,7 +203,7 @@ class VList {
|
||||
|
||||
remove() {
|
||||
const { parentEl, anchor } = this;
|
||||
if (this.isOnlyChild) {
|
||||
if (this.isOnlyChild && !this.deepRemove) {
|
||||
nodeSetTextContent.call(parentEl, "");
|
||||
} else {
|
||||
const children = this.children;
|
||||
@@ -227,8 +228,8 @@ class VList {
|
||||
}
|
||||
}
|
||||
|
||||
export function list(children: VNode[]): VNode<VList> {
|
||||
return new VList(children);
|
||||
export function list(children: VNode[], deepRemove = false): VNode<VList> {
|
||||
return new VList(children, deepRemove);
|
||||
}
|
||||
|
||||
function createMapping(ch1: any[], startIdx1: number, endIdx2: number): { [key: string]: any } {
|
||||
|
||||
@@ -15,9 +15,11 @@ export class VMulti {
|
||||
anchors?: Node[] | undefined;
|
||||
parentEl?: HTMLElement | undefined;
|
||||
isOnlyChild?: boolean | undefined;
|
||||
deepRemove: boolean;
|
||||
|
||||
constructor(children: (VNode | undefined)[]) {
|
||||
constructor(children: (VNode | undefined)[], deepRemove: boolean) {
|
||||
this.children = children;
|
||||
this.deepRemove = deepRemove;
|
||||
}
|
||||
|
||||
mount(parent: HTMLElement, afterNode: Node | null) {
|
||||
@@ -103,7 +105,7 @@ export class VMulti {
|
||||
|
||||
remove() {
|
||||
const parentEl = this.parentEl;
|
||||
if (this.isOnlyChild) {
|
||||
if (this.isOnlyChild && !this.deepRemove) {
|
||||
nodeSetTextContent.call(parentEl, "");
|
||||
} else {
|
||||
const children = this.children;
|
||||
@@ -129,6 +131,6 @@ export class VMulti {
|
||||
}
|
||||
}
|
||||
|
||||
export function multi(children: (VNode | undefined)[]): VNode<VMulti> {
|
||||
return new VMulti(children);
|
||||
export function multi(children: (VNode | undefined)[], deepRemove = false): VNode<VMulti> {
|
||||
return new VMulti(children, deepRemove);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user