1// Copyright 2014 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 "components/web_modal/popup_manager.h"
6
7#include "components/web_modal/web_contents_modal_dialog_host.h"
8#include "components/web_modal/web_contents_modal_dialog_manager.h"
9#include "content/public/browser/web_contents.h"
10#include "content/public/browser/web_contents_user_data.h"
11#include "ui/gfx/geometry/size.h"
12
13using content::WebContents;
14
15namespace web_modal {
16
17namespace {
18
19const char kPopupManagerUserDataKey[] = "PopupManager";
20
21// This class provides a hook to get a PopupManager from a WebContents.
22// The PopupManager is browser-scoped, but will use a FromWebContents API
23// to attach to each WebContents in that browser.
24class PopupManagerRelay : public content::WebContentsUserData<PopupManager> {
25 public:
26  explicit PopupManagerRelay(base::WeakPtr<PopupManager> manager)
27      : manager_(manager) {}
28
29  virtual ~PopupManagerRelay() {}
30
31  base::WeakPtr<PopupManager> manager_;
32};
33
34}  // namespace
35
36PopupManager::PopupManager(WebContentsModalDialogHost* host)
37    : host_(host),
38      weak_factory_(this) {}
39
40PopupManager::~PopupManager() {
41}
42
43void PopupManager::ShowPopup(scoped_ptr<SinglePopupManager> manager) {
44  content::WebContents* web_contents = manager->GetBoundWebContents();
45  // TODO(gbillock): get rid of this when we handle bubbles
46  DCHECK(web_contents);
47
48  // TODO(gbillock): remove when we port the popup management logic to this
49  // class.
50  NativeWebContentsModalDialog dialog =
51      static_cast<NativeWebContentsModalDialog>(manager->popup());
52
53  WebContentsModalDialogManager* wm_manager =
54      WebContentsModalDialogManager::FromWebContents(web_contents);
55  DCHECK(wm_manager);
56  wm_manager->ShowModalDialog(dialog);
57}
58
59void PopupManager::ShowModalDialog(NativePopup popup,
60                                   content::WebContents* web_contents) {
61  // TODO make a new native popup manager and call ShowPopup.
62  // For now just lay off to WCMDM.
63  WebContentsModalDialogManager* manager =
64      WebContentsModalDialogManager::FromWebContents(web_contents);
65  manager->ShowModalDialog(popup);
66}
67
68bool PopupManager::IsWebModalDialogActive(
69    const content::WebContents* web_contents) const {
70  if (web_contents == NULL)
71    return false;
72
73  const WebContentsModalDialogManager* manager =
74      WebContentsModalDialogManager::FromWebContents(web_contents);
75  return manager && manager->IsDialogActive();
76}
77
78void PopupManager::WasFocused(const content::WebContents* web_contents) {
79  if (!IsWebModalDialogActive(web_contents))
80    return;
81
82  const WebContentsModalDialogManager* manager =
83      WebContentsModalDialogManager::FromWebContents(web_contents);
84  if (manager)
85    manager->FocusTopmostDialog();
86}
87
88void PopupManager::WillClose(NativePopup popup) {
89}
90
91void PopupManager::RegisterWith(content::WebContents* web_contents) {
92  web_contents->SetUserData(kPopupManagerUserDataKey,
93                            new PopupManagerRelay(weak_factory_.GetWeakPtr()));
94  // TODO(gbillock): Need to do something more extreme here to manage changing
95  // popup managers with popups in-flight?
96}
97
98void PopupManager::UnregisterWith(content::WebContents* web_contents) {
99  web_contents->RemoveUserData(kPopupManagerUserDataKey);
100  // TODO(gbillock): Need to do something more extreme here to manage changing
101  // popup managers with popups in-flight?
102}
103
104PopupManager* PopupManager::FromWebContents(
105    content::WebContents* web_contents) {
106  PopupManagerRelay* relay = static_cast<PopupManagerRelay*>(
107      web_contents->GetUserData(kPopupManagerUserDataKey));
108  if (!relay)
109    return NULL;
110
111  return relay->manager_.get();
112}
113
114gfx::NativeView PopupManager::GetHostView() const {
115  // TODO(gbillock): replace this with a PopupManagerHost or something.
116  DCHECK(host_);
117  return host_->GetHostView();
118}
119
120void PopupManager::CloseAllDialogsForTesting(
121    content::WebContents* web_contents) {
122  // TODO: re-implement, probably in terms of something in the host_,
123  // or of owned WCMDMs.
124  WebContentsModalDialogManager* manager =
125      WebContentsModalDialogManager::FromWebContents(web_contents);
126  manager->CloseAllDialogs();
127}
128
129}  // namespace web_modal
130