summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/page/EventHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/page/EventHandler.cpp')
-rw-r--r--Source/WebCore/page/EventHandler.cpp105
1 files changed, 82 insertions, 23 deletions
diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
index ef2ffb3..de59083 100644
--- a/Source/WebCore/page/EventHandler.cpp
+++ b/Source/WebCore/page/EventHandler.cpp
@@ -98,6 +98,10 @@
#include "TouchEvent.h"
#endif
+#if ENABLE(GESTURE_RECOGNIZER)
+#include "PlatformGestureRecognizer.h"
+#endif
+
#if defined(ANDROID_PLUGINS)
#include "WebViewCore.h"
#endif
@@ -209,6 +213,9 @@ EventHandler::EventHandler(Frame* frame)
#if ENABLE(TOUCH_EVENTS)
, m_touchPressed(false)
#endif
+#if ENABLE(GESTURE_RECOGNIZER)
+ , m_gestureRecognizer(PlatformGestureRecognizer::create())
+#endif
{
}
@@ -260,6 +267,20 @@ void EventHandler::clear()
#endif
}
+static void setSelectionIfNeeded(SelectionController* selection, const VisibleSelection& newSelection)
+{
+ ASSERT(selection);
+ if (selection->selection() != newSelection && selection->shouldChangeSelection(newSelection))
+ selection->setSelection(newSelection);
+}
+
+static void setNonDirectionalSelectionIfNeeded(SelectionController* selection, const VisibleSelection& newSelection, TextGranularity granularity)
+{
+ ASSERT(selection);
+ if (selection->selection() != newSelection && selection->shouldChangeSelection(newSelection))
+ selection->setSelection(newSelection, granularity, MakeNonDirectionalSelection);
+}
+
void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result)
{
Node* innerNode = result.targetNode();
@@ -279,9 +300,8 @@ void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestRe
if (result.event().clickCount() == 2 && m_frame->editor()->isSelectTrailingWhitespaceEnabled())
newSelection.appendTrailingWhitespace();
}
-
- if (m_frame->selection()->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection, granularity, MakeNonDirectionalSelection);
+
+ setNonDirectionalSelectionIfNeeded(m_frame->selection(), newSelection, granularity);
}
}
@@ -305,8 +325,7 @@ void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHit
m_beganSelectingText = true;
}
- if (m_frame->selection()->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection, granularity, MakeNonDirectionalSelection);
+ setNonDirectionalSelectionIfNeeded(m_frame->selection(), newSelection, granularity);
}
}
@@ -349,9 +368,8 @@ bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestR
granularity = ParagraphGranularity;
m_beganSelectingText = true;
}
-
- if (m_frame->selection()->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection, granularity, MakeNonDirectionalSelection);
+
+ setNonDirectionalSelectionIfNeeded(m_frame->selection(), newSelection, granularity);
return true;
}
@@ -416,9 +434,8 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
m_beganSelectingText = true;
} else
newSelection = VisibleSelection(visiblePos);
-
- if (m_frame->selection()->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection, granularity, MakeNonDirectionalSelection);
+
+ setNonDirectionalSelectionIfNeeded(m_frame->selection(), newSelection, granularity);
return true;
}
@@ -555,7 +572,13 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
m_mouseDownMayStartAutoscroll = false;
}
-
+
+ if (!m_beganSelectingText) {
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
+ HitTestResult result(m_mouseDownPos);
+ m_frame->document()->renderView()->layer()->hitTest(request, result);
+ updateSelectionForMouseDrag(result.innerNode(), result.localPoint());
+ }
updateSelectionForMouseDrag(targetNode, event.localPoint());
return true;
}
@@ -653,10 +676,7 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint&
if (m_frame->selection()->granularity() != CharacterGranularity)
newSelection.expandUsingGranularity(m_frame->selection()->granularity());
- if (m_frame->selection()->shouldChangeSelection(newSelection)) {
- m_frame->selection()->setIsDirectional(false);
- m_frame->selection()->setSelection(newSelection, m_frame->selection()->granularity(), MakeNonDirectionalSelection);
- }
+ setNonDirectionalSelectionIfNeeded(m_frame->selection(), newSelection, m_frame->selection()->granularity());
}
#endif // ENABLE(DRAG_SUPPORT)
@@ -713,12 +733,12 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e
VisibleSelection newSelection;
Node* node = event.targetNode();
bool caretBrowsing = m_frame->settings()->caretBrowsingEnabled();
- if (node && (caretBrowsing || node->isContentEditable()) && node->renderer()) {
+ if (node && (caretBrowsing || node->rendererIsEditable()) && node->renderer()) {
VisiblePosition pos = node->renderer()->positionForPoint(event.localPoint());
newSelection = VisibleSelection(pos);
}
- if (m_frame->selection()->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection);
+
+ setSelectionIfNeeded(m_frame->selection(), newSelection);
handled = true;
}
@@ -1165,7 +1185,7 @@ Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Scr
switch (style ? style->cursor() : CURSOR_AUTO) {
case CURSOR_AUTO: {
- bool editable = (node && node->isContentEditable());
+ bool editable = (node && node->rendererIsEditable());
bool editableLinkEnabled = false;
// If the link is editable, then we need to check the settings to see whether or not the link should be followed
@@ -1456,6 +1476,22 @@ bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEv
return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
}
+static RenderLayer* layerForNode(Node* node)
+{
+ if (!node)
+ return 0;
+
+ RenderObject* renderer = node->renderer();
+ if (!renderer)
+ return 0;
+
+ RenderLayer* layer = renderer->enclosingLayer();
+ if (!layer)
+ return 0;
+
+ return layer;
+}
+
bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
{
HitTestResult hoveredNode = HitTestResult(IntPoint());
@@ -1465,6 +1501,11 @@ bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
if (!page)
return result;
+ if (RenderLayer* layer = layerForNode(hoveredNode.innerNode())) {
+ if (page->containsScrollableArea(layer))
+ layer->scrollAnimator()->mouseMovedInContentArea();
+ }
+
if (FrameView* frameView = m_frame->view())
frameView->scrollAnimator()->mouseMovedInContentArea();
@@ -1889,21 +1930,32 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
// Fire mouseout/mouseover if the mouse has shifted to a different node.
if (fireMouseOverOut) {
- // FIXME: This code will only correctly handle transitions between frames with scrollbars,
- // not transitions between overflow regions, or transitions between two frames
- // that don't have scrollbars contained within a frame that does.
+ RenderLayer* layerForLastNode = layerForNode(m_lastNodeUnderMouse.get());
+ RenderLayer* layerForNodeUnderMouse = layerForNode(m_nodeUnderMouse.get());
+ Page* page = m_frame->page();
+
if (m_lastNodeUnderMouse && (!m_nodeUnderMouse || m_nodeUnderMouse->document() != m_frame->document())) {
+ // The mouse has moved between frames.
if (Frame* frame = m_lastNodeUnderMouse->document()->frame()) {
if (FrameView* frameView = frame->view())
frameView->scrollAnimator()->mouseExitedContentArea();
}
+ } else if (page && (layerForLastNode && (!layerForNodeUnderMouse || layerForNodeUnderMouse != layerForLastNode))) {
+ // The mouse has moved between layers.
+ if (page->containsScrollableArea(layerForLastNode))
+ layerForLastNode->scrollAnimator()->mouseExitedContentArea();
}
if (m_nodeUnderMouse && (!m_lastNodeUnderMouse || m_lastNodeUnderMouse->document() != m_frame->document())) {
+ // The mouse has moved between frames.
if (Frame* frame = m_nodeUnderMouse->document()->frame()) {
if (FrameView* frameView = frame->view())
frameView->scrollAnimator()->mouseEnteredContentArea();
}
+ } else if (page && (layerForNodeUnderMouse && (!layerForLastNode || layerForNodeUnderMouse != layerForLastNode))) {
+ // The mouse has moved between layers.
+ if (page->containsScrollableArea(layerForNodeUnderMouse))
+ layerForNodeUnderMouse->scrollAnimator()->mouseEnteredContentArea();
}
if (m_lastNodeUnderMouse && m_lastNodeUnderMouse->document() != m_frame->document()) {
@@ -2360,6 +2412,8 @@ bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
{
+ RefPtr<FrameView> protector(m_frame->view());
+
#if ENABLE(PAN_SCROLLING)
if (Page* page = m_frame->page()) {
if (page->mainFrame()->eventHandler()->panScrollInProgress() || m_autoscrollInProgress) {
@@ -3123,6 +3177,11 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
}
}
+#if ENABLE(GESTURE_RECOGNIZER)
+ if (m_gestureRecognizer)
+ m_gestureRecognizer->processTouchEventForGesture(event, this, defaultPrevented);
+#endif
+
return defaultPrevented;
}
#endif