FIX: Ensure mention autocomplete box doesn't go off-screen in RTL locales (#21905)

Meta topic: https://meta.discourse.org/t/mention-suggestion-list-box-in-the-rtl-website-in-wrong-place/266763?u=osama.

Our autocomplete box doesn't currently take into account the user's locale and places itself off-screen when using an RTL locale. This commit changes the placement logic for the autocomplete box when an RTL locale is used to make sure that:

1. the autocomplete box's right side is near and to the left of the caret 
2. the autocomplete box doesn't go beyond the composer's left side.
This commit is contained in:
Osama Sayegh 2023-06-02 19:55:00 +03:00 committed by GitHub
parent 95a51b7d8a
commit fc0e7fe802
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,6 +6,7 @@ import Site from "discourse/models/site";
import { createPopper } from "@popperjs/core";
import discourseDebounce from "discourse-common/lib/debounce";
import { iconHTML } from "discourse-common/lib/icon-library";
import { isDocumentRTL } from "discourse/lib/text-direction";
/**
This is a jQuery plugin to support autocompleting values in our text fields.
@ -420,20 +421,14 @@ export default function (options) {
}
let vOffset = 0;
let hOffset = 0;
let pos = me.caretPosition({
pos: completeStart + 1,
});
hOffset = 10;
if (options.treatAsTextarea) {
vOffset = -32;
}
div.css({
left: "-1000px",
});
if (!isInput && !options.treatAsTextarea) {
vOffset = div.height();
@ -446,34 +441,39 @@ export default function (options) {
vOffset = BELOW;
}
if (Site.currentProp("mobileView") && me.height() / 2 >= pos.top) {
vOffset = BELOW;
}
}
const mePos = me.position();
let left;
if (isDocumentRTL()) {
left = mePos.left + pos.left - div.width();
} else {
let hOffset = 10;
if (Site.currentProp("mobileView")) {
if (me.height() / 2 >= pos.top) {
vOffset = BELOW;
}
if (me.width() / 2 <= pos.left) {
hOffset = -div.width();
}
}
left = mePos.left + pos.left + hOffset;
}
let mePos = me.position();
let borderTop = parseInt(me.css("border-top-width"), 10) || 0;
let left = mePos.left + pos.left + hOffset;
if (left < 0) {
left = 0;
}
const offsetTop = me.offset().top;
const borderTop = parseInt(me.css("border-top-width"), 10) || 0;
if (mePos.top + pos.top + borderTop - vOffset + offsetTop < 30) {
vOffset = BELOW;
}
div.css({
position: "absolute",
top: mePos.top + pos.top - vOffset + borderTop + "px",
left: left + "px",
top: `${mePos.top + pos.top - vOffset + borderTop}px`,
left: `${left}px`,
});
}