mirror of
https://github.com/keepassxreboot/keepassxc-browser.git
synced 2026-03-11 08:54:43 +00:00
Fix the coordinate shift caused by CSS zoom (#2341)
Fixed the coordinate shift caused by CSS zoom
This commit is contained in:
parent
928ed65e51
commit
4792d44af8
3 changed files with 28 additions and 21 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue