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 "chrome/browser/extensions/api/web_view/chrome_web_view_internal_api.h"
6
7#include "chrome/browser/extensions/api/context_menus/context_menus_api.h"
8#include "chrome/browser/extensions/api/context_menus/context_menus_api_helpers.h"
9#include "chrome/browser/profiles/profile.h"
10#include "chrome/common/extensions/api/chrome_web_view_internal.h"
11#include "extensions/common/error_utils.h"
12
13namespace helpers = extensions::context_menus_api_helpers;
14namespace webview = extensions::api::chrome_web_view_internal;
15
16namespace extensions {
17
18// TODO(lazyboy): Add checks similar to
19// WebViewInternalExtensionFunction::RunAsyncSafe(WebViewGuest*).
20bool ChromeWebViewInternalContextMenusCreateFunction::RunAsync() {
21  scoped_ptr<webview::ContextMenusCreate::Params> params(
22      webview::ContextMenusCreate::Params::Create(*args_));
23  EXTENSION_FUNCTION_VALIDATE(params.get());
24
25  MenuItem::Id id(
26      Profile::FromBrowserContext(browser_context())->IsOffTheRecord(),
27      MenuItem::ExtensionKey(extension_id(), params->instance_id));
28
29  if (params->create_properties.id.get()) {
30    id.string_uid = *params->create_properties.id;
31  } else {
32    // The Generated Id is added by web_view_internal_custom_bindings.js.
33    base::DictionaryValue* properties = NULL;
34    EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &properties));
35    EXTENSION_FUNCTION_VALIDATE(
36        properties->GetInteger(helpers::kGeneratedIdKey, &id.uid));
37  }
38
39  bool success = extensions::context_menus_api_helpers::CreateMenuItem(
40      params->create_properties,
41      Profile::FromBrowserContext(browser_context()),
42      extension(),
43      id,
44      &error_);
45
46  SendResponse(success);
47  return success;
48}
49
50bool ChromeWebViewInternalContextMenusUpdateFunction::RunAsync() {
51  scoped_ptr<webview::ContextMenusUpdate::Params> params(
52      webview::ContextMenusUpdate::Params::Create(*args_));
53  EXTENSION_FUNCTION_VALIDATE(params.get());
54
55  Profile* profile = Profile::FromBrowserContext(browser_context());
56  MenuItem::Id item_id(
57      profile->IsOffTheRecord(),
58      MenuItem::ExtensionKey(extension_id(), params->instance_id));
59
60  if (params->id.as_string)
61    item_id.string_uid = *params->id.as_string;
62  else if (params->id.as_integer)
63    item_id.uid = *params->id.as_integer;
64  else
65    NOTREACHED();
66
67  bool success = extensions::context_menus_api_helpers::UpdateMenuItem(
68      params->update_properties, profile, extension(), item_id, &error_);
69  SendResponse(success);
70  return success;
71}
72
73bool ChromeWebViewInternalContextMenusRemoveFunction::RunAsync() {
74  scoped_ptr<webview::ContextMenusRemove::Params> params(
75      webview::ContextMenusRemove::Params::Create(*args_));
76  EXTENSION_FUNCTION_VALIDATE(params.get());
77
78  MenuManager* menu_manager =
79      MenuManager::Get(Profile::FromBrowserContext(browser_context()));
80
81  MenuItem::Id id(
82      Profile::FromBrowserContext(browser_context())->IsOffTheRecord(),
83      MenuItem::ExtensionKey(extension_id(), params->instance_id));
84
85  if (params->menu_item_id.as_string) {
86    id.string_uid = *params->menu_item_id.as_string;
87  } else if (params->menu_item_id.as_integer) {
88    id.uid = *params->menu_item_id.as_integer;
89  } else {
90    NOTREACHED();
91  }
92
93  bool success = true;
94  MenuItem* item = menu_manager->GetItemById(id);
95  // Ensure one <webview> can't remove another's menu items.
96  if (!item || item->id().extension_key != id.extension_key) {
97    error_ = ErrorUtils::FormatErrorMessage(
98        context_menus_api_helpers::kCannotFindItemError,
99        context_menus_api_helpers::GetIDString(id));
100    success = false;
101  } else if (!menu_manager->RemoveContextMenuItem(id)) {
102    success = false;
103  }
104
105  SendResponse(success);
106  return success;
107}
108
109bool ChromeWebViewInternalContextMenusRemoveAllFunction::RunAsync() {
110  scoped_ptr<webview::ContextMenusRemoveAll::Params> params(
111      webview::ContextMenusRemoveAll::Params::Create(*args_));
112  EXTENSION_FUNCTION_VALIDATE(params.get());
113
114  MenuManager* menu_manager =
115      MenuManager::Get(Profile::FromBrowserContext(browser_context()));
116
117  int webview_instance_id = params->instance_id;
118  menu_manager->RemoveAllContextItems(
119      MenuItem::ExtensionKey(extension()->id(), webview_instance_id));
120  SendResponse(true);
121  return true;
122}
123
124ChromeWebViewInternalShowContextMenuFunction::
125    ChromeWebViewInternalShowContextMenuFunction() {
126}
127
128ChromeWebViewInternalShowContextMenuFunction::
129    ~ChromeWebViewInternalShowContextMenuFunction() {
130}
131
132bool ChromeWebViewInternalShowContextMenuFunction::RunAsyncSafe(
133    WebViewGuest* guest) {
134  scoped_ptr<webview::ShowContextMenu::Params> params(
135      webview::ShowContextMenu::Params::Create(*args_));
136  EXTENSION_FUNCTION_VALIDATE(params.get());
137
138  // TODO(lazyboy): Actually implement filtering menu items, we pass NULL for
139  // now.
140  guest->ShowContextMenu(params->request_id, NULL);
141
142  SendResponse(true);
143  return true;
144}
145
146}  // namespace extensions
147