diff --git a/doc/reference/app.md b/doc/reference/app.md index c168bc36..af5337fc 100644 --- a/doc/reference/app.md +++ b/doc/reference/app.md @@ -66,6 +66,8 @@ The `config` object is an object with some of the following keys: needs a template. If undefined is returned, owl looks into the app templates. - **`warnIfNoStaticProps (boolean, default=false)`**: if true, Owl will log a warning whenever it encounters a component that does not provide a [static props description](props.md#props-validation). +- **`customDirectives (object)`**: if given, the corresponding function on the object will be called + on the template custom directives: `t-custom-*` (see [Custom Directives](templates.md#custom-directives)). ## `mount` helper diff --git a/doc/reference/templates.md b/doc/reference/templates.md index 705728a8..1e88a94b 100644 --- a/doc/reference/templates.md +++ b/doc/reference/templates.md @@ -18,6 +18,7 @@ - [Sub Templates](#sub-templates) - [Dynamic Sub Templates](#dynamic-sub-templates) - [Debugging](#debugging) + - [Custom Directives](#custom-directives) - [Fragments](#fragments) - [Inline templates](#inline-templates) - [Rendering svg](#rendering-svg) @@ -80,6 +81,7 @@ needs. Here is a list of all Owl specific directives: | `t-slot`, `t-set-slot`, `t-slot-scope` | [Rendering a slot](slots.md) | | `t-model` | [Form input bindings](input_bindings.md) | | `t-tag` | [Rendering nodes with dynamic tag name](#dynamic-tag-names) | +| `t-custom-*` | [Rendering nodes with custom directives](#custom-directives) | ## QWeb Template Reference @@ -588,6 +590,35 @@ will stop execution if the browser dev tools are open. will print 42 to the console. +### Custom Directives + +Owl 2 supports the declaration of custom directives. To use them, an Object of functions needs to be configured on the owl APP: + +```js + new App(..., { + customDirectives: { + test_directive: function (el, value) { + el.setAttribute("t-on-click", value); + } + } + }); +``` + +The functions will be called when a custom directive with the name of the +function is found. The original element will be replaced with the one +modified by the function. +This : + +```xml +
+``` + +will be replaced by : + +```xml + +``` + ## Fragments Owl 2 supports templates with an arbitrary number of root elements, or even just diff --git a/src/common/types.ts b/src/common/types.ts new file mode 100644 index 00000000..0a900bdb --- /dev/null +++ b/src/common/types.ts @@ -0,0 +1,4 @@ +export type customDirectives = Record< + string, + (node: Element, value: string, modifier?: string) => void +>; diff --git a/src/compiler/index.ts b/src/compiler/index.ts index 16683bc1..ba513de9 100644 --- a/src/compiler/index.ts +++ b/src/compiler/index.ts @@ -1,3 +1,4 @@ +import type { customDirectives } from "../common/types"; import type { TemplateSet } from "../runtime/template_set"; import type { BDom } from "../runtime/blockdom"; import { CodeGenerator, Config } from "./code_generator"; @@ -10,13 +11,14 @@ export type TemplateFunction = (app: TemplateSet, bdom: any, helpers: any) => Te interface CompileOptions extends Config { name?: string; + customDirectives?: customDirectives; } export function compile( template: string | Element, options: CompileOptions = {} ): TemplateFunction { // parsing - const ast = parse(template); + const ast = parse(template, options.customDirectives); // some work const hasSafeContext = diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 11c9bdb7..dc5c3ee7 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1,4 +1,5 @@ import { OwlError } from "../common/owl_error"; +import type { customDirectives } from "../common/types"; import { parseXML } from "../common/utils"; // ----------------------------------------------------------------------------- @@ -198,23 +199,26 @@ export type AST = // ----------------------------------------------------------------------------- const cache: WeakMap