mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] compiler: do not look up ComponentNode in the context
With the introduction of t-call-context, there is now no guarantee that the ComponentNode can be found in the rendering context, any attempt to do so can crash when combined with t-call-context. This commit fixes that by using `this` instead, which in compiled templates refers to the component that is being rendered.
This commit is contained in:
committed by
Géry Debongnie
parent
3d49daedcd
commit
9a5edb4590
@@ -191,7 +191,7 @@ class CodeTarget {
|
||||
let result: string[] = [];
|
||||
result.push(`function ${this.name}(ctx, node, key = "") {`);
|
||||
if (this.hasRef) {
|
||||
result.push(` const refs = ctx.__owl__.refs;`);
|
||||
result.push(` const refs = this.__owl__.refs;`);
|
||||
for (let name in this.refInfo) {
|
||||
const [id, expr] = this.refInfo[name];
|
||||
result.push(` const ${id} = ${expr};`);
|
||||
@@ -1104,7 +1104,7 @@ export class CodeGenerator {
|
||||
if (suffix === "bind") {
|
||||
this.helpers.add("bind");
|
||||
name = _name;
|
||||
value = `bind(ctx, ${value || undefined})`;
|
||||
value = `bind(this, ${value || undefined})`;
|
||||
} else {
|
||||
throw new OwlError("Invalid prop suffix");
|
||||
}
|
||||
@@ -1140,7 +1140,7 @@ export class CodeGenerator {
|
||||
if (this.target.loopLevel || !this.hasSafeContext) {
|
||||
ctxStr = generateId("ctx");
|
||||
this.helpers.add("capture");
|
||||
this.define(ctxStr, `capture(ctx)`);
|
||||
this.define(ctxStr, `capture(ctx, this)`);
|
||||
}
|
||||
let slotStr: string[] = [];
|
||||
for (let slotName in ast.slots) {
|
||||
@@ -1148,7 +1148,7 @@ export class CodeGenerator {
|
||||
const params = [];
|
||||
if (slotAst.content) {
|
||||
const name = this.compileInNewTarget("slot", slotAst.content, ctx, slotAst.on);
|
||||
params.push(`__render: ${name}, __ctx: ${ctxStr}`);
|
||||
params.push(`__render: ${name}.bind(this), __ctx: ${ctxStr}`);
|
||||
}
|
||||
const scope = ast.slots[slotName].scope;
|
||||
if (scope) {
|
||||
@@ -1275,7 +1275,7 @@ export class CodeGenerator {
|
||||
const scope = this.getPropString(props, dynProps);
|
||||
if (ast.defaultContent) {
|
||||
const name = this.compileInNewTarget("defaultContent", ast.defaultContent, ctx);
|
||||
blockString = `callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope}, ${name})`;
|
||||
blockString = `callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope}, ${name}.bind(this))`;
|
||||
} else {
|
||||
if (dynamic) {
|
||||
let name = generateId("slot");
|
||||
@@ -1316,7 +1316,7 @@ export class CodeGenerator {
|
||||
if (this.target.loopLevel || !this.hasSafeContext) {
|
||||
ctxStr = generateId("ctx");
|
||||
this.helpers.add("capture");
|
||||
this.define(ctxStr, `capture(ctx)`);
|
||||
this.define(ctxStr, `capture(ctx, this)`);
|
||||
}
|
||||
let id = generateId("comp");
|
||||
this.staticDefs.push({
|
||||
@@ -1325,7 +1325,7 @@ export class CodeGenerator {
|
||||
});
|
||||
|
||||
const target = compileExpr(ast.target);
|
||||
const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}, __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx, Portal)`;
|
||||
const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}.bind(this), __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx, Portal)`;
|
||||
if (block) {
|
||||
this.insertAnchor(block);
|
||||
}
|
||||
|
||||
@@ -32,22 +32,21 @@ function callSlot(
|
||||
if (__scope) {
|
||||
slotScope[__scope] = extra;
|
||||
}
|
||||
const slotBDom = __render ? __render.call(__ctx.__owl__.component, slotScope, parent, key) : null;
|
||||
const slotBDom = __render ? __render(slotScope, parent, key) : null;
|
||||
if (defaultContent) {
|
||||
let child1: BDom | undefined = undefined;
|
||||
let child2: BDom | undefined = undefined;
|
||||
if (slotBDom) {
|
||||
child1 = dynamic ? toggler(name, slotBDom) : slotBDom;
|
||||
} else {
|
||||
child2 = defaultContent.call(ctx.__owl__.component, ctx, parent, key);
|
||||
child2 = defaultContent(ctx, parent, key);
|
||||
}
|
||||
return multi([child1, child2]);
|
||||
}
|
||||
return slotBDom || text("");
|
||||
}
|
||||
|
||||
function capture(ctx: any): any {
|
||||
const component = ctx.__owl__.component;
|
||||
function capture(ctx: any, component: any): any {
|
||||
const result = ObjectCreate(component);
|
||||
for (let k in ctx) {
|
||||
result[k] = ctx[k];
|
||||
@@ -115,7 +114,7 @@ class LazyValue {
|
||||
|
||||
constructor(fn: any, ctx: any, component: any, node: any, key: any) {
|
||||
this.fn = fn;
|
||||
this.ctx = capture(ctx);
|
||||
this.ctx = capture(ctx, component);
|
||||
this.component = component;
|
||||
this.node = node;
|
||||
this.key = key;
|
||||
@@ -171,8 +170,7 @@ let boundFunctions = new WeakMap();
|
||||
const WeakMapGet = WeakMap.prototype.get;
|
||||
const WeakMapSet = WeakMap.prototype.set;
|
||||
|
||||
function bind(ctx: any, fn: Function): Function {
|
||||
let component = ctx.__owl__.component;
|
||||
function bind(component: any, fn: Function): Function {
|
||||
let boundFnMap = WeakMapGet.call(boundFunctions, component);
|
||||
if (!boundFnMap) {
|
||||
boundFnMap = new WeakMap();
|
||||
|
||||
Reference in New Issue
Block a user