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();
}
Example #3
0
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())));
}