mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
import h from "../libs/snabbdom/src/h";
|
import h from "../libs/snabbdom/src/h";
|
||||||
import sdAttrs from "../libs/snabbdom/src/modules/attributes";
|
import sdAttrs from "../libs/snabbdom/src/modules/attributes";
|
||||||
|
import sdProps from "../libs/snabbdom/src/modules/props";
|
||||||
import sdListeners from "../libs/snabbdom/src/modules/eventlisteners";
|
import sdListeners from "../libs/snabbdom/src/modules/eventlisteners";
|
||||||
import { init } from "../libs/snabbdom/src/snabbdom";
|
import { init } from "../libs/snabbdom/src/snabbdom";
|
||||||
import { VNode } from "../libs/snabbdom/src/vnode";
|
import { VNode } from "../libs/snabbdom/src/vnode";
|
||||||
@@ -35,7 +36,7 @@ export interface Meta<T extends Env, Props> {
|
|||||||
boundHandlers: { [key: number]: any };
|
boundHandlers: { [key: number]: any };
|
||||||
}
|
}
|
||||||
|
|
||||||
const patch = init([sdListeners, sdAttrs]);
|
const patch = init([sdListeners, sdAttrs, sdProps]);
|
||||||
|
|
||||||
export interface Type<T> extends Function {
|
export interface Type<T> extends Function {
|
||||||
new (...args: any[]): T;
|
new (...args: any[]): T;
|
||||||
|
|||||||
+41
@@ -23,6 +23,15 @@ const WORD_REPLACEMENT = {
|
|||||||
lte: "<="
|
lte: "<="
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DISABLED_TAGS = [
|
||||||
|
"input",
|
||||||
|
"textarea",
|
||||||
|
"button",
|
||||||
|
"select",
|
||||||
|
"option",
|
||||||
|
"optgroup"
|
||||||
|
];
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Compilation Context
|
// Compilation Context
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -413,7 +422,34 @@ export class QWeb {
|
|||||||
}
|
}
|
||||||
const attributes = (<Element>node).attributes;
|
const attributes = (<Element>node).attributes;
|
||||||
const attrs: string[] = [];
|
const attrs: string[] = [];
|
||||||
|
const props: string[] = [];
|
||||||
const tattrs: number[] = [];
|
const tattrs: number[] = [];
|
||||||
|
|
||||||
|
function handleBooleanProps(key, val) {
|
||||||
|
let isProp = false;
|
||||||
|
if (node.nodeName === "input" && key === "checked") {
|
||||||
|
let type = (<Element>node).getAttribute("type");
|
||||||
|
if (type === "checkbox" || type === "radio") {
|
||||||
|
isProp = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node.nodeName === "option" && key === "selected") {
|
||||||
|
isProp = true;
|
||||||
|
}
|
||||||
|
if (key === "disabled" && DISABLED_TAGS.indexOf(node.nodeName) > -1) {
|
||||||
|
isProp = true;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(key === "readonly" && node.nodeName === "input") ||
|
||||||
|
node.nodeName === "textarea"
|
||||||
|
) {
|
||||||
|
isProp = true;
|
||||||
|
}
|
||||||
|
if (isProp) {
|
||||||
|
props.push(`${key}: _${val}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0; i < attributes.length; i++) {
|
for (let i = 0; i < attributes.length; i++) {
|
||||||
let name = attributes[i].name;
|
let name = attributes[i].name;
|
||||||
const value = attributes[i].textContent!;
|
const value = attributes[i].textContent!;
|
||||||
@@ -427,6 +463,7 @@ export class QWeb {
|
|||||||
name = '"' + name + '"';
|
name = '"' + name + '"';
|
||||||
}
|
}
|
||||||
attrs.push(`${name}: _${attID}`);
|
attrs.push(`${name}: _${attID}`);
|
||||||
|
handleBooleanProps(name, attID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dynamic attributes
|
// dynamic attributes
|
||||||
@@ -448,6 +485,7 @@ export class QWeb {
|
|||||||
}
|
}
|
||||||
ctx.addLine(`let _${attID} = ${formattedValue};`);
|
ctx.addLine(`let _${attID} = ${formattedValue};`);
|
||||||
attrs.push(`${attName}: _${attID}`);
|
attrs.push(`${attName}: _${attID}`);
|
||||||
|
handleBooleanProps(attName, attID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name.startsWith("t-attf-")) {
|
if (name.startsWith("t-attf-")) {
|
||||||
@@ -477,6 +515,9 @@ export class QWeb {
|
|||||||
if (attrs.length + tattrs.length > 0) {
|
if (attrs.length + tattrs.length > 0) {
|
||||||
parts.push(`attrs:{${attrs.join(",")}}`);
|
parts.push(`attrs:{${attrs.join(",")}}`);
|
||||||
}
|
}
|
||||||
|
if (props.length > 0) {
|
||||||
|
parts.push(`props:{${props.join(",")}}`);
|
||||||
|
}
|
||||||
if (withHandlers) {
|
if (withHandlers) {
|
||||||
parts.push(`on:{}`);
|
parts.push(`on:{}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -581,6 +581,74 @@ exports[`misc global 1`] = `
|
|||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`special cases for some boolean html attributes/properties input type= checkbox, with t-att-checked 1`] = `
|
||||||
|
"function anonymous(context,extra
|
||||||
|
) {
|
||||||
|
let h = this.utils.h;
|
||||||
|
let _1 = 'checkbox';
|
||||||
|
let _2 = context['flag'];
|
||||||
|
let c3 = [], p3 = {key:3,attrs:{type: _1,checked: _2},props:{checked: _2}};
|
||||||
|
let vn3 = h('input', p3, c3);
|
||||||
|
return vn3;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`special cases for some boolean html attributes/properties various boolean html attributes 1`] = `
|
||||||
|
"function anonymous(context,extra
|
||||||
|
) {
|
||||||
|
let h = this.utils.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
let vn1 = h('div', p1, c1);
|
||||||
|
c1.push({text: \`
|
||||||
|
\`});
|
||||||
|
let _2 = 'checkbox';
|
||||||
|
let _3 = 'checked';
|
||||||
|
let c4 = [], p4 = {key:4,attrs:{type: _2,checked: _3},props:{checked: _3}};
|
||||||
|
let vn4 = h('input', p4, c4);
|
||||||
|
c1.push(vn4);
|
||||||
|
c1.push({text: \`
|
||||||
|
\`});
|
||||||
|
let _5 = 'checked';
|
||||||
|
let c6 = [], p6 = {key:6,attrs:{checked: _5}};
|
||||||
|
let vn6 = h('input', p6, c6);
|
||||||
|
c1.push(vn6);
|
||||||
|
c1.push({text: \`
|
||||||
|
\`});
|
||||||
|
let _7 = 'checked';
|
||||||
|
let c8 = [], p8 = {key:8,attrs:{checked: _7}};
|
||||||
|
let vn8 = h('div', p8, c8);
|
||||||
|
c1.push(vn8);
|
||||||
|
c1.push({text: \`
|
||||||
|
\`});
|
||||||
|
let _9 = 'selected';
|
||||||
|
let c10 = [], p10 = {key:10,attrs:{selected: _9}};
|
||||||
|
let vn10 = h('div', p10, c10);
|
||||||
|
c1.push(vn10);
|
||||||
|
c1.push({text: \`
|
||||||
|
\`});
|
||||||
|
let _11 = 'selected';
|
||||||
|
let _12 = '1';
|
||||||
|
let c13 = [], p13 = {key:13,attrs:{selected: _11,other: _12},props:{selected: _11}};
|
||||||
|
let vn13 = h('option', p13, c13);
|
||||||
|
c1.push(vn13);
|
||||||
|
c1.push({text: \`
|
||||||
|
\`});
|
||||||
|
let _14 = 'readonly';
|
||||||
|
let c15 = [], p15 = {key:15,attrs:{readonly: _14},props:{readonly: _14}};
|
||||||
|
let vn15 = h('input', p15, c15);
|
||||||
|
c1.push(vn15);
|
||||||
|
c1.push({text: \`
|
||||||
|
\`});
|
||||||
|
let _16 = 'disabled';
|
||||||
|
let c17 = [], p17 = {key:17,attrs:{disabled: _16},props:{disabled: _16}};
|
||||||
|
let vn17 = h('button', p17, c17);
|
||||||
|
c1.push(vn17);
|
||||||
|
c1.push({text: \`
|
||||||
|
\`});
|
||||||
|
return vn1;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`static templates div with a span child node 1`] = `
|
exports[`static templates div with a span child node 1`] = `
|
||||||
"function anonymous(context,extra
|
"function anonymous(context,extra
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -886,3 +886,32 @@ describe("loading templates", () => {
|
|||||||
expect(qweb.processedTemplates).toEqual({});
|
expect(qweb.processedTemplates).toEqual({});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("special cases for some boolean html attributes/properties", () => {
|
||||||
|
test("input type= checkbox, with t-att-checked", () => {
|
||||||
|
qweb.addTemplate("test", `<input type="checkbox" t-att-checked="flag"/>`);
|
||||||
|
const result = renderToString(qweb, "test", { flag: true });
|
||||||
|
expect(result).toBe(`<input type="checkbox" checked="">`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("various boolean html attributes", () => {
|
||||||
|
// the unique assertion here is the code snapshot automatically done by
|
||||||
|
// renderToString
|
||||||
|
expect.assertions(1);
|
||||||
|
qweb.addTemplate(
|
||||||
|
"test",
|
||||||
|
`
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" checked="checked"/>
|
||||||
|
<input checked="checked"/>
|
||||||
|
<div checked="checked"/>
|
||||||
|
<div selected="selected"/>
|
||||||
|
<option selected="selected" other="1"/>
|
||||||
|
<input readonly="readonly"/>
|
||||||
|
<button disabled="disabled"/>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
renderToString(qweb, "test", { flag: true });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user