Compare commits

...

5 Commits

Author SHA1 Message Date
Géry Debongnie 76c389a7a8 [REL] v2.0.0-beta-11
# v2.0.0-beta-11

Yet another release with some small fixes.

[FIX] fix some issues with t-out with falsy values, and with default values
[REF] app: slightly simplify the create component path
[IMP] compiler: add support for binary operators
[IMP] add support for t-call-context directive
[FIX] properly get component reference instead of context
[FIX] blockdom: fix crash when class object key has leading spaces
2022-06-28 15:28:12 +02:00
Géry Debongnie b9ba0abf41 [FIX] test: run prettier 2022-06-28 15:26:55 +02:00
Géry Debongnie 4ca37be7f3 [FIX] tests: update wrong snapshot
oups
2022-06-28 15:20:53 +02:00
Géry Debongnie d6667ddf2e [FIX] fix some issues with t-out with falsy values, and with default value 2022-06-28 15:10:11 +02:00
Géry Debongnie 6f86beeaf3 [REF] app: slightly simplify the create component path 2022-06-28 13:11:57 +02:00
12 changed files with 163 additions and 22 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@odoo/owl",
"version": "2.0.0-beta-10",
"version": "2.0.0-beta-11",
"description": "Odoo Web Library (OWL)",
"main": "dist/owl.cjs.js",
"browser": "dist/owl.iife.js",
+13 -7
View File
@@ -754,16 +754,22 @@ export class CodeGenerator {
this.insertAnchor(block);
}
block = this.createBlock(block, "html", ctx);
this.helpers.add(ast.expr === "0" ? "zero" : "safeOutput");
let expr = ast.expr === "0" ? "ctx[zero]" : `safeOutput(${compileExpr(ast.expr)})`;
if (ast.body) {
const nextId = BlockDescription.nextBlockId;
let blockStr;
if (ast.expr === "0") {
this.helpers.add("zero");
blockStr = `ctx[zero]`;
} else if (ast.body) {
let bodyValue = null;
bodyValue = BlockDescription.nextBlockId;
const subCtx: Context = createContext(ctx);
this.compileAST({ type: ASTType.Multi, content: ast.body }, subCtx);
this.helpers.add("withDefault");
expr = `withDefault(${expr}, b${nextId})`;
this.helpers.add("safeOutput");
blockStr = `safeOutput(${compileExpr(ast.expr)}, b${bodyValue})`;
} else {
this.helpers.add("safeOutput");
blockStr = `safeOutput(${compileExpr(ast.expr)})`;
}
this.insertBlock(`${expr}`, block, ctx);
this.insertBlock(blockStr, block, ctx);
}
compileTIf(ast: ASTTif, ctx: Context, nextNode?: ASTDomNode) {
+1 -5
View File
@@ -3,7 +3,6 @@ import { ComponentNode } from "./component_node";
import { nodeErrorHandlers } from "./error_handling";
import { Fiber, MountOptions } from "./fibers";
import { Scheduler } from "./scheduler";
import { STATUS } from "./status";
import { validateProps } from "./template_helpers";
import { TemplateSet, TemplateSetConfig } from "./template_set";
import { validateTarget } from "./utils";
@@ -141,10 +140,7 @@ export class App<
return (props: P, key: string, ctx: ComponentNode, parent: any, C: any) => {
let children = ctx.children;
let node: any = children[key];
if (
node &&
(node.status === STATUS.DESTROYED || (isDynamic && node.component.constructor !== C))
) {
if (isDynamic && node && node.component.constructor !== C) {
node = undefined;
}
const parentFiber = ctx.fiber!;
+1
View File
@@ -56,6 +56,7 @@ function cancelFibers(fibers: Fiber[]): number {
fiber.render = throwOnRender;
if (node.status === STATUS.NEW) {
node.destroy();
delete node.parent!.children[node.parentKey!];
}
node.fiber = null;
if (fiber.bdom) {
+3 -3
View File
@@ -129,9 +129,9 @@ class LazyValue {
/*
* Safely outputs `value` as a block depending on the nature of `value`
*/
export function safeOutput(value: any): ReturnType<typeof toggler> {
if (!value) {
return value;
export function safeOutput(value: any, defaultValue?: any): ReturnType<typeof toggler> {
if (value === undefined) {
return defaultValue ? toggler("default", defaultValue) : toggler("undefined", text(""));
}
let safeKey;
let block;
@@ -166,13 +166,13 @@ exports[`misc global 4`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput, withDefault } = helpers;
let { safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b3 = text(\`toto default\`);
const b2 = withDefault(safeOutput(ctx['toto']), b3);
const b2 = safeOutput(ctx['toto'], b3);
return block1([], [b2]);
}
}"
@@ -133,6 +133,31 @@ exports[`t-esc t-esc is escaped 1`] = `
}"
`;
exports[`t-esc t-esc with the 0 number 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['var']);
}
}"
`;
exports[`t-esc t-esc with the 0 number, in a p 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<p><block-text-0/></p>\`);
return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['var'];
return block1([txt1]);
}
}"
`;
exports[`t-esc t-esc work with spread operator 1`] = `
"function anonymous(app, bdom, helpers
) {
@@ -183,6 +208,17 @@ exports[`t-esc t-esc=0 is escaped 2`] = `
}"
`;
exports[`t-esc top level t-esc with undefined 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['var']);
}
}"
`;
exports[`t-esc variable 1`] = `
"function anonymous(app, bdom, helpers
) {
@@ -217,13 +217,13 @@ exports[`t-out t-out on a node with a body, as a default 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput, withDefault } = helpers;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
const b3 = text(\`nope\`);
const b2 = withDefault(safeOutput(ctx['var']), b3);
const b2 = safeOutput(ctx['var'], b3);
return block1([], [b2]);
}
}"
@@ -233,14 +233,14 @@ exports[`t-out t-out on a node with a dom node in body, as a default 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput, withDefault } = helpers;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
let block3 = createBlock(\`<div>nope</div>\`);
return function template(ctx, node, key = \\"\\") {
const b3 = block3();
const b2 = withDefault(safeOutput(ctx['var']), b3);
const b2 = safeOutput(ctx['var'], b3);
return block1([], [b2]);
}
}"
@@ -407,6 +407,45 @@ exports[`t-out t-out with just a t-set t-value in body 1`] = `
}"
`;
exports[`t-out t-out with the 0 number 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") {
return safeOutput(ctx['var']);
}
}"
`;
exports[`t-out t-out with the 0 number, in a p 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = safeOutput(ctx['var']);
return block1([], [b2]);
}
}"
`;
exports[`t-out top level t-out with undefined 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") {
return safeOutput(ctx['var']);
}
}"
`;
exports[`t-out variable 1`] = `
"function anonymous(app, bdom, helpers
) {
+15
View File
@@ -67,6 +67,21 @@ describe("t-esc", () => {
);
});
test("t-esc with the 0 number", () => {
const template = `<t t-esc="var"/>`;
expect(renderToString(template, { var: 0 })).toBe("0");
});
test("t-esc with the 0 number, in a p", () => {
const template = `<p><t t-esc="var"/></p>`;
expect(renderToString(template, { var: 0 })).toBe("<p>0</p>");
});
test("top level t-esc with undefined", () => {
const template = `<t t-esc="var"/>`;
expect(renderToString(template, { var: undefined })).toBe("");
});
test("falsy values in text nodes", () => {
const template = `
<t t-esc="v1"/>:<t t-esc="v2"/>:<t t-esc="v3"/>:<t t-esc="v4"/>:<t t-esc="v5"/>`;
+15
View File
@@ -47,6 +47,21 @@ describe("t-out", () => {
expect(renderToString(template, { var: new String("ok") })).toBe("<span>ok</span>");
});
test("t-out with the 0 number", () => {
const template = `<t t-out="var"/>`;
expect(renderToString(template, { var: 0 })).toBe("0");
});
test("t-out with the 0 number, in a p", () => {
const template = `<p><t t-out="var"/></p>`;
expect(renderToString(template, { var: 0 })).toBe("<p>0</p>");
});
test("top level t-out with undefined", () => {
const template = `<t t-out="var"/>`;
expect(renderToString(template, { var: undefined })).toBe("");
});
test("with an extended String class", () => {
class LoveString extends String {
valueOf(): string {
@@ -1308,6 +1308,18 @@ exports[`t-out in components can switch the contents of two t-out repeatedly 1`]
}"
`;
exports[`t-out in components t-out and updating falsy values, 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") {
return safeOutput(ctx['state'].a);
}
}"
`;
exports[`t-out in components update properly on state changes 1`] = `
"function anonymous(app, bdom, helpers
) {
+21
View File
@@ -1084,4 +1084,25 @@ describe("t-out in components", () => {
await nextTick();
expect(fixture.innerHTML).toBe("<div>1</div><div>2</div>");
});
test("t-out and updating falsy values, ", async () => {
class Test extends Component {
static template = xml`<t t-out="state.a"/>`;
state: any = useState({ a: 0 });
}
const comp = await mount(Test, fixture);
expect(fixture.innerHTML).toBe("0");
comp.state.a = undefined;
await nextTick();
expect(fixture.innerHTML).toBe("");
comp.state.a = "hello";
await nextTick();
expect(fixture.innerHTML).toBe("hello");
comp.state.a = false;
await nextTick();
expect(fixture.innerHTML).toBe("false");
});
});