mirror of
https://github.com/keepassxreboot/keepassxc-browser.git
synced 2026-03-11 08:54:43 +00:00
Fix topmost input element check with labels (#2667)
Fix topmost input element check with labels
This commit is contained in:
parent
7f062de937
commit
345b5e0bc9
3 changed files with 21 additions and 7 deletions
|
|
@ -124,6 +124,7 @@
|
|||
"IMPROVED_DETECTION_PREDEFINED_SITELIST": "readonly",
|
||||
"initColorTheme": "readonly",
|
||||
"isEdge": "readonly",
|
||||
"isElementInside": "readonly",
|
||||
"isFirefox": "readonly",
|
||||
"keepass": "readonly",
|
||||
"keepassClient": "readonly",
|
||||
|
|
|
|||
|
|
@ -182,11 +182,13 @@ const getCurrentTab = async function() {
|
|||
return tabs?.length > 0 ? tabs[0] : undefined;
|
||||
};
|
||||
|
||||
// Check if element b is inside a
|
||||
const isElementInside = (a, b) => (b.x >= a.x || b.right <= a.right) && (b.y >= a.y || b.bottom <= a.bottom);
|
||||
|
||||
// Check if two elements overlap
|
||||
const elementsOverlap = function(rect1, rect2) {
|
||||
const isInside = (a, b) => (b.x >= a.x || b.right <= a.right) && (b.y >= a.y || b.bottom <= a.bottom);
|
||||
const overlaps = (a, b) => !(a.right < b.left || a.left > b.right || a.bottom < b.top || a.top > b.bottom);
|
||||
return isInside(rect1, rect2) || overlaps(rect1, rect2);
|
||||
return isElementInside(rect1, rect2) || overlaps(rect1, rect2);
|
||||
};
|
||||
|
||||
// Exports for tests
|
||||
|
|
|
|||
|
|
@ -416,13 +416,24 @@ kpxcFields.isTopElement = function(elem, rect) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Check topmost element from three points inside the input
|
||||
const verticalMiddle = rect.top + (rect.height / 2);
|
||||
const rootNode = elem.getRootNode() ?? document;
|
||||
|
||||
// Returns the topmost element from point x, height/2
|
||||
// If the input has a label as the top element and it's inside the input, allow it.
|
||||
const getTopmostElement = (element, x, elementRect) => {
|
||||
const topElement = rootNode.elementFromPoint(x, elementRect.top + (elementRect.height / 2));
|
||||
return element?.labels &&
|
||||
element.labels[0] === topElement &&
|
||||
isElementInside(elementRect, topElement.getBoundingClientRect())
|
||||
? element
|
||||
: topElement;
|
||||
};
|
||||
|
||||
// Check topmost element from three points inside the input
|
||||
if (matchesWithNodeName(elem, 'INPUT') && [
|
||||
rootNode.elementFromPoint(rect.left + (rect.width / 4), verticalMiddle), // First third
|
||||
rootNode.elementFromPoint(rect.left + (rect.width / 2), verticalMiddle), // Middle
|
||||
rootNode.elementFromPoint(rect.left + (rect.width / 1.33), verticalMiddle), // Last third
|
||||
getTopmostElement(elem, rect.left + (rect.width / 4), rect), // First third
|
||||
getTopmostElement(elem, rect.left + (rect.width / 2), rect), // Middle
|
||||
getTopmostElement(elem, rect.left + (rect.width / 1.33), rect), // Last third
|
||||
].some((e) => e !== elem)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue