bool InjectedBundlePageContextMenuClient::getCustomMenuFromDefaultItems(WebPage& page, const HitTestResult& hitTestResult, const Vector<ContextMenuItem>& proposedMenu, Vector<WebContextMenuItemData>& newMenu, RefPtr<API::Object>& userData) { if (!m_client.getContextMenuFromDefaultMenu) return false; Vector<WebContextMenuItemData> defaultMenu = kitItems(proposedMenu); Vector<RefPtr<API::Object>> defaultMenuItems; defaultMenuItems.reserveInitialCapacity(defaultMenu.size()); for (const auto& item : defaultMenu) defaultMenuItems.uncheckedAppend(WebContextMenuItem::create(item)); WKArrayRef newMenuWK = nullptr; WKTypeRef userDataToPass = nullptr; m_client.getContextMenuFromDefaultMenu(toAPI(&page), toAPI(InjectedBundleHitTestResult::create(hitTestResult).get()), toAPI(API::Array::create(WTF::move(defaultMenuItems)).ptr()), &newMenuWK, &userDataToPass, m_client.base.clientInfo); RefPtr<API::Array> array = adoptRef(toImpl(newMenuWK)); userData = adoptRef(toImpl(userDataToPass)); newMenu.clear(); if (!array || !array->size()) return true; size_t size = array->size(); for (size_t i = 0; i < size; ++i) { WebContextMenuItem* item = array->at<WebContextMenuItem>(i); if (!item) { LOG(ContextMenu, "New menu entry at index %i is not a WebContextMenuItem", (int)i); continue; } newMenu.append(*item->data()); } return true; }
WebContextMenuItemData::WebContextMenuItemData(const WebCore::ContextMenuItem& item, WebCore::ContextMenu* menu) : m_type(item.type()) , m_action(item.action()) , m_title(item.title()) { if (m_type == WebCore::SubmenuType) { #if USE(CROSS_PLATFORM_CONTEXT_MENUS) const Vector<WebCore::ContextMenuItem>& coreSubmenu = item.subMenuItems(); #else Vector<WebCore::ContextMenuItem> coreSubmenu = WebCore::contextMenuItemVector(item.platformSubMenu()); #endif m_submenu = kitItems(coreSubmenu, menu); } m_enabled = item.enabled(); m_checked = item.checked(); }
void WebContextMenu::menuItemsWithUserData(Vector<WebContextMenuItemData> &menuItems, RefPtr<API::Object>& userData) const { ContextMenuController& controller = m_page->corePage()->contextMenuController(); ContextMenu* menu = controller.contextMenu(); if (!menu) return; // Give the bundle client a chance to process the menu. #if USE(CROSS_PLATFORM_CONTEXT_MENUS) const Vector<ContextMenuItem>& coreItems = menu->items(); #else Vector<ContextMenuItem> coreItems = contextMenuItemVector(menu->platformDescription()); #endif Vector<WebContextMenuItemData> proposedMenu = kitItems(coreItems, menu); Vector<WebContextMenuItemData> newMenu; RefPtr<InjectedBundleHitTestResult> hitTestResult = InjectedBundleHitTestResult::create(controller.hitTestResult()); if (m_page->injectedBundleContextMenuClient().getCustomMenuFromDefaultItems(m_page, hitTestResult.get(), proposedMenu, newMenu, userData)) proposedMenu = newMenu; menuItems = proposedMenu; }
void WebContextMenu::show() { ContextMenuController* controller = m_page->corePage()->contextMenuController(); if (!controller) return; ContextMenu* menu = controller->contextMenu(); if (!menu) return; Node* node = controller->hitTestResult().innerNonSharedNode(); if (!node) return; Frame* frame = node->document()->frame(); if (!frame) return; FrameView* view = frame->view(); if (!view) return; // Give the bundle client a chance to process the menu. #if USE(CROSS_PLATFORM_CONTEXT_MENUS) const Vector<ContextMenuItem>& coreItems = menu->items(); #else Vector<ContextMenuItem> coreItems = contextMenuItemVector(menu->platformDescription()); #endif Vector<WebContextMenuItemData> proposedMenu = kitItems(coreItems, menu); Vector<WebContextMenuItemData> newMenu; RefPtr<APIObject> userData; RefPtr<InjectedBundleHitTestResult> hitTestResult = InjectedBundleHitTestResult::create(controller->hitTestResult()); if (m_page->injectedBundleContextMenuClient().getCustomMenuFromDefaultItems(m_page, hitTestResult.get(), proposedMenu, newMenu, userData)) proposedMenu = newMenu; ContextMenuState contextMenuState; contextMenuState.absoluteImageURLString = controller->hitTestResult().absoluteImageURL().string(); contextMenuState.absoluteLinkURLString = controller->hitTestResult().absoluteLinkURL().string(); // Notify the UIProcess. m_page->send(Messages::WebPageProxy::ShowContextMenu(view->contentsToWindow(controller->hitTestResult().point()), contextMenuState, proposedMenu, InjectedBundleUserMessageEncoder(userData.get()))); }