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

Tracking issue: //extensions integration #19447

Closed
8 of 11 tasks
nornagon opened this issue Jul 25, 2019 · 63 comments
Closed
8 of 11 tasks

Tracking issue: //extensions integration #19447

nornagon opened this issue Jul 25, 2019 · 63 comments

Comments

@nornagon
Copy link
Member

nornagon commented Jul 25, 2019

This is a tracking issue for the work remaining to migrate our Chrome Extensions support away from our ad-hoc polyfills to the official //extensions code in Chromium.

@nornagon
Copy link
Member Author

nornagon commented Jul 25, 2019

Building on the API that @samuelmaddock suggested in #17440, here's a draft to be evolved as requirements become evident.

interface Extension {
  id: string,
  path: string,
  manifest: chrome.Manifest
}

class Session {
  /** Emitted when extension is installed and ready. */
  on(event: 'extension-ready', listener: (event: Event, extension: Extension) => void): this;

  /** Loads an extension from the filesystem.
   * The returned promise is fulfilled when the extension has been successfully loaded,
   * or rejected with an error if the extension could not be successfully loaded.
   */
  loadExtension(path: string): Promise<Extension>;
  removeExtension(extensionId: string): void;
  enableExtension(extensionId: string): void;
  disableExtension(extensionId: string): void;

  getExtension(extensionId: string): Extension;
  getAllExtensions(): Extension[];
}

@nornagon
Copy link
Member Author

nornagon commented Jul 26, 2019

To remove in the new world:

  • BrowserWindow.addDevToolsExtension
  • BrowserWindow.removeDevToolsExtension
  • BrowserWindow.getDevToolsExtensions

//extensions doesn't distinguish between devtools extensions and non-devtools extensions. We can deprecate these functions and delegate them to defaultSession.loadExtension &c. to avoid breaking users without warning.

  • BrowserWindow.addExtension
  • BrowserWindow.removeExtension
  • BrowserWindow.getExtensions

Extensions are session-specific, so these APIs should move to Session. We can deprecate these functions and delegate them to the default session in the interim.

@sentialx
Copy link
Contributor

sentialx commented Jul 28, 2019

@nornagon How chrome.tabs related functions will be handled? Could I listen for example to chrome.tabs.create? I suggest adding for example a extensions-tabs-create event which is fired when an extension calls a chrome.tabs.create function to the Session class. Also, I've been implementing my own extensions system and I think that the extensionsRenderer object might be interesting for you as it handles UI related events such as the aforementioned API or chrome.browserAction.onClicked etc.

@nornagon
Copy link
Member Author

A lot of the chrome.tabs APIs don't make a lot of sense in an Electron context (e.g. chrome.tabs.getAllInWindow), so I don't think it makes sense for us to implement the full API. In general we aren't aiming to support every Chrome extension, only just enough to support the most common use cases (in particular, devtools extensions like React Devtools, and the internal PDF viewer extension). We probably want to make sure it's possible for apps to add custom implementations for APIs we don't support, e.g. through preload scripts.

Do you have a particular use-case in mind for the chrome.tabs.create API?

@sentialx
Copy link
Contributor

I'm making a web browser with multi-window and tabs support, so it would be nice to at least extend the chrome apis in background and content scripts.

@sentialx
Copy link
Contributor

@nornagon What bothers me now is how injecting preload scripts into the background pages would work? Will be there a session.setBackgroundPreloads API or something? Also, content scripts execute in isolated worlds, so how would I know in which world there's a chrome object?

@nornagon
Copy link
Member Author

Yes, it should be possible to inject preload scripts into background pages. session.setPreloads should do it. I think the easiest way to extend our current preload API would be to add a way for a preload script to know what kind of world it's being injected into (e.g. a global.electron.worldType variable or similar). Ideally we'd extend the preload API so you could specify a different script for each world type.

@kinop112365362
Copy link

Is there a guide to participating in the contributing code, about Google's extensions? @nornagon

@MarshallOfSound
Copy link
Member

What happens if you load the same extension id with a different version, does it replace the old one, or fail, or something else ❓

@sentialx
Copy link
Contributor

Is there a list of supported chrome APIs in the new extensions implementation?

@nornagon
Copy link
Member Author

Not yet but there should be! So far I think the list is something like:

  • chrome.runtime.*
  • chrome.extension.getURL (and maybe a couple of other chrome.extension APIs?)
  • chrome.tabs.executeScript - limited support, requires specifying tabId
  • chrome.tabs.sendMessage
  • chrome.devtools.* for devtools extensions
  • chrome.storage.local.*

this is just off the top of my head though, I think that there are quite a few more that may be supported already (e.g. i think most of the things in this list should work?) and there may be some restrictions on some of these APIs that I don't recall. I'll do a more thorough investigation soon and add this list to the docs at some point.

Ultimately though, we are not interested in maintaining anything close to feature parity with Chrome extensions. Our goal is to support devtools extensions (which we already do to some extent, so this will be maintaining roughly the same level of support) and to enable internal extensions like the PDF viewer. There are many concepts in Chrome's extensions API which do not map well to Electron—things like tabs, windows, the omnibox, sync profiles and so on—and it would be far too much effort to hook and expose all of these to app authors.

@sentialx
Copy link
Contributor

@nornagon Thanks for your great and hard work on it! I would be very grateful if chrome.extension.getBackgroundPage and chrome.extension.getViews would be also supported since it's very hard to actually implement this in JS by using only IPC. Or I would also appreciate if you could at least guide me how these APIs could be implemented.

@nornagon
Copy link
Member Author

those seem plausibly doable! i'll look into it.

@spikecodes
Copy link

Super excited about this!

@samuelmaddock
Copy link
Member

cc @sentialx @alexstrat @stewartlord @Thomas101

There are potentially breaking changes being introduced with the planned deprecation of Electron's current extension support in #21812. Projects adding additional Chrome APIs using the existing extensions implementation would likely cease to function.

I alerted @nornagon to this problem and he mentioned investigating whether it would be possible to support both implementations.

As far as I know, @nornagon is the only contributor actively working on the new extensions system implementation. Based on his work in #21779, it would likely be a considerable effort to support all Chrome APIs. I would encourage folks with an interest in this to start investigating solutions using the new extensions system.

@stewartlord
Copy link
Contributor

@samuelmaddock Thanks for the heads up! I'm excited to see this work continue to move forward. It would be great to preserve compatibility for a couple of releases until the new extension system is able to support existing implementations and apps in the wild have a chance to switch over.

Are you expecting BC breakage in 8.0?

@nornagon
Copy link
Member Author

There are no changes to extensions scheduled for 8.0, currently I'm targeting 9.0 for the switchover, so that gives us a bit of breathing room.

@stewartlord
Copy link
Contributor

Thanks @nornagon. Thrilled that you are working on it btw! Do you know what APIs will be affected and when we can start testing early builds? Extension support in our app is largely independent of the support that is bundled with Electron, but there are a couple of key touch points like InspectorFrontendAPI.addExtensions()

@mitermayer
Copy link

What are the remaining blockers for this issue? Would love to contribute in any way to help push this along

@samuelmaddock
Copy link
Member

samuelmaddock commented Apr 13, 2020

@mitermayer this work is available in v9.x.y. Basic unpacked extensions can be loaded into a session. However, not all extension APIs are available or function properly. @sentialx and I have been contributing recently to fix some of these issues.

Since Electron applications aren't constrained to the same tabbed browser model as traditional web browsers, some APIs such as chrome.tabs are intentionally left incomplete.

There are a few projects made to fill this gap:

If you're looking to use any extension in the Chrome webstore, there's still much work to be done. And as @nornagon mentioned, this will fall outside of officially maintained support.

@sentialx
Copy link
Contributor

sentialx commented Apr 13, 2020

@mitermayer
I don't know the official "stable blockers" described by the Electron team, but for me and probably for anyone who wants to support Chrome extensions in their app is:

  • no session property in the e.sender object received through an ipc message, it makes it impossible to identify the session when messaging
  • crash when loading for example 1Password X and probably many others
  • no way to add additional properties to Tab object like selected or highlighted.

The rest can be implemented easily in JS.

@nornagon
Copy link
Member Author

To clarify, it is not the intention of the Electron team to support loading arbitrary extensions from the Chrome Web Store. Our main goals with this effort are to:

  1. Reduce our maintenance burden by aligning with Chrome's architecture,
  2. Maintain & improve support for devtools extensions, and
  3. Provide a more solid base on which app developers can build.

I think we still have some work to go with (3), but since supporting non-devtools extensions is a new feature, a few rough edges there aren't a stable blocker for us.

@sentialx
Copy link
Contributor

Another thing that makes it difficult are CORS errors when extensions are trying to do an XHR request.
image

I made a temporary workaround here.

@GoldSmyth
Copy link

GoldSmyth commented Nov 4, 2020

Hi, I'm trying to find a way to activate the 'chrome.runtime' within the Electron browser, currently the chrome object is empty.

Could somebody advise on the best way to do this?

edit: I read above that I need to load an extension, could I load in the cryptoTokenExtension that comes bundled in Chrome? is there a way to import that?

Any help appreciated

Electron v9.3.1 Chrome v83.0.4103.122

@sentialx
Copy link
Contributor

sentialx commented Nov 4, 2020

@GoldSmyth
Copy link

@GoldSmyth You can download the extension from here: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/resources/cryptotoken/

Thank you, this solved the issue I was having!

@corysimmons
Copy link

corysimmons commented Nov 9, 2020

Bump?

@nornagon
Copy link
Member Author

I'm closing this as extensions support has landed and seems to be working fairly well, and as such there's not much use for a general-purpose tracking issue any more.

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

10 participants