From b10a70038166ab134d429df2c44fa2740bd07023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Thu, 26 May 2022 22:42:25 +0200 Subject: [PATCH] [REF] add static App.registerTemplate and update Portal to use it The goal is to get closer to the possibility of using Owl without the compiler. This commit removes Portal dependency on the compiler, and opens the way to register pre-compiled template functions. --- src/app/template_set.ts | 34 ++++++++++++++++++++++++++++----- src/component/component_node.ts | 2 +- src/index.ts | 3 ++- src/portal.ts | 13 +++++++++++-- src/utils.ts | 14 -------------- tests/helpers.ts | 3 +-- 6 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/app/template_set.ts b/src/app/template_set.ts index f905f64b..0fb1b2bf 100644 --- a/src/app/template_set.ts +++ b/src/app/template_set.ts @@ -1,9 +1,8 @@ import { createBlock, html, list, multi, text, toggler, comment } from "../blockdom"; -import { compile, Template } from "../compiler"; -import { Portal } from "../portal"; +import { compile, Template, TemplateFunction } from "../compiler"; +import { Portal, portalTemplate } from "../portal"; import { component, getCurrent } from "../component/component_node"; import { helpers } from "./template_helpers"; -import { globalTemplates } from "../utils"; const bdom = { text, createBlock, list, multi, html, toggler, component, comment }; @@ -45,6 +44,9 @@ export interface TemplateSetConfig { } export class TemplateSet { + static registerTemplate(name: string, fn: TemplateFunction) { + globalTemplates[name] = fn; + } dev: boolean; rawTemplates: typeof globalTemplates = Object.create(globalTemplates); templates: { [name: string]: Template } = {}; @@ -64,7 +66,12 @@ export class TemplateSet { addTemplate(name: string, template: string | Element) { if (name in this.rawTemplates) { const rawTemplate = this.rawTemplates[name]; - const currentAsString = typeof rawTemplate === "string" ? rawTemplate : rawTemplate.outerHTML; + const currentAsString = + typeof rawTemplate === "string" + ? rawTemplate + : rawTemplate instanceof Element + ? rawTemplate.outerHTML + : rawTemplate.toString(); const newAsString = typeof template === "string" ? template : template.outerHTML; if (currentAsString === newAsString) { return; @@ -97,7 +104,8 @@ export class TemplateSet { } catch {} throw new Error(`Missing template: "${name}"${extraInfo}`); } - const templateFn = this._compileTemplate(name, rawTemplate); + const isFn = typeof rawTemplate === "function" && !(rawTemplate instanceof Element); + const templateFn = isFn ? rawTemplate : this._compileTemplate(name, rawTemplate); // first add a function to lazily get the template, in case there is a // recursive call to the template name const templates = this.templates; @@ -124,3 +132,19 @@ export class TemplateSet { return toggler(subTemplate, template.call(owner, ctx, parent, key)); } } + +// ----------------------------------------------------------------------------- +// xml tag helper +// ----------------------------------------------------------------------------- +export const globalTemplates: { [key: string]: string | Element | TemplateFunction } = {}; + +export function xml(...args: Parameters) { + const name = `__template__${xml.nextId++}`; + const value = String.raw(...args); + globalTemplates[name] = value; + return name; +} + +xml.nextId = 1; + +TemplateSet.registerTemplate("__portal__", portalTemplate); diff --git a/src/component/component_node.ts b/src/component/component_node.ts index 599c0e67..252baaf9 100644 --- a/src/component/component_node.ts +++ b/src/component/component_node.ts @@ -188,7 +188,7 @@ export class ComponentNode

implements VNode> { } } +/** + * + */ +export function portalTemplate(app: any, bdom: any, helpers: any) { + let { callSlot } = helpers; + return function template(ctx: any, node: any, key = "") { + return callSlot(ctx, node, key, "default", false, null); + }; +} export class Portal extends Component { - static template = xml``; + static template = "__portal__"; static props = { target: { type: String, diff --git a/src/utils.ts b/src/utils.ts index 78d32876..990dfc04 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -73,17 +73,3 @@ export class Markup extends String {} export function markup(value: any) { return new Markup(value); } - -// ----------------------------------------------------------------------------- -// xml tag helper -// ----------------------------------------------------------------------------- -export const globalTemplates: { [key: string]: string | Element } = {}; - -export function xml(...args: Parameters) { - const name = `__template__${xml.nextId++}`; - const value = String.raw(...args); - globalTemplates[name] = value; - return name; -} - -xml.nextId = 1; diff --git a/tests/helpers.ts b/tests/helpers.ts index 5b93970b..c660861c 100644 --- a/tests/helpers.ts +++ b/tests/helpers.ts @@ -16,10 +16,9 @@ import { xml, } from "../src"; import { helpers } from "../src/app/template_helpers"; -import { TemplateSet } from "../src/app/template_set"; +import { TemplateSet, globalTemplates } from "../src/app/template_set"; import { BDom } from "../src/blockdom"; import { compile } from "../src/compiler"; -import { globalTemplates } from "../src/utils"; const mount = blockDom.mount;