153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)/*
253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2010 Igalia S.L
453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *
553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * modification, are permitted provided that the following conditions
753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * are met:
853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
1053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
1153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
1253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *    documentation and/or other materials provided with the distribution.
1353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *
1453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
1553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
1853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) */
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "config.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/ContextMenuController.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
3106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/Event.h"
3206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/MouseEvent.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Node.h"
34d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/ContextMenuClient.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/ContextMenuProvider.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/EventHandler.h"
3851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/ContextMenu.h"
3951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/ContextMenuItem.h"
4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)namespace WebCore {
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
43f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)ContextMenuController::ContextMenuController(Page*, ContextMenuClient* client)
44f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    : m_client(client)
4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_ARG(client, client);
4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)ContextMenuController::~ContextMenuController()
5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
53c4de9692585dd12fa75b760eebef04fa43fc1ae6Bo LiuPassOwnPtr<ContextMenuController> ContextMenuController::create(Page* page, ContextMenuClient* client)
5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
55c4de9692585dd12fa75b760eebef04fa43fc1ae6Bo Liu    return adoptPtr(new ContextMenuController(page, client));
5653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
5753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
5853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ContextMenuController::clearContextMenu()
5953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
6053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_contextMenu.clear();
6153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_menuProvider)
6253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_menuProvider->contextMenuCleared();
63d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_menuProvider = nullptr;
64e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    m_client->clearContextMenu();
65d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_hitTestResult = HitTestResult();
66e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
67e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
68e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)void ContextMenuController::documentDetached(Document* document)
69e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
70e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (Node* innerNode = m_hitTestResult.innerNode()) {
71e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        // Invalidate the context menu info if its target document is detached.
721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (innerNode->document() == document)
73e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            clearContextMenu();
74e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
7553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
7653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
7753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ContextMenuController::handleContextMenuEvent(Event* event)
7853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
7953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_contextMenu = createContextMenu(event);
8053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!m_contextMenu)
8153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
8253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    showContextMenu(event);
8453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
8553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenuProvider> menuProvider)
8753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
8853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_menuProvider = menuProvider;
8953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
9053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_contextMenu = createContextMenu(event);
9153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!m_contextMenu) {
9253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        clearContextMenu();
9353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
9453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
9553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
9653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_menuProvider->populateContextMenu(m_contextMenu.get());
9753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    showContextMenu(event);
9853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
9953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
10053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event)
10153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
10253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(event);
10302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
10453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!event->isMouseEvent())
10553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return nullptr;
10653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
107591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    MouseEvent* mouseEvent = toMouseEvent(event);
10853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    HitTestResult result(mouseEvent->absoluteLocation());
10953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
110d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (LocalFrame* frame = event->target()->toNode()->document().frame())
11119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        result = frame->eventHandler().hitTestResultAtPoint(mouseEvent->absoluteLocation(), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
11253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
11353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!result.innerNonSharedNode())
11453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return nullptr;
11553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
11653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_hitTestResult = result;
11753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
11853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return adoptPtr(new ContextMenu);
11953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
12053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
12153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ContextMenuController::showContextMenu(Event* event)
12253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
12393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    m_client->showContextMenu(m_contextMenu.get());
12453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    event->setDefaultHandled();
12553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
12653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
12753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ContextMenuController::contextMenuItemSelected(const ContextMenuItem* item)
12853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
12953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(item->type() == ActionType || item->type() == CheckableActionType);
13053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
13193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (item->action() < ContextMenuItemBaseCustomTag || item->action() > ContextMenuItemLastCustomTag)
13253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
13353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
13493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    ASSERT(m_menuProvider);
13593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    m_menuProvider->contextMenuItemSelected(item);
13653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
13753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
13853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} // namespace WebCore
139