From 1e2a2004e9684a1fc0db503db7ade3cac84cb087 Mon Sep 17 00:00:00 2001 From: Eryk Rakowski Date: Wed, 16 Dec 2020 00:52:43 +0100 Subject: [PATCH] feat: add support for webContents option in BrowserView (#26802) * feat: add support for webContents option in BrowserView * tests: add tests --- .../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 +++------------ spec-main/api-browser-view-spec.ts | 9 +++++++ 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/shell/browser/api/electron_api_browser_view.cc b/shell/browser/api/electron_api_browser_view.cc index 1fd448dc736a..ac8137ab2cbe 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 10c7fdc219e5..93358c5e3865 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -3738,6 +3738,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 a12c24b9d47d..25d0ee354e05 100644 --- a/shell/browser/api/electron_api_web_contents.h +++ b/shell/browser/api/electron_api_web_contents.h @@ -134,6 +134,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 67358c32dc77..48e32af4d0e9 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); diff --git a/spec-main/api-browser-view-spec.ts b/spec-main/api-browser-view-spec.ts index e6813e31cefa..6f7d1f1ea614 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();