Chromium Code Reviews| Index: chrome/browser/devtools/devtools_window.cc |
| diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc |
| index 29e22ba82ab416d19f54e60c91244ca70bd66afe..a2bbe20027fd6c628ad4a4c4d824d53f0ea8c48f 100644 |
| --- a/chrome/browser/devtools/devtools_window.cc |
| +++ b/chrome/browser/devtools/devtools_window.cc |
| @@ -204,11 +204,37 @@ DevToolsWindow::InspectedWebContentsObserver::InspectedWebContentsObserver( |
| DevToolsWindow::InspectedWebContentsObserver::~InspectedWebContentsObserver() { |
| } |
| +class DevToolsToolboxDelegate |
| + : public content::WebContentsObserver, |
| + public content::WebContentsDelegate { |
| + public: |
| + explicit DevToolsToolboxDelegate(WebContents* web_contents) |
| + : WebContentsObserver(web_contents) { } |
| + virtual ~DevToolsToolboxDelegate() { } |
| + |
| + virtual content::WebContents* OpenURLFromTab( |
| + content::WebContents* source, |
| + const content::OpenURLParams& params) OVERRIDE { |
| + DCHECK(source == web_contents()); |
| + if (!params.url.SchemeIs(content::kChromeDevToolsScheme)) |
| + return NULL; |
| + content::NavigationController::LoadURLParams load_url_params(params.url); |
| + source->GetController().LoadURLWithParams(load_url_params); |
| + return source; |
| + } |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(DevToolsToolboxDelegate); |
| +}; |
| + |
| // DevToolsWindow ------------------------------------------------------------- |
| const char DevToolsWindow::kDevToolsApp[] = "DevToolsApp"; |
| DevToolsWindow::~DevToolsWindow() { |
| + if (toolbox_web_contents_) |
| + delete toolbox_web_contents_; |
| + UpdateBrowserWindow(); |
| UpdateBrowserToolbar(); |
| DevToolsWindows* instances = g_instances.Pointer(); |
| @@ -259,17 +285,30 @@ void DevToolsWindow::RegisterProfilePrefs( |
| } |
| // static |
| -DevToolsWindow* DevToolsWindow::GetDockedInstanceForInspectedTab( |
| - WebContents* inspected_web_contents) { |
| - DevToolsWindow* window = GetInstanceForInspectedRenderViewHost( |
| - inspected_web_contents->GetRenderViewHost()); |
| +content::WebContents* DevToolsWindow::GetWebContentsToShowForInspectedTab( |
| + WebContents* inspected_web_contents, |
| + DevToolsContentsResizingStrategy* out_strategy) { |
| + DevToolsWindow* window = GetInstanceForInspectedWebContents( |
| + inspected_web_contents); |
| if (!window) |
| return NULL; |
| + |
| // Not yet loaded window is treated as docked, but we should not present it |
| // until we decided on docking. |
| bool is_docked_set = window->load_state_ == kLoadCompleted || |
| window->load_state_ == kIsDockedSet; |
| - return window->is_docked_ && is_docked_set ? window : NULL; |
| + if (!is_docked_set) |
| + return NULL; |
| + |
| + // Undocked window should have toolbox web contents. |
| + if (!window->is_docked_ && !window->toolbox_web_contents_) |
| + return NULL; |
| + |
| + if (out_strategy) |
| + out_strategy->CopyFrom(window->contents_resizing_strategy_); |
| + |
| + return window->is_docked_ ? window->main_web_contents_ : |
| + window->toolbox_web_contents_; |
| } |
| // static |
| @@ -432,16 +471,6 @@ void DevToolsWindow::InspectElement(content::RenderViewHost* inspected_rvh, |
| window->inspect_element_start_time_ = start_time; |
| } |
| -const DevToolsContentsResizingStrategy& |
| -DevToolsWindow::GetContentsResizingStrategy() const { |
| - return contents_resizing_strategy_; |
| -} |
| - |
| -gfx::Size DevToolsWindow::GetMinimumSize() const { |
| - const gfx::Size kMinDevToolsSize = gfx::Size(230, 100); |
| - return kMinDevToolsSize; |
| -} |
| - |
| void DevToolsWindow::ScheduleShow(const DevToolsToggleAction& action) { |
| if (load_state_ == kLoadCompleted) { |
| Show(action); |
| @@ -474,21 +503,21 @@ void DevToolsWindow::Show(const DevToolsToggleAction& action) { |
| // Tell inspected browser to update splitter and switch to inspected panel. |
| BrowserWindow* inspected_window = inspected_browser->window(); |
| - web_contents_->SetDelegate(this); |
| + main_web_contents_->SetDelegate(this); |
| TabStripModel* tab_strip_model = inspected_browser->tab_strip_model(); |
| tab_strip_model->ActivateTabAt(inspected_tab_index, true); |
| inspected_window->UpdateDevTools(); |
| - web_contents_->SetInitialFocus(); |
| + main_web_contents_->SetInitialFocus(); |
| inspected_window->Show(); |
| // On Aura, focusing once is not enough. Do it again. |
| // Note that focusing only here but not before isn't enough either. We just |
| // need to focus twice. |
| - web_contents_->SetInitialFocus(); |
| + main_web_contents_->SetInitialFocus(); |
| - PrefsTabHelper::CreateForWebContents(web_contents_); |
| - web_contents_->GetRenderViewHost()->SyncRendererPrefs(); |
| + PrefsTabHelper::CreateForWebContents(main_web_contents_); |
| + main_web_contents_->GetRenderViewHost()->SyncRendererPrefs(); |
| DoAction(action); |
| return; |
| @@ -504,8 +533,10 @@ void DevToolsWindow::Show(const DevToolsToggleAction& action) { |
| if (should_show_window) { |
| browser_->window()->Show(); |
| - web_contents_->SetInitialFocus(); |
| + main_web_contents_->SetInitialFocus(); |
| } |
| + if (toolbox_web_contents_) |
| + UpdateBrowserWindow(); |
| DoAction(action); |
| } |
| @@ -539,8 +570,8 @@ bool DevToolsWindow::InterceptPageBeforeUnload(WebContents* contents) { |
| window->intercepted_page_beforeunload_ = true; |
| // Handle case of devtools inspecting another devtools instance by passing |
| // the call up to the inspecting devtools instance. |
| - if (!DevToolsWindow::InterceptPageBeforeUnload(window->web_contents_)) { |
| - window->web_contents_->DispatchBeforeUnload(false); |
| + if (!DevToolsWindow::InterceptPageBeforeUnload(window->main_web_contents_)) { |
| + window->main_web_contents_->DispatchBeforeUnload(false); |
| } |
| return true; |
| } |
| @@ -580,7 +611,7 @@ void DevToolsWindow::OnPageCloseCanceled(WebContents* contents) { |
| return; |
| window->intercepted_page_beforeunload_ = false; |
| // Propagate to devtools opened on devtools if any. |
| - DevToolsWindow::OnPageCloseCanceled(window->web_contents_); |
| + DevToolsWindow::OnPageCloseCanceled(window->main_web_contents_); |
| } |
| DevToolsWindow::DevToolsWindow(Profile* profile, |
| @@ -588,7 +619,9 @@ DevToolsWindow::DevToolsWindow(Profile* profile, |
| content::RenderViewHost* inspected_rvh, |
| bool can_dock) |
| : profile_(profile), |
| - web_contents_(WebContents::Create(WebContents::CreateParams(profile))), |
| + main_web_contents_( |
| + WebContents::Create(WebContents::CreateParams(profile))), |
| + toolbox_web_contents_(NULL), |
| bindings_(NULL), |
| browser_(NULL), |
| is_docked_(true), |
| @@ -602,9 +635,9 @@ DevToolsWindow::DevToolsWindow(Profile* profile, |
| intercepted_page_beforeunload_(false) { |
| // Set up delegate, so we get fully-functional window immediately. |
| // It will not appear in UI though until |load_state_ == kLoadCompleted|. |
| - web_contents_->SetDelegate(this); |
| + main_web_contents_->SetDelegate(this); |
| bindings_ = new DevToolsUIBindings( |
| - web_contents_, |
| + main_web_contents_, |
| DevToolsUIBindings::ApplyThemeToURL(profile, url)); |
| // Bindings take ownership over devtools as its delegate. |
| bindings_->SetDelegate(this); |
| @@ -695,7 +728,7 @@ DevToolsWindow* DevToolsWindow::AsDevToolsWindow( |
| DevToolsWindows* instances = g_instances.Pointer(); |
| for (DevToolsWindows::iterator it(instances->begin()); it != instances->end(); |
| ++it) { |
| - if ((*it)->web_contents_->GetRenderViewHost() == window_rvh) |
| + if ((*it)->main_web_contents_->GetRenderViewHost() == window_rvh) |
| return *it; |
| } |
| return NULL; |
| @@ -704,7 +737,7 @@ DevToolsWindow* DevToolsWindow::AsDevToolsWindow( |
| WebContents* DevToolsWindow::OpenURLFromTab( |
| WebContents* source, |
| const content::OpenURLParams& params) { |
| - DCHECK(source == web_contents_); |
| + DCHECK(source == main_web_contents_); |
| if (!params.url.SchemeIs(content::kChromeDevToolsScheme)) { |
| WebContents* inspected_web_contents = GetInspectedWebContents(); |
| return inspected_web_contents ? |
| @@ -721,8 +754,8 @@ WebContents* DevToolsWindow::OpenURLFromTab( |
| bindings_->frontend_host()); |
| content::NavigationController::LoadURLParams load_url_params(params.url); |
| - web_contents_->GetController().LoadURLWithParams(load_url_params); |
| - return web_contents_; |
| + main_web_contents_->GetController().LoadURLWithParams(load_url_params); |
| + return main_web_contents_; |
| } |
| void DevToolsWindow::ActivateContents(WebContents* contents) { |
| @@ -740,6 +773,13 @@ void DevToolsWindow::AddNewContents(WebContents* source, |
| const gfx::Rect& initial_pos, |
| bool user_gesture, |
| bool* was_blocked) { |
| + if (new_contents == toolbox_web_contents_) { |
| + toolbox_web_contents_->SetDelegate( |
| + new DevToolsToolboxDelegate(toolbox_web_contents_)); |
|
pfeldman
2014/05/27 15:26:19
When is the delegate deleted?
dgozman
2014/05/29 11:22:23
Done.
|
| + UpdateBrowserWindow(); |
| + return; |
| + } |
| + |
| WebContents* inspected_web_contents = GetInspectedWebContents(); |
| if (inspected_web_contents) { |
| inspected_web_contents->GetDelegate()->AddNewContents( |
| @@ -748,6 +788,18 @@ void DevToolsWindow::AddNewContents(WebContents* source, |
| } |
| } |
| +void DevToolsWindow::WebContentsCreated(WebContents* source_contents, |
| + int opener_render_frame_id, |
| + const base::string16& frame_name, |
| + const GURL& target_url, |
| + WebContents* new_contents) { |
| + if (target_url.SchemeIs(content::kChromeDevToolsScheme) && |
| + target_url.query().find("toolbox=true") != std::string::npos) { |
| + CHECK(can_dock_); |
| + toolbox_web_contents_ = new_contents; |
| + } |
| +} |
| + |
| void DevToolsWindow::CloseContents(WebContents* source) { |
| CHECK(is_docked_); |
| // Do this first so that when GetDockedInstanceForInspectedTab is called |
| @@ -758,19 +810,16 @@ void DevToolsWindow::CloseContents(WebContents* source) { |
| // This will prevent any activity after frontend is loaded. |
| action_on_load_ = DevToolsToggleAction::NoOp(); |
| ignore_set_is_docked_ = true; |
| - // Update dev tools to reflect removed dev tools window. |
| - BrowserWindow* inspected_window = GetInspectedBrowserWindow(); |
| - if (inspected_window) |
| - inspected_window->UpdateDevTools(); |
| - // In case of docked web_contents_, we own it so delete here. |
| + UpdateBrowserWindow(); |
| + // In case of docked main_web_contents_, we own it so delete here. |
| // Embedding DevTools window will be deleted as a result of |
| // DevToolsUIBindings destruction. |
| - delete web_contents_; |
| + delete main_web_contents_; |
| } |
| void DevToolsWindow::ContentsZoomChange(bool zoom_in) { |
| DCHECK(is_docked_); |
| - chrome_page_zoom::Zoom(web_contents_, |
| + chrome_page_zoom::Zoom(main_web_contents_, |
| zoom_in ? content::PAGE_ZOOM_IN : content::PAGE_ZOOM_OUT); |
| } |
| @@ -866,7 +915,7 @@ bool DevToolsWindow::PreHandleGestureEvent( |
| void DevToolsWindow::ActivateWindow() { |
| if (is_docked_ && GetInspectedBrowserWindow()) |
| - web_contents_->Focus(); |
| + main_web_contents_->Focus(); |
| else if (!is_docked_ && !browser_->window()->IsActive()) |
| browser_->window()->Activate(); |
| } |
| @@ -876,7 +925,7 @@ void DevToolsWindow::CloseWindow() { |
| // This will prevent any activity after frontend is loaded. |
| action_on_load_ = DevToolsToggleAction::NoOp(); |
| ignore_set_is_docked_ = true; |
| - web_contents_->DispatchBeforeUnload(false); |
| + main_web_contents_->DispatchBeforeUnload(false); |
| } |
| void DevToolsWindow::SetInspectedPageBounds(const gfx::Rect& rect) { |
| @@ -885,12 +934,7 @@ void DevToolsWindow::SetInspectedPageBounds(const gfx::Rect& rect) { |
| return; |
| contents_resizing_strategy_.CopyFrom(strategy); |
| - if (is_docked_) { |
| - // Update inspected window. |
| - BrowserWindow* inspected_window = GetInspectedBrowserWindow(); |
| - if (inspected_window) |
| - inspected_window->UpdateDevTools(); |
| - } |
| + UpdateBrowserWindow(); |
| } |
| void DevToolsWindow::SetContentsResizingStrategy( |
| @@ -900,12 +944,7 @@ void DevToolsWindow::SetContentsResizingStrategy( |
| return; |
| contents_resizing_strategy_.CopyFrom(strategy); |
| - if (is_docked_) { |
| - // Update inspected window. |
| - BrowserWindow* inspected_window = GetInspectedBrowserWindow(); |
| - if (inspected_window) |
| - inspected_window->UpdateDevTools(); |
| - } |
| + UpdateBrowserWindow(); |
| } |
| void DevToolsWindow::InspectElementCompleted() { |
| @@ -969,13 +1008,10 @@ void DevToolsWindow::SetIsDocked(bool dock_requested) { |
| // the browser object's close and delete. Remove observer first. |
| TabStripModel* tab_strip_model = browser_->tab_strip_model(); |
| tab_strip_model->DetachWebContentsAt( |
| - tab_strip_model->GetIndexOfWebContents(web_contents_)); |
| + tab_strip_model->GetIndexOfWebContents(main_web_contents_)); |
| browser_ = NULL; |
| } else if (!dock_requested && was_docked) { |
| - // Update inspected window to hide split and reset it. |
| - BrowserWindow* inspected_window = GetInspectedBrowserWindow(); |
| - if (inspected_window) |
| - inspected_window->UpdateDevTools(); |
| + UpdateBrowserWindow(); |
| } |
| Show(DevToolsToggleAction::Show()); |
| @@ -1021,21 +1057,21 @@ void DevToolsWindow::InspectedContentsClosing() { |
| // This will prevent any activity after frontend is loaded. |
| action_on_load_ = DevToolsToggleAction::NoOp(); |
| ignore_set_is_docked_ = true; |
| - web_contents_->GetRenderViewHost()->ClosePage(); |
| + main_web_contents_->GetRenderViewHost()->ClosePage(); |
| } |
| InfoBarService* DevToolsWindow::GetInfoBarService() { |
| return is_docked_ ? |
| InfoBarService::FromWebContents(GetInspectedWebContents()) : |
| - InfoBarService::FromWebContents(web_contents_); |
| + InfoBarService::FromWebContents(main_web_contents_); |
| } |
| void DevToolsWindow::RenderProcessGone() { |
| - // Docked DevToolsWindow owns its web_contents_ and must delete it. |
| - // Undocked web_contents_ are owned and handled by browser. |
| + // Docked DevToolsWindow owns its main_web_contents_ and must delete it. |
| + // Undocked main_web_contents_ are owned and handled by browser. |
| // see crbug.com/369932 |
| if (is_docked_) |
| - CloseContents(web_contents_); |
| + CloseContents(main_web_contents_); |
| } |
| void DevToolsWindow::OnLoadCompleted() { |
| @@ -1079,11 +1115,11 @@ void DevToolsWindow::CreateDevToolsBrowser() { |
| browser_ = new Browser(Browser::CreateParams::CreateForDevTools( |
| profile_, |
| chrome::GetHostDesktopTypeForNativeView( |
| - web_contents_->GetNativeView()))); |
| + main_web_contents_->GetNativeView()))); |
| browser_->tab_strip_model()->AddWebContents( |
| - web_contents_, -1, content::PAGE_TRANSITION_AUTO_TOPLEVEL, |
| + main_web_contents_, -1, content::PAGE_TRANSITION_AUTO_TOPLEVEL, |
| TabStripModel::ADD_ACTIVE); |
| - web_contents_->GetRenderViewHost()->SyncRendererPrefs(); |
| + main_web_contents_->GetRenderViewHost()->SyncRendererPrefs(); |
| } |
| // static |
| @@ -1153,6 +1189,12 @@ void DevToolsWindow::UpdateBrowserToolbar() { |
| inspected_window->UpdateToolbar(NULL); |
| } |
| +void DevToolsWindow::UpdateBrowserWindow() { |
| + BrowserWindow* inspected_window = GetInspectedBrowserWindow(); |
| + if (inspected_window) |
| + inspected_window->UpdateDevTools(); |
| +} |
| + |
| WebContents* DevToolsWindow::GetInspectedWebContents() { |
| return inspected_contents_observer_ ? |
| inspected_contents_observer_->web_contents() : NULL; |