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/webui/constrained_web_dialog_ui.h"
6
7#include <string>
8#include <vector>
9
10#include "base/bind.h"
11#include "base/bind_helpers.h"
12#include "base/lazy_instance.h"
13#include "base/values.h"
14#include "content/public/browser/notification_service.h"
15#include "content/public/browser/render_view_host.h"
16#include "content/public/browser/web_contents.h"
17#include "content/public/browser/web_ui.h"
18#include "ui/web_dialogs/web_dialog_delegate.h"
19#include "ui/web_dialogs/web_dialog_ui.h"
20
21#if defined(ENABLE_EXTENSIONS)
22#include "chrome/browser/extensions/tab_helper.h"
23#endif
24
25using content::RenderViewHost;
26using content::WebContents;
27using content::WebUIMessageHandler;
28
29namespace {
30
31const char kConstrainedWebDialogDelegateUserDataKey[] =
32    "ConstrainedWebDialogDelegateUserData";
33
34class ConstrainedWebDialogDelegateUserData
35    : public base::SupportsUserData::Data {
36 public:
37  explicit ConstrainedWebDialogDelegateUserData(
38      ConstrainedWebDialogDelegate* delegate) : delegate_(delegate) {}
39  virtual ~ConstrainedWebDialogDelegateUserData() {}
40
41  ConstrainedWebDialogDelegate* delegate() { return delegate_; }
42
43 private:
44  ConstrainedWebDialogDelegate* delegate_;  // unowned
45
46  DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateUserData);
47};
48
49}  // namespace
50
51ConstrainedWebDialogUI::ConstrainedWebDialogUI(content::WebUI* web_ui)
52    : WebUIController(web_ui) {
53#if defined(ENABLE_EXTENSIONS)
54  extensions::TabHelper::CreateForWebContents(web_ui->GetWebContents());
55#endif
56}
57
58ConstrainedWebDialogUI::~ConstrainedWebDialogUI() {
59}
60
61void ConstrainedWebDialogUI::RenderViewCreated(
62    RenderViewHost* render_view_host) {
63  ConstrainedWebDialogDelegate* delegate = GetConstrainedDelegate();
64  if (!delegate)
65    return;
66
67  ui::WebDialogDelegate* dialog_delegate = delegate->GetWebDialogDelegate();
68  std::vector<WebUIMessageHandler*> handlers;
69  dialog_delegate->GetWebUIMessageHandlers(&handlers);
70  render_view_host->SetWebUIProperty("dialogArguments",
71                                     dialog_delegate->GetDialogArgs());
72  for (std::vector<WebUIMessageHandler*>::iterator it = handlers.begin();
73       it != handlers.end(); ++it) {
74    web_ui()->AddMessageHandler(*it);
75  }
76
77  // Add a "dialogClose" callback which matches WebDialogUI behavior.
78  web_ui()->RegisterMessageCallback("dialogClose",
79      base::Bind(&ConstrainedWebDialogUI::OnDialogCloseMessage,
80                 base::Unretained(this)));
81
82  dialog_delegate->OnDialogShown(web_ui(), render_view_host);
83}
84
85void ConstrainedWebDialogUI::OnDialogCloseMessage(const base::ListValue* args) {
86  ConstrainedWebDialogDelegate* delegate = GetConstrainedDelegate();
87  if (!delegate)
88    return;
89
90  std::string json_retval;
91  if (!args->empty() && !args->GetString(0, &json_retval))
92    NOTREACHED() << "Could not read JSON argument";
93  delegate->GetWebDialogDelegate()->OnDialogClosed(json_retval);
94  delegate->OnDialogCloseFromWebUI();
95}
96
97// static
98void ConstrainedWebDialogUI::SetConstrainedDelegate(
99    content::WebContents* web_contents,
100    ConstrainedWebDialogDelegate* delegate) {
101  web_contents->SetUserData(&kConstrainedWebDialogDelegateUserDataKey,
102                            new ConstrainedWebDialogDelegateUserData(delegate));
103}
104
105ConstrainedWebDialogDelegate* ConstrainedWebDialogUI::GetConstrainedDelegate() {
106  ConstrainedWebDialogDelegateUserData* user_data =
107      static_cast<ConstrainedWebDialogDelegateUserData*>(
108          web_ui()->GetWebContents()->
109              GetUserData(&kConstrainedWebDialogDelegateUserDataKey));
110
111  return user_data ? user_data->delegate() : NULL;
112}
113