Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(842)

Unified Diff: Source/core/editing/SelectionController.cpp

Issue 1195213002: Clean up the SelectionControl class with c++11 enum class (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/editing/SelectionController.cpp
diff --git a/Source/core/editing/SelectionController.cpp b/Source/core/editing/SelectionController.cpp
index 2f0bae1eded7d0d971e29a4e87a384c8ab1e67bf..14c6122831fdf06e2f4435b74c166d534557f663 100644
--- a/Source/core/editing/SelectionController.cpp
+++ b/Source/core/editing/SelectionController.cpp
@@ -46,31 +46,17 @@
#include "platform/RuntimeEnabledFeatures.h"
namespace blink {
-PassOwnPtrWillBeRawPtr<SelectionController> SelectionController::create(LocalFrame& frame)
-{
- return adoptPtrWillBeNoop(new SelectionController(frame));
-}
-SelectionController::SelectionController(LocalFrame& frame)
- : m_frame(&frame)
- , m_mouseDownMayStartSelect(false)
- , m_mouseDownWasSingleClickInSelection(false)
- , m_selectionInitiationState(HaveNotStartedSelection)
-{
-}
+namespace {
-DEFINE_TRACE(SelectionController)
+void setSelectionIfNeeded(FrameSelection& selection, const VisibleSelection& newSelection)
{
- visitor->trace(m_frame);
-}
-
-static void setSelectionIfNeeded(FrameSelection& selection, const VisibleSelection& newSelection)
-{
- if (selection.selection() != newSelection)
- selection.setSelection(newSelection);
+ if (selection.selection() == newSelection)
+ return;
+ selection.setSelection(newSelection);
}
-static inline bool dispatchSelectStart(Node* node)
+bool dispatchSelectStart(Node* node)
{
if (!node || !node->layoutObject())
return true;
@@ -94,164 +80,33 @@ VisibleSelection expandSelectionToRespectUserSelectAllAlgorithm(Node* targetNode
return newSelection;
}
-static VisibleSelection expandSelectionToRespectUserSelectAll(Node* targetNode, const VisibleSelection& selection)
+VisibleSelection expandSelectionToRespectUserSelectAll(Node* targetNode, const VisibleSelection& selection)
{
return expandSelectionToRespectUserSelectAllAlgorithm<VisibleSelection::InDOMTree>(targetNode, selection);
}
-static bool expandSelectionUsingGranularity(VisibleSelection& selection, TextGranularity granularity)
+bool expandSelectionUsingGranularity(VisibleSelection& selection, TextGranularity granularity)
{
return selection.expandUsingGranularity(granularity);
}
-bool SelectionController::updateSelectionForMouseDownDispatchingSelectStart(Node* targetNode, const VisibleSelection& selection, TextGranularity granularity)
-{
- if (Position::nodeIsUserSelectNone(targetNode))
- return false;
-
- if (!dispatchSelectStart(targetNode))
- return false;
-
- if (selection.isRange()) {
- m_selectionInitiationState = ExtendedSelection;
- } else {
- granularity = CharacterGranularity;
- m_selectionInitiationState = PlacedCaret;
- }
-
- m_frame->selection().setNonDirectionalSelectionIfNeeded(selection, granularity);
-
- return true;
-}
-
-void SelectionController::selectClosestWordFromHitTestResult(const HitTestResult& result, AppendTrailingWhitespace appendTrailingWhitespace)
-{
- Node* innerNode = result.innerNode();
- VisibleSelection newSelection;
-
- if (innerNode && innerNode->layoutObject()) {
- VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.localPoint()));
- if (pos.isNotNull()) {
- newSelection = VisibleSelection(pos);
- expandSelectionUsingGranularity(newSelection, WordGranularity);
- }
-
- if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSelection.isRange())
- newSelection.appendTrailingWhitespace();
-
- updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
- }
-}
-
-void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTestResult& result, AppendTrailingWhitespace appendTrailingWhitespace)
-{
- Node* innerNode = result.innerNode();
- VisibleSelection newSelection;
-
- if (innerNode && innerNode->layoutObject()) {
- VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.localPoint()));
- Position start = pos.deepEquivalent();
- Position end = pos.deepEquivalent();
- if (pos.isNotNull()) {
- DocumentMarkerVector markers = innerNode->document().markers().markersInRange(makeRange(pos, pos).get(), DocumentMarker::MisspellingMarkers());
- if (markers.size() == 1) {
- start.moveToOffset(markers[0]->startOffset());
- end.moveToOffset(markers[0]->endOffset());
- newSelection = VisibleSelection(start, end);
- }
- }
-
- if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSelection.isRange())
- newSelection.appendTrailingWhitespace();
-
- updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
- }
-}
-
-void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result)
+int textDistance(const Position& start, const Position& end)
yosin_UTC9 2015/06/22 05:31:11 textDistance() is also templatized in ToT. Could y
Miyoung Shin(c) 2015/06/24 07:43:27 Ok.
{
- if (m_mouseDownMayStartSelect) {
- selectClosestWordFromHitTestResult(result.hitTestResult(),
- (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhitespace);
- }
-}
-
-void SelectionController::selectClosestMisspellingFromMouseEvent(const MouseEventWithHitTestResults& result)
-{
- if (m_mouseDownMayStartSelect) {
- selectClosestMisspellingFromHitTestResult(result.hitTestResult(),
- (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhitespace);
- }
-}
-
-void SelectionController::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults& result)
-{
- if (!result.hitTestResult().isLiveLink())
- return selectClosestWordFromMouseEvent(result);
-
- Node* innerNode = result.innerNode();
-
- if (innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect) {
- VisibleSelection newSelection;
- Element* URLElement = result.hitTestResult().URLElement();
- VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.localPoint()));
- if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescendantOf(URLElement))
- newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement);
-
- updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
- }
+ return TextIterator::rangeLength(start, end, true);
}
-bool SelectionController::handleMousePressEventDoubleClick(const MouseEventWithHitTestResults& event)
+bool canMouseDownStartSelect(Node* node)
{
- TRACE_EVENT0("blink", "SelectionController::handleMousePressEventDoubleClick");
+ if (!node || !node->layoutObject())
+ return true;
- if (event.event().button() != LeftButton)
+ if (!node->canStartSelection())
return false;
- if (m_frame->selection().isRange()) {
- // A double-click when range is already selected
- // should not change the selection. So, do not call
- // selectClosestWordFromMouseEvent, but do set
- // m_beganSelectingText to prevent handleMouseReleaseEvent
- // from setting caret selection.
- m_selectionInitiationState = ExtendedSelection;
- } else {
- selectClosestWordFromMouseEvent(event);
- }
return true;
}
-bool SelectionController::handleMousePressEventTripleClick(const MouseEventWithHitTestResults& event)
-{
- TRACE_EVENT0("blink", "SelectionController::handleMousePressEventTripleClick");
-
- if (event.event().button() != LeftButton)
- return false;
-
- Node* innerNode = event.innerNode();
- if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect))
- return false;
-
- VisibleSelection newSelection;
- VisiblePosition pos(innerNode->layoutObject()->positionForPoint(event.localPoint()));
- if (pos.isNotNull()) {
- newSelection = VisibleSelection(pos);
- expandSelectionUsingGranularity(newSelection, ParagraphGranularity);
- }
-
- return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity);
-}
-
-static int textDistance(const Position& start, const Position& end)
-{
- return TextIterator::rangeLength(start, end, true);
-}
-
-bool SelectionController::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
-{
- return handleMousePressEventSingleClickAlgorithm<VisibleSelection::InDOMTree>(event);
-}
+} // namespace
template <typename Strategy>
bool SelectionController::handleMousePressEventSingleClickAlgorithm(const MouseEventWithHitTestResults& event)
@@ -271,7 +126,7 @@ bool SelectionController::handleMousePressEventSingleClickAlgorithm(const MouseE
// existing selection so we can allow for text dragging.
if (FrameView* view = m_frame->view()) {
LayoutPoint vPoint = view->rootFrameToContents(event.event().position());
- if (!extendSelection && m_frame->selection().contains(vPoint)) {
+ if (!extendSelection && selection().contains(vPoint)) {
m_mouseDownWasSingleClickInSelection = true;
return false;
}
@@ -282,7 +137,7 @@ bool SelectionController::handleMousePressEventSingleClickAlgorithm(const MouseE
visiblePos = VisiblePosition(firstPositionInOrBeforeNode(innerNode), DOWNSTREAM);
PositionType pos = Strategy::toPositionType(visiblePos.deepEquivalent());
- VisibleSelection newSelection = m_frame->selection().selection();
+ VisibleSelection newSelection = selection().selection();
TextGranularity granularity = CharacterGranularity;
if (extendSelection && newSelection.isCaretOrRange()) {
@@ -311,9 +166,9 @@ bool SelectionController::handleMousePressEventSingleClickAlgorithm(const MouseE
newSelection.setExtent(pos);
}
- if (m_frame->selection().granularity() != CharacterGranularity) {
- granularity = m_frame->selection().granularity();
- expandSelectionUsingGranularity(newSelection, m_frame->selection().granularity());
+ if (selection().granularity() != CharacterGranularity) {
+ granularity = selection().granularity();
+ expandSelectionUsingGranularity(newSelection, selection().granularity());
}
} else {
newSelection = expandSelectionToRespectUserSelectAll(innerNode, VisibleSelection(visiblePos));
@@ -324,57 +179,6 @@ bool SelectionController::handleMousePressEventSingleClickAlgorithm(const MouseE
return false;
}
-static inline bool canMouseDownStartSelect(Node* node)
-{
- if (!node || !node->layoutObject())
- return true;
-
- if (!node->canStartSelection())
- return false;
-
- return true;
-}
-
-void SelectionController::handleMousePressEvent(const MouseEventWithHitTestResults& event)
-{
- // If we got the event back, that must mean it wasn't prevented,
- // so it's allowed to start a drag or selection if it wasn't in a scrollbar.
- m_mouseDownMayStartSelect = canMouseDownStartSelect(event.innerNode()) && !event.scrollbar();
- m_mouseDownWasSingleClickInSelection = false;
-}
-
-void SelectionController::handleMouseDraggedEvent(const MouseEventWithHitTestResults& event, const IntPoint& mouseDownPos, const LayoutPoint& dragStartPos, Node* mousePressNode, const IntPoint& lastKnownMousePosition)
-{
- if (m_selectionInitiationState != ExtendedSelection) {
- HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
- HitTestResult result(request, mouseDownPos);
- m_frame->document()->layoutView()->hitTest(result);
-
- updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKnownMousePosition);
- }
- updateSelectionForMouseDrag(event.hitTestResult(), mousePressNode, dragStartPos, lastKnownMousePosition);
-}
-
-void SelectionController::updateSelectionForMouseDrag(Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint& lastKnownMousePosition)
-{
- FrameView* view = m_frame->view();
- if (!view)
- return;
- LayoutView* layoutObject = m_frame->contentLayoutObject();
- if (!layoutObject)
- return;
-
- HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::Move);
- HitTestResult result(request, view->rootFrameToContents(lastKnownMousePosition));
- layoutObject->hitTest(result);
- updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKnownMousePosition);
-}
-
-void SelectionController::updateSelectionForMouseDrag(const HitTestResult& hitTestResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint& lastKnownMousePosition)
-{
- updateSelectionForMouseDragAlgorithm<VisibleSelection::InDOMTree>(hitTestResult, mousePressNode, dragStartPos, lastKnownMousePosition);
-}
-
template <typename Strategy>
void SelectionController::updateSelectionForMouseDragAlgorithm(const HitTestResult& hitTestResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint& lastKnownMousePosition)
{
@@ -387,14 +191,14 @@ void SelectionController::updateSelectionForMouseDragAlgorithm(const HitTestResu
if (!target)
return;
- VisiblePosition targetPosition = m_frame->selection().selection().visiblePositionRespectingEditingBoundary(hitTestResult.localPoint(), target);
+ VisiblePosition targetPosition = selection().selection().visiblePositionRespectingEditingBoundary(hitTestResult.localPoint(), target);
// Don't modify the selection if we're not on a node.
if (targetPosition.isNull())
return;
// Restart the selection if this is the first mouse move. This work is usually
// done in handleMousePressEvent, but not if the mouse press was on an existing selection.
- VisibleSelection newSelection = m_frame->selection().selection();
+ VisibleSelection newSelection = selection().selection();
// Special case to limit selection to the containing block for SVG text.
// FIXME: Isn't there a better non-SVG-specific way to do this?
@@ -407,12 +211,12 @@ void SelectionController::updateSelectionForMouseDragAlgorithm(const HitTestResu
}
}
- if (m_selectionInitiationState == HaveNotStartedSelection && !dispatchSelectStart(target))
+ if (m_selectionState == SelectionState::HaveNotStartedSelection && !dispatchSelectStart(target))
return;
- if (m_selectionInitiationState != ExtendedSelection) {
+ if (m_selectionState != SelectionState::ExtendedSelection) {
// Always extend selection here because it's caused by a mouse drag
- m_selectionInitiationState = ExtendedSelection;
+ m_selectionState = SelectionState::ExtendedSelection;
newSelection = VisibleSelection(targetPosition);
}
@@ -442,13 +246,220 @@ void SelectionController::updateSelectionForMouseDragAlgorithm(const HitTestResu
newSelection.setExtent(targetPosition);
}
- if (m_frame->selection().granularity() != CharacterGranularity)
- expandSelectionUsingGranularity(newSelection, m_frame->selection().granularity());
+ if (selection().granularity() != CharacterGranularity)
+ expandSelectionUsingGranularity(newSelection, selection().granularity());
- m_frame->selection().setNonDirectionalSelectionIfNeeded(newSelection, m_frame->selection().granularity(),
+ selection().setNonDirectionalSelectionIfNeeded(newSelection, selection().granularity(),
FrameSelection::AdjustEndpointsAtBidiBoundary);
}
+PassOwnPtrWillBeRawPtr<SelectionController> SelectionController::create(LocalFrame& frame)
yosin_UTC9 2015/06/22 05:31:10 Let's keep original source code location for them
Miyoung Shin(c) 2015/06/24 07:43:27 when picking up template codes, it looks like thes
+{
+ return adoptPtrWillBeNoop(new SelectionController(frame));
+}
+
+SelectionController::SelectionController(LocalFrame& frame)
+ : m_frame(&frame)
+ , m_mouseDownMayStartSelect(false)
+ , m_mouseDownWasSingleClickInSelection(false)
+ , m_selectionState(SelectionState::HaveNotStartedSelection)
+{
+}
+
+DEFINE_TRACE(SelectionController)
+{
+ visitor->trace(m_frame);
+}
+
+bool SelectionController::updateSelectionForMouseDownDispatchingSelectStart(Node* targetNode, const VisibleSelection& visibleSelection, TextGranularity granularity)
+{
+ if (Position::nodeIsUserSelectNone(targetNode))
+ return false;
+
+ if (!dispatchSelectStart(targetNode))
+ return false;
+
+ if (visibleSelection.isRange()) {
+ m_selectionState = SelectionState::ExtendedSelection;
+ } else {
+ granularity = CharacterGranularity;
+ m_selectionState = SelectionState::PlacedCaret;
+ }
+
+ selection().setNonDirectionalSelectionIfNeeded(visibleSelection, granularity);
+
+ return true;
+}
+
+void SelectionController::selectClosestWordFromHitTestResult(const HitTestResult& result, AppendTrailingWhitespace appendTrailingWhitespace)
+{
+ Node* innerNode = result.innerNode();
+ VisibleSelection newSelection;
+
+ if (!innerNode || !innerNode->layoutObject())
+ return;
+
+ VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.localPoint()));
+ if (pos.isNotNull()) {
+ newSelection = VisibleSelection(pos);
+ expandSelectionUsingGranularity(newSelection, WordGranularity);
+ }
+
+ if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && newSelection.isRange())
+ newSelection.appendTrailingWhitespace();
+
+ updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
+}
+
+void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTestResult& result, AppendTrailingWhitespace appendTrailingWhitespace)
+{
+ Node* innerNode = result.innerNode();
+ VisibleSelection newSelection;
+
+ if (!innerNode || !innerNode->layoutObject())
+ return;
+
+ VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.localPoint()));
+ Position start = pos.deepEquivalent();
+ Position end = pos.deepEquivalent();
+ if (pos.isNotNull()) {
+ DocumentMarkerVector markers = innerNode->document().markers().markersInRange(makeRange(pos, pos).get(), DocumentMarker::MisspellingMarkers());
+ if (markers.size() == 1) {
+ start.moveToOffset(markers[0]->startOffset());
+ end.moveToOffset(markers[0]->endOffset());
+ newSelection = VisibleSelection(start, end);
+ }
+ }
+
+ if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && newSelection.isRange())
+ newSelection.appendTrailingWhitespace();
+
+ updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
+}
+
+void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result)
+{
+ if (!m_mouseDownMayStartSelect)
+ return;
+
+ selectClosestWordFromHitTestResult(result.hitTestResult(),
+ (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingWhitespaceEnabled()) ? AppendTrailingWhitespace::ShouldAppend : AppendTrailingWhitespace::DontAppend);
+}
+
+void SelectionController::selectClosestMisspellingFromMouseEvent(const MouseEventWithHitTestResults& result)
+{
+ if (!m_mouseDownMayStartSelect)
+ return;
+
+ selectClosestMisspellingFromHitTestResult(result.hitTestResult(),
+ (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingWhitespaceEnabled()) ? AppendTrailingWhitespace::ShouldAppend : AppendTrailingWhitespace::DontAppend);
+}
+
+void SelectionController::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults& result)
+{
+ if (!result.hitTestResult().isLiveLink())
+ return selectClosestWordFromMouseEvent(result);
+
+ Node* innerNode = result.innerNode();
+
+ if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect))
+ return;
+
+ VisibleSelection newSelection;
+ Element* URLElement = result.hitTestResult().URLElement();
+ VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.localPoint()));
+ if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescendantOf(URLElement))
+ newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement);
+
+ updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
+}
+
+bool SelectionController::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
+{
+ return handleMousePressEventSingleClickAlgorithm<VisibleSelection::InDOMTree>(event);
+}
+
+bool SelectionController::handleMousePressEventDoubleClick(const MouseEventWithHitTestResults& event)
+{
+ TRACE_EVENT0("blink", "SelectionController::handleMousePressEventDoubleClick");
+
+ if (event.event().button() != LeftButton)
+ return false;
+
+ if (selection().isRange()) {
+ // A double-click when range is already selected
+ // should not change the selection. So, do not call
+ // selectClosestWordFromMouseEvent, but do set
+ // m_beganSelectingText to prevent handleMouseReleaseEvent
+ // from setting caret selection.
+ m_selectionState = SelectionState::ExtendedSelection;
+ } else {
+ selectClosestWordFromMouseEvent(event);
+ }
+ return true;
+}
+
+bool SelectionController::handleMousePressEventTripleClick(const MouseEventWithHitTestResults& event)
+{
+ TRACE_EVENT0("blink", "SelectionController::handleMousePressEventTripleClick");
+
+ if (event.event().button() != LeftButton)
+ return false;
+
+ Node* innerNode = event.innerNode();
+ if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect))
+ return false;
+
+ VisibleSelection newSelection;
+ VisiblePosition pos(innerNode->layoutObject()->positionForPoint(event.localPoint()));
+ if (pos.isNotNull()) {
+ newSelection = VisibleSelection(pos);
+ expandSelectionUsingGranularity(newSelection, ParagraphGranularity);
+ }
+
+ return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity);
+}
+
+void SelectionController::handleMousePressEvent(const MouseEventWithHitTestResults& event)
+{
+ // If we got the event back, that must mean it wasn't prevented,
+ // so it's allowed to start a drag or selection if it wasn't in a scrollbar.
+ m_mouseDownMayStartSelect = canMouseDownStartSelect(event.innerNode()) && !event.scrollbar();
+ m_mouseDownWasSingleClickInSelection = false;
+}
+
+void SelectionController::handleMouseDraggedEvent(const MouseEventWithHitTestResults& event, const IntPoint& mouseDownPos, const LayoutPoint& dragStartPos, Node* mousePressNode, const IntPoint& lastKnownMousePosition)
+{
+ if (m_selectionState != SelectionState::ExtendedSelection) {
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
+ HitTestResult result(request, mouseDownPos);
+ m_frame->document()->layoutView()->hitTest(result);
+
+ updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKnownMousePosition);
+ }
+ updateSelectionForMouseDrag(event.hitTestResult(), mousePressNode, dragStartPos, lastKnownMousePosition);
+}
+
+void SelectionController::updateSelectionForMouseDrag(Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint& lastKnownMousePosition)
+{
+ FrameView* view = m_frame->view();
+ if (!view)
+ return;
+ LayoutView* layoutObject = m_frame->contentLayoutObject();
+ if (!layoutObject)
+ return;
+
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::Move);
+ HitTestResult result(request, view->rootFrameToContents(lastKnownMousePosition));
+ layoutObject->hitTest(result);
+ updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKnownMousePosition);
+}
+
+void SelectionController::updateSelectionForMouseDrag(const HitTestResult& hitTestResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint& lastKnownMousePosition)
+{
+ updateSelectionForMouseDragAlgorithm<VisibleSelection::InDOMTree>(hitTestResult, mousePressNode, dragStartPos, lastKnownMousePosition);
+}
+
bool SelectionController::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event, const LayoutPoint& dragStartPos)
{
bool handled = false;
@@ -457,9 +468,9 @@ bool SelectionController::handleMouseReleaseEvent(const MouseEventWithHitTestRes
// 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_selectionInitiationState != ExtendedSelection
+ if (m_mouseDownWasSingleClickInSelection && m_selectionState != SelectionState::ExtendedSelection
&& dragStartPos == event.event().position()
- && m_frame->selection().isRange()
+ && selection().isRange()
&& event.event().button() != RightButton) {
VisibleSelection newSelection;
Node* node = event.innerNode();
@@ -469,14 +480,14 @@ bool SelectionController::handleMouseReleaseEvent(const MouseEventWithHitTestRes
newSelection = VisibleSelection(pos);
}
- setSelectionIfNeeded(m_frame->selection(), newSelection);
+ setSelectionIfNeeded(selection(), newSelection);
handled = true;
}
- m_frame->selection().notifyLayoutObjectOfSelectionChange(UserTriggered);
+ selection().notifyLayoutObjectOfSelectionChange(UserTriggered);
- m_frame->selection().selectFrameElementInParentIfFullySelected();
+ selection().selectFrameElementInParentIfFullySelected();
if (event.event().button() == MiddleButton && !event.isOverLink()) {
// Ignore handled, since we want to paste to where the caret was placed anyway.
@@ -486,7 +497,6 @@ bool SelectionController::handleMouseReleaseEvent(const MouseEventWithHitTestRes
return handled;
}
-
bool SelectionController::handlePasteGlobalSelection(const PlatformMouseEvent& mouseEvent)
{
// If the event was a middle click, attempt to copy global selection in after
@@ -525,58 +535,61 @@ bool SelectionController::handleGestureLongPress(const PlatformGestureEvent& ges
#else
bool shouldLongPressSelectWord = m_frame->settings() && m_frame->settings()->touchEditingEnabled();
#endif
- if (shouldLongPressSelectWord) {
-
+ if (!shouldLongPressSelectWord)
+ return false;
- Node* innerNode = hitTestResult.innerNode();
- if (!hitTestResult.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode()
+ Node* innerNode = hitTestResult.innerNode();
+ if (hitTestResult.isLiveLink() || !innerNode || !(innerNode->isContentEditable() || innerNode->isTextNode()
#if OS(ANDROID)
- || innerNode->canStartSelection()
+ || innerNode->canStartSelection()
#endif
- )) {
- selectClosestWordFromHitTestResult(hitTestResult, DontAppendTrailingWhitespace);
- if (m_frame->selection().isRange())
- return true;
- }
- }
- return false;
+ ))
+ return false;
+
+ selectClosestWordFromHitTestResult(hitTestResult, AppendTrailingWhitespace::DontAppend);
+ if (!selection().isRange())
+ return false;
+
+ return true;
}
-void SelectionController::sendContextMenuEvent(const MouseEventWithHitTestResults& mev, const LayoutPoint& position)
+void SelectionController::prepareForContextMenu(const MouseEventWithHitTestResults& mev, const LayoutPoint& position)
{
- if (!m_frame->selection().contains(position)
- && !mev.scrollbar()
+ if (selection().contains(position)
+ || 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.innerNode() && mev.innerNode()->isTextNode()))) {
- m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
+ || !(selection().isContentEditable() || (mev.innerNode() && mev.innerNode()->isTextNode())))
+ return;
- if (mev.hitTestResult().isMisspelled())
- selectClosestMisspellingFromMouseEvent(mev);
- else if (m_frame->editor().behavior().shouldSelectOnContextualMenuClick())
- selectClosestWordOrLinkFromMouseEvent(mev);
- }
+ 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);
}
-void SelectionController::passMousePressEventToSubframe(const MouseEventWithHitTestResults& mev)
+void SelectionController::preparePassMousePressEventToSubframe(const MouseEventWithHitTestResults& mev)
{
// If we're clicking into a frame that is selected, the frame will appear
// greyed out even though we're clicking on the selection. This looks
// really strange (having the whole frame be greyed out), so we deselect the
// selection.
IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position());
- if (m_frame->selection().contains(p)) {
- VisiblePosition visiblePos(
- mev.innerNode()->layoutObject()->positionForPoint(mev.localPoint()));
- VisibleSelection newSelection(visiblePos);
- m_frame->selection().setSelection(newSelection);
- }
+ if (!selection().contains(p))
+ return;
+
+ VisiblePosition visiblePos(
+ mev.innerNode()->layoutObject()->positionForPoint(mev.localPoint()));
+ VisibleSelection newSelection(visiblePos);
+ selection().setSelection(newSelection);
}
void SelectionController::initializeSelectionState()
{
- m_selectionInitiationState = HaveNotStartedSelection;
+ m_selectionState = SelectionState::HaveNotStartedSelection;
}
void SelectionController::setMouseDownMayStartSelect(bool mayStartSelect)
@@ -594,4 +607,9 @@ bool SelectionController::mouseDownWasSingleClickInSelection() const
return m_mouseDownWasSingleClickInSelection;
}
+FrameSelection& SelectionController::selection() const
+{
+ return m_frame->selection();
+}
+
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698