cc: Added inline to Tile::IsReadyToDraw
[chromium-blink-merge.git] / components / web_modal / web_contents_modal_dialog_manager.cc
blobf30b6a05fa1823c37810a67c8f1373536dee808c
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
3 // found in the LICENSE file.
5 #include "components/web_modal/web_contents_modal_dialog_manager.h"
7 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
8 #include "content/public/browser/navigation_details.h"
9 #include "content/public/browser/navigation_entry.h"
10 #include "content/public/browser/notification_details.h"
11 #include "content/public/browser/notification_source.h"
12 #include "content/public/browser/notification_types.h"
13 #include "content/public/browser/render_view_host.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/browser/web_contents_view.h"
16 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
18 using content::WebContents;
20 DEFINE_WEB_CONTENTS_USER_DATA_KEY(web_modal::WebContentsModalDialogManager);
22 namespace web_modal {
24 WebContentsModalDialogManager::~WebContentsModalDialogManager() {
25 DCHECK(child_dialogs_.empty());
28 void WebContentsModalDialogManager::SetDelegate(
29 WebContentsModalDialogManagerDelegate* d) {
30 delegate_ = d;
31 // Delegate can be NULL on Views/Win32 during tab drag.
32 native_manager_->HostChanged(d ? d->GetWebContentsModalDialogHost() : NULL);
35 void WebContentsModalDialogManager::ShowDialog(
36 NativeWebContentsModalDialog dialog) {
37 child_dialogs_.push_back(dialog);
39 native_manager_->ManageDialog(dialog);
41 if (child_dialogs_.size() == 1) {
42 if (delegate_ && delegate_->IsWebContentsVisible(web_contents()))
43 native_manager_->ShowDialog(dialog);
44 BlockWebContentsInteraction(true);
48 bool WebContentsModalDialogManager::IsShowingDialog() const {
49 return !child_dialogs_.empty();
52 void WebContentsModalDialogManager::FocusTopmostDialog() {
53 DCHECK(!child_dialogs_.empty());
54 native_manager_->FocusDialog(child_dialogs_.front());
57 content::WebContents* WebContentsModalDialogManager::GetWebContents() const {
58 return web_contents();
61 void WebContentsModalDialogManager::WillClose(
62 NativeWebContentsModalDialog dialog) {
63 WebContentsModalDialogList::iterator i(
64 std::find(child_dialogs_.begin(), child_dialogs_.end(), dialog));
66 // The Views tab contents modal dialog calls WillClose twice. Ignore the
67 // second invocation.
68 if (i == child_dialogs_.end())
69 return;
71 bool removed_topmost_dialog = i == child_dialogs_.begin();
72 child_dialogs_.erase(i);
73 if (!child_dialogs_.empty() && removed_topmost_dialog &&
74 !closing_all_dialogs_)
75 native_manager_->ShowDialog(child_dialogs_.front());
77 BlockWebContentsInteraction(!child_dialogs_.empty());
80 void WebContentsModalDialogManager::Observe(
81 int type,
82 const content::NotificationSource& source,
83 const content::NotificationDetails& details) {
84 DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED);
86 if (child_dialogs_.empty())
87 return;
89 bool visible = *content::Details<bool>(details).ptr();
90 if (visible)
91 native_manager_->ShowDialog(child_dialogs_.front());
92 else
93 native_manager_->HideDialog(child_dialogs_.front());
96 WebContentsModalDialogManager::WebContentsModalDialogManager(
97 content::WebContents* web_contents)
98 : content::WebContentsObserver(web_contents),
99 delegate_(NULL),
100 native_manager_(CreateNativeManager(this)),
101 closing_all_dialogs_(false) {
102 DCHECK(native_manager_);
103 registrar_.Add(this,
104 content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED,
105 content::Source<content::WebContents>(web_contents));
108 void WebContentsModalDialogManager::BlockWebContentsInteraction(bool blocked) {
109 WebContents* contents = web_contents();
110 if (!contents) {
111 // The WebContents has already disconnected.
112 return;
115 // RenderViewHost may be NULL during shutdown.
116 content::RenderViewHost* host = contents->GetRenderViewHost();
117 if (host)
118 host->SetIgnoreInputEvents(blocked);
119 if (delegate_)
120 delegate_->SetWebContentsBlocked(contents, blocked);
123 void WebContentsModalDialogManager::CloseAllDialogs() {
124 closing_all_dialogs_ = true;
126 // Clear out any dialogs since we are leaving this page entirely.
127 while (!child_dialogs_.empty())
128 native_manager_->CloseDialog(child_dialogs_.front());
130 closing_all_dialogs_ = false;
133 void WebContentsModalDialogManager::DidNavigateMainFrame(
134 const content::LoadCommittedDetails& details,
135 const content::FrameNavigateParams& params) {
136 // Close constrained windows if necessary.
137 if (!net::registry_controlled_domains::SameDomainOrHost(
138 details.previous_url, details.entry->GetURL(),
139 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES))
140 CloseAllDialogs();
143 void WebContentsModalDialogManager::DidGetIgnoredUIEvent() {
144 if (!child_dialogs_.empty())
145 native_manager_->FocusDialog(child_dialogs_.front());
148 void WebContentsModalDialogManager::WebContentsDestroyed(WebContents* tab) {
149 // First cleanly close all child dialogs.
150 // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked
151 // some of these to close. CloseAllDialogs is async, so it might get called
152 // twice before it runs.
153 CloseAllDialogs();
156 } // namespace web_modal