Home | History | Annotate | Download | only in page
      1 /*
      2  * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
      3  * Copyright (C) 2010 Igalia S.L
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "config.h"
     28 #include "core/page/ContextMenuController.h"
     29 
     30 #include "core/dom/Document.h"
     31 #include "core/dom/Event.h"
     32 #include "core/dom/MouseEvent.h"
     33 #include "core/dom/Node.h"
     34 #include "core/page/ContextMenuClient.h"
     35 #include "core/page/ContextMenuProvider.h"
     36 #include "core/page/EventHandler.h"
     37 #include "core/page/Frame.h"
     38 #include "core/platform/ContextMenu.h"
     39 #include "core/platform/ContextMenuItem.h"
     40 #include "core/rendering/HitTestResult.h"
     41 
     42 namespace WebCore {
     43 
     44 ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* client)
     45     : m_page(page)
     46     , m_client(client)
     47 {
     48     ASSERT_ARG(page, page);
     49     ASSERT_ARG(client, client);
     50 }
     51 
     52 ContextMenuController::~ContextMenuController()
     53 {
     54 }
     55 
     56 PassOwnPtr<ContextMenuController> ContextMenuController::create(Page* page, ContextMenuClient* client)
     57 {
     58     return adoptPtr(new ContextMenuController(page, client));
     59 }
     60 
     61 void ContextMenuController::clearContextMenu()
     62 {
     63     m_contextMenu.clear();
     64     if (m_menuProvider)
     65         m_menuProvider->contextMenuCleared();
     66     m_menuProvider = 0;
     67 }
     68 
     69 void ContextMenuController::handleContextMenuEvent(Event* event)
     70 {
     71     m_contextMenu = createContextMenu(event);
     72     if (!m_contextMenu)
     73         return;
     74 
     75     showContextMenu(event);
     76 }
     77 
     78 void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenuProvider> menuProvider)
     79 {
     80     m_menuProvider = menuProvider;
     81 
     82     m_contextMenu = createContextMenu(event);
     83     if (!m_contextMenu) {
     84         clearContextMenu();
     85         return;
     86     }
     87 
     88     m_menuProvider->populateContextMenu(m_contextMenu.get());
     89     showContextMenu(event);
     90 }
     91 
     92 PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event)
     93 {
     94     ASSERT(event);
     95 
     96     if (!event->isMouseEvent())
     97         return nullptr;
     98 
     99     MouseEvent* mouseEvent = toMouseEvent(event);
    100     HitTestResult result(mouseEvent->absoluteLocation());
    101 
    102     if (Frame* frame = event->target()->toNode()->document()->frame())
    103         result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
    104 
    105     if (!result.innerNonSharedNode())
    106         return nullptr;
    107 
    108     m_hitTestResult = result;
    109 
    110     return adoptPtr(new ContextMenu);
    111 }
    112 
    113 void ContextMenuController::showContextMenu(Event* event)
    114 {
    115     m_client->showContextMenu(m_contextMenu.get());
    116     event->setDefaultHandled();
    117 }
    118 
    119 void ContextMenuController::contextMenuItemSelected(const ContextMenuItem* item)
    120 {
    121     ASSERT(item->type() == ActionType || item->type() == CheckableActionType);
    122 
    123     if (item->action() < ContextMenuItemBaseCustomTag || item->action() > ContextMenuItemLastCustomTag)
    124         return;
    125 
    126     ASSERT(m_menuProvider);
    127     m_menuProvider->contextMenuItemSelected(item);
    128 }
    129 
    130 } // namespace WebCore
    131