OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/devtools/devtools_window.h" | 5 #include "chrome/browser/devtools/devtools_window.h" |
6 | |
7 #include <algorithm> | 6 #include <algorithm> |
8 | 7 |
9 #include "base/command_line.h" | 8 #include "base/command_line.h" |
10 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
11 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
12 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
13 #include "base/prefs/scoped_user_pref_update.h" | 12 #include "base/prefs/scoped_user_pref_update.h" |
14 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
15 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
16 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 } | 220 } |
222 | 221 |
223 // DevToolsWindow ------------------------------------------------------------- | 222 // DevToolsWindow ------------------------------------------------------------- |
224 | 223 |
225 namespace { | 224 namespace { |
226 | 225 |
227 typedef std::vector<DevToolsWindow*> DevToolsWindows; | 226 typedef std::vector<DevToolsWindow*> DevToolsWindows; |
228 base::LazyInstance<DevToolsWindows>::Leaky g_instances = | 227 base::LazyInstance<DevToolsWindows>::Leaky g_instances = |
229 LAZY_INSTANCE_INITIALIZER; | 228 LAZY_INSTANCE_INITIALIZER; |
230 | 229 |
231 const char kPrefBottom[] = "dock_bottom"; | 230 // TODO(dgozman): remove after switching to SetIsDocked. |
232 const char kPrefRight[] = "dock_right"; | |
233 const char kPrefUndocked[] = "undocked"; | |
234 | |
235 const char kDockSideBottom[] = "bottom"; | |
236 const char kDockSideRight[] = "right"; | |
237 const char kDockSideUndocked[] = "undocked"; | 231 const char kDockSideUndocked[] = "undocked"; |
238 const char kDockSideMinimized[] = "minimized"; | |
239 | 232 |
240 static const char kFrontendHostId[] = "id"; | 233 static const char kFrontendHostId[] = "id"; |
241 static const char kFrontendHostMethod[] = "method"; | 234 static const char kFrontendHostMethod[] = "method"; |
242 static const char kFrontendHostParams[] = "params"; | 235 static const char kFrontendHostParams[] = "params"; |
243 | 236 |
244 std::string SkColorToRGBAString(SkColor color) { | 237 std::string SkColorToRGBAString(SkColor color) { |
245 // We avoid StringPrintf because it will use locale specific formatters for | 238 // We avoid StringPrintf because it will use locale specific formatters for |
246 // the double (e.g. ',' instead of '.' in German). | 239 // the double (e.g. ',' instead of '.' in German). |
247 return "rgba(" + base::IntToString(SkColorGetR(color)) + "," + | 240 return "rgba(" + base::IntToString(SkColorGetR(color)) + "," + |
248 base::IntToString(SkColorGetG(color)) + "," + | 241 base::IntToString(SkColorGetG(color)) + "," + |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 | 276 |
284 // static | 277 // static |
285 std::string DevToolsWindow::GetDevToolsWindowPlacementPrefKey() { | 278 std::string DevToolsWindow::GetDevToolsWindowPlacementPrefKey() { |
286 return std::string(prefs::kBrowserWindowPlacement) + "_" + | 279 return std::string(prefs::kBrowserWindowPlacement) + "_" + |
287 std::string(kDevToolsApp); | 280 std::string(kDevToolsApp); |
288 } | 281 } |
289 | 282 |
290 // static | 283 // static |
291 void DevToolsWindow::RegisterProfilePrefs( | 284 void DevToolsWindow::RegisterProfilePrefs( |
292 user_prefs::PrefRegistrySyncable* registry) { | 285 user_prefs::PrefRegistrySyncable* registry) { |
293 registry->RegisterBooleanPref( | |
294 prefs::kDevToolsOpenDocked, true, | |
295 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | |
296 registry->RegisterStringPref( | |
297 prefs::kDevToolsDockSide, kDockSideBottom, | |
298 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | |
299 registry->RegisterDictionaryPref( | 286 registry->RegisterDictionaryPref( |
300 prefs::kDevToolsEditedFiles, | 287 prefs::kDevToolsEditedFiles, |
301 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 288 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
302 registry->RegisterDictionaryPref( | 289 registry->RegisterDictionaryPref( |
303 prefs::kDevToolsFileSystemPaths, | 290 prefs::kDevToolsFileSystemPaths, |
304 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 291 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
305 registry->RegisterStringPref( | 292 registry->RegisterStringPref( |
306 prefs::kDevToolsAdbKey, std::string(), | 293 prefs::kDevToolsAdbKey, std::string(), |
307 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 294 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
308 | 295 |
(...skipping 16 matching lines...) Expand all Loading... |
325 registry->RegisterDictionaryPref( | 312 registry->RegisterDictionaryPref( |
326 prefs::kDevToolsPortForwardingConfig, | 313 prefs::kDevToolsPortForwardingConfig, |
327 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 314 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
328 } | 315 } |
329 | 316 |
330 // static | 317 // static |
331 DevToolsWindow* DevToolsWindow::GetDockedInstanceForInspectedTab( | 318 DevToolsWindow* DevToolsWindow::GetDockedInstanceForInspectedTab( |
332 content::WebContents* inspected_web_contents) { | 319 content::WebContents* inspected_web_contents) { |
333 DevToolsWindow* window = GetInstanceForInspectedRenderViewHost( | 320 DevToolsWindow* window = GetInstanceForInspectedRenderViewHost( |
334 inspected_web_contents->GetRenderViewHost()); | 321 inspected_web_contents->GetRenderViewHost()); |
335 return (window && window->IsDocked()) ? window : NULL; | 322 if (!window) |
| 323 return NULL; |
| 324 // Not yet loaded window is treated as docked, but we should not present it |
| 325 // until we decided on docking. |
| 326 bool is_docked_set = window->load_state_ == kLoadCompleted || |
| 327 window->load_state_ == kIsDockedSet; |
| 328 return window->is_docked_ && is_docked_set ? window : NULL; |
336 } | 329 } |
337 | 330 |
338 // static | 331 // static |
339 DevToolsWindow* DevToolsWindow::GetInstanceForInspectedRenderViewHost( | 332 DevToolsWindow* DevToolsWindow::GetInstanceForInspectedRenderViewHost( |
340 content::RenderViewHost* inspected_rvh) { | 333 content::RenderViewHost* inspected_rvh) { |
341 if (!inspected_rvh || !DevToolsAgentHost::HasFor(inspected_rvh)) | 334 if (!inspected_rvh || !DevToolsAgentHost::HasFor(inspected_rvh)) |
342 return NULL; | 335 return NULL; |
343 | 336 |
344 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor( | 337 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor( |
345 inspected_rvh)); | 338 inspected_rvh)); |
346 return FindDevToolsWindow(agent.get()); | 339 return FindDevToolsWindow(agent.get()); |
347 } | 340 } |
348 | 341 |
349 // static | 342 // static |
350 bool DevToolsWindow::IsDevToolsWindow(content::RenderViewHost* window_rvh) { | 343 bool DevToolsWindow::IsDevToolsWindow(content::RenderViewHost* window_rvh) { |
351 return AsDevToolsWindow(window_rvh) != NULL; | 344 return AsDevToolsWindow(window_rvh) != NULL; |
352 } | 345 } |
353 | 346 |
354 // static | 347 // static |
355 DevToolsWindow* DevToolsWindow::OpenDevToolsWindowForWorker( | 348 DevToolsWindow* DevToolsWindow::OpenDevToolsWindowForWorker( |
356 Profile* profile, | 349 Profile* profile, |
357 DevToolsAgentHost* worker_agent) { | 350 DevToolsAgentHost* worker_agent) { |
358 DevToolsWindow* window = FindDevToolsWindow(worker_agent); | 351 DevToolsWindow* window = FindDevToolsWindow(worker_agent); |
359 if (!window) { | 352 if (!window) { |
360 window = DevToolsWindow::CreateDevToolsWindowForWorker(profile); | 353 window = DevToolsWindow::CreateDevToolsWindowForWorker(profile); |
361 // Will disconnect the current client host if there is one. | 354 // Will disconnect the current client host if there is one. |
362 content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor( | 355 content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor( |
363 worker_agent, window->frontend_host_.get()); | 356 worker_agent, window->frontend_host_.get()); |
364 } | 357 } |
365 window->Show(DevToolsToggleAction::Show()); | 358 window->ScheduleShow(DevToolsToggleAction::Show()); |
366 return window; | 359 return window; |
367 } | 360 } |
368 | 361 |
369 // static | 362 // static |
370 DevToolsWindow* DevToolsWindow::CreateDevToolsWindowForWorker( | 363 DevToolsWindow* DevToolsWindow::CreateDevToolsWindowForWorker( |
371 Profile* profile) { | 364 Profile* profile) { |
372 content::RecordAction(base::UserMetricsAction("DevTools_InspectWorker")); | 365 content::RecordAction(base::UserMetricsAction("DevTools_InspectWorker")); |
373 return Create(profile, GURL(), NULL, DEVTOOLS_DOCK_SIDE_UNDOCKED, true, | 366 return Create(profile, GURL(), NULL, true, false, false); |
374 false, false); | |
375 } | 367 } |
376 | 368 |
377 // static | 369 // static |
378 DevToolsWindow* DevToolsWindow::OpenDevToolsWindow( | 370 DevToolsWindow* DevToolsWindow::OpenDevToolsWindow( |
379 content::RenderViewHost* inspected_rvh) { | 371 content::RenderViewHost* inspected_rvh) { |
380 return ToggleDevToolsWindow( | 372 return ToggleDevToolsWindow( |
381 inspected_rvh, true, DevToolsToggleAction::Show()); | 373 inspected_rvh, true, DevToolsToggleAction::Show()); |
382 } | 374 } |
383 | 375 |
384 // static | 376 // static |
| 377 DevToolsWindow* DevToolsWindow::OpenDevToolsWindow( |
| 378 content::RenderViewHost* inspected_rvh, |
| 379 const DevToolsToggleAction& action) { |
| 380 return ToggleDevToolsWindow( |
| 381 inspected_rvh, true, action); |
| 382 } |
| 383 |
| 384 // static |
| 385 DevToolsWindow* DevToolsWindow::OpenDevToolsWindowForTest( |
| 386 content::RenderViewHost* inspected_rvh, |
| 387 bool is_docked) { |
| 388 DevToolsWindow* window = OpenDevToolsWindow(inspected_rvh); |
| 389 window->SetIsDockedAndShowImmediatelyForTest(is_docked); |
| 390 return window; |
| 391 } |
| 392 |
| 393 // static |
| 394 DevToolsWindow* DevToolsWindow::OpenDevToolsWindowForTest( |
| 395 Browser* browser, |
| 396 bool is_docked) { |
| 397 return OpenDevToolsWindowForTest( |
| 398 browser->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(), |
| 399 is_docked); |
| 400 } |
| 401 |
| 402 // static |
385 DevToolsWindow* DevToolsWindow::ToggleDevToolsWindow( | 403 DevToolsWindow* DevToolsWindow::ToggleDevToolsWindow( |
386 Browser* browser, | 404 Browser* browser, |
387 const DevToolsToggleAction& action) { | 405 const DevToolsToggleAction& action) { |
388 if (action.type() == DevToolsToggleAction::kToggle && | 406 if (action.type() == DevToolsToggleAction::kToggle && |
389 browser->is_devtools()) { | 407 browser->is_devtools()) { |
390 browser->tab_strip_model()->CloseAllTabs(); | 408 browser->tab_strip_model()->CloseAllTabs(); |
391 return NULL; | 409 return NULL; |
392 } | 410 } |
393 | 411 |
394 return ToggleDevToolsWindow( | 412 return ToggleDevToolsWindow( |
395 browser->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(), | 413 browser->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(), |
396 action.type() == DevToolsToggleAction::kInspect, action); | 414 action.type() == DevToolsToggleAction::kInspect, action); |
397 } | 415 } |
398 | 416 |
399 // static | 417 // static |
400 void DevToolsWindow::OpenExternalFrontend( | 418 void DevToolsWindow::OpenExternalFrontend( |
401 Profile* profile, | 419 Profile* profile, |
402 const std::string& frontend_url, | 420 const std::string& frontend_url, |
403 content::DevToolsAgentHost* agent_host) { | 421 content::DevToolsAgentHost* agent_host) { |
404 DevToolsWindow* window = FindDevToolsWindow(agent_host); | 422 DevToolsWindow* window = FindDevToolsWindow(agent_host); |
405 if (!window) { | 423 if (!window) { |
406 window = Create(profile, DevToolsUI::GetProxyURL(frontend_url), NULL, | 424 window = Create(profile, DevToolsUI::GetProxyURL(frontend_url), NULL, |
407 DEVTOOLS_DOCK_SIDE_UNDOCKED, false, true, false); | 425 false, true, false); |
408 content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor( | 426 content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor( |
409 agent_host, window->frontend_host_.get()); | 427 agent_host, window->frontend_host_.get()); |
410 } | 428 } |
411 window->Show(DevToolsToggleAction::Show()); | 429 window->ScheduleShow(DevToolsToggleAction::Show()); |
412 } | 430 } |
413 | 431 |
414 // static | 432 // static |
415 DevToolsWindow* DevToolsWindow::ToggleDevToolsWindow( | 433 DevToolsWindow* DevToolsWindow::ToggleDevToolsWindow( |
416 content::RenderViewHost* inspected_rvh, | 434 content::RenderViewHost* inspected_rvh, |
417 bool force_open, | 435 bool force_open, |
418 const DevToolsToggleAction& action) { | 436 const DevToolsToggleAction& action) { |
419 scoped_refptr<DevToolsAgentHost> agent( | 437 scoped_refptr<DevToolsAgentHost> agent( |
420 DevToolsAgentHost::GetOrCreateFor(inspected_rvh)); | 438 DevToolsAgentHost::GetOrCreateFor(inspected_rvh)); |
421 content::DevToolsManager* manager = content::DevToolsManager::GetInstance(); | 439 content::DevToolsManager* manager = content::DevToolsManager::GetInstance(); |
422 DevToolsWindow* window = FindDevToolsWindow(agent.get()); | 440 DevToolsWindow* window = FindDevToolsWindow(agent.get()); |
423 bool do_open = force_open; | 441 bool do_open = force_open; |
424 if (!window) { | 442 if (!window) { |
425 Profile* profile = Profile::FromBrowserContext( | 443 Profile* profile = Profile::FromBrowserContext( |
426 inspected_rvh->GetProcess()->GetBrowserContext()); | 444 inspected_rvh->GetProcess()->GetBrowserContext()); |
427 DevToolsDockSide dock_side = GetDockSideFromPrefs(profile); | |
428 content::RecordAction( | 445 content::RecordAction( |
429 base::UserMetricsAction("DevTools_InspectRenderer")); | 446 base::UserMetricsAction("DevTools_InspectRenderer")); |
430 window = Create(profile, GURL(), inspected_rvh, dock_side, false, false, | 447 window = Create(profile, GURL(), inspected_rvh, false, false, true); |
431 true); | |
432 manager->RegisterDevToolsClientHostFor(agent.get(), | 448 manager->RegisterDevToolsClientHostFor(agent.get(), |
433 window->frontend_host_.get()); | 449 window->frontend_host_.get()); |
434 do_open = true; | 450 do_open = true; |
435 } | 451 } |
436 | 452 |
437 // Update toolbar to reflect DevTools changes. | 453 // Update toolbar to reflect DevTools changes. |
438 window->UpdateBrowserToolbar(); | 454 window->UpdateBrowserToolbar(); |
439 | 455 |
440 // If window is docked and visible, we hide it on toggle. If window is | 456 // If window is docked and visible, we hide it on toggle. If window is |
441 // undocked, we show (activate) it. If window is minimized, we maximize it. | 457 // undocked, we show (activate) it. |
442 if (window->dock_side_ == DEVTOOLS_DOCK_SIDE_MINIMIZED) | 458 if (!window->is_docked_ || do_open) |
443 window->Restore(); | 459 window->ScheduleShow(action); |
444 else if (!window->IsDocked() || do_open) | |
445 window->Show(action); | |
446 else | 460 else |
447 window->CloseWindow(); | 461 window->CloseWindow(); |
448 | 462 |
449 return window; | 463 return window; |
450 } | 464 } |
451 | 465 |
452 // static | 466 // static |
453 void DevToolsWindow::InspectElement(content::RenderViewHost* inspected_rvh, | 467 void DevToolsWindow::InspectElement(content::RenderViewHost* inspected_rvh, |
454 int x, | 468 int x, |
455 int y) { | 469 int y) { |
456 scoped_refptr<DevToolsAgentHost> agent( | 470 scoped_refptr<DevToolsAgentHost> agent( |
457 DevToolsAgentHost::GetOrCreateFor(inspected_rvh)); | 471 DevToolsAgentHost::GetOrCreateFor(inspected_rvh)); |
458 agent->InspectElement(x, y); | 472 agent->InspectElement(x, y); |
459 // TODO(loislo): we should initiate DevTools window opening from within | 473 // TODO(loislo): we should initiate DevTools window opening from within |
460 // renderer. Otherwise, we still can hit a race condition here. | 474 // renderer. Otherwise, we still can hit a race condition here. |
461 OpenDevToolsWindow(inspected_rvh); | 475 OpenDevToolsWindow(inspected_rvh); |
462 } | 476 } |
463 | 477 |
464 // static | 478 // static |
465 int DevToolsWindow::GetMinimizedHeight() { | 479 int DevToolsWindow::GetMinimizedHeight() { |
466 const int kMinimizedDevToolsHeight = 24; | 480 const int kMinimizedDevToolsHeight = 24; |
467 return kMinimizedDevToolsHeight; | 481 return kMinimizedDevToolsHeight; |
468 } | 482 } |
469 | 483 |
470 void DevToolsWindow::InspectedContentsClosing() { | 484 void DevToolsWindow::InspectedContentsClosing() { |
471 intercepted_page_beforeunload_ = false; | 485 intercepted_page_beforeunload_ = false; |
| 486 // This will prevent any activity after frontend is loaded. |
| 487 action_on_load_ = DevToolsToggleAction::NoOp(); |
472 web_contents_->GetRenderViewHost()->ClosePage(); | 488 web_contents_->GetRenderViewHost()->ClosePage(); |
473 } | 489 } |
474 | 490 |
475 content::RenderViewHost* DevToolsWindow::GetRenderViewHost() { | 491 content::RenderViewHost* DevToolsWindow::GetRenderViewHost() { |
476 return web_contents_->GetRenderViewHost(); | 492 return web_contents_->GetRenderViewHost(); |
477 } | 493 } |
478 | 494 |
479 content::DevToolsClientHost* DevToolsWindow::GetDevToolsClientHostForTest() { | |
480 return frontend_host_.get(); | |
481 } | |
482 | |
483 gfx::Insets DevToolsWindow::GetContentsInsets() const { | 495 gfx::Insets DevToolsWindow::GetContentsInsets() const { |
484 return contents_insets_; | 496 return contents_insets_; |
485 } | 497 } |
486 | 498 |
487 gfx::Size DevToolsWindow::GetMinimumSize() const { | 499 gfx::Size DevToolsWindow::GetMinimumSize() const { |
488 const gfx::Size kMinDevToolsSize = gfx::Size(200, 100); | 500 const gfx::Size kMinDevToolsSize = gfx::Size(200, 100); |
489 return kMinDevToolsSize; | 501 return kMinDevToolsSize; |
490 } | 502 } |
491 | 503 |
| 504 void DevToolsWindow::ScheduleShow(const DevToolsToggleAction& action) { |
| 505 if (load_state_ == kLoadCompleted) { |
| 506 Show(action); |
| 507 return; |
| 508 } |
| 509 |
| 510 // Action will be done only after load completed. |
| 511 action_on_load_ = action; |
| 512 |
| 513 if (!can_dock_) { |
| 514 // No harm to show always-undocked window right away. |
| 515 is_docked_ = false; |
| 516 Show(DevToolsToggleAction::Show()); |
| 517 } |
| 518 } |
| 519 |
492 void DevToolsWindow::Show(const DevToolsToggleAction& action) { | 520 void DevToolsWindow::Show(const DevToolsToggleAction& action) { |
493 if (IsDocked()) { | 521 if (action.type() == DevToolsToggleAction::kNoOp) |
| 522 return; |
| 523 |
| 524 if (is_docked_) { |
| 525 DCHECK(can_dock_); |
494 Browser* inspected_browser = NULL; | 526 Browser* inspected_browser = NULL; |
495 int inspected_tab_index = -1; | 527 int inspected_tab_index = -1; |
| 528 FindInspectedBrowserAndTabIndex(GetInspectedWebContents(), |
| 529 &inspected_browser, |
| 530 &inspected_tab_index); |
| 531 DCHECK(inspected_browser); |
| 532 DCHECK(inspected_tab_index != -1); |
| 533 |
496 // Tell inspected browser to update splitter and switch to inspected panel. | 534 // Tell inspected browser to update splitter and switch to inspected panel. |
497 if (!IsInspectedBrowserPopup() && | 535 BrowserWindow* inspected_window = inspected_browser->window(); |
498 FindInspectedBrowserAndTabIndex(GetInspectedWebContents(), | 536 web_contents_->SetDelegate(this); |
499 &inspected_browser, | 537 inspected_window->UpdateDevTools(); |
500 &inspected_tab_index)) { | 538 web_contents_->GetView()->SetInitialFocus(); |
501 BrowserWindow* inspected_window = inspected_browser->window(); | 539 inspected_window->Show(); |
502 web_contents_->SetDelegate(this); | |
503 inspected_window->UpdateDevTools(); | |
504 web_contents_->GetView()->SetInitialFocus(); | |
505 inspected_window->Show(); | |
506 TabStripModel* tab_strip_model = inspected_browser->tab_strip_model(); | |
507 tab_strip_model->ActivateTabAt(inspected_tab_index, true); | |
508 PrefsTabHelper::CreateForWebContents(web_contents_); | |
509 GetRenderViewHost()->SyncRendererPrefs(); | |
510 ScheduleAction(action); | |
511 return; | |
512 } | |
513 | 540 |
514 // Sometimes we don't know where to dock. Stay undocked. | 541 TabStripModel* tab_strip_model = inspected_browser->tab_strip_model(); |
515 dock_side_ = DEVTOOLS_DOCK_SIDE_UNDOCKED; | 542 tab_strip_model->ActivateTabAt(inspected_tab_index, true); |
| 543 PrefsTabHelper::CreateForWebContents(web_contents_); |
| 544 GetRenderViewHost()->SyncRendererPrefs(); |
| 545 |
| 546 DoAction(action); |
| 547 return; |
516 } | 548 } |
517 | 549 |
518 // Avoid consecutive window switching if the devtools window has been opened | 550 // Avoid consecutive window switching if the devtools window has been opened |
519 // and the Inspect Element shortcut is pressed in the inspected tab. | 551 // and the Inspect Element shortcut is pressed in the inspected tab. |
520 bool should_show_window = | 552 bool should_show_window = |
521 !browser_ || (action.type() != DevToolsToggleAction::kInspect); | 553 !browser_ || (action.type() != DevToolsToggleAction::kInspect); |
522 | 554 |
523 if (!browser_) | 555 if (!browser_) |
524 CreateDevToolsBrowser(); | 556 CreateDevToolsBrowser(); |
525 | 557 |
526 if (should_show_window) { | 558 if (should_show_window) { |
527 browser_->window()->Show(); | 559 browser_->window()->Show(); |
528 web_contents_->GetView()->SetInitialFocus(); | 560 web_contents_->GetView()->SetInitialFocus(); |
529 } | 561 } |
530 | 562 |
531 ScheduleAction(action); | 563 DoAction(action); |
532 } | 564 } |
533 | 565 |
534 // static | 566 // static |
535 bool DevToolsWindow::HandleBeforeUnload(content::WebContents* frontend_contents, | 567 bool DevToolsWindow::HandleBeforeUnload(content::WebContents* frontend_contents, |
536 bool proceed, bool* proceed_to_fire_unload) { | 568 bool proceed, bool* proceed_to_fire_unload) { |
537 DevToolsWindow* window = AsDevToolsWindow( | 569 DevToolsWindow* window = AsDevToolsWindow( |
538 frontend_contents->GetRenderViewHost()); | 570 frontend_contents->GetRenderViewHost()); |
539 if (!window) | 571 if (!window) |
540 return false; | 572 return false; |
541 if (!window->intercepted_page_beforeunload_) | 573 if (!window->intercepted_page_beforeunload_) |
542 return false; | 574 return false; |
543 window->BeforeUnloadFired(frontend_contents, proceed, | 575 window->BeforeUnloadFired(frontend_contents, proceed, |
544 proceed_to_fire_unload); | 576 proceed_to_fire_unload); |
545 return true; | 577 return true; |
546 } | 578 } |
547 | 579 |
548 // static | 580 // static |
549 bool DevToolsWindow::InterceptPageBeforeUnload(content::WebContents* contents) { | 581 bool DevToolsWindow::InterceptPageBeforeUnload(content::WebContents* contents) { |
550 DevToolsWindow* window = | 582 DevToolsWindow* window = |
551 DevToolsWindow::GetInstanceForInspectedRenderViewHost( | 583 DevToolsWindow::GetInstanceForInspectedRenderViewHost( |
552 contents->GetRenderViewHost()); | 584 contents->GetRenderViewHost()); |
553 if (!window || window->intercepted_page_beforeunload_) | 585 if (!window || window->intercepted_page_beforeunload_) |
554 return false; | 586 return false; |
555 | 587 |
| 588 // Not yet loaded frontend will not handle beforeunload. |
| 589 if (window->load_state_ != kLoadCompleted) |
| 590 return false; |
| 591 |
556 window->intercepted_page_beforeunload_ = true; | 592 window->intercepted_page_beforeunload_ = true; |
557 // Handle case of devtools inspecting another devtools instance by passing | 593 // Handle case of devtools inspecting another devtools instance by passing |
558 // the call up to the inspecting devtools instance. | 594 // the call up to the inspecting devtools instance. |
559 if (!DevToolsWindow::InterceptPageBeforeUnload(window->web_contents())) { | 595 if (!DevToolsWindow::InterceptPageBeforeUnload(window->web_contents())) { |
560 window->web_contents()->GetRenderViewHost()->FirePageBeforeUnload(false); | 596 window->web_contents()->GetRenderViewHost()->FirePageBeforeUnload(false); |
561 } | 597 } |
562 return true; | 598 return true; |
563 } | 599 } |
564 | 600 |
565 // static | 601 // static |
(...skipping 27 matching lines...) Expand all Loading... |
593 DevToolsWindow *window = | 629 DevToolsWindow *window = |
594 DevToolsWindow::GetInstanceForInspectedRenderViewHost( | 630 DevToolsWindow::GetInstanceForInspectedRenderViewHost( |
595 contents->GetRenderViewHost()); | 631 contents->GetRenderViewHost()); |
596 if (!window) | 632 if (!window) |
597 return; | 633 return; |
598 window->intercepted_page_beforeunload_ = false; | 634 window->intercepted_page_beforeunload_ = false; |
599 // Propagate to devtools opened on devtools if any. | 635 // Propagate to devtools opened on devtools if any. |
600 DevToolsWindow::OnPageCloseCanceled(window->web_contents()); | 636 DevToolsWindow::OnPageCloseCanceled(window->web_contents()); |
601 } | 637 } |
602 | 638 |
603 void DevToolsWindow::SetDockSideForTest(DevToolsDockSide dock_side) { | |
604 SetDockSide(SideToString(dock_side)); | |
605 } | |
606 | |
607 DevToolsWindow::DevToolsWindow(Profile* profile, | 639 DevToolsWindow::DevToolsWindow(Profile* profile, |
608 const GURL& url, | 640 const GURL& url, |
609 content::RenderViewHost* inspected_rvh, | 641 content::RenderViewHost* inspected_rvh, |
610 DevToolsDockSide dock_side) | 642 bool can_dock) |
611 : profile_(profile), | 643 : profile_(profile), |
612 browser_(NULL), | 644 browser_(NULL), |
613 dock_side_(dock_side), | 645 is_docked_(true), |
614 is_loaded_(false), | 646 can_dock_(can_dock), |
615 action_on_load_(DevToolsToggleAction::Show()), | 647 // This initialization allows external front-end to work without changes. |
616 dock_side_before_minimized_(dock_side), | 648 // We don't wait for docking call, but instead immediately show undocked. |
| 649 // Passing "dockSide=undocked" parameter ensures proper UI. |
| 650 load_state_(can_dock ? kNotLoaded : kIsDockedSet), |
| 651 action_on_load_(DevToolsToggleAction::NoOp()), |
| 652 ignore_set_is_docked_for_test_(false), |
617 intercepted_page_beforeunload_(false), | 653 intercepted_page_beforeunload_(false), |
618 weak_factory_(this) { | 654 weak_factory_(this) { |
619 web_contents_ = | 655 web_contents_ = |
620 content::WebContents::Create(content::WebContents::CreateParams(profile)); | 656 content::WebContents::Create(content::WebContents::CreateParams(profile)); |
621 frontend_contents_observer_.reset(new FrontendWebContentsObserver(this)); | 657 frontend_contents_observer_.reset(new FrontendWebContentsObserver(this)); |
622 | 658 |
| 659 // Set up delegate, so we get fully-functional window immediately. |
| 660 // It will not appear in UI though until |load_state_ == kLoadCompleted|. |
| 661 web_contents_->SetDelegate(this); |
| 662 |
623 web_contents_->GetController().LoadURL(url, content::Referrer(), | 663 web_contents_->GetController().LoadURL(url, content::Referrer(), |
624 content::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string()); | 664 content::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string()); |
625 | 665 |
626 frontend_host_.reset(content::DevToolsClientHost::CreateDevToolsFrontendHost( | 666 frontend_host_.reset(content::DevToolsClientHost::CreateDevToolsFrontendHost( |
627 web_contents_, this)); | 667 web_contents_, this)); |
628 file_helper_.reset(new DevToolsFileHelper(web_contents_, profile)); | 668 file_helper_.reset(new DevToolsFileHelper(web_contents_, profile)); |
629 file_system_indexer_ = new DevToolsFileSystemIndexer(); | 669 file_system_indexer_ = new DevToolsFileSystemIndexer(); |
630 extensions::ExtensionWebContentsObserver::CreateForWebContents(web_contents_); | 670 extensions::ExtensionWebContentsObserver::CreateForWebContents(web_contents_); |
631 | 671 |
632 g_instances.Get().push_back(this); | 672 g_instances.Get().push_back(this); |
(...skipping 17 matching lines...) Expand all Loading... |
650 | 690 |
651 embedder_message_dispatcher_.reset( | 691 embedder_message_dispatcher_.reset( |
652 new DevToolsEmbedderMessageDispatcher(this)); | 692 new DevToolsEmbedderMessageDispatcher(this)); |
653 } | 693 } |
654 | 694 |
655 // static | 695 // static |
656 DevToolsWindow* DevToolsWindow::Create( | 696 DevToolsWindow* DevToolsWindow::Create( |
657 Profile* profile, | 697 Profile* profile, |
658 const GURL& frontend_url, | 698 const GURL& frontend_url, |
659 content::RenderViewHost* inspected_rvh, | 699 content::RenderViewHost* inspected_rvh, |
660 DevToolsDockSide dock_side, | |
661 bool shared_worker_frontend, | 700 bool shared_worker_frontend, |
662 bool external_frontend, | 701 bool external_frontend, |
663 bool can_dock) { | 702 bool can_dock) { |
664 if (inspected_rvh) { | 703 if (inspected_rvh) { |
665 // Check for a place to dock. | 704 // Check for a place to dock. |
666 Browser* browser = NULL; | 705 Browser* browser = NULL; |
667 int tab; | 706 int tab; |
668 content::WebContents* inspected_web_contents = | 707 content::WebContents* inspected_web_contents = |
669 content::WebContents::FromRenderViewHost(inspected_rvh); | 708 content::WebContents::FromRenderViewHost(inspected_rvh); |
670 if (!FindInspectedBrowserAndTabIndex(inspected_web_contents, | 709 if (!FindInspectedBrowserAndTabIndex(inspected_web_contents, |
671 &browser, &tab) || | 710 &browser, &tab) || |
672 browser->is_type_popup()) { | 711 browser->is_type_popup()) { |
673 can_dock = false; | 712 can_dock = false; |
674 } | 713 } |
675 } | 714 } |
676 | 715 |
677 // Create WebContents with devtools. | 716 // Create WebContents with devtools. |
678 GURL url(GetDevToolsURL(profile, frontend_url, dock_side, | 717 GURL url(GetDevToolsURL(profile, frontend_url, |
679 shared_worker_frontend, | 718 shared_worker_frontend, |
680 external_frontend, | 719 external_frontend, |
681 can_dock)); | 720 can_dock)); |
682 return new DevToolsWindow(profile, url, inspected_rvh, dock_side); | 721 return new DevToolsWindow(profile, url, inspected_rvh, can_dock); |
683 } | 722 } |
684 | 723 |
685 // static | 724 // static |
686 GURL DevToolsWindow::GetDevToolsURL(Profile* profile, | 725 GURL DevToolsWindow::GetDevToolsURL(Profile* profile, |
687 const GURL& base_url, | 726 const GURL& base_url, |
688 DevToolsDockSide dock_side, | |
689 bool shared_worker_frontend, | 727 bool shared_worker_frontend, |
690 bool external_frontend, | 728 bool external_frontend, |
691 bool can_dock) { | 729 bool can_dock) { |
692 if (base_url.SchemeIs("data")) | 730 if (base_url.SchemeIs("data")) |
693 return base_url; | 731 return base_url; |
694 | 732 |
695 std::string frontend_url( | 733 std::string frontend_url( |
696 base_url.is_empty() ? chrome::kChromeUIDevToolsURL : base_url.spec()); | 734 base_url.is_empty() ? chrome::kChromeUIDevToolsURL : base_url.spec()); |
697 ThemeService* tp = ThemeServiceFactory::GetForProfile(profile); | 735 ThemeService* tp = ThemeServiceFactory::GetForProfile(profile); |
698 DCHECK(tp); | 736 DCHECK(tp); |
699 std::string url_string( | 737 std::string url_string( |
700 frontend_url + | 738 frontend_url + |
701 ((frontend_url.find("?") == std::string::npos) ? "?" : "&") + | 739 ((frontend_url.find("?") == std::string::npos) ? "?" : "&") + |
702 "dockSide=" + SideToString(dock_side) + | 740 "dockSide=undocked" + // TODO(dgozman): remove this support in M38. |
703 "&toolbarColor=" + | 741 "&toolbarColor=" + |
704 SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) + | 742 SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) + |
705 "&textColor=" + | 743 "&textColor=" + |
706 SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT))); | 744 SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT))); |
707 if (shared_worker_frontend) | 745 if (shared_worker_frontend) |
708 url_string += "&isSharedWorker=true"; | 746 url_string += "&isSharedWorker=true"; |
709 if (external_frontend) | 747 if (external_frontend) |
710 url_string += "&remoteFrontend=true"; | 748 url_string += "&remoteFrontend=true"; |
711 if (can_dock) | 749 if (can_dock) |
712 url_string += "&can_dock=true"; | 750 url_string += "&can_dock=true"; |
(...skipping 25 matching lines...) Expand all Loading... |
738 return NULL; | 776 return NULL; |
739 DevToolsWindows* instances = &g_instances.Get(); | 777 DevToolsWindows* instances = &g_instances.Get(); |
740 for (DevToolsWindows::iterator it(instances->begin()); it != instances->end(); | 778 for (DevToolsWindows::iterator it(instances->begin()); it != instances->end(); |
741 ++it) { | 779 ++it) { |
742 if ((*it)->web_contents_->GetRenderViewHost() == window_rvh) | 780 if ((*it)->web_contents_->GetRenderViewHost() == window_rvh) |
743 return *it; | 781 return *it; |
744 } | 782 } |
745 return NULL; | 783 return NULL; |
746 } | 784 } |
747 | 785 |
| 786 // TODO(dgozman): remove after switch to SetIsDocked. |
748 // static | 787 // static |
749 DevToolsDockSide DevToolsWindow::GetDockSideFromPrefs(Profile* profile) { | 788 bool DevToolsWindow::IsDockedFromString(const std::string& dock_side) { |
750 std::string dock_side = | 789 return dock_side != kDockSideUndocked; |
751 profile->GetPrefs()->GetString(prefs::kDevToolsDockSide); | |
752 | |
753 // Migrate prefs. | |
754 const char kOldPrefBottom[] = "bottom"; | |
755 const char kOldPrefRight[] = "right"; | |
756 if ((dock_side == kOldPrefBottom) || (dock_side == kOldPrefRight)) { | |
757 if (!profile->GetPrefs()->GetBoolean(prefs::kDevToolsOpenDocked)) | |
758 return DEVTOOLS_DOCK_SIDE_UNDOCKED; | |
759 return (dock_side == kOldPrefBottom) ? | |
760 DEVTOOLS_DOCK_SIDE_BOTTOM : DEVTOOLS_DOCK_SIDE_RIGHT; | |
761 } | |
762 | |
763 if (dock_side == kPrefUndocked) | |
764 return DEVTOOLS_DOCK_SIDE_UNDOCKED; | |
765 if (dock_side == kPrefRight) | |
766 return DEVTOOLS_DOCK_SIDE_RIGHT; | |
767 // Default to docked to bottom. | |
768 return DEVTOOLS_DOCK_SIDE_BOTTOM; | |
769 } | |
770 | |
771 // static | |
772 std::string DevToolsWindow::SideToString(DevToolsDockSide dock_side) { | |
773 switch (dock_side) { | |
774 case DEVTOOLS_DOCK_SIDE_UNDOCKED: return kDockSideUndocked; | |
775 case DEVTOOLS_DOCK_SIDE_RIGHT: return kDockSideRight; | |
776 case DEVTOOLS_DOCK_SIDE_BOTTOM: return kDockSideBottom; | |
777 case DEVTOOLS_DOCK_SIDE_MINIMIZED: return kDockSideMinimized; | |
778 default: return kDockSideUndocked; | |
779 } | |
780 } | |
781 | |
782 // static | |
783 DevToolsDockSide DevToolsWindow::SideFromString( | |
784 const std::string& dock_side) { | |
785 if (dock_side == kDockSideRight) | |
786 return DEVTOOLS_DOCK_SIDE_RIGHT; | |
787 if (dock_side == kDockSideBottom) | |
788 return DEVTOOLS_DOCK_SIDE_BOTTOM; | |
789 return (dock_side == kDockSideMinimized) ? | |
790 DEVTOOLS_DOCK_SIDE_MINIMIZED : DEVTOOLS_DOCK_SIDE_UNDOCKED; | |
791 } | 790 } |
792 | 791 |
793 void DevToolsWindow::Observe(int type, | 792 void DevToolsWindow::Observe(int type, |
794 const content::NotificationSource& source, | 793 const content::NotificationSource& source, |
795 const content::NotificationDetails& details) { | 794 const content::NotificationDetails& details) { |
796 DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, type); | 795 DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, type); |
797 UpdateTheme(); | 796 UpdateTheme(); |
798 } | 797 } |
799 | 798 |
800 content::WebContents* DevToolsWindow::OpenURLFromTab( | 799 content::WebContents* DevToolsWindow::OpenURLFromTab( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
833 bool* was_blocked) { | 832 bool* was_blocked) { |
834 content::WebContents* inspected_web_contents = GetInspectedWebContents(); | 833 content::WebContents* inspected_web_contents = GetInspectedWebContents(); |
835 if (inspected_web_contents) { | 834 if (inspected_web_contents) { |
836 inspected_web_contents->GetDelegate()->AddNewContents( | 835 inspected_web_contents->GetDelegate()->AddNewContents( |
837 source, new_contents, disposition, initial_pos, user_gesture, | 836 source, new_contents, disposition, initial_pos, user_gesture, |
838 was_blocked); | 837 was_blocked); |
839 } | 838 } |
840 } | 839 } |
841 | 840 |
842 void DevToolsWindow::CloseContents(content::WebContents* source) { | 841 void DevToolsWindow::CloseContents(content::WebContents* source) { |
843 CHECK(IsDocked()); | 842 CHECK(is_docked_); |
| 843 // This will prevent any activity after frontend is loaded. |
| 844 action_on_load_ = DevToolsToggleAction::NoOp(); |
844 // Update dev tools to reflect removed dev tools window. | 845 // Update dev tools to reflect removed dev tools window. |
845 BrowserWindow* inspected_window = GetInspectedBrowserWindow(); | 846 BrowserWindow* inspected_window = GetInspectedBrowserWindow(); |
846 if (inspected_window) | 847 if (inspected_window) |
847 inspected_window->UpdateDevTools(); | 848 inspected_window->UpdateDevTools(); |
848 // In case of docked web_contents_, we own it so delete here. | 849 // In case of docked web_contents_, we own it so delete here. |
849 // Embedding DevTools window will be deleted as a result of | 850 // Embedding DevTools window will be deleted as a result of |
850 // WebContentsDestroyed callback. | 851 // WebContentsDestroyed callback. |
851 delete web_contents_; | 852 delete web_contents_; |
852 } | 853 } |
853 | 854 |
(...skipping 19 matching lines...) Expand all Loading... |
873 DCHECK(!should_proceed); | 874 DCHECK(!should_proceed); |
874 } | 875 } |
875 *proceed_to_fire_unload = false; | 876 *proceed_to_fire_unload = false; |
876 } | 877 } |
877 } | 878 } |
878 | 879 |
879 bool DevToolsWindow::PreHandleKeyboardEvent( | 880 bool DevToolsWindow::PreHandleKeyboardEvent( |
880 content::WebContents* source, | 881 content::WebContents* source, |
881 const content::NativeWebKeyboardEvent& event, | 882 const content::NativeWebKeyboardEvent& event, |
882 bool* is_keyboard_shortcut) { | 883 bool* is_keyboard_shortcut) { |
883 if (IsDocked()) { | 884 if (is_docked_) { |
884 BrowserWindow* inspected_window = GetInspectedBrowserWindow(); | 885 BrowserWindow* inspected_window = GetInspectedBrowserWindow(); |
885 if (inspected_window) { | 886 if (inspected_window) { |
886 return inspected_window->PreHandleKeyboardEvent(event, | 887 return inspected_window->PreHandleKeyboardEvent(event, |
887 is_keyboard_shortcut); | 888 is_keyboard_shortcut); |
888 } | 889 } |
889 } | 890 } |
890 return false; | 891 return false; |
891 } | 892 } |
892 | 893 |
893 void DevToolsWindow::HandleKeyboardEvent( | 894 void DevToolsWindow::HandleKeyboardEvent( |
894 content::WebContents* source, | 895 content::WebContents* source, |
895 const content::NativeWebKeyboardEvent& event) { | 896 const content::NativeWebKeyboardEvent& event) { |
896 if (IsDocked()) { | 897 if (is_docked_) { |
897 if (event.windowsKeyCode == 0x08) { | 898 if (event.windowsKeyCode == 0x08) { |
898 // Do not navigate back in history on Windows (http://crbug.com/74156). | 899 // Do not navigate back in history on Windows (http://crbug.com/74156). |
899 return; | 900 return; |
900 } | 901 } |
901 BrowserWindow* inspected_window = GetInspectedBrowserWindow(); | 902 BrowserWindow* inspected_window = GetInspectedBrowserWindow(); |
902 if (inspected_window) | 903 if (inspected_window) |
903 inspected_window->HandleKeyboardEvent(event); | 904 inspected_window->HandleKeyboardEvent(event); |
904 } | 905 } |
905 } | 906 } |
906 | 907 |
(...skipping 12 matching lines...) Expand all Loading... |
919 } | 920 } |
920 | 921 |
921 void DevToolsWindow::RunFileChooser(content::WebContents* web_contents, | 922 void DevToolsWindow::RunFileChooser(content::WebContents* web_contents, |
922 const content::FileChooserParams& params) { | 923 const content::FileChooserParams& params) { |
923 FileSelectHelper::RunFileChooser(web_contents, params); | 924 FileSelectHelper::RunFileChooser(web_contents, params); |
924 } | 925 } |
925 | 926 |
926 void DevToolsWindow::WebContentsFocused(content::WebContents* contents) { | 927 void DevToolsWindow::WebContentsFocused(content::WebContents* contents) { |
927 Browser* inspected_browser = NULL; | 928 Browser* inspected_browser = NULL; |
928 int inspected_tab_index = -1; | 929 int inspected_tab_index = -1; |
929 if (IsDocked() && FindInspectedBrowserAndTabIndex(GetInspectedWebContents(), | 930 if (is_docked_ && FindInspectedBrowserAndTabIndex(GetInspectedWebContents(), |
930 &inspected_browser, | 931 &inspected_browser, |
931 &inspected_tab_index)) | 932 &inspected_tab_index)) |
932 inspected_browser->window()->WebContentsFocused(contents); | 933 inspected_browser->window()->WebContentsFocused(contents); |
933 } | 934 } |
934 | 935 |
935 void DevToolsWindow::DispatchOnEmbedder(const std::string& message) { | 936 void DevToolsWindow::DispatchOnEmbedder(const std::string& message) { |
936 std::string method; | 937 std::string method; |
937 base::ListValue empty_params; | 938 base::ListValue empty_params; |
938 base::ListValue* params = &empty_params; | 939 base::ListValue* params = &empty_params; |
939 | 940 |
(...skipping 14 matching lines...) Expand all Loading... |
954 std::string error = embedder_message_dispatcher_->Dispatch(method, params); | 955 std::string error = embedder_message_dispatcher_->Dispatch(method, params); |
955 if (id) { | 956 if (id) { |
956 scoped_ptr<base::Value> id_value(base::Value::CreateIntegerValue(id)); | 957 scoped_ptr<base::Value> id_value(base::Value::CreateIntegerValue(id)); |
957 scoped_ptr<base::Value> error_value(base::Value::CreateStringValue(error)); | 958 scoped_ptr<base::Value> error_value(base::Value::CreateStringValue(error)); |
958 CallClientFunction("InspectorFrontendAPI.embedderMessageAck", | 959 CallClientFunction("InspectorFrontendAPI.embedderMessageAck", |
959 id_value.get(), error_value.get(), NULL); | 960 id_value.get(), error_value.get(), NULL); |
960 } | 961 } |
961 } | 962 } |
962 | 963 |
963 void DevToolsWindow::ActivateWindow() { | 964 void DevToolsWindow::ActivateWindow() { |
964 if (IsDocked() && GetInspectedBrowserWindow()) | 965 if (is_docked_ && GetInspectedBrowserWindow()) |
965 web_contents_->GetView()->Focus(); | 966 web_contents_->GetView()->Focus(); |
966 else if (!IsDocked() && !browser_->window()->IsActive()) | 967 else if (!is_docked_ && !browser_->window()->IsActive()) |
967 browser_->window()->Activate(); | 968 browser_->window()->Activate(); |
968 } | 969 } |
969 | 970 |
970 void DevToolsWindow::ActivateContents(content::WebContents* contents) { | 971 void DevToolsWindow::ActivateContents(content::WebContents* contents) { |
971 if (IsDocked()) { | 972 if (is_docked_) { |
972 content::WebContents* inspected_tab = this->GetInspectedWebContents(); | 973 content::WebContents* inspected_tab = this->GetInspectedWebContents(); |
973 inspected_tab->GetDelegate()->ActivateContents(inspected_tab); | 974 inspected_tab->GetDelegate()->ActivateContents(inspected_tab); |
974 } else { | 975 } else { |
975 browser_->window()->Activate(); | 976 browser_->window()->Activate(); |
976 } | 977 } |
977 } | 978 } |
978 | 979 |
979 void DevToolsWindow::CloseWindow() { | 980 void DevToolsWindow::CloseWindow() { |
980 DCHECK(IsDocked()); | 981 DCHECK(is_docked_); |
| 982 // This will prevent any activity after frontend is loaded. |
| 983 action_on_load_ = DevToolsToggleAction::NoOp(); |
981 web_contents_->GetRenderViewHost()->FirePageBeforeUnload(false); | 984 web_contents_->GetRenderViewHost()->FirePageBeforeUnload(false); |
982 } | 985 } |
983 | 986 |
984 void DevToolsWindow::SetContentsInsets( | 987 void DevToolsWindow::SetContentsInsets( |
985 int top, int left, int bottom, int right) { | 988 int top, int left, int bottom, int right) { |
986 if (contents_insets_.top() == top && | 989 if (contents_insets_.top() == top && |
987 contents_insets_.left() == left && | 990 contents_insets_.left() == left && |
988 contents_insets_.bottom() == bottom && | 991 contents_insets_.bottom() == bottom && |
989 contents_insets_.right() == right) { | 992 contents_insets_.right() == right) { |
990 return; | 993 return; |
991 } | 994 } |
992 | 995 |
993 contents_insets_ = gfx::Insets(top, left, bottom, right); | 996 contents_insets_ = gfx::Insets(top, left, bottom, right); |
994 if (IsDocked()) { | 997 if (is_docked_) { |
995 // Update inspected window. | 998 // Update inspected window. |
996 BrowserWindow* inspected_window = GetInspectedBrowserWindow(); | 999 BrowserWindow* inspected_window = GetInspectedBrowserWindow(); |
997 if (inspected_window) | 1000 if (inspected_window) |
998 inspected_window->UpdateDevTools(); | 1001 inspected_window->UpdateDevTools(); |
999 } | 1002 } |
1000 } | 1003 } |
1001 | 1004 |
1002 void DevToolsWindow::MoveWindow(int x, int y) { | 1005 void DevToolsWindow::MoveWindow(int x, int y) { |
1003 if (!IsDocked()) { | 1006 if (!is_docked_) { |
1004 gfx::Rect bounds = browser_->window()->GetBounds(); | 1007 gfx::Rect bounds = browser_->window()->GetBounds(); |
1005 bounds.Offset(x, y); | 1008 bounds.Offset(x, y); |
1006 browser_->window()->SetBounds(bounds); | 1009 browser_->window()->SetBounds(bounds); |
1007 } | 1010 } |
1008 } | 1011 } |
1009 | 1012 |
| 1013 void DevToolsWindow::SetIsDockedAndShowImmediatelyForTest(bool is_docked) { |
| 1014 DCHECK(!is_docked || can_dock_); |
| 1015 if (load_state_ == kLoadCompleted) { |
| 1016 SetIsDocked(is_docked); |
| 1017 } else { |
| 1018 is_docked_ = is_docked; |
| 1019 load_state_ = load_state_ == kNotLoaded ? kIsDockedSet : kLoadCompleted; |
| 1020 // Note that action_on_load_ will be performed after the load is actually |
| 1021 // completed. For now, just show the window. |
| 1022 Show(DevToolsToggleAction::Show()); |
| 1023 if (load_state_ == kLoadCompleted) |
| 1024 LoadCompleted(); |
| 1025 } |
| 1026 ignore_set_is_docked_for_test_ = true; |
| 1027 } |
| 1028 |
1010 void DevToolsWindow::SetDockSide(const std::string& side) { | 1029 void DevToolsWindow::SetDockSide(const std::string& side) { |
1011 DevToolsDockSide requested_side = SideFromString(side); | 1030 // TODO(dgozman): remove this method after frontend switches to SetIsDocked. |
1012 bool dock_requested = requested_side != DEVTOOLS_DOCK_SIDE_UNDOCKED; | 1031 SetIsDocked(IsDockedFromString(side)); |
1013 bool is_docked = IsDocked(); | 1032 } |
1014 | 1033 |
1015 if (dock_requested && | 1034 void DevToolsWindow::SetIsDocked(bool dock_requested) { |
1016 (!GetInspectedWebContents() || !GetInspectedBrowserWindow() || | 1035 if (ignore_set_is_docked_for_test_) |
1017 IsInspectedBrowserPopup())) { | 1036 return; |
1018 // Cannot dock, avoid window flashing due to close-reopen cycle. | 1037 |
| 1038 DCHECK(can_dock_ || !dock_requested); |
| 1039 if (!can_dock_) |
| 1040 dock_requested = false; |
| 1041 |
| 1042 bool was_docked = is_docked_; |
| 1043 is_docked_ = dock_requested; |
| 1044 |
| 1045 if (load_state_ != kLoadCompleted) { |
| 1046 // This is a first time call we waited for to initialize. |
| 1047 load_state_ = load_state_ == kNotLoaded ? kIsDockedSet : kLoadCompleted; |
| 1048 if (load_state_ == kLoadCompleted) |
| 1049 LoadCompleted(); |
1019 return; | 1050 return; |
1020 } | 1051 } |
1021 | 1052 |
1022 if ((dock_side_ != DEVTOOLS_DOCK_SIDE_MINIMIZED) && | 1053 if (dock_requested == was_docked) |
1023 (requested_side == DEVTOOLS_DOCK_SIDE_MINIMIZED)) | 1054 return; |
1024 dock_side_before_minimized_ = dock_side_; | |
1025 | 1055 |
1026 dock_side_ = requested_side; | 1056 if (dock_requested && !was_docked) { |
1027 if (dock_requested && !is_docked) { | |
1028 // Detach window from the external devtools browser. It will lead to | 1057 // Detach window from the external devtools browser. It will lead to |
1029 // the browser object's close and delete. Remove observer first. | 1058 // the browser object's close and delete. Remove observer first. |
1030 TabStripModel* tab_strip_model = browser_->tab_strip_model(); | 1059 TabStripModel* tab_strip_model = browser_->tab_strip_model(); |
1031 tab_strip_model->DetachWebContentsAt( | 1060 tab_strip_model->DetachWebContentsAt( |
1032 tab_strip_model->GetIndexOfWebContents(web_contents_)); | 1061 tab_strip_model->GetIndexOfWebContents(web_contents_)); |
1033 browser_ = NULL; | 1062 browser_ = NULL; |
1034 } else if (!dock_requested && is_docked) { | 1063 } else if (!dock_requested && was_docked) { |
1035 // Update inspected window to hide split and reset it. | 1064 // Update inspected window to hide split and reset it. |
1036 BrowserWindow* inspected_window = GetInspectedBrowserWindow(); | 1065 BrowserWindow* inspected_window = GetInspectedBrowserWindow(); |
1037 if (inspected_window) | 1066 if (inspected_window) |
1038 inspected_window->UpdateDevTools(); | 1067 inspected_window->UpdateDevTools(); |
1039 } | 1068 } |
1040 | 1069 |
1041 if (dock_side_ != DEVTOOLS_DOCK_SIDE_MINIMIZED) { | |
1042 std::string pref_value = kPrefBottom; | |
1043 switch (dock_side_) { | |
1044 case DEVTOOLS_DOCK_SIDE_UNDOCKED: | |
1045 pref_value = kPrefUndocked; | |
1046 break; | |
1047 case DEVTOOLS_DOCK_SIDE_RIGHT: | |
1048 pref_value = kPrefRight; | |
1049 break; | |
1050 case DEVTOOLS_DOCK_SIDE_BOTTOM: | |
1051 pref_value = kPrefBottom; | |
1052 break; | |
1053 case DEVTOOLS_DOCK_SIDE_MINIMIZED: | |
1054 // We don't persist minimized state. | |
1055 break; | |
1056 } | |
1057 profile_->GetPrefs()->SetString(prefs::kDevToolsDockSide, pref_value); | |
1058 } | |
1059 | |
1060 Show(DevToolsToggleAction::Show()); | 1070 Show(DevToolsToggleAction::Show()); |
1061 } | 1071 } |
1062 | 1072 |
1063 void DevToolsWindow::OpenInNewTab(const std::string& url) { | 1073 void DevToolsWindow::OpenInNewTab(const std::string& url) { |
1064 content::OpenURLParams params( | 1074 content::OpenURLParams params( |
1065 GURL(url), content::Referrer(), NEW_FOREGROUND_TAB, | 1075 GURL(url), content::Referrer(), NEW_FOREGROUND_TAB, |
1066 content::PAGE_TRANSITION_LINK, false); | 1076 content::PAGE_TRANSITION_LINK, false); |
1067 content::WebContents* inspected_web_contents = GetInspectedWebContents(); | 1077 content::WebContents* inspected_web_contents = GetInspectedWebContents(); |
1068 if (inspected_web_contents) { | 1078 if (inspected_web_contents) { |
1069 inspected_web_contents->OpenURL(params); | 1079 inspected_web_contents->OpenURL(params); |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1275 base::FundamentalValue request_id_value(request_id); | 1285 base::FundamentalValue request_id_value(request_id); |
1276 base::StringValue file_system_path_value(file_system_path); | 1286 base::StringValue file_system_path_value(file_system_path); |
1277 CallClientFunction("InspectorFrontendAPI.searchCompleted", &request_id_value, | 1287 CallClientFunction("InspectorFrontendAPI.searchCompleted", &request_id_value, |
1278 &file_system_path_value, &file_paths_value); | 1288 &file_system_path_value, &file_paths_value); |
1279 } | 1289 } |
1280 | 1290 |
1281 void DevToolsWindow::ShowDevToolsConfirmInfoBar( | 1291 void DevToolsWindow::ShowDevToolsConfirmInfoBar( |
1282 const base::string16& message, | 1292 const base::string16& message, |
1283 const InfoBarCallback& callback) { | 1293 const InfoBarCallback& callback) { |
1284 DevToolsConfirmInfoBarDelegate::Create( | 1294 DevToolsConfirmInfoBarDelegate::Create( |
1285 IsDocked() ? | 1295 is_docked_ ? |
1286 InfoBarService::FromWebContents(GetInspectedWebContents()) : | 1296 InfoBarService::FromWebContents(GetInspectedWebContents()) : |
1287 InfoBarService::FromWebContents(web_contents_), | 1297 InfoBarService::FromWebContents(web_contents_), |
1288 callback, message); | 1298 callback, message); |
1289 } | 1299 } |
1290 | 1300 |
1291 void DevToolsWindow::CreateDevToolsBrowser() { | 1301 void DevToolsWindow::CreateDevToolsBrowser() { |
1292 std::string wp_key = GetDevToolsWindowPlacementPrefKey(); | 1302 std::string wp_key = GetDevToolsWindowPlacementPrefKey(); |
1293 PrefService* prefs = profile_->GetPrefs(); | 1303 PrefService* prefs = profile_->GetPrefs(); |
1294 const base::DictionaryValue* wp_pref = prefs->GetDictionary(wp_key.c_str()); | 1304 const base::DictionaryValue* wp_pref = prefs->GetDictionary(wp_key.c_str()); |
1295 if (!wp_pref || wp_pref->empty()) { | 1305 if (!wp_pref || wp_pref->empty()) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1332 } | 1342 } |
1333 | 1343 |
1334 BrowserWindow* DevToolsWindow::GetInspectedBrowserWindow() { | 1344 BrowserWindow* DevToolsWindow::GetInspectedBrowserWindow() { |
1335 Browser* browser = NULL; | 1345 Browser* browser = NULL; |
1336 int tab; | 1346 int tab; |
1337 return FindInspectedBrowserAndTabIndex(GetInspectedWebContents(), | 1347 return FindInspectedBrowserAndTabIndex(GetInspectedWebContents(), |
1338 &browser, &tab) ? | 1348 &browser, &tab) ? |
1339 browser->window() : NULL; | 1349 browser->window() : NULL; |
1340 } | 1350 } |
1341 | 1351 |
1342 bool DevToolsWindow::IsInspectedBrowserPopup() { | 1352 void DevToolsWindow::DoAction(const DevToolsToggleAction& action) { |
1343 Browser* browser = NULL; | 1353 switch (action.type()) { |
1344 int tab; | |
1345 return FindInspectedBrowserAndTabIndex(GetInspectedWebContents(), | |
1346 &browser, &tab) && | |
1347 browser->is_type_popup(); | |
1348 } | |
1349 | |
1350 void DevToolsWindow::UpdateFrontendDockSide() { | |
1351 base::StringValue dock_side(SideToString(dock_side_)); | |
1352 CallClientFunction("InspectorFrontendAPI.setDockSide", &dock_side, NULL, | |
1353 NULL); | |
1354 base::FundamentalValue docked(IsDocked()); | |
1355 CallClientFunction("InspectorFrontendAPI.setAttachedWindow", &docked, NULL, | |
1356 NULL); | |
1357 } | |
1358 | |
1359 void DevToolsWindow::ScheduleAction(const DevToolsToggleAction& action) { | |
1360 action_on_load_ = action; | |
1361 if (is_loaded_) | |
1362 DoAction(); | |
1363 } | |
1364 | |
1365 void DevToolsWindow::DoAction() { | |
1366 UpdateFrontendDockSide(); | |
1367 switch (action_on_load_.type()) { | |
1368 case DevToolsToggleAction::kShowConsole: | 1354 case DevToolsToggleAction::kShowConsole: |
1369 CallClientFunction("InspectorFrontendAPI.showConsole", NULL, NULL, NULL); | 1355 CallClientFunction("InspectorFrontendAPI.showConsole", NULL, NULL, NULL); |
1370 break; | 1356 break; |
1371 | 1357 |
1372 case DevToolsToggleAction::kInspect: | 1358 case DevToolsToggleAction::kInspect: |
1373 CallClientFunction("InspectorFrontendAPI.enterInspectElementMode", NULL, | 1359 CallClientFunction("InspectorFrontendAPI.enterInspectElementMode", NULL, |
1374 NULL, NULL); | 1360 NULL, NULL); |
1375 break; | 1361 break; |
1376 | 1362 |
1377 case DevToolsToggleAction::kShow: | 1363 case DevToolsToggleAction::kShow: |
1378 case DevToolsToggleAction::kToggle: | 1364 case DevToolsToggleAction::kToggle: |
1379 // Do nothing. | 1365 // Do nothing. |
1380 break; | 1366 break; |
1381 | 1367 |
1382 case DevToolsToggleAction::kReveal: { | 1368 case DevToolsToggleAction::kReveal: { |
1383 const DevToolsToggleAction::RevealParams* params = | 1369 const DevToolsToggleAction::RevealParams* params = |
1384 action_on_load_.params(); | 1370 action.params(); |
1385 CHECK(params); | 1371 CHECK(params); |
1386 base::StringValue url_value(params->url); | 1372 base::StringValue url_value(params->url); |
1387 base::FundamentalValue line_value(static_cast<int>(params->line_number)); | 1373 base::FundamentalValue line_value(static_cast<int>(params->line_number)); |
1388 base::FundamentalValue column_value( | 1374 base::FundamentalValue column_value( |
1389 static_cast<int>(params->column_number)); | 1375 static_cast<int>(params->column_number)); |
1390 CallClientFunction("InspectorFrontendAPI.revealSourceLine", | 1376 CallClientFunction("InspectorFrontendAPI.revealSourceLine", |
1391 &url_value, | 1377 &url_value, |
1392 &line_value, | 1378 &line_value, |
1393 &column_value); | 1379 &column_value); |
1394 break; | 1380 break; |
1395 } | 1381 } |
1396 default: | 1382 default: |
1397 NOTREACHED(); | 1383 NOTREACHED(); |
1398 break; | 1384 break; |
1399 } | 1385 } |
1400 action_on_load_ = DevToolsToggleAction::Show(); | |
1401 } | 1386 } |
1402 | 1387 |
1403 void DevToolsWindow::UpdateTheme() { | 1388 void DevToolsWindow::UpdateTheme() { |
1404 ThemeService* tp = ThemeServiceFactory::GetForProfile(profile_); | 1389 ThemeService* tp = ThemeServiceFactory::GetForProfile(profile_); |
1405 DCHECK(tp); | 1390 DCHECK(tp); |
1406 | 1391 |
1407 std::string command("InspectorFrontendAPI.setToolbarColors(\"" + | 1392 std::string command("InspectorFrontendAPI.setToolbarColors(\"" + |
1408 SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) + | 1393 SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) + |
1409 "\", \"" + | 1394 "\", \"" + |
1410 SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)) + | 1395 SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)) + |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1475 web_contents_->GetRenderViewHost()->ExecuteJavascriptInWebFrame( | 1460 web_contents_->GetRenderViewHost()->ExecuteJavascriptInWebFrame( |
1476 base::string16(), javascript); | 1461 base::string16(), javascript); |
1477 } | 1462 } |
1478 | 1463 |
1479 void DevToolsWindow::UpdateBrowserToolbar() { | 1464 void DevToolsWindow::UpdateBrowserToolbar() { |
1480 BrowserWindow* inspected_window = GetInspectedBrowserWindow(); | 1465 BrowserWindow* inspected_window = GetInspectedBrowserWindow(); |
1481 if (inspected_window) | 1466 if (inspected_window) |
1482 inspected_window->UpdateToolbar(NULL); | 1467 inspected_window->UpdateToolbar(NULL); |
1483 } | 1468 } |
1484 | 1469 |
1485 bool DevToolsWindow::IsDocked() { | |
1486 return dock_side_ != DEVTOOLS_DOCK_SIDE_UNDOCKED; | |
1487 } | |
1488 | |
1489 void DevToolsWindow::Restore() { | |
1490 if (dock_side_ == DEVTOOLS_DOCK_SIDE_MINIMIZED) | |
1491 SetDockSide(SideToString(dock_side_before_minimized_)); | |
1492 } | |
1493 | |
1494 content::WebContents* DevToolsWindow::GetInspectedWebContents() { | 1470 content::WebContents* DevToolsWindow::GetInspectedWebContents() { |
1495 return inspected_contents_observer_ ? | 1471 return inspected_contents_observer_ ? |
1496 inspected_contents_observer_->web_contents() : NULL; | 1472 inspected_contents_observer_->web_contents() : NULL; |
1497 } | 1473 } |
1498 | 1474 |
1499 void DevToolsWindow::DocumentOnLoadCompletedInMainFrame() { | 1475 void DevToolsWindow::DocumentOnLoadCompletedInMainFrame() { |
1500 is_loaded_ = true; | 1476 load_state_ = load_state_ == kNotLoaded ? kOnLoadFired : kLoadCompleted; |
| 1477 if (load_state_ == kLoadCompleted) |
| 1478 LoadCompleted(); |
| 1479 } |
| 1480 |
| 1481 void DevToolsWindow::LoadCompleted() { |
| 1482 Show(action_on_load_); |
| 1483 action_on_load_ = DevToolsToggleAction::NoOp(); |
1501 UpdateTheme(); | 1484 UpdateTheme(); |
1502 DoAction(); | |
1503 AddDevToolsExtensionsToClient(); | 1485 AddDevToolsExtensionsToClient(); |
1504 } | 1486 } |
OLD | NEW |