Fix the coordinate shift caused by CSS zoom (#2341)

Fixed the coordinate shift caused by CSS zoom
This commit is contained in:
笑小笑 2024-10-05 14:07:46 +08:00 committed by GitHub
parent 928ed65e51
commit 4792d44af8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 28 additions and 21 deletions

View file

@ -324,7 +324,7 @@ class Autocomplete {
}
}
updatePosition() {
updatePosition() {
if (!this.container || !this.input) {
return;
}
@ -335,21 +335,25 @@ class Autocomplete {
// Extend the list's max width to input field's width or at least to the maxWidth defined in the CSS file
this.list.style.maxWidth = `max(${Pixels(this.input.offsetWidth)}, 600px)`;
// Get body zoom radio
const zoom = kpxcUI.bodyStyle.zoom || 1;
// Calculate Y offset if menu does not fit to the bottom of the screen -> show it at the top of the input field
const menuRect = this.container.getBoundingClientRect();
const totalHeight = menuRect.height + rect.height;
const menuOffset = totalHeight + rect.y > window.self.visualViewport.height ? totalHeight : 0;
const menuOffset = (totalHeight + rect.y) / zoom > window.self.visualViewport.height ? totalHeight / zoom : 0;
const scrollTop = kpxcUI.getScrollTop() / zoom;
const scrollLeft = kpxcUI.getScrollLeft() / zoom;
const scrollTop = kpxcUI.getScrollTop();
const scrollLeft = kpxcUI.getScrollLeft();
if (kpxcUI.bodyStyle.position.toLowerCase() === 'relative') {
this.container.style.top = Pixels(
rect.top - kpxcUI.bodyRect.top + scrollTop + this.input.offsetHeight - menuOffset,
((rect.top - kpxcUI.bodyRect.top) / zoom + scrollTop + this.input.offsetHeight - menuOffset)
);
this.container.style.left = Pixels(rect.left - kpxcUI.bodyRect.left + scrollLeft);
this.container.style.left = Pixels((rect.left - kpxcUI.bodyRect.left) / zoom + scrollLeft);
} else {
this.container.style.top = Pixels(rect.top + scrollTop + this.input.offsetHeight - menuOffset);
this.container.style.left = Pixels(rect.left + scrollLeft);
this.container.style.top = Pixels(rect.top / zoom + scrollTop + this.input.offsetHeight - menuOffset)
this.container.style.left = Pixels(rect.left / zoom + scrollLeft);
}
}
}

View file

@ -504,6 +504,7 @@ kpxcCustomLoginFieldsBanner.selectStringFields = function() {
kpxcCustomLoginFieldsBanner.markFields = function() {
let firstInput;
const inputs = document.querySelectorAll(kpxcCustomLoginFieldsBanner.inputQueryPattern);
const zoom = kpxcUI.bodyStyle.zoom || 1;
for (const i of inputs) {
if (kpxcCustomLoginFieldsBanner.isFieldSelected(i) || inputFieldIsSelected(i)) {
@ -519,10 +520,10 @@ kpxcCustomLoginFieldsBanner.markFields = function() {
field.originalElement = i;
const rect = i.getBoundingClientRect();
field.style.top = Pixels(rect.top);
field.style.left = Pixels(rect.left);
field.style.width = Pixels(rect.width);
field.style.height = Pixels(rect.height);
field.style.top = Pixels(rect.top / zoom);
field.style.left = Pixels(rect.left / zoom);
field.style.width = Pixels(rect.width / zoom);
field.style.height = Pixels(rect.height / zoom);
field.textContent = dataStepToString();
// Change selection theme if needed
@ -605,11 +606,12 @@ kpxcCustomLoginFieldsBanner.monitorSelectionPosition = function(selection) {
// Set selection input field position dynamically including the scroll position
kpxcCustomLoginFieldsBanner.setSelectionPosition = function(field) {
const zoom = kpxcUI.bodyStyle.zoom || 1;
const rect = field.originalElement.getBoundingClientRect();
const left = kpxcUI.getRelativeLeftPosition(rect);
const top = kpxcUI.getRelativeTopPosition(rect);
const scrollTop = kpxcUI.getScrollTop();
const scrollLeft = kpxcUI.getScrollLeft();
const left = kpxcUI.getRelativeLeftPosition(rect) / zoom;
const top = kpxcUI.getRelativeTopPosition(rect) / zoom;
const scrollTop = kpxcUI.getScrollTop() / zoom;
const scrollLeft = kpxcUI.getScrollLeft() / zoom;
field.style.top = Pixels(top + scrollTop);
field.style.left = Pixels(left + scrollLeft);

View file

@ -154,8 +154,9 @@ kpxcUI.setIconPosition = function(icon, field, rtl = false, segmented = false) {
const rect = field.getBoundingClientRect();
const size = Number(icon.getAttribute('size'));
const offset = kpxcUI.calculateIconOffset(field, size);
let left = kpxcUI.getRelativeLeftPosition(rect);
let top = kpxcUI.getRelativeTopPosition(rect);
const zoom = kpxcUI.bodyStyle.zoom || 1;
let left = kpxcUI.getRelativeLeftPosition(rect) / zoom;
let top = kpxcUI.getRelativeTopPosition(rect) / zoom;
// Add more space for the icon to show it at the right side of the field if TOTP fields are segmented
if (segmented) {
@ -169,11 +170,11 @@ kpxcUI.setIconPosition = function(icon, field, rtl = false, segmented = false) {
top = iconOffset[1];
}
const scrollTop = kpxcUI.getScrollTop();
const scrollLeft = kpxcUI.getScrollLeft();
const scrollTop = kpxcUI.getScrollTop() / zoom;
const scrollLeft = kpxcUI.getScrollLeft() / zoom;
icon.style.top = Pixels(top + scrollTop + offset + 1);
icon.style.left = rtl
? Pixels((left + scrollLeft) + offset)
? Pixels(left + scrollLeft + offset)
: Pixels(left + scrollLeft + field.offsetWidth - size - offset);
};