From c3bdede4acad4946f7468ae5adfa8d4c8c48489a Mon Sep 17 00:00:00 2001 From: sentialx Date: Wed, 2 Dec 2020 18:25:22 +0100 Subject: [PATCH 1/2] feat: add support for webContents option in BrowserView --- .../browser/api/electron_api_browser_view.cc | 13 +++++++-- .../browser/api/electron_api_web_contents.cc | 27 +++++++++++++++++++ shell/browser/api/electron_api_web_contents.h | 4 +++ .../api/electron_api_web_contents_view.cc | 22 +++------------ 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/shell/browser/api/electron_api_browser_view.cc b/shell/browser/api/electron_api_browser_view.cc index 1fd448dc736aa..ac8137ab2cbe8 100644 --- a/shell/browser/api/electron_api_browser_view.cc +++ b/shell/browser/api/electron_api_browser_view.cc @@ -78,8 +78,17 @@ BrowserView::BrowserView(gin::Arguments* args, gin::Dictionary::CreateEmpty(isolate); options.Get(options::kWebPreferences, &web_preferences); web_preferences.Set("type", "browserView"); - gin::Handle web_contents = - WebContents::New(isolate, web_preferences); + + v8::Local value; + + // Copy the webContents option to webPreferences. This is only used internally + // to implement nativeWindowOpen option. + if (options.Get("webContents", &value)) { + web_preferences.SetHidden("webContents", value); + } + + auto web_contents = + WebContents::CreateFromWebPreferences(args->isolate(), web_preferences); web_contents_.Reset(isolate, web_contents.ToV8()); api_web_contents_ = web_contents.get(); diff --git a/shell/browser/api/electron_api_web_contents.cc b/shell/browser/api/electron_api_web_contents.cc index 684323bc10293..797d95ad4157d 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -3764,6 +3764,33 @@ gin::Handle WebContents::FromOrCreate( return gin::CreateHandle(isolate, api_web_contents); } +// static +gin::Handle WebContents::CreateFromWebPreferences( + v8::Isolate* isolate, + const gin_helper::Dictionary& web_preferences) { + // Check if webPreferences has |webContents| option. + gin::Handle web_contents; + if (web_preferences.GetHidden("webContents", &web_contents) && + !web_contents.IsEmpty()) { + // Set webPreferences from options if using an existing webContents. + // These preferences will be used when the webContent launches new + // render processes. + auto* existing_preferences = + WebContentsPreferences::From(web_contents->web_contents()); + base::DictionaryValue web_preferences_dict; + if (gin::ConvertFromV8(isolate, web_preferences.GetHandle(), + &web_preferences_dict)) { + existing_preferences->Clear(); + existing_preferences->Merge(web_preferences_dict); + } + } else { + // Create one if not. + web_contents = WebContents::New(isolate, web_preferences); + } + + return web_contents; +} + // static WebContents* WebContents::FromID(int32_t id) { return GetAllWebContents().Lookup(id); diff --git a/shell/browser/api/electron_api_web_contents.h b/shell/browser/api/electron_api_web_contents.h index 45596e1bb2ff6..a745340df6048 100644 --- a/shell/browser/api/electron_api_web_contents.h +++ b/shell/browser/api/electron_api_web_contents.h @@ -135,6 +135,10 @@ class WebContents : public gin::Wrappable, v8::Isolate* isolate, content::WebContents* web_contents); + static gin::Handle CreateFromWebPreferences( + v8::Isolate* isolate, + const gin_helper::Dictionary& web_preferences); + // gin::Wrappable static gin::WrapperInfo kWrapperInfo; static v8::Local FillObjectTemplate( diff --git a/shell/browser/api/electron_api_web_contents_view.cc b/shell/browser/api/electron_api_web_contents_view.cc index 67358c32dc77e..48e32af4d0e94 100644 --- a/shell/browser/api/electron_api_web_contents_view.cc +++ b/shell/browser/api/electron_api_web_contents_view.cc @@ -97,25 +97,9 @@ v8::Local WebContentsView::GetConstructor(v8::Isolate* isolate) { gin_helper::WrappableBase* WebContentsView::New( gin_helper::Arguments* args, const gin_helper::Dictionary& web_preferences) { - // Check if BrowserWindow has passend |webContents| option to us. - gin::Handle web_contents; - if (web_preferences.GetHidden("webContents", &web_contents) && - !web_contents.IsEmpty()) { - // Set webPreferences from options if using an existing webContents. - // These preferences will be used when the webContent launches new - // render processes. - auto* existing_preferences = - WebContentsPreferences::From(web_contents->web_contents()); - base::DictionaryValue web_preferences_dict; - if (gin::ConvertFromV8(args->isolate(), web_preferences.GetHandle(), - &web_preferences_dict)) { - existing_preferences->Clear(); - existing_preferences->Merge(web_preferences_dict); - } - } else { - // Create one if not. - web_contents = WebContents::New(args->isolate(), web_preferences); - } + auto web_contents = + WebContents::CreateFromWebPreferences(args->isolate(), web_preferences); + // Constructor call. auto* view = new WebContentsView(args->isolate(), web_contents); view->InitWithArgs(args); From 2b173c667285967de1ee3b2ad32aa2a65af2529f Mon Sep 17 00:00:00 2001 From: sentialx Date: Mon, 14 Dec 2020 12:16:19 +0100 Subject: [PATCH 2/2] tests: add tests --- spec-main/api-browser-view-spec.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spec-main/api-browser-view-spec.ts b/spec-main/api-browser-view-spec.ts index e6813e31cefac..6f7d1f1ea614a 100644 --- a/spec-main/api-browser-view-spec.ts +++ b/spec-main/api-browser-view-spec.ts @@ -39,6 +39,15 @@ describe('BrowserView module', () => { expect(webContents.getAllWebContents()).to.have.length(0); }); + it('can be created with an existing webContents', async () => { + const wc = (webContents as any).create({ sandbox: true }); + await wc.loadURL('about:blank'); + + view = new BrowserView({ webContents: wc } as any); + + expect(view.webContents.getURL()).to.equal('about:blank'); + }); + describe('BrowserView.setBackgroundColor()', () => { it('does not throw for valid args', () => { view = new BrowserView();