Chromium Code Reviews| Index: Source/core/page/CustomContextMenuProvider.cpp |
| diff --git a/Source/core/page/CustomContextMenuProvider.cpp b/Source/core/page/CustomContextMenuProvider.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e6d6857f76daf649d02bf72a99709683b467991c |
| --- /dev/null |
| +++ b/Source/core/page/CustomContextMenuProvider.cpp |
| @@ -0,0 +1,81 @@ |
| +// 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 "config.h" |
| +#include "core/page/CustomContextMenuProvider.h" |
| + |
| +#include "core/dom/Document.h" |
| +#include "core/dom/ElementTraversal.h" |
| +#include "core/events/EventDispatcher.h" |
| +#include "core/events/MouseEvent.h" |
| +#include "core/html/HTMLMenuElement.h" |
| +#include "core/html/HTMLMenuItemElement.h" |
| +#include "core/page/ContextMenuController.h" |
| +#include "core/page/Page.h" |
| +#include "platform/ContextMenu.h" |
| + |
| +namespace blink { |
| + |
| +using namespace HTMLNames; |
| + |
| +CustomContextMenuProvider::CustomContextMenuProvider(HTMLMenuElement& menu, HTMLElement& subject) |
| + : m_menu(menu) |
| + , m_subjectElement(subject) |
| +{ |
| +} |
| + |
| +CustomContextMenuProvider::~CustomContextMenuProvider() |
| +{ |
| +} |
| + |
| +void CustomContextMenuProvider::populateContextMenu(ContextMenu* menu) |
| +{ |
| + populateContextMenuItems(*m_menu, *menu); |
| +} |
| + |
| +void CustomContextMenuProvider::contextMenuItemSelected(const ContextMenuItem* item) |
| +{ |
| + if (HTMLElement* element = menuItemAt(item->action())) { |
| + RefPtrWillBeRawPtr<SimulatedMouseEvent> click = SimulatedMouseEvent::create(EventTypeNames::click, m_menu->document().domWindow(), Event::create()); |
| + click->setRelatedTarget(m_subjectElement.get()); |
| + element->dispatchEvent(click.release()); |
| + } |
| +} |
| + |
| +void CustomContextMenuProvider::contextMenuCleared() |
| +{ |
| + m_menuItems.clear(); |
| + m_subjectElement = nullptr; |
| +} |
| + |
| +void CustomContextMenuProvider::populateContextMenuItems(const HTMLMenuElement& menu, ContextMenu& contextMenu) |
| +{ |
| + HTMLElement* nextElement = Traversal<HTMLElement>::firstWithin(menu); |
| + while (nextElement) { |
|
tkent
2014/08/21 01:34:39
The code doesn't match to the menu construction al
pals
2014/08/25 14:19:41
Done.
|
| + if (isHTMLMenuElement(*nextElement)) { |
| + ContextMenu subMenu; |
| + populateContextMenuItems(*toHTMLMenuElement(nextElement), subMenu); |
| + contextMenu.appendItem(ContextMenuItem(SubmenuType, ContextMenuItemCustomTagNoAction, nextElement->fastGetAttribute(labelAttr), &subMenu)); |
| + nextElement = Traversal<HTMLElement>::nextSibling(*nextElement); |
| + } else if (isHTMLMenuItemElement(*nextElement)) { |
| + m_menuItems.append(nextElement); |
| + contextMenu.appendItem(ContextMenuItem(ActionType, static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + m_menuItems.size() - 1), nextElement->fastGetAttribute(labelAttr))); |
| + if (ContextMenuItemBaseCustomTag + m_menuItems.size() >= ContextMenuItemLastCustomTag) |
| + break; |
| + nextElement = Traversal<HTMLElement>::next(*nextElement, &menu); |
| + } else { |
| + nextElement = Traversal<HTMLElement>::next(*nextElement, &menu); |
| + } |
| + } |
| +} |
| + |
| +HTMLElement* CustomContextMenuProvider::menuItemAt(unsigned menuId) |
| +{ |
| + int itemIndex = menuId - ContextMenuItemBaseCustomTag; |
| + if (itemIndex < 0 || static_cast<unsigned long>(itemIndex) >= m_menuItems.size()) |
| + return 0; |
| + return m_menuItems[itemIndex].get(); |
| +} |
| + |
| +} // namespace blink |