diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 8761482bae..eac378b2a7 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -274,7 +274,7 @@ WebContents::WebContents(v8::Isolate* isolate, } Observe(web_contents); - InitWithWebContents(web_contents); + InitWithWebContents(web_contents, session->browser_context()); managed_web_contents()->GetView()->SetDelegate(this); @@ -379,7 +379,7 @@ void WebContents::MoveContents(content::WebContents* source, void WebContents::CloseContents(content::WebContents* source) { Emit("close"); - if (type_ == BROWSER_WINDOW) + if (type_ == BROWSER_WINDOW && owner_window()) owner_window()->CloseContents(source); } @@ -394,14 +394,12 @@ bool WebContents::IsPopupOrPanel(const content::WebContents* source) const { void WebContents::HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { - if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen()) { - // Escape exits tabbed fullscreen mode. - ExitFullscreenModeForTab(source); - } else if (type_ == BROWSER_WINDOW) { - owner_window()->HandleKeyboardEvent(source, event); - } else if (type_ == WEB_VIEW && guest_delegate_) { + if (type_ == WEB_VIEW && embedder_) { // Send the unhandled keyboard events back to the embedder. - guest_delegate_->HandleKeyboardEvent(source, event); + embedder_->HandleKeyboardEvent(source, event); + } else { + // Go to the default keyboard handling. + CommonWebContentsDelegate::HandleKeyboardEvent(source, event); } } @@ -430,13 +428,13 @@ void WebContents::ExitFullscreenModeForTab(content::WebContents* source) { void WebContents::RendererUnresponsive(content::WebContents* source) { Emit("unresponsive"); - if (type_ == BROWSER_WINDOW) + if (type_ == BROWSER_WINDOW && owner_window()) owner_window()->RendererUnresponsive(source); } void WebContents::RendererResponsive(content::WebContents* source) { Emit("responsive"); - if (type_ == BROWSER_WINDOW) + if (type_ == BROWSER_WINDOW && owner_window()) owner_window()->RendererResponsive(source); } @@ -866,7 +864,7 @@ void WebContents::OpenDevTools(mate::Arguments* args) { return; std::string state; - if (type_ == WEB_VIEW) { + if (type_ == WEB_VIEW || !owner_window()) { state = "detach"; } else if (args && args->Length() == 1) { bool detach = false; @@ -1174,6 +1172,10 @@ v8::Local WebContents::GetOwnerBrowserWindow() { return v8::Null(isolate()); } +int32_t WebContents::ID() const { + return weak_map_id(); +} + v8::Local WebContents::Session(v8::Isolate* isolate) { return v8::Local::New(isolate, session_); } @@ -1266,6 +1268,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("_printToPDF", &WebContents::PrintToPDF) .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) + .SetProperty("id", &WebContents::ID) .SetProperty("session", &WebContents::Session) .SetProperty("hostWebContents", &WebContents::HostWebContents) .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 9deb1696c4..81d97dfdde 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -154,6 +154,7 @@ class WebContents : public mate::TrackableObject, v8::Local GetOwnerBrowserWindow(); // Properties. + int32_t ID() const; v8::Local Session(v8::Isolate* isolate); content::WebContents* HostWebContents(); v8::Local DevToolsWebContents(v8::Isolate* isolate); diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index 2093b8f489..ea2bf8677c 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -31,14 +31,6 @@ #include "content/public/browser/security_style_explanations.h" #include "storage/browser/fileapi/isolated_context.h" -#if defined(TOOLKIT_VIEWS) -#include "atom/browser/native_window_views.h" -#endif - -#if defined(USE_X11) -#include "atom/browser/browser.h" -#endif - using content::BrowserThread; using security_state::SecurityStateModel; @@ -182,7 +174,9 @@ CommonWebContentsDelegate::~CommonWebContentsDelegate() { } void CommonWebContentsDelegate::InitWithWebContents( - content::WebContents* web_contents) { + content::WebContents* web_contents, + AtomBrowserContext* browser_context) { + browser_context_ = browser_context; web_contents->SetDelegate(this); printing::PrintViewManagerBasic::CreateForWebContents(web_contents); @@ -628,23 +622,6 @@ void CommonWebContentsDelegate::OnDevToolsSearchCompleted( &file_paths_value); } -#if defined(TOOLKIT_VIEWS) -gfx::ImageSkia CommonWebContentsDelegate::GetDevToolsWindowIcon() { - if (!owner_window()) - return gfx::ImageSkia(); - return static_cast(static_cast( - owner_window()))->GetWindowAppIcon(); -} -#endif - -#if defined(USE_X11) -void CommonWebContentsDelegate::GetDevToolsWindowWMClass( - std::string* name, std::string* class_name) { - *class_name = Browser::Get()->GetName(); - *name = base::ToLowerASCII(*class_name); -} -#endif - void CommonWebContentsDelegate::SetHtmlApiFullscreen(bool enter_fullscreen) { // Window is already in fullscreen mode, save the state. if (enter_fullscreen && owner_window_->IsFullscreen()) { diff --git a/atom/browser/common_web_contents_delegate.h b/atom/browser/common_web_contents_delegate.h index dbd5ddeebd..095dad3bce 100644 --- a/atom/browser/common_web_contents_delegate.h +++ b/atom/browser/common_web_contents_delegate.h @@ -19,6 +19,7 @@ using brightray::DevToolsFileSystemIndexer; namespace atom { +class AtomBrowserContext; class AtomJavaScriptDialogManager; class NativeWindow; class WebDialogHelper; @@ -33,7 +34,8 @@ class CommonWebContentsDelegate // Creates a InspectableWebContents object and takes onwership of // |web_contents|. - void InitWithWebContents(content::WebContents* web_contents); + void InitWithWebContents(content::WebContents* web_contents, + AtomBrowserContext* browser_context); // Set the window as owner window. void SetOwnerWindow(NativeWindow* owner_window); @@ -82,6 +84,9 @@ class CommonWebContentsDelegate content::SecurityStyle GetSecurityStyle( content::WebContents* web_contents, content::SecurityStyleExplanations* explanations) override; + void HandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) override; // brightray::InspectableWebContentsDelegate: void DevToolsSaveToFile(const std::string& url, @@ -145,6 +150,9 @@ class CommonWebContentsDelegate scoped_ptr dialog_manager_; scoped_refptr devtools_file_system_indexer_; + // Make sure BrowserContext is alwasys destroyed after WebContents. + scoped_refptr browser_context_; + // The stored InspectableWebContents object. // Notice that web_contents_ must be placed after dialog_manager_, so we can // make sure web_contents_ is destroyed before dialog_manager_, otherwise a diff --git a/atom/browser/common_web_contents_delegate_mac.mm b/atom/browser/common_web_contents_delegate_mac.mm new file mode 100644 index 0000000000..69117f1905 --- /dev/null +++ b/atom/browser/common_web_contents_delegate_mac.mm @@ -0,0 +1,39 @@ +// Copyright (c) 2016 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/common_web_contents_delegate.h" + +#import + +#include "content/public/browser/native_web_keyboard_event.h" +#include "ui/events/keycodes/keyboard_codes.h" + +namespace atom { + +void CommonWebContentsDelegate::HandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) { + if (event.skip_in_browser || + event.type == content::NativeWebKeyboardEvent::Char) + return; + + // Escape exits tabbed fullscreen mode. + if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen()) + ExitFullscreenModeForTab(source); + + BOOL handled = [[NSApp mainMenu] performKeyEquivalent:event.os_event]; + if (!handled && event.os_event.window) { + // Handle the cmd+~ shortcut. + if ((event.os_event.modifierFlags & NSCommandKeyMask) /* cmd */ && + (event.os_event.keyCode == 50 /* ~ */)) { + if (event.os_event.modifierFlags & NSShiftKeyMask) { + [NSApp sendAction:@selector(_cycleWindowsReversed:) to:nil from:nil]; + } else { + [NSApp sendAction:@selector(_cycleWindows:) to:nil from:nil]; + } + } + } +} + +} // namespace atom diff --git a/atom/browser/common_web_contents_delegate_views.cc b/atom/browser/common_web_contents_delegate_views.cc new file mode 100644 index 0000000000..d70884c45c --- /dev/null +++ b/atom/browser/common_web_contents_delegate_views.cc @@ -0,0 +1,45 @@ +// Copyright (c) 2016 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/common_web_contents_delegate.h" + +#include "atom/browser/native_window_views.h" +#include "base/strings/string_util.h" +#include "content/public/browser/native_web_keyboard_event.h" +#include "ui/events/keycodes/keyboard_codes.h" + +#if defined(USE_X11) +#include "atom/browser/browser.h" +#endif + +namespace atom { + +void CommonWebContentsDelegate::HandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) { + // Escape exits tabbed fullscreen mode. + if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen()) + ExitFullscreenModeForTab(source); + + // Let the NativeWindow handle other parts. + if (owner_window()) + owner_window()->HandleKeyboardEvent(source, event); +} + +gfx::ImageSkia CommonWebContentsDelegate::GetDevToolsWindowIcon() { + if (!owner_window()) + return gfx::ImageSkia(); + return static_cast(static_cast( + owner_window()))->GetWindowAppIcon(); +} + +#if defined(USE_X11) +void CommonWebContentsDelegate::GetDevToolsWindowWMClass( + std::string* name, std::string* class_name) { + *class_name = Browser::Get()->GetName(); + *name = base::ToLowerASCII(*class_name); +} +#endif + +} // namespace atom diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 22390f42dd..cfb3141ede 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -100,11 +100,6 @@ class NativeWindowMac : public NativeWindow { } protected: - // NativeWindow: - void HandleKeyboardEvent( - content::WebContents*, - const content::NativeWebKeyboardEvent&) override; - // Return a vector of non-draggable regions that fill a window of size // |width| by |height|, but leave gaps where the window should be draggable. std::vector CalculateNonDraggableRegions( diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 0f782d5851..bfffc7a08d 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -15,7 +15,6 @@ #include "brightray/browser/inspectable_web_contents.h" #include "brightray/browser/inspectable_web_contents_view.h" #include "content/public/browser/browser_accessibility_state.h" -#include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" @@ -935,27 +934,6 @@ bool NativeWindowMac::IsVisibleOnAllWorkspaces() { return collectionBehavior & NSWindowCollectionBehaviorCanJoinAllSpaces; } -void NativeWindowMac::HandleKeyboardEvent( - content::WebContents*, - const content::NativeWebKeyboardEvent& event) { - if (event.skip_in_browser || - event.type == content::NativeWebKeyboardEvent::Char) - return; - - BOOL handled = [[NSApp mainMenu] performKeyEquivalent:event.os_event]; - if (!handled && event.os_event.window) { - // Handle the cmd+~ shortcut. - if ((event.os_event.modifierFlags & NSCommandKeyMask) /* cmd */ && - (event.os_event.keyCode == 50 /* ~ */)) { - if (event.os_event.modifierFlags & NSShiftKeyMask) { - [NSApp sendAction:@selector(_cycleWindowsReversed:) to:nil from:nil]; - } else { - [NSApp sendAction:@selector(_cycleWindows:) to:nil from:nil]; - } - } - } -} - std::vector NativeWindowMac::CalculateNonDraggableRegions( const std::vector& regions, int width, int height) { std::vector result; diff --git a/atom/browser/web_view_guest_delegate.cc b/atom/browser/web_view_guest_delegate.cc index 6abb9713bf..11f8219bf0 100644 --- a/atom/browser/web_view_guest_delegate.cc +++ b/atom/browser/web_view_guest_delegate.cc @@ -95,13 +95,6 @@ void WebViewGuestDelegate::SetSize(const SetSizeParams& params) { auto_size_enabled_ = enable_auto_size; } -void WebViewGuestDelegate::HandleKeyboardEvent( - content::WebContents* source, - const content::NativeWebKeyboardEvent& event) { - if (embedder_web_contents_) - embedder_web_contents_->GetDelegate()->HandleKeyboardEvent(source, event); -} - void WebViewGuestDelegate::DidCommitProvisionalLoadForFrame( content::RenderFrameHost* render_frame_host, const GURL& url, ui::PageTransition transition_type) { diff --git a/atom/browser/web_view_guest_delegate.h b/atom/browser/web_view_guest_delegate.h index 95888ff749..3dae1a1749 100644 --- a/atom/browser/web_view_guest_delegate.h +++ b/atom/browser/web_view_guest_delegate.h @@ -8,10 +8,6 @@ #include "content/public/browser/browser_plugin_guest_delegate.h" #include "content/public/browser/web_contents_observer.h" -namespace content { -struct NativeWebKeyboardEvent; -} - namespace atom { namespace api { @@ -49,10 +45,6 @@ class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate, // and normal sizes. void SetSize(const SetSizeParams& params); - // Transfer the keyboard event to embedder. - void HandleKeyboardEvent(content::WebContents* source, - const content::NativeWebKeyboardEvent& event); - protected: // content::WebContentsObserver: void DidCommitProvisionalLoadForFrame( diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 7d42b8a48a..d0716305ab 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -913,6 +913,10 @@ win.webContents.on('did-finish-load', () => { `WebContents` objects also have the following properties: +### `webContents.id` + +The unique ID of this WebContents. + ### `webContents.session` Returns the [session](session.md) object used by this webContents. diff --git a/filenames.gypi b/filenames.gypi index f9bbe8f75f..cc33d9a81a 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -171,6 +171,8 @@ 'atom/browser/browser_mac.mm', 'atom/browser/browser_win.cc', 'atom/browser/browser_observer.h', + 'atom/browser/common_web_contents_delegate_mac.mm', + 'atom/browser/common_web_contents_delegate_views.cc', 'atom/browser/common_web_contents_delegate.cc', 'atom/browser/common_web_contents_delegate.h', 'atom/browser/javascript_environment.cc', diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index 01d777e852..617a1fe81a 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -250,16 +250,13 @@ ipcRenderer.on('ELECTRON_RENDERER_RELEASE_CALLBACK', function (event, id) { const browserModules = require('../../browser/api/exports/electron') // And add a helper receiver for each one. -var fn = function (name) { - return Object.defineProperty(exports, name, { +for (let name of Object.getOwnPropertyNames(browserModules)) { + Object.defineProperty(exports, name, { get: function () { return exports.getBuiltin(name) } }) } -for (var name in browserModules) { - fn(name) -} // Get remote module. exports.require = function (module) {