diff --git a/shell/browser/api/electron_api_app.cc b/shell/browser/api/electron_api_app.cc index fca954a915fc..e649304192bc 100644 --- a/shell/browser/api/electron_api_app.cc +++ b/shell/browser/api/electron_api_app.cc @@ -877,17 +877,6 @@ void App::BrowserChildProcessCrashedOrKilled( void App::RenderProcessReady(content::RenderProcessHost* host) { ChildProcessLaunched(content::PROCESS_TYPE_RENDERER, host->GetID(), host->GetProcess().Handle()); - - // TODO(jeremy): this isn't really the right place to be creating - // `WebContents` instances, but this was implicitly happening before in - // `RenderProcessPreferences`, so this is at least more explicit... - content::WebContents* web_contents = - ElectronBrowserClient::Get()->GetWebContentsFromProcessID(host->GetID()); - if (web_contents) { - v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); - v8::HandleScope scope(isolate); - WebContents::FromOrCreate(isolate, web_contents); - } } void App::RenderProcessExited(content::RenderProcessHost* host) { diff --git a/shell/browser/extensions/electron_extension_host_delegate.cc b/shell/browser/extensions/electron_extension_host_delegate.cc index 82dbe4ca9960..1aa8cc73e5bd 100644 --- a/shell/browser/extensions/electron_extension_host_delegate.cc +++ b/shell/browser/extensions/electron_extension_host_delegate.cc @@ -11,7 +11,9 @@ #include "base/lazy_instance.h" #include "base/logging.h" #include "extensions/browser/media_capture_util.h" +#include "shell/browser/api/electron_api_web_contents.h" #include "shell/browser/extensions/electron_extension_web_contents_observer.h" +#include "v8/include/v8.h" namespace extensions { @@ -22,6 +24,9 @@ ElectronExtensionHostDelegate::~ElectronExtensionHostDelegate() {} void ElectronExtensionHostDelegate::OnExtensionHostCreated( content::WebContents* web_contents) { ElectronExtensionWebContentsObserver::CreateForWebContents(web_contents); + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::HandleScope scope(isolate); + electron::api::WebContents::FromOrCreate(isolate, web_contents); } void ElectronExtensionHostDelegate::OnMainFrameCreatedForBackgroundPage( diff --git a/shell/browser/extensions/electron_extensions_api_client.cc b/shell/browser/extensions/electron_extensions_api_client.cc index 9a74b5a6add0..3c9f146e54ab 100644 --- a/shell/browser/extensions/electron_extensions_api_client.cc +++ b/shell/browser/extensions/electron_extensions_api_client.cc @@ -8,11 +8,14 @@ #include #include "electron/buildflags/buildflags.h" +#include "extensions/browser/guest_view/extensions_guest_view_manager_delegate.h" #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h" #include "printing/buildflags/buildflags.h" +#include "shell/browser/api/electron_api_web_contents.h" #include "shell/browser/extensions/api/management/electron_management_api_delegate.h" #include "shell/browser/extensions/electron_extension_web_contents_observer.h" #include "shell/browser/extensions/electron_messaging_delegate.h" +#include "v8/include/v8.h" #if BUILDFLAG(ENABLE_PRINTING) #include "chrome/browser/printing/print_view_manager_basic.h" @@ -27,6 +30,24 @@ namespace extensions { +class ElectronGuestViewManagerDelegate + : public ExtensionsGuestViewManagerDelegate { + public: + explicit ElectronGuestViewManagerDelegate(content::BrowserContext* context) + : ExtensionsGuestViewManagerDelegate(context) {} + ~ElectronGuestViewManagerDelegate() override = default; + + // GuestViewManagerDelegate: + void OnGuestAdded(content::WebContents* guest_web_contents) const override { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::HandleScope scope(isolate); + electron::api::WebContents::FromOrCreate(isolate, guest_web_contents); + } + + private: + DISALLOW_COPY_AND_ASSIGN(ElectronGuestViewManagerDelegate); +}; + class ElectronMimeHandlerViewGuestDelegate : public MimeHandlerViewGuestDelegate { public: @@ -83,4 +104,10 @@ ElectronExtensionsAPIClient::CreateMimeHandlerViewGuestDelegate( return std::make_unique(); } +std::unique_ptr +ElectronExtensionsAPIClient::CreateGuestViewManagerDelegate( + content::BrowserContext* context) const { + return std::make_unique(context); +} + } // namespace extensions diff --git a/shell/browser/extensions/electron_extensions_api_client.h b/shell/browser/extensions/electron_extensions_api_client.h index 03d07d8453bb..a389ec5fa548 100644 --- a/shell/browser/extensions/electron_extensions_api_client.h +++ b/shell/browser/extensions/electron_extensions_api_client.h @@ -26,6 +26,9 @@ class ElectronExtensionsAPIClient : public ExtensionsAPIClient { CreateMimeHandlerViewGuestDelegate( MimeHandlerViewGuest* guest) const override; ManagementAPIDelegate* CreateManagementAPIDelegate() const override; + std::unique_ptr + CreateGuestViewManagerDelegate( + content::BrowserContext* context) const override; private: std::unique_ptr messaging_delegate_; diff --git a/shell/browser/ui/inspectable_web_contents.cc b/shell/browser/ui/inspectable_web_contents.cc index 350fbe5c0032..3ed07a6a2703 100644 --- a/shell/browser/ui/inspectable_web_contents.cc +++ b/shell/browser/ui/inspectable_web_contents.cc @@ -41,6 +41,7 @@ #include "services/network/public/cpp/simple_url_loader.h" #include "services/network/public/cpp/simple_url_loader_stream_consumer.h" #include "services/network/public/cpp/wrapper_shared_url_loader_factory.h" +#include "shell/browser/api/electron_api_web_contents.h" #include "shell/browser/net/asar/asar_url_loader_factory.h" #include "shell/browser/protocol_registry.h" #include "shell/browser/ui/inspectable_web_contents_delegate.h" @@ -51,6 +52,7 @@ #include "third_party/blink/public/common/page/page_zoom.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "v8/include/v8.h" #if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS) #include "chrome/common/extensions/chrome_manifest_url_handlers.h" @@ -450,6 +452,10 @@ void InspectableWebContents::ShowDevTools(bool activate) { managed_devtools_web_contents_ = content::WebContents::Create( content::WebContents::CreateParams(web_contents_->GetBrowserContext())); managed_devtools_web_contents_->SetDelegate(this); + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::HandleScope scope(isolate); + api::WebContents::FromOrCreate(isolate, + managed_devtools_web_contents_.get()); } Observe(GetDevToolsWebContents()); diff --git a/spec-main/chromium-spec.ts b/spec-main/chromium-spec.ts index 3de4b6efe894..40d9de0739fc 100644 --- a/spec-main/chromium-spec.ts +++ b/spec-main/chromium-spec.ts @@ -1382,6 +1382,7 @@ describe('chromium features', () => { const w = new BrowserWindow({ show: false }); w.loadURL(pdfSource); const [, contents] = await emittedOnce(app, 'web-contents-created'); + await emittedOnce(contents, 'did-navigate'); expect(contents.getURL()).to.equal('chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html'); }); @@ -1389,6 +1390,7 @@ describe('chromium features', () => { const w = new BrowserWindow({ show: false }); w.loadFile(path.join(__dirname, 'fixtures', 'pages', 'pdf-in-iframe.html')); const [, contents] = await emittedOnce(app, 'web-contents-created'); + await emittedOnce(contents, 'did-navigate'); expect(contents.getURL()).to.equal('chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html'); }); }); diff --git a/spec-main/extensions-spec.ts b/spec-main/extensions-spec.ts index ade02bee72d0..9d2e31e823b7 100644 --- a/spec-main/extensions-spec.ts +++ b/spec-main/extensions-spec.ts @@ -57,8 +57,9 @@ describe('chrome extensions', () => { const w = new BrowserWindow({ show: false, webPreferences: { session: customSession, sandbox: true } }); await w.loadURL('about:blank'); + const promise = emittedOnce(app, 'web-contents-created'); await customSession.loadExtension(path.join(fixtures, 'extensions', 'persistent-background-page')); - const args: any = await emittedOnce(app, 'web-contents-created'); + const args: any = await promise; const wc: Electron.WebContents = args[1]; await expect(wc.executeJavaScript(` (() => { @@ -76,8 +77,9 @@ describe('chrome extensions', () => { const w = new BrowserWindow({ show: false, webPreferences: { session: customSession, sandbox: true } }); await w.loadURL('about:blank'); + const promise = emittedOnce(app, 'web-contents-created'); await customSession.loadExtension(path.join(fixtures, 'extensions', 'persistent-background-page')); - const args: any = await emittedOnce(app, 'web-contents-created'); + const args: any = await promise; const wc: Electron.WebContents = args[1]; await expect(wc.executeJavaScript('(()=>{try{openDatabase("t", "1.0", "test", 2e5);return true;}catch(e){throw e}})()')).to.not.be.rejected(); }); @@ -429,19 +431,21 @@ describe('chrome extensions', () => { it('has session in background page', async () => { const customSession = session.fromPartition(`persist:${require('uuid').v4()}`); + const promise = emittedOnce(app, 'web-contents-created'); await customSession.loadExtension(path.join(fixtures, 'extensions', 'persistent-background-page')); const w = new BrowserWindow({ show: false, webPreferences: { session: customSession } }); - const promise = emittedOnce(app, 'web-contents-created'); await w.loadURL('about:blank'); const [, bgPageContents] = await promise; + expect(bgPageContents.getType()).to.equal('backgroundPage'); + expect(bgPageContents.getURL()).to.match(/^chrome-extension:\/\/.+\/_generated_background_page.html$/); expect(bgPageContents.session).to.not.equal(undefined); }); it('can open devtools of background page', async () => { const customSession = session.fromPartition(`persist:${require('uuid').v4()}`); + const promise = emittedOnce(app, 'web-contents-created'); await customSession.loadExtension(path.join(fixtures, 'extensions', 'persistent-background-page')); const w = new BrowserWindow({ show: false, webPreferences: { session: customSession } }); - const promise = emittedOnce(app, 'web-contents-created'); await w.loadURL('about:blank'); const [, bgPageContents] = await promise; expect(bgPageContents.getType()).to.equal('backgroundPage');