From: Cheng Zhao Date: Thu, 25 Jun 2015 03:07:23 +0000 (+0800) Subject: Decouple WebContentsDelegate from NativeWindow X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fb5fe7a7140837c63631f2fde46bcc2690017f79;p=platform%2Fframework%2Fweb%2Fcrosswalk-tizen.git Decouple WebContentsDelegate from NativeWindow --- diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index a7877fa..dd05988 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -142,12 +142,6 @@ content::ServiceWorkerContext* GetServiceWorkerContext( } // namespace -WebContents::WebContents(brightray::InspectableWebContents* web_contents) - : WebContents(web_contents->GetWebContents()) { - type_ = BROWSER_WINDOW; - inspectable_web_contents_ = web_contents; -} - WebContents::WebContents(content::WebContents* web_contents) : content::WebContentsObserver(web_contents), guest_opaque_(true), @@ -210,8 +204,12 @@ bool WebContents::AddMessageToConsole(content::WebContents* source, const base::string16& message, int32 line_no, const base::string16& source_id) { - Emit("console-message", level, message, line_no, source_id); - return true; + if (type_ == BROWSER_WINDOW) { + return false; + } else { + Emit("console-message", level, message, line_no, source_id); + return true; + } } bool WebContents::ShouldCreateWebContents( @@ -223,19 +221,21 @@ bool WebContents::ShouldCreateWebContents( const GURL& target_url, const std::string& partition_id, content::SessionStorageNamespace* session_storage_namespace) { - Emit("new-window", target_url, frame_name, NEW_FOREGROUND_TAB); + if (type_ == BROWSER_WINDOW) + Emit("-new-window", target_url, frame_name, NEW_FOREGROUND_TAB); + else + Emit("new-window", target_url, frame_name, NEW_FOREGROUND_TAB); return false; } -void WebContents::CloseContents(content::WebContents* source) { - Emit("close"); -} - content::WebContents* WebContents::OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params) { if (params.disposition != CURRENT_TAB) { - Emit("new-window", params.url, "", params.disposition); + if (type_ == BROWSER_WINDOW) + Emit("-new-window", params.url, "", params.disposition); + else + Emit("new-window", params.url, "", params.disposition); return nullptr; } @@ -246,6 +246,31 @@ content::WebContents* WebContents::OpenURLFromTab( return CommonWebContentsDelegate::OpenURLFromTab(source, params); } +void WebContents::BeforeUnloadFired(content::WebContents* tab, + bool proceed, + bool* proceed_to_fire_unload) { + if (type_ == BROWSER_WINDOW) + *proceed_to_fire_unload = proceed; + else + *proceed_to_fire_unload = true; +} + +void WebContents::MoveContents(content::WebContents* source, + const gfx::Rect& pos) { + Emit("move", pos); +} + +void WebContents::CloseContents(content::WebContents* source) { + Emit("closed"); + if (type_ == BROWSER_WINDOW) + owner_window()->CloseContents(source); +} + +void WebContents::ActivateContents(content::WebContents* source) { + if (type_ == BROWSER_WINDOW) + owner_window()->CloseContents(source); +} + bool WebContents::IsPopupOrPanel(const content::WebContents* source) const { return type_ == BROWSER_WINDOW; } @@ -253,12 +278,12 @@ bool WebContents::IsPopupOrPanel(const content::WebContents* source) const { void WebContents::HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { - if (!attached()) - return; - - // Send the unhandled keyboard events back to the embedder to reprocess them. - embedder_web_contents_->GetDelegate()->HandleKeyboardEvent( - web_contents(), event); + if (type_ == BROWSER_WINDOW) { + owner_window()->HandleKeyboardEvent(source, event); + } else if (type_ == WEB_VIEW && !attached()) { + // Send the unhandled keyboard events back to the embedder. + embedder_web_contents_->GetDelegate()->HandleKeyboardEvent(source, event); + } } void WebContents::EnterFullscreenModeForTab(content::WebContents* source, @@ -272,6 +297,23 @@ void WebContents::ExitFullscreenModeForTab(content::WebContents* source) { Emit("leave-html-full-screen"); } +void WebContents::RendererUnresponsive(content::WebContents* source) { + Emit("unresponsive"); + if (type_ == BROWSER_WINDOW) + owner_window()->RendererUnresponsive(source); +} + +void WebContents::RendererResponsive(content::WebContents* source) { + Emit("responsive"); + if (type_ == BROWSER_WINDOW) + owner_window()->RendererResponsive(source); +} + +void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) { + // Do nothing, we override this method just to avoid compilation error since + // there are two virtual functions named BeforeUnloadFired. +} + void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) { int process_id = render_view_host->GetProcess()->GetID(); Emit("render-view-deleted", process_id); @@ -900,21 +942,6 @@ gfx::Size WebContents::GetDefaultSize() const { // static mate::Handle WebContents::CreateFrom( - v8::Isolate* isolate, brightray::InspectableWebContents* web_contents) { - // We have an existing WebContents object in JS. - auto existing = TrackableObject::FromWrappedClass( - isolate, web_contents->GetWebContents()); - if (existing) - return mate::CreateHandle(isolate, static_cast(existing)); - - // Otherwise create a new WebContents wrapper object. - auto handle = mate::CreateHandle(isolate, new WebContents(web_contents)); - g_wrap_web_contents.Run(handle.ToV8()); - return handle; -} - -// static -mate::Handle WebContents::CreateFrom( v8::Isolate* isolate, content::WebContents* web_contents) { // We have an existing WebContents object in JS. auto existing = TrackableObject::FromWrappedClass(isolate, web_contents); diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index be874d9..55f0877 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -58,8 +58,6 @@ class WebContents : public mate::TrackableObject, // Create from an existing WebContents. static mate::Handle CreateFrom( - v8::Isolate* isolate, brightray::InspectableWebContents* web_contents); - static mate::Handle CreateFrom( v8::Isolate* isolate, content::WebContents* web_contents); // Create a new WebContents. @@ -136,7 +134,6 @@ class WebContents : public mate::TrackableObject, } protected: - explicit WebContents(brightray::InspectableWebContents* web_contents); explicit WebContents(content::WebContents* web_contents); explicit WebContents(const mate::Dictionary& options); ~WebContents(); @@ -160,10 +157,16 @@ class WebContents : public mate::TrackableObject, const GURL& target_url, const std::string& partition_id, content::SessionStorageNamespace* session_storage_namespace) override; - void CloseContents(content::WebContents* source) override; content::WebContents* OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params) override; + void BeforeUnloadFired(content::WebContents* tab, + bool proceed, + bool* proceed_to_fire_unload) override; + void MoveContents(content::WebContents* source, + const gfx::Rect& pos) override; + void CloseContents(content::WebContents* source) override; + void ActivateContents(content::WebContents* contents) override; bool IsPopupOrPanel(const content::WebContents* source) const override; void HandleKeyboardEvent( content::WebContents* source, @@ -171,8 +174,11 @@ class WebContents : public mate::TrackableObject, void EnterFullscreenModeForTab(content::WebContents* source, const GURL& origin) override; void ExitFullscreenModeForTab(content::WebContents* source) override; + void RendererUnresponsive(content::WebContents* source) override; + void RendererResponsive(content::WebContents* source) override; // content::WebContentsObserver: + void BeforeUnloadFired(const base::TimeTicks& proceed_time) override; void RenderViewDeleted(content::RenderViewHost*) override; void RenderProcessGone(base::TerminationStatus status) override; void DocumentLoadedInFrame( diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 9869e36..2dae7f8 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -43,6 +43,7 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) { mate::Dictionary web_contents_options(isolate, v8::Object::New(isolate)); auto web_contents = WebContents::Create(isolate, web_contents_options); web_contents_.Reset(isolate, web_contents.ToV8()); + api_web_contents_ = web_contents.get(); // Creates BrowserWindow. window_.reset(NativeWindow::Create(web_contents->managed_web_contents(), @@ -62,17 +63,6 @@ void Window::OnPageTitleUpdated(bool* prevent_default, *prevent_default = Emit("page-title-updated", title); } -void Window::WillCreatePopupWindow(const base::string16& frame_name, - const GURL& target_url, - const std::string& partition_id, - WindowOpenDisposition disposition) { - Emit("-new-window", target_url, frame_name); -} - -void Window::WillNavigate(bool* prevent_default, const GURL& url) { - *prevent_default = Emit("-will-navigate", url); -} - void Window::WillCloseWindow(bool* prevent_default) { *prevent_default = Emit("close"); } @@ -80,6 +70,12 @@ void Window::WillCloseWindow(bool* prevent_default) { void Window::OnWindowClosed() { Emit("closed"); + if (api_web_contents_) { + api_web_contents_->DestroyWebContents(); + api_web_contents_ = nullptr; + web_contents_.Reset(); + } + RemoveFromWeakMap(); window_->RemoveObserver(this); } @@ -153,8 +149,8 @@ void Window::OnDevToolsOpened() { v8::Locker locker(isolate()); v8::HandleScope handle_scope(isolate()); - auto handle = WebContents::CreateFrom(isolate(), - window_->GetDevToolsWebContents()); + auto handle = WebContents::CreateFrom( + isolate(), api_web_contents_->GetDevToolsWebContents()); devtools_web_contents_.Reset(isolate(), handle.ToV8()); } @@ -178,8 +174,7 @@ mate::Wrappable* Window::New(v8::Isolate* isolate, } void Window::Destroy() { - window_->DestroyWebContents(); - window_->CloseImmediately(); + window_->CloseContents(nullptr); } void Window::Close() { diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index f6c99eb..41383ea 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -51,11 +51,6 @@ class Window : public mate::TrackableObject, // NativeWindowObserver: void OnPageTitleUpdated(bool* prevent_default, const std::string& title) override; - void WillCreatePopupWindow(const base::string16& frame_name, - const GURL& target_url, - const std::string& partition_id, - WindowOpenDisposition disposition) override; - void WillNavigate(bool* prevent_default, const GURL& url) override; void WillCloseWindow(bool* prevent_default) override; void OnWindowClosed() override; void OnWindowBlur() override; @@ -151,6 +146,8 @@ class Window : public mate::TrackableObject, v8::Global devtools_web_contents_; v8::Global menu_; + api::WebContents* api_web_contents_; + scoped_ptr window_; DISALLOW_COPY_AND_ASSIGN(Window); diff --git a/atom/browser/api/lib/browser-window.coffee b/atom/browser/api/lib/browser-window.coffee index 66e0670..24ae7b8 100644 --- a/atom/browser/api/lib/browser-window.coffee +++ b/atom/browser/api/lib/browser-window.coffee @@ -12,14 +12,13 @@ BrowserWindow::_init = -> @setMenu menu if menu? # Make new windows requested by links behave like "window.open" - @on '-new-window', (event, url, frameName) => - event.sender = @webContents + @webContents.on '-new-window', (event, url, frameName) -> options = show: true, width: 800, height: 600 ipc.emit 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options - # Redirect "will-navigate" to webContents. - @on '-will-navigate', (event, url) => - @webContents.emit 'will-navigate', event, url + # window.move(...) + @webContents.on 'move', (event, size) => + @setSize size # Redirect focus/blur event to app instance too. @on 'blur', (event) => diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index fc32ee7..8748388 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -94,6 +94,7 @@ NativeWindow::NativeWindow( node_integration_(true), has_dialog_attached_(false), zoom_factor_(1.0), + inspectable_web_contents_(inspectable_web_contents), weak_factory_(this) { options.Get(switches::kFrame, &has_frame_); options.Get(switches::kTransparent, &transparent_); @@ -341,6 +342,13 @@ void NativeWindow::CloseWebContents() { web_contents->Close(); } +content::WebContents* NativeWindow::GetWebContents() const { + if (inspectable_web_contents_) + return inspectable_web_contents_->GetWebContents(); + else + return nullptr; +} + void NativeWindow::AppendExtraCommandLineSwitches( base::CommandLine* command_line) { // Append --node-integration to renderer process. @@ -475,52 +483,6 @@ void NativeWindow::NotifyWindowLeaveHtmlFullScreen() { OnWindowLeaveHtmlFullScreen()); } -bool NativeWindow::ShouldCreateWebContents( - content::WebContents* web_contents, - int route_id, - int main_frame_route_id, - WindowContainerType window_container_type, - const base::string16& frame_name, - const GURL& target_url, - const std::string& partition_id, - content::SessionStorageNamespace* session_storage_namespace) { - FOR_EACH_OBSERVER(NativeWindowObserver, - observers_, - WillCreatePopupWindow(frame_name, - target_url, - partition_id, - NEW_FOREGROUND_TAB)); - return false; -} - -// In atom-shell all reloads and navigations started by renderer process would -// be redirected to this method, so we can have precise control of how we -// would open the url (in our case, is to restart the renderer process). See -// AtomRendererClient::ShouldFork for how this is done. -content::WebContents* NativeWindow::OpenURLFromTab( - content::WebContents* source, - const content::OpenURLParams& params) { - if (params.disposition != CURRENT_TAB) { - FOR_EACH_OBSERVER(NativeWindowObserver, - observers_, - WillCreatePopupWindow(base::string16(), - params.url, - "", - params.disposition)); - return nullptr; - } - - // Give user a chance to prevent navigation. - bool prevent_default = false; - FOR_EACH_OBSERVER(NativeWindowObserver, - observers_, - WillNavigate(&prevent_default, params.url)); - if (prevent_default) - return nullptr; - - return CommonWebContentsDelegate::OpenURLFromTab(source, params); -} - void NativeWindow::RenderViewCreated( content::RenderViewHost* render_view_host) { if (!transparent_) @@ -533,20 +495,8 @@ void NativeWindow::RenderViewCreated( impl->SetBackgroundOpaque(false); } -void NativeWindow::BeforeUnloadFired(content::WebContents* tab, - bool proceed, - bool* proceed_to_fire_unload) { - *proceed_to_fire_unload = proceed; -} - -void NativeWindow::MoveContents(content::WebContents* source, - const gfx::Rect& pos) { - SetBounds(pos); -} - void NativeWindow::CloseContents(content::WebContents* source) { - // Destroy the WebContents before we close the window. - DestroyWebContents(); + inspectable_web_contents_ = nullptr; // When the web contents is gone, close the window immediately, but the // memory will not be freed until you call delete. @@ -575,11 +525,6 @@ void NativeWindow::RendererResponsive(content::WebContents* source) { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererResponsive()); } -void NativeWindow::BeforeUnloadFired(const base::TimeTicks& proceed_time) { - // Do nothing, we override this method just to avoid compilation error since - // there are two virtual functions named BeforeUnloadFired. -} - void NativeWindow::BeforeUnloadDialogCancelled() { WindowList::WindowCloseCancelled(this); @@ -609,18 +554,6 @@ bool NativeWindow::OnMessageReceived(const IPC::Message& message) { return handled; } -void NativeWindow::DevToolsFocused() { - FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsFocus()); -} - -void NativeWindow::DevToolsOpened() { - FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsOpened()); -} - -void NativeWindow::DevToolsClosed() { - FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsClosed()); -} - void NativeWindow::ScheduleUnresponsiveEvent(int ms) { if (!window_unresposive_closure_.IsCancelled()) return; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 0f06145..8fe5143 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -9,7 +9,6 @@ #include #include -#include "atom/browser/common_web_contents_delegate.h" #include "atom/browser/native_window_observer.h" #include "atom/browser/ui/accelerator_util.h" #include "base/cancelable_callback.h" @@ -17,17 +16,22 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "content/public/browser/readback_types.h" +#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" #include "native_mate/persistent_dictionary.h" #include "ui/gfx/image/image.h" +#include "ui/gfx/image/image_skia.h" namespace base { class CommandLine; } +namespace brightray { +class InspectableWebContents; +} + namespace content { -class BrowserContext; -class WebContents; +struct NativeWebKeyboardEvent; struct WebPreferences; } @@ -49,8 +53,7 @@ namespace atom { struct DraggableRegion; -class NativeWindow : public CommonWebContentsDelegate, - public content::WebContentsObserver { +class NativeWindow : public content::WebContentsObserver { public: typedef base::Callback CapturePageCallback; @@ -167,6 +170,17 @@ class NativeWindow : public CommonWebContentsDelegate, return weak_factory_.GetWeakPtr(); } + content::WebContents* GetWebContents() const; + + // Methods called by the WebContents. + virtual void CloseContents(content::WebContents* source); + virtual void RendererUnresponsive(content::WebContents* source); + virtual void RendererResponsive(content::WebContents* source); + virtual void ActivateContents(content::WebContents* contents) {} + virtual void HandleKeyboardEvent( + content::WebContents*, + const content::NativeWebKeyboardEvent& event) {} + // Called when renderer process is going to be started. void AppendExtraCommandLineSwitches(base::CommandLine* command_line); void OverrideWebkitPrefs(content::WebPreferences* prefs); @@ -214,40 +228,12 @@ class NativeWindow : public CommonWebContentsDelegate, virtual void UpdateDraggableRegions( const std::vector& regions) = 0; - // Implementations of content::WebContentsDelegate. - bool ShouldCreateWebContents( - content::WebContents* web_contents, - int route_id, - int main_frame_route_id, - WindowContainerType window_container_type, - const base::string16& frame_name, - const GURL& target_url, - const std::string& partition_id, - content::SessionStorageNamespace* session_storage_namespace) override; - content::WebContents* OpenURLFromTab( - content::WebContents* source, - const content::OpenURLParams& params) override; - void BeforeUnloadFired(content::WebContents* tab, - bool proceed, - bool* proceed_to_fire_unload) override; - void MoveContents(content::WebContents* source, - const gfx::Rect& pos) override; - void CloseContents(content::WebContents* source) override; - void RendererUnresponsive(content::WebContents* source) override; - void RendererResponsive(content::WebContents* source) override; - // Implementations of content::WebContentsObserver. void RenderViewCreated(content::RenderViewHost* render_view_host) override; - void BeforeUnloadFired(const base::TimeTicks& proceed_time) override; void BeforeUnloadDialogCancelled() override; void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override; bool OnMessageReceived(const IPC::Message& message) override; - // Implementations of brightray::InspectableWebContentsDelegate. - void DevToolsFocused() override; - void DevToolsOpened() override; - void DevToolsClosed() override; - // Whether window has standard frame. bool has_frame_; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 7f9272b..67f4389 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -27,7 +27,7 @@ class NativeWindowMac : public NativeWindow { const mate::Dictionary& options); ~NativeWindowMac() override; - // NativeWindow implementation. + // NativeWindow: void Close() override; void CloseImmediately() override; void Focus(bool focus) override; @@ -91,7 +91,7 @@ class NativeWindowMac : public NativeWindow { void UpdateDraggableRegions( const std::vector& regions) override; - // Implementations of content::WebContentsDelegate. + // NativeWindow: void HandleKeyboardEvent( content::WebContents*, const content::NativeWebKeyboardEvent&) override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 093b183..5c17ee3 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -386,9 +386,7 @@ NativeWindowMac::NativeWindowMac( } NativeWindowMac::~NativeWindowMac() { - // Force InspectableWebContents to be destroyed before we destroy window, - // because it may still be observing the window at this time. - DestroyWebContents(); + Observe(nullptr); } void NativeWindowMac::Close() { diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 6211225..c446d53 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -127,7 +127,7 @@ class NativeWindowViews : public NativeWindow, std::string* name, std::string* class_name) override; #endif - // content::WebContentsDelegate: + // NativeWindow: void ActivateContents(content::WebContents* contents) override; void HandleKeyboardEvent( content::WebContents*,