[IMP] component: add support for dynamic css on t-widget

closes #80
This commit is contained in:
Géry Debongnie
2019-05-06 10:36:40 +02:00
parent 51320204f9
commit b9591cfecd
4 changed files with 200 additions and 10 deletions
@@ -1,5 +1,103 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`class and style attributes with t-widget dynamic t-att-style is properly added and updated on widget root el 1`] = `
"function anonymous(context,extra
) {
let owner = context;
var h = this.utils.h;
var c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1);
//WIDGET
let _2_index = c1.length;
c1.push(null);
let def3;
let w4 = 4 in context.__owl__.cmap ? context.__owl__.children[context.__owl__.cmap[4]] : false;
let props4 = {};
let isNew4 = !w4;
if (w4 && w4.__owl__.renderPromise) {
if (w4.__owl__.isStarted) {
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
} else {
isNew4 = true
if (props4 === w4.__owl__.renderProps) {
def3 = w4.__owl__.renderPromise;
} else {
w4.destroy();
w4 = false
}
}
}
if (!def3) {
if (w4) {
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
} else {
w4 = new context.widgets['child'](owner, props4);
context.__owl__.cmap[4] = w4.__owl__.id;
def3 = w4._prepare();
}
}
const _5 = context['state'].style;
if (isNew4) {
def3 = def3.then(vnode=>{vnode.data.hook = {create(_, vn){vn.elm.style = _5}};let pvnode=h(vnode.sel, {key: 4});c1[_2_index]=pvnode;pvnode.data.hook = {insert(vn){let nvn=w4._mount(vnode, vn.elm);pvnode.elm=nvn.elm;},remove(){w4.destroy()},destroy(){w4.destroy()}}; w4.__owl__.pvnode = pvnode;});
} else {
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};w4.el.style=_5;let vnode;if (!w4.__owl__.vnode){vnode=w4.__owl__.pvnode} else { vnode=h(w4.__owl__.vnode.sel, {key: 4});vnode.elm=w4.el;vnode.data.hook = {insert(a){a.elm.parentNode.replaceChild(w4.el,a.elm);a.elm=w4.el;w4.__mount();},remove(){w4.destroy()}, destroy() {w4.destroy()}}}c1[_2_index]=vnode;});
}
extra.promises.push(def3);
return vn1;
}"
`;
exports[`class and style attributes with t-widget t-att-class is properly added/removed on widget root el 1`] = `
"function anonymous(context,extra
) {
let owner = context;
var h = this.utils.h;
var c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1);
//WIDGET
let _2_index = c1.length;
c1.push(null);
let def3;
let w4 = 4 in context.__owl__.cmap ? context.__owl__.children[context.__owl__.cmap[4]] : false;
let props4 = {};
let isNew4 = !w4;
if (w4 && w4.__owl__.renderPromise) {
if (w4.__owl__.isStarted) {
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
} else {
isNew4 = true
if (props4 === w4.__owl__.renderProps) {
def3 = w4.__owl__.renderPromise;
} else {
w4.destroy();
w4 = false
}
}
}
if (!def3) {
if (w4) {
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
} else {
w4 = new context.widgets['child'](owner, props4);
context.__owl__.cmap[4] = w4.__owl__.id;
def3 = w4._prepare();
}
}
const _5 = {a: context['state'].a,b: context['state'].b};
if (isNew4) {
def3 = def3.then(vnode=>{vnode.data.hook = {create(_, vn){for (let k in _5) {
if (_5[k]) {
vn.elm.classList.add(k);
}
}}};let pvnode=h(vnode.sel, {key: 4});c1[_2_index]=pvnode;pvnode.data.hook = {insert(vn){let nvn=w4._mount(vnode, vn.elm);pvnode.elm=nvn.elm;},remove(){w4.destroy()},destroy(){w4.destroy()}}; w4.__owl__.pvnode = pvnode;});
} else {
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let cl=w4.el.classList;for (let k in _5) {if (_5[k]) {cl.add(k)} else {cl.remove(k)}}let vnode;if (!w4.__owl__.vnode){vnode=w4.__owl__.pvnode} else { vnode=h(w4.__owl__.vnode.sel, {key: 4});vnode.elm=w4.el;vnode.data.hook = {insert(a){a.elm.parentNode.replaceChild(w4.el,a.elm);a.elm=w4.el;w4.__mount();},remove(){w4.destroy()}, destroy() {w4.destroy()}}}c1[_2_index]=vnode;});
}
extra.promises.push(def3);
return vn1;
}"
`;
exports[`composition sub widgets with some state rendered in a loop 1`] = `
"function anonymous(context,extra
) {
+60 -2
View File
@@ -1234,13 +1234,39 @@ describe("class and style attributes with t-widget", () => {
widgets = { child: Child };
}
class Child extends Widget {
inlineTemplate = `<div class="c"/>`
inlineTemplate = `<div class="c"/>`;
}
const widget = new ParentWidget(env);
await widget.mount(fixture);
expect(fixture.innerHTML).toBe(`<div><div class="c a b"></div></div>`);
});
test("t-att-class is properly added/removed on widget root el", async () => {
env.qweb.addTemplate(
"parent",
`<div>
<t t-widget="child" t-att-class="{a:state.a, b:state.b}"/>
</div>`
);
class ParentWidget extends Widget {
template = "parent";
widgets = { child: Child };
state = { a: true, b: false };
}
class Child extends Widget {
inlineTemplate = `<div class="c"/>`;
}
const widget = new ParentWidget(env);
await widget.mount(fixture);
expect(fixture.innerHTML).toBe(`<div><div class="c a"></div></div>`);
expect(env.qweb.templates.parent.fn.toString()).toMatchSnapshot();
widget.state.a = false;
widget.state.b = true;
await nextTick();
expect(fixture.innerHTML).toBe(`<div><div class="c b"></div></div>`);
});
test("style is properly added on widget root el", async () => {
class ParentWidget extends Widget {
inlineTemplate = `
@@ -1251,7 +1277,39 @@ describe("class and style attributes with t-widget", () => {
}
const widget = new ParentWidget(env);
await widget.mount(fixture);
expect(fixture.innerHTML).toBe(`<div><div style="font-weight: bold;"></div></div>`);
expect(fixture.innerHTML).toBe(
`<div><div style="font-weight: bold;"></div></div>`
);
});
test("dynamic t-att-style is properly added and updated on widget root el", async () => {
env.qweb.addTemplate(
"parent",
`
<div>
<t t-widget="child" t-att-style="state.style"/>
</div>`
);
class ParentWidget extends Widget {
template = "parent";
widgets = { child: Widget };
state = { style: "font-size: 20px" };
}
const widget = new ParentWidget(env);
await widget.mount(fixture);
expect(env.qweb.templates.parent.fn.toString()).toMatchSnapshot();
expect(fixture.innerHTML).toBe(
`<div><div style="font-size: 20px;"></div></div>`
);
widget.state.style = "font-size: 30px";
await nextTick();
expect(fixture.innerHTML).toBe(
`<div><div style="font-size: 30px;"></div></div>`
);
});
});