Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: chrome/browser/ui/web_contents_modal_dialog_manager.cc

Issue 14969012: components: Create web_modal component. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/ui/web_contents_modal_dialog_manager.h"
6
7 #include "chrome/browser/ui/web_contents_modal_dialog_manager_delegate.h"
8 #include "chrome/common/render_messages.h"
9 #include "content/public/browser/navigation_details.h"
10 #include "content/public/browser/navigation_entry.h"
11 #include "content/public/browser/notification_details.h"
12 #include "content/public/browser/notification_source.h"
13 #include "content/public/browser/notification_types.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/web_contents.h"
16 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
17
18 using content::WebContents;
19
20 DEFINE_WEB_CONTENTS_USER_DATA_KEY(WebContentsModalDialogManager);
21
22 WebContentsModalDialogManager::~WebContentsModalDialogManager() {
23 DCHECK(child_dialogs_.empty());
24 }
25
26 void WebContentsModalDialogManager::ShowDialog(
27 NativeWebContentsModalDialog dialog) {
28 child_dialogs_.push_back(dialog);
29
30 native_manager_->ManageDialog(dialog);
31
32 if (child_dialogs_.size() == 1) {
33 native_manager_->ShowDialog(dialog);
34 BlockWebContentsInteraction(true);
35 }
36 }
37
38 void WebContentsModalDialogManager::BlockWebContentsInteraction(bool blocked) {
39 WebContents* contents = web_contents();
40 if (!contents) {
41 // The WebContents has already disconnected.
42 return;
43 }
44
45 // RenderViewHost may be NULL during shutdown.
46 content::RenderViewHost* host = contents->GetRenderViewHost();
47 if (host) {
48 host->SetIgnoreInputEvents(blocked);
49 host->Send(new ChromeViewMsg_SetVisuallyDeemphasized(
50 host->GetRoutingID(), blocked));
51 }
52 if (delegate_)
53 delegate_->SetWebContentsBlocked(contents, blocked);
54 }
55
56 bool WebContentsModalDialogManager::IsShowingDialog() const {
57 return dialog_count() > 0;
58 }
59
60 void WebContentsModalDialogManager::FocusTopmostDialog() {
61 DCHECK(dialog_count());
62 native_manager_->FocusDialog(*dialog_begin());
63 }
64
65 content::WebContents* WebContentsModalDialogManager::GetWebContents() const {
66 return web_contents();
67 }
68
69 void WebContentsModalDialogManager::WillClose(
70 NativeWebContentsModalDialog dialog) {
71 WebContentsModalDialogList::iterator i(
72 std::find(child_dialogs_.begin(),
73 child_dialogs_.end(),
74 dialog));
75 bool removed_topmost_dialog = i == child_dialogs_.begin();
76 if (i != child_dialogs_.end())
77 child_dialogs_.erase(i);
78 if (child_dialogs_.empty()) {
79 BlockWebContentsInteraction(false);
80 } else {
81 if (removed_topmost_dialog && !closing_all_dialogs_)
82 native_manager_->ShowDialog(child_dialogs_[0]);
83 BlockWebContentsInteraction(true);
84 }
85 }
86
87 void WebContentsModalDialogManager::Observe(
88 int type,
89 const content::NotificationSource& source,
90 const content::NotificationDetails& details) {
91 DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED);
92
93 if (child_dialogs_.empty())
94 return;
95
96 bool visible = *content::Details<bool>(details).ptr();
97 if (visible)
98 native_manager_->ShowDialog(child_dialogs_[0]);
99 else
100 native_manager_->HideDialog(child_dialogs_[0]);
101 }
102
103 WebContentsModalDialogManager::WebContentsModalDialogManager(
104 content::WebContents* web_contents)
105 : content::WebContentsObserver(web_contents),
106 delegate_(NULL),
107 native_manager_(CreateNativeManager(this)),
108 closing_all_dialogs_(false) {
109 DCHECK(native_manager_);
110 registrar_.Add(this,
111 content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED,
112 content::Source<content::WebContents>(web_contents));
113 }
114
115 void WebContentsModalDialogManager::CloseAllDialogs() {
116 closing_all_dialogs_ = true;
117
118 // Clear out any dialogs since we are leaving this page entirely. To ensure
119 // that we iterate over every element in child_dialogs_ we need to use a copy
120 // of child_dialogs_. Otherwise if closing a dialog causes child_dialogs_ to
121 // be modified, we could end up skipping some elements.
122 WebContentsModalDialogList child_dialogs_copy(child_dialogs_);
123 for (WebContentsModalDialogList::iterator it = child_dialogs_copy.begin();
124 it != child_dialogs_copy.end(); ++it) {
125 native_manager_->CloseDialog(*it);
126 BlockWebContentsInteraction(false);
127 }
128
129 closing_all_dialogs_ = false;
130 }
131
132 void WebContentsModalDialogManager::DidNavigateMainFrame(
133 const content::LoadCommittedDetails& details,
134 const content::FrameNavigateParams& params) {
135 // Close constrained windows if necessary.
136 if (!net::RegistryControlledDomainService::SameDomainOrHost(
137 details.previous_url, details.entry->GetURL()))
138 CloseAllDialogs();
139 }
140
141 void WebContentsModalDialogManager::DidGetIgnoredUIEvent() {
142 if (dialog_count())
143 native_manager_->FocusDialog(*dialog_begin());
144 }
145
146 void WebContentsModalDialogManager::WebContentsDestroyed(WebContents* tab) {
147 // First cleanly close all child dialogs.
148 // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked
149 // some of these to close. CloseAllDialogs is async, so it might get called
150 // twice before it runs.
151 CloseAllDialogs();
152 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698