mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-10 19:38:11 +01:00
[PM-5189] Fixing issues found with focusing elements between iframes, as well as fade in of the inline menu in a simultaneous manner for all visual elements
This commit is contained in:
parent
0dfdad07e2
commit
2ed62cc6a4
@ -54,6 +54,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
private pageDetailsForTab: PageDetailsForTab = {};
|
private pageDetailsForTab: PageDetailsForTab = {};
|
||||||
private subFrameOffsetsForTab: SubFrameOffsetsForTab = {};
|
private subFrameOffsetsForTab: SubFrameOffsetsForTab = {};
|
||||||
private updateInlineMenuPositionTimeout: number | NodeJS.Timeout;
|
private updateInlineMenuPositionTimeout: number | NodeJS.Timeout;
|
||||||
|
private inlineMenuFadeInTimeout: number | NodeJS.Timeout;
|
||||||
private userAuthStatus: AuthenticationStatus = AuthenticationStatus.LoggedOut;
|
private userAuthStatus: AuthenticationStatus = AuthenticationStatus.LoggedOut;
|
||||||
private inlineMenuButtonPort: chrome.runtime.Port;
|
private inlineMenuButtonPort: chrome.runtime.Port;
|
||||||
private inlineMenuListPort: chrome.runtime.Port;
|
private inlineMenuListPort: chrome.runtime.Port;
|
||||||
@ -440,7 +441,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sender.frameId === this.focusedFieldData?.frameId && this.isFieldCurrentlyFocused) {
|
if (this.isFieldCurrentlyFocused) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,9 +519,11 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
subFrameOffsets = subFrameOffsetsForTab.get(this.focusedFieldData.frameId);
|
subFrameOffsets = subFrameOffsetsForTab.get(this.focusedFieldData.frameId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setInlineMenuFadeInTimeout();
|
||||||
|
|
||||||
if (overlayElement === AutofillOverlayElement.Button) {
|
if (overlayElement === AutofillOverlayElement.Button) {
|
||||||
this.inlineMenuButtonPort?.postMessage({
|
this.inlineMenuButtonPort?.postMessage({
|
||||||
command: "updateIframePosition",
|
command: "updateInlineMenuIframePosition",
|
||||||
styles: this.getInlineMenuButtonPosition(subFrameOffsets),
|
styles: this.getInlineMenuButtonPosition(subFrameOffsets),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -528,11 +531,23 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.inlineMenuListPort?.postMessage({
|
this.inlineMenuListPort?.postMessage({
|
||||||
command: "updateIframePosition",
|
command: "updateInlineMenuIframePosition",
|
||||||
styles: this.getInlineMenuListPosition(subFrameOffsets),
|
styles: this.getInlineMenuListPosition(subFrameOffsets),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setInlineMenuFadeInTimeout() {
|
||||||
|
if (this.inlineMenuFadeInTimeout) {
|
||||||
|
globalThis.clearTimeout(this.inlineMenuFadeInTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = { command: "updateInlineMenuIframePosition", styles: { opacity: "1" } };
|
||||||
|
this.inlineMenuFadeInTimeout = globalThis.setTimeout(() => {
|
||||||
|
this.inlineMenuButtonPort?.postMessage(message);
|
||||||
|
this.inlineMenuListPort?.postMessage(message);
|
||||||
|
}, 75);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the position of the focused field and calculates the position
|
* Gets the position of the focused field and calculates the position
|
||||||
* of the inline menu button based on the focused field's position and dimensions.
|
* of the inline menu button based on the focused field's position and dimensions.
|
||||||
@ -600,6 +615,14 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
{ focusedFieldData }: OverlayBackgroundExtensionMessage,
|
{ focusedFieldData }: OverlayBackgroundExtensionMessage,
|
||||||
sender: chrome.runtime.MessageSender,
|
sender: chrome.runtime.MessageSender,
|
||||||
) {
|
) {
|
||||||
|
if (this.focusedFieldData?.frameId && this.focusedFieldData.frameId !== sender.frameId) {
|
||||||
|
void BrowserApi.tabSendMessage(
|
||||||
|
sender.tab,
|
||||||
|
{ command: "unsetMostRecentlyFocusedField" },
|
||||||
|
{ frameId: this.focusedFieldData.frameId },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.focusedFieldData = { ...focusedFieldData, tabId: sender.tab.id, frameId: sender.frameId };
|
this.focusedFieldData = { ...focusedFieldData, tabId: sender.tab.id, frameId: sender.frameId };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -922,7 +945,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
|
|
||||||
private updateInlineMenuListHeight(message: OverlayBackgroundExtensionMessage) {
|
private updateInlineMenuListHeight(message: OverlayBackgroundExtensionMessage) {
|
||||||
this.inlineMenuListPort?.postMessage({
|
this.inlineMenuListPort?.postMessage({
|
||||||
command: "updateIframePosition",
|
command: "updateInlineMenuIframePosition",
|
||||||
styles: message.styles,
|
styles: message.styles,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,9 @@ export type BackgroundPortMessageHandlers = {
|
|||||||
message,
|
message,
|
||||||
}: AutofillInlineMenuIframeExtensionMessageParam) => void;
|
}: AutofillInlineMenuIframeExtensionMessageParam) => void;
|
||||||
initAutofillInlineMenuList: ({ message }: AutofillInlineMenuIframeExtensionMessageParam) => void;
|
initAutofillInlineMenuList: ({ message }: AutofillInlineMenuIframeExtensionMessageParam) => void;
|
||||||
updateIframePosition: ({ message }: AutofillInlineMenuIframeExtensionMessageParam) => void;
|
updateInlineMenuIframePosition: ({
|
||||||
|
message,
|
||||||
|
}: AutofillInlineMenuIframeExtensionMessageParam) => void;
|
||||||
updateInlineMenuHidden: ({ message }: AutofillInlineMenuIframeExtensionMessageParam) => void;
|
updateInlineMenuHidden: ({ message }: AutofillInlineMenuIframeExtensionMessageParam) => void;
|
||||||
updateAutofillInlineMenuColorScheme: () => void;
|
updateAutofillInlineMenuColorScheme: () => void;
|
||||||
};
|
};
|
||||||
|
@ -104,9 +104,7 @@ export class AutofillInlineMenuContentService implements AutofillInlineMenuConte
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.buttonElement.remove();
|
this.buttonElement.remove();
|
||||||
|
|
||||||
this.isButtonVisible = false;
|
this.isButtonVisible = false;
|
||||||
|
|
||||||
void this.sendExtensionMessage("autofillOverlayElementClosed", {
|
void this.sendExtensionMessage("autofillOverlayElementClosed", {
|
||||||
overlayElement: AutofillOverlayElement.Button,
|
overlayElement: AutofillOverlayElement.Button,
|
||||||
});
|
});
|
||||||
@ -121,9 +119,7 @@ export class AutofillInlineMenuContentService implements AutofillInlineMenuConte
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.listElement.remove();
|
this.listElement.remove();
|
||||||
|
|
||||||
this.isListVisible = false;
|
this.isListVisible = false;
|
||||||
|
|
||||||
void this.sendExtensionMessage("autofillOverlayElementClosed", {
|
void this.sendExtensionMessage("autofillOverlayElementClosed", {
|
||||||
overlayElement: AutofillOverlayElement.List,
|
overlayElement: AutofillOverlayElement.List,
|
||||||
});
|
});
|
||||||
|
@ -193,9 +193,9 @@ describe("AutofillInlineMenuIframeService", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("handles port messages that are registered with the message handlers and does not pass the message on to the iframe", () => {
|
it("handles port messages that are registered with the message handlers and does not pass the message on to the iframe", () => {
|
||||||
jest.spyOn(autofillInlineMenuIframeService as any, "updateIframePosition");
|
jest.spyOn(autofillInlineMenuIframeService as any, "updateInlineMenuIframePosition");
|
||||||
|
|
||||||
sendPortMessage(portSpy, { command: "updateIframePosition" });
|
sendPortMessage(portSpy, { command: "updateInlineMenuIframePosition" });
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
autofillInlineMenuIframeService["iframe"].contentWindow.postMessage,
|
autofillInlineMenuIframeService["iframe"].contentWindow.postMessage,
|
||||||
@ -344,7 +344,7 @@ describe("AutofillInlineMenuIframeService", () => {
|
|||||||
jest.spyOn(globalThis.document, "hasFocus").mockReturnValue(false);
|
jest.spyOn(globalThis.document, "hasFocus").mockReturnValue(false);
|
||||||
|
|
||||||
sendPortMessage(portSpy, {
|
sendPortMessage(portSpy, {
|
||||||
command: "updateIframePosition",
|
command: "updateInlineMenuIframePosition",
|
||||||
styles: { top: 100, left: 100 },
|
styles: { top: 100, left: 100 },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -355,7 +355,7 @@ describe("AutofillInlineMenuIframeService", () => {
|
|||||||
const styles = { top: "100px", left: "100px" };
|
const styles = { top: "100px", left: "100px" };
|
||||||
|
|
||||||
sendPortMessage(portSpy, {
|
sendPortMessage(portSpy, {
|
||||||
command: "updateIframePosition",
|
command: "updateInlineMenuIframePosition",
|
||||||
styles,
|
styles,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -368,7 +368,7 @@ describe("AutofillInlineMenuIframeService", () => {
|
|||||||
const styles = { top: "100px", left: "100px" };
|
const styles = { top: "100px", left: "100px" };
|
||||||
|
|
||||||
sendPortMessage(portSpy, {
|
sendPortMessage(portSpy, {
|
||||||
command: "updateIframePosition",
|
command: "updateInlineMenuIframePosition",
|
||||||
styles,
|
styles,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -382,7 +382,7 @@ describe("AutofillInlineMenuIframeService", () => {
|
|||||||
const styles = { top: "100px", left: "100px" };
|
const styles = { top: "100px", left: "100px" };
|
||||||
|
|
||||||
sendPortMessage(portSpy, {
|
sendPortMessage(portSpy, {
|
||||||
command: "updateIframePosition",
|
command: "updateInlineMenuIframePosition",
|
||||||
styles,
|
styles,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
|
|||||||
private readonly backgroundPortMessageHandlers: BackgroundPortMessageHandlers = {
|
private readonly backgroundPortMessageHandlers: BackgroundPortMessageHandlers = {
|
||||||
initAutofillInlineMenuButton: ({ message }) => this.initAutofillInlineMenu(message),
|
initAutofillInlineMenuButton: ({ message }) => this.initAutofillInlineMenu(message),
|
||||||
initAutofillInlineMenuList: ({ message }) => this.initAutofillInlineMenu(message),
|
initAutofillInlineMenuList: ({ message }) => this.initAutofillInlineMenu(message),
|
||||||
updateIframePosition: ({ message }) => this.updateIframePosition(message.styles),
|
updateInlineMenuIframePosition: ({ message }) => this.updateIframePosition(message.styles),
|
||||||
updateInlineMenuHidden: ({ message }) => this.updateElementStyles(this.iframe, message.styles),
|
updateInlineMenuHidden: ({ message }) => this.updateElementStyles(this.iframe, message.styles),
|
||||||
updateAutofillInlineMenuColorScheme: () => this.updateAutofillInlineMenuColorScheme(),
|
updateAutofillInlineMenuColorScheme: () => this.updateAutofillInlineMenuColorScheme(),
|
||||||
};
|
};
|
||||||
@ -248,7 +248,7 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.updateElementStyles(this.iframe, position);
|
this.updateElementStyles(this.iframe, position);
|
||||||
setTimeout(() => this.updateElementStyles(this.iframe, { opacity: "1" }), 0);
|
// setTimeout(() => this.updateElementStyles(this.iframe, { opacity: "1" }), 0);
|
||||||
this.announceAriaAlert();
|
this.announceAriaAlert();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ export type AutofillOverlayContentExtensionMessageHandlers = {
|
|||||||
openAutofillInlineMenu: ({ message }: AutofillExtensionMessageParam) => void;
|
openAutofillInlineMenu: ({ message }: AutofillExtensionMessageParam) => void;
|
||||||
addNewVaultItemFromOverlay: () => void;
|
addNewVaultItemFromOverlay: () => void;
|
||||||
blurMostRecentlyFocusedField: () => void;
|
blurMostRecentlyFocusedField: () => void;
|
||||||
|
unsetMostRecentlyFocusedField: () => void;
|
||||||
bgUnlockPopoutOpened: () => void;
|
bgUnlockPopoutOpened: () => void;
|
||||||
bgVaultItemRepromptPopoutOpened: () => void;
|
bgVaultItemRepromptPopoutOpened: () => void;
|
||||||
redirectAutofillInlineMenuFocusOut: ({ message }: AutofillExtensionMessageParam) => void;
|
redirectAutofillInlineMenuFocusOut: ({ message }: AutofillExtensionMessageParam) => void;
|
||||||
|
@ -44,6 +44,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
|||||||
openAutofillInlineMenu: ({ message }) => this.openAutofillInlineMenu(message),
|
openAutofillInlineMenu: ({ message }) => this.openAutofillInlineMenu(message),
|
||||||
addNewVaultItemFromOverlay: () => this.addNewVaultItem(),
|
addNewVaultItemFromOverlay: () => this.addNewVaultItem(),
|
||||||
blurMostRecentlyFocusedField: () => this.blurMostRecentlyFocusedField(),
|
blurMostRecentlyFocusedField: () => this.blurMostRecentlyFocusedField(),
|
||||||
|
unsetMostRecentlyFocusedField: () => this.unsetMostRecentlyFocusedField(),
|
||||||
bgUnlockPopoutOpened: () => this.blurMostRecentlyFocusedField(true),
|
bgUnlockPopoutOpened: () => this.blurMostRecentlyFocusedField(true),
|
||||||
bgVaultItemRepromptPopoutOpened: () => this.blurMostRecentlyFocusedField(true),
|
bgVaultItemRepromptPopoutOpened: () => this.blurMostRecentlyFocusedField(true),
|
||||||
redirectAutofillInlineMenuFocusOut: ({ message }) =>
|
redirectAutofillInlineMenuFocusOut: ({ message }) =>
|
||||||
@ -162,6 +163,10 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsetMostRecentlyFocusedField() {
|
||||||
|
this.mostRecentlyFocusedField = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats any found user filled fields for a login cipher and sends a message
|
* Formats any found user filled fields for a login cipher and sends a message
|
||||||
* to the background script to add a new cipher.
|
* to the background script to add a new cipher.
|
||||||
@ -797,7 +802,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
|||||||
await this.updateMostRecentlyFocusedField(this.mostRecentlyFocusedField);
|
await this.updateMostRecentlyFocusedField(this.mostRecentlyFocusedField);
|
||||||
this.updateAutofillInlineMenuElementsPosition();
|
this.updateAutofillInlineMenuElementsPosition();
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
this.toggleAutofillInlineMenuHidden(false);
|
this.toggleAutofillInlineMenuHidden(false, true);
|
||||||
if (
|
if (
|
||||||
await this.hideAutofillInlineMenuListOnFilledField(
|
await this.hideAutofillInlineMenuListOnFilledField(
|
||||||
this.mostRecentlyFocusedField as FillableFormFieldElement,
|
this.mostRecentlyFocusedField as FillableFormFieldElement,
|
||||||
|
Loading…
Reference in New Issue
Block a user