Diff
Modified: trunk/LayoutTests/ChangeLog (87095 => 87096)
--- trunk/LayoutTests/ChangeLog 2011-05-23 20:47:06 UTC (rev 87095)
+++ trunk/LayoutTests/ChangeLog 2011-05-23 20:49:37 UTC (rev 87096)
@@ -1,3 +1,20 @@
+2011-05-23 Ryosuke Niwa <[email protected]>
+
+ Reviewed by Alexey Proskuryakov.
+
+ selectstart is fired for every mouse move
+ https://bugs.webkit.org/show_bug.cgi?id=19489
+
+ Added tests to ensure selectstart is dispatches exactly once when selecting text by a mouse drag,
+ a mouse click, a double click, or a triple click. Also rebaselined a test that previously logged
+ extra selectstart dispatches.
+
+ * fast/events/selectstart-by-double-triple-clicks-expected.txt: Added.
+ * fast/events/selectstart-by-double-triple-clicks.html: Added.
+ * fast/events/selectstart-by-drag.html:
+ * fast/events/selectstart-by-single-click-with-shift-expected.txt: Added.
+ * fast/events/selectstart-by-single-click-with-shift.html: Added.
+
2011-05-22 Robert Hogan <[email protected]>
Reviewed by Andreas Kling.
Added: trunk/LayoutTests/fast/events/selectstart-by-double-triple-clicks-expected.txt (0 => 87096)
--- trunk/LayoutTests/fast/events/selectstart-by-double-triple-clicks-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/selectstart-by-double-triple-clicks-expected.txt 2011-05-23 20:49:37 UTC (rev 87096)
@@ -0,0 +1,11 @@
+This test ensures selectstart is fired exactly once when selecting text by a mouse drag.
+
+Initial state: PASS
+Mouse down: PASS
+Mouse up: PASS
+Second mouse down: PASS
+Second mouse up: PASS
+Third mouse down: PASS
+Third mouse up: PASS
+Done.
+
Added: trunk/LayoutTests/fast/events/selectstart-by-double-triple-clicks.html (0 => 87096)
--- trunk/LayoutTests/fast/events/selectstart-by-double-triple-clicks.html (rev 0)
+++ trunk/LayoutTests/fast/events/selectstart-by-double-triple-clicks.html 2011-05-23 20:49:37 UTC (rev 87096)
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This test ensures selectstart is fired exactly once when selecting text by a mouse drag.
+</p><span style='font-size: 50px; padding: 10px;'>hello world</span><pre><script>
+
+var span = document.getElementsByTagName('span')[0];
+span.focus();
+
+var selectStartCount = 0;
+span.addEventListener('selectstart', function (event) { selectStartCount++; });
+
+function expect(title, expectedCount, expectedType, expectedString) {
+ document.write(title + ': ');
+ var actualSelectionType = window.getSelection().isCollapsed ? 'caret' : 'range';
+ var actualString = window.getSelection().toString();
+
+ if (selectStartCount != expectedCount)
+ document.writeln('FAIL - expected ' + expectedCount + ' events but got ' + selectStartCount + ' events');
+ else if (actualSelectionType != expectedType)
+ document.writeln('FAIL - expected selection to be ' + expectedType + ' but was ' + actualSelectionType);
+ else if (actualString && actualString != expectedString)
+ document.writeln('FAIL - expected selection to be "' + expectedString + '" but was "' + actualString + '"');
+ else
+ document.writeln('PASS');
+}
+
+if (window.layoutTestController && !window.eventSender)
+ document.write('This test requires eventSender');
+else if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+
+ var y = span.offsetTop + span.offsetHeight / 2;
+ expect('Initial state', 0, 'caret');
+ eventSender.mouseMoveTo(span.offsetLeft + 5, y);
+ eventSender.mouseDown();
+ expect('Mouse down', 1, 'caret');
+ eventSender.leapForward(200);
+ eventSender.mouseUp();
+ expect('Mouse up', 1, 'caret');
+
+ eventSender.leapForward(200);
+ eventSender.mouseDown();
+ expect('Second mouse down', 2, 'range', 'hello');
+ eventSender.leapForward(200);
+ eventSender.mouseUp();
+ expect('Second mouse up', 2, 'range', 'hello');
+
+ eventSender.leapForward(200);
+ eventSender.mouseDown();
+ expect('Third mouse down', 3, 'range', 'hello world\n');
+ eventSender.leapForward(200);
+ eventSender.mouseUp();
+ expect('Third mouse up', 3, 'range', 'hello world\n');
+
+ document.writeln('Done.');
+ span.parentNode.removeChild(span);
+}
+
+</script></pre>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/selectstart-by-drag-expected.txt (0 => 87096)
--- trunk/LayoutTests/fast/events/selectstart-by-drag-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/selectstart-by-drag-expected.txt 2011-05-23 20:49:37 UTC (rev 87096)
@@ -0,0 +1,14 @@
+This test ensures selectstart is fired exactly once when selecting text by a mouse drag.
+
+Initial state: PASS
+Mouse down: PASS
+Moving slightly to the right: PASS
+Moving slightly to the left: PASS
+Moving to the right: PASS
+Moving further to the right: PASS
+Moving back to the left: PASS
+Moving to the right again: PASS
+Mouse down on the right: PASS
+Moving to the left: PASS
+Done.
+
Added: trunk/LayoutTests/fast/events/selectstart-by-drag.html (0 => 87096)
--- trunk/LayoutTests/fast/events/selectstart-by-drag.html (rev 0)
+++ trunk/LayoutTests/fast/events/selectstart-by-drag.html 2011-05-23 20:49:37 UTC (rev 87096)
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This test ensures selectstart is fired exactly once when selecting text by a mouse drag.
+</p><span style='font-size: 50px; padding: 10px;' contenteditable>hello
+</span><pre><script>
+
+var span = document.getElementsByTagName('span')[0];
+span.focus();
+
+var selectStartCount = 0;
+span.addEventListener('selectstart', function (event) { selectStartCount++; });
+
+function expect(title, expectedCount, expectedType) {
+ document.write(title + ': ');
+ var actualSelectionType = window.getSelection().isCollapsed ? 'caret' : 'range';
+
+ if (selectStartCount != expectedCount)
+ document.writeln('FAIL - expected ' + expectedCount + ' events but got ' + selectStartCount + ' events');
+ else if (actualSelectionType != expectedType)
+ document.writeln('FAIL - expected selection to be ' + expectedType + ' but was ' + actualSelectionType);
+ else
+ document.writeln('PASS');
+}
+
+if (window.layoutTestController && !window.eventSender)
+ document.write('This test requires eventSender');
+else if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+
+ var y = span.offsetTop + span.offsetHeight / 2;
+
+ function leapForwardAndMove(x) {
+ eventSender.leapForward(200);
+ eventSender.mouseMoveTo(span.offsetLeft + x, y);
+ }
+
+ expect('Initial state', 0, 'caret');
+ eventSender.dragMode = false;
+ eventSender.mouseMoveTo(span.offsetLeft + 5, y);
+ eventSender.mouseDown();
+ expect('Mouse down', 1, 'caret');
+
+ leapForwardAndMove(5);
+ expect('Moving slightly to the right', 1, 'caret');
+
+ leapForwardAndMove(-5);
+ expect('Moving slightly to the left', 1, 'caret');
+
+ leapForwardAndMove(span.offsetWidth / 2);
+ expect('Moving to the right', 1, 'range');
+
+ leapForwardAndMove(span.offsetWidth);
+ expect('Moving further to the right', 1, 'range');
+
+ leapForwardAndMove(0);
+ expect('Moving back to the left', 1, 'caret');
+
+ leapForwardAndMove(span.offsetWidth);
+ expect('Moving to the right again', 1, 'range');
+
+ eventSender.mouseUp();
+ window.getSelection().setPosition(span, 0);
+ eventSender.leapForward(1000);
+
+ eventSender.mouseMoveTo(span.offsetLeft + span.offsetWidth - 5, y);
+ eventSender.mouseDown();
+ expect('Mouse down on the right', 2, 'caret');
+
+ leapForwardAndMove(span.offsetWidth / 2);
+ expect('Moving to the left', 2, 'range');
+
+ eventSender.mouseUp();
+
+ document.writeln('Done.');
+ span.parentNode.removeChild(span);
+}
+
+</script></pre>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/selectstart-by-single-click-with-shift-expected.txt (0 => 87096)
--- trunk/LayoutTests/fast/events/selectstart-by-single-click-with-shift-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/selectstart-by-single-click-with-shift-expected.txt 2011-05-23 20:49:37 UTC (rev 87096)
@@ -0,0 +1,10 @@
+This test ensures selectstart is fired exactly once when selecting text by a mouse drag.
+
+Initial state: PASS
+Mouse down: PASS
+Mouse up: PASS
+Moving to the right: PASS
+Second mouse down: PASS
+Second mouse up: PASS
+Done.
+
Added: trunk/LayoutTests/fast/events/selectstart-by-single-click-with-shift.html (0 => 87096)
--- trunk/LayoutTests/fast/events/selectstart-by-single-click-with-shift.html (rev 0)
+++ trunk/LayoutTests/fast/events/selectstart-by-single-click-with-shift.html 2011-05-23 20:49:37 UTC (rev 87096)
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This test ensures selectstart is fired exactly once when selecting text by a mouse drag.
+</p><span style='font-size: 50px; padding: 10px;'>hello world
+</span><pre><script>
+
+var span = document.getElementsByTagName('span')[0];
+span.focus();
+
+var selectStartCount = 0;
+span.addEventListener('selectstart', function (event) { selectStartCount++; });
+
+function expect(title, expectedCount, expectedType) {
+ document.write(title + ': ');
+ var actualSelectionType = window.getSelection().isCollapsed ? 'caret' : 'range';
+
+ if (selectStartCount != expectedCount)
+ document.writeln('FAIL - expected ' + expectedCount + ' events but got ' + selectStartCount + ' events');
+ else if (actualSelectionType != expectedType)
+ document.writeln('FAIL - expected selection to be ' + expectedType + ' but was ' + actualSelectionType);
+ else
+ document.writeln('PASS');
+}
+
+if (window.layoutTestController && !window.eventSender)
+ document.write('This test requires eventSender');
+else if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+
+ var y = span.offsetTop + span.offsetHeight / 2;
+ expect('Initial state', 0, 'caret');
+ eventSender.mouseMoveTo(span.offsetLeft + 5, y);
+ eventSender.mouseDown();
+ expect('Mouse down', 1, 'caret');
+ eventSender.leapForward(200);
+ eventSender.mouseUp();
+ expect('Mouse up', 1, 'caret');
+
+ eventSender.mouseMoveTo(span.offsetLeft + span.offsetWidth - 5, y);
+ expect('Moving to the right', 1, 'caret');
+ eventSender.mouseDown(0, ['shiftKey']);
+ expect('Second mouse down', 2, 'range');
+ eventSender.leapForward(200);
+ eventSender.mouseUp();
+ expect('Second mouse up', 2, 'range');
+
+ document.writeln('Done.');
+ span.parentNode.removeChild(span);
+}
+
+</script></pre>
+</body>
+</html>
Modified: trunk/LayoutTests/platform/mac/fast/events/objc-event-api-expected.txt (87095 => 87096)
--- trunk/LayoutTests/platform/mac/fast/events/objc-event-api-expected.txt 2011-05-23 20:47:06 UTC (rev 87095)
+++ trunk/LayoutTests/platform/mac/fast/events/objc-event-api-expected.txt 2011-05-23 20:49:37 UTC (rev 87096)
@@ -341,11 +341,6 @@
screenX: -9999
screenY: -9999
modifier keys: c:0 s:0 a:0 m:0
-event type: selectstart
- target: <html>
- eventPhase: 3
- bubbles: 1
- cancelable: 1
event type: mouseup
target: <html>
eventPhase: 3
Modified: trunk/Source/WebCore/ChangeLog (87095 => 87096)
--- trunk/Source/WebCore/ChangeLog 2011-05-23 20:47:06 UTC (rev 87095)
+++ trunk/Source/WebCore/ChangeLog 2011-05-23 20:49:37 UTC (rev 87096)
@@ -1,3 +1,54 @@
+2011-05-23 Ryosuke Niwa <[email protected]>
+
+ Reviewed by Alexey Proskuryakov.
+
+ selectstart is fired for every mouse move
+ https://bugs.webkit.org/show_bug.cgi?id=19489
+
+ Fixed the bug by dispatching selectstart event immediately before modifying selection in
+ handleMousePressEventSingleClick and updateSelectionForMouseDrag.
+
+ Also replaced a boolean EventHandler::m_beganSelectingText by an enum-valued m_selectionInitiationState
+ to retain 3 states:
+ 1. HaveNotStartedSelection - Selection has not been set by a mouse drag or a mouse click
+ 2. PlacedCaret - A caret was placed by a mouse click, double click, or triple click, and is about
+ to replace selection if a mouse drag never occurs.
+ 3. ExtendedSelection - A range selection was set by a mouse click, a double click, a triple click,
+ or a mouse drag; otherwise a caret selection was set by a mouse drag.
+
+ State 1 corresponds to m_beganSelectingText being false and state 3 corresponds to m_beganSelectingText
+ being true. State 2 is used in updateSelectionForMouseDrag to avoid dispatching selectstart twice.
+
+ States 1 and 2 are set by updateSelectionForMouseDownDispatchingSelectStart and state 3 is set by
+ updateSelectionForMouseDrag.
+
+ Test: fast/events/selectstart-by-double-triple-clicks.html
+ fast/events/selectstart-by-drag.html
+ fast/events/selectstart-by-single-click-with-shift.html
+
+ * page/EventHandler.cpp: Removed canMouseDragExtendSelect.
+ (WebCore::EventHandler::EventHandler): Initializes m_selectionInitiationState.
+ (WebCore::dispatchSelectStart): Returns true only if selectstart was successfully fired
+ and default action was not prevented.
+ (WebCore::EventHandler::updateSelectionForMouseDownDispatchingSelectStart): Updates m_selectionInitiationState
+ and modifies the selection if dispatchSelectStart returns true.
+ (WebCore::EventHandler::selectClosestWordFromMouseEvent): Calls updateSelectionForMouseDownDispatchingSelectStart.
+ (WebCore::EventHandler::selectClosestWordOrLinkFromMouseEvent): Ditto.
+ (WebCore::EventHandler::handleMousePressEventDoubleClick):
+ (WebCore::EventHandler::handleMousePressEventTripleClick): Ditto.
+ (WebCore::EventHandler::handleMousePressEventSingleClick): Ditto.
+ (WebCore::canMouseDownStartSelect): No longer dispatches startselect; also renamed from
+ EventHandler::canMouseDownStartSelect.
+ (WebCore::EventHandler::handleMousePressEvent): No longer calls canMouseDragExtendSelect.
+ (WebCore::EventHandler::handleMouseDraggedEvent):
+ (WebCore::EventHandler::updateSelectionForMouseDrag): Exit early if m_selectionInitiationState is
+ HaveNotStartedSelection and dispatchSelectStart returns false. Since setSelectionIfPossible dispatches
+ selectstart event before assigning PlacedCaret or ExtendedSelection to m_selectionInitiationState,
+ there is no need to dispatch event for those two cases.
+ (WebCore::EventHandler::handleMouseReleaseEvent):
+ * page/EventHandler.h: Removed canMouseDownStartSelect and canMouseDragExtendSelect from EventHandler
+ and added setSelectionIfPossible.
+
2011-05-23 Adam Klein <[email protected]>
Reviewed by Jian Li.
Modified: trunk/Source/WebCore/page/EventHandler.cpp (87095 => 87096)
--- trunk/Source/WebCore/page/EventHandler.cpp 2011-05-23 20:47:06 UTC (rev 87095)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2011-05-23 20:49:37 UTC (rev 87096)
@@ -182,7 +182,7 @@
, m_dragMayStartSelectionInstead(false)
#endif
, m_mouseDownWasSingleClickInSelection(false)
- , m_beganSelectingText(false)
+ , m_selectionInitiationState(HaveNotStartedSelection)
, m_panScrollInProgress(false)
, m_panScrollButtonPressed(false)
, m_springLoadedPanScrollInProgress(false)
@@ -281,6 +281,31 @@
selection->setSelection(newSelection, granularity, MakeNonDirectionalSelection);
}
+static inline bool dispatchSelectStart(Node* node)
+{
+ if (!node || !node->renderer())
+ return true;
+
+ return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true));
+}
+
+bool EventHandler::updateSelectionForMouseDownDispatchingSelectStart(Node* targetNode, const VisibleSelection& newSelection, TextGranularity granularity)
+{
+ if (!dispatchSelectStart(targetNode))
+ return false;
+
+ if (newSelection.isRange())
+ m_selectionInitiationState = ExtendedSelection;
+ else {
+ granularity = CharacterGranularity;
+ m_selectionInitiationState = PlacedCaret;
+ }
+
+ setNonDirectionalSelectionIfNeeded(m_frame->selection(), newSelection, granularity);
+
+ return true;
+}
+
void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result)
{
Node* innerNode = targetNode(result);
@@ -288,20 +313,15 @@
if (innerNode && innerNode->renderer() && m_mouseDownMayStartSelect) {
VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint()));
- TextGranularity granularity = CharacterGranularity;
if (pos.isNotNull()) {
newSelection = VisibleSelection(pos);
newSelection.expandUsingGranularity(WordGranularity);
}
-
- if (newSelection.isRange()) {
- granularity = WordGranularity;
- m_beganSelectingText = true;
- if (result.event().clickCount() == 2 && m_frame->editor()->isSelectTrailingWhitespaceEnabled())
- newSelection.appendTrailingWhitespace();
- }
- setNonDirectionalSelectionIfNeeded(m_frame->selection(), newSelection, granularity);
+ if (newSelection.isRange() && result.event().clickCount() == 2 && m_frame->editor()->isSelectTrailingWhitespaceEnabled())
+ newSelection.appendTrailingWhitespace();
+
+ updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, WordGranularity);
}
}
@@ -318,14 +338,8 @@
VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint()));
if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescendantOf(URLElement))
newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement);
-
- TextGranularity granularity = CharacterGranularity;
- if (newSelection.isRange()) {
- granularity = WordGranularity;
- m_beganSelectingText = true;
- }
- setNonDirectionalSelectionIfNeeded(m_frame->selection(), newSelection, granularity);
+ updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, WordGranularity);
}
}
@@ -340,7 +354,7 @@
// selectClosestWordFromMouseEvent, but do set
// m_beganSelectingText to prevent handleMouseReleaseEvent
// from setting caret selection.
- m_beganSelectingText = true;
+ m_selectionInitiationState = ExtendedSelection;
else
selectClosestWordFromMouseEvent(event);
@@ -362,16 +376,8 @@
newSelection = VisibleSelection(pos);
newSelection.expandUsingGranularity(ParagraphGranularity);
}
-
- TextGranularity granularity = CharacterGranularity;
- if (newSelection.isRange()) {
- granularity = ParagraphGranularity;
- m_beganSelectingText = true;
- }
- setNonDirectionalSelectionIfNeeded(m_frame->selection(), newSelection, granularity);
-
- return true;
+ return updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, ParagraphGranularity);
}
static int textDistance(const Position& start, const Position& end)
@@ -422,21 +428,27 @@
newSelection = VisibleSelection(end, pos);
else
newSelection = VisibleSelection(start, pos);
- } else {
+ } else
newSelection.setExtent(pos);
- }
if (m_frame->selection()->granularity() != CharacterGranularity) {
granularity = m_frame->selection()->granularity();
newSelection.expandUsingGranularity(m_frame->selection()->granularity());
}
-
- m_beganSelectingText = true;
} else
newSelection = VisibleSelection(visiblePos);
+
+ return updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, granularity);
+}
- setNonDirectionalSelectionIfNeeded(m_frame->selection(), newSelection, granularity);
+static inline bool canMouseDownStartSelect(Node* node)
+{
+ if (!node || !node->renderer())
+ return true;
+ if (!node->canStartSelection())
+ return false;
+
return true;
}
@@ -497,7 +509,7 @@
bool swallowEvent = false;
m_mousePressed = true;
- m_beganSelectingText = false;
+ m_selectionInitiationState = HaveNotStartedSelection;
if (event.event().clickCount() == 2)
swallowEvent = handleMousePressEventDoubleClick(event);
@@ -573,7 +585,7 @@
m_mouseDownMayStartAutoscroll = false;
}
- if (!m_beganSelectingText) {
+ if (m_selectionInitiationState != ExtendedSelection) {
HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
HitTestResult result(m_mouseDownPos);
m_frame->document()->renderView()->layer()->hitTest(request, result);
@@ -661,9 +673,6 @@
if (!target)
return;
- if (!canMouseDragExtendSelect(target))
- return;
-
VisiblePosition targetPosition = selectionExtentRespectingEditingBoundary(m_frame->selection()->selection(), hitTestResult.localPoint(), target);
// Don't modify the selection if we're not on a node.
@@ -684,8 +693,12 @@
return;
#endif
- if (!m_beganSelectingText) {
- m_beganSelectingText = true;
+ if (m_selectionInitiationState == HaveNotStartedSelection && !dispatchSelectStart(target))
+ return;
+
+ if (m_selectionInitiationState != ExtendedSelection) {
+ // Always extend selection here because it's caused by a mouse drag
+ m_selectionInitiationState = ExtendedSelection;
newSelection = VisibleSelection(targetPosition);
}
@@ -741,7 +754,7 @@
// press and it's not a context menu click. We do this so when clicking
// on the selection, the selection goes away. However, if we are
// editing, place the caret.
- if (m_mouseDownWasSingleClickInSelection && !m_beganSelectingText
+ if (m_mouseDownWasSingleClickInSelection && m_selectionInitiationState != ExtendedSelection
#if ENABLE(DRAG_SUPPORT)
&& m_dragStartPos == event.event().pos()
#endif
@@ -2334,29 +2347,6 @@
mouseMoved(fakeMouseMoveEvent);
}
-// Whether or not a mouse down can begin the creation of a selection. Fires the selectStart event.
-bool EventHandler::canMouseDownStartSelect(Node* node)
-{
- if (!node || !node->renderer())
- return true;
-
- // Some controls and images can't start a select on a mouse down.
- if (!node->canStartSelection())
- return false;
-
- return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true));
-}
-
-#if ENABLE(DRAG_SUPPORT)
-bool EventHandler::canMouseDragExtendSelect(Node* node)
-{
- if (!node || !node->renderer())
- return true;
-
- return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true));
-}
-#endif // ENABLE(DRAG_SUPPORT)
-
void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet)
{
m_frameSetBeingResized = frameSet;
Modified: trunk/Source/WebCore/page/EventHandler.h (87095 => 87096)
--- trunk/Source/WebCore/page/EventHandler.h 2011-05-23 20:47:06 UTC (rev 87095)
+++ trunk/Source/WebCore/page/EventHandler.h 2011-05-23 20:49:37 UTC (rev 87096)
@@ -33,6 +33,7 @@
#include "PlatformMouseEvent.h"
#include "ScrollTypes.h"
#include "TextEventInputType.h"
+#include "TextGranularity.h"
#include "Timer.h"
#include <wtf/Forward.h>
#include <wtf/OwnPtr.h>
@@ -71,6 +72,7 @@
class Scrollbar;
class TextEvent;
class TouchEvent;
+class VisibleSelection;
class WheelEvent;
class Widget;
@@ -230,6 +232,7 @@
#endif // ENABLE(DRAG_SUPPORT)
bool eventActivatedView(const PlatformMouseEvent&) const;
+ bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
@@ -256,11 +259,6 @@
void hoverTimerFired(Timer<EventHandler>*);
- static bool canMouseDownStartSelect(Node*);
-#if ENABLE(DRAG_SUPPORT)
- static bool canMouseDragExtendSelect(Node*);
-#endif
-
void handleAutoscroll(RenderObject*);
void startAutoscrollTimer();
void setAutoscrollRenderer(RenderObject*);
@@ -367,7 +365,8 @@
bool m_dragMayStartSelectionInstead;
#endif
bool m_mouseDownWasSingleClickInSelection;
- bool m_beganSelectingText;
+ enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
+ SelectionInitiationState m_selectionInitiationState;
#if ENABLE(DRAG_SUPPORT)
IntPoint m_dragStartPos;