feat: Allow WebContentsView to accept webContents object. (#42319)
feat: Allow WebContentsView to accept webContents object Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Krzysztof Halwa <krzysztofhalwa@outlook.com>
This commit is contained in:
parent
0d12131f50
commit
038e261069
3 changed files with 69 additions and 2 deletions
|
@ -36,8 +36,9 @@ Process: [Main](../glossary.md#main-process)
|
||||||
|
|
||||||
* `options` Object (optional)
|
* `options` Object (optional)
|
||||||
* `webPreferences` [WebPreferences](structures/web-preferences.md) (optional) - Settings of web page's features.
|
* `webPreferences` [WebPreferences](structures/web-preferences.md) (optional) - Settings of web page's features.
|
||||||
|
* `webContents` [WebContents](web-contents.md) (optional) - If present, the given WebContents will be adopted by the WebContentsView. A WebContents may only be presented in one WebContentsView at a time.
|
||||||
|
|
||||||
Creates an empty WebContentsView.
|
Creates a WebContentsView.
|
||||||
|
|
||||||
### Instance Properties
|
### Instance Properties
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,7 @@ v8::Local<v8::Function> WebContentsView::GetConstructor(v8::Isolate* isolate) {
|
||||||
// static
|
// static
|
||||||
gin_helper::WrappableBase* WebContentsView::New(gin_helper::Arguments* args) {
|
gin_helper::WrappableBase* WebContentsView::New(gin_helper::Arguments* args) {
|
||||||
gin_helper::Dictionary web_preferences;
|
gin_helper::Dictionary web_preferences;
|
||||||
|
v8::Local<v8::Value> existing_web_contents_value;
|
||||||
{
|
{
|
||||||
v8::Local<v8::Value> options_value;
|
v8::Local<v8::Value> options_value;
|
||||||
if (args->GetNext(&options_value)) {
|
if (args->GetNext(&options_value)) {
|
||||||
|
@ -154,12 +155,33 @@ gin_helper::WrappableBase* WebContentsView::New(gin_helper::Arguments* args) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.Get("webContents", &existing_web_contents_value)) {
|
||||||
|
gin::Handle<WebContents> existing_web_contents;
|
||||||
|
if (!gin::ConvertFromV8(args->isolate(), existing_web_contents_value,
|
||||||
|
&existing_web_contents)) {
|
||||||
|
args->ThrowError("options.webContents must be a WebContents");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existing_web_contents->owner_window() != nullptr) {
|
||||||
|
args->ThrowError(
|
||||||
|
"options.webContents is already attached to a window");
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (web_preferences.IsEmpty())
|
if (web_preferences.IsEmpty())
|
||||||
web_preferences = gin_helper::Dictionary::CreateEmpty(args->isolate());
|
web_preferences = gin_helper::Dictionary::CreateEmpty(args->isolate());
|
||||||
if (!web_preferences.Has(options::kShow))
|
if (!web_preferences.Has(options::kShow))
|
||||||
web_preferences.Set(options::kShow, false);
|
web_preferences.Set(options::kShow, false);
|
||||||
|
|
||||||
|
if (!existing_web_contents_value.IsEmpty()) {
|
||||||
|
web_preferences.SetHidden("webContents", existing_web_contents_value);
|
||||||
|
}
|
||||||
|
|
||||||
auto web_contents =
|
auto web_contents =
|
||||||
WebContents::CreateFromWebPreferences(args->isolate(), web_preferences);
|
WebContents::CreateFromWebPreferences(args->isolate(), web_preferences);
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { closeAllWindows } from './lib/window-helpers';
|
import { closeAllWindows } from './lib/window-helpers';
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
|
|
||||||
import { BaseWindow, View, WebContentsView } from 'electron/main';
|
import { BaseWindow, View, WebContentsView, webContents } from 'electron/main';
|
||||||
import { once } from 'node:events';
|
import { once } from 'node:events';
|
||||||
|
import { defer } from './lib/spec-helpers';
|
||||||
|
import { BrowserWindow } from 'electron';
|
||||||
|
|
||||||
describe('WebContentsView', () => {
|
describe('WebContentsView', () => {
|
||||||
afterEach(closeAllWindows);
|
afterEach(closeAllWindows);
|
||||||
|
@ -17,6 +19,48 @@ describe('WebContentsView', () => {
|
||||||
new WebContentsView({});
|
new WebContentsView({});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('accepts existing webContents object', async () => {
|
||||||
|
const currentWebContentsCount = webContents.getAllWebContents().length;
|
||||||
|
|
||||||
|
const wc = (webContents as typeof ElectronInternal.WebContents).create({ sandbox: true });
|
||||||
|
defer(() => wc.destroy());
|
||||||
|
await wc.loadURL('about:blank');
|
||||||
|
|
||||||
|
const webContentsView = new WebContentsView({
|
||||||
|
webContents: wc
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(webContentsView.webContents).to.eq(wc);
|
||||||
|
expect(webContents.getAllWebContents().length).to.equal(currentWebContentsCount + 1, 'expected only single webcontents to be created');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw error when created with already attached webContents to BrowserWindow', () => {
|
||||||
|
const browserWindow = new BrowserWindow();
|
||||||
|
defer(() => browserWindow.webContents.destroy());
|
||||||
|
|
||||||
|
const webContentsView = new WebContentsView();
|
||||||
|
defer(() => webContentsView.webContents.destroy());
|
||||||
|
|
||||||
|
browserWindow.contentView.addChildView(webContentsView);
|
||||||
|
defer(() => browserWindow.contentView.removeChildView(webContentsView));
|
||||||
|
|
||||||
|
expect(() => new WebContentsView({
|
||||||
|
webContents: webContentsView.webContents
|
||||||
|
})).to.throw('options.webContents is already attached to a window');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw error when created with already attached webContents to other WebContentsView', () => {
|
||||||
|
const browserWindow = new BrowserWindow();
|
||||||
|
|
||||||
|
const webContentsView = new WebContentsView();
|
||||||
|
defer(() => webContentsView.webContents.destroy());
|
||||||
|
webContentsView.webContents.loadURL('about:blank');
|
||||||
|
|
||||||
|
expect(() => new WebContentsView({
|
||||||
|
webContents: browserWindow.webContents
|
||||||
|
})).to.throw('options.webContents is already attached to a window');
|
||||||
|
});
|
||||||
|
|
||||||
it('can be used as content view', () => {
|
it('can be used as content view', () => {
|
||||||
const w = new BaseWindow({ show: false });
|
const w = new BaseWindow({ show: false });
|
||||||
w.setContentView(new WebContentsView());
|
w.setContentView(new WebContentsView());
|
||||||
|
|
Loading…
Reference in a new issue