mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] component: reorganize fiber update algorithm
Closes #473 Closes #484 Closes #489 Closes #492 Closes #512 Co-authored-by: Aaron Bohy <aab@odoo.com>
This commit is contained in:
+72
-23
@@ -1,13 +1,15 @@
|
||||
import { Component, Env } from "../src/component/component";
|
||||
import { QWeb } from "../src/qweb/index";
|
||||
import { useState, useRef } from "../src/hooks";
|
||||
import { xml } from "../src/tags";
|
||||
import {
|
||||
makeDeferred,
|
||||
makeTestFixture,
|
||||
makeTestEnv,
|
||||
patchNextFrame,
|
||||
renderToDOM,
|
||||
unpatchNextFrame
|
||||
unpatchNextFrame,
|
||||
nextTick
|
||||
} from "./helpers";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -321,30 +323,23 @@ describe("animations", () => {
|
||||
});
|
||||
|
||||
test("t-transition combined with t-component, remove and re-add before transitionend", async () => {
|
||||
expect.assertions(11);
|
||||
expect.assertions(12);
|
||||
|
||||
env.qweb.addTemplates(
|
||||
`<templates>
|
||||
<div t-name="Parent">
|
||||
<button t-on-click="toggle">Toggle</button>
|
||||
<t t-if="state.flag" t-component="Child" t-transition="chimay"/>
|
||||
</div>
|
||||
<span t-name="Child">blue</span>
|
||||
</templates>`
|
||||
);
|
||||
class Child extends Widget {}
|
||||
class Child extends Widget {
|
||||
static template = xml`<span>blue</span>`;
|
||||
}
|
||||
class Parent extends Widget {
|
||||
static template = xml`
|
||||
<div t-name="Parent">
|
||||
<t t-if="state.flag" t-component="Child" t-transition="chimay"/>
|
||||
</div>`;
|
||||
static components = { Child };
|
||||
state = useState({ flag: false });
|
||||
|
||||
toggle() {
|
||||
this.state.flag = !this.state.flag;
|
||||
}
|
||||
}
|
||||
|
||||
const widget = new Parent();
|
||||
await widget.mount(fixture);
|
||||
let button = widget.el!.querySelector("button");
|
||||
expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot();
|
||||
|
||||
let def = makeDeferred();
|
||||
let phase = "enter";
|
||||
@@ -357,24 +352,78 @@ describe("animations", () => {
|
||||
def.resolve();
|
||||
});
|
||||
|
||||
// click display the span
|
||||
button!.click();
|
||||
// display the span
|
||||
widget.state.flag = true;
|
||||
await def; // wait for the mocked repaint to be done
|
||||
widget.el!.querySelector("span")!.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
||||
expect(fixture.innerHTML).toBe('<div><button>Toggle</button><span class="">blue</span></div>');
|
||||
expect(fixture.innerHTML).toBe('<div><span class="">blue</span></div>');
|
||||
|
||||
// click to remove the span, and click again to re-add it before transitionend
|
||||
def = makeDeferred();
|
||||
phase = "leave";
|
||||
button!.click();
|
||||
|
||||
widget.state.flag = false;
|
||||
|
||||
await def; // wait for the mocked repaint to be done
|
||||
def = makeDeferred();
|
||||
phase = "enter";
|
||||
button!.click();
|
||||
widget.state.flag = true;
|
||||
|
||||
await def; // wait for the mocked repaint to be done
|
||||
widget.el!.querySelector("span")!.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
||||
expect(fixture.innerHTML).toBe('<div><button>Toggle</button><span class="">blue</span></div>');
|
||||
expect(fixture.innerHTML).toBe('<div><span class="" data-owl-key="__5__">blue</span></div>');
|
||||
});
|
||||
|
||||
test("transitionInsert is called the correct amount of times", async () => {
|
||||
const oldTransitionInsert = QWeb.utils.transitionInsert;
|
||||
QWeb.utils.transitionInsert = jest.fn(oldTransitionInsert);
|
||||
|
||||
class Child extends Widget {
|
||||
static template = xml`<span>blue</span>`;
|
||||
}
|
||||
class Parent extends Widget {
|
||||
static template = xml`
|
||||
<div t-name="Parent">
|
||||
<Child t-if="state.flag" t-transition="chimay"/>
|
||||
</div>`;
|
||||
static components = { Child };
|
||||
state = useState({ flag: false });
|
||||
}
|
||||
|
||||
patchNextFrame(cb => cb());
|
||||
|
||||
const widget = new Parent();
|
||||
await widget.mount(fixture);
|
||||
|
||||
widget.state.flag = true;
|
||||
|
||||
await nextTick();
|
||||
widget.el!.querySelector("span")!.dispatchEvent(new Event("transitionend"));
|
||||
expect(fixture.innerHTML).toBe('<div><span class="">blue</span></div>');
|
||||
expect(QWeb.utils.transitionInsert).toBeCalledTimes(1);
|
||||
|
||||
widget.state.flag = false;
|
||||
await nextTick();
|
||||
expect(fixture.innerHTML).toBe(
|
||||
'<div><span class="chimay-leave-active chimay-leave-to" data-owl-key="__5__">blue</span></div>'
|
||||
);
|
||||
expect(QWeb.utils.transitionInsert).toBeCalledTimes(1);
|
||||
|
||||
widget.state.flag = true;
|
||||
await nextTick();
|
||||
expect(fixture.innerHTML).toBe(
|
||||
'<div><span class="chimay-enter-active chimay-enter-to" data-owl-key="__5__">blue</span></div>'
|
||||
);
|
||||
expect(QWeb.utils.transitionInsert).toBeCalledTimes(2);
|
||||
|
||||
widget.state.flag = false;
|
||||
await nextTick();
|
||||
widget.state.flag = true;
|
||||
await nextTick();
|
||||
|
||||
expect(QWeb.utils.transitionInsert).toBeCalledTimes(3);
|
||||
widget.el!.querySelector("span")!.dispatchEvent(new Event("transitionend"));
|
||||
expect(fixture.innerHTML).toBe('<div><span class="" data-owl-key="__5__">blue</span></div>');
|
||||
QWeb.utils.transitionInsert = oldTransitionInsert;
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user