mirror of
https://github.com/keepassxreboot/keepassxc-browser.git
synced 2026-03-11 08:54:43 +00:00
Merge pull request #2687 from keepassxreboot/fix/overlay_elements
Use popovers for icons and Autocomplete Menu in DOM
This commit is contained in:
commit
e842e01cf3
9 changed files with 39 additions and 26 deletions
|
|
@ -100,7 +100,9 @@ class Autocomplete {
|
|||
styleSheet.addEventListener('load', () => (this.wrapper.style.display = 'block'));
|
||||
this.container = kpxcUI.createElement('div', 'kpxcAutocomplete-container', {
|
||||
id: 'kpxcAutocomplete-container',
|
||||
popover: 'manual',
|
||||
});
|
||||
this.container.style.margin = 0;
|
||||
|
||||
// Apply compact mode class
|
||||
if (kpxc.settings.useCompactMode) {
|
||||
|
|
@ -128,6 +130,7 @@ class Autocomplete {
|
|||
|
||||
this.updateList();
|
||||
this.container.classList.add('kpxcAutocomplete-container--visible');
|
||||
this.container.showPopover({ source: inputField });
|
||||
this.updatePosition();
|
||||
}
|
||||
|
||||
|
|
@ -235,6 +238,7 @@ class Autocomplete {
|
|||
}
|
||||
|
||||
this.container.classList.remove('kpxcAutocomplete-container--visible');
|
||||
this.container.hidePopover();
|
||||
}
|
||||
|
||||
getAllItems() {
|
||||
|
|
@ -338,7 +342,7 @@ class Autocomplete {
|
|||
|
||||
// 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;
|
||||
|
|
|
|||
|
|
@ -433,7 +433,7 @@ kpxcFields.isSearchField = function(target) {
|
|||
|
||||
// :popover-open selector is supported only with Firefox >= 125 and Chrome >= 114
|
||||
kpxcFields.discoverOverlays = function() {
|
||||
try {
|
||||
try {
|
||||
kpxcFields.overlays = document.querySelectorAll(':popover-open, [popover]');
|
||||
} catch (e) {
|
||||
// Ignore SyntaxError (e.g., unsupported selector)
|
||||
|
|
|
|||
|
|
@ -50,18 +50,17 @@ PasswordIcon.prototype.initField = function(field) {
|
|||
|
||||
PasswordIcon.prototype.createIcon = function(field) {
|
||||
const className = (isFirefox() ? 'key-moz' : 'key');
|
||||
const size = (field.offsetHeight > 28) ? 24 : 16;
|
||||
const offset = kpxcUI.calculateIconOffset(field, size);
|
||||
const size = this.calculateIconSize(field);
|
||||
|
||||
const icon = kpxcUI.createElement('div', 'kpxc kpxc-pwgen-icon ' + className,
|
||||
{
|
||||
'title': tr('passwordGeneratorGenerateText'),
|
||||
'size': size,
|
||||
'offset': offset,
|
||||
'kpxc-pwgen-field-id': field.getAttribute('data-kpxc-id') // Needed?
|
||||
'kpxc-pwgen-field-id': field.getAttribute('data-kpxc-id'),
|
||||
'popover': 'manual'
|
||||
});
|
||||
|
||||
icon.style.zIndex = '10000000';
|
||||
icon.style.margin = 0;
|
||||
icon.style.width = Pixels(size);
|
||||
icon.style.height = Pixels(size);
|
||||
|
||||
|
|
@ -75,7 +74,7 @@ PasswordIcon.prototype.createIcon = function(field) {
|
|||
}
|
||||
|
||||
if (e.shiftKey) {
|
||||
icon.style.display = 'none';
|
||||
icon.hidePopover();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -89,6 +88,7 @@ PasswordIcon.prototype.createIcon = function(field) {
|
|||
kpxcUI.setIconPosition(icon, field, this.rtl);
|
||||
this.icon = icon;
|
||||
this.createWrapper('css/pwgen.css');
|
||||
icon.showPopover();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -140,18 +140,15 @@ TOTPFieldIcon.prototype.initField = async function(field, segmented) {
|
|||
|
||||
TOTPFieldIcon.prototype.createIcon = function(field, segmented = false) {
|
||||
const className = (isFirefox() ? 'moz' : 'default');
|
||||
|
||||
// Size the icon dynamically, but not greater than 24 or smaller than 14
|
||||
const size = Math.max(Math.min(24, field.offsetHeight - 4), 14);
|
||||
const offset = kpxcUI.calculateIconOffset(field, size);
|
||||
const size = this.calculateIconSize(field);
|
||||
|
||||
const icon = kpxcUI.createElement('div', 'kpxc kpxc-totp-icon ' + className,
|
||||
{
|
||||
'title': tr('totpFieldText'),
|
||||
'size': size,
|
||||
'offset': offset
|
||||
'popover': 'manual'
|
||||
});
|
||||
icon.style.zIndex = '10000000';
|
||||
icon.style.margin = 0;
|
||||
icon.style.width = Pixels(size);
|
||||
icon.style.height = Pixels(size);
|
||||
|
||||
|
|
@ -167,7 +164,7 @@ TOTPFieldIcon.prototype.createIcon = function(field, segmented = false) {
|
|||
}
|
||||
|
||||
if (e.shiftKey) {
|
||||
icon.style.display = 'none';
|
||||
icon.hidePopover();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -182,4 +179,5 @@ TOTPFieldIcon.prototype.createIcon = function(field, segmented = false) {
|
|||
kpxcUI.setIconPosition(icon, field, this.rtl, segmented);
|
||||
this.icon = icon;
|
||||
this.createWrapper('css/totp.css');
|
||||
icon.showPopover();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ const MIN_INPUT_FIELD_OFFSET_WIDTH = 60;
|
|||
const MIN_OPACITY = 0.7;
|
||||
const MAX_OPACITY = 1;
|
||||
|
||||
const MIN_ICON_SIZE = 14;
|
||||
const MAX_ICON_SIZE = 24;
|
||||
|
||||
const BLUE_BUTTON = 'kpxc-button kpxc-blue-button';
|
||||
const GREEN_BUTTON = 'kpxc-button kpxc-green-button';
|
||||
const ORANGE_BUTTON = 'kpxc-button kpxc-orange-button';
|
||||
|
|
@ -52,6 +55,11 @@ class Icon {
|
|||
}
|
||||
}
|
||||
|
||||
// Size the icon dynamically, but not greater than 24 or smaller than 14
|
||||
calculateIconSize(field) {
|
||||
return Math.max(Math.min(MAX_ICON_SIZE, field.offsetHeight - 4), MIN_ICON_SIZE);
|
||||
}
|
||||
|
||||
// Creates a wrapper div that has the icon in Shadow DOM
|
||||
createWrapper(styleSheetFilename) {
|
||||
const styleSheet = createStylesheet(styleSheetFilename);
|
||||
|
|
|
|||
|
|
@ -68,9 +68,7 @@ UsernameFieldIcon.prototype.initField = function(field) {
|
|||
|
||||
UsernameFieldIcon.prototype.createIcon = function(field) {
|
||||
const className = getIconClassName(this.databaseState);
|
||||
|
||||
// Size the icon dynamically, but not greater than 24 or smaller than 14
|
||||
const size = Math.max(Math.min(24, field.offsetHeight - 4), 14);
|
||||
const size = this.calculateIconSize(field);
|
||||
|
||||
// Don't create the icon if the input field is too small
|
||||
if (field.offsetWidth < (size * 1.5) || field.offsetHeight < size) {
|
||||
|
|
@ -78,16 +76,14 @@ UsernameFieldIcon.prototype.createIcon = function(field) {
|
|||
return;
|
||||
}
|
||||
|
||||
const offset = kpxcUI.calculateIconOffset(field, size);
|
||||
|
||||
const icon = kpxcUI.createElement('div', 'kpxc kpxc-username-icon ' + className,
|
||||
{
|
||||
'title': getIconText(this.databaseState),
|
||||
'size': size,
|
||||
'offset': offset,
|
||||
'kpxc-pwgen-field-id': field.getAttribute('data-kpxc-id')
|
||||
'kpxc-pwgen-field-id': field.getAttribute('data-kpxc-id'),
|
||||
'popover': 'manual'
|
||||
});
|
||||
icon.style.zIndex = '10000000';
|
||||
icon.style.margin = 0;
|
||||
icon.style.width = Pixels(size);
|
||||
icon.style.height = Pixels(size);
|
||||
|
||||
|
|
@ -97,7 +93,7 @@ UsernameFieldIcon.prototype.createIcon = function(field) {
|
|||
}
|
||||
|
||||
if (e.shiftKey) {
|
||||
icon.style.display = 'none';
|
||||
icon.hidePopover();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -111,6 +107,7 @@ UsernameFieldIcon.prototype.createIcon = function(field) {
|
|||
kpxcUI.setIconPosition(icon, field, this.rtl);
|
||||
this.icon = icon;
|
||||
this.createWrapper('css/username.css');
|
||||
icon.showPopover();
|
||||
};
|
||||
|
||||
const iconClicked = async function(field, icon) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
.kpxc-pwgen-icon {
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
padding: 0 !important;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
.kpxc-totp-icon {
|
||||
position: absolute;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
padding: 0 !important;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.kpxc-totp-icon.default {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
.kpxc-username-icon {
|
||||
position: absolute;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
padding: 0 !important;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.kpxc-username-icon.disconnected {
|
||||
|
|
|
|||
Loading…
Reference in a new issue