Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
// Copyright (c) 2017 GitHub, Inc.
|
|
|
|
// Use of this source code is governed by the MIT license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "atom/browser/api/atom_api_browser_view.h"
|
|
|
|
|
|
|
|
#include "atom/browser/api/atom_api_web_contents.h"
|
|
|
|
#include "atom/browser/browser.h"
|
|
|
|
#include "atom/browser/native_browser_view.h"
|
|
|
|
#include "atom/common/color_util.h"
|
|
|
|
#include "atom/common/native_mate_converters/gfx_converter.h"
|
|
|
|
#include "atom/common/native_mate_converters/value_converter.h"
|
|
|
|
#include "atom/common/node_includes.h"
|
|
|
|
#include "atom/common/options_switches.h"
|
|
|
|
#include "native_mate/constructor.h"
|
|
|
|
#include "native_mate/dictionary.h"
|
|
|
|
#include "ui/gfx/geometry/rect.h"
|
|
|
|
|
2017-04-12 11:40:31 +00:00
|
|
|
namespace mate {
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct Converter<atom::AutoResizeFlags> {
|
|
|
|
static bool FromV8(v8::Isolate* isolate,
|
|
|
|
v8::Local<v8::Value> val,
|
|
|
|
atom::AutoResizeFlags* auto_resize_flags) {
|
|
|
|
mate::Dictionary params;
|
|
|
|
if (!ConvertFromV8(isolate, val, ¶ms)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t flags = 0;
|
|
|
|
bool width = false;
|
|
|
|
if (params.Get("width", &width) && width) {
|
|
|
|
flags |= atom::kAutoResizeWidth;
|
|
|
|
}
|
|
|
|
bool height = false;
|
|
|
|
if (params.Get("height", &height) && height) {
|
|
|
|
flags |= atom::kAutoResizeHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
*auto_resize_flags = static_cast<atom::AutoResizeFlags>(flags);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace mate
|
|
|
|
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
namespace atom {
|
|
|
|
|
|
|
|
namespace api {
|
|
|
|
|
|
|
|
BrowserView::BrowserView(v8::Isolate* isolate,
|
|
|
|
v8::Local<v8::Object> wrapper,
|
|
|
|
const mate::Dictionary& options)
|
|
|
|
: api_web_contents_(nullptr) {
|
|
|
|
Init(isolate, wrapper, options);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BrowserView::Init(v8::Isolate* isolate,
|
|
|
|
v8::Local<v8::Object> wrapper,
|
|
|
|
const mate::Dictionary& options) {
|
|
|
|
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
|
|
|
options.Get(options::kWebPreferences, &web_preferences);
|
|
|
|
web_preferences.Set("isBrowserView", true);
|
|
|
|
mate::Handle<class WebContents> web_contents =
|
|
|
|
WebContents::Create(isolate, web_preferences);
|
|
|
|
|
|
|
|
web_contents_.Reset(isolate, web_contents.ToV8());
|
|
|
|
api_web_contents_ = web_contents.get();
|
|
|
|
|
|
|
|
view_.reset(NativeBrowserView::Create(
|
|
|
|
api_web_contents_->managed_web_contents()->GetView()));
|
|
|
|
|
|
|
|
InitWith(isolate, wrapper);
|
|
|
|
}
|
|
|
|
|
|
|
|
BrowserView::~BrowserView() {
|
2017-04-19 16:37:12 +00:00
|
|
|
api_web_contents_->DestroyWebContents(true /* async */);
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
mate::WrappableBase* BrowserView::New(mate::Arguments* args) {
|
|
|
|
if (!Browser::Get()->is_ready()) {
|
|
|
|
args->ThrowError("Cannot create BrowserView before app is ready");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args->Length() > 1) {
|
|
|
|
args->ThrowError("Too many arguments");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
mate::Dictionary options;
|
|
|
|
if (!(args->Length() == 1 && args->GetNext(&options))) {
|
|
|
|
options = mate::Dictionary::CreateEmpty(args->isolate());
|
|
|
|
}
|
|
|
|
|
|
|
|
return new BrowserView(args->isolate(), args->GetThis(), options);
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t BrowserView::ID() const {
|
|
|
|
return weak_map_id();
|
|
|
|
}
|
|
|
|
|
2017-04-12 11:40:31 +00:00
|
|
|
void BrowserView::SetAutoResize(AutoResizeFlags flags) {
|
|
|
|
view_->SetAutoResizeFlags(flags);
|
|
|
|
}
|
|
|
|
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
void BrowserView::SetBounds(const gfx::Rect& bounds) {
|
|
|
|
view_->SetBounds(bounds);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BrowserView::SetBackgroundColor(const std::string& color_name) {
|
|
|
|
view_->SetBackgroundColor(ParseHexColor(color_name));
|
|
|
|
}
|
|
|
|
|
2017-11-21 12:47:51 +00:00
|
|
|
v8::Local<v8::Value> BrowserView::GetWebContents() {
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
if (web_contents_.IsEmpty()) {
|
|
|
|
return v8::Null(isolate());
|
|
|
|
}
|
|
|
|
|
|
|
|
return v8::Local<v8::Value>::New(isolate(), web_contents_);
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
void BrowserView::BuildPrototype(v8::Isolate* isolate,
|
|
|
|
v8::Local<v8::FunctionTemplate> prototype) {
|
|
|
|
prototype->SetClassName(mate::StringToV8(isolate, "BrowserView"));
|
|
|
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
|
|
|
.MakeDestroyable()
|
2017-04-12 11:40:31 +00:00
|
|
|
.SetMethod("setAutoResize", &BrowserView::SetAutoResize)
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
.SetMethod("setBounds", &BrowserView::SetBounds)
|
|
|
|
.SetMethod("setBackgroundColor", &BrowserView::SetBackgroundColor)
|
2017-11-21 12:47:51 +00:00
|
|
|
.SetProperty("webContents", &BrowserView::GetWebContents)
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
.SetProperty("id", &BrowserView::ID);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace api
|
|
|
|
|
|
|
|
} // namespace atom
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
using atom::api::BrowserView;
|
|
|
|
|
|
|
|
void Initialize(v8::Local<v8::Object> exports,
|
|
|
|
v8::Local<v8::Value> unused,
|
|
|
|
v8::Local<v8::Context> context,
|
|
|
|
void* priv) {
|
|
|
|
v8::Isolate* isolate = context->GetIsolate();
|
|
|
|
BrowserView::SetConstructor(isolate, base::Bind(&BrowserView::New));
|
|
|
|
|
|
|
|
mate::Dictionary browser_view(
|
|
|
|
isolate, BrowserView::GetConstructor(isolate)->GetFunction());
|
2017-07-24 03:32:30 +00:00
|
|
|
browser_view.SetMethod("fromId",
|
|
|
|
&mate::TrackableObject<BrowserView>::FromWeakMapID);
|
2017-11-23 00:58:32 +00:00
|
|
|
browser_view.SetMethod("getAllViews",
|
|
|
|
&mate::TrackableObject<BrowserView>::GetAll);
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
mate::Dictionary dict(isolate, exports);
|
|
|
|
dict.Set("BrowserView", browser_view);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_browser_view, Initialize)
|