1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-06-20 09:35:22 +02:00
bitwarden-browser/apps/browser/src/autofill/content/context-menu-handler.ts
Robyn MacCallum 7ebedbecfb
[SG-998] and [SG-999] Vault and Autofill team refactor (#4542)
* Move DeprecatedVaultFilterService to vault folder

* [libs] move VaultItemsComponent

* [libs] move AddEditComponent

* [libs] move AddEditCustomFields

* [libs] move attachmentsComponent

* [libs] folderAddEditComponent

* [libs] IconComponent

* [libs] PasswordRepormptComponent

* [libs] PremiumComponent

* [libs] ViewCustomFieldsComponent

* [libs] ViewComponent

* [libs] PasswordRepromptService

* [libs] Move FolderService and FolderApiService abstractions

* [libs] FolderService imports

* [libs] PasswordHistoryComponent

* [libs] move Sync and SyncNotifier abstractions

* [libs] SyncService imports

* [libs] fix file casing for passwordReprompt abstraction

* [libs] SyncNotifier import fix

* [libs] CipherServiceAbstraction

* [libs] PasswordRepromptService abstraction

* [libs] Fix file casing for angular passwordReprompt service

* [libs] fix file casing for SyncNotifierService

* [libs] CipherRepromptType

* [libs] rename CipherRepromptType

* [libs] CipherType

* [libs] Rename CipherType

* [libs] CipherData

* [libs] FolderData

* [libs] PasswordHistoryData

* [libs] AttachmentData

* [libs] CardData

* [libs] FieldData

* [libs] IdentityData

* [libs] LocalData

* [libs] LoginData

* [libs] SecureNoteData

* [libs] LoginUriData

* [libs] Domain classes

* [libs] SecureNote

* [libs] Request models

* [libs] Response models

* [libs] View part 1

* [libs] Views part 2

* [libs] Move folder services

* [libs] Views fixes

* [libs] Move sync services

* [libs] cipher service

* [libs] Types

* [libs] Sync file casing

* [libs] Fix folder service import

* [libs] Move spec files

* [libs] casing fixes on spec files

* [browser] Autofill background, clipboard, commands

* [browser] Fix ContextMenusBackground casing

* [browser] Rename fix

* [browser] Autofill content

* [browser] autofill.js

* [libs] enpass importer spec fix

* [browser] autofill models

* [browser] autofill manifest path updates

* [browser] Autofill notification files

* [browser] autofill services

* [browser] Fix file casing

* [browser] Vault popup loose components

* [browser] Vault components

* [browser] Manifest fixes

* [browser] Vault services

* [cli] vault commands and models

* [browser] File capitilization fixes

* [desktop] Vault components and services

* [web] vault loose components

* [web] Vault components

* [browser] Fix misc-utils import

* [libs] Fix psono spec imports

* [fix] Add comments to address lint rules
2023-01-31 16:08:37 -05:00

70 lines
2.2 KiB
TypeScript

const inputTags = ["input", "textarea", "select"];
const labelTags = ["label", "span"];
const attributes = ["id", "name", "label-aria", "placeholder"];
const invalidElement = chrome.i18n.getMessage("copyCustomFieldNameInvalidElement");
const noUniqueIdentifier = chrome.i18n.getMessage("copyCustomFieldNameNotUnique");
let clickedEl: HTMLElement = null;
// Find the best attribute to be used as the Name for an element in a custom field.
function getClickedElementIdentifier() {
if (clickedEl == null) {
return invalidElement;
}
const clickedTag = clickedEl.nodeName.toLowerCase();
let inputEl = null;
// Try to identify the input element (which may not be the clicked element)
if (labelTags.includes(clickedTag)) {
let inputId = null;
if (clickedTag === "label") {
inputId = clickedEl.getAttribute("for");
} else {
inputId = clickedEl.closest("label")?.getAttribute("for");
}
inputEl = document.getElementById(inputId);
} else {
inputEl = clickedEl;
}
if (inputEl == null || !inputTags.includes(inputEl.nodeName.toLowerCase())) {
return invalidElement;
}
for (const attr of attributes) {
const attributeValue = inputEl.getAttribute(attr);
const selector = "[" + attr + '="' + attributeValue + '"]';
if (!isNullOrEmpty(attributeValue) && document.querySelectorAll(selector)?.length === 1) {
return attributeValue;
}
}
return noUniqueIdentifier;
}
function isNullOrEmpty(s: string) {
return s == null || s === "";
}
// We only have access to the element that's been clicked when the context menu is first opened.
// Remember it for use later.
document.addEventListener("contextmenu", (event) => {
clickedEl = event.target as HTMLElement;
});
// Runs when the 'Copy Custom Field Name' context menu item is actually clicked.
chrome.runtime.onMessage.addListener((event, _sender, sendResponse) => {
if (event.command === "getClickedElement") {
const identifier = getClickedElementIdentifier();
if (sendResponse) {
sendResponse(identifier);
}
chrome.runtime.sendMessage({
command: "getClickedElementResponse",
sender: "contextMenuHandler",
identifier: identifier,
});
}
});