Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3465)

Unified Diff: chrome/browser/extensions/menu_manager.cc

Issue 186213003: <webview>: Context menu API implementation CL. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: sync @tott Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/extensions/menu_manager.h ('k') | chrome/browser/extensions/menu_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/extensions/menu_manager.cc
diff --git a/chrome/browser/extensions/menu_manager.cc b/chrome/browser/extensions/menu_manager.cc
index 424366390b34035298c5790bd32d417cd7ed67a8..12097669f618e80f9efeffaa06eda9d833e8a7b5 100644
--- a/chrome/browser/extensions/menu_manager.cc
+++ b/chrome/browser/extensions/menu_manager.cc
@@ -19,6 +19,7 @@
#include "chrome/browser/extensions/menu_manager_factory.h"
#include "chrome/browser/extensions/state_store.h"
#include "chrome/browser/extensions/tab_helper.h"
+#include "chrome/browser/guestview/webview/webview_guest.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/context_menus.h"
#include "content/public/browser/notification_details.h"
@@ -222,7 +223,7 @@ MenuItem* MenuItem::Populate(const std::string& extension_id,
bool incognito = false;
if (!value.GetBoolean(kIncognitoKey, &incognito))
return NULL;
- Id id(incognito, extension_id);
+ Id id(incognito, MenuItem::ExtensionKey(extension_id));
if (!value.GetString(kStringUIDKey, &id.string_uid))
return NULL;
int type_int;
@@ -266,7 +267,8 @@ MenuItem* MenuItem::Populate(const std::string& extension_id,
// parent_id is filled in from the value, but it might not be valid. It's left
// to be validated upon being added (via AddChildItem) to the menu manager.
- scoped_ptr<Id> parent_id(new Id(incognito, extension_id));
+ scoped_ptr<Id> parent_id(
+ new Id(incognito, MenuItem::ExtensionKey(extension_id)));
if (value.HasKey(kParentUIDKey)) {
if (!value.GetString(kParentUIDKey, &parent_id->string_uid))
return NULL;
@@ -318,8 +320,8 @@ MenuManager* MenuManager::Get(Profile* profile) {
return MenuManagerFactory::GetForProfile(profile);
}
-std::set<std::string> MenuManager::ExtensionIds() {
- std::set<std::string> id_set;
+std::set<MenuItem::ExtensionKey> MenuManager::ExtensionIds() {
+ std::set<MenuItem::ExtensionKey> id_set;
for (MenuItemMap::const_iterator i = context_items_.begin();
i != context_items_.end(); ++i) {
id_set.insert(i->first);
@@ -328,34 +330,32 @@ std::set<std::string> MenuManager::ExtensionIds() {
}
const MenuItem::List* MenuManager::MenuItems(
- const std::string& extension_id) {
- MenuItemMap::iterator i = context_items_.find(extension_id);
+ const MenuItem::ExtensionKey& key) {
+ MenuItemMap::iterator i = context_items_.find(key);
if (i != context_items_.end()) {
return &(i->second);
}
return NULL;
}
-bool MenuManager::AddContextItem(
- const Extension* extension,
- MenuItem* item) {
- const std::string& extension_id = item->extension_id();
+bool MenuManager::AddContextItem(const Extension* extension, MenuItem* item) {
+ const MenuItem::ExtensionKey& key = item->id().extension_key;
// The item must have a non-empty extension id, and not have already been
// added.
- if (extension_id.empty() || ContainsKey(items_by_id_, item->id()))
+ if (key.empty() || ContainsKey(items_by_id_, item->id()))
return false;
- DCHECK_EQ(extension->id(), extension_id);
+ DCHECK_EQ(extension->id(), key.extension_id);
- bool first_item = !ContainsKey(context_items_, extension_id);
- context_items_[extension_id].push_back(item);
+ bool first_item = !ContainsKey(context_items_, key);
+ context_items_[key].push_back(item);
items_by_id_[item->id()] = item;
if (item->type() == MenuItem::RADIO) {
if (item->checked())
RadioItemSelected(item);
else
- SanitizeRadioList(context_items_[extension_id]);
+ SanitizeRadioList(context_items_[key]);
}
// If this is the first item for this extension, start loading its icon.
@@ -424,14 +424,14 @@ bool MenuManager::ChangeParent(const MenuItem::Id& child_id,
} else {
// This is a top-level item, so we need to pull it out of our list of
// top-level items.
- MenuItemMap::iterator i = context_items_.find(child->extension_id());
+ const MenuItem::ExtensionKey& child_key = child->id().extension_key;
+ MenuItemMap::iterator i = context_items_.find(child_key);
if (i == context_items_.end()) {
NOTREACHED();
return false;
}
MenuItem::List& list = i->second;
- MenuItem::List::iterator j = std::find(list.begin(), list.end(),
- child);
+ MenuItem::List::iterator j = std::find(list.begin(), list.end(), child);
if (j == list.end()) {
NOTREACHED();
return false;
@@ -444,9 +444,10 @@ bool MenuManager::ChangeParent(const MenuItem::Id& child_id,
new_parent->AddChild(child);
SanitizeRadioList(new_parent->children());
} else {
- context_items_[child->extension_id()].push_back(child);
+ const MenuItem::ExtensionKey& child_key = child->id().extension_key;
+ context_items_[child_key].push_back(child);
child->parent_id_.reset(NULL);
- SanitizeRadioList(context_items_[child->extension_id()]);
+ SanitizeRadioList(context_items_[child_key]);
}
return true;
}
@@ -457,8 +458,8 @@ bool MenuManager::RemoveContextMenuItem(const MenuItem::Id& id) {
MenuItem* menu_item = GetItemById(id);
DCHECK(menu_item);
- std::string extension_id = menu_item->extension_id();
- MenuItemMap::iterator i = context_items_.find(extension_id);
+ const MenuItem::ExtensionKey extension_key = id.extension_key;
+ MenuItemMap::iterator i = context_items_.find(extension_key);
if (i == context_items_.end()) {
NOTREACHED();
return false;
@@ -503,16 +504,18 @@ bool MenuManager::RemoveContextMenuItem(const MenuItem::Id& id) {
}
if (list.empty()) {
- context_items_.erase(extension_id);
- icon_manager_.RemoveIcon(extension_id);
+ context_items_.erase(extension_key);
+ icon_manager_.RemoveIcon(extension_key.extension_id);
}
return result;
}
-void MenuManager::RemoveAllContextItems(const std::string& extension_id) {
+void MenuManager::RemoveAllContextItems(
+ const MenuItem::ExtensionKey& extension_key) {
MenuItem::List::iterator i;
- for (i = context_items_[extension_id].begin();
- i != context_items_[extension_id].end(); ++i) {
+ for (i = context_items_[extension_key].begin();
+ i != context_items_[extension_key].end();
+ ++i) {
MenuItem* item = *i;
items_by_id_.erase(item->id());
@@ -523,9 +526,9 @@ void MenuManager::RemoveAllContextItems(const std::string& extension_id) {
items_by_id_.erase(*j);
}
}
- STLDeleteElements(&context_items_[extension_id]);
- context_items_.erase(extension_id);
- icon_manager_.RemoveIcon(extension_id);
+ STLDeleteElements(&context_items_[extension_key]);
+ context_items_.erase(extension_key);
+ icon_manager_.RemoveIcon(extension_key.extension_id);
}
MenuItem* MenuManager::GetItemById(const MenuItem::Id& id) const {
@@ -549,11 +552,12 @@ void MenuManager::RadioItemSelected(MenuItem* item) {
}
list = &(parent->children());
} else {
- if (context_items_.find(item->extension_id()) == context_items_.end()) {
+ const MenuItem::ExtensionKey& key = item->id().extension_key;
+ if (context_items_.find(key) == context_items_.end()) {
NOTREACHED();
return;
}
- list = &context_items_[item->extension_id()];
+ list = &context_items_[key];
}
// Find where |item| is in the list.
@@ -610,8 +614,8 @@ void MenuManager::ExecuteCommand(Profile* profile,
// ExtensionService/Extension can be NULL in unit tests :(
ExtensionService* service =
ExtensionSystem::Get(profile_)->extension_service();
- const Extension* extension = service ?
- service->extensions()->GetByID(menu_item_id.extension_id) : NULL;
+ const Extension* extension =
+ service ? service->extensions()->GetByID(item->extension_id()) : NULL;
if (item->type() == MenuItem::RADIO)
RadioItemSelected(item);
@@ -646,6 +650,14 @@ void MenuManager::ExecuteCommand(Profile* profile,
properties->SetBoolean("editable", params.is_editable);
+ WebViewGuest* webview_guest = WebViewGuest::FromWebContents(web_contents);
+ if (webview_guest) {
+ // This is used in webview_custom_bindings.js.
+ // The property is not exposed to developer API.
+ properties->SetInteger("webviewInstanceId",
+ webview_guest->view_instance_id());
+ }
+
args->Append(properties);
// Add the tab info to the argument list.
@@ -673,7 +685,7 @@ void MenuManager::ExecuteCommand(Profile* profile,
properties->SetBoolean("checked", item->checked());
if (extension)
- WriteToStorage(extension);
+ WriteToStorage(extension, item->id().extension_key);
}
// Note: web_contents are NULL in unit tests :(
@@ -683,6 +695,7 @@ void MenuManager::ExecuteCommand(Profile* profile,
}
{
+ // Dispatch to menu item's .onclick handler.
scoped_ptr<Event> event(new Event(
event_names::kOnContextMenus,
scoped_ptr<base::ListValue>(args->DeepCopy())));
@@ -691,10 +704,15 @@ void MenuManager::ExecuteCommand(Profile* profile,
event_router->DispatchEventToExtension(item->extension_id(), event.Pass());
}
{
- scoped_ptr<Event> event(new Event(context_menus::OnClicked::kEventName,
- args.Pass()));
+ // Dispatch to .contextMenus.onClicked handler.
+ scoped_ptr<Event> event(
+ new Event(webview_guest ? event_names::kOnWebviewContextMenus
+ : context_menus::OnClicked::kEventName,
+ args.Pass()));
event->restrict_to_browser_context = profile;
event->user_gesture = EventRouter::USER_GESTURE_ENABLED;
+ if (webview_guest)
+ event->filter_info.SetInstanceID(webview_guest->view_instance_id());
event_router->DispatchEventToExtension(item->extension_id(), event.Pass());
}
}
@@ -743,8 +761,8 @@ bool MenuManager::ItemUpdated(const MenuItem::Id& id) {
if (menu_item->parent_id()) {
SanitizeRadioList(GetItemById(*menu_item->parent_id())->children());
} else {
- std::string extension_id = menu_item->extension_id();
- MenuItemMap::iterator i = context_items_.find(extension_id);
+ MenuItemMap::iterator i =
+ context_items_.find(menu_item->id().extension_key);
if (i == context_items_.end()) {
NOTREACHED();
return false;
@@ -755,21 +773,27 @@ bool MenuManager::ItemUpdated(const MenuItem::Id& id) {
return true;
}
-void MenuManager::WriteToStorage(const Extension* extension) {
+void MenuManager::WriteToStorage(const Extension* extension,
+ const MenuItem::ExtensionKey& extension_key) {
if (!BackgroundInfo::HasLazyBackgroundPage(extension))
return;
- const MenuItem::List* top_items = MenuItems(extension->id());
+ // <webview> menu items are transient and not stored in storage.
+ if (extension_key.webview_instance_id)
+ return;
+ const MenuItem::List* top_items = MenuItems(extension_key);
MenuItem::List all_items;
if (top_items) {
for (MenuItem::List::const_iterator i = top_items->begin();
i != top_items->end(); ++i) {
+ DCHECK(!(*i)->id().extension_key.webview_instance_id);
(*i)->GetFlattenedSubtree(&all_items);
}
}
- if (store_)
+ if (store_) {
store_->SetExtensionValue(extension->id(), kContextMenusKey,
MenuItemsToValue(all_items));
+ }
}
void MenuManager::ReadFromStorage(const std::string& extension_id,
@@ -804,8 +828,9 @@ void MenuManager::Observe(int type,
// Remove menu items for disabled/uninstalled extensions.
const Extension* extension =
content::Details<UnloadedExtensionInfo>(details)->extension;
- if (ContainsKey(context_items_, extension->id())) {
- RemoveAllContextItems(extension->id());
+ MenuItem::ExtensionKey extension_key(extension->id());
+ if (ContainsKey(context_items_, extension_key)) {
+ RemoveAllContextItems(extension_key);
}
break;
}
@@ -859,18 +884,46 @@ void MenuManager::RemoveAllIncognitoContextItems() {
RemoveContextMenuItem(*remove_iter);
}
+MenuItem::ExtensionKey::ExtensionKey() : webview_instance_id(0) {}
+
+MenuItem::ExtensionKey::ExtensionKey(const std::string& extension_id,
+ int webview_instance_id)
+ : extension_id(extension_id), webview_instance_id(webview_instance_id) {}
+
+MenuItem::ExtensionKey::ExtensionKey(const std::string& extension_id)
+ : extension_id(extension_id), webview_instance_id(0) {}
+
+bool MenuItem::ExtensionKey::operator==(const ExtensionKey& other) const {
+ return extension_id == other.extension_id &&
+ webview_instance_id == other.webview_instance_id;
+}
+
+bool MenuItem::ExtensionKey::operator<(const ExtensionKey& other) const {
+ if (extension_id != other.extension_id)
+ return extension_id < other.extension_id;
+
+ return webview_instance_id < other.webview_instance_id;
+}
+
+bool MenuItem::ExtensionKey::operator!=(const ExtensionKey& other) const {
+ return !(*this == other);
+}
+
+bool MenuItem::ExtensionKey::empty() const {
+ return extension_id.empty() && !webview_instance_id;
+}
+
MenuItem::Id::Id() : incognito(false), uid(0) {}
-MenuItem::Id::Id(bool incognito, const std::string& extension_id)
- : incognito(incognito), extension_id(extension_id), uid(0) {}
+MenuItem::Id::Id(bool incognito, const MenuItem::ExtensionKey& extension_key)
+ : incognito(incognito), extension_key(extension_key), uid(0) {}
MenuItem::Id::~Id() {
}
bool MenuItem::Id::operator==(const Id& other) const {
return (incognito == other.incognito &&
- extension_id == other.extension_id &&
- uid == other.uid &&
+ extension_key == other.extension_key && uid == other.uid &&
string_uid == other.string_uid);
}
@@ -882,9 +935,9 @@ bool MenuItem::Id::operator<(const Id& other) const {
if (incognito < other.incognito)
return true;
if (incognito == other.incognito) {
- if (extension_id < other.extension_id)
+ if (extension_key < other.extension_key)
return true;
- if (extension_id == other.extension_id) {
+ if (extension_key == other.extension_key) {
if (uid < other.uid)
return true;
if (uid == other.uid)
« no previous file with comments | « chrome/browser/extensions/menu_manager.h ('k') | chrome/browser/extensions/menu_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698