diff --git a/doc/component.md b/doc/component.md index ee728f30..4890a224 100644 --- a/doc/component.md +++ b/doc/component.md @@ -677,7 +677,6 @@ to event `menu-loaded` will receive the payload in its `someMethod` handler By convention, we use KebabCase for the name of _business_ events. - The `t-on` directive allows to prebind some arguments. For example, ```xml @@ -695,10 +694,12 @@ One can also directly specify inline statements. For example, Here, `state` must be defined in the rendering context (typically the component) as it will be translated to: -```js -button.addEventListener("click", () => { component.state.counter++; }); -``` +```js +button.addEventListener("click", () => { + component.state.counter++; +}); +``` In order to remove the DOM event details from the event handlers (like calls to `event.preventDefault`) and let them focus on data logic, _modifiers_ can be diff --git a/doc/tags.md b/doc/tags.md index e733c1d5..24defba5 100644 --- a/doc/tags.md +++ b/doc/tags.md @@ -1,8 +1,15 @@ # 🦉 Tags 🦉 +## Content + +- [Overview](#overview) +- [`xml` tag](#xml-tag) + +## Overview + Tags are very small helpers to make it easy to write inline templates. There is only one currently available tag: `xml`, but we plan to add other tags later, -such as a `css` tag, which will be used to write single file components. +such as a `css` tag, which will be used to write [single file components](tooling.md#single-file-component). ## XML tag @@ -31,8 +38,8 @@ With tags, this process is slightly simplified. The name is uniquely generated, and the template is automatically registered: ```js -import { Component } from 'owl' -import { xml } from 'owl/tags' +const { Component } = owl; +const { xml } = owl.tags; class MyComponent extends Component { static template = xml` diff --git a/doc/tooling.md b/doc/tooling.md index 040d0d92..d206b766 100644 --- a/doc/tooling.md +++ b/doc/tooling.md @@ -60,12 +60,21 @@ useful to compare various performance metrics on some tasks. ## Single File Component -If you want to have `xml` syntax highlighting while using the `xml` helper which -helps you define inline templates, there is a VS Code addon `Comment tagged template` -which, if installed, does exactly that. To enable it, you need to add a comment, -like this: +It is very useful to group code by feature instead of by type of file. It makes +it easier to scale application to larger size. + +To do so, Owl currently has a small helper that makes it easy to define a +template inside a javascript (or typescript) file: the [`xml`](tags.md#xml-tag) +helper. With this, a template is automatically registered to [QWeb](qweb.md). + +This means that the template and the javascript code can be defined in the same +file. It is not currently possible to add css to the same file, but Owl may +get a `css` tag helper later. ```js +const { Component } = owl; +const { xml } = owl.tags; + // ----------------------------------------------------------------------------- // TEMPLATE // ----------------------------------------------------------------------------- @@ -85,3 +94,8 @@ class MyComponent extends Component { // rest of component... } ``` + +Note that the above example has an inline xml comment, just after the `xml` call. +This is useful for some editor plugins, such as the VS Code addon +`Comment tagged template`, which, if installed, add syntax highlighting to the +content of the template string. diff --git a/src/qweb/extensions.ts b/src/qweb/extensions.ts index 5f8f0ace..120fe837 100644 --- a/src/qweb/extensions.ts +++ b/src/qweb/extensions.ts @@ -58,7 +58,9 @@ QWeb.addDirective({ ctx.addLine(`p${nodeID}.on['${eventName}'] = extra.handlers['${eventName}' + ${nodeID}];`); } else { const handlerKey = `handler${ctx.generateID()}`; - ctx.addLine(`const ${handlerKey} = context['${handlerName}'] && context['${handlerName}'].bind(${params});`); + ctx.addLine( + `const ${handlerKey} = context['${handlerName}'] && context['${handlerName}'].bind(${params});` + ); handler += `if (${handlerKey}) { ${handlerKey}(e); } else { context.${value}; }`; handler += `}`; ctx.addLine(`p${nodeID}.on['${eventName}'] = ${handler};`); diff --git a/tests/component/component.test.ts b/tests/component/component.test.ts index ded73e3c..d2593403 100644 --- a/tests/component/component.test.ts +++ b/tests/component/component.test.ts @@ -2142,7 +2142,7 @@ describe("other directives with t-component", () => { `; static components = { Child }; - state = useState({counter: 0}); + state = useState({ counter: 0 }); get handler() { this.state.counter++; return () => {}; @@ -2152,12 +2152,12 @@ describe("other directives with t-component", () => { await parent.mount(fixture); expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot(); - expect(fixture.innerHTML).toBe('
0
'); + expect(fixture.innerHTML).toBe("
0
"); let child = children(parent)[0]; child.trigger("ev"); await nextTick(); - expect(fixture.innerHTML).toBe('
1
'); + expect(fixture.innerHTML).toBe("
1
"); }); test("t-on with inline statement", async () => { @@ -2171,18 +2171,18 @@ describe("other directives with t-component", () => { `; static components = { Child }; - state = useState({counter: 0}); + state = useState({ counter: 0 }); } const parent = new Parent(env); await parent.mount(fixture); expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot(); - expect(fixture.innerHTML).toBe('
0
'); + expect(fixture.innerHTML).toBe("
0
"); let child = children(parent)[0]; child.trigger("ev"); await nextTick(); - expect(fixture.innerHTML).toBe('
1
'); + expect(fixture.innerHTML).toBe("
1
"); }); test("t-on with no handler (only modifiers)", async () => { diff --git a/tests/qweb/qweb.test.ts b/tests/qweb/qweb.test.ts index d3ec6a36..6073f289 100644 --- a/tests/qweb/qweb.test.ts +++ b/tests/qweb/qweb.test.ts @@ -1044,8 +1044,8 @@ describe("t-on", () => { qweb.addTemplate("test", ``); let owner = { state: { - counter: 0, - }, + counter: 0 + } }; const node = renderToDOM(qweb, "test", owner, { handlers: [] }); expect(owner.state.counter).toBe(0); @@ -1058,8 +1058,10 @@ describe("t-on", () => { let owner = { state: { counter: 0, - incrementCounter: (inc) => { owner.state.counter += inc; }, - }, + incrementCounter: inc => { + owner.state.counter += inc; + } + } }; const node = renderToDOM(qweb, "test", owner, { handlers: [] }); expect(owner.state.counter).toBe(0); @@ -1223,7 +1225,7 @@ describe("t-on", () => { ); const node = renderToDOM(qweb, "test", {}, { handlers: [] }); - node.addEventListener('click', (e) => { + node.addEventListener("click", e => { expect(e.defaultPrevented).toBe(true); });