mirror of
https://github.com/keepassxreboot/keepassxc-browser.git
synced 2026-03-11 08:54:43 +00:00
Performance adjustments
This commit is contained in:
parent
d4fa2f7155
commit
e95c8ad450
5 changed files with 117 additions and 53 deletions
|
|
@ -575,6 +575,14 @@
|
|||
"message": "Activate username field icons.",
|
||||
"description": "Activate username field icons textbox text."
|
||||
},
|
||||
"optionsUseObserver": {
|
||||
"message": "Use dynamic input field detection.",
|
||||
"description": "Use dynamic input field detection checkbox text."
|
||||
},
|
||||
"optionsUseObserverHelpText": {
|
||||
"message": "Useful with pages that use popups or dynamic dialogs. Disable the feature to reduce CPU load on slower machines. When disabled credentials can be only inserted using keyboard shortcuts, the context menu or the extension popup.",
|
||||
"description": "Use dynamic input field detection help text."
|
||||
},
|
||||
"optionsCheckboxOTPIcons": {
|
||||
"message": "Activate 2FA/OTP field icons.",
|
||||
"description": "Activate OTP field icons textbox text."
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ const defaultSettings = {
|
|||
showLoginNotifications: true,
|
||||
showNotifications: true,
|
||||
showOTPIcon: true,
|
||||
useObserver: true,
|
||||
usePasswordGeneratorIcons: false
|
||||
};
|
||||
|
||||
|
|
@ -76,6 +77,10 @@ page.initSettings = async function() {
|
|||
page.settings.defaultGroupAlwaysAsk = defaultSettings.defaultGroupAlwaysAsk;
|
||||
}
|
||||
|
||||
if (!('redirectAllowance' in page.settings)) {
|
||||
page.settings.redirectAllowance = defaultSettings.redirectAllowance;
|
||||
}
|
||||
|
||||
if (!('saveDomainOnly' in page.settings)) {
|
||||
page.settings.saveDomainOnly = defaultSettings.saveDomainOnly;
|
||||
}
|
||||
|
|
@ -100,8 +105,12 @@ page.initSettings = async function() {
|
|||
page.settings.usePasswordGeneratorIcons = defaultSettings.usePasswordGeneratorIcons;
|
||||
}
|
||||
|
||||
if (!('redirectAllowance' in page.settings)) {
|
||||
page.settings.redirectAllowance = defaultSettings.redirectAllowance;
|
||||
if (!('useObserver' in page.settings)) {
|
||||
page.settings.useObserver = defaultSettings.useObserver;
|
||||
}
|
||||
|
||||
if (!('usePasswordGeneratorIcons' in page.settings)) {
|
||||
page.settings.usePasswordGeneratorIcons = defaultSettings.usePasswordGeneratorIcons;
|
||||
}
|
||||
|
||||
await browser.storage.local.set({ 'settings': page.settings });
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ _called.manualFillRequested = ManualFill.NONE;
|
|||
let _singleInputEnabledForPage = false;
|
||||
let _databaseClosed = true;
|
||||
const _maximumInputs = 100;
|
||||
const _maximumMutations = 200;
|
||||
|
||||
// Count of detected form fields on the page
|
||||
var _detectedFields = 0;
|
||||
|
|
@ -712,7 +713,7 @@ kpxcObserverHelper.handleObserverAdd = function(target) {
|
|||
if (Object.keys(kpxc.settings).length === 0) {
|
||||
kpxc.init();
|
||||
} else {
|
||||
kpxc.initCredentialFields(true);
|
||||
kpxc.initCredentialFields(true, inputs);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -747,53 +748,6 @@ kpxcObserverHelper.detectURLChange = function() {
|
|||
|
||||
MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
|
||||
|
||||
// Detects DOM changes in the document
|
||||
const observer = new MutationObserver(function(mutations, obs) {
|
||||
if (document.visibilityState === 'hidden') {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const mut of mutations) {
|
||||
// Skip text nodes
|
||||
if (mut.target.nodeType === Node.TEXT_NODE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check document URL change and detect new fields
|
||||
kpxcObserverHelper.detectURLChange();
|
||||
|
||||
// Handle attributes only if CSS display is modified
|
||||
if (mut.type === 'attributes') {
|
||||
// Check if some class is changed that folds a form or input field(s)
|
||||
if (mut.attributeName === 'class' && mut.target.querySelectorAll('form input').length > 0) {
|
||||
kpxc.initCredentialFields(true);
|
||||
continue;
|
||||
}
|
||||
|
||||
const newValue = mut.target.getAttribute(mut.attributeName);
|
||||
if (newValue && (newValue.includes('display') || newValue.includes('z-index'))) {
|
||||
if (mut.target.style.display !== 'none') {
|
||||
kpxcObserverHelper.handleObserverAdd(mut.target);
|
||||
} else {
|
||||
kpxcObserverHelper.handleObserverRemove(mut.target);
|
||||
}
|
||||
}
|
||||
} else if (mut.type === 'childList') {
|
||||
kpxcObserverHelper.handleObserverAdd((mut.addedNodes.length > 0) ? mut.addedNodes[0] : mut.target);
|
||||
kpxcObserverHelper.handleObserverRemove((mut.removedNodes.length > 0) ? mut.removedNodes[0] : mut.target);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// define what element should be observed by the observer
|
||||
// and what types of mutations trigger the callback
|
||||
observer.observe(document, {
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
childList: true,
|
||||
characterData: true,
|
||||
attributeFilter: [ 'style', 'class' ]
|
||||
});
|
||||
|
||||
|
||||
const kpxc = {};
|
||||
|
|
@ -811,6 +765,16 @@ const initcb = async function() {
|
|||
});
|
||||
|
||||
kpxc.settings = settings;
|
||||
|
||||
// Don't initialize MutationObserver if the site is ignored
|
||||
if (kpxc.siteIgnored()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (kpxc.settings.useObserver) {
|
||||
kpxc.initObserver();
|
||||
}
|
||||
|
||||
await kpxc.initCredentialFields();
|
||||
|
||||
// Retrieve submitted credentials if available.
|
||||
|
|
@ -851,6 +815,61 @@ kpxc.init = function() {
|
|||
initcb();
|
||||
};
|
||||
|
||||
// Detects DOM changes in the document
|
||||
kpxc.initObserver = function() {
|
||||
const observer = new MutationObserver(function(mutations, obs) {
|
||||
if (document.visibilityState === 'hidden' || kpxcUI.mouseDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Limit the mutation handling
|
||||
if (mutations.length > _maximumMutations) {
|
||||
mutations.slice(0, _maximumMutations);
|
||||
}
|
||||
|
||||
for (const mut of mutations) {
|
||||
// Skip text nodes
|
||||
if (mut.target.nodeType === Node.TEXT_NODE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check document URL change and detect new fields
|
||||
kpxcObserverHelper.detectURLChange();
|
||||
|
||||
// Handle attributes only if CSS display is modified
|
||||
if (mut.type === 'attributes') {
|
||||
// Check if some class is changed that folds a form or input field(s)
|
||||
if (mut.attributeName === 'class' && mut.target.querySelectorAll('form input').length > 0) {
|
||||
kpxc.initCredentialFields(true);
|
||||
continue;
|
||||
}
|
||||
|
||||
const newValue = mut.target.getAttribute(mut.attributeName);
|
||||
if (newValue && (newValue.includes('display') || newValue.includes('z-index'))) {
|
||||
if (mut.target.style.display !== 'none') {
|
||||
kpxcObserverHelper.handleObserverAdd(mut.target);
|
||||
} else {
|
||||
kpxcObserverHelper.handleObserverRemove(mut.target);
|
||||
}
|
||||
}
|
||||
} else if (mut.type === 'childList') {
|
||||
kpxcObserverHelper.handleObserverAdd((mut.addedNodes.length > 0) ? mut.addedNodes[0] : mut.target);
|
||||
kpxcObserverHelper.handleObserverRemove((mut.removedNodes.length > 0) ? mut.removedNodes[0] : mut.target);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// define what element should be observed by the observer
|
||||
// and what types of mutations trigger the callback
|
||||
observer.observe(document, {
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
childList: true,
|
||||
characterData: true,
|
||||
attributeFilter: [ 'style', 'class' ]
|
||||
});
|
||||
};
|
||||
|
||||
// Clears all from the content and background scripts, including autocomplete
|
||||
kpxc.clearAllFromPage = function() {
|
||||
kpxcEvents.clearCredentials();
|
||||
|
|
@ -920,7 +939,7 @@ kpxc.siteIgnored = function(condition) {
|
|||
return false;
|
||||
};
|
||||
|
||||
kpxc.initCredentialFields = async function(forceCall) {
|
||||
kpxc.initCredentialFields = async function(forceCall, inputs) {
|
||||
if (_called.initCredentialFields && !forceCall) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -937,7 +956,11 @@ kpxc.initCredentialFields = async function(forceCall) {
|
|||
return;
|
||||
}
|
||||
|
||||
const inputs = kpxcFields.getAllFields();
|
||||
// If target input fields are not defined, get inputs from the whole document
|
||||
if (inputs === undefined) {
|
||||
inputs = kpxcFields.getAllFields();
|
||||
}
|
||||
|
||||
if (inputs.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -989,9 +1012,13 @@ kpxc.initCredentialFields = async function(forceCall) {
|
|||
};
|
||||
|
||||
kpxc.initPasswordGenerator = function(inputs) {
|
||||
if (!kpxc.settings.usePasswordGeneratorIcons) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < inputs.length; i++) {
|
||||
if (inputs[i] && inputs[i].getLowerCaseAttribute('type') === 'password') {
|
||||
kpxcPasswordIcons.newIcon(kpxc.settings.usePasswordGeneratorIcons, inputs[i], inputs, i, _databaseClosed);
|
||||
kpxcPasswordIcons.newIcon(true, inputs[i], inputs, i, _databaseClosed);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class Icon {
|
|||
};
|
||||
|
||||
const kpxcUI = {};
|
||||
kpxcUI.mouseDown = false;
|
||||
|
||||
// Wrapper for creating elements
|
||||
kpxcUI.createElement = function(type, classes, attributes, textContent) {
|
||||
|
|
@ -167,6 +168,10 @@ const initColorTheme = function(elem) {
|
|||
|
||||
// Enables dragging
|
||||
document.addEventListener('mousemove', function(e) {
|
||||
if (!kpxcUI.mouseDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (kpxcPasswordDialog.selected === kpxcPasswordDialog.titleBar) {
|
||||
const xPos = e.clientX - kpxcPasswordDialog.diffX;
|
||||
const yPos = e.clientY - kpxcPasswordDialog.diffY;
|
||||
|
|
@ -188,9 +193,14 @@ document.addEventListener('mousemove', function(e) {
|
|||
}
|
||||
});
|
||||
|
||||
document.addEventListener('mousedown', function() {
|
||||
kpxcUI.mouseDown = true;
|
||||
});
|
||||
|
||||
document.addEventListener('mouseup', function() {
|
||||
kpxcPasswordDialog.selected = null;
|
||||
kpxcDefine.selected = null;
|
||||
kpxcUI.mouseDown = false;
|
||||
});
|
||||
|
||||
HTMLDivElement.prototype.appendMultiple = function(...args) {
|
||||
|
|
|
|||
|
|
@ -77,6 +77,16 @@
|
|||
</div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="useObserver" value="true"/><span data-i18n="optionsUseObserver"></span>
|
||||
</label>
|
||||
<span class="help-block">
|
||||
<span data-i18n="optionsUseObserverHelpText"></span>
|
||||
</span>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
<div class="checkbox">
|
||||
<label class="checkbox">
|
||||
|
|
|
|||
Loading…
Reference in a new issue