mirror of
https://github.com/keepassxreboot/keepassxc-browser.git
synced 2026-03-11 08:54:43 +00:00
Fixes for page object checks and context menu item creation
This commit is contained in:
parent
a8297aeb5d
commit
d5063a6cfd
6 changed files with 243 additions and 206 deletions
|
|
@ -11,7 +11,7 @@ browserAction.show = async function(tab, popupData) {
|
|||
path: await browserAction.generateIconName(popupData.iconType)
|
||||
});
|
||||
|
||||
if (popupData.popup) {
|
||||
if (popupData.popup && tab?.id) {
|
||||
browserActionWrapper.setPopup({
|
||||
tabId: tab.id,
|
||||
popup: `popups/${popupData.popup}.html`
|
||||
|
|
@ -19,9 +19,9 @@ browserAction.show = async function(tab, popupData) {
|
|||
|
||||
let badgeText = '';
|
||||
if (popupData.popup === 'popup_login') {
|
||||
badgeText = String(page.tabs[tab.id]?.loginList?.length);
|
||||
badgeText = page.tabs[tab.id]?.loginList?.length;
|
||||
} else if (popupData.popup === 'popup_httpauth') {
|
||||
badgeText = String(page.tabs[tab.id]?.loginList?.logins?.length);
|
||||
badgeText = page.tabs[tab.id]?.loginList?.logins?.length;
|
||||
}
|
||||
|
||||
browserAction.setBadgeText(tab?.id, badgeText);
|
||||
|
|
@ -52,33 +52,22 @@ browserAction.showDefault = async function(tab) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (page.tabs[tab.id]?.loginList.length > 0) {
|
||||
if (page?.tabs[tab.id]?.loginList.length > 0) {
|
||||
popupData.iconType = 'normal';
|
||||
popupData.popup = 'popup_login';
|
||||
browserAction.setBadgeText(tab?.id, String(page.tabs[tab.id]?.loginList.length));
|
||||
browserAction.setBadgeText(tab?.id, page.tabs[tab.id]?.loginList.length);
|
||||
}
|
||||
|
||||
await browserAction.show(tab, popupData);
|
||||
};
|
||||
|
||||
browserAction.updateIcon = async function(tab, iconType) {
|
||||
if (!tab) {
|
||||
const tabs = await browser.tabs.query({ 'active': true, 'currentWindow': true });
|
||||
if (tabs.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
tab = tabs[0];
|
||||
browserAction.setBadgeText = function(tabId, badgeText) {
|
||||
if (!tabId) {
|
||||
return;
|
||||
}
|
||||
|
||||
browserActionWrapper.setIcon({
|
||||
path: browserAction.generateIconName(iconType)
|
||||
});
|
||||
};
|
||||
|
||||
browserAction.setBadgeText = function(tabId, badgeText) {
|
||||
browserActionWrapper.setBadgeBackgroundColor({ color: '#666666' });
|
||||
browserActionWrapper.setBadgeText({ text: badgeText, tabId: tabId });
|
||||
browserActionWrapper.setBadgeText({ text: String(badgeText), tabId: tabId });
|
||||
};
|
||||
|
||||
browserAction.generateIconName = async function(iconType) {
|
||||
|
|
@ -87,7 +76,7 @@ browserAction.generateIconName = async function(iconType) {
|
|||
name += (!iconType || iconType === 'normal') ? 'normal' : iconType;
|
||||
|
||||
let style = 'colored';
|
||||
if (page.settings.useMonochromeToolbarIcon) {
|
||||
if (page?.settings?.useMonochromeToolbarIcon) {
|
||||
if (page.settings.colorTheme === 'system') {
|
||||
style = await retrieveColorScheme();
|
||||
} else {
|
||||
|
|
@ -103,8 +92,10 @@ browserAction.ignoreSite = async function(url) {
|
|||
const tab = await getCurrentTab();
|
||||
|
||||
// Send the message to the current tab's content script
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: 'ignore_site',
|
||||
args: [ url ]
|
||||
});
|
||||
if (tab?.id) {
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: 'ignore_site',
|
||||
args: [ url ]
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ const kpxcEvent = {};
|
|||
|
||||
kpxcEvent.onMessage = async function(request, sender) {
|
||||
if (request.action in kpxcEvent.messageHandlers) {
|
||||
if (!Object.hasOwn(sender, 'tab') || sender.tab.id < 1) {
|
||||
if (!Object.hasOwn(sender, 'tab') || sender?.tab?.id < 1) {
|
||||
sender.tab = {};
|
||||
sender.tab.id = page.currentTabId;
|
||||
}
|
||||
|
|
@ -158,8 +158,10 @@ kpxcEvent.onLoginPopup = async function(tab, logins) {
|
|||
popup: 'popup_login'
|
||||
};
|
||||
|
||||
page.tabs[tab.id].loginList = logins;
|
||||
await browserAction.show(tab, popupData);
|
||||
if (tab?.id) {
|
||||
page.tabs[tab.id].loginList = logins;
|
||||
await browserAction.show(tab, popupData);
|
||||
}
|
||||
};
|
||||
|
||||
kpxcEvent.initHttpAuth = async function() {
|
||||
|
|
@ -177,11 +179,15 @@ kpxcEvent.onHTTPAuthPopup = async function(tab, data) {
|
|||
};
|
||||
|
||||
kpxcEvent.onUsernameFieldDetected = async function(tab, detected) {
|
||||
page.tabs[tab.id].usernameFieldDetected = detected;
|
||||
if (tab?.id) {
|
||||
page.tabs[tab.id].usernameFieldDetected = detected;
|
||||
}
|
||||
};
|
||||
|
||||
kpxcEvent.onIframeDetected = async function(tab, detected) {
|
||||
page.tabs[tab.id].iframeDetected = detected;
|
||||
if (tab?.id) {
|
||||
page.tabs[tab.id].iframeDetected = detected;
|
||||
}
|
||||
};
|
||||
|
||||
kpxcEvent.passwordGetFilled = async function() {
|
||||
|
|
@ -201,7 +207,7 @@ kpxcEvent.pageGetRedirectCount = async function() {
|
|||
};
|
||||
|
||||
kpxcEvent.pageClearLogins = async function(tab, alreadyCalled) {
|
||||
if (!alreadyCalled) {
|
||||
if (!alreadyCalled && tab?.id) {
|
||||
page.clearLogins(tab.id);
|
||||
}
|
||||
};
|
||||
|
|
@ -230,7 +236,9 @@ kpxcEvent.hideTroubleshootingGuideAlert = async function(tab) {
|
|||
|
||||
// Bounce message back to all frames
|
||||
kpxcEvent.sendBackToTabs = async function(tab, args = []) {
|
||||
await browser.tabs.sendMessage(tab.id, { action: 'frame_message', args: args });
|
||||
if (tab?.id) {
|
||||
await browser.tabs.sendMessage(tab.id, { action: 'frame_message', args: args });
|
||||
}
|
||||
};
|
||||
|
||||
// All methods named in this object have to be declared BEFORE this!
|
||||
|
|
|
|||
|
|
@ -1,113 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
await keepass.migrateKeyRing();
|
||||
await page.initSettings();
|
||||
await page.initSitePreferences();
|
||||
await page.initOpenedTabs();
|
||||
await httpAuth.init();
|
||||
await keepass.reconnect(null, 5000); // 5 second timeout for the first connect
|
||||
await keepass.enableAutomaticReconnect();
|
||||
await keepass.updateDatabase();
|
||||
} catch (e) {
|
||||
logError('init.js failed');
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* Generate information structure for created tab and invoke all needed
|
||||
* functions if tab is created in foreground
|
||||
* @param {object} tab
|
||||
*/
|
||||
browser.tabs.onCreated.addListener((tab) => {
|
||||
if (tab?.id > 0 && tab?.selected) {
|
||||
page.currentTabId = tab.id;
|
||||
|
||||
if (!page.tabs[tab.id]) {
|
||||
page.createTabEntry(tab.id);
|
||||
}
|
||||
|
||||
page.switchTab(tab);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Remove information structure of closed tab for freeing memory
|
||||
* @param {integer} tabId
|
||||
* @param {object} removeInfo
|
||||
*/
|
||||
browser.tabs.onRemoved.addListener(async function(tabId, removeInfo) {
|
||||
if (page.currentTabId === tabId) {
|
||||
const currentTab = await getCurrentTab();
|
||||
page.currentTabId = currentTab ? currentTab.id : -1;
|
||||
}
|
||||
delete page.tabs[tabId];
|
||||
});
|
||||
|
||||
/**
|
||||
* Remove stored credentials on switching tabs.
|
||||
* Invoke functions to retrieve credentials for focused tab
|
||||
* @param {object} activeInfo
|
||||
*/
|
||||
browser.tabs.onActivated.addListener(async function(activeInfo) {
|
||||
try {
|
||||
const info = await browser.tabs.get(activeInfo.tabId);
|
||||
if (info && info.id) {
|
||||
page.currentTabId = info.id;
|
||||
if (info.status === 'complete') {
|
||||
if (!page.tabs[info.id]) {
|
||||
page.createTabEntry(info.id);
|
||||
}
|
||||
page.switchTab(info);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logError(err.message);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Update browserAction on every update of the page
|
||||
* @param {integer} tabId
|
||||
* @param {object} changeInfo
|
||||
* @param {object} tab
|
||||
*/
|
||||
browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
||||
// If the tab URL has changed (e.g. logged in) clear credentials
|
||||
if (changeInfo.url) {
|
||||
page.clearLogins(tabId);
|
||||
}
|
||||
|
||||
if (changeInfo.status === 'complete') {
|
||||
browserAction.showDefault(tab);
|
||||
if (!page.tabs[tab.id]) {
|
||||
page.createTabEntry(tab.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Detects page redirects and increases the count. Count is reset after a normal navigation event.
|
||||
* Form submit is counted as one.
|
||||
* @param {object} details
|
||||
*/
|
||||
browser.webNavigation.onCommitted.addListener((details) => {
|
||||
if (details.transitionQualifiers?.[0] === 'client_redirect' || details.transitionType === 'form_submit') {
|
||||
page.redirectCount += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear credentials on reload so a new retrieval can be made
|
||||
if (details.transitionType === 'reload') {
|
||||
page.clearLogins(details.tabId);
|
||||
}
|
||||
|
||||
page.redirectCount = 0;
|
||||
});
|
||||
|
||||
browser.runtime.onMessage.addListener(kpxcEvent.onMessage);
|
||||
|
||||
const contextMenuItems = [
|
||||
{ title: tr('contextMenuFillUsernameAndPassword'), action: 'fill_username_password' },
|
||||
{ title: tr('contextMenuFillPassword'), action: 'fill_password' },
|
||||
|
|
@ -119,53 +11,176 @@ const contextMenuItems = [
|
|||
];
|
||||
|
||||
const menuContexts = [ 'editable' ];
|
||||
|
||||
|
||||
if (isFirefox()) {
|
||||
menuContexts.push('password');
|
||||
}
|
||||
|
||||
// Create context menu items
|
||||
for (const item of contextMenuItems) {
|
||||
browser.contextMenus.create({
|
||||
title: item.title,
|
||||
contexts: menuContexts,
|
||||
visible: item.visible,
|
||||
id: item.id || item.action
|
||||
});
|
||||
}
|
||||
const initListeners = async function() {
|
||||
/**
|
||||
* Generate information structure for created tab and invoke all needed
|
||||
* functions if tab is created in foreground
|
||||
* @param {object} tab
|
||||
*/
|
||||
browser.tabs.onCreated.addListener((tab) => {
|
||||
if (tab?.id > 0 && tab?.selected) {
|
||||
page.currentTabId = tab.id;
|
||||
|
||||
// Listen for keyboard shortcuts specified by user
|
||||
browser.commands.onCommand.addListener(async (command) => {
|
||||
if (contextMenuItems.some(e => e.action === command)
|
||||
|| command === 'redetect_fields'
|
||||
|| command === 'choose_credential_fields'
|
||||
|| command === 'retrive_credentials_forced'
|
||||
|| command === 'reload_extension') {
|
||||
const tab = await getCurrentTab();
|
||||
if (tab) {
|
||||
browser.tabs.sendMessage(tab.id, { action: command });
|
||||
if (!page.tabs[tab.id]) {
|
||||
page.createTabEntry(tab.id);
|
||||
}
|
||||
|
||||
page.switchTab(tab);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
browser.contextMenus.onClicked.addListener(async (item, tab) => {
|
||||
if (item?.menuItemId?.startsWith('fill_attribute')) {
|
||||
const menuItem = page.attributeMenuItems.find(i => i?.action === item?.menuItemId);
|
||||
if (menuItem) {
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: 'fill_attribute',
|
||||
args: menuItem?.args
|
||||
}).catch((err) => {
|
||||
logError(err);
|
||||
/**
|
||||
* Remove information structure of closed tab for freeing memory
|
||||
* @param {integer} tabId
|
||||
* @param {object} removeInfo
|
||||
*/
|
||||
browser.tabs.onRemoved.addListener(async function(tabId, removeInfo) {
|
||||
if (page.currentTabId === tabId) {
|
||||
const currentTab = await getCurrentTab();
|
||||
page.currentTabId = currentTab ? currentTab.id : -1;
|
||||
}
|
||||
delete page.tabs[tabId];
|
||||
});
|
||||
|
||||
/**
|
||||
* Remove stored credentials on switching tabs.
|
||||
* Invoke functions to retrieve credentials for focused tab
|
||||
* @param {object} activeInfo
|
||||
*/
|
||||
browser.tabs.onActivated.addListener(async function(activeInfo) {
|
||||
try {
|
||||
const info = await browser.tabs.get(activeInfo.tabId);
|
||||
if (info && info.id) {
|
||||
page.currentTabId = info.id;
|
||||
if (info.status === 'complete') {
|
||||
if (!page.tabs[info.id]) {
|
||||
page.createTabEntry(info.id);
|
||||
}
|
||||
page.switchTab(info);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logError(err.message);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Update browserAction on every update of the page
|
||||
* @param {integer} tabId
|
||||
* @param {object} changeInfo
|
||||
* @param {object} tab
|
||||
*/
|
||||
browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
||||
// If the tab URL has changed (e.g. logged in) clear credentials
|
||||
if (changeInfo.url) {
|
||||
page.clearLogins(tabId);
|
||||
}
|
||||
|
||||
if (changeInfo.status === 'complete' && tab?.id) {
|
||||
browserAction.showDefault(tab);
|
||||
if (!page.tabs[tab.id]) {
|
||||
page.createTabEntry(tab.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Detects page redirects and increases the count. Count is reset after a normal navigation event.
|
||||
* Form submit is counted as one.
|
||||
* @param {object} details
|
||||
*/
|
||||
browser.webNavigation.onCommitted.addListener((details) => {
|
||||
if (details.transitionQualifiers?.[0] === 'client_redirect' || details.transitionType === 'form_submit') {
|
||||
page.redirectCount += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear credentials on reload so a new retrieval can be made
|
||||
if (details.transitionType === 'reload') {
|
||||
page.clearLogins(details.tabId);
|
||||
}
|
||||
|
||||
page.redirectCount = 0;
|
||||
});
|
||||
|
||||
browser.runtime.onMessage.addListener(kpxcEvent.onMessage);
|
||||
|
||||
// Listen for keyboard shortcuts specified by user
|
||||
browser.commands.onCommand.addListener(async (command) => {
|
||||
if (contextMenuItems.some(e => e.action === command)
|
||||
|| command === 'redetect_fields'
|
||||
|| command === 'choose_credential_fields'
|
||||
|| command === 'retrive_credentials_forced'
|
||||
|| command === 'reload_extension') {
|
||||
const tab = await getCurrentTab();
|
||||
if (tab?.id) {
|
||||
browser.tabs.sendMessage(tab.id, { action: command });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
browser.contextMenus.onClicked.addListener(async (item, tab) => {
|
||||
if (!tab?.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item?.menuItemId?.startsWith('fill_attribute')) {
|
||||
const menuItem = page.attributeMenuItems.find(i => i?.action === item?.menuItemId);
|
||||
if (menuItem) {
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: 'fill_attribute',
|
||||
args: menuItem?.args
|
||||
}).catch((err) => {
|
||||
logError(err);
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: item.menuItemId
|
||||
}).catch((err) => {
|
||||
logError(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const initContextMenuItems = async function() {
|
||||
// Create context menu items
|
||||
await browser.contextMenus.removeAll();
|
||||
for (const item of contextMenuItems) {
|
||||
try {
|
||||
await browser.contextMenus.create({
|
||||
title: item.title,
|
||||
contexts: menuContexts,
|
||||
visible: item.visible,
|
||||
id: item.id || item.action
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
} catch (e) {
|
||||
logError(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: item.menuItemId
|
||||
}).catch((err) => {
|
||||
logError(err);
|
||||
});
|
||||
});
|
||||
(async () => {
|
||||
try {
|
||||
await keepass.migrateKeyRing();
|
||||
await page.initSettings();
|
||||
await page.initSitePreferences();
|
||||
await page.initOpenedTabs();
|
||||
await initListeners();
|
||||
await initContextMenuItems();
|
||||
await httpAuth.init();
|
||||
await keepass.reconnect(null, 5000); // 5 second timeout for the first connect
|
||||
await keepass.enableAutomaticReconnect();
|
||||
await keepass.updateDatabase();
|
||||
} catch (e) {
|
||||
logError('init.js failed');
|
||||
}
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -929,7 +929,7 @@ keepass.updateDatabase = async function() {
|
|||
keepass.updateDatabaseHashToContent = async function() {
|
||||
try {
|
||||
const tab = await getCurrentTab();
|
||||
if (tab) {
|
||||
if (tab?.id) {
|
||||
// Send message to content script
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
action: 'check_database_hash',
|
||||
|
|
|
|||
|
|
@ -65,14 +65,25 @@ page.initSettings = async function() {
|
|||
const item = await browser.storage.local.get({ 'settings': {} });
|
||||
|
||||
// Load managed settings if found
|
||||
try {
|
||||
const managedSettings = await browser.storage.managed.get('settings');
|
||||
if (managedSettings?.settings) {
|
||||
console.log('Managed settings found.');
|
||||
item.settings = managedSettings.settings;
|
||||
if (isFirefox()) {
|
||||
try {
|
||||
const managedSettings = await browser.storage.managed.get('settings');
|
||||
if (managedSettings?.settings) {
|
||||
debugLogMessage('Managed settings found.');
|
||||
item.settings = managedSettings.settings;
|
||||
}
|
||||
} catch (err) {
|
||||
logError('page.initSettings error: ' + err);
|
||||
}
|
||||
} catch (err) {
|
||||
logError('page.initSettings error: ' + err);
|
||||
} else {
|
||||
chrome.storage.managed.get('settings').then((managedSettings) => {
|
||||
if (managedSettings?.settings) {
|
||||
debugLogMessage('Managed settings found.');
|
||||
item.settings = managedSettings.settings;
|
||||
}
|
||||
}).catch((err) => {
|
||||
logError('page.initSettings error: ' + err);
|
||||
});
|
||||
}
|
||||
|
||||
page.settings = item.settings;
|
||||
|
|
@ -106,7 +117,7 @@ page.initOpenedTabs = async function() {
|
|||
return;
|
||||
}
|
||||
|
||||
page.currentTabId = currentTab.id;
|
||||
page.currentTabId = currentTab?.id;
|
||||
browserAction.showDefault(currentTab);
|
||||
} catch (err) {
|
||||
logError('page.initOpenedTabs error: ' + err);
|
||||
|
|
@ -128,25 +139,27 @@ page.initSitePreferences = async function() {
|
|||
|
||||
page.switchTab = async function(tab) {
|
||||
// Clears Fill Attribute selection from context menu
|
||||
browser.contextMenus.update('fill_attribute', { visible: false });
|
||||
page.setFillAttributeContextMenuItemVisible(false);
|
||||
|
||||
// Clears all logins from other tabs after a timeout
|
||||
if (page.clearCredentialsTimeout) {
|
||||
if (page?.clearCredentialsTimeout) {
|
||||
clearTimeout(page.clearCredentialsTimeout);
|
||||
}
|
||||
|
||||
page.clearCredentialsTimeout = setTimeout(() => {
|
||||
for (const pageTabId of Object.keys(page.tabs)) {
|
||||
if (tab.id !== Number(pageTabId)) {
|
||||
if (tab?.id !== Number(pageTabId)) {
|
||||
page.clearCredentials(Number(pageTabId), true);
|
||||
}
|
||||
}
|
||||
}, page.settings.clearCredentialsTimeout * 1000);
|
||||
|
||||
browserAction.showDefault(tab);
|
||||
browser.tabs.sendMessage(tab.id, { action: 'activated_tab' }).catch((e) => {
|
||||
logError('Cannot send activated_tab message: ' + e.message);
|
||||
});
|
||||
if (tab?.id) {
|
||||
browser.tabs.sendMessage(tab.id, { action: 'activated_tab' }).catch((e) => {
|
||||
logError('Cannot send activated_tab message: ' + e.message);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
page.clearCredentials = async function(tabId, complete) {
|
||||
|
|
@ -166,7 +179,7 @@ page.clearCredentials = async function(tabId, complete) {
|
|||
}
|
||||
};
|
||||
|
||||
page.clearLogins = function(tabId) {
|
||||
page.clearLogins = async function(tabId) {
|
||||
if (!page.tabs[tabId]) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -176,8 +189,7 @@ page.clearLogins = function(tabId) {
|
|||
page.tabs[tabId].loginList = [];
|
||||
page.currentRequest = {};
|
||||
page.passwordFilled = false;
|
||||
|
||||
browser.contextMenus.update('fill_attribute', { visible: false });
|
||||
page.setFillAttributeContextMenuItemVisible(false);
|
||||
};
|
||||
|
||||
// Clear all logins from all pages and update the content scripts
|
||||
|
|
@ -201,7 +213,7 @@ page.clearSubmittedCredentials = async function() {
|
|||
page.submittedCredentials = {};
|
||||
};
|
||||
|
||||
page.createTabEntry = function(tabId) {
|
||||
page.createTabEntry = async function(tabId) {
|
||||
page.tabs[tabId] = {
|
||||
allowIframes: false,
|
||||
credentials: [],
|
||||
|
|
@ -211,14 +223,14 @@ page.createTabEntry = function(tabId) {
|
|||
};
|
||||
|
||||
page.clearSubmittedCredentials();
|
||||
browser.contextMenus.update('fill_attribute', { visible: false });
|
||||
page.setFillAttributeContextMenuItemVisible(false);
|
||||
};
|
||||
|
||||
// Retrieves the credentials. Returns cached values when found.
|
||||
// Page reload or tab switch clears the cache.
|
||||
// If the retrieval is forced (from Credential Banner), get new credentials normally.
|
||||
page.retrieveCredentials = async function(tab, args = []) {
|
||||
if (!tab?.active) {
|
||||
if (!tab?.active || !tab?.id) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
@ -256,7 +268,9 @@ page.getLoginId = async function(tab) {
|
|||
};
|
||||
|
||||
page.setLoginId = async function(tab, loginId) {
|
||||
page.tabs[tab.id].loginId = loginId;
|
||||
if (tab?.id) {
|
||||
page.tabs[tab.id].loginId = loginId;
|
||||
}
|
||||
};
|
||||
|
||||
page.getManualFill = async function(tab) {
|
||||
|
|
@ -278,7 +292,7 @@ page.setBannerPosition = async function(tab, position) {
|
|||
|
||||
page.getSubmitted = async function(tab) {
|
||||
// Do not return any credentials if the tab ID does not match.
|
||||
if (tab.id !== page.submittedCredentials.tabId) {
|
||||
if (tab?.id !== page.submittedCredentials.tabId) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
@ -336,6 +350,15 @@ page.isSiteIgnored = async function(tab, currentLocation) {
|
|||
return false;
|
||||
};
|
||||
|
||||
// Shows or hides the Fill Attribute context menu item
|
||||
page.setFillAttributeContextMenuItemVisible = async function(visible) {
|
||||
try {
|
||||
await browser.contextMenus.update('fill_attribute', { visible: visible });
|
||||
} catch (e) {
|
||||
logError(e);
|
||||
}
|
||||
};
|
||||
|
||||
// Update context menu for attribute filling
|
||||
page.updateContextMenu = async function(tab, credentials) {
|
||||
// Remove any old attribute items
|
||||
|
|
@ -345,7 +368,7 @@ page.updateContextMenu = async function(tab, credentials) {
|
|||
page.attributeMenuItems = [];
|
||||
|
||||
// Set parent item visibility
|
||||
browser.contextMenus.update('fill_attribute', { visible: true });
|
||||
page.setFillAttributeContextMenuItemVisible(true);
|
||||
|
||||
// Add any new attribute items
|
||||
for (const cred of credentials) {
|
||||
|
|
@ -381,7 +404,7 @@ page.setAllowIframes = async function(tab, args = []) {
|
|||
const [ allowIframes, site ] = args;
|
||||
|
||||
// Only set when main windows' URL is used
|
||||
if (trimURL(tab?.url) === trimURL(site)) {
|
||||
if (trimURL(tab?.url) === trimURL(site) && tab?.id) {
|
||||
page.tabs[tab.id].allowIframes = allowIframes;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ const getFileAndLine = function() {
|
|||
|
||||
const getCurrentTab = async function() {
|
||||
const tabs = await browser.tabs.query({ active: true, currentWindow: true });
|
||||
return tabs.length > 0 ? tabs[0] : undefined;
|
||||
return tabs?.length > 0 ? tabs[0] : undefined;
|
||||
};
|
||||
|
||||
// Exports for tests
|
||||
|
|
|
|||
Loading…
Reference in a new issue