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
This commit is contained in:
Eryk Rakowski
2021-01-05 03:22:56 +01:00
committed by GitHub
parent f5deaedfaa
commit d3f7ad2035
5 changed files with 55 additions and 22 deletions

View File

@@ -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();

View File

@@ -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

View File

@@ -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.

View File

@@ -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);

View File

@@ -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();