mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] app: add templates in app config
Also, improve the parsing code
This commit is contained in:
committed by
Lucas Perais - lpe@odoo
parent
536d9e1762
commit
4a4b1fbba5
@@ -15,6 +15,7 @@ export interface AppConfig {
|
|||||||
env?: Env;
|
env?: Env;
|
||||||
translatableAttributes?: string[];
|
translatableAttributes?: string[];
|
||||||
translateFn?: (s: string) => string;
|
translateFn?: (s: string) => string;
|
||||||
|
templates?: string | Document;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DEV_MSG = `Owl is running in 'dev' mode.
|
export const DEV_MSG = `Owl is running in 'dev' mode.
|
||||||
@@ -49,6 +50,9 @@ export class App<T extends typeof Component = any> extends TemplateSet {
|
|||||||
if (config.translatableAttributes) {
|
if (config.translatableAttributes) {
|
||||||
this.translatableAttributes = config.translatableAttributes;
|
this.translatableAttributes = config.translatableAttributes;
|
||||||
}
|
}
|
||||||
|
if (config.templates) {
|
||||||
|
this.addTemplates(config.templates);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+35
-1
@@ -7,6 +7,36 @@ const bdom = { text, createBlock, list, multi, html, toggler, component };
|
|||||||
|
|
||||||
export const globalTemplates: { [key: string]: string | Node } = {};
|
export const globalTemplates: { [key: string]: string | Node } = {};
|
||||||
|
|
||||||
|
function parseXML(xml: string): Document {
|
||||||
|
const parser = new DOMParser();
|
||||||
|
|
||||||
|
const doc = parser.parseFromString(xml, "text/xml");
|
||||||
|
if (doc.getElementsByTagName("parsererror").length) {
|
||||||
|
let msg = "Invalid XML in template.";
|
||||||
|
const parsererrorText = doc.getElementsByTagName("parsererror")[0].textContent;
|
||||||
|
if (parsererrorText) {
|
||||||
|
msg += "\nThe parser has produced the following error message:\n" + parsererrorText;
|
||||||
|
const re = /\d+/g;
|
||||||
|
const firstMatch = re.exec(parsererrorText);
|
||||||
|
if (firstMatch) {
|
||||||
|
const lineNumber = Number(firstMatch[0]);
|
||||||
|
const line = xml.split("\n")[lineNumber - 1];
|
||||||
|
const secondMatch = re.exec(parsererrorText);
|
||||||
|
if (line && secondMatch) {
|
||||||
|
const columnIndex = Number(secondMatch[0]) - 1;
|
||||||
|
if (line[columnIndex]) {
|
||||||
|
msg +=
|
||||||
|
`\nThe error might be located at xml line ${lineNumber} column ${columnIndex}\n` +
|
||||||
|
`${line}\n${"-".repeat(columnIndex - 1)}^`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error(msg);
|
||||||
|
}
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
export class TemplateSet {
|
export class TemplateSet {
|
||||||
rawTemplates: typeof globalTemplates = Object.create(globalTemplates);
|
rawTemplates: typeof globalTemplates = Object.create(globalTemplates);
|
||||||
templates: { [name: string]: Template } = {};
|
templates: { [name: string]: Template } = {};
|
||||||
@@ -33,7 +63,11 @@ export class TemplateSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addTemplates(xml: string | Document, options: { allowDuplicate?: boolean } = {}) {
|
addTemplates(xml: string | Document, options: { allowDuplicate?: boolean } = {}) {
|
||||||
xml = xml instanceof Document ? xml : new DOMParser().parseFromString(xml, "text/xml");
|
if (!xml) {
|
||||||
|
// empty string
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xml = xml instanceof Document ? xml : parseXML(xml);
|
||||||
for (const template of xml.querySelectorAll("[t-name]")) {
|
for (const template of xml.querySelectorAll("[t-name]")) {
|
||||||
const name = template.getAttribute("t-name")!;
|
const name = template.getAttribute("t-name")!;
|
||||||
template.removeAttribute("t-name");
|
template.removeAttribute("t-name");
|
||||||
|
|||||||
@@ -21,12 +21,12 @@ describe("error handling", () => {
|
|||||||
expect(() => context.addTemplate("test", "<div/>")).toThrow("already defined");
|
expect(() => context.addTemplate("test", "<div/>")).toThrow("already defined");
|
||||||
});
|
});
|
||||||
|
|
||||||
// test("addTemplates throw if parser error", () => {
|
test("addTemplates throw if parser error", () => {
|
||||||
// const context = new TestContext();
|
const context = new TestContext();
|
||||||
// expect(() => {
|
expect(() => {
|
||||||
// context.addTemplates("<templates><abc>></templates>");
|
context.addTemplates("<templates><abc>></templates>");
|
||||||
// }).toThrow("Invalid XML in template");
|
}).toThrow("Invalid XML in template");
|
||||||
// });
|
});
|
||||||
|
|
||||||
test("nice error when t-on is evaluated with a missing event", () => {
|
test("nice error when t-on is evaluated with a missing event", () => {
|
||||||
expect(() => renderToString(`<div t-on="somemethod"></div>`)).toThrow(
|
expect(() => renderToString(`<div t-on="somemethod"></div>`)).toThrow(
|
||||||
|
|||||||
Reference in New Issue
Block a user