1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 09:13:33 +00:00

[PM-5189] Fixing a weird side issue that appears when a frame within the page triggers a reposition after the inline menu has been built

This commit is contained in:
Cesar Gonzalez
2024-06-06 13:00:47 -05:00
parent 67db794eda
commit e2c9fa4b59
3 changed files with 50 additions and 8 deletions

View File

@@ -12,10 +12,11 @@ export type PageDetailsForTab = Record<
>; >;
export type SubFrameOffsetData = { export type SubFrameOffsetData = {
frameId?: number;
url?: string;
top: number; top: number;
left: number; left: number;
url?: string;
frameId?: number;
parentFrameIds?: number[];
} | null; } | null;
export type SubFrameOffsetsForTab = Record< export type SubFrameOffsetsForTab = Record<
@@ -116,6 +117,8 @@ export type OverlayBackgroundExtensionMessageHandlers = {
updateAutofillInlineMenuHidden: ({ message, sender }: BackgroundOnMessageHandlerParams) => void; updateAutofillInlineMenuHidden: ({ message, sender }: BackgroundOnMessageHandlerParams) => void;
checkIsAutofillInlineMenuButtonVisible: ({ sender }: BackgroundSenderParam) => void; checkIsAutofillInlineMenuButtonVisible: ({ sender }: BackgroundSenderParam) => void;
checkIsAutofillInlineMenuListVisible: ({ sender }: BackgroundSenderParam) => void; checkIsAutofillInlineMenuListVisible: ({ sender }: BackgroundSenderParam) => void;
checkShouldRepositionInlineMenu: ({ sender }: BackgroundSenderParam) => boolean;
getCurrentTabFrameId: ({ sender }: BackgroundSenderParam) => number;
updateSubFrameData: ({ message, sender }: BackgroundOnMessageHandlerParams) => void; updateSubFrameData: ({ message, sender }: BackgroundOnMessageHandlerParams) => void;
rebuildSubFrameOffsets: ({ sender }: BackgroundSenderParam) => void; rebuildSubFrameOffsets: ({ sender }: BackgroundSenderParam) => void;
collectPageDetailsResponse: ({ message, sender }: BackgroundOnMessageHandlerParams) => void; collectPageDetailsResponse: ({ message, sender }: BackgroundOnMessageHandlerParams) => void;

View File

@@ -88,6 +88,8 @@ export class OverlayBackground implements OverlayBackgroundInterface {
this.checkIsAutofillInlineMenuButtonVisible(sender), this.checkIsAutofillInlineMenuButtonVisible(sender),
checkIsAutofillInlineMenuListVisible: ({ sender }) => checkIsAutofillInlineMenuListVisible: ({ sender }) =>
this.checkIsAutofillInlineMenuListVisible(sender), this.checkIsAutofillInlineMenuListVisible(sender),
checkShouldRepositionInlineMenu: ({ sender }) => this.checkShouldRepositionInlineMenu(sender),
getCurrentTabFrameId: ({ sender }) => this.getCurrentFrameId(sender),
updateSubFrameData: ({ message, sender }) => this.updateSubFrameData(message, sender), updateSubFrameData: ({ message, sender }) => this.updateSubFrameData(message, sender),
rebuildSubFrameOffsets: ({ sender }) => this.rebuildSubFrameOffsets(sender), rebuildSubFrameOffsets: ({ sender }) => this.rebuildSubFrameOffsets(sender),
collectPageDetailsResponse: ({ message, sender }) => this.storePageDetails(message, sender), collectPageDetailsResponse: ({ message, sender }) => this.storePageDetails(message, sender),
@@ -256,6 +258,10 @@ export class OverlayBackground implements OverlayBackgroundInterface {
pageDetailsMap.set(sender.frameId, pageDetails); pageDetailsMap.set(sender.frameId, pageDetails);
} }
private getCurrentFrameId(sender: chrome.runtime.MessageSender) {
return sender.frameId;
}
/** /**
* Handles sub frame offset calculations for the given tab and frame id. * Handles sub frame offset calculations for the given tab and frame id.
* Is used in setting the position of the inline menu list and button. * Is used in setting the position of the inline menu list and button.
@@ -293,7 +299,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
return; return;
} }
const subFrameData = { url, top: 0, left: 0 }; const subFrameData: SubFrameOffsetData = { url, top: 0, left: 0, parentFrameIds: [] };
let frameDetails = await BrowserApi.getFrameDetails({ tabId, frameId }); let frameDetails = await BrowserApi.getFrameDetails({ tabId, frameId });
while (frameDetails && frameDetails.parentFrameId > -1) { while (frameDetails && frameDetails.parentFrameId > -1) {
@@ -319,6 +325,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
subFrameData.top += subFrameOffset.top; subFrameData.top += subFrameOffset.top;
subFrameData.left += subFrameOffset.left; subFrameData.left += subFrameOffset.left;
subFrameData.parentFrameIds.push(frameDetails.parentFrameId);
frameDetails = await BrowserApi.getFrameDetails({ frameDetails = await BrowserApi.getFrameDetails({
tabId, tabId,
@@ -1005,6 +1012,34 @@ export class OverlayBackground implements OverlayBackgroundInterface {
); );
} }
private checkShouldRepositionInlineMenu(sender: chrome.runtime.MessageSender): boolean {
if (
!this.focusedFieldData ||
sender.tab.id !== this.focusedFieldData.tabId ||
!this.isFieldCurrentlyFocused
) {
return false;
}
if (this.focusedFieldData.frameId === sender.frameId) {
return true;
}
const subFrameOffsetsForTab = this.subFrameOffsetsForTab[sender.tab.id];
if (!subFrameOffsetsForTab) {
return false;
}
const parentFrameIds = new Set();
subFrameOffsetsForTab.forEach((subFrameOffsetData) =>
subFrameOffsetData.parentFrameIds.forEach((parentFrameId) =>
parentFrameIds.add(parentFrameId),
),
);
return parentFrameIds.has(sender.frameId);
}
/** /**
* Responds to the content script's request to check if the inline menu ciphers are populated. * Responds to the content script's request to check if the inline menu ciphers are populated.
* This will return true only if the sender is the focused field's tab and the inline menu * This will return true only if the sender is the focused field's tab and the inline menu

View File

@@ -765,17 +765,18 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
globalThis.removeEventListener(EVENTS.RESIZE, this.handleOverlayRepositionEvent); globalThis.removeEventListener(EVENTS.RESIZE, this.handleOverlayRepositionEvent);
} }
private overlayRepositionTimeout: number | NodeJS.Timeout;
/** /**
* Handles the resize or scroll events that enact * Handles the resize or scroll events that enact
* repositioning of existing overlay elements. * repositioning of existing overlay elements.
*/ */
private handleOverlayRepositionEvent = async () => { private handleOverlayRepositionEvent = async () => {
this.rebuildSubFrameOffsets(); if (!(await this.sendExtensionMessage("checkShouldRepositionInlineMenu"))) {
if (!(await this.isInlineMenuButtonVisible()) && !(await this.isInlineMenuListVisible())) {
return; return;
} }
this.rebuildSubFrameOffsets();
this.toggleAutofillInlineMenuHidden(true); this.toggleAutofillInlineMenuHidden(true);
this.clearUserInteractionEventTimeout(); this.clearUserInteractionEventTimeout();
this.userInteractionEventTimeout = setTimeout(this.triggerOverlayRepositionUpdates, 750); this.userInteractionEventTimeout = setTimeout(this.triggerOverlayRepositionUpdates, 750);
@@ -957,6 +958,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
frameId: message.subFrameId, frameId: message.subFrameId,
left: 0, left: 0,
top: 0, top: 0,
parentFrameIds: [],
}, },
}, },
"*", "*",
@@ -968,10 +970,10 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
return; return;
} }
this.calculateSubFramePositioning(event); void this.calculateSubFramePositioning(event);
}; };
private calculateSubFramePositioning = (event: MessageEvent) => { private calculateSubFramePositioning = async (event: MessageEvent) => {
const subFrameData = event.data.subFrameData; const subFrameData = event.data.subFrameData;
let subFrameOffsets: SubFrameOffsetData; let subFrameOffsets: SubFrameOffsetData;
const iframes = document.querySelectorAll("iframe"); const iframes = document.querySelectorAll("iframe");
@@ -983,9 +985,11 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
subFrameData.url, subFrameData.url,
subFrameData.frameId, subFrameData.frameId,
); );
const parentFrameId = await this.sendExtensionMessage("getCurrentTabFrameId");
subFrameData.top += subFrameOffsets.top; subFrameData.top += subFrameOffsets.top;
subFrameData.left += subFrameOffsets.left; subFrameData.left += subFrameOffsets.left;
subFrameData.parentFrameIds.push(parentFrameId);
break; break;
} }