Commit 5ef358a8 authored by pfeldman@chromium.org's avatar pfeldman@chromium.org

DevTools: extract DevToolsWindowBase, leave docking, unload and factory logic in DevToolsWindow.

R=dgozman@chromium.org, vsevik@chromium.org
TBR=jam for chrome/chrome.gyp

Review URL: https://codereview.chromium.org/253823005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266873 0039d316-1c4b-4281-b951-d872f2087c98
parent 7f9a60e9
...@@ -89,14 +89,14 @@ void RunTestFunction(DevToolsWindow* window, const char* test_name) { ...@@ -89,14 +89,14 @@ void RunTestFunction(DevToolsWindow* window, const char* test_name) {
// files have been loaded) and has runTest method. // files have been loaded) and has runTest method.
ASSERT_TRUE( ASSERT_TRUE(
content::ExecuteScriptAndExtractString( content::ExecuteScriptAndExtractString(
window->GetRenderViewHost(), window->web_contents()->GetRenderViewHost(),
"window.domAutomationController.send(" "window.domAutomationController.send("
" '' + (window.uiTests && (typeof uiTests.runTest)));", " '' + (window.uiTests && (typeof uiTests.runTest)));",
&result)); &result));
ASSERT_EQ("function", result) << "DevTools front-end is broken."; ASSERT_EQ("function", result) << "DevTools front-end is broken.";
ASSERT_TRUE(content::ExecuteScriptAndExtractString( ASSERT_TRUE(content::ExecuteScriptAndExtractString(
window->GetRenderViewHost(), window->web_contents()->GetRenderViewHost(),
base::StringPrintf("uiTests.runTest('%s')", test_name), base::StringPrintf("uiTests.runTest('%s')", test_name),
&result)); &result));
EXPECT_EQ("[OK]", result); EXPECT_EQ("[OK]", result);
...@@ -539,7 +539,7 @@ class WorkerDevToolsSanityTest : public InProcessBrowserTest { ...@@ -539,7 +539,7 @@ class WorkerDevToolsSanityTest : public InProcessBrowserTest {
worker_data->worker_process_id, worker_data->worker_process_id,
worker_data->worker_route_id)); worker_data->worker_route_id));
window_ = DevToolsWindow::OpenDevToolsWindowForWorker(profile, agent_host); window_ = DevToolsWindow::OpenDevToolsWindowForWorker(profile, agent_host);
RenderViewHost* client_rvh = window_->GetRenderViewHost(); RenderViewHost* client_rvh = window_->web_contents()->GetRenderViewHost();
WebContents* client_contents = WebContents::FromRenderViewHost(client_rvh); WebContents* client_contents = WebContents::FromRenderViewHost(client_rvh);
content::WaitForLoadStop(client_contents); content::WaitForLoadStop(client_contents);
} }
...@@ -871,7 +871,7 @@ IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestPageWithNoJavaScript) { ...@@ -871,7 +871,7 @@ IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestPageWithNoJavaScript) {
std::string result; std::string result;
ASSERT_TRUE( ASSERT_TRUE(
content::ExecuteScriptAndExtractString( content::ExecuteScriptAndExtractString(
window_->GetRenderViewHost(), window_->web_contents()->GetRenderViewHost(),
"window.domAutomationController.send(" "window.domAutomationController.send("
" '' + (window.uiTests && (typeof uiTests.runTest)));", " '' + (window.uiTests && (typeof uiTests.runTest)));",
&result)); &result));
......
...@@ -6,32 +6,16 @@ ...@@ -6,32 +6,16 @@
#include <algorithm> #include <algorithm>
#include "base/command_line.h"
#include "base/json/json_reader.h" #include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/lazy_instance.h"
#include "base/metrics/histogram.h" #include "base/metrics/histogram.h"
#include "base/prefs/scoped_user_pref_update.h" #include "base/prefs/scoped_user_pref_update.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chrome_page_zoom.h" #include "chrome/browser/chrome_page_zoom.h"
#include "chrome/browser/extensions/api/debugger/debugger_api.h"
#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/file_select_helper.h" #include "chrome/browser/file_select_helper.h"
#include "chrome/browser/infobars/confirm_infobar_delegate.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/prefs/pref_service_syncable.h" #include "chrome/browser/prefs/pref_service_syncable.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/session_tab_helper.h" #include "chrome/browser/sessions/session_tab_helper.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_iterator.h" #include "chrome/browser/ui/browser_iterator.h"
...@@ -42,19 +26,14 @@ ...@@ -42,19 +26,14 @@
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/webui/devtools_ui.h" #include "chrome/browser/ui/webui/devtools_ui.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "chrome/common/render_messages.h" #include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "components/infobars/core/infobar.h"
#include "components/user_prefs/pref_registry_syncable.h" #include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/devtools_client_host.h" #include "content/public/browser/devtools_client_host.h"
#include "content/public/browser/devtools_manager.h" #include "content/public/browser/devtools_manager.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/load_notification_details.h"
#include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_entry.h"
...@@ -66,111 +45,32 @@ ...@@ -66,111 +45,32 @@
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_view.h" #include "content/public/browser/web_contents_view.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/content_client.h" #include "content/public/common/content_client.h"
#include "content/public/common/page_transition_types.h" #include "content/public/common/page_transition_types.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/url_constants.h" #include "content/public/common/url_constants.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension_set.h"
#include "grit/generated_resources.h"
#include "third_party/WebKit/public/web/WebInputEvent.h" #include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/events/keycodes/keyboard_codes.h" #include "ui/events/keycodes/keyboard_codes.h"
using base::DictionaryValue; using base::DictionaryValue;
using blink::WebInputEvent; using blink::WebInputEvent;
using content::BrowserThread; using content::BrowserThread;
using content::DevToolsAgentHost; using content::DevToolsAgentHost;
using content::WebContents;
// DevToolsConfirmInfoBarDelegate ---------------------------------------------
class DevToolsConfirmInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
// If |infobar_service| is NULL, runs |callback| with a single argument with
// value "false". Otherwise, creates a dev tools confirm infobar and delegate
// and adds the infobar to |infobar_service|.
static void Create(InfoBarService* infobar_service,
const DevToolsWindow::InfoBarCallback& callback,
const base::string16& message);
private:
DevToolsConfirmInfoBarDelegate(
const DevToolsWindow::InfoBarCallback& callback,
const base::string16& message);
virtual ~DevToolsConfirmInfoBarDelegate();
virtual base::string16 GetMessageText() const OVERRIDE;
virtual base::string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
virtual bool Accept() OVERRIDE;
virtual bool Cancel() OVERRIDE;
DevToolsWindow::InfoBarCallback callback_;
const base::string16 message_;
DISALLOW_COPY_AND_ASSIGN(DevToolsConfirmInfoBarDelegate);
};
void DevToolsConfirmInfoBarDelegate::Create(
InfoBarService* infobar_service,
const DevToolsWindow::InfoBarCallback& callback,
const base::string16& message) {
if (!infobar_service) {
callback.Run(false);
return;
}
infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
scoped_ptr<ConfirmInfoBarDelegate>(
new DevToolsConfirmInfoBarDelegate(callback, message))));
}
DevToolsConfirmInfoBarDelegate::DevToolsConfirmInfoBarDelegate(
const DevToolsWindow::InfoBarCallback& callback,
const base::string16& message)
: ConfirmInfoBarDelegate(),
callback_(callback),
message_(message) {
}
DevToolsConfirmInfoBarDelegate::~DevToolsConfirmInfoBarDelegate() {
if (!callback_.is_null())
callback_.Run(false);
}
base::string16 DevToolsConfirmInfoBarDelegate::GetMessageText() const {
return message_;
}
base::string16 DevToolsConfirmInfoBarDelegate::GetButtonLabel(
InfoBarButton button) const {
return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
IDS_DEV_TOOLS_CONFIRM_ALLOW_BUTTON : IDS_DEV_TOOLS_CONFIRM_DENY_BUTTON);
}
bool DevToolsConfirmInfoBarDelegate::Accept() {
callback_.Run(true);
callback_.Reset();
return true;
}
bool DevToolsConfirmInfoBarDelegate::Cancel() {
callback_.Run(false);
callback_.Reset();
return true;
}
// DevToolsEventForwarder -----------------------------------------------------
namespace { namespace {
typedef std::vector<DevToolsWindow*> DevToolsWindows;
base::LazyInstance<DevToolsWindows>::Leaky g_instances =
LAZY_INSTANCE_INITIALIZER;
static const char kKeyUpEventName[] = "keyup"; static const char kKeyUpEventName[] = "keyup";
static const char kKeyDownEventName[] = "keydown"; static const char kKeyDownEventName[] = "keydown";
} // namespace } // namespace
// DevToolsEventForwarder -----------------------------------------------------
class DevToolsEventForwarder { class DevToolsEventForwarder {
public: public:
explicit DevToolsEventForwarder(DevToolsWindow* window) explicit DevToolsEventForwarder(DevToolsWindow* window)
...@@ -285,10 +185,10 @@ int DevToolsEventForwarder::VirtualKeyCodeWithoutLocation(int key_code) ...@@ -285,10 +185,10 @@ int DevToolsEventForwarder::VirtualKeyCodeWithoutLocation(int key_code)
class DevToolsWindow::InspectedWebContentsObserver class DevToolsWindow::InspectedWebContentsObserver
: public content::WebContentsObserver { : public content::WebContentsObserver {
public: public:
explicit InspectedWebContentsObserver(content::WebContents* web_contents); explicit InspectedWebContentsObserver(WebContents* web_contents);
virtual ~InspectedWebContentsObserver(); virtual ~InspectedWebContentsObserver();
content::WebContents* web_contents() { WebContents* web_contents() {
return WebContentsObserver::web_contents(); return WebContentsObserver::web_contents();
} }
...@@ -297,94 +197,18 @@ class DevToolsWindow::InspectedWebContentsObserver ...@@ -297,94 +197,18 @@ class DevToolsWindow::InspectedWebContentsObserver
}; };
DevToolsWindow::InspectedWebContentsObserver::InspectedWebContentsObserver( DevToolsWindow::InspectedWebContentsObserver::InspectedWebContentsObserver(
content::WebContents* web_contents) WebContents* web_contents)
: WebContentsObserver(web_contents) { : WebContentsObserver(web_contents) {
} }
DevToolsWindow::InspectedWebContentsObserver::~InspectedWebContentsObserver() { DevToolsWindow::InspectedWebContentsObserver::~InspectedWebContentsObserver() {
} }
// DevToolsWindow::FrontendWebContentsObserver --------------------------------
class DevToolsWindow::FrontendWebContentsObserver
: public content::WebContentsObserver {
public:
explicit FrontendWebContentsObserver(DevToolsWindow* window);
virtual ~FrontendWebContentsObserver();
private:
// contents::WebContentsObserver:
virtual void AboutToNavigateRenderView(
content::RenderViewHost* render_view_host) OVERRIDE;
virtual void DocumentOnLoadCompletedInMainFrame(int32 page_id) OVERRIDE;
virtual void WebContentsDestroyed(content::WebContents*) OVERRIDE;
DevToolsWindow* devtools_window_;
DISALLOW_COPY_AND_ASSIGN(FrontendWebContentsObserver);
};
DevToolsWindow::FrontendWebContentsObserver::FrontendWebContentsObserver(
DevToolsWindow* devtools_window)
: WebContentsObserver(devtools_window->web_contents()),
devtools_window_(devtools_window) {
}
void DevToolsWindow::FrontendWebContentsObserver::WebContentsDestroyed(
content::WebContents* contents) {
delete devtools_window_;
}
DevToolsWindow::FrontendWebContentsObserver::~FrontendWebContentsObserver() {
}
void DevToolsWindow::FrontendWebContentsObserver::AboutToNavigateRenderView(
content::RenderViewHost* render_view_host) {
content::DevToolsClientHost::SetupDevToolsFrontendClient(render_view_host);
}
void DevToolsWindow::FrontendWebContentsObserver::
DocumentOnLoadCompletedInMainFrame(int32 page_id) {
devtools_window_->DocumentOnLoadCompletedInMainFrame();
}
// DevToolsWindow ------------------------------------------------------------- // DevToolsWindow -------------------------------------------------------------
namespace {
typedef std::vector<DevToolsWindow*> DevToolsWindows;
base::LazyInstance<DevToolsWindows>::Leaky g_instances =
LAZY_INSTANCE_INITIALIZER;
static const char kFrontendHostId[] = "id";
static const char kFrontendHostMethod[] = "method";
static const char kFrontendHostParams[] = "params";
std::string SkColorToRGBAString(SkColor color) {
// We avoid StringPrintf because it will use locale specific formatters for
// the double (e.g. ',' instead of '.' in German).
return "rgba(" + base::IntToString(SkColorGetR(color)) + "," +
base::IntToString(SkColorGetG(color)) + "," +
base::IntToString(SkColorGetB(color)) + "," +
base::DoubleToString(SkColorGetA(color) / 255.0) + ")";
}
base::DictionaryValue* CreateFileSystemValue(
DevToolsFileHelper::FileSystem file_system) {
base::DictionaryValue* file_system_value = new base::DictionaryValue();
file_system_value->SetString("fileSystemName", file_system.file_system_name);
file_system_value->SetString("rootURL", file_system.root_url);
file_system_value->SetString("fileSystemPath", file_system.file_system_path);
return file_system_value;
}
} // namespace
const char DevToolsWindow::kDevToolsApp[] = "DevToolsApp"; const char DevToolsWindow::kDevToolsApp[] = "DevToolsApp";
DevToolsWindow::~DevToolsWindow() { DevToolsWindow::~DevToolsWindow() {
content::DevToolsManager::GetInstance()->ClientHostClosing(
frontend_host_.get());
UpdateBrowserToolbar(); UpdateBrowserToolbar();
DevToolsWindows* instances = g_instances.Pointer(); DevToolsWindows* instances = g_instances.Pointer();
...@@ -392,14 +216,6 @@ DevToolsWindow::~DevToolsWindow() { ...@@ -392,14 +216,6 @@ DevToolsWindow::~DevToolsWindow() {
std::find(instances->begin(), instances->end(), this)); std::find(instances->begin(), instances->end(), this));
DCHECK(it != instances->end()); DCHECK(it != instances->end());
instances->erase(it); instances->erase(it);
for (IndexingJobsMap::const_iterator jobs_it(indexing_jobs_.begin());
jobs_it != indexing_jobs_.end(); ++jobs_it) {
jobs_it->second->Stop();
}
indexing_jobs_.clear();
if (device_listener_enabled_)
EnableRemoteDeviceCounter(false);
} }
// static // static
...@@ -444,7 +260,7 @@ void DevToolsWindow::RegisterProfilePrefs( ...@@ -444,7 +260,7 @@ void DevToolsWindow::RegisterProfilePrefs(
// static // static
DevToolsWindow* DevToolsWindow::GetDockedInstanceForInspectedTab( DevToolsWindow* DevToolsWindow::GetDockedInstanceForInspectedTab(
content::WebContents* inspected_web_contents) { WebContents* inspected_web_contents) {
DevToolsWindow* window = GetInstanceForInspectedRenderViewHost( DevToolsWindow* window = GetInstanceForInspectedRenderViewHost(
inspected_web_contents->GetRenderViewHost()); inspected_web_contents->GetRenderViewHost());
if (!window) if (!window)
...@@ -469,7 +285,7 @@ DevToolsWindow* DevToolsWindow::GetInstanceForInspectedRenderViewHost( ...@@ -469,7 +285,7 @@ DevToolsWindow* DevToolsWindow::GetInstanceForInspectedRenderViewHost(
// static // static
DevToolsWindow* DevToolsWindow::GetInstanceForInspectedWebContents( DevToolsWindow* DevToolsWindow::GetInstanceForInspectedWebContents(
content::WebContents* inspected_web_contents) { WebContents* inspected_web_contents) {
if (!inspected_web_contents) if (!inspected_web_contents)
return NULL; return NULL;
return GetInstanceForInspectedRenderViewHost( return GetInstanceForInspectedRenderViewHost(
...@@ -490,7 +306,7 @@ DevToolsWindow* DevToolsWindow::OpenDevToolsWindowForWorker( ...@@ -490,7 +306,7 @@ DevToolsWindow* DevToolsWindow::OpenDevToolsWindowForWorker(
window = DevToolsWindow::CreateDevToolsWindowForWorker(profile); window = DevToolsWindow::CreateDevToolsWindowForWorker(profile);
// Will disconnect the current client host if there is one. // Will disconnect the current client host if there is one.
content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor( content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(
worker_agent, window->frontend_host_.get()); worker_agent, window->frontend_host());
} }
window->ScheduleShow(DevToolsToggleAction::Show()); window->ScheduleShow(DevToolsToggleAction::Show());
return window; return window;
...@@ -561,7 +377,7 @@ void DevToolsWindow::OpenExternalFrontend( ...@@ -561,7 +377,7 @@ void DevToolsWindow::OpenExternalFrontend(
window = Create(profile, DevToolsUI::GetProxyURL(frontend_url), NULL, window = Create(profile, DevToolsUI::GetProxyURL(frontend_url), NULL,
false, true, false); false, true, false);
content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor( content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(
agent_host, window->frontend_host_.get()); agent_host, window->frontend_host());
} }
window->ScheduleShow(DevToolsToggleAction::Show()); window->ScheduleShow(DevToolsToggleAction::Show());
} }
...@@ -583,7 +399,7 @@ DevToolsWindow* DevToolsWindow::ToggleDevToolsWindow( ...@@ -583,7 +399,7 @@ DevToolsWindow* DevToolsWindow::ToggleDevToolsWindow(
base::UserMetricsAction("DevTools_InspectRenderer")); base::UserMetricsAction("DevTools_InspectRenderer"));
window = Create(profile, GURL(), inspected_rvh, false, false, true); window = Create(profile, GURL(), inspected_rvh, false, false, true);
manager->RegisterDevToolsClientHostFor(agent.get(), manager->RegisterDevToolsClientHostFor(agent.get(),
window->frontend_host_.get()); window->frontend_host());
do_open = true; do_open = true;
} }
...@@ -616,18 +432,6 @@ void DevToolsWindow::InspectElement(content::RenderViewHost* inspected_rvh, ...@@ -616,18 +432,6 @@ void DevToolsWindow::InspectElement(content::RenderViewHost* inspected_rvh,
window->inspect_element_start_time_ = start_time; window->inspect_element_start_time_ = start_time;
} }
void DevToolsWindow::InspectedContentsClosing() {
intercepted_page_beforeunload_ = false;
// This will prevent any activity after frontend is loaded.
action_on_load_ = DevToolsToggleAction::NoOp();
ignore_set_is_docked_ = true;
web_contents_->GetRenderViewHost()->ClosePage();
}
content::RenderViewHost* DevToolsWindow::GetRenderViewHost() {
return web_contents_->GetRenderViewHost();
}
const DevToolsContentsResizingStrategy& const DevToolsContentsResizingStrategy&
DevToolsWindow::GetContentsResizingStrategy() const { DevToolsWindow::GetContentsResizingStrategy() const {
return contents_resizing_strategy_; return contents_resizing_strategy_;
...@@ -670,21 +474,21 @@ void DevToolsWindow::Show(const DevToolsToggleAction& action) { ...@@ -670,21 +474,21 @@ void DevToolsWindow::Show(const DevToolsToggleAction& action) {
// Tell inspected browser to update splitter and switch to inspected panel. // Tell inspected browser to update splitter and switch to inspected panel.
BrowserWindow* inspected_window = inspected_browser->window(); BrowserWindow* inspected_window = inspected_browser->window();
web_contents_->SetDelegate(this); web_contents()->SetDelegate(this);
TabStripModel* tab_strip_model = inspected_browser->tab_strip_model(); TabStripModel* tab_strip_model = inspected_browser->tab_strip_model();
tab_strip_model->ActivateTabAt(inspected_tab_index, true); tab_strip_model->ActivateTabAt(inspected_tab_index, true);
inspected_window->UpdateDevTools(); inspected_window->UpdateDevTools();
web_contents_->GetView()->SetInitialFocus(); web_contents()->GetView()->SetInitialFocus();
inspected_window->Show(); inspected_window->Show();
// On Aura, focusing once is not enough. Do it again. // On Aura, focusing once is not enough. Do it again.
// Note that focusing only here but not before isn't enough either. We just // Note that focusing only here but not before isn't enough either. We just
// need to focus twice. // need to focus twice.
web_contents_->GetView()->SetInitialFocus(); web_contents()->GetView()->SetInitialFocus();
PrefsTabHelper::CreateForWebContents(web_contents_); PrefsTabHelper::CreateForWebContents(web_contents());
GetRenderViewHost()->SyncRendererPrefs(); web_contents()->GetRenderViewHost()->SyncRendererPrefs();
DoAction(action); DoAction(action);
return; return;
...@@ -700,14 +504,14 @@ void DevToolsWindow::Show(const DevToolsToggleAction& action) { ...@@ -700,14 +504,14 @@ void DevToolsWindow::Show(const DevToolsToggleAction& action) {
if (should_show_window) { if (should_show_window) {
browser_->window()->Show(); browser_->window()->Show();
web_contents_->GetView()->SetInitialFocus(); web_contents()->GetView()->SetInitialFocus();
} }
DoAction(action); DoAction(action);
} }
// static // static
bool DevToolsWindow::HandleBeforeUnload(content::WebContents* frontend_contents, bool DevToolsWindow::HandleBeforeUnload(WebContents* frontend_contents,
bool proceed, bool* proceed_to_fire_unload) { bool proceed, bool* proceed_to_fire_unload) {
DevToolsWindow* window = AsDevToolsWindow( DevToolsWindow* window = AsDevToolsWindow(
frontend_contents->GetRenderViewHost()); frontend_contents->GetRenderViewHost());
...@@ -721,7 +525,7 @@ bool DevToolsWindow::HandleBeforeUnload(content::WebContents* frontend_contents, ...@@ -721,7 +525,7 @@ bool DevToolsWindow::HandleBeforeUnload(content::WebContents* frontend_contents,
} }
// static // static
bool DevToolsWindow::InterceptPageBeforeUnload(content::WebContents* contents) { bool DevToolsWindow::InterceptPageBeforeUnload(WebContents* contents) {
DevToolsWindow* window = DevToolsWindow* window =
DevToolsWindow::GetInstanceForInspectedRenderViewHost( DevToolsWindow::GetInstanceForInspectedRenderViewHost(
contents->GetRenderViewHost()); contents->GetRenderViewHost());
...@@ -743,7 +547,7 @@ bool DevToolsWindow::InterceptPageBeforeUnload(content::WebContents* contents) { ...@@ -743,7 +547,7 @@ bool DevToolsWindow::InterceptPageBeforeUnload(content::WebContents* contents) {
// static // static
bool DevToolsWindow::NeedsToInterceptBeforeUnload( bool DevToolsWindow::NeedsToInterceptBeforeUnload(
content::WebContents* contents) { WebContents* contents) {
DevToolsWindow* window = DevToolsWindow* window =
DevToolsWindow::GetInstanceForInspectedRenderViewHost( DevToolsWindow::GetInstanceForInspectedRenderViewHost(
contents->GetRenderViewHost()); contents->GetRenderViewHost());
...@@ -759,7 +563,7 @@ bool DevToolsWindow::HasFiredBeforeUnloadEventForDevToolsBrowser( ...@@ -759,7 +563,7 @@ bool DevToolsWindow::HasFiredBeforeUnloadEventForDevToolsBrowser(
// beforeunload. // beforeunload.
if (browser->tab_strip_model()->empty()) if (browser->tab_strip_model()->empty())
return true; return true;
content::WebContents* contents = WebContents* contents =
browser->tab_strip_model()->GetWebContentsAt(0); browser->tab_strip_model()->GetWebContentsAt(0);
DevToolsWindow* window = AsDevToolsWindow(contents->GetRenderViewHost()); DevToolsWindow* window = AsDevToolsWindow(contents->GetRenderViewHost());
if (!window) if (!window)
...@@ -768,7 +572,7 @@ bool DevToolsWindow::HasFiredBeforeUnloadEventForDevToolsBrowser( ...@@ -768,7 +572,7 @@ bool DevToolsWindow::HasFiredBeforeUnloadEventForDevToolsBrowser(
} }
// static // static
void DevToolsWindow::OnPageCloseCanceled(content::WebContents* contents) { void DevToolsWindow::OnPageCloseCanceled(WebContents* contents) {
DevToolsWindow *window = DevToolsWindow *window =
DevToolsWindow::GetInstanceForInspectedRenderViewHost( DevToolsWindow::GetInstanceForInspectedRenderViewHost(
contents->GetRenderViewHost()); contents->GetRenderViewHost());
...@@ -783,59 +587,29 @@ DevToolsWindow::DevToolsWindow(Profile* profile, ...@@ -783,59 +587,29 @@ DevToolsWindow::DevToolsWindow(Profile* profile,
const GURL& url, const GURL& url,
content::RenderViewHost* inspected_rvh, content::RenderViewHost* inspected_rvh,
bool can_dock) bool can_dock)
: profile_(profile), : DevToolsWindowBase(
WebContents::Create(WebContents::CreateParams(profile)), url),
browser_(NULL), browser_(NULL),
is_docked_(true), is_docked_(true),
can_dock_(can_dock), can_dock_(can_dock),
device_listener_enabled_(false),
// This initialization allows external front-end to work without changes. // This initialization allows external front-end to work without changes.
// We don't wait for docking call, but instead immediately show undocked. // We don't wait for docking call, but instead immediately show undocked.
// Passing "dockSide=undocked" parameter ensures proper UI. // Passing "dockSide=undocked" parameter ensures proper UI.
load_state_(can_dock ? kNotLoaded : kIsDockedSet), load_state_(can_dock ? kNotLoaded : kIsDockedSet),
action_on_load_(DevToolsToggleAction::NoOp()), action_on_load_(DevToolsToggleAction::NoOp()),
ignore_set_is_docked_(false), ignore_set_is_docked_(false),
intercepted_page_beforeunload_(false), intercepted_page_beforeunload_(false) {
weak_factory_(this) {
web_contents_ =
content::WebContents::Create(content::WebContents::CreateParams(profile));
frontend_contents_observer_.reset(new FrontendWebContentsObserver(this));
web_contents_->GetMutableRendererPrefs()->can_accept_load_drops = false;
// Set up delegate, so we get fully-functional window immediately. // Set up delegate, so we get fully-functional window immediately.
// It will not appear in UI though until |load_state_ == kLoadCompleted|. // It will not appear in UI though until |load_state_ == kLoadCompleted|.
web_contents_->SetDelegate(this); web_contents()->SetDelegate(this);
web_contents_->GetController().LoadURL(url, content::Referrer(),
content::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string());
frontend_host_.reset(content::DevToolsClientHost::CreateDevToolsFrontendHost(
web_contents_, this));
file_helper_.reset(new DevToolsFileHelper(web_contents_, profile));
file_system_indexer_ = new DevToolsFileSystemIndexer();
extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
web_contents_);
g_instances.Get().push_back(this); g_instances.Get().push_back(this);
// Wipe out page icon so that the default application icon is used.
content::NavigationEntry* entry =
web_contents_->GetController().GetActiveEntry();
entry->GetFavicon().image = gfx::Image();
entry->GetFavicon().valid = true;
// Register on-load actions.
registrar_.Add(
this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
content::Source<ThemeService>(
ThemeServiceFactory::GetForProfile(profile_)));
// There is no inspected_rvh in case of shared workers. // There is no inspected_rvh in case of shared workers.
if (inspected_rvh) if (inspected_rvh)
inspected_contents_observer_.reset(new InspectedWebContentsObserver( inspected_contents_observer_.reset(new InspectedWebContentsObserver(
content::WebContents::FromRenderViewHost(inspected_rvh))); content::WebContents::FromRenderViewHost(inspected_rvh)));
embedder_message_dispatcher_.reset(
DevToolsEmbedderMessageDispatcher::createForDevToolsFrontend(this));
event_forwarder_.reset(new DevToolsEventForwarder(this)); event_forwarder_.reset(new DevToolsEventForwarder(this));
} }
...@@ -851,7 +625,7 @@ DevToolsWindow* DevToolsWindow::Create( ...@@ -851,7 +625,7 @@ DevToolsWindow* DevToolsWindow::Create(
// Check for a place to dock. // Check for a place to dock.
Browser* browser = NULL; Browser* browser = NULL;
int tab; int tab;
content::WebContents* inspected_web_contents = WebContents* inspected_web_contents =
content::WebContents::FromRenderViewHost(inspected_rvh); content::WebContents::FromRenderViewHost(inspected_rvh);
if (!FindInspectedBrowserAndTabIndex(inspected_web_contents, if (!FindInspectedBrowserAndTabIndex(inspected_web_contents,
&browser, &tab) || &browser, &tab) ||
...@@ -875,31 +649,22 @@ GURL DevToolsWindow::GetDevToolsURL(Profile* profile, ...@@ -875,31 +649,22 @@ GURL DevToolsWindow::GetDevToolsURL(Profile* profile,
bool shared_worker_frontend, bool shared_worker_frontend,
bool external_frontend, bool external_frontend,
bool can_dock) { bool can_dock) {
// Compatibility errors are encoded with data urls, pass them
// through with no decoration.
if (base_url.SchemeIs("data")) if (base_url.SchemeIs("data"))
return base_url; return base_url;
std::string frontend_url( std::string frontend_url(
base_url.is_empty() ? chrome::kChromeUIDevToolsURL : base_url.spec()); base_url.is_empty() ? chrome::kChromeUIDevToolsURL : base_url.spec());
ThemeService* tp = ThemeServiceFactory::GetForProfile(profile);
DCHECK(tp);
std::string url_string( std::string url_string(
frontend_url + frontend_url +
((frontend_url.find("?") == std::string::npos) ? "?" : "&") + ((frontend_url.find("?") == std::string::npos) ? "?" : "&"));
"dockSide=undocked" + // TODO(dgozman): remove this support in M38.
"&toolbarColor=" +
SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) +
"&textColor=" +
SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)));
if (shared_worker_frontend) if (shared_worker_frontend)
url_string += "&isSharedWorker=true"; url_string += "&isSharedWorker=true";
if (external_frontend) if (external_frontend)
url_string += "&remoteFrontend=true"; url_string += "&remoteFrontend=true";
if (can_dock) if (can_dock)
url_string += "&can_dock=true"; url_string += "&can_dock=true";
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableDevToolsExperiments))
url_string += "&experiments=true";
url_string += "&updateAppcache";
return GURL(url_string); return GURL(url_string);
} }
...@@ -910,7 +675,7 @@ DevToolsWindow* DevToolsWindow::FindDevToolsWindow( ...@@ -910,7 +675,7 @@ DevToolsWindow* DevToolsWindow::FindDevToolsWindow(
content::DevToolsManager* manager = content::DevToolsManager::GetInstance(); content::DevToolsManager* manager = content::DevToolsManager::GetInstance();
for (DevToolsWindows::iterator it(instances->begin()); it != instances->end(); for (DevToolsWindows::iterator it(instances->begin()); it != instances->end();
++it) { ++it) {
if (manager->GetDevToolsAgentHostFor((*it)->frontend_host_.get()) == if (manager->GetDevToolsAgentHostFor((*it)->frontend_host()) ==
agent_host) agent_host)
return *it; return *it;
} }
...@@ -925,50 +690,60 @@ DevToolsWindow* DevToolsWindow::AsDevToolsWindow( ...@@ -925,50 +690,60 @@ DevToolsWindow* DevToolsWindow::AsDevToolsWindow(
DevToolsWindows* instances = g_instances.Pointer(); DevToolsWindows* instances = g_instances.Pointer();
for (DevToolsWindows::iterator it(instances->begin()); it != instances->end(); for (DevToolsWindows::iterator it(instances->begin()); it != instances->end();
++it) { ++it) {
if ((*it)->web_contents_->GetRenderViewHost() == window_rvh) if ((*it)->web_contents()->GetRenderViewHost() == window_rvh)
return *it; return *it;
} }
return NULL; return NULL;
} }
void DevToolsWindow::Observe(int type, void DevToolsWindow::InspectedContentsClosing() {
const content::NotificationSource& source, intercepted_page_beforeunload_ = false;
const content::NotificationDetails& details) { // This will prevent any activity after frontend is loaded.
DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, type); action_on_load_ = DevToolsToggleAction::NoOp();
UpdateTheme(); ignore_set_is_docked_ = true;
DevToolsWindowBase::InspectedContentsClosing();
} }
content::WebContents* DevToolsWindow::OpenURLFromTab( WebContents* DevToolsWindow::OpenURLFromTab(
content::WebContents* source, WebContents* source,
const content::OpenURLParams& params) { const content::OpenURLParams& params) {
DCHECK(source == web_contents_); DCHECK(source == web_contents());
if (!params.url.SchemeIs(content::kChromeDevToolsScheme)) { if (!params.url.SchemeIs(content::kChromeDevToolsScheme)) {
content::WebContents* inspected_web_contents = GetInspectedWebContents(); WebContents* inspected_web_contents = GetInspectedWebContents();
return inspected_web_contents ? return inspected_web_contents ?
inspected_web_contents->OpenURL(params) : NULL; inspected_web_contents->OpenURL(params) : NULL;
} }
content::DevToolsManager* manager = content::DevToolsManager::GetInstance(); content::DevToolsManager* manager = content::DevToolsManager::GetInstance();
scoped_refptr<DevToolsAgentHost> agent_host( scoped_refptr<DevToolsAgentHost> agent_host(
manager->GetDevToolsAgentHostFor(frontend_host_.get())); manager->GetDevToolsAgentHostFor(frontend_host()));
if (!agent_host.get()) if (!agent_host.get())
return NULL; return NULL;
manager->ClientHostClosing(frontend_host_.get()); manager->ClientHostClosing(frontend_host());
manager->RegisterDevToolsClientHostFor(agent_host.get(), manager->RegisterDevToolsClientHostFor(agent_host.get(),
frontend_host_.get()); frontend_host());
content::NavigationController::LoadURLParams load_url_params(params.url); content::NavigationController::LoadURLParams load_url_params(params.url);
web_contents_->GetController().LoadURLWithParams(load_url_params); web_contents()->GetController().LoadURLWithParams(load_url_params);
return web_contents_; return web_contents();
}
void DevToolsWindow::ActivateContents(WebContents* contents) {
if (is_docked_) {
WebContents* inspected_tab = GetInspectedWebContents();
inspected_tab->GetDelegate()->ActivateContents(inspected_tab);
} else {
browser_->window()->Activate();
}
} }
void DevToolsWindow::AddNewContents(content::WebContents* source, void DevToolsWindow::AddNewContents(WebContents* source,
content::WebContents* new_contents, WebContents* new_contents,
WindowOpenDisposition disposition, WindowOpenDisposition disposition,
const gfx::Rect& initial_pos, const gfx::Rect& initial_pos,
bool user_gesture, bool user_gesture,
bool* was_blocked) { bool* was_blocked) {
content::WebContents* inspected_web_contents = GetInspectedWebContents(); WebContents* inspected_web_contents = GetInspectedWebContents();
if (inspected_web_contents) { if (inspected_web_contents) {
inspected_web_contents->GetDelegate()->AddNewContents( inspected_web_contents->GetDelegate()->AddNewContents(
source, new_contents, disposition, initial_pos, user_gesture, source, new_contents, disposition, initial_pos, user_gesture,
...@@ -976,7 +751,7 @@ void DevToolsWindow::AddNewContents(content::WebContents* source, ...@@ -976,7 +751,7 @@ void DevToolsWindow::AddNewContents(content::WebContents* source,
} }
} }
void DevToolsWindow::CloseContents(content::WebContents* source) { void DevToolsWindow::CloseContents(WebContents* source) {
CHECK(is_docked_); CHECK(is_docked_);
// This will prevent any activity after frontend is loaded. // This will prevent any activity after frontend is loaded.
action_on_load_ = DevToolsToggleAction::NoOp(); action_on_load_ = DevToolsToggleAction::NoOp();
...@@ -985,10 +760,10 @@ void DevToolsWindow::CloseContents(content::WebContents* source) { ...@@ -985,10 +760,10 @@ void DevToolsWindow::CloseContents(content::WebContents* source) {
BrowserWindow* inspected_window = GetInspectedBrowserWindow(); BrowserWindow* inspected_window = GetInspectedBrowserWindow();
if (inspected_window) if (inspected_window)
inspected_window->UpdateDevTools(); inspected_window->UpdateDevTools();
// In case of docked web_contents_, we own it so delete here. // In case of docked web_contents(), we own it so delete here.
// Embedding DevTools window will be deleted as a result of // Embedding DevTools window will be deleted as a result of
// WebContentsDestroyed callback. // WebContentsDestroyed callback.
delete web_contents_; delete web_contents();
} }
void DevToolsWindow::ContentsZoomChange(bool zoom_in) { void DevToolsWindow::ContentsZoomChange(bool zoom_in) {
...@@ -997,19 +772,19 @@ void DevToolsWindow::ContentsZoomChange(bool zoom_in) { ...@@ -997,19 +772,19 @@ void DevToolsWindow::ContentsZoomChange(bool zoom_in) {
zoom_in ? content::PAGE_ZOOM_IN : content::PAGE_ZOOM_OUT); zoom_in ? content::PAGE_ZOOM_IN : content::PAGE_ZOOM_OUT);
} }
void DevToolsWindow::BeforeUnloadFired(content::WebContents* tab, void DevToolsWindow::BeforeUnloadFired(WebContents* tab,
bool proceed, bool proceed,
bool* proceed_to_fire_unload) { bool* proceed_to_fire_unload) {
if (!intercepted_page_beforeunload_) { if (!intercepted_page_beforeunload_) {
// Docked devtools window closed directly. // Docked devtools window closed directly.
if (proceed) { if (proceed) {
content::DevToolsManager::GetInstance()->ClientHostClosing( content::DevToolsManager::GetInstance()->ClientHostClosing(
frontend_host_.get()); frontend_host());
} }
*proceed_to_fire_unload = proceed; *proceed_to_fire_unload = proceed;
} else { } else {
// Inspected page is attempting to close. // Inspected page is attempting to close.
content::WebContents* inspected_web_contents = GetInspectedWebContents(); WebContents* inspected_web_contents = GetInspectedWebContents();
if (proceed) { if (proceed) {
inspected_web_contents->DispatchBeforeUnload(false); inspected_web_contents->DispatchBeforeUnload(false);
} else { } else {
...@@ -1023,7 +798,7 @@ void DevToolsWindow::BeforeUnloadFired(content::WebContents* tab, ...@@ -1023,7 +798,7 @@ void DevToolsWindow::BeforeUnloadFired(content::WebContents* tab,
} }
bool DevToolsWindow::PreHandleKeyboardEvent( bool DevToolsWindow::PreHandleKeyboardEvent(
content::WebContents* source, WebContents* source,
const content::NativeWebKeyboardEvent& event, const content::NativeWebKeyboardEvent& event,
bool* is_keyboard_shortcut) { bool* is_keyboard_shortcut) {
if (is_docked_) { if (is_docked_) {
...@@ -1037,7 +812,7 @@ bool DevToolsWindow::PreHandleKeyboardEvent( ...@@ -1037,7 +812,7 @@ bool DevToolsWindow::PreHandleKeyboardEvent(
} }
void DevToolsWindow::HandleKeyboardEvent( void DevToolsWindow::HandleKeyboardEvent(
content::WebContents* source, WebContents* source,
const content::NativeWebKeyboardEvent& event) { const content::NativeWebKeyboardEvent& event) {
if (is_docked_) { if (is_docked_) {
if (event.windowsKeyCode == 0x08) { if (event.windowsKeyCode == 0x08) {
...@@ -1051,25 +826,25 @@ void DevToolsWindow::HandleKeyboardEvent( ...@@ -1051,25 +826,25 @@ void DevToolsWindow::HandleKeyboardEvent(
} }
content::JavaScriptDialogManager* DevToolsWindow::GetJavaScriptDialogManager() { content::JavaScriptDialogManager* DevToolsWindow::GetJavaScriptDialogManager() {
content::WebContents* inspected_web_contents = GetInspectedWebContents(); WebContents* inspected_web_contents = GetInspectedWebContents();
return (inspected_web_contents && inspected_web_contents->GetDelegate()) ? return (inspected_web_contents && inspected_web_contents->GetDelegate()) ?
inspected_web_contents->GetDelegate()->GetJavaScriptDialogManager() : inspected_web_contents->GetDelegate()->GetJavaScriptDialogManager() :
content::WebContentsDelegate::GetJavaScriptDialogManager(); content::WebContentsDelegate::GetJavaScriptDialogManager();
} }
content::ColorChooser* DevToolsWindow::OpenColorChooser( content::ColorChooser* DevToolsWindow::OpenColorChooser(
content::WebContents* web_contents, WebContents* web_contents,
SkColor initial_color, SkColor initial_color,
const std::vector<content::ColorSuggestion>& suggestions) { const std::vector<content::ColorSuggestion>& suggestions) {
return chrome::ShowColorChooser(web_contents, initial_color); return chrome::ShowColorChooser(web_contents, initial_color);
} }
void DevToolsWindow::RunFileChooser(content::WebContents* web_contents, void DevToolsWindow::RunFileChooser(WebContents* web_contents,
const content::FileChooserParams& params) { const content::FileChooserParams& params) {
FileSelectHelper::RunFileChooser(web_contents, params); FileSelectHelper::RunFileChooser(web_contents, params);
} }
void DevToolsWindow::WebContentsFocused(content::WebContents* contents) { void DevToolsWindow::WebContentsFocused(WebContents* contents) {
Browser* inspected_browser = NULL; Browser* inspected_browser = NULL;
int inspected_tab_index = -1; int inspected_tab_index = -1;
if (is_docked_ && FindInspectedBrowserAndTabIndex(GetInspectedWebContents(), if (is_docked_ && FindInspectedBrowserAndTabIndex(GetInspectedWebContents(),
...@@ -1079,7 +854,7 @@ void DevToolsWindow::WebContentsFocused(content::WebContents* contents) { ...@@ -1079,7 +854,7 @@ void DevToolsWindow::WebContentsFocused(content::WebContents* contents) {
} }
bool DevToolsWindow::PreHandleGestureEvent( bool DevToolsWindow::PreHandleGestureEvent(
content::WebContents* source, WebContents* source,
const blink::WebGestureEvent& event) { const blink::WebGestureEvent& event) {
// Disable pinch zooming. // Disable pinch zooming.
return event.type == blink::WebGestureEvent::GesturePinchBegin || return event.type == blink::WebGestureEvent::GesturePinchBegin ||
...@@ -1087,57 +862,19 @@ bool DevToolsWindow::PreHandleGestureEvent( ...@@ -1087,57 +862,19 @@ bool DevToolsWindow::PreHandleGestureEvent(
event.type == blink::WebGestureEvent::GesturePinchEnd; event.type == blink::WebGestureEvent::GesturePinchEnd;
} }
void DevToolsWindow::DispatchOnEmbedder(const std::string& message) {
std::string method;
base::ListValue empty_params;
base::ListValue* params = &empty_params;
base::DictionaryValue* dict = NULL;
scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
if (!parsed_message ||
!parsed_message->GetAsDictionary(&dict) ||
!dict->GetString(kFrontendHostMethod, &method) ||
(dict->HasKey(kFrontendHostParams) &&
!dict->GetList(kFrontendHostParams, &params))) {
LOG(ERROR) << "Invalid message was sent to embedder: " << message;
return;
}
int id = 0;
dict->GetInteger(kFrontendHostId, &id);
std::string error;
embedder_message_dispatcher_->Dispatch(method, params, &error);
if (id) {
scoped_ptr<base::Value> id_value(base::Value::CreateIntegerValue(id));
scoped_ptr<base::Value> error_value(base::Value::CreateStringValue(error));
CallClientFunction("InspectorFrontendAPI.embedderMessageAck",
id_value.get(), error_value.get(), NULL);
}
}
void DevToolsWindow::ActivateWindow() { void DevToolsWindow::ActivateWindow() {
if (is_docked_ && GetInspectedBrowserWindow()) if (is_docked_ && GetInspectedBrowserWindow())
web_contents_->GetView()->Focus(); web_contents()->GetView()->Focus();
else if (!is_docked_ && !browser_->window()->IsActive()) else if (!is_docked_ && !browser_->window()->IsActive())
browser_->window()->Activate(); browser_->window()->Activate();
} }
void DevToolsWindow::ActivateContents(content::WebContents* contents) {
if (is_docked_) {
content::WebContents* inspected_tab = this->GetInspectedWebContents();
inspected_tab->GetDelegate()->ActivateContents(inspected_tab);
} else {
browser_->window()->Activate();
}
}
void DevToolsWindow::CloseWindow() { void DevToolsWindow::CloseWindow() {
DCHECK(is_docked_); DCHECK(is_docked_);
// This will prevent any activity after frontend is loaded. // This will prevent any activity after frontend is loaded.
action_on_load_ = DevToolsToggleAction::NoOp(); action_on_load_ = DevToolsToggleAction::NoOp();
ignore_set_is_docked_ = true; ignore_set_is_docked_ = true;
web_contents_->DispatchBeforeUnload(false); web_contents()->DispatchBeforeUnload(false);
} }
void DevToolsWindow::SetContentsInsets( void DevToolsWindow::SetContentsInsets(
...@@ -1222,7 +959,7 @@ void DevToolsWindow::SetIsDocked(bool dock_requested) { ...@@ -1222,7 +959,7 @@ void DevToolsWindow::SetIsDocked(bool dock_requested) {
// the browser object's close and delete. Remove observer first. // the browser object's close and delete. Remove observer first.
TabStripModel* tab_strip_model = browser_->tab_strip_model(); TabStripModel* tab_strip_model = browser_->tab_strip_model();
tab_strip_model->DetachWebContentsAt( tab_strip_model->DetachWebContentsAt(
tab_strip_model->GetIndexOfWebContents(web_contents_)); tab_strip_model->GetIndexOfWebContents(web_contents()));
browser_ = NULL; browser_ = NULL;
} else if (!dock_requested && was_docked) { } else if (!dock_requested && was_docked) {
// Update inspected window to hide split and reset it. // Update inspected window to hide split and reset it.
...@@ -1238,7 +975,7 @@ void DevToolsWindow::OpenInNewTab(const std::string& url) { ...@@ -1238,7 +975,7 @@ void DevToolsWindow::OpenInNewTab(const std::string& url) {
content::OpenURLParams params( content::OpenURLParams params(
GURL(url), content::Referrer(), NEW_FOREGROUND_TAB, GURL(url), content::Referrer(), NEW_FOREGROUND_TAB,
content::PAGE_TRANSITION_LINK, false); content::PAGE_TRANSITION_LINK, false);
content::WebContents* inspected_web_contents = GetInspectedWebContents(); WebContents* inspected_web_contents = GetInspectedWebContents();
if (inspected_web_contents) { if (inspected_web_contents) {
inspected_web_contents->OpenURL(params); inspected_web_contents->OpenURL(params);
} else { } else {
...@@ -1264,264 +1001,14 @@ void DevToolsWindow::OpenInNewTab(const std::string& url) { ...@@ -1264,264 +1001,14 @@ void DevToolsWindow::OpenInNewTab(const std::string& url) {
} }
} }
void DevToolsWindow::SaveToFile(const std::string& url, void DevToolsWindow::SetWhitelistedShortcuts(
const std::string& content, const std::string& message) {
bool save_as) { event_forwarder_->SetWhitelistedShortcuts(message);
file_helper_->Save(url, content, save_as,
base::Bind(&DevToolsWindow::FileSavedAs,
weak_factory_.GetWeakPtr(), url),
base::Bind(&DevToolsWindow::CanceledFileSaveAs,
weak_factory_.GetWeakPtr(), url));
}
void DevToolsWindow::AppendToFile(const std::string& url,
const std::string& content) {
file_helper_->Append(url, content,
base::Bind(&DevToolsWindow::AppendedTo,
weak_factory_.GetWeakPtr(), url));
}
void DevToolsWindow::RequestFileSystems() {
CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
file_helper_->RequestFileSystems(base::Bind(
&DevToolsWindow::FileSystemsLoaded, weak_factory_.GetWeakPtr()));
}
void DevToolsWindow::AddFileSystem() {
CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
file_helper_->AddFileSystem(
base::Bind(&DevToolsWindow::FileSystemAdded, weak_factory_.GetWeakPtr()),
base::Bind(&DevToolsWindow::ShowDevToolsConfirmInfoBar,
weak_factory_.GetWeakPtr()));
}
void DevToolsWindow::RemoveFileSystem(const std::string& file_system_path) {
CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
file_helper_->RemoveFileSystem(file_system_path);
base::StringValue file_system_path_value(file_system_path);
CallClientFunction("InspectorFrontendAPI.fileSystemRemoved",
&file_system_path_value, NULL, NULL);
}
void DevToolsWindow::UpgradeDraggedFileSystemPermissions(
const std::string& file_system_url) {
CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
file_helper_->UpgradeDraggedFileSystemPermissions(
file_system_url,
base::Bind(&DevToolsWindow::FileSystemAdded, weak_factory_.GetWeakPtr()),
base::Bind(&DevToolsWindow::ShowDevToolsConfirmInfoBar,
weak_factory_.GetWeakPtr()));
}
void DevToolsWindow::IndexPath(int request_id,
const std::string& file_system_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
if (!file_helper_->IsFileSystemAdded(file_system_path)) {
IndexingDone(request_id, file_system_path);
return;
}
indexing_jobs_[request_id] =
scoped_refptr<DevToolsFileSystemIndexer::FileSystemIndexingJob>(
file_system_indexer_->IndexPath(
file_system_path,
Bind(&DevToolsWindow::IndexingTotalWorkCalculated,
weak_factory_.GetWeakPtr(),
request_id,
file_system_path),
Bind(&DevToolsWindow::IndexingWorked,
weak_factory_.GetWeakPtr(),
request_id,
file_system_path),
Bind(&DevToolsWindow::IndexingDone,
weak_factory_.GetWeakPtr(),
request_id,
file_system_path)));
}
void DevToolsWindow::StopIndexing(int request_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
IndexingJobsMap::iterator it = indexing_jobs_.find(request_id);
if (it == indexing_jobs_.end())
return;
it->second->Stop();
indexing_jobs_.erase(it);
}
void DevToolsWindow::SearchInPath(int request_id,
const std::string& file_system_path,
const std::string& query) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
if (!file_helper_->IsFileSystemAdded(file_system_path)) {
SearchCompleted(request_id, file_system_path, std::vector<std::string>());
return;
}
file_system_indexer_->SearchInPath(file_system_path,
query,
Bind(&DevToolsWindow::SearchCompleted,
weak_factory_.GetWeakPtr(),
request_id,
file_system_path));
}
void DevToolsWindow::ZoomIn() {
chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_IN);
}
void DevToolsWindow::ZoomOut() {
chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_OUT);
}
void DevToolsWindow::ResetZoom() {
chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_RESET);
}
void DevToolsWindow::OpenUrlOnRemoteDeviceAndInspect(
const std::string& browser_id,
const std::string& url) {
if (remote_targets_handler_)
remote_targets_handler_->OpenAndInspect(browser_id, url, profile_);
}
void DevToolsWindow::StartRemoteDevicesListener() {
remote_targets_handler_ = DevToolsRemoteTargetsUIHandler::CreateForAdb(
base::Bind(&DevToolsWindow::PopulateRemoteDevices,
base::Unretained(this)),
profile_);
}
void DevToolsWindow::StopRemoteDevicesListener() {
remote_targets_handler_.reset();
}
void DevToolsWindow::EnableRemoteDeviceCounter(bool enable) {
DevToolsAndroidBridge* adb_bridge =
DevToolsAndroidBridge::Factory::GetForProfile(profile_);
if (!adb_bridge)
return;
DCHECK(device_listener_enabled_ != enable);
device_listener_enabled_ = enable;
if (enable)
adb_bridge->AddDeviceCountListener(this);
else
adb_bridge->RemoveDeviceCountListener(this);
}
void DevToolsWindow::DeviceCountChanged(int count) {
base::FundamentalValue value(count);
CallClientFunction(
"InspectorFrontendAPI.setRemoteDeviceCount", &value, NULL, NULL);
}
void DevToolsWindow::PopulateRemoteDevices(
const std::string& source,
scoped_ptr<base::ListValue> targets) {
CallClientFunction(
"InspectorFrontendAPI.populateRemoteDevices", targets.get(), NULL, NULL);
}
void DevToolsWindow::FileSavedAs(const std::string& url) {
base::StringValue url_value(url);
CallClientFunction("InspectorFrontendAPI.savedURL", &url_value, NULL, NULL);
}
void DevToolsWindow::CanceledFileSaveAs(const std::string& url) {
base::StringValue url_value(url);
CallClientFunction("InspectorFrontendAPI.canceledSaveURL",
&url_value, NULL, NULL);
}
void DevToolsWindow::AppendedTo(const std::string& url) {
base::StringValue url_value(url);
CallClientFunction("InspectorFrontendAPI.appendedToURL", &url_value, NULL,
NULL);
}
void DevToolsWindow::FileSystemsLoaded(
const std::vector<DevToolsFileHelper::FileSystem>& file_systems) {
base::ListValue file_systems_value;
for (size_t i = 0; i < file_systems.size(); ++i)
file_systems_value.Append(CreateFileSystemValue(file_systems[i]));
CallClientFunction("InspectorFrontendAPI.fileSystemsLoaded",
&file_systems_value, NULL, NULL);
}
void DevToolsWindow::FileSystemAdded(
const DevToolsFileHelper::FileSystem& file_system) {
scoped_ptr<base::StringValue> error_string_value(
new base::StringValue(std::string()));
scoped_ptr<base::DictionaryValue> file_system_value;
if (!file_system.file_system_path.empty())
file_system_value.reset(CreateFileSystemValue(file_system));
CallClientFunction("InspectorFrontendAPI.fileSystemAdded",
error_string_value.get(), file_system_value.get(), NULL);
}
void DevToolsWindow::IndexingTotalWorkCalculated(
int request_id,
const std::string& file_system_path,
int total_work) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::FundamentalValue request_id_value(request_id);
base::StringValue file_system_path_value(file_system_path);
base::FundamentalValue total_work_value(total_work);
CallClientFunction("InspectorFrontendAPI.indexingTotalWorkCalculated",
&request_id_value, &file_system_path_value,
&total_work_value);
}
void DevToolsWindow::IndexingWorked(int request_id,
const std::string& file_system_path,
int worked) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::FundamentalValue request_id_value(request_id);
base::StringValue file_system_path_value(file_system_path);
base::FundamentalValue worked_value(worked);
CallClientFunction("InspectorFrontendAPI.indexingWorked", &request_id_value,
&file_system_path_value, &worked_value);
}
void DevToolsWindow::IndexingDone(int request_id,
const std::string& file_system_path) {
indexing_jobs_.erase(request_id);
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::FundamentalValue request_id_value(request_id);
base::StringValue file_system_path_value(file_system_path);
CallClientFunction("InspectorFrontendAPI.indexingDone", &request_id_value,
&file_system_path_value, NULL);
}
void DevToolsWindow::SearchCompleted(
int request_id,
const std::string& file_system_path,
const std::vector<std::string>& file_paths) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::ListValue file_paths_value;
for (std::vector<std::string>::const_iterator it(file_paths.begin());
it != file_paths.end(); ++it) {
file_paths_value.AppendString(*it);
}
base::FundamentalValue request_id_value(request_id);
base::StringValue file_system_path_value(file_system_path);
CallClientFunction("InspectorFrontendAPI.searchCompleted", &request_id_value,
&file_system_path_value, &file_paths_value);
}
void DevToolsWindow::ShowDevToolsConfirmInfoBar(
const base::string16& message,
const InfoBarCallback& callback) {
DevToolsConfirmInfoBarDelegate::Create(
is_docked_ ?
InfoBarService::FromWebContents(GetInspectedWebContents()) :
InfoBarService::FromWebContents(web_contents_),
callback, message);
} }
void DevToolsWindow::CreateDevToolsBrowser() { void DevToolsWindow::CreateDevToolsBrowser() {
std::string wp_key = GetDevToolsWindowPlacementPrefKey(); std::string wp_key = GetDevToolsWindowPlacementPrefKey();
PrefService* prefs = profile_->GetPrefs(); PrefService* prefs = profile()->GetPrefs();
const base::DictionaryValue* wp_pref = prefs->GetDictionary(wp_key.c_str()); const base::DictionaryValue* wp_pref = prefs->GetDictionary(wp_key.c_str());
if (!wp_pref || wp_pref->empty()) { if (!wp_pref || wp_pref->empty()) {
DictionaryPrefUpdate update(prefs, wp_key.c_str()); DictionaryPrefUpdate update(prefs, wp_key.c_str());
...@@ -1535,18 +1022,18 @@ void DevToolsWindow::CreateDevToolsBrowser() { ...@@ -1535,18 +1022,18 @@ void DevToolsWindow::CreateDevToolsBrowser() {
} }
browser_ = new Browser(Browser::CreateParams::CreateForDevTools( browser_ = new Browser(Browser::CreateParams::CreateForDevTools(
profile_, profile(),
chrome::GetHostDesktopTypeForNativeView( chrome::GetHostDesktopTypeForNativeView(
web_contents_->GetView()->GetNativeView()))); web_contents()->GetView()->GetNativeView())));
browser_->tab_strip_model()->AddWebContents( browser_->tab_strip_model()->AddWebContents(
web_contents_, -1, content::PAGE_TRANSITION_AUTO_TOPLEVEL, web_contents(), -1, content::PAGE_TRANSITION_AUTO_TOPLEVEL,
TabStripModel::ADD_ACTIVE); TabStripModel::ADD_ACTIVE);
GetRenderViewHost()->SyncRendererPrefs(); web_contents()->GetRenderViewHost()->SyncRendererPrefs();
} }
// static // static
bool DevToolsWindow::FindInspectedBrowserAndTabIndex( bool DevToolsWindow::FindInspectedBrowserAndTabIndex(
content::WebContents* inspected_web_contents, Browser** browser, int* tab) { WebContents* inspected_web_contents, Browser** browser, int* tab) {
if (!inspected_web_contents) if (!inspected_web_contents)
return false; return false;
...@@ -1606,20 +1093,8 @@ void DevToolsWindow::DoAction(const DevToolsToggleAction& action) { ...@@ -1606,20 +1093,8 @@ void DevToolsWindow::DoAction(const DevToolsToggleAction& action) {
} }
} }
void DevToolsWindow::UpdateTheme() {
ThemeService* tp = ThemeServiceFactory::GetForProfile(profile_);
DCHECK(tp);
std::string command("InspectorFrontendAPI.setToolbarColors(\"" +
SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) +
"\", \"" +
SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)) +
"\")");
web_contents_->GetMainFrame()->ExecuteJavaScript(base::ASCIIToUTF16(command));
}
void DevToolsWindow::AddDevToolsExtensionsToClient() { void DevToolsWindow::AddDevToolsExtensionsToClient() {
content::WebContents* inspected_web_contents = GetInspectedWebContents(); WebContents* inspected_web_contents = GetInspectedWebContents();
if (inspected_web_contents) { if (inspected_web_contents) {
SessionTabHelper* session_tab_helper = SessionTabHelper* session_tab_helper =
SessionTabHelper::FromWebContents(inspected_web_contents); SessionTabHelper::FromWebContents(inspected_web_contents);
...@@ -1628,56 +1103,7 @@ void DevToolsWindow::AddDevToolsExtensionsToClient() { ...@@ -1628,56 +1103,7 @@ void DevToolsWindow::AddDevToolsExtensionsToClient() {
CallClientFunction("WebInspector.setInspectedTabId", &tabId, NULL, NULL); CallClientFunction("WebInspector.setInspectedTabId", &tabId, NULL, NULL);
} }
} }
DevToolsWindowBase::AddDevToolsExtensionsToClient();
Profile* profile =
Profile::FromBrowserContext(web_contents_->GetBrowserContext());
const ExtensionService* extension_service = extensions::ExtensionSystem::Get(
profile->GetOriginalProfile())->extension_service();
if (!extension_service)
return;
const extensions::ExtensionSet* extensions = extension_service->extensions();
base::ListValue results;
for (extensions::ExtensionSet::const_iterator extension(extensions->begin());
extension != extensions->end(); ++extension) {
if (extensions::ManifestURL::GetDevToolsPage(extension->get()).is_empty())
continue;
base::DictionaryValue* extension_info = new base::DictionaryValue();
extension_info->Set(
"startPage",
new base::StringValue(
extensions::ManifestURL::GetDevToolsPage(extension->get()).spec()));
extension_info->Set("name", new base::StringValue((*extension)->name()));
extension_info->Set(
"exposeExperimentalAPIs",
new base::FundamentalValue((*extension)->HasAPIPermission(
extensions::APIPermission::kExperimental)));
results.Append(extension_info);
}
CallClientFunction("WebInspector.addExtensions", &results, NULL, NULL);
}
void DevToolsWindow::CallClientFunction(const std::string& function_name,
const base::Value* arg1,
const base::Value* arg2,
const base::Value* arg3) {
std::string params;
if (arg1) {
std::string json;
base::JSONWriter::Write(arg1, &json);
params.append(json);
if (arg2) {
base::JSONWriter::Write(arg2, &json);
params.append(", " + json);
if (arg3) {
base::JSONWriter::Write(arg3, &json);
params.append(", " + json);
}
}
}
base::string16 javascript =
base::UTF8ToUTF16(function_name + "(" + params + ");");
web_contents_->GetMainFrame()->ExecuteJavaScript(javascript);
} }
void DevToolsWindow::UpdateBrowserToolbar() { void DevToolsWindow::UpdateBrowserToolbar() {
...@@ -1686,12 +1112,13 @@ void DevToolsWindow::UpdateBrowserToolbar() { ...@@ -1686,12 +1112,13 @@ void DevToolsWindow::UpdateBrowserToolbar() {
inspected_window->UpdateToolbar(NULL); inspected_window->UpdateToolbar(NULL);
} }
content::WebContents* DevToolsWindow::GetInspectedWebContents() { WebContents* DevToolsWindow::GetInspectedWebContents() {
return inspected_contents_observer_ ? return inspected_contents_observer_ ?
inspected_contents_observer_->web_contents() : NULL; inspected_contents_observer_->web_contents() : NULL;
} }
void DevToolsWindow::DocumentOnLoadCompletedInMainFrame() { void DevToolsWindow::DocumentOnLoadCompletedInMainFrame() {
DevToolsWindowBase::DocumentOnLoadCompletedInMainFrame();
// We could be in kLoadCompleted state already if frontend reloads itself. // We could be in kLoadCompleted state already if frontend reloads itself.
if (load_state_ != kLoadCompleted) { if (load_state_ != kLoadCompleted) {
// Load is completed when both kIsDockedSet and kOnLoadFired happened. // Load is completed when both kIsDockedSet and kOnLoadFired happened.
...@@ -1705,8 +1132,6 @@ void DevToolsWindow::DocumentOnLoadCompletedInMainFrame() { ...@@ -1705,8 +1132,6 @@ void DevToolsWindow::DocumentOnLoadCompletedInMainFrame() {
void DevToolsWindow::LoadCompleted() { void DevToolsWindow::LoadCompleted() {
Show(action_on_load_); Show(action_on_load_);
action_on_load_ = DevToolsToggleAction::NoOp(); action_on_load_ = DevToolsToggleAction::NoOp();
UpdateTheme();
AddDevToolsExtensionsToClient();
if (!load_completed_callback_.is_null()) { if (!load_completed_callback_.is_null()) {
load_completed_callback_.Run(); load_completed_callback_.Run();
load_completed_callback_ = base::Closure(); load_completed_callback_ = base::Closure();
...@@ -1722,11 +1147,6 @@ void DevToolsWindow::SetLoadCompletedCallback(const base::Closure& closure) { ...@@ -1722,11 +1147,6 @@ void DevToolsWindow::SetLoadCompletedCallback(const base::Closure& closure) {
load_completed_callback_ = closure; load_completed_callback_ = closure;
} }
void DevToolsWindow::SetWhitelistedShortcuts(
const std::string& message) {
event_forwarder_->SetWhitelistedShortcuts(message);
}
bool DevToolsWindow::ForwardKeyboardEvent( bool DevToolsWindow::ForwardKeyboardEvent(
const content::NativeWebKeyboardEvent& event) { const content::NativeWebKeyboardEvent& event) {
return event_forwarder_->ForwardEvent(event); return event_forwarder_->ForwardEvent(event);
......
...@@ -5,62 +5,29 @@ ...@@ -5,62 +5,29 @@
#ifndef CHROME_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_H_ #ifndef CHROME_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_H_
#define CHROME_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_H_ #define CHROME_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_H_
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "chrome/browser/devtools/device/devtools_android_bridge.h"
#include "chrome/browser/devtools/devtools_contents_resizing_strategy.h" #include "chrome/browser/devtools/devtools_contents_resizing_strategy.h"
#include "chrome/browser/devtools/devtools_embedder_message_dispatcher.h"
#include "chrome/browser/devtools/devtools_file_helper.h"
#include "chrome/browser/devtools/devtools_file_system_indexer.h"
#include "chrome/browser/devtools/devtools_targets_ui.h"
#include "chrome/browser/devtools/devtools_toggle_action.h" #include "chrome/browser/devtools/devtools_toggle_action.h"
#include "content/public/browser/devtools_client_host.h" #include "chrome/browser/devtools/devtools_window_base.h"
#include "content/public/browser/devtools_frontend_host_delegate.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_delegate.h"
#include "ui/gfx/size.h"
class Browser; class Browser;
class BrowserWindow; class BrowserWindow;
class DevToolsControllerTest; class DevToolsControllerTest;
class DevToolsEventForwarder; class DevToolsEventForwarder;
class Profile;
namespace base {
class Value;
}
namespace content { namespace content {
class DevToolsAgentHost; class DevToolsAgentHost;
class DevToolsClientHost;
struct FileChooserParams;
struct NativeWebKeyboardEvent; struct NativeWebKeyboardEvent;
class RenderViewHost; class RenderViewHost;
class WebContents;
}
namespace IPC {
class Message;
} }
namespace user_prefs { namespace user_prefs {
class PrefRegistrySyncable; class PrefRegistrySyncable;
} }
class DevToolsWindow : private content::NotificationObserver, class DevToolsWindow : public DevToolsWindowBase,
private content::WebContentsDelegate, public content::WebContentsDelegate {
private content::DevToolsFrontendHostDelegate,
private DevToolsEmbedderMessageDispatcher::Delegate,
private DevToolsAndroidBridge::DeviceCountListener {
public: public:
typedef base::Callback<void(bool)> InfoBarCallback;
static const char kDevToolsApp[]; static const char kDevToolsApp[];
virtual ~DevToolsWindow(); virtual ~DevToolsWindow();
...@@ -122,14 +89,8 @@ class DevToolsWindow : private content::NotificationObserver, ...@@ -122,14 +89,8 @@ class DevToolsWindow : private content::NotificationObserver,
static void InspectElement( static void InspectElement(
content::RenderViewHost* inspected_rvh, int x, int y); content::RenderViewHost* inspected_rvh, int x, int y);
// content::DevToolsFrontendHostDelegate:
virtual void InspectedContentsClosing() OVERRIDE;
content::WebContents* web_contents() { return web_contents_; }
Browser* browser() { return browser_; } // For tests. Browser* browser() { return browser_; } // For tests.
content::RenderViewHost* GetRenderViewHost();
// Inspected WebContents is placed over DevTools WebContents in docked mode. // Inspected WebContents is placed over DevTools WebContents in docked mode.
// The following method returns the resizing strategy of inspected // The following method returns the resizing strategy of inspected
// WebContents relative to DevTools WebContents. // WebContents relative to DevTools WebContents.
...@@ -267,15 +228,14 @@ class DevToolsWindow : private content::NotificationObserver, ...@@ -267,15 +228,14 @@ class DevToolsWindow : private content::NotificationObserver,
bool force_open, bool force_open,
const DevToolsToggleAction& action); const DevToolsToggleAction& action);
// content::NotificationObserver: // content::DevToolsFrontendHostDelegate override:
virtual void Observe(int type, virtual void InspectedContentsClosing() OVERRIDE;
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
// content::WebContentsDelegate: // content::WebContentsDelegate:
virtual content::WebContents* OpenURLFromTab( virtual content::WebContents* OpenURLFromTab(
content::WebContents* source, content::WebContents* source,
const content::OpenURLParams& params) OVERRIDE; const content::OpenURLParams& params) OVERRIDE;
virtual void ActivateContents(content::WebContents* contents) OVERRIDE;
virtual void AddNewContents(content::WebContents* source, virtual void AddNewContents(content::WebContents* source,
content::WebContents* new_contents, content::WebContents* new_contents,
WindowOpenDisposition disposition, WindowOpenDisposition disposition,
...@@ -308,12 +268,8 @@ class DevToolsWindow : private content::NotificationObserver, ...@@ -308,12 +268,8 @@ class DevToolsWindow : private content::NotificationObserver,
content::WebContents* source, content::WebContents* source,
const blink::WebGestureEvent& event) OVERRIDE; const blink::WebGestureEvent& event) OVERRIDE;
// content::DevToolsFrontendHostDelegate override:
virtual void DispatchOnEmbedder(const std::string& message) OVERRIDE;
// DevToolsEmbedderMessageDispatcher::Delegate overrides: // DevToolsEmbedderMessageDispatcher::Delegate overrides:
virtual void ActivateWindow() OVERRIDE; virtual void ActivateWindow() OVERRIDE;
virtual void ActivateContents(content::WebContents* contents) OVERRIDE;
virtual void CloseWindow() OVERRIDE; virtual void CloseWindow() OVERRIDE;
virtual void SetContentsInsets( virtual void SetContentsInsets(
int left, int top, int right, int bottom) OVERRIDE; int left, int top, int right, int bottom) OVERRIDE;
...@@ -323,58 +279,11 @@ class DevToolsWindow : private content::NotificationObserver, ...@@ -323,58 +279,11 @@ class DevToolsWindow : private content::NotificationObserver,
virtual void MoveWindow(int x, int y) OVERRIDE; virtual void MoveWindow(int x, int y) OVERRIDE;
virtual void SetIsDocked(bool is_docked) OVERRIDE; virtual void SetIsDocked(bool is_docked) OVERRIDE;
virtual void OpenInNewTab(const std::string& url) OVERRIDE; virtual void OpenInNewTab(const std::string& url) OVERRIDE;
virtual void SaveToFile(const std::string& url,
const std::string& content,
bool save_as) OVERRIDE;
virtual void AppendToFile(const std::string& url,
const std::string& content) OVERRIDE;
virtual void RequestFileSystems() OVERRIDE;
virtual void AddFileSystem() OVERRIDE;
virtual void RemoveFileSystem(const std::string& file_system_path) OVERRIDE;
virtual void UpgradeDraggedFileSystemPermissions(
const std::string& file_system_url) OVERRIDE;
virtual void IndexPath(int request_id,
const std::string& file_system_path) OVERRIDE;
virtual void StopIndexing(int request_id) OVERRIDE;
virtual void SearchInPath(int request_id,
const std::string& file_system_path,
const std::string& query) OVERRIDE;
virtual void SetWhitelistedShortcuts(const std::string& message) OVERRIDE; virtual void SetWhitelistedShortcuts(const std::string& message) OVERRIDE;
virtual void ZoomIn() OVERRIDE;
virtual void ZoomOut() OVERRIDE; // DevToolsWindowBase overrides
virtual void ResetZoom() OVERRIDE; virtual void AddDevToolsExtensionsToClient() OVERRIDE;
virtual void OpenUrlOnRemoteDeviceAndInspect(const std::string& browser_id, virtual void DocumentOnLoadCompletedInMainFrame() OVERRIDE;
const std::string& url) OVERRIDE;
virtual void StartRemoteDevicesListener() OVERRIDE;
virtual void StopRemoteDevicesListener() OVERRIDE;
virtual void EnableRemoteDeviceCounter(bool enable) OVERRIDE;
// DevToolsAndroidBridge::DeviceCountListener override:
virtual void DeviceCountChanged(int count) OVERRIDE;
// Forwards discovered devices to frontend.
virtual void PopulateRemoteDevices(const std::string& source,
scoped_ptr<base::ListValue> targets);
// DevToolsFileHelper callbacks.
void FileSavedAs(const std::string& url);
void CanceledFileSaveAs(const std::string& url);
void AppendedTo(const std::string& url);
void FileSystemsLoaded(
const std::vector<DevToolsFileHelper::FileSystem>& file_systems);
void FileSystemAdded(const DevToolsFileHelper::FileSystem& file_system);
void IndexingTotalWorkCalculated(int request_id,
const std::string& file_system_path,
int total_work);
void IndexingWorked(int request_id,
const std::string& file_system_path,
int worked);
void IndexingDone(int request_id, const std::string& file_system_path);
void SearchCompleted(int request_id,
const std::string& file_system_path,
const std::vector<std::string>& file_paths);
void ShowDevToolsConfirmInfoBar(const base::string16& message,
const InfoBarCallback& callback);
void CreateDevToolsBrowser(); void CreateDevToolsBrowser();
BrowserWindow* GetInspectedBrowserWindow(); BrowserWindow* GetInspectedBrowserWindow();
...@@ -383,49 +292,24 @@ class DevToolsWindow : private content::NotificationObserver, ...@@ -383,49 +292,24 @@ class DevToolsWindow : private content::NotificationObserver,
void DoAction(const DevToolsToggleAction& action); void DoAction(const DevToolsToggleAction& action);
void LoadCompleted(); void LoadCompleted();
void SetIsDockedAndShowImmediatelyForTest(bool is_docked); void SetIsDockedAndShowImmediatelyForTest(bool is_docked);
void UpdateTheme();
void AddDevToolsExtensionsToClient();
void CallClientFunction(const std::string& function_name,
const base::Value* arg1,
const base::Value* arg2,
const base::Value* arg3);
void UpdateBrowserToolbar(); void UpdateBrowserToolbar();
content::WebContents* GetInspectedWebContents(); content::WebContents* GetInspectedWebContents();
void DocumentOnLoadCompletedInMainFrame();
class InspectedWebContentsObserver; class InspectedWebContentsObserver;
scoped_ptr<InspectedWebContentsObserver> inspected_contents_observer_; scoped_ptr<InspectedWebContentsObserver> inspected_contents_observer_;
class FrontendWebContentsObserver;
friend class FrontendWebContentsObserver;
scoped_ptr<FrontendWebContentsObserver> frontend_contents_observer_;
Profile* profile_;
content::WebContents* web_contents_;
Browser* browser_; Browser* browser_;
bool is_docked_; bool is_docked_;
const bool can_dock_; const bool can_dock_;
bool device_listener_enabled_;
LoadState load_state_; LoadState load_state_;
DevToolsToggleAction action_on_load_; DevToolsToggleAction action_on_load_;
bool ignore_set_is_docked_; bool ignore_set_is_docked_;
content::NotificationRegistrar registrar_;
scoped_ptr<content::DevToolsClientHost> frontend_host_;
scoped_ptr<DevToolsFileHelper> file_helper_;
scoped_refptr<DevToolsFileSystemIndexer> file_system_indexer_;
typedef std::map<
int,
scoped_refptr<DevToolsFileSystemIndexer::FileSystemIndexingJob> >
IndexingJobsMap;
IndexingJobsMap indexing_jobs_;
DevToolsContentsResizingStrategy contents_resizing_strategy_; DevToolsContentsResizingStrategy contents_resizing_strategy_;
// True if we're in the process of handling a beforeunload event originating // True if we're in the process of handling a beforeunload event originating
// from the inspected webcontents, see InterceptPageBeforeUnload for details. // from the inspected webcontents, see InterceptPageBeforeUnload for details.
bool intercepted_page_beforeunload_; bool intercepted_page_beforeunload_;
base::Closure load_completed_callback_; base::Closure load_completed_callback_;
scoped_ptr<DevToolsRemoteTargetsUIHandler> remote_targets_handler_;
scoped_ptr<DevToolsEmbedderMessageDispatcher> embedder_message_dispatcher_;
base::WeakPtrFactory<DevToolsWindow> weak_factory_;
base::TimeTicks inspect_element_start_time_; base::TimeTicks inspect_element_start_time_;
scoped_ptr<DevToolsEventForwarder> event_forwarder_; scoped_ptr<DevToolsEventForwarder> event_forwarder_;
......
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/devtools/devtools_window.h"
#include <algorithm>
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chrome_page_zoom.h"
#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/infobars/confirm_infobar_delegate.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_iterator.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "chrome/common/url_constants.h"
#include "components/infobars/core/infobar.h"
#include "content/public/browser/devtools_client_host.h"
#include "content/public/browser/devtools_manager.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/common/page_transition_types.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/url_constants.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension_set.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
using base::DictionaryValue;
using content::BrowserThread;
namespace {
// DevToolsConfirmInfoBarDelegate ---------------------------------------------
typedef base::Callback<void(bool)> InfoBarCallback;
class DevToolsConfirmInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
// If |infobar_service| is NULL, runs |callback| with a single argument with
// value "false". Otherwise, creates a dev tools confirm infobar and delegate
// and adds the infobar to |infobar_service|.
static void Create(InfoBarService* infobar_service,
const InfoBarCallback& callback,
const base::string16& message);
private:
DevToolsConfirmInfoBarDelegate(
const InfoBarCallback& callback,
const base::string16& message);
virtual ~DevToolsConfirmInfoBarDelegate();
virtual base::string16 GetMessageText() const OVERRIDE;
virtual base::string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
virtual bool Accept() OVERRIDE;
virtual bool Cancel() OVERRIDE;
InfoBarCallback callback_;
const base::string16 message_;
DISALLOW_COPY_AND_ASSIGN(DevToolsConfirmInfoBarDelegate);
};
void DevToolsConfirmInfoBarDelegate::Create(
InfoBarService* infobar_service,
const InfoBarCallback& callback,
const base::string16& message) {
if (!infobar_service) {
callback.Run(false);
return;
}
infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
scoped_ptr<ConfirmInfoBarDelegate>(
new DevToolsConfirmInfoBarDelegate(callback, message))));
}
DevToolsConfirmInfoBarDelegate::DevToolsConfirmInfoBarDelegate(
const InfoBarCallback& callback,
const base::string16& message)
: ConfirmInfoBarDelegate(),
callback_(callback),
message_(message) {
}
DevToolsConfirmInfoBarDelegate::~DevToolsConfirmInfoBarDelegate() {
if (!callback_.is_null())
callback_.Run(false);
}
base::string16 DevToolsConfirmInfoBarDelegate::GetMessageText() const {
return message_;
}
base::string16 DevToolsConfirmInfoBarDelegate::GetButtonLabel(
InfoBarButton button) const {
return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
IDS_DEV_TOOLS_CONFIRM_ALLOW_BUTTON : IDS_DEV_TOOLS_CONFIRM_DENY_BUTTON);
}
bool DevToolsConfirmInfoBarDelegate::Accept() {
callback_.Run(true);
callback_.Reset();
return true;
}
bool DevToolsConfirmInfoBarDelegate::Cancel() {
callback_.Run(false);
callback_.Reset();
return true;
}
static const char kFrontendHostId[] = "id";
static const char kFrontendHostMethod[] = "method";
static const char kFrontendHostParams[] = "params";
std::string SkColorToRGBAString(SkColor color) {
// We avoid StringPrintf because it will use locale specific formatters for
// the double (e.g. ',' instead of '.' in German).
return "rgba(" + base::IntToString(SkColorGetR(color)) + "," +
base::IntToString(SkColorGetG(color)) + "," +
base::IntToString(SkColorGetB(color)) + "," +
base::DoubleToString(SkColorGetA(color) / 255.0) + ")";
}
base::DictionaryValue* CreateFileSystemValue(
DevToolsFileHelper::FileSystem file_system) {
base::DictionaryValue* file_system_value = new base::DictionaryValue();
file_system_value->SetString("fileSystemName", file_system.file_system_name);
file_system_value->SetString("rootURL", file_system.root_url);
file_system_value->SetString("fileSystemPath", file_system.file_system_path);
return file_system_value;
}
Browser* FindBrowser(content::WebContents* web_contents) {
for (chrome::BrowserIterator it; !it.done(); it.Next()) {
int tab_index = it->tab_strip_model()->GetIndexOfWebContents(
web_contents);
if (tab_index != TabStripModel::kNoTab)
return *it;
}
return NULL;
}
} // namespace
// DevToolsWindowBase::FrontendWebContentsObserver ----------------------------
class DevToolsWindowBase::FrontendWebContentsObserver
: public content::WebContentsObserver {
public:
explicit FrontendWebContentsObserver(DevToolsWindowBase* window);
virtual ~FrontendWebContentsObserver();
private:
// contents::WebContentsObserver:
virtual void AboutToNavigateRenderView(
content::RenderViewHost* render_view_host) OVERRIDE;
virtual void DocumentOnLoadCompletedInMainFrame(int32 page_id) OVERRIDE;
virtual void WebContentsDestroyed(content::WebContents*) OVERRIDE;
DevToolsWindowBase* devtools_window_;
DISALLOW_COPY_AND_ASSIGN(FrontendWebContentsObserver);
};
DevToolsWindowBase::FrontendWebContentsObserver::FrontendWebContentsObserver(
DevToolsWindowBase* devtools_window)
: WebContentsObserver(devtools_window->web_contents()),
devtools_window_(devtools_window) {
}
void DevToolsWindowBase::FrontendWebContentsObserver::WebContentsDestroyed(
content::WebContents* contents) {
delete devtools_window_;
}
DevToolsWindowBase::FrontendWebContentsObserver::
~FrontendWebContentsObserver() {
}
void DevToolsWindowBase::FrontendWebContentsObserver::AboutToNavigateRenderView(
content::RenderViewHost* render_view_host) {
content::DevToolsClientHost::SetupDevToolsFrontendClient(render_view_host);
}
void DevToolsWindowBase::FrontendWebContentsObserver::
DocumentOnLoadCompletedInMainFrame(int32 page_id) {
devtools_window_->DocumentOnLoadCompletedInMainFrame();
}
// DevToolsWindowBase ---------------------------------------------------------
DevToolsWindowBase::~DevToolsWindowBase() {
content::DevToolsManager::GetInstance()->ClientHostClosing(
frontend_host_.get());
for (IndexingJobsMap::const_iterator jobs_it(indexing_jobs_.begin());
jobs_it != indexing_jobs_.end(); ++jobs_it) {
jobs_it->second->Stop();
}
indexing_jobs_.clear();
if (device_listener_enabled_)
EnableRemoteDeviceCounter(false);
}
void DevToolsWindowBase::InspectedContentsClosing() {
web_contents_->GetRenderViewHost()->ClosePage();
}
DevToolsWindowBase::DevToolsWindowBase(content::WebContents* web_contents,
const GURL& url)
: profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())),
web_contents_(web_contents),
device_listener_enabled_(false),
weak_factory_(this) {
frontend_contents_observer_.reset(new FrontendWebContentsObserver(this));
web_contents_->GetMutableRendererPrefs()->can_accept_load_drops = false;
web_contents_->GetController().LoadURL(
ApplyThemeToURL(url), content::Referrer(),
content::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string());
frontend_host_.reset(content::DevToolsClientHost::CreateDevToolsFrontendHost(
web_contents_, this));
file_helper_.reset(new DevToolsFileHelper(web_contents_, profile_));
file_system_indexer_ = new DevToolsFileSystemIndexer();
extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
web_contents_);
// Wipe out page icon so that the default application icon is used.
content::NavigationEntry* entry =
web_contents_->GetController().GetActiveEntry();
entry->GetFavicon().image = gfx::Image();
entry->GetFavicon().valid = true;
// Register on-load actions.
registrar_.Add(
this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
content::Source<ThemeService>(
ThemeServiceFactory::GetForProfile(profile_)));
embedder_message_dispatcher_.reset(
DevToolsEmbedderMessageDispatcher::createForDevToolsFrontend(this));
}
GURL DevToolsWindowBase::ApplyThemeToURL(const GURL& base_url) {
std::string frontend_url = base_url.spec();
ThemeService* tp = ThemeServiceFactory::GetForProfile(profile_);
DCHECK(tp);
std::string url_string(
frontend_url +
((frontend_url.find("?") == std::string::npos) ? "?" : "&") +
"dockSide=undocked" + // TODO(dgozman): remove this support in M38.
"&toolbarColor=" +
SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) +
"&textColor=" +
SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)));
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableDevToolsExperiments))
url_string += "&experiments=true";
return GURL(url_string);
}
void DevToolsWindowBase::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, type);
UpdateTheme();
}
void DevToolsWindowBase::DispatchOnEmbedder(const std::string& message) {
std::string method;
base::ListValue empty_params;
base::ListValue* params = &empty_params;
base::DictionaryValue* dict = NULL;
scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
if (!parsed_message ||
!parsed_message->GetAsDictionary(&dict) ||
!dict->GetString(kFrontendHostMethod, &method) ||
(dict->HasKey(kFrontendHostParams) &&
!dict->GetList(kFrontendHostParams, &params))) {
LOG(ERROR) << "Invalid message was sent to embedder: " << message;
return;
}
int id = 0;
dict->GetInteger(kFrontendHostId, &id);
std::string error;
embedder_message_dispatcher_->Dispatch(method, params, &error);
if (id) {
scoped_ptr<base::Value> id_value(base::Value::CreateIntegerValue(id));
scoped_ptr<base::Value> error_value(base::Value::CreateStringValue(error));
CallClientFunction("InspectorFrontendAPI.embedderMessageAck",
id_value.get(), error_value.get(), NULL);
}
}
void DevToolsWindowBase::ActivateWindow() {
web_contents_->GetDelegate()->ActivateContents(web_contents_);
web_contents_->GetView()->Focus();
}
void DevToolsWindowBase::CloseWindow() {
}
void DevToolsWindowBase::SetContentsInsets(
int top, int left, int bottom, int right) {
}
void DevToolsWindowBase::SetContentsResizingStrategy(
const gfx::Insets& insets, const gfx::Size& min_size) {
}
void DevToolsWindowBase::MoveWindow(int x, int y) {
}
void DevToolsWindowBase::SetIsDocked(bool dock_requested) {
}
void DevToolsWindowBase::InspectElementCompleted() {
}
void DevToolsWindowBase::OpenInNewTab(const std::string& url) {
content::OpenURLParams params(
GURL(url), content::Referrer(), NEW_FOREGROUND_TAB,
content::PAGE_TRANSITION_LINK, false);
Browser* browser = FindBrowser(web_contents_);
browser->OpenURL(params);
}
void DevToolsWindowBase::SaveToFile(const std::string& url,
const std::string& content,
bool save_as) {
file_helper_->Save(url, content, save_as,
base::Bind(&DevToolsWindowBase::FileSavedAs,
weak_factory_.GetWeakPtr(), url),
base::Bind(&DevToolsWindowBase::CanceledFileSaveAs,
weak_factory_.GetWeakPtr(), url));
}
void DevToolsWindowBase::AppendToFile(const std::string& url,
const std::string& content) {
file_helper_->Append(url, content,
base::Bind(&DevToolsWindowBase::AppendedTo,
weak_factory_.GetWeakPtr(), url));
}
void DevToolsWindowBase::RequestFileSystems() {
CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
file_helper_->RequestFileSystems(base::Bind(
&DevToolsWindowBase::FileSystemsLoaded, weak_factory_.GetWeakPtr()));
}
void DevToolsWindowBase::AddFileSystem() {
CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
file_helper_->AddFileSystem(
base::Bind(&DevToolsWindowBase::FileSystemAdded,
weak_factory_.GetWeakPtr()),
base::Bind(&DevToolsWindowBase::ShowDevToolsConfirmInfoBar,
weak_factory_.GetWeakPtr()));
}
void DevToolsWindowBase::RemoveFileSystem(
const std::string& file_system_path) {
CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
file_helper_->RemoveFileSystem(file_system_path);
base::StringValue file_system_path_value(file_system_path);
CallClientFunction("InspectorFrontendAPI.fileSystemRemoved",
&file_system_path_value, NULL, NULL);
}
void DevToolsWindowBase::UpgradeDraggedFileSystemPermissions(
const std::string& file_system_url) {
CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
file_helper_->UpgradeDraggedFileSystemPermissions(
file_system_url,
base::Bind(&DevToolsWindowBase::FileSystemAdded,
weak_factory_.GetWeakPtr()),
base::Bind(&DevToolsWindowBase::ShowDevToolsConfirmInfoBar,
weak_factory_.GetWeakPtr()));
}
void DevToolsWindowBase::IndexPath(int request_id,
const std::string& file_system_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
if (!file_helper_->IsFileSystemAdded(file_system_path)) {
IndexingDone(request_id, file_system_path);
return;
}
indexing_jobs_[request_id] =
scoped_refptr<DevToolsFileSystemIndexer::FileSystemIndexingJob>(
file_system_indexer_->IndexPath(
file_system_path,
Bind(&DevToolsWindowBase::IndexingTotalWorkCalculated,
weak_factory_.GetWeakPtr(),
request_id,
file_system_path),
Bind(&DevToolsWindowBase::IndexingWorked,
weak_factory_.GetWeakPtr(),
request_id,
file_system_path),
Bind(&DevToolsWindowBase::IndexingDone,
weak_factory_.GetWeakPtr(),
request_id,
file_system_path)));
}
void DevToolsWindowBase::StopIndexing(int request_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
IndexingJobsMap::iterator it = indexing_jobs_.find(request_id);
if (it == indexing_jobs_.end())
return;
it->second->Stop();
indexing_jobs_.erase(it);
}
void DevToolsWindowBase::SearchInPath(int request_id,
const std::string& file_system_path,
const std::string& query) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
if (!file_helper_->IsFileSystemAdded(file_system_path)) {
SearchCompleted(request_id, file_system_path, std::vector<std::string>());
return;
}
file_system_indexer_->SearchInPath(file_system_path,
query,
Bind(&DevToolsWindowBase::SearchCompleted,
weak_factory_.GetWeakPtr(),
request_id,
file_system_path));
}
void DevToolsWindowBase::SetWhitelistedShortcuts(
const std::string& message) {
}
void DevToolsWindowBase::ZoomIn() {
chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_IN);
}
void DevToolsWindowBase::ZoomOut() {
chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_OUT);
}
void DevToolsWindowBase::ResetZoom() {
chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_RESET);
}
void DevToolsWindowBase::OpenUrlOnRemoteDeviceAndInspect(
const std::string& browser_id,
const std::string& url) {
if (remote_targets_handler_)
remote_targets_handler_->OpenAndInspect(browser_id, url, profile_);
}
void DevToolsWindowBase::StartRemoteDevicesListener() {
remote_targets_handler_ = DevToolsRemoteTargetsUIHandler::CreateForAdb(
base::Bind(&DevToolsWindowBase::PopulateRemoteDevices,
base::Unretained(this)),
profile_);
}
void DevToolsWindowBase::StopRemoteDevicesListener() {
remote_targets_handler_.reset();
}
void DevToolsWindowBase::EnableRemoteDeviceCounter(bool enable) {
DevToolsAndroidBridge* adb_bridge =
DevToolsAndroidBridge::Factory::GetForProfile(profile_);
if (!adb_bridge)
return;
DCHECK(device_listener_enabled_ != enable);
device_listener_enabled_ = enable;
if (enable)
adb_bridge->AddDeviceCountListener(this);
else
adb_bridge->RemoveDeviceCountListener(this);
}
void DevToolsWindowBase::DeviceCountChanged(int count) {
base::FundamentalValue value(count);
CallClientFunction(
"InspectorFrontendAPI.setRemoteDeviceCount", &value, NULL, NULL);
}
void DevToolsWindowBase::PopulateRemoteDevices(
const std::string& source,
scoped_ptr<base::ListValue> targets) {
CallClientFunction(
"InspectorFrontendAPI.populateRemoteDevices", targets.get(), NULL, NULL);
}
void DevToolsWindowBase::FileSavedAs(const std::string& url) {
base::StringValue url_value(url);
CallClientFunction("InspectorFrontendAPI.savedURL", &url_value, NULL, NULL);
}
void DevToolsWindowBase::CanceledFileSaveAs(const std::string& url) {
base::StringValue url_value(url);
CallClientFunction("InspectorFrontendAPI.canceledSaveURL",
&url_value, NULL, NULL);
}
void DevToolsWindowBase::AppendedTo(const std::string& url) {
base::StringValue url_value(url);
CallClientFunction("InspectorFrontendAPI.appendedToURL", &url_value, NULL,
NULL);
}
void DevToolsWindowBase::FileSystemsLoaded(
const std::vector<DevToolsFileHelper::FileSystem>& file_systems) {
base::ListValue file_systems_value;
for (size_t i = 0; i < file_systems.size(); ++i)
file_systems_value.Append(CreateFileSystemValue(file_systems[i]));
CallClientFunction("InspectorFrontendAPI.fileSystemsLoaded",
&file_systems_value, NULL, NULL);
}
void DevToolsWindowBase::FileSystemAdded(
const DevToolsFileHelper::FileSystem& file_system) {
scoped_ptr<base::StringValue> error_string_value(
new base::StringValue(std::string()));
scoped_ptr<base::DictionaryValue> file_system_value;
if (!file_system.file_system_path.empty())
file_system_value.reset(CreateFileSystemValue(file_system));
CallClientFunction("InspectorFrontendAPI.fileSystemAdded",
error_string_value.get(), file_system_value.get(), NULL);
}
void DevToolsWindowBase::IndexingTotalWorkCalculated(
int request_id,
const std::string& file_system_path,
int total_work) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::FundamentalValue request_id_value(request_id);
base::StringValue file_system_path_value(file_system_path);
base::FundamentalValue total_work_value(total_work);
CallClientFunction("InspectorFrontendAPI.indexingTotalWorkCalculated",
&request_id_value, &file_system_path_value,
&total_work_value);
}
void DevToolsWindowBase::IndexingWorked(int request_id,
const std::string& file_system_path,
int worked) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::FundamentalValue request_id_value(request_id);
base::StringValue file_system_path_value(file_system_path);
base::FundamentalValue worked_value(worked);
CallClientFunction("InspectorFrontendAPI.indexingWorked", &request_id_value,
&file_system_path_value, &worked_value);
}
void DevToolsWindowBase::IndexingDone(int request_id,
const std::string& file_system_path) {
indexing_jobs_.erase(request_id);
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::FundamentalValue request_id_value(request_id);
base::StringValue file_system_path_value(file_system_path);
CallClientFunction("InspectorFrontendAPI.indexingDone", &request_id_value,
&file_system_path_value, NULL);
}
void DevToolsWindowBase::SearchCompleted(
int request_id,
const std::string& file_system_path,
const std::vector<std::string>& file_paths) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::ListValue file_paths_value;
for (std::vector<std::string>::const_iterator it(file_paths.begin());
it != file_paths.end(); ++it) {
file_paths_value.AppendString(*it);
}
base::FundamentalValue request_id_value(request_id);
base::StringValue file_system_path_value(file_system_path);
CallClientFunction("InspectorFrontendAPI.searchCompleted", &request_id_value,
&file_system_path_value, &file_paths_value);
}
void DevToolsWindowBase::ShowDevToolsConfirmInfoBar(
const base::string16& message,
const InfoBarCallback& callback) {
DevToolsConfirmInfoBarDelegate::Create(
InfoBarService::FromWebContents(web_contents_),
callback, message);
}
void DevToolsWindowBase::UpdateTheme() {
ThemeService* tp = ThemeServiceFactory::GetForProfile(profile_);
DCHECK(tp);
std::string command("InspectorFrontendAPI.setToolbarColors(\"" +
SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) +
"\", \"" +
SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)) +
"\")");
web_contents_->GetMainFrame()->ExecuteJavaScript(base::ASCIIToUTF16(command));
}
void DevToolsWindowBase::AddDevToolsExtensionsToClient() {
const ExtensionService* extension_service = extensions::ExtensionSystem::Get(
profile_->GetOriginalProfile())->extension_service();
if (!extension_service)
return;
const extensions::ExtensionSet* extensions = extension_service->extensions();
base::ListValue results;
for (extensions::ExtensionSet::const_iterator extension(extensions->begin());
extension != extensions->end(); ++extension) {
if (extensions::ManifestURL::GetDevToolsPage(extension->get()).is_empty())
continue;
base::DictionaryValue* extension_info = new base::DictionaryValue();
extension_info->Set(
"startPage",
new base::StringValue(
extensions::ManifestURL::GetDevToolsPage(
extension->get()).spec()));
extension_info->Set("name", new base::StringValue((*extension)->name()));
extension_info->Set(
"exposeExperimentalAPIs",
new base::FundamentalValue((*extension)->HasAPIPermission(
extensions::APIPermission::kExperimental)));
results.Append(extension_info);
}
CallClientFunction("WebInspector.addExtensions", &results, NULL, NULL);
}
void DevToolsWindowBase::CallClientFunction(const std::string& function_name,
const base::Value* arg1,
const base::Value* arg2,
const base::Value* arg3) {
std::string params;
if (arg1) {
std::string json;
base::JSONWriter::Write(arg1, &json);
params.append(json);
if (arg2) {
base::JSONWriter::Write(arg2, &json);
params.append(", " + json);
if (arg3) {
base::JSONWriter::Write(arg3, &json);
params.append(", " + json);
}
}
}
base::string16 javascript =
base::UTF8ToUTF16(function_name + "(" + params + ");");
web_contents_->GetMainFrame()->ExecuteJavaScript(javascript);
}
void DevToolsWindowBase::DocumentOnLoadCompletedInMainFrame() {
UpdateTheme();
AddDevToolsExtensionsToClient();
}
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_BASE_H_
#define CHROME_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_BASE_H_
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "chrome/browser/devtools/device/devtools_android_bridge.h"
#include "chrome/browser/devtools/devtools_embedder_message_dispatcher.h"
#include "chrome/browser/devtools/devtools_file_helper.h"
#include "chrome/browser/devtools/devtools_file_system_indexer.h"
#include "chrome/browser/devtools/devtools_targets_ui.h"
#include "content/public/browser/devtools_client_host.h"
#include "content/public/browser/devtools_frontend_host_delegate.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "ui/gfx/size.h"
class Profile;
namespace content {
class DevToolsClientHost;
struct FileChooserParams;
class WebContents;
}
// Base implementation of DevTools bindings around front-end.
class DevToolsWindowBase : public content::NotificationObserver,
public content::DevToolsFrontendHostDelegate,
public DevToolsEmbedderMessageDispatcher::Delegate,
public DevToolsAndroidBridge::DeviceCountListener {
public:
virtual ~DevToolsWindowBase();
content::WebContents* web_contents() { return web_contents_; }
// content::NotificationObserver:
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
// content::DevToolsFrontendHostDelegate override:
virtual void InspectedContentsClosing() OVERRIDE;
virtual void DispatchOnEmbedder(const std::string& message) OVERRIDE;
// DevToolsEmbedderMessageDispatcher::Delegate overrides:
virtual void ActivateWindow() OVERRIDE;
virtual void CloseWindow() OVERRIDE;
virtual void SetContentsInsets(
int left, int top, int right, int bottom) OVERRIDE;
virtual void SetContentsResizingStrategy(
const gfx::Insets& insets, const gfx::Size& min_size) OVERRIDE;
virtual void InspectElementCompleted() OVERRIDE;
virtual void MoveWindow(int x, int y) OVERRIDE;
virtual void SetIsDocked(bool is_docked) OVERRIDE;
virtual void OpenInNewTab(const std::string& url) OVERRIDE;
virtual void SaveToFile(const std::string& url,
const std::string& content,
bool save_as) OVERRIDE;
virtual void AppendToFile(const std::string& url,
const std::string& content) OVERRIDE;
virtual void RequestFileSystems() OVERRIDE;
virtual void AddFileSystem() OVERRIDE;
virtual void RemoveFileSystem(const std::string& file_system_path) OVERRIDE;
virtual void UpgradeDraggedFileSystemPermissions(
const std::string& file_system_url) OVERRIDE;
virtual void IndexPath(int request_id,
const std::string& file_system_path) OVERRIDE;
virtual void StopIndexing(int request_id) OVERRIDE;
virtual void SearchInPath(int request_id,
const std::string& file_system_path,
const std::string& query) OVERRIDE;
virtual void SetWhitelistedShortcuts(const std::string& message) OVERRIDE;
virtual void ZoomIn() OVERRIDE;
virtual void ZoomOut() OVERRIDE;
virtual void ResetZoom() OVERRIDE;
virtual void OpenUrlOnRemoteDeviceAndInspect(const std::string& browser_id,
const std::string& url) OVERRIDE;
virtual void StartRemoteDevicesListener() OVERRIDE;
virtual void StopRemoteDevicesListener() OVERRIDE;
virtual void EnableRemoteDeviceCounter(bool enable) OVERRIDE;
// DevToolsAndroidBridge::DeviceCountListener override:
virtual void DeviceCountChanged(int count) OVERRIDE;
// Forwards discovered devices to frontend.
virtual void PopulateRemoteDevices(const std::string& source,
scoped_ptr<base::ListValue> targets);
protected:
DevToolsWindowBase(content::WebContents* web_contents,
const GURL& frontend_url);
virtual void AddDevToolsExtensionsToClient();
virtual void DocumentOnLoadCompletedInMainFrame();
void CallClientFunction(const std::string& function_name,
const base::Value* arg1,
const base::Value* arg2,
const base::Value* arg3);
Profile* profile() { return profile_; }
content::DevToolsClientHost* frontend_host() { return frontend_host_.get(); }
private:
typedef base::Callback<void(bool)> InfoBarCallback;
// DevToolsFileHelper callbacks.
void FileSavedAs(const std::string& url);
void CanceledFileSaveAs(const std::string& url);
void AppendedTo(const std::string& url);
void FileSystemsLoaded(
const std::vector<DevToolsFileHelper::FileSystem>& file_systems);
void FileSystemAdded(const DevToolsFileHelper::FileSystem& file_system);
void IndexingTotalWorkCalculated(int request_id,
const std::string& file_system_path,
int total_work);
void IndexingWorked(int request_id,
const std::string& file_system_path,
int worked);
void IndexingDone(int request_id, const std::string& file_system_path);
void SearchCompleted(int request_id,
const std::string& file_system_path,
const std::vector<std::string>& file_paths);
void ShowDevToolsConfirmInfoBar(const base::string16& message,
const InfoBarCallback& callback);
// Theme and extensions support.
GURL ApplyThemeToURL(const GURL& base_url);
void UpdateTheme();
class FrontendWebContentsObserver;
friend class FrontendWebContentsObserver;
scoped_ptr<FrontendWebContentsObserver> frontend_contents_observer_;
Profile* profile_;
content::WebContents* web_contents_;
bool device_listener_enabled_;
content::NotificationRegistrar registrar_;
scoped_ptr<content::DevToolsClientHost> frontend_host_;
scoped_ptr<DevToolsFileHelper> file_helper_;
scoped_refptr<DevToolsFileSystemIndexer> file_system_indexer_;
typedef std::map<
int,
scoped_refptr<DevToolsFileSystemIndexer::FileSystemIndexingJob> >
IndexingJobsMap;
IndexingJobsMap indexing_jobs_;
scoped_ptr<DevToolsRemoteTargetsUIHandler> remote_targets_handler_;
scoped_ptr<DevToolsEmbedderMessageDispatcher> embedder_message_dispatcher_;
base::WeakPtrFactory<DevToolsWindowBase> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DevToolsWindowBase);
};
#endif // CHROME_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_BASE_H_
...@@ -186,6 +186,8 @@ ...@@ -186,6 +186,8 @@
'browser/devtools/devtools_toggle_action.h', 'browser/devtools/devtools_toggle_action.h',
'browser/devtools/devtools_window.cc', 'browser/devtools/devtools_window.cc',
'browser/devtools/devtools_window.h', 'browser/devtools/devtools_window.h',
'browser/devtools/devtools_window_base.cc',
'browser/devtools/devtools_window_base.h',
'browser/devtools/remote_debugging_server.cc', 'browser/devtools/remote_debugging_server.cc',
'browser/devtools/remote_debugging_server.h', 'browser/devtools/remote_debugging_server.h',
], ],
...@@ -200,6 +202,7 @@ ...@@ -200,6 +202,7 @@
'browser/devtools/devtools_file_system_indexer.cc', 'browser/devtools/devtools_file_system_indexer.cc',
'browser/devtools/devtools_target_impl.cc', 'browser/devtools/devtools_target_impl.cc',
'browser/devtools/devtools_window.cc', 'browser/devtools/devtools_window.cc',
'browser/devtools/devtools_window_base.cc',
'browser/devtools/remote_debugging_server.cc', 'browser/devtools/remote_debugging_server.cc',
], ],
}], }],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment