Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/compiler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { BDom } from "../runtime/blockdom";
import { CodeGenerator, Config } from "./code_generator";
import { parse } from "./parser";
import { OwlError } from "../common/owl_error";
import { parseXML } from "../common/utils";

export type Template = (context: any, vnode: any, key?: string) => BDom;

Expand All @@ -16,13 +17,13 @@ export function compile(
options: CompileOptions = {}
): TemplateFunction {
// parsing
if (typeof template === "string") {
template = parseXML(`<t>${template}</t>`).firstChild as Element;
}
const ast = parse(template);

// some work
const hasSafeContext =
template instanceof Node
? !(template instanceof Element) || template.querySelector("[t-set], [t-call]") === null
: !template.includes("t-set") && !template.includes("t-call");
const hasSafeContext = template.querySelector("[t-set], [t-call]") === null;

// code generation
const codeGenerator = new CodeGenerator(ast, { ...options, hasSafeContext });
Expand Down
7 changes: 1 addition & 6 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { OwlError } from "../common/owl_error";
import { parseXML } from "../common/utils";

// -----------------------------------------------------------------------------
// AST Type definition
Expand Down Expand Up @@ -198,11 +197,7 @@ export type AST =
// -----------------------------------------------------------------------------
const cache: WeakMap<Element, AST> = new WeakMap();

export function parse(xml: string | Element): AST {
if (typeof xml === "string") {
const elem = parseXML(`<t>${xml}</t>`).firstChild as Element;
return _parse(elem);
}
export function parse(xml: Element): AST {
let ast = cache.get(xml);
if (!ast) {
// we clone here the xml to prevent modifying it in place
Expand Down
5 changes: 4 additions & 1 deletion tests/compiler/parser.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { ASTType, parse } from "../../src/compiler/parser";
import { parseXML } from "../../src/common/utils";
import { ASTType, parse as _parse } from "../../src/compiler/parser";

const parse = (template: string) => _parse(parseXML(`<t>${template}</t>`).firstChild as Element);

describe("qweb parser", () => {
// ---------------------------------------------------------------------------
Expand Down
5 changes: 2 additions & 3 deletions tests/components/__snapshots__/refs.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ exports[`refs refs are properly bound in slots 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { capture, markRaw } = helpers;
let { markRaw } = helpers;
const comp1 = app.createComponent(\`Dialog\`, true, true, false, []);

let block1 = createBlock(\`<div><span class=\\"counter\\"><block-text-0/></span><block-child-0/></div>\`);
Expand All @@ -113,8 +113,7 @@ exports[`refs refs are properly bound in slots 1`] = `

return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['state'].val;
const ctx1 = capture(ctx);
const b3 = comp1({slots: markRaw({'footer': {__render: slot1.bind(this), __ctx: ctx1}})}, key + \`__1\`, node, this, null);
const b3 = comp1({slots: markRaw({'footer': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__1\`, node, this, null);
return block1([txt1], [b3]);
}
}"
Expand Down
149 changes: 76 additions & 73 deletions tests/components/__snapshots__/slots.test.ts.snap

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions tests/components/__snapshots__/t_foreach.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ exports[`list of components order is correct when slots are not of same type 1`]
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { capture, markRaw } = helpers;
let { markRaw } = helpers;
const comp1 = app.createComponent(\`Child\`, true, true, false, []);

let block2 = createBlock(\`<div>A</div>\`);
Expand All @@ -175,8 +175,7 @@ exports[`list of components order is correct when slots are not of same type 1`]
}

return function template(ctx, node, key = \\"\\") {
const ctx1 = capture(ctx);
return comp1({slots: markRaw({'a': {__render: slot1.bind(this), __ctx: ctx1, active: !ctx['state'].active}, 'b': {__render: slot2.bind(this), __ctx: ctx1, active: true}, 'c': {__render: slot3.bind(this), __ctx: ctx1, active: ctx['state'].active}})}, key + \`__1\`, node, this, null);
return comp1({slots: markRaw({'a': {__render: slot1.bind(this), __ctx: ctx, active: !ctx['state'].active}, 'b': {__render: slot2.bind(this), __ctx: ctx, active: true}, 'c': {__render: slot3.bind(this), __ctx: ctx, active: ctx['state'].active}})}, key + \`__1\`, node, this, null);
}
}"
`;
Expand Down
5 changes: 2 additions & 3 deletions tests/components/__snapshots__/t_on.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ exports[`t-on t-on on t-set-slots 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { capture, createCatcher, markRaw } = helpers;
let { createCatcher, markRaw } = helpers;
const catcher1 = createCatcher({\\"click\\":0});
const comp1 = app.createComponent(\`Child\`, true, true, false, []);

Expand All @@ -405,8 +405,7 @@ exports[`t-on t-on on t-set-slots 1`] = `
const b2 = text(\` [\`);
const b3 = text(ctx['state'].count);
const b4 = text(\`] \`);
const ctx1 = capture(ctx);
const b8 = comp1({slots: markRaw({'myslot': {__render: slot1.bind(this), __ctx: ctx1}})}, key + \`__1\`, node, this, null);
const b8 = comp1({slots: markRaw({'myslot': {__render: slot1.bind(this), __ctx: ctx}})}, key + \`__1\`, node, this, null);
return multi([b2, b3, b4, b8]);
}
}"
Expand Down
24 changes: 23 additions & 1 deletion tests/components/slots.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { App, Component, mount, onMounted, useState, xml } from "../../src/index";
import { App, Component, mount, onMounted, onRendered, useState, xml } from "../../src/index";
import { children, makeTestFixture, nextAppError, nextTick, snapshotEverything } from "../helpers";

snapshotEverything();
Expand Down Expand Up @@ -62,6 +62,28 @@ describe("slots", () => {
expect(fixture.innerHTML).toBe("some other text");
});

test("t-set-slot doesn't cause context to be captured", async () => {
class Child extends Component {
static template = xml`<t t-slot="default"/>`;
}

class Parent extends Component {
static template = xml`<Child>
<t t-set-slot="default"><t t-esc="someVal"/></t>
</Child>`;
static components = { Child };
someVal = "some text";
setup() {
onRendered(() => {
this.someVal = "some other text";
});
}
}
await mount(Parent, fixture);

expect(fixture.textContent).toBe("some other text");
});

test("simple slot with slot scope", async () => {
let child: any;
class Child extends Component {
Expand Down