[IMP] web_tour: center tip on texts in tours

Before, the tour tip was centered on the container tag instead of the
text content. That asymmetry was visible for text with a text-align
different than center.

Therefore the _reposition method of the tip has been modified to better
handle such text elements. If its anchor element has inner text we
use a range to get the width of the text.

task-2477212

closes odoo/odoo#67771

Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
Younn Olivier
2021-07-09 07:53:06 +00:00
parent d6217a86a7
commit ea3b1ec9a0
+35 -2
View File
@@ -15,6 +15,7 @@ var Tip = Widget.extend({
mouseleave: '_onMouseLeave',
transitionend: '_onTransitionEnd',
},
CENTER_ON_TEXT_TAGS: ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'],
/**
* @param {Widget} parent
@@ -317,8 +318,40 @@ var Tip = Widget.extend({
of: this.$anchor,
collision: "none",
using: props => {
this.el.style.setProperty('top', `${props.top}px`, 'important');
this.el.style.setProperty('left', `${props.left}px`, 'important');
const {top} = props;
let {left} = props;
const anchorEl = this.$anchor[0];
if (this.CENTER_ON_TEXT_TAGS.includes(anchorEl.nodeName)) {
const textContainerWidth = anchorEl.getBoundingClientRect().width;
const textNode = anchorEl.firstChild;
const range = document.createRange();
range.selectNodeContents(textNode);
const textWidth = range.getBoundingClientRect().width;
const alignment = window.getComputedStyle(anchorEl).getPropertyValue('text-align');
const posVertical = (this.info.position === 'top' || this.info.position === 'bottom');
if (alignment === 'left') {
if (posVertical) {
left = left - textContainerWidth / 2 + textWidth / 2;
} else if (this.info.position === 'right') {
left = left - textContainerWidth + textWidth;
}
} else if (alignment === 'right') {
if (posVertical) {
left = left + textContainerWidth / 2 - textWidth / 2;
} else if (this.info.position === 'left') {
left = left + textContainerWidth - textWidth;
}
} else if (alignment === 'center') {
if (this.info.position === 'left') {
left = left + textContainerWidth / 2 - textWidth / 2;
} else if (this.info.position === 'right') {
left = left - textContainerWidth / 2 + textWidth / 2;
}
}
}
this.el.style.setProperty('top', `${top}px`, 'important');
this.el.style.setProperty('left', `${left}px`, 'important');
},
});
} else {