From d1e0fc378712b209e36c4ea18391ae16cbc76aea Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Sun, 29 Jul 2018 20:35:26 +0200 Subject: [PATCH] feat: add activate option to webContents.openDevTools --- atom/browser/api/atom_api_web_contents.cc | 4 +++- brightray/browser/inspectable_web_contents.h | 2 +- .../browser/inspectable_web_contents_impl.cc | 13 ++++++----- .../browser/inspectable_web_contents_impl.h | 3 ++- .../browser/inspectable_web_contents_view.h | 4 ++-- .../inspectable_web_contents_view_mac.h | 4 ++-- .../inspectable_web_contents_view_mac.mm | 10 ++++----- .../mac/bry_inspectable_web_contents_view.h | 4 ++-- .../mac/bry_inspectable_web_contents_view.mm | 16 +++++++++----- .../inspectable_web_contents_view_views.cc | 12 ++++++---- .../inspectable_web_contents_view_views.h | 4 ++-- docs/api/web-contents.md | 2 ++ spec/api-web-contents-spec.js | 22 +++++++++++++++++++ 13 files changed, 69 insertions(+), 31 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 1fde7dc8d1aa4..c2e8fc6436d35 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1279,14 +1279,16 @@ void WebContents::OpenDevTools(mate::Arguments* args) { if (type_ == WEB_VIEW || !owner_window()) { state = "detach"; } + bool activate = true; if (args && args->Length() == 1) { mate::Dictionary options; if (args->GetNext(&options)) { options.Get("mode", &state); + options.Get("activate", &activate); } } managed_web_contents()->SetDockState(state); - managed_web_contents()->ShowDevTools(); + managed_web_contents()->ShowDevTools(activate); } void WebContents::CloseDevTools() { diff --git a/brightray/browser/inspectable_web_contents.h b/brightray/browser/inspectable_web_contents.h index 7b0a010b9e217..8d7d939730a35 100644 --- a/brightray/browser/inspectable_web_contents.h +++ b/brightray/browser/inspectable_web_contents.h @@ -39,7 +39,7 @@ class InspectableWebContents { virtual void SetDevToolsWebContents(content::WebContents* devtools) = 0; virtual void SetDockState(const std::string& state) = 0; - virtual void ShowDevTools() = 0; + virtual void ShowDevTools(bool activate) = 0; virtual void CloseDevTools() = 0; virtual bool IsDevToolsViewShowing() = 0; virtual void AttachTo(scoped_refptr) = 0; diff --git a/brightray/browser/inspectable_web_contents_impl.cc b/brightray/browser/inspectable_web_contents_impl.cc index 426df497c60bb..d0e73963bcce3 100644 --- a/brightray/browser/inspectable_web_contents_impl.cc +++ b/brightray/browser/inspectable_web_contents_impl.cc @@ -297,13 +297,15 @@ void InspectableWebContentsImpl::SetDevToolsWebContents( external_devtools_web_contents_ = devtools; } -void InspectableWebContentsImpl::ShowDevTools() { +void InspectableWebContentsImpl::ShowDevTools(bool activate) { if (embedder_message_dispatcher_) { if (managed_devtools_web_contents_) - view_->ShowDevTools(); + view_->ShowDevTools(activate); return; } + activate_ = activate; + // Show devtools only after it has done loading, this is to make sure the // SetIsDocked is called *BEFORE* ShowDevTools. embedder_message_dispatcher_.reset( @@ -412,8 +414,9 @@ void InspectableWebContentsImpl::CloseWindow() { void InspectableWebContentsImpl::LoadCompleted() { frontend_loaded_ = true; - if (managed_devtools_web_contents_) - view_->ShowDevTools(); + if (managed_devtools_web_contents_) { + view_->ShowDevTools(activate_); + } // If the devtools can dock, "SetIsDocked" will be called by devtools itself. if (!can_dock_) { @@ -483,7 +486,7 @@ void InspectableWebContentsImpl::LoadNetworkResource( void InspectableWebContentsImpl::SetIsDocked(const DispatchCallback& callback, bool docked) { if (managed_devtools_web_contents_) - view_->SetIsDocked(docked); + view_->SetIsDocked(docked, activate_); if (!callback.is_null()) callback.Run(nullptr); } diff --git a/brightray/browser/inspectable_web_contents_impl.h b/brightray/browser/inspectable_web_contents_impl.h index c75f46fed4270..30f2fbd02388a 100644 --- a/brightray/browser/inspectable_web_contents_impl.h +++ b/brightray/browser/inspectable_web_contents_impl.h @@ -50,7 +50,7 @@ class InspectableWebContentsImpl InspectableWebContentsDelegate* GetDelegate() const override; void SetDevToolsWebContents(content::WebContents* devtools) override; void SetDockState(const std::string& state) override; - void ShowDevTools() override; + void ShowDevTools(bool activate) override; void CloseDevTools() override; bool IsDevToolsViewShowing() override; void AttachTo(scoped_refptr) override; @@ -199,6 +199,7 @@ class InspectableWebContentsImpl gfx::Rect devtools_bounds_; bool can_dock_; std::string dock_state_; + bool activate_ = true; using PendingRequestsMap = std::map; PendingRequestsMap pending_requests_; diff --git a/brightray/browser/inspectable_web_contents_view.h b/brightray/browser/inspectable_web_contents_view.h index 0ec2dae4814f1..96dd6aedf583e 100644 --- a/brightray/browser/inspectable_web_contents_view.h +++ b/brightray/browser/inspectable_web_contents_view.h @@ -38,12 +38,12 @@ class InspectableWebContentsView { virtual gfx::NativeView GetNativeView() const = 0; #endif - virtual void ShowDevTools() = 0; + virtual void ShowDevTools(bool activate) = 0; // Hide the DevTools view. virtual void CloseDevTools() = 0; virtual bool IsDevToolsViewShowing() = 0; virtual bool IsDevToolsViewFocused() = 0; - virtual void SetIsDocked(bool docked) = 0; + virtual void SetIsDocked(bool docked, bool activate) = 0; virtual void SetContentsResizingStrategy( const DevToolsContentsResizingStrategy& strategy) = 0; virtual void SetTitle(const base::string16& title) = 0; diff --git a/brightray/browser/inspectable_web_contents_view_mac.h b/brightray/browser/inspectable_web_contents_view_mac.h index 40a140c7297f2..447e9aa4079d3 100644 --- a/brightray/browser/inspectable_web_contents_view_mac.h +++ b/brightray/browser/inspectable_web_contents_view_mac.h @@ -18,11 +18,11 @@ class InspectableWebContentsViewMac : public InspectableWebContentsView { ~InspectableWebContentsViewMac() override; gfx::NativeView GetNativeView() const override; - void ShowDevTools() override; + void ShowDevTools(bool activate) override; void CloseDevTools() override; bool IsDevToolsViewShowing() override; bool IsDevToolsViewFocused() override; - void SetIsDocked(bool docked) override; + void SetIsDocked(bool docked, bool activate) override; void SetContentsResizingStrategy( const DevToolsContentsResizingStrategy& strategy) override; void SetTitle(const base::string16& title) override; diff --git a/brightray/browser/inspectable_web_contents_view_mac.mm b/brightray/browser/inspectable_web_contents_view_mac.mm index ad41099241c5e..c1c819e851317 100644 --- a/brightray/browser/inspectable_web_contents_view_mac.mm +++ b/brightray/browser/inspectable_web_contents_view_mac.mm @@ -29,12 +29,12 @@ return view_.get(); } -void InspectableWebContentsViewMac::ShowDevTools() { - [view_ setDevToolsVisible:YES]; +void InspectableWebContentsViewMac::ShowDevTools(bool activate) { + [view_ setDevToolsVisible:YES activate:activate]; } void InspectableWebContentsViewMac::CloseDevTools() { - [view_ setDevToolsVisible:NO]; + [view_ setDevToolsVisible:NO activate:NO]; } bool InspectableWebContentsViewMac::IsDevToolsViewShowing() { @@ -45,8 +45,8 @@ return [view_ isDevToolsFocused]; } -void InspectableWebContentsViewMac::SetIsDocked(bool docked) { - [view_ setIsDocked:docked]; +void InspectableWebContentsViewMac::SetIsDocked(bool docked, bool activate) { + [view_ setIsDocked:docked activate:activate]; } void InspectableWebContentsViewMac::SetContentsResizingStrategy( diff --git a/brightray/browser/mac/bry_inspectable_web_contents_view.h b/brightray/browser/mac/bry_inspectable_web_contents_view.h index 2a99ff0e9f9f7..8b264ed0eaa7f 100644 --- a/brightray/browser/mac/bry_inspectable_web_contents_view.h +++ b/brightray/browser/mac/bry_inspectable_web_contents_view.h @@ -26,10 +26,10 @@ using brightray::InspectableWebContentsViewMac; (InspectableWebContentsViewMac*)view; - (void)removeObservers; - (void)notifyDevToolsFocused; -- (void)setDevToolsVisible:(BOOL)visible; +- (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate; - (BOOL)isDevToolsVisible; - (BOOL)isDevToolsFocused; -- (void)setIsDocked:(BOOL)docked; +- (void)setIsDocked:(BOOL)docked activate:(BOOL)activate; - (void)setContentsResizingStrategy: (const DevToolsContentsResizingStrategy&)strategy; - (void)setTitle:(NSString*)title; diff --git a/brightray/browser/mac/bry_inspectable_web_contents_view.mm b/brightray/browser/mac/bry_inspectable_web_contents_view.mm index b72a489ba7745..3c6e1963fafd8 100644 --- a/brightray/browser/mac/bry_inspectable_web_contents_view.mm +++ b/brightray/browser/mac/bry_inspectable_web_contents_view.mm @@ -53,7 +53,7 @@ - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize { } - (IBAction)showDevTools:(id)sender { - inspectableWebContentsView_->inspectable_web_contents()->ShowDevTools(); + inspectableWebContentsView_->inspectable_web_contents()->ShowDevTools(true); } - (void)notifyDevToolsFocused { @@ -61,7 +61,7 @@ - (void)notifyDevToolsFocused { inspectableWebContentsView_->GetDelegate()->DevToolsFocused(); } -- (void)setDevToolsVisible:(BOOL)visible { +- (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate { if (visible == devtools_visible_) return; @@ -96,7 +96,11 @@ - (void)setDevToolsVisible:(BOOL)visible { } } else { if (visible) { - [devtools_window_ makeKeyAndOrderFront:nil]; + if (activate) { + [devtools_window_ makeKeyAndOrderFront:nil]; + } else { + [devtools_window_ orderBack:nil]; + } } else { [devtools_window_ setDelegate:nil]; [devtools_window_ close]; @@ -117,9 +121,9 @@ - (BOOL)isDevToolsFocused { } } -- (void)setIsDocked:(BOOL)docked { +- (void)setIsDocked:(BOOL)docked activate:(BOOL)activate { // Revert to no-devtools state. - [self setDevToolsVisible:NO]; + [self setDevToolsVisible:NO activate:NO]; // Switch to new state. devtools_docked_ = docked; @@ -153,7 +157,7 @@ - (void)setIsDocked:(BOOL)docked { [contentView addSubview:devToolsView]; } - [self setDevToolsVisible:YES]; + [self setDevToolsVisible:YES activate:activate]; } - (void)setContentsResizingStrategy: diff --git a/brightray/browser/views/inspectable_web_contents_view_views.cc b/brightray/browser/views/inspectable_web_contents_view_views.cc index e95ffd05ee3c1..596d63aac2785 100644 --- a/brightray/browser/views/inspectable_web_contents_view_views.cc +++ b/brightray/browser/views/inspectable_web_contents_view_views.cc @@ -110,7 +110,7 @@ views::View* InspectableWebContentsViewViews::GetWebView() { return contents_web_view_; } -void InspectableWebContentsViewViews::ShowDevTools() { +void InspectableWebContentsViewViews::ShowDevTools(bool activate) { if (devtools_visible_) return; @@ -120,7 +120,11 @@ void InspectableWebContentsViewViews::ShowDevTools() { inspectable_web_contents_->GetDevToolsWebContents()); devtools_window_->SetBounds( inspectable_web_contents()->GetDevToolsBounds()); - devtools_window_->Show(); + if (activate) { + devtools_window_->Show(); + } else { + devtools_window_->ShowInactive(); + } } else { devtools_web_view_->SetVisible(true); devtools_web_view_->SetWebContents( @@ -161,7 +165,7 @@ bool InspectableWebContentsViewViews::IsDevToolsViewFocused() { return false; } -void InspectableWebContentsViewViews::SetIsDocked(bool docked) { +void InspectableWebContentsViewViews::SetIsDocked(bool docked, bool activate) { CloseDevTools(); if (!docked) { @@ -186,7 +190,7 @@ void InspectableWebContentsViewViews::SetIsDocked(bool docked) { devtools_window_->UpdateWindowIcon(); } - ShowDevTools(); + ShowDevTools(activate); } void InspectableWebContentsViewViews::SetContentsResizingStrategy( diff --git a/brightray/browser/views/inspectable_web_contents_view_views.h b/brightray/browser/views/inspectable_web_contents_view_views.h index 5b1dba91363fc..b2f619066f08f 100644 --- a/brightray/browser/views/inspectable_web_contents_view_views.h +++ b/brightray/browser/views/inspectable_web_contents_view_views.h @@ -26,11 +26,11 @@ class InspectableWebContentsViewViews : public InspectableWebContentsView, // InspectableWebContentsView: views::View* GetView() override; views::View* GetWebView() override; - void ShowDevTools() override; + void ShowDevTools(bool activate) override; void CloseDevTools() override; bool IsDevToolsViewShowing() override; bool IsDevToolsViewFocused() override; - void SetIsDocked(bool docked) override; + void SetIsDocked(bool docked, bool activate) override; void SetContentsResizingStrategy( const DevToolsContentsResizingStrategy& strategy) override; void SetTitle(const base::string16& title) override; diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 9d5acd284db41..411effb31c484 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -1182,6 +1182,8 @@ app.once('ready', () => { * `options` Object (optional) * `mode` String - Opens the devtools with specified dock state, can be `right`, `bottom`, `undocked`, `detach`. Defaults to last used dock state. + * `activate` Boolean (optional) - Whether to bring the opened devtools window to the + foreground. The default is `true`. In `undocked` mode it's possible to dock back. In `detach` mode it's not. Opens the devtools. diff --git a/spec/api-web-contents-spec.js b/spec/api-web-contents-spec.js index 0ec5196c1da7f..cf53fed125eec 100644 --- a/spec/api-web-contents-spec.js +++ b/spec/api-web-contents-spec.js @@ -147,6 +147,28 @@ describe('webContents module', () => { }) }) + describe('openDevTools() API', () => { + it('can show window with activation', (done) => { + w.show() + assert.equal(w.isFocused(), true) + w.webContents.openDevTools({ mode: 'detach', activate: true }) + w.webContents.once('devtools-opened', () => { + assert.equal(w.isFocused(), false) + done() + }) + }) + + it('can show window without activation', (done) => { + w.show() + assert.equal(w.isFocused(), true) + w.webContents.openDevTools({ mode: 'detach', activate: false }) + w.webContents.once('devtools-opened', () => { + assert.equal(w.isFocused(), true) + done() + }) + }) + }) + describe('before-input-event event', () => { it('can prevent document keyboard events', (done) => { w.loadURL(`file://${path.join(__dirname, 'fixtures', 'pages', 'key-events.html')}`)