[FIX] transition: no crash if added/removed quickly

This commit should fix crashes coming from transition code on nodes.
This does not impact transitions on components.

closes #637
closes #641
This commit is contained in:
Géry Debongnie
2020-02-20 13:46:00 +01:00
committed by aab-odoo
parent b00188c1ce
commit ce052e0992
3 changed files with 51 additions and 0 deletions
+7
View File
@@ -183,6 +183,13 @@ function toMs(s: string): number {
}
function whenTransitionEnd(elm: HTMLElement, cb) {
if (!elm.parentNode) {
// if we get here, this means that the element was removed for some other
// reasons, and in that case, we don't want to work on animation since nothing
// will be displayed anyway.
return;
}
const styles = window.getComputedStyle(elm);
const delays: Array<string> = (styles.transitionDelay || "").split(", ");
const durations: Array<string> = (styles.transitionDuration || "").split(", ");
@@ -177,3 +177,24 @@ exports[`animations t-transition, on a simple node (insert) 1`] = `
return vn1;
}"
`;
exports[`animations t-transition, on a simple node, not in the DOM 1`] = `
"function anonymous(context, extra
) {
// Template name: \\"test\\"
let utils = this.constructor.utils;
let h = this.h;
let c1 = [], p1 = {key:1};
let vn1 = h('span', p1, c1);
p1.hook = {
insert: vn => {
utils.transitionInsert(vn, 'chimay');
},
remove: (vn, rm) => {
utils.transitionRemove(vn, 'chimay', rm);
},
};
c1.push({text: \`blue\`});
return vn1;
}"
`;
+23
View File
@@ -78,6 +78,7 @@ describe("animations", () => {
def.resolve();
});
let node: HTMLElement = <HTMLElement>renderToDOM(qweb, "test");
fixture.appendChild(node);
expect(node.className).toBe("chimay-enter chimay-enter-active");
await def; // wait for the mocked repaint to be done
@@ -85,6 +86,27 @@ describe("animations", () => {
expect(node.className).toBe("");
});
test("t-transition, on a simple node, not in the DOM", async () => {
expect.assertions(5);
qweb.addTemplate("test", `<span t-transition="chimay">blue</span>`);
let def = makeDeferred();
patchNextFrame(cb => {
expect(node.className).toBe("chimay-enter chimay-enter-active");
cb();
expect(node.className).toBe("chimay-enter-active chimay-enter-to");
def.resolve();
});
let node: HTMLElement = <HTMLElement>renderToDOM(qweb, "test");
expect(node.className).toBe("chimay-enter chimay-enter-active");
await def; // wait for the mocked repaint to be done
node.dispatchEvent(new Event("transitionend"));
// we check here that the css classes have not been removed, since the
// element is not in the dom, we actually do not want to do anything.
expect(node.className).toBe("chimay-enter-active chimay-enter-to");
});
test("t-transition with no delay/duration", async () => {
expect.assertions(4);
qweb.addTemplate("test", `<span t-transition="jupiler">blue</span>`);
@@ -97,6 +119,7 @@ describe("animations", () => {
def.resolve();
});
let node: HTMLElement = <HTMLElement>renderToDOM(qweb, "test");
fixture.appendChild(node);
expect(node.className).toBe("jupiler-enter jupiler-enter-active");
await def;
});