diff --git a/src/component/component.ts b/src/component/component.ts index ef278c2e..af3417f3 100644 --- a/src/component/component.ts +++ b/src/component/component.ts @@ -70,12 +70,6 @@ interface Internal { classObj: { [key: string]: boolean } | null; } -// If a component does not define explicitely a template -// key, it needs to find a template with its name (or a parent's). This is -// qweb dependant, so we need a place to store this information indexed by -// qweb instances. -const TEMPLATE_MAP: { [key: number]: { [name: string]: string } } = {}; - //------------------------------------------------------------------------------ // Component //------------------------------------------------------------------------------ @@ -83,7 +77,8 @@ let nextId = 1; export class Component { readonly __owl__: Internal; - template?: string; + static template?: string | null = null; + static _template?: string | null = null; /** * The `el` is the root element of the component. Note that it could be null: @@ -527,30 +522,28 @@ export class Component { return Promise.resolve(h("div")); } const qweb = this.env.qweb; - if (!this.template) { - let tmap = TEMPLATE_MAP[qweb.id]; - if (!tmap) { - tmap = {}; - TEMPLATE_MAP[qweb.id] = tmap; - } - let p = (this).constructor; - let name: string = p.name; - let template = tmap[name]; - if (template) { - this.template = template; + let p = (this).constructor; + // console.warn(p, p.template, p._template, 'template' in p, p.hasOwnProperty('template')) + if (!p.hasOwnProperty("_template")) { + if (p.template) { + p._template = p.template; } else { + // here, the component and none of its superclasses defines a static `template` + // key. So we fall back on looking for a template matching its name (or + // one of its subclass). + + let template: string; while ((template = p.name) && !(template in qweb.templates) && p !== Component) { p = p.__proto__; } if (p === Component) { throw new Error(`Could not find template for component "${this.constructor.name}"`); } else { - tmap[name] = template; - this.template = template; + p._template = template; } } } - __owl__.render = qweb.render.bind(qweb, this.template); + __owl__.render = qweb.render.bind(qweb, p._template); this.__observeState(); return this.__render(false, [], scope, vars); diff --git a/src/qweb/qweb.ts b/src/qweb/qweb.ts index 84a73675..3da9f961 100644 --- a/src/qweb/qweb.ts +++ b/src/qweb/qweb.ts @@ -125,8 +125,6 @@ function parseXML(xml: string): Document { return doc; } -let nextID = 1; - //------------------------------------------------------------------------------ // QWeb rendering engine //------------------------------------------------------------------------------ @@ -147,10 +145,6 @@ export class QWeb extends EventBus { // dev mode enables better error messages or more costly validations static dev: boolean = false; - // the id field is useful to be able to hash qweb instances. The current - // use case is that component's templates are qweb dependant, and need to be - // able to map a qweb instance to a template name. - id = nextID++; // slots contains sub templates defined with t-set inside t-component nodes, and // are meant to be used by the t-slot directive. @@ -326,8 +320,8 @@ export class QWeb extends EventBus { _compile(name: string, elem: Element, parentContext?: Context): CompiledTemplate { const isDebug = elem.attributes.hasOwnProperty("t-debug"); const ctx = new Context(name); - if (elem.tagName !== 't') { - ctx.shouldDefineResult = false; + if (elem.tagName !== "t") { + ctx.shouldDefineResult = false; } if (parentContext) { ctx.templates = Object.create(parentContext.templates); diff --git a/src/router/Link.ts b/src/router/Link.ts index db1a7ebe..dcb9af30 100644 --- a/src/router/Link.ts +++ b/src/router/Link.ts @@ -12,7 +12,7 @@ export const LINK_TEMPLATE = ` type Props = Destination; export class Link extends Component { - template = LINK_TEMPLATE_NAME; + static template = LINK_TEMPLATE_NAME; href: string = this.env.router.destToPath(this.props); async willUpdateProps(nextProps) { diff --git a/src/router/RouteComponent.ts b/src/router/RouteComponent.ts index 164cdef1..162d047a 100644 --- a/src/router/RouteComponent.ts +++ b/src/router/RouteComponent.ts @@ -9,7 +9,7 @@ export const ROUTE_COMPONENT_TEMPLATE = ` `; export class RouteComponent extends Component { - template = ROUTE_COMPONENT_TEMPLATE_NAME; + static template = ROUTE_COMPONENT_TEMPLATE_NAME; routes: any[] = []; constructor(parent, props) { super(parent, props); diff --git a/tests/component/component.test.ts b/tests/component/component.test.ts index eb33e032..791e5753 100644 --- a/tests/component/component.test.ts +++ b/tests/component/component.test.ts @@ -1288,7 +1288,7 @@ describe("composition", () => { ` ); class Parent extends Widget { - template = "parent"; + static template = "parent"; state = { numbers: [1, 2, 3] }; @@ -3003,7 +3003,7 @@ describe("can deduce template from name", () => { test("can find template of parent component, defined by template key", async () => { class ABC extends Widget { - template = "Achel"; + static template = "Achel"; } class DEF extends ABC {} env.qweb.addTemplate("Achel", "Orval");