Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can a content script target a frame? #41

Open
fregante opened this issue Oct 13, 2021 · 3 comments
Open

How can a content script target a frame? #41

fregante opened this issue Oct 13, 2021 · 3 comments

Comments

@fregante
Copy link
Contributor

Content scripts should be able to send messages to "the sidebar".

At the moment, the background has some logic to track the sidebar, which I assume is:

https://github.com/pixiebrix/pixiebrix-extension/blob/b37306c112a8d495e226be0b0445d1da33d0c060/src/background/browserAction.ts#L226

This allows the content script to message the sidebar without knowing its ID. This is only possible because there's a smart "middle man" that tracks the connection between the two.

This specific situation could be fixed by having the sidebar register itself directly with the content script instead of the background page. Then the content script will be able to contact the sidebar with the usual target information:

const registeredSidebar: Target = {tabId: 123 /* current tab */, frameId: 3};
await renderPanelMessage(registeredSidebar, panels);
@fregante fregante changed the title How can a content script target a sidebar or iframe? (self-resolved) How can a content script target a sidebar or iframe? Oct 14, 2021
@fregante
Copy link
Contributor Author

This could happen in the user’s code, but it would mean having to implement mapping, waiting, registration events, etc… outside webext-messenger

I'm going to implement named targets. More in:

@twschiller
Copy link
Collaborator

twschiller commented Oct 18, 2021

There's a few different scenarios:

  1. A singleton extension "component", e.g., the PixieBrix sidebar of which there will ever be at most 1 on the page
  2. A persistent frame that the extension added, e.g., an inline panel that uses a frame for showing its content to isolate styles/hotkeys from the main page. In this case, there may be more than 1 frame, but they could potentially be uniquely identified by the extension id that placed the frame
  3. Frames from 3rd party sites. E.g., a common case is a iframe embedded in a SaaS app via the app's marketplace. (I.e., the SaaS app is using frames to protect against malicious apps in their marketplace)

Therefore I think supporting a couple patterns could be useful:

  • Allow a frame to register a unique name that it can be referenced by on the tab. This also enables scenario 2 because the contentScript would know the name of the frame ahead of time (at least in our case, it could be derived from the extension id)
  • Support matching by frame URL, with the caller selecting whether multiple matches are an error or result in an array of responses being response

Related:

@fregante
Copy link
Contributor Author

Currently the messenger lets us target chrome-extension pages by URL since chrome.runtime.sendMessage will send a message to every such page:

doSomething({ page: "/iframe.html" }, ...args);

it can also target such page in a specific tab:

doSomething({ page: "/iframe.html", tabId: 123 }, ...args);

chrome.tabs.sendMessage can do something similar IIRC, but only as long as you know the tab ID:

// I think
browser.tabs.sendMessage(tabId, message, {
	allFrames: true
})

The messenger does not support this yet, but maybe we can implement it:

doSomething({ page: "https://full.page.url/iframe.html", tabId: 123 }, ...args);

With two requirements:

  • it must receive a tab ID
  • it must receive a full https URL so that the messenger knows whether to use chrome.runtime or chrome.tabs to send the message

Since content scripts cannot use the chrome.tabs API, the messenger would have to forward them via the background page as well.

@fregante fregante changed the title How can a content script target a sidebar or iframe? How can a content script target a iframe? Jan 19, 2024
@fregante fregante changed the title How can a content script target a iframe? How can a content script target a frame? Jan 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants