feat: browserWindow.getBrowserViews()
to return sorted by z-index array (#38943)
This commit is contained in:
parent
905e41bbdd
commit
f959fb0c96
4 changed files with 36 additions and 13 deletions
|
@ -1651,8 +1651,8 @@ Throws an error if `browserView` is not attached to `win`.
|
||||||
|
|
||||||
#### `win.getBrowserViews()` _Experimental_
|
#### `win.getBrowserViews()` _Experimental_
|
||||||
|
|
||||||
Returns `BrowserView[]` - an array of all BrowserViews that have been attached
|
Returns `BrowserView[]` - a sorted by z-index array of all BrowserViews that have been attached
|
||||||
with `addBrowserView` or `setBrowserView`.
|
with `addBrowserView` or `setBrowserView`. The top-most BrowserView is the last element of the array.
|
||||||
|
|
||||||
**Note:** The BrowserView API is currently experimental and may change or be
|
**Note:** The BrowserView API is currently experimental and may change or be
|
||||||
removed in future Electron releases.
|
removed in future Electron releases.
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "shell/browser/api/electron_api_base_window.h"
|
#include "shell/browser/api/electron_api_base_window.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -756,7 +757,7 @@ void BaseWindow::SetBrowserView(
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseWindow::AddBrowserView(gin::Handle<BrowserView> browser_view) {
|
void BaseWindow::AddBrowserView(gin::Handle<BrowserView> browser_view) {
|
||||||
if (!base::Contains(browser_views_, browser_view->ID())) {
|
if (!base::Contains(browser_views_, browser_view.ToV8())) {
|
||||||
// If we're reparenting a BrowserView, ensure that it's detached from
|
// If we're reparenting a BrowserView, ensure that it's detached from
|
||||||
// its previous owner window.
|
// its previous owner window.
|
||||||
BaseWindow* owner_window = browser_view->owner_window();
|
BaseWindow* owner_window = browser_view->owner_window();
|
||||||
|
@ -770,17 +771,19 @@ void BaseWindow::AddBrowserView(gin::Handle<BrowserView> browser_view) {
|
||||||
window_->AddBrowserView(browser_view->view());
|
window_->AddBrowserView(browser_view->view());
|
||||||
window_->AddDraggableRegionProvider(browser_view.get());
|
window_->AddDraggableRegionProvider(browser_view.get());
|
||||||
browser_view->SetOwnerWindow(this);
|
browser_view->SetOwnerWindow(this);
|
||||||
browser_views_[browser_view->ID()].Reset(isolate(), browser_view.ToV8());
|
browser_views_.emplace_back().Reset(isolate(), browser_view.ToV8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseWindow::RemoveBrowserView(gin::Handle<BrowserView> browser_view) {
|
void BaseWindow::RemoveBrowserView(gin::Handle<BrowserView> browser_view) {
|
||||||
auto iter = browser_views_.find(browser_view->ID());
|
auto iter = std::find(browser_views_.begin(), browser_views_.end(),
|
||||||
|
browser_view.ToV8());
|
||||||
|
|
||||||
if (iter != browser_views_.end()) {
|
if (iter != browser_views_.end()) {
|
||||||
window_->RemoveBrowserView(browser_view->view());
|
window_->RemoveBrowserView(browser_view->view());
|
||||||
window_->RemoveDraggableRegionProvider(browser_view.get());
|
window_->RemoveDraggableRegionProvider(browser_view.get());
|
||||||
browser_view->SetOwnerWindow(nullptr);
|
browser_view->SetOwnerWindow(nullptr);
|
||||||
iter->second.Reset();
|
iter->Reset();
|
||||||
browser_views_.erase(iter);
|
browser_views_.erase(iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -788,12 +791,15 @@ void BaseWindow::RemoveBrowserView(gin::Handle<BrowserView> browser_view) {
|
||||||
void BaseWindow::SetTopBrowserView(gin::Handle<BrowserView> browser_view,
|
void BaseWindow::SetTopBrowserView(gin::Handle<BrowserView> browser_view,
|
||||||
gin_helper::Arguments* args) {
|
gin_helper::Arguments* args) {
|
||||||
BaseWindow* owner_window = browser_view->owner_window();
|
BaseWindow* owner_window = browser_view->owner_window();
|
||||||
auto iter = browser_views_.find(browser_view->ID());
|
auto iter = std::find(browser_views_.begin(), browser_views_.end(),
|
||||||
|
browser_view.ToV8());
|
||||||
if (iter == browser_views_.end() || (owner_window && owner_window != this)) {
|
if (iter == browser_views_.end() || (owner_window && owner_window != this)) {
|
||||||
args->ThrowError("Given BrowserView is not attached to the window");
|
args->ThrowError("Given BrowserView is not attached to the window");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
browser_views_.erase(iter);
|
||||||
|
browser_views_.emplace_back().Reset(isolate(), browser_view.ToV8());
|
||||||
window_->SetTopBrowserView(browser_view->view());
|
window_->SetTopBrowserView(browser_view->view());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1000,7 +1006,7 @@ v8::Local<v8::Value> BaseWindow::GetBrowserView(
|
||||||
return v8::Null(isolate());
|
return v8::Null(isolate());
|
||||||
} else if (browser_views_.size() == 1) {
|
} else if (browser_views_.size() == 1) {
|
||||||
auto first_view = browser_views_.begin();
|
auto first_view = browser_views_.begin();
|
||||||
return v8::Local<v8::Value>::New(isolate(), (*first_view).second);
|
return v8::Local<v8::Value>::New(isolate(), *first_view);
|
||||||
} else {
|
} else {
|
||||||
args->ThrowError(
|
args->ThrowError(
|
||||||
"BrowserWindow have multiple BrowserViews, "
|
"BrowserWindow have multiple BrowserViews, "
|
||||||
|
@ -1012,8 +1018,8 @@ v8::Local<v8::Value> BaseWindow::GetBrowserView(
|
||||||
std::vector<v8::Local<v8::Value>> BaseWindow::GetBrowserViews() const {
|
std::vector<v8::Local<v8::Value>> BaseWindow::GetBrowserViews() const {
|
||||||
std::vector<v8::Local<v8::Value>> ret;
|
std::vector<v8::Local<v8::Value>> ret;
|
||||||
|
|
||||||
for (auto const& views_iter : browser_views_) {
|
for (auto const& browser_view : browser_views_) {
|
||||||
ret.push_back(v8::Local<v8::Value>::New(isolate(), views_iter.second));
|
ret.push_back(v8::Local<v8::Value>::New(isolate(), browser_view));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1122,7 +1128,7 @@ void BaseWindow::ResetBrowserViews() {
|
||||||
for (auto& item : browser_views_) {
|
for (auto& item : browser_views_) {
|
||||||
gin::Handle<BrowserView> browser_view;
|
gin::Handle<BrowserView> browser_view;
|
||||||
if (gin::ConvertFromV8(isolate(),
|
if (gin::ConvertFromV8(isolate(),
|
||||||
v8::Local<v8::Value>::New(isolate(), item.second),
|
v8::Local<v8::Value>::New(isolate(), item),
|
||||||
&browser_view) &&
|
&browser_view) &&
|
||||||
!browser_view.IsEmpty()) {
|
!browser_view.IsEmpty()) {
|
||||||
// There's a chance that the BrowserView may have been reparented - only
|
// There's a chance that the BrowserView may have been reparented - only
|
||||||
|
@ -1135,7 +1141,7 @@ void BaseWindow::ResetBrowserViews() {
|
||||||
browser_view->SetOwnerWindow(nullptr);
|
browser_view->SetOwnerWindow(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
item.second.Reset();
|
item.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
browser_views_.clear();
|
browser_views_.clear();
|
||||||
|
|
|
@ -275,7 +275,7 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
v8::Global<v8::Value> content_view_;
|
v8::Global<v8::Value> content_view_;
|
||||||
std::map<int32_t, v8::Global<v8::Value>> browser_views_;
|
std::vector<v8::Global<v8::Value>> browser_views_;
|
||||||
v8::Global<v8::Value> menu_;
|
v8::Global<v8::Value> menu_;
|
||||||
v8::Global<v8::Value> parent_window_;
|
v8::Global<v8::Value> parent_window_;
|
||||||
KeyWeakMap<int> child_windows_;
|
KeyWeakMap<int> child_windows_;
|
||||||
|
|
|
@ -286,6 +286,23 @@ describe('BrowserView module', () => {
|
||||||
expect(views[0].webContents.id).to.equal(view1.webContents.id);
|
expect(views[0].webContents.id).to.equal(view1.webContents.id);
|
||||||
expect(views[1].webContents.id).to.equal(view2.webContents.id);
|
expect(views[1].webContents.id).to.equal(view2.webContents.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('persists ordering by z-index', () => {
|
||||||
|
const view1 = new BrowserView();
|
||||||
|
defer(() => view1.webContents.destroy());
|
||||||
|
w.addBrowserView(view1);
|
||||||
|
defer(() => w.removeBrowserView(view1));
|
||||||
|
const view2 = new BrowserView();
|
||||||
|
defer(() => view2.webContents.destroy());
|
||||||
|
w.addBrowserView(view2);
|
||||||
|
defer(() => w.removeBrowserView(view2));
|
||||||
|
w.setTopBrowserView(view1);
|
||||||
|
|
||||||
|
const views = w.getBrowserViews();
|
||||||
|
expect(views).to.have.lengthOf(2);
|
||||||
|
expect(views[0].webContents.id).to.equal(view2.webContents.id);
|
||||||
|
expect(views[1].webContents.id).to.equal(view1.webContents.id);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('BrowserWindow.setTopBrowserView()', () => {
|
describe('BrowserWindow.setTopBrowserView()', () => {
|
||||||
|
|
Loading…
Reference in a new issue