mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] compiler: call translate function with correct string
Before this commit, the parser would remove all consecutive white spaces for text nodes. After that, the code generator would call the translate function with the resulting string, which then is different than what we would expect. With this commit, we make sure we apply the translation before removing the additional whitespace. To do that, we have to move the code processing the string from the parser into the code generator, which actually makes sense, as the parser should only collect all useful information without applying too much logic. closes #1351
This commit is contained in:
committed by
Sam Degueldre
parent
cdad48d3a6
commit
7ac81ed5fe
@@ -32,6 +32,7 @@ import {
|
||||
import { OwlError } from "../runtime/error_handling";
|
||||
|
||||
type BlockType = "block" | "text" | "multi" | "list" | "html" | "comment";
|
||||
const whitespaceRE = /\s+/g;
|
||||
|
||||
export interface Config {
|
||||
translateFn?: (s: string) => string;
|
||||
@@ -166,6 +167,7 @@ interface Context {
|
||||
nameSpace?: string;
|
||||
tModelSelectedExpr?: string;
|
||||
ctxVar?: string;
|
||||
inPreTag?: boolean;
|
||||
}
|
||||
|
||||
function createContext(parentCtx: Context, params?: Partial<Context>): Context {
|
||||
@@ -534,6 +536,9 @@ export class CodeGenerator {
|
||||
const match = translationRE.exec(value) as any;
|
||||
value = match[1] + this.translateFn(match[2]) + match[3];
|
||||
}
|
||||
if (!ctx.inPreTag) {
|
||||
value = value.replace(whitespaceRE, " ");
|
||||
}
|
||||
|
||||
if (!block || forceNewBlock) {
|
||||
block = this.createBlock(block, "text", ctx);
|
||||
@@ -746,6 +751,7 @@ export class CodeGenerator {
|
||||
tKeyExpr: ctx.tKeyExpr,
|
||||
nameSpace,
|
||||
tModelSelectedExpr,
|
||||
inPreTag: ctx.inPreTag || ast.tag === "pre",
|
||||
});
|
||||
this.compileAST(child, subCtx);
|
||||
}
|
||||
|
||||
@@ -261,16 +261,12 @@ function parseTNode(node: Element, ctx: ParsingContext): AST | null {
|
||||
// Text and Comment Nodes
|
||||
// -----------------------------------------------------------------------------
|
||||
const lineBreakRE = /[\r\n]/;
|
||||
const whitespaceRE = /\s+/g;
|
||||
|
||||
function parseTextCommentNode(node: Node, ctx: ParsingContext): AST | null {
|
||||
if (node.nodeType === Node.TEXT_NODE) {
|
||||
let value = node.textContent || "";
|
||||
if (!ctx.inPreTag) {
|
||||
if (lineBreakRE.test(value) && !value.trim()) {
|
||||
return null;
|
||||
}
|
||||
value = value.replace(whitespaceRE, " ");
|
||||
if (!ctx.inPreTag && lineBreakRE.test(value) && !value.trim()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { type: ASTType.Text, value };
|
||||
|
||||
@@ -64,3 +64,16 @@ exports[`translation support translation is done on the trimmed text, with extra
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`translation support translation works, even if initial string has inner consecutive white space 1`] = `
|
||||
"function anonymous(app, bdom, helpers
|
||||
) {
|
||||
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
|
||||
|
||||
let block1 = createBlock(\`<div>un mot</div>\`);
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return block1();
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
@@ -26,10 +26,10 @@ describe("qweb parser", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("white spaces are condensed into a single space", async () => {
|
||||
test("white spaces are maintained", async () => {
|
||||
expect(parse(" ")).toEqual({
|
||||
type: ASTType.Text,
|
||||
value: " ",
|
||||
value: " ",
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -88,4 +88,16 @@ describe("translation support", () => {
|
||||
expect(fixture.innerHTML).toBe("<div> mot </div>");
|
||||
expect(translateFn).toHaveBeenCalledWith("word");
|
||||
});
|
||||
|
||||
test("translation works, even if initial string has inner consecutive white space", async () => {
|
||||
class SomeComponent extends Component {
|
||||
static template = xml`<div>some word</div>`;
|
||||
}
|
||||
|
||||
const translateFn = jest.fn((expr: string) => (expr === "some word" ? "un mot" : expr));
|
||||
|
||||
await mount(SomeComponent, fixture, { translateFn });
|
||||
expect(translateFn).toHaveBeenCalledWith("some word");
|
||||
expect(fixture.innerHTML).toBe("<div>un mot</div>");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user