imp: allow object descriptors for attributes

close #6
This commit is contained in:
Géry Debongnie
2019-03-21 11:14:18 +01:00
parent a8b3ec7726
commit a34fc39100
4 changed files with 46 additions and 5 deletions
+4 -4
View File
@@ -27,13 +27,13 @@
</span>
<ul class="filters">
<li>
<a href="#/all" t-on-click="updateState({filter:'all'})" t-att-class="state.filter === 'all' ? 'selected' : ''">All</a>
<a href="#/all" t-on-click="updateState({filter:'all'})" t-att-class="{selected: state.filter === 'all'}">All</a>
</li>
<li>
<a href="#/active" t-on-click="updateState({filter:'active'})" t-att-class="state.filter === 'active' ? 'selected' : ''">Active</a>
<a href="#/active" t-on-click="updateState({filter:'active'})" t-att-class="{selected: state.filter === 'active'}">Active</a>
</li>
<li>
<a href="#/completed" t-on-click="updateState({filter:'completed'})" t-att-class="state.filter === 'completed' ? 'selected' : ''">Completed</a>
<a href="#/completed" t-on-click="updateState({filter:'completed'})" t-att-class="{selected: state.filter === 'completed'}">Completed</a>
</li>
</ul>
<button class="clear-completed" t-if="todos.length gt remaining" t-on-click="clearCompleted">
@@ -42,7 +42,7 @@
</footer>
</section>
<li t-name="todoitem" class="todo" t-att-class="(props.completed ? 'completed ' : ' ') + (state.isEditing ? 'editing' : '')">
<li t-name="todoitem" class="todo" t-att-class="{completed: props.completed, editing: state.isEditing}">
<div class="view">
<input class="toggle" type="checkbox" t-on-change="toggleTodo" t-att-checked="props.completed"/>
<label t-on-dblclick="editTodo">
+19
View File
@@ -162,6 +162,15 @@ export class QWeb {
const temp = document.createElement("template");
temp.innerHTML = str;
return temp.content;
},
objectToAttrString(obj: Object): string {
let classes: string[] = [];
for (let k in obj) {
if (obj[k]) {
classes.push(k);
}
}
return classes.join(" ");
}
};
@@ -470,6 +479,12 @@ export class QWeb {
if (name.startsWith("t-att-")) {
let attName = name.slice(6);
let formattedValue = this._formatExpression(ctx.getValue(value!), ctx);
if (
formattedValue[0] === "{" &&
formattedValue[formattedValue.length - 1] === "}"
) {
formattedValue = `this.utils.objectToAttrString(${formattedValue})`;
}
const attID = ctx.generateID();
if (!attName.match(/^[a-zA-Z]+$/)) {
// attribute contains 'non letters' => we want to quote it
@@ -482,6 +497,10 @@ export class QWeb {
const attValueID = ctx.generateID();
ctx.addLine(`let _${attValueID} = ${formattedValue};`);
formattedValue = `'${attValue}' + (_${attValueID} ? ' ' + _${attValueID} : '')`;
const attrIndex = attrs.findIndex(att =>
att.startsWith(attName + ":")
);
attrs.splice(attrIndex, 1);
}
ctx.addLine(`let _${attID} = ${formattedValue};`);
attrs.push(`${attName}: _${attID}`);
+14 -1
View File
@@ -188,7 +188,20 @@ exports[`attributes t-att-class and class should combine together 1`] = `
let _1 = 'hello';
let _3 = context['value'];
let _2 = 'hello' + (_3 ? ' ' + _3 : '');
let c4 = [], p4 = {key:4,attrs:{class: _1,class: _2}};
let c4 = [], p4 = {key:4,attrs:{class: _2}};
let vn4 = h('div', p4, c4);
return vn4;
}"
`;
exports[`attributes t-att-class with object 1`] = `
"function anonymous(context,extra
) {
let h = this.utils.h;
let _1 = 'static';
let _3 = this.utils.objectToAttrString({a: context['b'],c: context['d'],e: context['f']});
let _2 = 'static' + (_3 ? ' ' + _3 : '');
let c4 = [], p4 = {key:4,attrs:{class: _2}};
let vn4 = h('div', p4, c4);
return vn4;
}"
+9
View File
@@ -464,6 +464,15 @@ describe("attributes", () => {
const result = renderToString(qweb, "test", { value: "world" });
expect(result).toBe(`<div class="hello world"></div>`);
});
test("t-att-class with object", () => {
qweb.addTemplate(
"test",
`<div class="static" t-att-class="{a: b, c: d, e: f}"/>`
);
const result = renderToString(qweb, "test", { b: true, d: false, f: true });
expect(result).toBe(`<div class="static a e"></div>`);
});
});
describe("t-call (template calling", () => {