Home | History | Annotate | Download | only in web_modal
      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 
     13 using content::WebContents;
     14 
     15 namespace web_modal {
     16 
     17 namespace {
     18 
     19 const 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.
     24 class 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 
     36 PopupManager::PopupManager(WebContentsModalDialogHost* host)
     37     : host_(host),
     38       weak_factory_(this) {}
     39 
     40 PopupManager::~PopupManager() {
     41 }
     42 
     43 void 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 
     59 void 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 
     68 bool 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 
     78 void 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 
     88 void PopupManager::WillClose(NativePopup popup) {
     89 }
     90 
     91 void 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 
     98 void 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 
    104 PopupManager* 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 
    114 gfx::NativeView PopupManager::GetHostView() const {
    115   // TODO(gbillock): replace this with a PopupManagerHost or something.
    116   DCHECK(host_);
    117   return host_->GetHostView();
    118 }
    119 
    120 void 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