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)`
|
`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 {
|
} else {
|
||||||
target = component.__owl__.vnode || document.createElement(fiber.vnode!.sel!);
|
target = component.__owl__.vnode || document.createElement(fiber.vnode!.sel!);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,14 +28,30 @@ afterEach(() => {
|
|||||||
describe("mount targets", () => {
|
describe("mount targets", () => {
|
||||||
test("can attach a component to an existing node (if same tagname)", async () => {
|
test("can attach a component to an existing node (if same tagname)", async () => {
|
||||||
class App extends Component {
|
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");
|
const div = document.createElement("div");
|
||||||
|
div.classList.add('arbitrary');
|
||||||
|
div.innerHTML = `<p>pre-existing</p>`;
|
||||||
fixture.appendChild(div);
|
fixture.appendChild(div);
|
||||||
|
|
||||||
const app = new App();
|
const app = new App();
|
||||||
await app.mount(div, { position: "self" });
|
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 () => {
|
test("cannot attach a component to an existing node (if not same tagname)", async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user