diff --git a/addons/web_tour/static/src/tour_pointer/tour_pointer.js b/addons/web_tour/static/src/tour_pointer/tour_pointer.js
index 5faea7bf50a..18b4a865470 100644
--- a/addons/web_tour/static/src/tour_pointer/tour_pointer.js
+++ b/addons/web_tour/static/src/tour_pointer/tour_pointer.js
@@ -19,7 +19,6 @@ export class TourPointer extends Component {
shape: {
anchor: { type: HTMLElement, optional: true },
content: { type: String, optional: true },
- fixed: { type: Boolean, optional: true },
isOpen: { type: Boolean, optional: true },
isVisible: { type: Boolean, optional: true },
onClick: { type: [Function, { value: null }], optional: true },
@@ -54,6 +53,7 @@ export class TourPointer extends Component {
let dimensions = null;
let lastMeasuredContent = null;
let lastOpenState = this.isOpen;
+ let lastAnchor;
let [anchorX, anchorY] = [0, 0];
useEffect(
@@ -90,7 +90,7 @@ export class TourPointer extends Component {
if (!this.isOpen) {
const { anchor } = this.props.pointerState;
- if (anchor) {
+ if (anchor === lastAnchor) {
const { x, y, width } = anchor.getBoundingClientRect();
const [lastAnchorX, lastAnchorY] = [anchorX, anchorY];
[anchorX, anchorY] = [x, y];
@@ -104,35 +104,38 @@ export class TourPointer extends Component {
const wouldOverflow =
window.innerWidth - x - width / 2 < dimensions?.width;
el.classList.toggle("o_expand_left", wouldOverflow);
- reposition(anchor, el, null, {
- position: this.position,
- margin: 6,
- onPositioned: (popper, position) => {
- const popperRect = popper.getBoundingClientRect();
- const { top, left, direction } = position;
- if (direction === "top") {
- popper.style.bottom = `${
- window.innerHeight - top - popperRect.height
- }px`;
- popper.style.removeProperty("top");
- } else {
- popper.style.top = `${top}px`;
- }
- if (direction === "left") {
- popper.style.right = `${
- window.innerWidth - left - popperRect.width
- }px`;
- popper.style.removeProperty("left");
- } else {
- popper.style.left = `${left}px`;
- }
- },
- });
}
+ lastAnchor = anchor;
+ el.style.bottom = "";
+ el.style.right = "";
+ reposition(anchor, el, null, {
+ position: this.position,
+ margin: 6,
+ onPositioned: (popper, position) => {
+ const popperRect = popper.getBoundingClientRect();
+ const { top, left, direction } = position;
+ if (direction === "top") {
+ // position from the bottom instead of the top as it is needed
+ // to ensure the expand animation is properly done
+ popper.style.bottom = `${
+ window.innerHeight - top - popperRect.height
+ }px`;
+ popper.style.removeProperty("top");
+ } else if (direction === "left") {
+ // position from the right instead of the left as it is needed
+ // to ensure the expand animation is properly done
+ popper.style.right = `${
+ window.innerWidth - left - popperRect.width
+ }px`;
+ popper.style.removeProperty("left");
+ }
+ },
+ });
}
} else {
lastMeasuredContent = null;
lastOpenState = false;
+ lastAnchor = null;
dimensions = null;
}
},
diff --git a/addons/web_tour/static/src/tour_pointer/tour_pointer.xml b/addons/web_tour/static/src/tour_pointer/tour_pointer.xml
index 65e2328fffd..4234ef7f5eb 100644
--- a/addons/web_tour/static/src/tour_pointer/tour_pointer.xml
+++ b/addons/web_tour/static/src/tour_pointer/tour_pointer.xml
@@ -8,7 +8,6 @@
o_tour_pointer
o_{{ position }}
{{ isOpen ? 'o_open' : (props.bounce ? 'o_bouncing' : '') }}
- {{ props.pointerState.fixed ? 'position-fixed' : 'position-absolute' }}
{{ props.pointerState.onClick ? 'cursor-pointer' : '' }}
"
t-attf-style="
diff --git a/addons/web_tour/static/src/tour_service/tour_pointer_state.js b/addons/web_tour/static/src/tour_service/tour_pointer_state.js
index 50e169fe36e..b7189f987c9 100644
--- a/addons/web_tour/static/src/tour_service/tour_pointer_state.js
+++ b/addons/web_tour/static/src/tour_service/tour_pointer_state.js
@@ -15,7 +15,6 @@ import { getScrollParent } from "./tour_utils";
* @typedef TourPointerState
* @property {HTMLElement} [anchor]
* @property {string} [content]
- * @property {boolean} fixed
* @property {boolean} [isOpen]
* @property {() => {}} [onClick]
* @property {() => {}} [onMouseEnter]
diff --git a/addons/web_tour/static/tests/tour_service_tests.js b/addons/web_tour/static/tests/tour_service_tests.js
index cda8479ee46..66186929af7 100644
--- a/addons/web_tour/static/tests/tour_service_tests.js
+++ b/addons/web_tour/static/tests/tour_service_tests.js
@@ -60,7 +60,7 @@ QUnit.module("Tour service", (hooks) => {
start() {
super.start(...arguments);
macroEngines.push(this);
- }
+ },
});
registerCleanup(() => {
macroEngines.forEach((e) => e.stop());
@@ -76,7 +76,7 @@ QUnit.module("Tour service", (hooks) => {
.add("tour_service", tourService);
patchWithCleanup(browser.console, {
// prevent form logging "tour successful" which would end the qunit suite test
- log: () => {}
+ log: () => {},
});
});
@@ -135,6 +135,60 @@ QUnit.module("Tour service", (hooks) => {
assert.strictEqual(target.querySelector("span.value").textContent, "1");
});
+ QUnit.test("next step with new anchor at same position", async (assert) => {
+ registry.category("web_tour.tours").add("tour1", {
+ sequence: 10,
+ steps: () => [{ trigger: "button.foo" }, { trigger: "button.bar" }],
+ });
+ const env = await makeTestEnv({});
+
+ const { Component: OverlayContainer, props: overlayContainerProps } = registry
+ .category("main_components")
+ .get("OverlayContainer");
+
+ class Dummy extends Component {
+ state = useState({ bool: true });
+ static template = xml/*html*/ `
+
+
+ `;
+ }
+ class Root extends Component {
+ static components = { OverlayContainer, Dummy };
+ static template = xml/*html*/ `
+