Browse Source

feat: add support for webContents option in BrowserView (#27094)

* feat: add support for webContents option in BrowserView (#26802)

* feat: add support for webContents option in BrowserView

* tests: add tests

* fix: missing webContents import

* fix: WebContents::New -> Create
Eryk Rakowski 4 years ago
parent
commit
d3f7ad2035

+ 11 - 2
shell/browser/api/electron_api_browser_view.cc

@@ -66,8 +66,17 @@ BrowserView::BrowserView(gin::Arguments* args,
       gin::Dictionary::CreateEmpty(isolate);
   options.Get(options::kWebPreferences, &web_preferences);
   web_preferences.Set("type", "browserView");
-  gin::Handle<class WebContents> web_contents =
-      WebContents::Create(isolate, web_preferences);
+
+  v8::Local<v8::Value> 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();

+ 27 - 0
shell/browser/api/electron_api_web_contents.cc

@@ -3003,6 +3003,33 @@ gin::Handle<WebContents> WebContents::FromOrCreate(
     return gin::CreateHandle(isolate, new WebContents(isolate, web_contents));
 }
 
+// static
+gin::Handle<WebContents> WebContents::CreateFromWebPreferences(
+    v8::Isolate* isolate,
+    const gin_helper::Dictionary& web_preferences) {
+  // Check if webPreferences has |webContents| option.
+  gin::Handle<WebContents> 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::Create(isolate, web_preferences);
+  }
+
+  return web_contents;
+}
+
 }  // namespace api
 
 }  // namespace electron

+ 4 - 0
shell/browser/api/electron_api_web_contents.h

@@ -156,6 +156,10 @@ class WebContents : public gin_helper::TrackableObject<WebContents>,
   static void BuildPrototype(v8::Isolate* isolate,
                              v8::Local<v8::FunctionTemplate> prototype);
 
+  static gin::Handle<WebContents> CreateFromWebPreferences(
+      v8::Isolate* isolate,
+      const gin_helper::Dictionary& web_preferences);
+
   base::WeakPtr<WebContents> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
 
   // Destroy the managed content::WebContents instance.

+ 3 - 19
shell/browser/api/electron_api_web_contents_view.cc

@@ -96,25 +96,9 @@ v8::Local<v8::Function> 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<WebContents> 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::Create(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);

+ 10 - 1
spec-main/api-browser-view-spec.ts

@@ -2,7 +2,7 @@ import { expect } from 'chai';
 import * as ChildProcess from 'child_process';
 import * as path from 'path';
 import { emittedOnce } from './events-helpers';
-import { BrowserView, BrowserWindow } from 'electron/main';
+import { BrowserView, BrowserWindow, webContents } from 'electron/main';
 import { closeWindow } from './window-helpers';
 
 describe('BrowserView module', () => {
@@ -46,6 +46,15 @@ describe('BrowserView module', () => {
     });
   });
 
+  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();