提交 725950ed 编写于 作者: E Elliott Sprehn

Remove context menus.

R=ojan@chromium.org

Review URL: https://codereview.chromium.org/640143004
上级 47a70575
......@@ -656,8 +656,6 @@ sky_core_files = [
"events/PopStateEvent.h",
"events/ProgressEvent.cpp",
"events/ProgressEvent.h",
"events/RelatedEvent.cpp",
"events/RelatedEvent.h",
"events/ResourceProgressEvent.cpp",
"events/ResourceProgressEvent.h",
"events/ScopedEventQueue.cpp",
......@@ -1021,8 +1019,6 @@ sky_core_files = [
"page/AutoscrollController.cpp",
"page/AutoscrollController.h",
"page/Chrome.cpp",
"page/ContextMenuController.cpp",
"page/ContextMenuProvider.h",
"page/EventHandler.cpp",
"page/EventWithHitTestResults.h",
"page/FocusController.cpp",
......@@ -1291,7 +1287,6 @@ core_idl_files = get_path_info([
"events/PageTransitionEvent.idl",
"events/PopStateEvent.idl",
"events/ProgressEvent.idl",
"events/RelatedEvent.idl",
"events/ResourceProgressEvent.idl",
"events/TextEvent.idl",
"events/TouchEvent.idl",
......@@ -1409,7 +1404,6 @@ core_event_idl_files = get_path_info([
"events/PageTransitionEvent.idl",
"events/PopStateEvent.idl",
"events/ProgressEvent.idl",
"events/RelatedEvent.idl",
"events/ResourceProgressEvent.idl",
"events/TextEvent.idl",
"events/TouchEvent.idl",
......
......@@ -72,7 +72,6 @@
#include "core/frame/Settings.h"
#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLStyleElement.h"
#include "core/page/ContextMenuController.h"
#include "core/page/EventHandler.h"
#include "core/page/Page.h"
#include "core/rendering/RenderBox.h"
......@@ -1823,9 +1822,6 @@ void Node::defaultEventHandler(Event* event)
int detail = event->isUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0;
if (dispatchDOMActivateEvent(detail, event))
event->setDefaultHandled();
} else if (eventType == EventTypeNames::contextmenu) {
if (Page* page = document().page())
page->contextMenuController().handleContextMenuEvent(event);
} else if (eventType == EventTypeNames::textInput) {
if (event->hasInterface(EventNames::TextEvent)) {
if (LocalFrame* frame = document().frame())
......
......@@ -168,11 +168,6 @@ bool Event::isWheelEvent() const
return false;
}
bool Event::isRelatedEvent() const
{
return false;
}
bool Event::isDragEvent() const
{
return false;
......
......@@ -145,7 +145,6 @@ public:
virtual bool isTouchEvent() const;
virtual bool isGestureEvent() const;
virtual bool isWheelEvent() const;
virtual bool isRelatedEvent() const;
// Drag events are a subset of mouse events.
virtual bool isDragEvent() const;
......
......@@ -50,7 +50,6 @@ compositionupdate
connect
connecting
contextlost
contextmenu
contextrestored
copy
cut
......
// 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/events/RelatedEvent.h"
namespace blink {
RelatedEventInit::RelatedEventInit()
{
}
RelatedEvent::~RelatedEvent()
{
}
PassRefPtrWillBeRawPtr<RelatedEvent> RelatedEvent::create()
{
return adoptRefWillBeNoop(new RelatedEvent);
}
PassRefPtrWillBeRawPtr<RelatedEvent> RelatedEvent::create(const AtomicString& type, bool canBubble, bool cancelable, EventTarget* relatedTarget)
{
return adoptRefWillBeNoop(new RelatedEvent(type, canBubble, cancelable, relatedTarget));
}
PassRefPtrWillBeRawPtr<RelatedEvent> RelatedEvent::create(const AtomicString& type, const RelatedEventInit& initializer)
{
return adoptRefWillBeNoop(new RelatedEvent(type, initializer));
}
RelatedEvent::RelatedEvent()
{
ScriptWrappable::init(this);
}
RelatedEvent::RelatedEvent(const AtomicString& type, bool canBubble, bool cancelable, EventTarget* relatedTarget)
: Event(type, canBubble, cancelable)
, m_relatedTarget(relatedTarget)
{
ScriptWrappable::init(this);
}
RelatedEvent::RelatedEvent(const AtomicString& eventType, const RelatedEventInit& initializer)
: Event(eventType, initializer)
, m_relatedTarget(initializer.relatedTarget)
{
ScriptWrappable::init(this);
}
void RelatedEvent::trace(Visitor* visitor)
{
visitor->trace(m_relatedTarget);
Event::trace(visitor);
}
} // namespace blink
// 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.
#ifndef RelatedEvent_h
#define RelatedEvent_h
#include "core/events/Event.h"
namespace blink {
struct RelatedEventInit : public EventInit {
RelatedEventInit();
RefPtrWillBeMember<EventTarget> relatedTarget;
};
class RelatedEvent FINAL : public Event {
DEFINE_WRAPPERTYPEINFO();
public:
static PassRefPtrWillBeRawPtr<RelatedEvent> create();
static PassRefPtrWillBeRawPtr<RelatedEvent> create(const AtomicString& type, bool canBubble, bool cancelable, EventTarget* relatedTarget);
static PassRefPtrWillBeRawPtr<RelatedEvent> create(const AtomicString& eventType, const RelatedEventInit&);
virtual ~RelatedEvent();
EventTarget* relatedTarget() const { return m_relatedTarget.get(); }
virtual const AtomicString& interfaceName() const OVERRIDE { return EventNames::RelatedEvent; }
virtual bool isRelatedEvent() const OVERRIDE { return true; }
virtual void trace(Visitor*) OVERRIDE;
private:
RelatedEvent();
RelatedEvent(const AtomicString& type, bool canBubble, bool cancelable, EventTarget*);
RelatedEvent(const AtomicString& type, const RelatedEventInit&);
RefPtrWillBeMember<EventTarget> m_relatedTarget;
};
DEFINE_EVENT_TYPE_CASTS(RelatedEvent);
} // namespace blink
#endif // RelatedEvent_h
// 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.
[
EventConstructor,
RuntimeEnabled=ContextMenu,
] interface RelatedEvent : Event {
[InitializedByEventConstructor] readonly attribute EventTarget? relatedTarget;
};
......@@ -38,9 +38,6 @@ void fillWithEmptyClients(Page::PageClients& pageClients)
static ChromeClient* dummyChromeClient = adoptPtr(new EmptyChromeClient).leakPtr();
pageClients.chromeClient = dummyChromeClient;
static ContextMenuClient* dummyContextMenuClient = adoptPtr(new EmptyContextMenuClient).leakPtr();
pageClients.contextMenuClient = dummyContextMenuClient;
static EditorClient* dummyEditorClient = adoptPtr(new EmptyEditorClient).leakPtr();
pageClients.editorClient = dummyEditorClient;
......
......@@ -32,7 +32,6 @@
#include "core/editing/UndoStep.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/page/ChromeClient.h"
#include "core/page/ContextMenuClient.h"
#include "core/page/EditorClient.h"
#include "core/page/FocusType.h"
#include "core/page/Page.h"
......@@ -189,15 +188,6 @@ public:
virtual bool handleKeyboardEvent() OVERRIDE { return false; }
};
class EmptyContextMenuClient FINAL : public ContextMenuClient {
WTF_MAKE_NONCOPYABLE(EmptyContextMenuClient); WTF_MAKE_FAST_ALLOCATED;
public:
EmptyContextMenuClient() { }
virtual ~EmptyContextMenuClient() { }
virtual void showContextMenu(const ContextMenu*) OVERRIDE { }
virtual void clearContextMenu() OVERRIDE { }
};
void fillWithEmptyClients(Page::PageClients&);
}
......
/*
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ContextMenuClient_h
#define ContextMenuClient_h
namespace blink {
class ContextMenu;
class ContextMenuClient {
public:
virtual ~ContextMenuClient() { }
virtual void showContextMenu(const ContextMenu*) = 0;
virtual void clearContextMenu() = 0;
};
}
#endif
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2010 Igalia S.L
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "core/page/ContextMenuController.h"
#include "core/dom/Document.h"
#include "core/dom/Node.h"
#include "core/events/Event.h"
#include "core/events/MouseEvent.h"
#include "core/events/RelatedEvent.h"
#include "core/frame/LocalFrame.h"
#include "core/page/ContextMenuClient.h"
#include "core/page/ContextMenuProvider.h"
#include "core/page/EventHandler.h"
#include "platform/ContextMenu.h"
#include "platform/ContextMenuItem.h"
namespace blink {
ContextMenuController::ContextMenuController(Page*, ContextMenuClient* client)
: m_client(client)
{
ASSERT_ARG(client, client);
}
ContextMenuController::~ContextMenuController()
{
}
PassOwnPtrWillBeRawPtr<ContextMenuController> ContextMenuController::create(Page* page, ContextMenuClient* client)
{
return adoptPtrWillBeNoop(new ContextMenuController(page, client));
}
void ContextMenuController::trace(Visitor* visitor)
{
visitor->trace(m_hitTestResult);
}
void ContextMenuController::clearContextMenu()
{
m_contextMenu.clear();
if (m_menuProvider)
m_menuProvider->contextMenuCleared();
m_menuProvider = nullptr;
m_client->clearContextMenu();
m_hitTestResult = HitTestResult();
}
void ContextMenuController::documentDetached(Document* document)
{
if (Node* innerNode = m_hitTestResult.innerNode()) {
// Invalidate the context menu info if its target document is detached.
if (innerNode->document() == document)
clearContextMenu();
}
}
void ContextMenuController::handleContextMenuEvent(Event* event)
{
m_contextMenu = createContextMenu(event);
if (!m_contextMenu)
return;
showContextMenu(event);
}
void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenuProvider> menuProvider)
{
m_menuProvider = menuProvider;
m_contextMenu = createContextMenu(event);
if (!m_contextMenu) {
clearContextMenu();
return;
}
m_menuProvider->populateContextMenu(m_contextMenu.get());
showContextMenu(event);
}
void ContextMenuController::showContextMenuAtPoint(LocalFrame* frame, float x, float y, PassRefPtr<ContextMenuProvider> menuProvider)
{
m_menuProvider = menuProvider;
LayoutPoint location(x, y);
m_contextMenu = createContextMenu(frame, location);
if (!m_contextMenu) {
clearContextMenu();
return;
}
m_menuProvider->populateContextMenu(m_contextMenu.get());
showContextMenu(nullptr);
}
PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event)
{
ASSERT(event);
if (!event->isMouseEvent())
return nullptr;
MouseEvent* mouseEvent = toMouseEvent(event);
return createContextMenu(event->target()->toNode()->document().frame(), mouseEvent->absoluteLocation());
}
PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(LocalFrame* frame, const LayoutPoint& location)
{
HitTestResult result(location);
if (frame)
result = frame->eventHandler().hitTestResultAtPoint(location, HitTestRequest::ReadOnly | HitTestRequest::Active);
if (!result.innerNonSharedNode())
return nullptr;
m_hitTestResult = result;
return adoptPtr(new ContextMenu);
}
void ContextMenuController::showContextMenu(Event* event)
{
m_client->showContextMenu(m_contextMenu.get());
if (event)
event->setDefaultHandled();
}
void ContextMenuController::contextMenuItemSelected(const ContextMenuItem* item)
{
ASSERT(item->type() == ActionType || item->type() == CheckableActionType);
if (item->action() < ContextMenuItemBaseCustomTag || item->action() > ContextMenuItemLastCustomTag)
return;
ASSERT(m_menuProvider);
m_menuProvider->contextMenuItemSelected(item);
}
} // namespace blink
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ContextMenuController_h
#define ContextMenuController_h
#include "core/rendering/HitTestResult.h"
#include "wtf/Noncopyable.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
namespace blink {
class ContextMenu;
class ContextMenuClient;
class ContextMenuItem;
class ContextMenuProvider;
class Document;
class Event;
class LocalFrame;
class Page;
class ContextMenuController : public NoBaseWillBeGarbageCollectedFinalized<ContextMenuController> {
WTF_MAKE_NONCOPYABLE(ContextMenuController); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
static PassOwnPtrWillBeRawPtr<ContextMenuController> create(Page*, ContextMenuClient*);
~ContextMenuController();
void trace(Visitor*);
ContextMenu* contextMenu() const { return m_contextMenu.get(); }
void clearContextMenu();
void documentDetached(Document*);
void handleContextMenuEvent(Event*);
void showContextMenu(Event*, PassRefPtr<ContextMenuProvider>);
void showContextMenuAtPoint(LocalFrame*, float x, float y, PassRefPtr<ContextMenuProvider>);
void contextMenuItemSelected(const ContextMenuItem*);
const HitTestResult& hitTestResult() { return m_hitTestResult; }
private:
ContextMenuController(Page*, ContextMenuClient*);
PassOwnPtr<ContextMenu> createContextMenu(Event*);
PassOwnPtr<ContextMenu> createContextMenu(LocalFrame*, const LayoutPoint&);
void showContextMenu(Event*);
ContextMenuClient* m_client;
OwnPtr<ContextMenu> m_contextMenu;
RefPtr<ContextMenuProvider> m_menuProvider;
HitTestResult m_hitTestResult;
};
}
#endif
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ContextMenuProvider_h
#define ContextMenuProvider_h
#include "wtf/RefCounted.h"
namespace blink {
class ContextMenu;
class ContextMenuItem;
class ContextMenuProvider : public RefCounted<ContextMenuProvider> {
public:
virtual ~ContextMenuProvider() { };
virtual void populateContextMenu(ContextMenu*) = 0;
virtual void contextMenuItemSelected(const ContextMenuItem*) = 0;
virtual void contextMenuCleared() = 0;
};
}
#endif // ContextMenuProvider_h
......@@ -177,7 +177,6 @@ EventHandler::EventHandler(LocalFrame* frame)
, m_lastGestureScrollOverWidget(false)
, m_maxMouseMovedDuration(0)
, m_didStartDrag(false)
, m_longTapShouldInvokeContextMenu(false)
, m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired)
, m_lastShowPressTimestamp(0)
{
......@@ -1318,15 +1317,8 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
bool swallowMouseUpEvent = !dispatchMouseEvent(EventTypeNames::mouseup, mev.targetNode(), m_clickCount, mouseEvent, false);
bool contextMenuEvent = mouseEvent.button() == RightButton;
#if OS(MACOSX)
// FIXME: The Mac port achieves the same behavior by checking whether the context menu is currently open in WebPage::mouseEvent(). Consider merging the implementations.
if (mouseEvent.button() == LeftButton && mouseEvent.modifiers() & PlatformEvent::CtrlKey)
contextMenuEvent = true;
#endif
bool swallowClickEvent = false;
if (m_clickCount > 0 && !contextMenuEvent && mev.targetNode() && m_clickNode) {
if (m_clickCount > 0 && mev.targetNode() && m_clickNode) {
if (Node* clickTargetNode = mev.targetNode()->commonAncestor(*m_clickNode, parentForClickEvent))
swallowClickEvent = !dispatchMouseEvent(EventTypeNames::click, clickTargetNode, m_clickCount, mouseEvent, true);
}
......@@ -1691,6 +1683,7 @@ bool EventHandler::handleGestureEventInFrame(const GestureEventWithHitTestResult
return true;
switch (gestureEvent.type()) {
case PlatformEvent::GestureTwoFingerTap: // FIXME(sky): Remove this.
case PlatformEvent::GestureTap:
return handleGestureTap(targetedEvent);
case PlatformEvent::GestureShowPress:
......@@ -1699,8 +1692,6 @@ bool EventHandler::handleGestureEventInFrame(const GestureEventWithHitTestResult
return handleGestureLongPress(targetedEvent);
case PlatformEvent::GestureLongTap:
return handleGestureLongTap(targetedEvent);
case PlatformEvent::GestureTwoFingerTap:
return sendContextMenuEventForGesture(targetedEvent);
case PlatformEvent::GestureTapDown:
case PlatformEvent::GesturePinchBegin:
case PlatformEvent::GesturePinchEnd:
......@@ -1865,7 +1856,6 @@ bool EventHandler::handleGestureLongPress(const GestureEventWithHitTestResults&
// supplied HitTestResult), but that will require some overhaul of the touch drag-and-drop code
// and LongPress is such a special scenario that it's unlikely to matter much in practice.
m_longTapShouldInvokeContextMenu = false;
#if OS(ANDROID)
bool shouldLongPressSelectWord = true;
#else
......@@ -1883,17 +1873,11 @@ bool EventHandler::handleGestureLongPress(const GestureEventWithHitTestResults&
}
}
}
return sendContextMenuEventForGesture(targetedEvent);
return true;
}
bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& targetedEvent)
{
#if !OS(ANDROID)
if (m_longTapShouldInvokeContextMenu) {
m_longTapShouldInvokeContextMenu = false;
return sendContextMenuEventForGesture(targetedEvent);
}
#endif
return false;
}
......@@ -2090,18 +2074,6 @@ bool EventHandler::bestClickableNodeForHitTestResult(const HitTestResult& result
return findBestClickableCandidate(targetNode, targetPoint, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> > (nodes));
}
bool EventHandler::bestContextMenuNodeForHitTestResult(const HitTestResult& result, IntPoint& targetPoint, Node*& targetNode)
{
ASSERT(result.isRectBasedTest());
IntPoint touchCenter = m_frame->view()->contentsToWindow(result.roundedPointInMainFrame());
IntRect touchRect = m_frame->view()->contentsToWindow(result.hitTestLocation().boundingBox());
WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
copyToVector(result.rectBasedTestResult(), nodes);
// FIXME: the explicit Vector conversion copies into a temporary and is wasteful.
return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes));
}
bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode)
{
IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
......@@ -2230,12 +2202,10 @@ void EventHandler::applyTouchAdjustment(PlatformGestureEvent* gestureEvent, HitT
case PlatformEvent::GestureTapUnconfirmed:
case PlatformEvent::GestureTapDown:
case PlatformEvent::GestureShowPress:
adjusted = bestClickableNodeForHitTestResult(*hitTestResult, adjustedPoint, adjustedNode);
break;
case PlatformEvent::GestureLongPress:
case PlatformEvent::GestureLongTap:
case PlatformEvent::GestureTwoFingerTap:
adjusted = bestContextMenuNodeForHitTestResult(*hitTestResult, adjustedPoint, adjustedNode);
adjusted = bestClickableNodeForHitTestResult(*hitTestResult, adjustedPoint, adjustedNode);
break;
default:
ASSERT_NOT_REACHED();
......@@ -2249,116 +2219,6 @@ void EventHandler::applyTouchAdjustment(PlatformGestureEvent* gestureEvent, HitT
}
}
bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
{
Document* doc = m_frame->document();
FrameView* v = m_frame->view();
if (!v)
return false;
// Clear mouse press state to avoid initiating a drag while context menu is up.
m_mousePressed = false;
LayoutPoint viewportPos = v->windowToContents(event.position());
HitTestRequest request(HitTestRequest::Active);
MouseEventWithHitTestResults mev = doc->prepareMouseEvent(request, viewportPos, event);
if (!m_frame->selection().contains(viewportPos)
&& !mev.scrollbar()
// FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
// If the selection is non-editable, we do word selection to make it easier to use the contextual menu items
// available for text selections. But only if we're above text.
&& (m_frame->selection().isContentEditable() || (mev.targetNode() && mev.targetNode()->isTextNode()))) {
m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
if (mev.hitTestResult().isMisspelled())
selectClosestMisspellingFromMouseEvent(mev);
else if (m_frame->editor().behavior().shouldSelectOnContextualMenuClick())
selectClosestWordOrLinkFromMouseEvent(mev);
}
return !dispatchMouseEvent(EventTypeNames::contextmenu, mev.targetNode(), 0, event, false);
}
bool EventHandler::sendContextMenuEventForKey()
{
FrameView* view = m_frame->view();
if (!view)
return false;
Document* doc = m_frame->document();
if (!doc)
return false;
// Clear mouse press state to avoid initiating a drag while context menu is up.
m_mousePressed = false;
static const int kContextMenuMargin = 1;
int rightAligned = 0;
IntPoint location;
Element* focusedElement = doc->focusedElement();
FrameSelection& selection = m_frame->selection();
Position start = selection.selection().start();
bool shouldTranslateToRootView = true;
if (start.deprecatedNode() && (selection.rootEditableElement() || selection.isRange())) {
RefPtrWillBeRawPtr<Range> selectionRange = selection.toNormalizedRange();
IntRect firstRect = m_frame->editor().firstRectForRange(selectionRange.get());
int x = rightAligned ? firstRect.maxX() : firstRect.x();
// In a multiline edit, firstRect.maxY() would endup on the next line, so -1.
int y = firstRect.maxY() ? firstRect.maxY() - 1 : 0;
location = IntPoint(x, y);
} else if (focusedElement) {
IntRect clippedRect = focusedElement->boundsInRootViewSpace();
location = IntPoint(clippedRect.center());
} else {
location = IntPoint(
rightAligned ? view->contentsWidth() - kContextMenuMargin : kContextMenuMargin,
kContextMenuMargin);
shouldTranslateToRootView = false;
}
m_frame->view()->setCursor(pointerCursor());
IntPoint position = shouldTranslateToRootView ? view->contentsToRootView(location) : location;
IntPoint globalPosition = view->hostWindow()->rootViewToScreen(IntRect(position, IntSize())).location();
Node* targetNode = doc->focusedElement();
if (!targetNode)
targetNode = doc;
// Use the focused node as the target for hover and active.
HitTestResult result(position);
result.setInnerNode(targetNode);
doc->updateHoverActiveState(HitTestRequest::Active, result.innerElement());
// The contextmenu event is a mouse event even when invoked using the keyboard.
// This is required for web compatibility.
PlatformEvent::Type eventType = PlatformEvent::MousePressed;
PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventType, 1, false, false, false, false, PlatformMouseEvent::RealOrIndistinguishable, WTF::currentTime());
handleMousePressEvent(mouseEvent);
return sendContextMenuEvent(mouseEvent);
}
bool EventHandler::sendContextMenuEventForGesture(const GestureEventWithHitTestResults& targetedEvent)
{
PlatformEvent::Type eventType = PlatformEvent::MousePressed;
PlatformMouseEvent mouseEvent(targetedEvent.event().position(), targetedEvent.event().globalPosition(), RightButton, eventType, 1, false, false, false, false, PlatformMouseEvent::RealOrIndistinguishable, WTF::currentTime());
// To simulate right-click behavior, we send a right mouse down and then
// context menu event.
// FIXME: Send HitTestResults to avoid redundant hit tests.
handleMousePressEvent(mouseEvent);
return sendContextMenuEvent(mouseEvent);
// We do not need to send a corresponding mouse release because in case of
// right-click, the context menu takes capture and consumes all events.
}
void EventHandler::scheduleHoverStateUpdate()
{
if (!m_hoverTimer.isActive())
......
......@@ -149,14 +149,9 @@ public:
bool isScrollbarHandlingGestures() const;
bool bestClickableNodeForHitTestResult(const HitTestResult&, IntPoint& targetPoint, Node*& targetNode);
bool bestContextMenuNodeForHitTestResult(const HitTestResult&, IntPoint& targetPoint, Node*& targetNode);
// FIXME: This doesn't appear to be used outside tests anymore, what path are we using now and is it tested?
bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
bool sendContextMenuEvent(const PlatformMouseEvent&);
bool sendContextMenuEventForKey();
bool sendContextMenuEventForGesture(const GestureEventWithHitTestResults&);
void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
static unsigned accessKeyModifiers();
......@@ -351,8 +346,6 @@ private:
double m_maxMouseMovedDuration;
bool m_didStartDrag;
bool m_longTapShouldInvokeContextMenu;
Timer<EventHandler> m_activeIntervalTimer;
double m_lastShowPressTimestamp;
RefPtrWillBeMember<Element> m_lastDeferredTapElement;
......
......@@ -37,7 +37,6 @@
#include "core/page/AutoscrollController.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
#include "core/page/ContextMenuController.h"
#include "core/page/FocusController.h"
#include "core/page/PageLifecycleNotifier.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
......@@ -99,7 +98,6 @@ Page::Page(PageClients& pageClients)
, m_chrome(Chrome::create(this, pageClients.chromeClient))
, m_dragCaretController(DragCaretController::create())
, m_focusController(FocusController::create(this))
, m_contextMenuController(ContextMenuController::create(this, pageClients.contextMenuClient))
, m_undoStack(UndoStack::create())
, m_mainFrame(0)
, m_editorClient(pageClients.editorClient)
......@@ -185,7 +183,6 @@ void Page::setMainFrame(LocalFrame* mainFrame)
void Page::documentDetached(Document* document)
{
m_multisamplingChangedObservers.clear();
m_contextMenuController->documentDetached(document);
}
bool Page::openedByDOM() const
......@@ -375,7 +372,6 @@ void Page::trace(Visitor* visitor)
{
#if ENABLE(OILPAN)
visitor->trace(m_dragCaretController);
visitor->trace(m_contextMenuController);
visitor->trace(m_undoStack);
visitor->trace(m_multisamplingChangedObservers);
visitor->trace(m_frameHost);
......@@ -408,7 +404,6 @@ void Page::willBeDestroyed()
Page::PageClients::PageClients()
: chromeClient(0)
, contextMenuClient(0)
, editorClient(0)
, spellCheckerClient(0)
{
......
......@@ -43,8 +43,6 @@ class AutoscrollController;
class Chrome;
class ChromeClient;
class ClientRectList;
class ContextMenuClient;
class ContextMenuController;
class Document;
class DragCaretController;
class EditorClient;
......@@ -82,7 +80,6 @@ public:
~PageClients();
ChromeClient* chromeClient;
ContextMenuClient* contextMenuClient;
EditorClient* editorClient;
SpellCheckerClient* spellCheckerClient;
};
......@@ -122,7 +119,6 @@ public:
AutoscrollController& autoscrollController() const { return *m_autoscrollController; }
DragCaretController& dragCaretController() const { return *m_dragCaretController; }
FocusController& focusController() const { return *m_focusController; }
ContextMenuController& contextMenuController() const { return *m_contextMenuController; }
ScrollingCoordinator* scrollingCoordinator();
......@@ -190,7 +186,6 @@ private:
const OwnPtr<Chrome> m_chrome;
const OwnPtrWillBeMember<DragCaretController> m_dragCaretController;
const OwnPtr<FocusController> m_focusController;
const OwnPtrWillBeMember<ContextMenuController> m_contextMenuController;
OwnPtr<ScrollingCoordinator> m_scrollingCoordinator;
const OwnPtrWillBeMember<UndoStack> m_undoStack;
......
......@@ -106,33 +106,6 @@ bool nodeIsZoomTarget(Node* node)
return node->renderer()->isBox();
}
bool providesContextMenuItems(Node* node)
{
// This function tries to match the nodes that receive special context-menu items in
// ContextMenuController::populate(), and should be kept uptodate with those.
ASSERT(node->renderer() || node->isShadowRoot());
if (!node->renderer())
return false;
if (node->isContentEditable())
return true;
if (node->isLink())
return true;
if (node->renderer()->isImage())
return true;
if (node->renderer()->isMedia())
return true;
if (node->renderer()->canBeSelectionLeaf()) {
// If the context menu gesture will trigger a selection all selectable nodes are valid targets.
if (node->renderer()->frame()->editor().behavior().shouldSelectOnContextualMenuClick())
return true;
// Only the selected part of the renderer is a valid target, but this will be corrected in
// appendContextSubtargetsForNode.
if (node->renderer()->selectionState() != RenderObject::SelectionNone)
return true;
}
return false;
}
static inline void appendQuadsToSubtargetList(Vector<FloatQuad>& quads, Node* node, SubtargetGeometryList& subtargets)
{
Vector<FloatQuad>::const_iterator it = quads.begin();
......@@ -152,65 +125,6 @@ static inline void appendBasicSubtargetsForNode(Node* node, SubtargetGeometryLis
appendQuadsToSubtargetList(quads, node, subtargets);
}
static inline void appendContextSubtargetsForNode(Node* node, SubtargetGeometryList& subtargets)
{
// This is a variant of appendBasicSubtargetsForNode that adds special subtargets for
// selected or auto-selectable parts of text nodes.
ASSERT(node->renderer());
if (!node->isTextNode())
return appendBasicSubtargetsForNode(node, subtargets);
Text* textNode = toText(node);
RenderText* textRenderer = textNode->renderer();
if (textRenderer->frame()->editor().behavior().shouldSelectOnContextualMenuClick()) {
// Make subtargets out of every word.
String textValue = textNode->data();
TextBreakIterator* wordIterator = wordBreakIterator(textValue, 0, textValue.length());
int lastOffset = wordIterator->first();
if (lastOffset == -1)
return;
int offset;
while ((offset = wordIterator->next()) != -1) {
if (isWordTextBreak(wordIterator)) {
Vector<FloatQuad> quads;
textRenderer->absoluteQuadsForRange(quads, lastOffset, offset);
appendQuadsToSubtargetList(quads, textNode, subtargets);
}
lastOffset = offset;
}
} else {
if (textRenderer->selectionState() == RenderObject::SelectionNone)
return appendBasicSubtargetsForNode(node, subtargets);
// If selected, make subtargets out of only the selected part of the text.
int startPos, endPos;
switch (textRenderer->selectionState()) {
case RenderObject::SelectionInside:
startPos = 0;
endPos = textRenderer->textLength();
break;
case RenderObject::SelectionStart:
textRenderer->selectionStartEnd(startPos, endPos);
endPos = textRenderer->textLength();
break;
case RenderObject::SelectionEnd:
textRenderer->selectionStartEnd(startPos, endPos);
startPos = 0;
break;
case RenderObject::SelectionBoth:
textRenderer->selectionStartEnd(startPos, endPos);
break;
default:
ASSERT_NOT_REACHED();
return;
}
Vector<FloatQuad> quads;
textRenderer->absoluteQuadsForRange(quads, startPos, endPos);
appendQuadsToSubtargetList(quads, textNode, subtargets);
}
}
static inline void appendZoomableSubtargets(Node* node, SubtargetGeometryList& subtargets)
{
RenderBox* renderer = toRenderBox(node->renderer());
......@@ -487,14 +401,6 @@ bool findBestClickableCandidate(Node*& targetNode, IntPoint& targetPoint, const
return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetPoint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::hybridDistanceFunction);
}
bool findBestContextMenuCandidate(Node*& targetNode, IntPoint& targetPoint, const IntPoint& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPtrWillBeMember<Node> >& nodes)
{
IntRect targetArea;
TouchAdjustment::SubtargetGeometryList subtargets;
TouchAdjustment::compileSubtargetList(nodes, subtargets, TouchAdjustment::providesContextMenuItems, TouchAdjustment::appendContextSubtargetsForNode);
return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetPoint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::hybridDistanceFunction);
}
bool findBestZoomableArea(Node*& targetNode, IntRect& targetArea, const IntPoint& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPtrWillBeMember<Node> >& nodes)
{
IntPoint targetPoint;
......
......@@ -31,7 +31,6 @@ namespace blink {
class Node;
bool findBestClickableCandidate(Node*& targetNode, IntPoint& targetPoint, const IntPoint& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPtrWillBeMember<Node> >&);
bool findBestContextMenuCandidate(Node*& targetNode, IntPoint& targetPoint, const IntPoint& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPtrWillBeMember<Node> >&);
bool findBestZoomableArea(Node*& targetNode, IntRect& targetArea, const IntPoint& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPtrWillBeMember<Node> >&);
// FIXME: Implement the similar functions for other gestures here as well.
......
......@@ -56,7 +56,6 @@ DummyPageHolder::DummyPageHolder(
fillWithEmptyClients(m_pageClients);
} else {
m_pageClients.chromeClient = pageClients->chromeClient;
m_pageClients.contextMenuClient = pageClients->contextMenuClient;
m_pageClients.editorClient = pageClients->editorClient;
m_pageClients.spellCheckerClient = pageClients->spellCheckerClient;
}
......
......@@ -115,10 +115,6 @@ component("platform") {
"Clock.h",
"ContentType.cpp",
"ContentType.h",
"ContextMenu.cpp",
"ContextMenu.h",
"ContextMenuItem.cpp",
"ContextMenuItem.h",
"Cursor.cpp",
"Cursor.h",
"DateComponents.cpp",
......
/*
* Copyright (C) 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "platform/ContextMenu.h"
namespace blink {
static const ContextMenuItem* findItemWithAction(unsigned action, const Vector<ContextMenuItem>& items)
{
for (size_t i = 0; i < items.size(); ++i) {
const ContextMenuItem& item = items[i];
if (item.action() == static_cast<ContextMenuAction>(action))
return &item;
if (item.type() != SubmenuType)
continue;
if (const ContextMenuItem* subMenuItem = findItemWithAction(action, item.subMenuItems()))
return subMenuItem;
}
return 0;
}
const ContextMenuItem* ContextMenu::itemWithAction(unsigned action) const
{
return findItemWithAction(action, m_items);
}
} // namespace blink
/*
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ContextMenu_h
#define ContextMenu_h
#include "platform/ContextMenuItem.h"
#include "platform/PlatformExport.h"
#include "wtf/Noncopyable.h"
#include "wtf/Vector.h"
namespace blink {
class PLATFORM_EXPORT ContextMenu {
WTF_MAKE_NONCOPYABLE(ContextMenu); WTF_MAKE_FAST_ALLOCATED;
public:
ContextMenu() { }
const ContextMenuItem* itemWithAction(unsigned) const;
const Vector<ContextMenuItem>& items() const { return m_items; }
void appendItem(const ContextMenuItem& item) { m_items.append(item); }
void removeLastItem() { m_items.removeLast(); }
private:
Vector<ContextMenuItem> m_items;
};
}
#endif // ContextMenu_h
/*
* Copyright (C) 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "platform/ContextMenuItem.h"
#include "platform/ContextMenu.h"
namespace blink {
ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* subMenu)
: m_type(type)
, m_action(action)
, m_title(title)
, m_enabled(true)
, m_checked(false)
{
if (subMenu)
setSubMenu(subMenu);
}
ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, bool enabled, bool checked)
: m_type(type)
, m_action(action)
, m_title(title)
, m_enabled(enabled)
, m_checked(checked)
{
}
ContextMenuItem::ContextMenuItem(ContextMenuAction action, const String& title, bool enabled, bool checked, const Vector<ContextMenuItem>& subMenuItems)
: m_type(SubmenuType)
, m_action(action)
, m_title(title)
, m_enabled(enabled)
, m_checked(checked)
, m_subMenuItems(subMenuItems)
{
}
ContextMenuItem::~ContextMenuItem()
{
}
void ContextMenuItem::setSubMenu(ContextMenu* subMenu)
{
if (subMenu) {
m_type = SubmenuType;
m_subMenuItems = subMenu->items();
} else {
m_type = ActionType;
m_subMenuItems.clear();
}
}
void ContextMenuItem::setType(ContextMenuItemType type)
{
m_type = type;
}
ContextMenuItemType ContextMenuItem::type() const
{
return m_type;
}
void ContextMenuItem::setAction(ContextMenuAction action)
{
m_action = action;
}
ContextMenuAction ContextMenuItem::action() const
{
return m_action;
}
void ContextMenuItem::setChecked(bool checked)
{
m_checked = checked;
}
bool ContextMenuItem::checked() const
{
return m_checked;
}
void ContextMenuItem::setEnabled(bool enabled)
{
m_enabled = enabled;
}
bool ContextMenuItem::enabled() const
{
return m_enabled;
}
} // namespace blink
/*
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2010 Igalia S.L
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ContextMenuItem_h
#define ContextMenuItem_h
#include "platform/PlatformExport.h"
#include "wtf/OwnPtr.h"
#include "wtf/text/WTFString.h"
namespace blink {
class ContextMenu;
enum ContextMenuAction {
ContextMenuItemBaseCustomTag = 5000,
ContextMenuItemCustomTagNoAction = 5998,
ContextMenuItemLastCustomTag = 5999
};
enum ContextMenuItemType {
ActionType,
CheckableActionType,
SeparatorType,
SubmenuType
};
class PLATFORM_EXPORT ContextMenuItem {
WTF_MAKE_FAST_ALLOCATED;
public:
ContextMenuItem(ContextMenuItemType, ContextMenuAction, const String&, ContextMenu* subMenu = 0);
ContextMenuItem(ContextMenuItemType, ContextMenuAction, const String&, bool enabled, bool checked);
~ContextMenuItem();
void setType(ContextMenuItemType);
ContextMenuItemType type() const;
void setAction(ContextMenuAction);
ContextMenuAction action() const;
void setChecked(bool = true);
bool checked() const;
void setEnabled(bool = true);
bool enabled() const;
void setSubMenu(ContextMenu*);
ContextMenuItem(ContextMenuAction, const String&, bool enabled, bool checked, const Vector<ContextMenuItem>& subMenuItems);
void setTitle(const String& title) { m_title = title; }
const String& title() const { return m_title; }
const Vector<ContextMenuItem>& subMenuItems() const { return m_subMenuItems; }
private:
ContextMenuItemType m_type;
ContextMenuAction m_action;
String m_title;
bool m_enabled;
bool m_checked;
Vector<ContextMenuItem> m_subMenuItems;
};
}
#endif // ContextMenuItem_h
......@@ -31,7 +31,6 @@ PrefixedVideoFullscreen status=stable
BleedingEdgeFastPaths
ClientHintsDpr status=experimental
ContextMenu status=experimental
Crypto status=stable
CSSAnimationUnprefixed status=experimental
CSSAttributeCaseSensitivity status=experimental
......
/*
* Copyright (C) 2009, 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef WebContextMenuData_h
#define WebContextMenuData_h
#include "../platform/WebPoint.h"
#include "../platform/WebReferrerPolicy.h"
#include "../platform/WebString.h"
#include "../platform/WebURL.h"
#include "../platform/WebVector.h"
#include "WebMenuItemInfo.h"
#include "WebNode.h"
#define WEBCONTEXT_MEDIATYPEFILE_DEFINED
namespace blink {
// This struct is passed to WebViewClient::ShowContextMenu.
struct WebContextMenuData {
enum MediaType {
// No special node is in context.
MediaTypeNone,
// An image node is selected.
MediaTypeImage,
// A video node is selected.
MediaTypeVideo,
// An audio node is selected.
MediaTypeAudio,
// A canvas node is selected.
MediaTypeCanvas,
// A file node is selected.
MediaTypeFile,
// A plugin node is selected.
MediaTypePlugin,
MediaTypeLast = MediaTypePlugin
};
// The type of media the context menu is being invoked on.
MediaType mediaType;
// The x and y position of the mouse pointer (relative to the webview).
WebPoint mousePosition;
// The absolute URL of the link that is in context.
WebURL linkURL;
// The absolute URL of the image/video/audio that is in context.
WebURL srcURL;
// Whether the image in context is a null.
bool hasImageContents;
// The absolute URL of the page in context.
WebURL pageURL;
// The absolute keyword search URL including the %s search tag when the
// "Add as search engine..." option is clicked (left empty if not used).
WebURL keywordURL;
// The absolute URL of the subframe in context.
WebURL frameURL;
// The encoding for the frame in context.
WebString frameEncoding;
enum MediaFlags {
MediaNone = 0x0,
MediaInError = 0x1,
MediaPaused = 0x2,
MediaMuted = 0x4,
MediaLoop = 0x8,
MediaCanSave = 0x10,
MediaHasAudio = 0x20,
MediaCanToggleControls = 0x40,
MediaControls = 0x80,
MediaCanPrint = 0x100,
MediaCanRotate = 0x200,
};
// Extra attributes describing media elements.
int mediaFlags;
// The raw text of the selection in context.
WebString selectedText;
// Whether spell checking is enabled.
bool isSpellCheckingEnabled;
// Suggested filename for saving file.
WebString suggestedFilename;
// The editable (possibily) misspelled word.
WebString misspelledWord;
// The identifier of the misspelling.
uint32_t misspellingHash;
// If misspelledWord is not empty, holds suggestions from the dictionary.
WebVector<WebString> dictionarySuggestions;
// Whether context is editable.
bool isEditable;
enum CheckableMenuItemFlags {
CheckableMenuItemDisabled = 0x0,
CheckableMenuItemEnabled = 0x1,
CheckableMenuItemChecked = 0x2,
};
// Writing direction menu items - values are unions of
// CheckableMenuItemFlags.
int writingDirectionDefault;
int writingDirectionLeftToRight;
int writingDirectionRightToLeft;
enum EditFlags {
CanDoNone = 0x0,
CanUndo = 0x1,
CanRedo = 0x2,
CanCut = 0x4,
CanCopy = 0x8,
CanPaste = 0x10,
CanDelete = 0x20,
CanSelectAll = 0x40,
CanTranslate = 0x80,
};
// Which edit operations are available in the context.
int editFlags;
// Security information for the context.
WebCString securityInfo;
// The referrer policy applicable to this context.
WebReferrerPolicy referrerPolicy;
// Custom context menu items provided by the WebCore internals.
WebVector<WebMenuItemInfo> customItems;
// The node that was clicked.
WebNode node;
WebContextMenuData()
: mediaType(MediaTypeNone)
, hasImageContents(true)
, mediaFlags(MediaNone)
, isSpellCheckingEnabled(false)
, misspellingHash(0)
, isEditable(false)
, writingDirectionDefault(CheckableMenuItemDisabled)
, writingDirectionLeftToRight(CheckableMenuItemEnabled)
, writingDirectionRightToLeft(CheckableMenuItemEnabled)
, editFlags(0) { }
};
} // namespace blink
#endif
......@@ -56,7 +56,6 @@ class WebURLLoader;
class WebURLResponse;
struct WebColorSuggestion;
struct WebConsoleMessage;
struct WebContextMenuData;
struct WebRect;
struct WebSize;
struct WebURLError;
......@@ -174,18 +173,6 @@ public:
// operations.
virtual void didChangeSelection(bool isSelectionEmpty) { }
// UI ------------------------------------------------------------------
// Shows a context menu with commands relevant to a specific element on
// the given frame. Additional context data is supplied.
virtual void showContextMenu(const WebContextMenuData&) { }
// Called when the data attached to the currently displayed context menu is
// invalidated. The context menu may be closed if possible.
virtual void clearContextMenu() { }
// Low-level resource notifications ------------------------------------
// An element will request a resource.
......
......@@ -94,8 +94,7 @@ public:
MouseMove,
MouseEnter,
MouseLeave,
ContextMenu,
MouseTypeLast = ContextMenu,
MouseTypeLast = MouseLeave,
// WebMouseWheelEvent
MouseWheel,
......
......@@ -266,14 +266,6 @@ public:
// to implement device metrics emulation.
virtual void setRootLayerTransform(const WebSize& offset, float scale) = 0;
// Context menu --------------------------------------------------------
virtual void performCustomContextMenuAction(unsigned action) = 0;
// Shows a context menu for the currently focused element.
virtual void showContextMenu() = 0;
// SmartClip support ---------------------------------------------------
virtual void extractSmartClipData(WebRect initRect, WebString& text, WebString& html, WebRect& resultRect) = 0;
......
......@@ -40,8 +40,6 @@ component("web") {
"CompositionUnderlineBuilder.h",
"CompositionUnderlineVectorBuilder.cpp",
"CompositionUnderlineVectorBuilder.h",
"ContextMenuClientImpl.cpp",
"ContextMenuClientImpl.h",
"EditorClientImpl.cpp",
"EditorClientImpl.h",
"FrameLoaderClientImpl.cpp",
......
/*
* Copyright (C) 2009, 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "web/ContextMenuClientImpl.h"
#include "bindings/core/v8/ExceptionStatePlaceholder.h"
#include "core/CSSPropertyNames.h"
#include "core/HTMLNames.h"
#include "core/css/CSSStyleDeclaration.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentMarkerController.h"
#include "core/editing/Editor.h"
#include "core/editing/SpellChecker.h"
#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
#include "core/frame/PinchViewport.h"
#include "core/frame/Settings.h"
#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/MediaError.h"
#include "core/page/ContextMenuController.h"
#include "core/page/EventHandler.h"
#include "core/page/Page.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderWidget.h"
#include "platform/ContextMenu.h"
#include "platform/Widget.h"
#include "platform/text/TextBreakIterator.h"
#include "platform/weborigin/KURL.h"
#include "public/platform/WebPoint.h"
#include "public/platform/WebString.h"
#include "public/platform/WebURL.h"
#include "public/platform/WebURLResponse.h"
#include "public/platform/WebVector.h"
#include "public/web/WebContextMenuData.h"
#include "public/web/WebFrameClient.h"
#include "public/web/WebMenuItemInfo.h"
#include "public/web/WebSpellCheckClient.h"
#include "public/web/WebViewClient.h"
#include "web/WebLocalFrameImpl.h"
#include "web/WebViewImpl.h"
#include "wtf/text/WTFString.h"
namespace blink {
// Figure out the URL of a page or subframe. Returns |page_type| as the type,
// which indicates page or subframe, or ContextNodeType::NONE if the URL could not
// be determined for some reason.
static WebURL urlFromFrame(LocalFrame* frame)
{
// FIXME(sky): This used to reach through the DocumentLoader but that made no sense.
if (frame)
return frame->document()->url();
return WebURL();
}
// Helper function to determine whether text is a single word.
static bool isASingleWord(const String& text)
{
TextBreakIterator* it = wordBreakIterator(text, 0, text.length());
return it && it->next() == static_cast<int>(text.length());
}
// Helper function to get misspelled word on which context menu
// is to be invoked. This function also sets the word on which context menu
// has been invoked to be the selected word, as required. This function changes
// the selection only when there were no selected characters on OS X.
static String selectMisspelledWord(LocalFrame* selectedFrame)
{
// First select from selectedText to check for multiple word selection.
String misspelledWord = selectedFrame->selectedText().stripWhiteSpace();
// If some texts were already selected, we don't change the selection.
if (!misspelledWord.isEmpty()) {
// Don't provide suggestions for multiple words.
if (!isASingleWord(misspelledWord))
return String();
return misspelledWord;
}
// Selection is empty, so change the selection to the word under the cursor.
HitTestResult hitTestResult = selectedFrame->eventHandler().
hitTestResultAtPoint(selectedFrame->page()->contextMenuController().hitTestResult().pointInInnerNodeFrame());
Node* innerNode = hitTestResult.innerNode();
VisiblePosition pos(innerNode->renderer()->positionForPoint(
hitTestResult.localPoint()));
if (pos.isNull())
return misspelledWord; // It is empty.
WebLocalFrameImpl::selectWordAroundPosition(selectedFrame, pos);
misspelledWord = selectedFrame->selectedText().stripWhiteSpace();
#if OS(MACOSX)
// If misspelled word is still empty, then that portion should not be
// selected. Set the selection to that position only, and do not expand.
if (misspelledWord.isEmpty())
selectedFrame->selection().setSelection(VisibleSelection(pos));
#else
// On non-Mac, right-click should not make a range selection in any case.
selectedFrame->selection().setSelection(VisibleSelection(pos));
#endif
return misspelledWord;
}
static bool IsWhiteSpaceOrPunctuation(UChar c)
{
return isSpaceOrNewline(c) || WTF::Unicode::isPunct(c);
}
static String selectMisspellingAsync(LocalFrame* selectedFrame, String& description, uint32_t& hash)
{
VisibleSelection selection = selectedFrame->selection().selection();
if (!selection.isCaretOrRange())
return String();
// Caret and range selections always return valid normalized ranges.
RefPtrWillBeRawPtr<Range> selectionRange = selection.toNormalizedRange();
DocumentMarkerVector markers = selectedFrame->document()->markers().markersInRange(selectionRange.get(), DocumentMarker::MisspellingMarkers());
if (markers.size() != 1)
return String();
description = markers[0]->description();
hash = markers[0]->hash();
// Cloning a range fails only for invalid ranges.
RefPtrWillBeRawPtr<Range> markerRange = selectionRange->cloneRange();
markerRange->setStart(markerRange->startContainer(), markers[0]->startOffset());
markerRange->setEnd(markerRange->endContainer(), markers[0]->endOffset());
if (markerRange->text().stripWhiteSpace(&IsWhiteSpaceOrPunctuation) != selectionRange->text().stripWhiteSpace(&IsWhiteSpaceOrPunctuation))
return String();
return markerRange->text();
}
void ContextMenuClientImpl::showContextMenu(const ContextMenu* defaultMenu)
{
// Displaying the context menu in this function is a big hack as we don't
// have context, i.e. whether this is being invoked via a script or in
// response to user input (Mouse event WM_RBUTTONDOWN,
// Keyboard events KeyVK_APPS, Shift+F10). Check if this is being invoked
// in response to the above input events before popping up the context menu.
if (!m_webView->contextMenuAllowed())
return;
HitTestResult r = m_webView->page()->contextMenuController().hitTestResult();
LocalFrame* selectedFrame = r.innerNodeFrame();
WebContextMenuData data;
IntPoint mousePoint = selectedFrame->view()->contentsToWindow(r.roundedPointInInnerNodeFrame());
// FIXME(bokan): crbug.com/371902 - We shouldn't be making these scale
// related coordinate transformatios in an ad hoc way.
PinchViewport& pinchViewport = selectedFrame->host()->pinchViewport();
mousePoint -= flooredIntSize(pinchViewport.visibleRect().location());
data.mousePosition = mousePoint;
// Compute edit flags.
data.editFlags = WebContextMenuData::CanDoNone;
Editor& editor = m_webView->focusedCoreFrame()->editor();
if (editor.canUndo())
data.editFlags |= WebContextMenuData::CanUndo;
if (editor.canRedo())
data.editFlags |= WebContextMenuData::CanRedo;
if (editor.canCut())
data.editFlags |= WebContextMenuData::CanCut;
if (editor.canCopy())
data.editFlags |= WebContextMenuData::CanCopy;
if (editor.canPaste())
data.editFlags |= WebContextMenuData::CanPaste;
if (editor.canDelete())
data.editFlags |= WebContextMenuData::CanDelete;
data.editFlags |= WebContextMenuData::CanTranslate;
// Links, Images, Media tags, and Image/Media-Links take preference over
// all else.
data.linkURL = r.absoluteLinkURL();
if (isHTMLCanvasElement(r.innerNonSharedNode())) {
data.mediaType = WebContextMenuData::MediaTypeCanvas;
data.hasImageContents = true;
} else if (!r.absoluteImageURL().isEmpty()) {
data.srcURL = r.absoluteImageURL();
data.mediaType = WebContextMenuData::MediaTypeImage;
data.mediaFlags |= WebContextMenuData::MediaCanPrint;
// An image can be null for many reasons, like being blocked, no image
// data received from server yet.
data.hasImageContents = r.image() && !r.image()->isNull();
} else if (!r.absoluteMediaURL().isEmpty()) {
data.srcURL = r.absoluteMediaURL();
// We know that if absoluteMediaURL() is not empty, then this
// is a media element.
HTMLMediaElement* mediaElement = toHTMLMediaElement(r.innerNonSharedNode());
if (isHTMLVideoElement(*mediaElement))
data.mediaType = WebContextMenuData::MediaTypeVideo;
else if (isHTMLAudioElement(*mediaElement))
data.mediaType = WebContextMenuData::MediaTypeAudio;
if (mediaElement->error())
data.mediaFlags |= WebContextMenuData::MediaInError;
if (mediaElement->paused())
data.mediaFlags |= WebContextMenuData::MediaPaused;
if (mediaElement->muted())
data.mediaFlags |= WebContextMenuData::MediaMuted;
if (mediaElement->loop())
data.mediaFlags |= WebContextMenuData::MediaLoop;
if (mediaElement->supportsSave())
data.mediaFlags |= WebContextMenuData::MediaCanSave;
if (mediaElement->hasAudio())
data.mediaFlags |= WebContextMenuData::MediaHasAudio;
// Media controls can be toggled only for video player. If we toggle
// controls for audio then the player disappears, and there is no way to
// return it back. Don't set this bit for fullscreen video, since
// toggling is ignored in that case.
if (mediaElement->hasVideo() && !mediaElement->isFullscreen())
data.mediaFlags |= WebContextMenuData::MediaCanToggleControls;
}
// Send the frame and page URLs in any case.
data.pageURL = urlFromFrame(m_webView->mainFrameImpl()->frame());
if (selectedFrame != m_webView->mainFrameImpl()->frame()) {
data.frameURL = urlFromFrame(selectedFrame);
}
if (r.isSelected())
data.selectedText = selectedFrame->selectedText().stripWhiteSpace();
if (r.isContentEditable()) {
data.isEditable = true;
// When Chrome enables asynchronous spellchecking, its spellchecker adds spelling markers to misspelled
// words and attaches suggestions to these markers in the background. Therefore, when a user right-clicks
// a mouse on a word, Chrome just needs to find a spelling marker on the word instead of spellchecking it.
if (selectedFrame->settings() && selectedFrame->settings()->asynchronousSpellCheckingEnabled()) {
String description;
uint32_t hash = 0;
data.misspelledWord = selectMisspellingAsync(selectedFrame, description, hash);
data.misspellingHash = hash;
if (description.length()) {
Vector<String> suggestions;
description.split('\n', suggestions);
data.dictionarySuggestions = suggestions;
} else if (m_webView->spellCheckClient()) {
int misspelledOffset, misspelledLength;
m_webView->spellCheckClient()->spellCheck(data.misspelledWord, misspelledOffset, misspelledLength, &data.dictionarySuggestions);
}
} else {
SpellChecker& spellChecker = m_webView->focusedCoreFrame()->spellChecker();
data.isSpellCheckingEnabled = spellChecker.isContinuousSpellCheckingEnabled();
// Spellchecking might be enabled for the field, but could be disabled on the node.
if (spellChecker.isSpellCheckingEnabledInFocusedNode()) {
data.misspelledWord = selectMisspelledWord(selectedFrame);
if (m_webView->spellCheckClient()) {
int misspelledOffset, misspelledLength;
m_webView->spellCheckClient()->spellCheck(
data.misspelledWord, misspelledOffset, misspelledLength,
&data.dictionarySuggestions);
if (!misspelledLength)
data.misspelledWord.reset();
}
}
}
}
if (selectedFrame->editor().selectionHasStyle(CSSPropertyDirection, "ltr") != FalseTriState)
data.writingDirectionLeftToRight |= WebContextMenuData::CheckableMenuItemChecked;
if (selectedFrame->editor().selectionHasStyle(CSSPropertyDirection, "rtl") != FalseTriState)
data.writingDirectionRightToLeft |= WebContextMenuData::CheckableMenuItemChecked;
data.referrerPolicy = static_cast<WebReferrerPolicy>(selectedFrame->document()->referrerPolicy());
// Filter out custom menu elements and add them into the data.
populateCustomMenuItems(defaultMenu, &data);
// Extract suggested filename for saving file.
if (isHTMLAnchorElement(r.URLElement())) {
HTMLAnchorElement* anchor = toHTMLAnchorElement(r.URLElement());
data.suggestedFilename = anchor->getAttribute(HTMLNames::downloadAttr);
}
data.node = r.innerNonSharedNode();
WebLocalFrameImpl* selectedWebFrame = WebLocalFrameImpl::fromFrame(selectedFrame);
if (selectedWebFrame->client())
selectedWebFrame->client()->showContextMenu(data);
}
void ContextMenuClientImpl::clearContextMenu()
{
HitTestResult r = m_webView->page()->contextMenuController().hitTestResult();
LocalFrame* selectedFrame = r.innerNodeFrame();
if (!selectedFrame)
return;
WebLocalFrameImpl* selectedWebFrame = WebLocalFrameImpl::fromFrame(selectedFrame);
if (selectedWebFrame->client())
selectedWebFrame->client()->clearContextMenu();
}
static void populateSubMenuItems(const Vector<ContextMenuItem>& inputMenu, WebVector<WebMenuItemInfo>& subMenuItems)
{
Vector<WebMenuItemInfo> subItems;
for (size_t i = 0; i < inputMenu.size(); ++i) {
const ContextMenuItem* inputItem = &inputMenu.at(i);
if (inputItem->action() < ContextMenuItemBaseCustomTag || inputItem->action() > ContextMenuItemLastCustomTag)
continue;
WebMenuItemInfo outputItem;
outputItem.label = inputItem->title();
outputItem.enabled = inputItem->enabled();
outputItem.checked = inputItem->checked();
outputItem.action = static_cast<unsigned>(inputItem->action() - ContextMenuItemBaseCustomTag);
switch (inputItem->type()) {
case ActionType:
outputItem.type = WebMenuItemInfo::Option;
break;
case CheckableActionType:
outputItem.type = WebMenuItemInfo::CheckableOption;
break;
case SeparatorType:
outputItem.type = WebMenuItemInfo::Separator;
break;
case SubmenuType:
outputItem.type = WebMenuItemInfo::SubMenu;
populateSubMenuItems(inputItem->subMenuItems(), outputItem.subMenuItems);
break;
}
subItems.append(outputItem);
}
WebVector<WebMenuItemInfo> outputItems(subItems.size());
for (size_t i = 0; i < subItems.size(); ++i)
outputItems[i] = subItems[i];
subMenuItems.swap(outputItems);
}
void ContextMenuClientImpl::populateCustomMenuItems(const ContextMenu* defaultMenu, WebContextMenuData* data)
{
populateSubMenuItems(defaultMenu->items(), data->customItems);
}
} // namespace blink
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ContextMenuClientImpl_h
#define ContextMenuClientImpl_h
#include "core/page/ContextMenuClient.h"
namespace blink {
class WebViewImpl;
struct WebContextMenuData;
class ContextMenuClientImpl FINAL : public ContextMenuClient {
public:
explicit ContextMenuClientImpl(WebViewImpl* webView) : m_webView(webView) { }
virtual ~ContextMenuClientImpl() {}
virtual void showContextMenu(const ContextMenu*) OVERRIDE;
virtual void clearContextMenu() OVERRIDE;
private:
void populateCustomMenuItems(const ContextMenu*, WebContextMenuData*);
WebViewImpl* m_webView;
};
} // namespace blink
#endif // ContextMenuClientImpl_h
......@@ -514,8 +514,6 @@ WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget, const RenderObj
type = WebInputEvent::MouseDown;
else if (event.type() == EventTypeNames::mouseup)
type = WebInputEvent::MouseUp;
else if (event.type() == EventTypeNames::contextmenu)
type = WebInputEvent::ContextMenu;
else
return; // Skip all other mouse events.
......
......@@ -56,8 +56,6 @@
#include "core/loader/FrameLoader.h"
#include "core/loader/UniqueIdentifier.h"
#include "core/page/Chrome.h"
#include "core/page/ContextMenuController.h"
#include "core/page/ContextMenuProvider.h"
#include "core/page/EventHandler.h"
#include "core/page/EventWithHitTestResults.h"
#include "core/page/FocusController.h"
......@@ -66,8 +64,6 @@
#include "core/rendering/RenderView.h"
#include "core/rendering/RenderWidget.h"
#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "platform/ContextMenu.h"
#include "platform/ContextMenuItem.h"
#include "platform/Cursor.h"
#include "platform/KeyboardCodes.h"
#include "platform/Logging.h"
......@@ -156,14 +152,12 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
: m_client(client)
, m_spellCheckClient(0)
, m_chromeClientImpl(this)
, m_contextMenuClientImpl(this)
, m_editorClientImpl(this)
, m_spellCheckerClientImpl(this)
, m_fixedLayoutSizeLock(false)
, m_zoomLevel(0)
, m_minimumZoomLevel(zoomFactorToZoomLevel(minTextSizeMultiplier))
, m_maximumZoomLevel(zoomFactorToZoomLevel(maxTextSizeMultiplier))
, m_contextMenuAllowed(false)
, m_doingDragAndDrop(false)
, m_ignoreInputEvents(false)
, m_compositorDeviceScaleFactorOverride(0)
......@@ -198,7 +192,6 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
{
Page::PageClients pageClients;
pageClients.chromeClient = &m_chromeClientImpl;
pageClients.contextMenuClient = &m_contextMenuClientImpl;
pageClients.editorClient = &m_editorClientImpl;
pageClients.spellCheckerClient = &m_spellCheckerClientImpl;
......@@ -247,55 +240,11 @@ void WebViewImpl::handleMouseDown(LocalFrame& mainFrame, const WebMouseEvent& ev
if (event.button == WebMouseEvent::ButtonLeft && m_mouseCaptureNode)
m_mouseCaptureGestureToken = mainFrame.eventHandler().takeLastMouseDownGestureToken();
// Dispatch the contextmenu event regardless of if the click was swallowed.
#if OS(MACOSX)
if (event.button == WebMouseEvent::ButtonRight
|| (event.button == WebMouseEvent::ButtonLeft
&& event.modifiers & WebMouseEvent::ControlKey))
mouseContextMenu(event);
#else
if (event.button == WebMouseEvent::ButtonRight)
mouseContextMenu(event);
#endif
}
void WebViewImpl::mouseContextMenu(const WebMouseEvent& event)
{
if (!mainFrameImpl() || !mainFrameImpl()->frameView())
return;
m_page->contextMenuController().clearContextMenu();
PlatformMouseEventBuilder pme(mainFrameImpl()->frameView(), event);
// Find the right target frame. See issue 1186900.
HitTestResult result = hitTestResultForWindowPos(pme.position());
LocalFrame* targetFrame;
if (result.innerNonSharedNode())
targetFrame = result.innerNonSharedNode()->document().frame();
else
targetFrame = m_page->focusController().focusedOrMainFrame();
LocalFrame* targetLocalFrame = targetFrame;
m_contextMenuAllowed = true;
targetLocalFrame->eventHandler().sendContextMenuEvent(pme);
m_contextMenuAllowed = false;
// Actually showing the context menu is handled by the ContextMenuClient
// implementation...
}
void WebViewImpl::handleMouseUp(LocalFrame& mainFrame, const WebMouseEvent& event)
{
PageWidgetEventHandler::handleMouseUp(mainFrame, event);
#if OS(WIN)
// Dispatch the contextmenu event regardless of if the click was swallowed.
// On Mac/Linux, we handle it on mouse down, not up.
if (event.button == WebMouseEvent::ButtonRight)
mouseContextMenu(event);
#endif
}
bool WebViewImpl::handleMouseWheel(LocalFrame& mainFrame, const WebMouseWheelEvent& event)
......@@ -437,11 +386,7 @@ bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event)
break;
m_client->cancelScheduledContentIntents();
m_page->contextMenuController().clearContextMenu();
m_contextMenuAllowed = true;
eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureEvent(platformEvent);
m_contextMenuAllowed = false;
break;
}
case WebInputEvent::GestureShowPress: {
......@@ -599,22 +544,6 @@ bool WebViewImpl::handleKeyEvent(const WebKeyboardEvent& event)
return true;
}
#if !OS(MACOSX)
const WebInputEvent::Type contextMenuTriggeringEventType =
#if OS(WIN)
WebInputEvent::KeyUp;
#else
WebInputEvent::RawKeyDown;
#endif
bool isUnmodifiedMenuKey = !(event.modifiers & WebInputEvent::InputModifiers) && event.windowsKeyCode == VKEY_APPS;
bool isShiftF10 = event.modifiers == WebInputEvent::ShiftKey && event.windowsKeyCode == VKEY_F10;
if ((isUnmodifiedMenuKey || isShiftF10) && event.type == contextMenuTriggeringEventType) {
sendContextMenuEvent(event);
return true;
}
#endif // !OS(MACOSX)
return keyEventDefault(event);
}
......@@ -862,34 +791,6 @@ bool WebViewImpl::hasTouchEventHandlersAt(const WebPoint& point)
return true;
}
#if !OS(MACOSX)
// Mac has no way to open a context menu based on a keyboard event.
bool WebViewImpl::sendContextMenuEvent(const WebKeyboardEvent& event)
{
// The contextMenuController() holds onto the last context menu that was
// popped up on the page until a new one is created. We need to clear
// this menu before propagating the event through the DOM so that we can
// detect if we create a new menu for this event, since we won't create
// a new menu if the DOM swallows the event and the defaultEventHandler does
// not run.
page()->contextMenuController().clearContextMenu();
m_contextMenuAllowed = true;
LocalFrame* focusedFrame = page()->focusController().focusedOrMainFrame();
bool handled = focusedFrame->eventHandler().sendContextMenuEventForKey();
m_contextMenuAllowed = false;
return handled;
}
#endif
void WebViewImpl::showContextMenuAtPoint(float x, float y, PassRefPtr<ContextMenuProvider> menuProvider)
{
m_contextMenuAllowed = true;
page()->contextMenuController().clearContextMenu();
page()->contextMenuController().showContextMenuAtPoint(page()->mainFrame(), x, y, menuProvider);
m_contextMenuAllowed = false;
}
bool WebViewImpl::keyEventDefault(const WebKeyboardEvent& event)
{
LocalFrame* frame = focusedCoreFrame();
......@@ -1232,8 +1133,6 @@ static String inputTypeToName(WebInputEvent::Type type)
return EventTypeNames::mouseenter;
case WebInputEvent::MouseLeave:
return EventTypeNames::mouseleave;
case WebInputEvent::ContextMenu:
return EventTypeNames::contextmenu;
case WebInputEvent::MouseWheel:
return EventTypeNames::mousewheel;
case WebInputEvent::KeyDown:
......@@ -2219,31 +2118,6 @@ void WebViewImpl::setRootLayerTransform(const WebSize& rootLayerOffset, float ro
updateRootLayerTransform();
}
void WebViewImpl::performCustomContextMenuAction(unsigned action)
{
if (!m_page)
return;
ContextMenu* menu = m_page->contextMenuController().contextMenu();
if (!menu)
return;
const ContextMenuItem* item = menu->itemWithAction(static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + action));
if (item)
m_page->contextMenuController().contextMenuItemSelected(item);
m_page->contextMenuController().clearContextMenu();
}
void WebViewImpl::showContextMenu()
{
if (!page())
return;
page()->contextMenuController().clearContextMenu();
m_contextMenuAllowed = true;
if (LocalFrame* focusedFrame = page()->focusController().focusedOrMainFrame())
focusedFrame->eventHandler().sendContextMenuEventForKey();
m_contextMenuAllowed = false;
}
void WebViewImpl::extractSmartClipData(WebRect rect, WebString& clipText, WebString& clipHtml, WebRect& clipRect)
{
}
......
......@@ -32,7 +32,6 @@
#define WebViewImpl_h
#include "core/html/ime/InputMethodContext.h"
#include "core/page/ContextMenuProvider.h"
#include "platform/geometry/IntPoint.h"
#include "platform/geometry/IntRect.h"
#include "platform/graphics/GraphicsLayer.h"
......@@ -46,7 +45,6 @@
#include "public/web/WebNavigationPolicy.h"
#include "public/web/WebView.h"
#include "web/ChromeClientImpl.h"
#include "web/ContextMenuClientImpl.h"
#include "web/EditorClientImpl.h"
#include "web/PageOverlayList.h"
#include "web/PageWidgetDelegate.h"
......@@ -177,8 +175,6 @@ public:
unsigned activeForegroundColor,
unsigned inactiveBackgroundColor,
unsigned inactiveForegroundColor) OVERRIDE;
virtual void performCustomContextMenuAction(unsigned action) OVERRIDE;
virtual void showContextMenu() OVERRIDE;
virtual void extractSmartClipData(WebRect, WebString&, WebString&, WebRect&) OVERRIDE;
virtual void addPageOverlay(WebPageOverlay*, int /* zOrder */) OVERRIDE;
virtual void removePageOverlay(WebPageOverlay*) OVERRIDE;
......@@ -246,7 +242,6 @@ public:
WebLocalFrameImpl* localFrameRootTemporary() const;
// Event related methods:
void mouseContextMenu(const WebMouseEvent&);
void mouseDoubleClick(const WebMouseEvent&);
bool detectContentOnTouch(const WebPoint&);
......@@ -256,16 +251,6 @@ public:
// WebGestureCurveTarget implementation for fling.
virtual bool scrollBy(const WebFloatSize& delta, const WebFloatSize& velocity) OVERRIDE;
// Handles context menu events orignated via the the keyboard. These
// include the VK_APPS virtual key and the Shift+F10 combine. Code is
// based on the Webkit function bool WebView::handleContextMenuEvent(WPARAM
// wParam, LPARAM lParam) in webkit\webkit\win\WebView.cpp. The only
// significant change in this function is the code to convert from a
// Keyboard event to the Right Mouse button down event.
bool sendContextMenuEvent(const WebKeyboardEvent&);
void showContextMenuAtPoint(float x, float y, PassRefPtr<ContextMenuProvider>);
// Notifies the WebView that a load has been committed. isNewNavigation
// will be true if a new session history item should be created for that
// load. isNavigationWithinPage will be true if the navigation does
......@@ -281,11 +266,6 @@ public:
void didRemoveAllPendingStylesheet(WebLocalFrameImpl*);
bool contextMenuAllowed() const
{
return m_contextMenuAllowed;
}
void updateMainFrameLayoutSize();
void updatePageDefinedViewportConstraints(const ViewportDescription&);
......@@ -417,7 +397,6 @@ private:
WebSpellCheckClient* m_spellCheckClient;
ChromeClientImpl m_chromeClientImpl;
ContextMenuClientImpl m_contextMenuClientImpl;
EditorClientImpl m_editorClientImpl;
SpellCheckerClientImpl m_spellCheckerClientImpl;
......@@ -448,8 +427,6 @@ private:
double m_maximumZoomLevel;
bool m_contextMenuAllowed;
bool m_doingDragAndDrop;
bool m_ignoreInputEvents;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册