mirror of
https://github.com/bitwarden/browser
synced 2025-12-19 01:33:33 +00:00
[PM-5189] Implementing methodology for gathering iframe rects within background script
This commit is contained in:
@@ -15,7 +15,7 @@ type SubFrameOffsetData = {
|
||||
url: string;
|
||||
top: number;
|
||||
left: number;
|
||||
};
|
||||
} | null;
|
||||
|
||||
type SubFrameOffsetsForTab = Record<
|
||||
chrome.runtime.MessageSender["tab"]["id"],
|
||||
|
||||
@@ -42,6 +42,7 @@ import {
|
||||
WebsiteIconData,
|
||||
PageDetailsForTab,
|
||||
SubFrameOffsetsForTab,
|
||||
SubFrameOffsetData,
|
||||
} from "./abstractions/overlay.background";
|
||||
|
||||
class OverlayBackground implements OverlayBackgroundInterface {
|
||||
@@ -112,12 +113,15 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
* @param tabId - Used to reference the page details of a specific tab
|
||||
*/
|
||||
removePageDetails(tabId: number) {
|
||||
if (!this.pageDetailsForTab[tabId]) {
|
||||
return;
|
||||
if (this.pageDetailsForTab[tabId]) {
|
||||
this.pageDetailsForTab[tabId].clear();
|
||||
delete this.pageDetailsForTab[tabId];
|
||||
}
|
||||
|
||||
this.pageDetailsForTab[tabId].clear();
|
||||
delete this.pageDetailsForTab[tabId];
|
||||
if (this.subFrameOffsetsForTab[tabId]) {
|
||||
this.subFrameOffsetsForTab[tabId].clear();
|
||||
delete this.subFrameOffsetsForTab[tabId];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,7 +216,6 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
};
|
||||
|
||||
if (pageDetails.frameId !== 0 && pageDetails.details.fields.length) {
|
||||
// NOT SURE I WANT THIS
|
||||
void this.buildSubFrameOffset(pageDetails);
|
||||
}
|
||||
|
||||
@@ -226,13 +229,42 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
}
|
||||
|
||||
private async buildSubFrameOffset({ tab, frameId, details }: PageDetail) {
|
||||
const frameDetails = await BrowserApi.getFrameDetails({
|
||||
tabId: tab.id,
|
||||
frameId,
|
||||
});
|
||||
const tabId = tab.id;
|
||||
let subFrameOffsetsForTab = this.subFrameOffsetsForTab[tabId];
|
||||
if (!subFrameOffsetsForTab) {
|
||||
this.subFrameOffsetsForTab[tabId] = new Map();
|
||||
subFrameOffsetsForTab = this.subFrameOffsetsForTab[tabId];
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
console.log(frameDetails);
|
||||
if (subFrameOffsetsForTab.get(frameId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const subFrameData = { url: details.url, top: 0, left: 0 };
|
||||
let frameDetails = await BrowserApi.getFrameDetails({ tabId, frameId });
|
||||
|
||||
while (frameDetails.parentFrameId !== -1) {
|
||||
const subFrameOffset: SubFrameOffsetData = await BrowserApi.tabSendMessage(
|
||||
tab,
|
||||
{ command: "getSubFrameOffsets", subFrameUrl: frameDetails.url },
|
||||
{ frameId: frameDetails.parentFrameId },
|
||||
);
|
||||
|
||||
if (!subFrameOffset) {
|
||||
subFrameOffsetsForTab.set(frameId, null);
|
||||
return;
|
||||
}
|
||||
|
||||
subFrameData.top += subFrameOffset.top;
|
||||
subFrameData.left += subFrameOffset.left;
|
||||
|
||||
frameDetails = await BrowserApi.getFrameDetails({
|
||||
tabId,
|
||||
frameId: frameDetails.parentFrameId,
|
||||
});
|
||||
}
|
||||
|
||||
subFrameOffsetsForTab.set(frameId, subFrameData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||
|
||||
import { SubFrameOffsetData } from "../../background/abstractions/overlay.background";
|
||||
import AutofillScript from "../../models/autofill-script";
|
||||
|
||||
type AutofillExtensionMessage = {
|
||||
@@ -8,6 +9,7 @@ type AutofillExtensionMessage = {
|
||||
sender?: string;
|
||||
fillScript?: AutofillScript;
|
||||
url?: string;
|
||||
subFrameUrl?: string;
|
||||
pageDetailsUrl?: string;
|
||||
ciphers?: any;
|
||||
data?: {
|
||||
@@ -36,6 +38,7 @@ type AutofillExtensionMessageHandlers = {
|
||||
bgUnlockPopoutOpened: () => void;
|
||||
bgVaultItemRepromptPopoutOpened: () => void;
|
||||
updateAutofillOverlayVisibility: ({ message }: AutofillExtensionMessageParam) => void;
|
||||
getSubFrameOffsets: ({ message }: AutofillExtensionMessageParam) => Promise<SubFrameOffsetData>;
|
||||
};
|
||||
|
||||
interface AutofillInit {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SubFrameOffsetData } from "../background/abstractions/overlay.background";
|
||||
import AutofillPageDetails from "../models/autofill-page-details";
|
||||
import { AutofillOverlayContentService } from "../services/abstractions/autofill-overlay-content.service";
|
||||
import CollectAutofillContentService from "../services/collect-autofill-content.service";
|
||||
@@ -28,7 +29,7 @@ class AutofillInit implements AutofillInitInterface {
|
||||
bgUnlockPopoutOpened: () => this.blurAndRemoveOverlay(),
|
||||
bgVaultItemRepromptPopoutOpened: () => this.blurAndRemoveOverlay(),
|
||||
updateAutofillOverlayVisibility: ({ message }) => this.updateAutofillOverlayVisibility(message),
|
||||
getSubFrameOffsets: () => this.getSubFrameOffsets(),
|
||||
getSubFrameOffsets: ({ message }) => this.getSubFrameOffsets(message),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -250,7 +251,33 @@ class AutofillInit implements AutofillInitInterface {
|
||||
this.autofillOverlayContentService.autofillOverlayVisibility = data?.autofillOverlayVisibility;
|
||||
}
|
||||
|
||||
private getSubFrameOffsets() {}
|
||||
private async getSubFrameOffsets(
|
||||
message: AutofillExtensionMessage,
|
||||
): Promise<SubFrameOffsetData | null> {
|
||||
const { subFrameUrl } = message;
|
||||
const subFrameUrlWithoutTrailingSlash = subFrameUrl?.replace(/\/$/, "");
|
||||
|
||||
// query iframe based on src attribute
|
||||
const iframeElement = document.querySelector(
|
||||
`iframe[src^="${subFrameUrlWithoutTrailingSlash}"]`,
|
||||
);
|
||||
if (!iframeElement) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const iframeRect = iframeElement.getBoundingClientRect();
|
||||
const iframeStyles = globalThis.getComputedStyle(iframeElement);
|
||||
const paddingLeft = parseInt(iframeStyles.getPropertyValue("padding-left"));
|
||||
const paddingTop = parseInt(iframeStyles.getPropertyValue("padding-top"));
|
||||
const borderWidthLeft = parseInt(iframeStyles.getPropertyValue("border-left-width"));
|
||||
const borderWidthTop = parseInt(iframeStyles.getPropertyValue("border-top-width"));
|
||||
|
||||
return {
|
||||
url: subFrameUrl,
|
||||
top: iframeRect.top + paddingTop + borderWidthTop,
|
||||
left: iframeRect.left + paddingLeft + borderWidthLeft,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the extension message listeners for the content script.
|
||||
|
||||
@@ -178,17 +178,17 @@ export class BrowserApi {
|
||||
tab: chrome.tabs.Tab,
|
||||
obj: T,
|
||||
options: chrome.tabs.MessageSendOptions = null,
|
||||
): Promise<void> {
|
||||
): Promise<any> {
|
||||
if (!tab || !tab.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
return new Promise<void>((resolve) => {
|
||||
chrome.tabs.sendMessage(tab.id, obj, options, () => {
|
||||
return new Promise<any>((resolve) => {
|
||||
chrome.tabs.sendMessage(tab.id, obj, options, (response) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
// Some error happened
|
||||
}
|
||||
resolve();
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user