普通文本  |  130行  |  4.16 KB

// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/web_modal/popup_manager.h"

#include "components/web_modal/web_contents_modal_dialog_host.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_user_data.h"
#include "ui/gfx/geometry/size.h"

using content::WebContents;

namespace web_modal {

namespace {

const char kPopupManagerUserDataKey[] = "PopupManager";

// This class provides a hook to get a PopupManager from a WebContents.
// The PopupManager is browser-scoped, but will use a FromWebContents API
// to attach to each WebContents in that browser.
class PopupManagerRelay : public content::WebContentsUserData<PopupManager> {
 public:
  explicit PopupManagerRelay(base::WeakPtr<PopupManager> manager)
      : manager_(manager) {}

  virtual ~PopupManagerRelay() {}

  base::WeakPtr<PopupManager> manager_;
};

}  // namespace

PopupManager::PopupManager(WebContentsModalDialogHost* host)
    : host_(host),
      weak_factory_(this) {}

PopupManager::~PopupManager() {
}

void PopupManager::ShowPopup(scoped_ptr<SinglePopupManager> manager) {
  content::WebContents* web_contents = manager->GetBoundWebContents();
  // TODO(gbillock): get rid of this when we handle bubbles
  DCHECK(web_contents);

  // TODO(gbillock): remove when we port the popup management logic to this
  // class.
  NativeWebContentsModalDialog dialog =
      static_cast<NativeWebContentsModalDialog>(manager->popup());

  WebContentsModalDialogManager* wm_manager =
      WebContentsModalDialogManager::FromWebContents(web_contents);
  DCHECK(wm_manager);
  wm_manager->ShowModalDialog(dialog);
}

void PopupManager::ShowModalDialog(NativePopup popup,
                                   content::WebContents* web_contents) {
  // TODO make a new native popup manager and call ShowPopup.
  // For now just lay off to WCMDM.
  WebContentsModalDialogManager* manager =
      WebContentsModalDialogManager::FromWebContents(web_contents);
  manager->ShowModalDialog(popup);
}

bool PopupManager::IsWebModalDialogActive(
    const content::WebContents* web_contents) const {
  if (web_contents == NULL)
    return false;

  const WebContentsModalDialogManager* manager =
      WebContentsModalDialogManager::FromWebContents(web_contents);
  return manager && manager->IsDialogActive();
}

void PopupManager::WasFocused(const content::WebContents* web_contents) {
  if (!IsWebModalDialogActive(web_contents))
    return;

  const WebContentsModalDialogManager* manager =
      WebContentsModalDialogManager::FromWebContents(web_contents);
  if (manager)
    manager->FocusTopmostDialog();
}

void PopupManager::WillClose(NativePopup popup) {
}

void PopupManager::RegisterWith(content::WebContents* web_contents) {
  web_contents->SetUserData(kPopupManagerUserDataKey,
                            new PopupManagerRelay(weak_factory_.GetWeakPtr()));
  // TODO(gbillock): Need to do something more extreme here to manage changing
  // popup managers with popups in-flight?
}

void PopupManager::UnregisterWith(content::WebContents* web_contents) {
  web_contents->RemoveUserData(kPopupManagerUserDataKey);
  // TODO(gbillock): Need to do something more extreme here to manage changing
  // popup managers with popups in-flight?
}

PopupManager* PopupManager::FromWebContents(
    content::WebContents* web_contents) {
  PopupManagerRelay* relay = static_cast<PopupManagerRelay*>(
      web_contents->GetUserData(kPopupManagerUserDataKey));
  if (!relay)
    return NULL;

  return relay->manager_.get();
}

gfx::NativeView PopupManager::GetHostView() const {
  // TODO(gbillock): replace this with a PopupManagerHost or something.
  DCHECK(host_);
  return host_->GetHostView();
}

void PopupManager::CloseAllDialogsForTesting(
    content::WebContents* web_contents) {
  // TODO: re-implement, probably in terms of something in the host_,
  // or of owned WCMDMs.
  WebContentsModalDialogManager* manager =
      WebContentsModalDialogManager::FromWebContents(web_contents);
  manager->CloseAllDialogs();
}

}  // namespace web_modal