mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] component: self mounting position keeps the reference
Have
```xml
<body t-name="webclient" />
```
and
```js
const comp = new WebClient();
comp.mount(document.body, {position: 'self'});
```
Before this commit, the body that was there before anything had happened
was *replaced* by the new body node created by the WebClient OWL component
After this commit, we ensure that the element body is the same at reference level
This commit is contained in:
committed by
Géry Debongnie
parent
718e5264ae
commit
b4ad14edc0
@@ -225,6 +225,12 @@ export class Fiber {
|
||||
`Cannot attach '${component.constructor.name}' to target node (not same tag name)`
|
||||
);
|
||||
}
|
||||
// In self mode, we *know* we are to take possession of the target
|
||||
// Hence we manually create the corresponding VNode and copy the "key" in data
|
||||
const selfVnodeData = fiber.vnode!.data ? {key: fiber.vnode!.data.key} : {};
|
||||
const selfVnode = h(fiber.vnode!.sel, selfVnodeData);
|
||||
selfVnode.elm = target;
|
||||
target = selfVnode;
|
||||
} else {
|
||||
target = component.__owl__.vnode || document.createElement(fiber.vnode!.sel!);
|
||||
}
|
||||
|
||||
@@ -28,14 +28,30 @@ afterEach(() => {
|
||||
describe("mount targets", () => {
|
||||
test("can attach a component to an existing node (if same tagname)", async () => {
|
||||
class App extends Component {
|
||||
static template = xml`<div>app</div>`;
|
||||
static template = xml`<div t-att-class="state.customClass">app<p>another tag</p></div>`;
|
||||
state = useState({customClass: 'custom'});
|
||||
}
|
||||
const div = document.createElement("div");
|
||||
div.classList.add('arbitrary');
|
||||
div.innerHTML = `<p>pre-existing</p>`;
|
||||
fixture.appendChild(div);
|
||||
|
||||
const app = new App();
|
||||
await app.mount(div, { position: "self" });
|
||||
expect(fixture.innerHTML).toBe("<div>app</div>");
|
||||
|
||||
expect(fixture.innerHTML).toBe(`<div class="arbitrary custom"><p>pre-existing</p>app<p>another tag</p></div>`);
|
||||
expect(div).toBe(app.el);
|
||||
|
||||
app.state.customClass = 'custom2';
|
||||
await nextTick();
|
||||
expect(fixture.innerHTML).toBe(`<div class="arbitrary custom2"><p>pre-existing</p>app<p>another tag</p></div>`);
|
||||
expect(div).toBe(app.el);
|
||||
|
||||
app.unmount()
|
||||
// This assert is a best guess
|
||||
// The use case it covers was not really thought through
|
||||
// and may change in the future
|
||||
expect(fixture.innerHTML).toBe("");
|
||||
});
|
||||
|
||||
test("cannot attach a component to an existing node (if not same tagname)", async () => {
|
||||
|
||||
Reference in New Issue
Block a user