| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. |
| 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
| 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) | 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) |
| 5 * Copyright (C) 2015 Google Inc. All rights reserved. | 5 * Copyright (C) 2015 Google Inc. All rights reserved. |
| 6 * | 6 * |
| 7 * Redistribution and use in source and binary forms, with or without | 7 * Redistribution and use in source and binary forms, with or without |
| 8 * modification, are permitted provided that the following conditions | 8 * modification, are permitted provided that the following conditions |
| 9 * are met: | 9 * are met: |
| 10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 { | 59 { |
| 60 } | 60 } |
| 61 | 61 |
| 62 DEFINE_TRACE(SelectionController) | 62 DEFINE_TRACE(SelectionController) |
| 63 { | 63 { |
| 64 visitor->trace(m_frame); | 64 visitor->trace(m_frame); |
| 65 } | 65 } |
| 66 | 66 |
| 67 namespace { | 67 namespace { |
| 68 | 68 |
| 69 void setSelectionIfNeeded(FrameSelection& selection, const VisibleSelection& new
Selection) | 69 template <typename Strategy> |
| 70 void setSelectionIfNeeded(FrameSelection& selection, const VisibleSelectionTempl
ate<Strategy>& newSelection) |
| 70 { | 71 { |
| 71 if (equalSelectionsInDOMTree(selection.selection(), newSelection)) | 72 if (selection.visibleSelection<Strategy>() == newSelection) |
| 72 return; | 73 return; |
| 73 selection.setSelection(newSelection); | 74 selection.setSelection(newSelection); |
| 74 } | 75 } |
| 75 | 76 |
| 76 bool dispatchSelectStart(Node* node) | 77 bool dispatchSelectStart(Node* node) |
| 77 { | 78 { |
| 78 if (!node || !node->layoutObject()) | 79 if (!node || !node->layoutObject()) |
| 79 return true; | 80 return true; |
| 80 | 81 |
| 81 return node->dispatchEvent(Event::createCancelableBubble(EventTypeNames::sel
ectstart)); | 82 return node->dispatchEvent(Event::createCancelableBubble(EventTypeNames::sel
ectstart)); |
| 82 } | 83 } |
| 83 | 84 |
| 84 template <typename Strategy> | 85 template <typename Strategy> |
| 85 VisibleSelectionTemplate<Strategy> expandSelectionToRespectUserSelectAll(Node* t
argetNode, const VisibleSelectionTemplate<Strategy>& selection) | 86 VisibleSelectionTemplate<Strategy> expandSelectionToRespectUserSelectAll(Node* t
argetNode, const VisibleSelectionTemplate<Strategy>& selection) |
| 86 { | 87 { |
| 87 Node* rootUserSelectAll = Strategy::rootUserSelectAllForNode(targetNode); | 88 Node* rootUserSelectAll = Strategy::rootUserSelectAllForNode(targetNode); |
| 88 if (!rootUserSelectAll) | 89 if (!rootUserSelectAll) |
| 89 return selection; | 90 return selection; |
| 90 | 91 |
| 91 VisibleSelectionTemplate<Strategy> newSelection(selection); | 92 VisibleSelectionTemplate<Strategy> newSelection(selection); |
| 92 newSelection.setBase(mostBackwardCaretPosition(PositionAlgorithm<Strategy>::
beforeNode(rootUserSelectAll), CanCrossEditingBoundary)); | 93 newSelection.setBase(mostBackwardCaretPosition(PositionAlgorithm<Strategy>::
beforeNode(rootUserSelectAll), CanCrossEditingBoundary)); |
| 93 newSelection.setExtent(mostForwardCaretPosition(PositionAlgorithm<Strategy>:
:afterNode(rootUserSelectAll), CanCrossEditingBoundary)); | 94 newSelection.setExtent(mostForwardCaretPosition(PositionAlgorithm<Strategy>:
:afterNode(rootUserSelectAll), CanCrossEditingBoundary)); |
| 94 | 95 |
| 95 return newSelection; | 96 return newSelection; |
| 96 } | 97 } |
| 97 | 98 |
| 98 // TODO(yosin) |expandSelectionToRespectUserSelectAll()| with |VisibleSelection| | |
| 99 // should be removed once we have full version of |VisibleSelectionTemplate|. | |
| 100 static VisibleSelectionTemplate<EditingStrategy> expandSelectionToRespectUserSel
ectAll(Node* targetNode, const VisibleSelection& selection) | |
| 101 { | |
| 102 return expandSelectionToRespectUserSelectAll(targetNode, VisibleSelectionTem
plate<EditingStrategy>(selection)); | |
| 103 } | |
| 104 | |
| 105 bool expandSelectionUsingGranularity(VisibleSelection& selection, TextGranularit
y granularity) | |
| 106 { | |
| 107 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) | |
| 108 return selection.expandUsingGranularityInComposedTree(granularity); | |
| 109 return selection.expandUsingGranularity(granularity); | |
| 110 } | |
| 111 | |
| 112 template <typename Strategy> | 99 template <typename Strategy> |
| 113 static int textDistance(const PositionAlgorithm<Strategy>& start, const Position
Algorithm<Strategy>& end) | 100 static int textDistance(const PositionAlgorithm<Strategy>& start, const Position
Algorithm<Strategy>& end) |
| 114 { | 101 { |
| 115 return TextIteratorAlgorithm<Strategy>::rangeLength(start, end, true); | 102 return TextIteratorAlgorithm<Strategy>::rangeLength(start, end, true); |
| 116 } | 103 } |
| 117 | 104 |
| 118 bool canMouseDownStartSelect(Node* node) | 105 bool canMouseDownStartSelect(Node* node) |
| 119 { | 106 { |
| 120 if (!node || !node->layoutObject()) | 107 if (!node || !node->layoutObject()) |
| 121 return true; | 108 return true; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 145 // existing selection so we can allow for text dragging. | 132 // existing selection so we can allow for text dragging. |
| 146 if (FrameView* view = m_frame->view()) { | 133 if (FrameView* view = m_frame->view()) { |
| 147 LayoutPoint vPoint = view->rootFrameToContents(event.event().position())
; | 134 LayoutPoint vPoint = view->rootFrameToContents(event.event().position())
; |
| 148 if (!extendSelection && selection().contains(vPoint)) { | 135 if (!extendSelection && selection().contains(vPoint)) { |
| 149 m_mouseDownWasSingleClickInSelection = true; | 136 m_mouseDownWasSingleClickInSelection = true; |
| 150 return false; | 137 return false; |
| 151 } | 138 } |
| 152 } | 139 } |
| 153 | 140 |
| 154 const PositionWithAffinity eventPos = innerNode->layoutObject()->positionFor
Point(event.localPoint()); | 141 const PositionWithAffinity eventPos = innerNode->layoutObject()->positionFor
Point(event.localPoint()); |
| 155 VisiblePositionTemplate<Strategy> visiblePos = createVisiblePosition(fromPos
itionInDOMTree<Strategy>(eventPos.position()), eventPos.affinity()); | 142 VisiblePositionTemplate<Strategy> visiblePos = createVisiblePosition(fromPos
itionInDOMTree<Strategy>(eventPos)); |
| 156 if (visiblePos.isNull()) | 143 if (visiblePos.isNull()) |
| 157 visiblePos = createVisiblePosition(PositionAlgorithm<Strategy>::firstPos
itionInOrBeforeNode(innerNode)); | 144 visiblePos = createVisiblePosition(PositionAlgorithm<Strategy>::firstPos
itionInOrBeforeNode(innerNode)); |
| 158 PositionAlgorithm<Strategy> pos = visiblePos.deepEquivalent(); | 145 PositionAlgorithm<Strategy> pos = visiblePos.deepEquivalent(); |
| 159 | 146 |
| 160 VisibleSelectionTemplate<Strategy> newSelection(selection().selection()); | 147 VisibleSelectionTemplate<Strategy> newSelection = selection().visibleSelecti
on<Strategy>(); |
| 161 TextGranularity granularity = CharacterGranularity; | 148 TextGranularity granularity = CharacterGranularity; |
| 162 | 149 |
| 163 if (extendSelection && newSelection.isCaretOrRange()) { | 150 if (extendSelection && newSelection.isCaretOrRange()) { |
| 164 const VisibleSelectionTemplate<Strategy> selectionInUserSelectAll(expand
SelectionToRespectUserSelectAll(innerNode, VisibleSelectionTemplate<Strategy>(cr
eateVisiblePosition(pos)))); | 151 const VisibleSelectionTemplate<Strategy> selectionInUserSelectAll(expand
SelectionToRespectUserSelectAll(innerNode, VisibleSelectionTemplate<Strategy>(cr
eateVisiblePosition(pos)))); |
| 165 if (selectionInUserSelectAll.isRange()) { | 152 if (selectionInUserSelectAll.isRange()) { |
| 166 if (selectionInUserSelectAll.start().compareTo(newSelection.start())
< 0) | 153 if (selectionInUserSelectAll.start().compareTo(newSelection.start())
< 0) |
| 167 pos = selectionInUserSelectAll.start(); | 154 pos = selectionInUserSelectAll.start(); |
| 168 else if (newSelection.end().compareTo(selectionInUserSelectAll.end()
) < 0) | 155 else if (newSelection.end().compareTo(selectionInUserSelectAll.end()
) < 0) |
| 169 pos = selectionInUserSelectAll.end(); | 156 pos = selectionInUserSelectAll.end(); |
| 170 } | 157 } |
| 171 | 158 |
| 172 if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()
) { | 159 if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()
) { |
| 173 if (pos.isNotNull()) { | 160 if (pos.isNotNull()) { |
| 174 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click d
eselects when selection | 161 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click |
| 175 // was created right-to-left | 162 // deselects when selection was created right-to-left |
| 176 const PositionAlgorithm<Strategy> start = newSelection.start(); | 163 const PositionAlgorithm<Strategy> start = newSelection.start(); |
| 177 const PositionAlgorithm<Strategy> end = newSelection.end(); | 164 const PositionAlgorithm<Strategy> end = newSelection.end(); |
| 178 int distanceToStart = textDistance(start, pos); | 165 int distanceToStart = textDistance(start, pos); |
| 179 int distanceToEnd = textDistance(pos, end); | 166 int distanceToEnd = textDistance(pos, end); |
| 180 if (distanceToStart <= distanceToEnd) | 167 if (distanceToStart <= distanceToEnd) |
| 181 newSelection = VisibleSelectionTemplate<Strategy>(end, pos); | 168 newSelection = VisibleSelectionTemplate<Strategy>(end, pos); |
| 182 else | 169 else |
| 183 newSelection = VisibleSelectionTemplate<Strategy>(start, pos
); | 170 newSelection = VisibleSelectionTemplate<Strategy>(start, pos
); |
| 184 } | 171 } |
| 185 } else { | 172 } else { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 202 template <typename Strategy> | 189 template <typename Strategy> |
| 203 void SelectionController::updateSelectionForMouseDragAlgorithm(const HitTestResu
lt& hitTestResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const
IntPoint& lastKnownMousePosition) | 190 void SelectionController::updateSelectionForMouseDragAlgorithm(const HitTestResu
lt& hitTestResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const
IntPoint& lastKnownMousePosition) |
| 204 { | 191 { |
| 205 if (!m_mouseDownMayStartSelect) | 192 if (!m_mouseDownMayStartSelect) |
| 206 return; | 193 return; |
| 207 | 194 |
| 208 Node* target = hitTestResult.innerNode(); | 195 Node* target = hitTestResult.innerNode(); |
| 209 if (!target) | 196 if (!target) |
| 210 return; | 197 return; |
| 211 | 198 |
| 212 const PositionWithAffinity rawTargetPosition = selection().selection().posit
ionRespectingEditingBoundary(hitTestResult.localPoint(), target); | 199 PositionWithAffinity rawTargetPosition = selection().selection().positionRes
pectingEditingBoundary(hitTestResult.localPoint(), target); |
| 213 const VisiblePositionTemplate<Strategy> targetPosition = createVisiblePositi
on(fromPositionInDOMTree<Strategy>(rawTargetPosition.position()), rawTargetPosit
ion.affinity()); | 200 VisiblePositionTemplate<Strategy> targetPosition = createVisiblePosition(fro
mPositionInDOMTree<Strategy>(rawTargetPosition)); |
| 214 // Don't modify the selection if we're not on a node. | 201 // Don't modify the selection if we're not on a node. |
| 215 if (targetPosition.isNull()) | 202 if (targetPosition.isNull()) |
| 216 return; | 203 return; |
| 217 | 204 |
| 218 // Restart the selection if this is the first mouse move. This work is usual
ly | 205 // Restart the selection if this is the first mouse move. This work is usual
ly |
| 219 // done in handleMousePressEvent, but not if the mouse press was on an exist
ing selection. | 206 // done in handleMousePressEvent, but not if the mouse press was on an exist
ing selection. |
| 220 VisibleSelectionTemplate<Strategy> newSelection(selection().selection()); | 207 VisibleSelectionTemplate<Strategy> newSelection = selection().visibleSelecti
on<Strategy>(); |
| 221 | 208 |
| 222 // Special case to limit selection to the containing block for SVG text. | 209 // Special case to limit selection to the containing block for SVG text. |
| 223 // FIXME: Isn't there a better non-SVG-specific way to do this? | 210 // FIXME: Isn't there a better non-SVG-specific way to do this? |
| 224 if (Node* selectionBaseNode = newSelection.base().anchorNode()) { | 211 if (Node* selectionBaseNode = newSelection.base().anchorNode()) { |
| 225 if (LayoutObject* selectionBaseLayoutObject = selectionBaseNode->layoutO
bject()) { | 212 if (LayoutObject* selectionBaseLayoutObject = selectionBaseNode->layoutO
bject()) { |
| 226 if (selectionBaseLayoutObject->isSVGText()) { | 213 if (selectionBaseLayoutObject->isSVGText()) { |
| 227 if (target->layoutObject()->containingBlock() != selectionBaseLa
youtObject->containingBlock()) | 214 if (target->layoutObject()->containingBlock() != selectionBaseLa
youtObject->containingBlock()) |
| 228 return; | 215 return; |
| 229 } | 216 } |
| 230 } | 217 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 } else { | 281 } else { |
| 295 granularity = CharacterGranularity; | 282 granularity = CharacterGranularity; |
| 296 m_selectionState = SelectionState::PlacedCaret; | 283 m_selectionState = SelectionState::PlacedCaret; |
| 297 } | 284 } |
| 298 | 285 |
| 299 this->selection().setNonDirectionalSelectionIfNeeded(selection, granularity)
; | 286 this->selection().setNonDirectionalSelectionIfNeeded(selection, granularity)
; |
| 300 | 287 |
| 301 return true; | 288 return true; |
| 302 } | 289 } |
| 303 | 290 |
| 291 template <typename Strategy> |
| 304 void SelectionController::selectClosestWordFromHitTestResult(const HitTestResult
& result, AppendTrailingWhitespace appendTrailingWhitespace) | 292 void SelectionController::selectClosestWordFromHitTestResult(const HitTestResult
& result, AppendTrailingWhitespace appendTrailingWhitespace) |
| 305 { | 293 { |
| 306 Node* innerNode = result.innerNode(); | 294 Node* innerNode = result.innerNode(); |
| 307 VisibleSelection newSelection; | 295 VisibleSelectionTemplate<Strategy> newSelection; |
| 308 | 296 |
| 309 if (!innerNode || !innerNode->layoutObject()) | 297 if (!innerNode || !innerNode->layoutObject()) |
| 310 return; | 298 return; |
| 311 | 299 |
| 312 VisiblePosition pos = createVisiblePosition(innerNode->layoutObject()->posit
ionForPoint(result.localPoint())); | 300 const VisiblePositionTemplate<Strategy> pos = createVisiblePosition(fromPosi
tionInDOMTree<Strategy>(innerNode->layoutObject()->positionForPoint(result.local
Point()))); |
| 313 if (pos.isNotNull()) { | 301 if (pos.isNotNull()) { |
| 314 newSelection = VisibleSelection(pos); | 302 newSelection = VisibleSelectionTemplate<Strategy>(pos); |
| 315 expandSelectionUsingGranularity(newSelection, WordGranularity); | 303 newSelection.expandUsingGranularity(WordGranularity); |
| 316 } | 304 } |
| 317 | 305 |
| 318 #if OS(ANDROID) | 306 #if OS(ANDROID) |
| 319 // If node is not editable and doesn't have text except space, tab or | 307 // If node is not editable and doesn't have text except space, tab or |
| 320 // line break, do not select that 'empty' area. | 308 // line break, do not select that 'empty' area. |
| 321 if (!innerNode->hasEditableStyle()) { | 309 if (!innerNode->hasEditableStyle()) { |
| 322 const EphemeralRangeInComposedTree range = EphemeralRangeInComposedTree(
newSelection.startInComposedTree(), newSelection.endInComposedTree()); | 310 EphemeralRangeTemplate<Strategy> range = EphemeralRangeTemplate<Strategy
>(newSelection.start(), newSelection.end()); |
| 323 String str = plainText(range, TextIteratorDefaultBehavior); | 311 String str = plainText(range, TextIteratorDefaultBehavior); |
| 324 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace()) | 312 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace()) |
| 325 return; | 313 return; |
| 326 } | 314 } |
| 327 #endif | 315 #endif |
| 328 | 316 |
| 329 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne
wSelection.isRange()) | 317 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne
wSelection.isRange()) |
| 330 newSelection.appendTrailingWhitespace(); | 318 newSelection.appendTrailingWhitespace(); |
| 331 | 319 |
| 332 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); | 320 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); |
| 333 } | 321 } |
| 334 | 322 |
| 323 template <typename Strategy> |
| 335 void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTes
tResult& result, AppendTrailingWhitespace appendTrailingWhitespace) | 324 void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTes
tResult& result, AppendTrailingWhitespace appendTrailingWhitespace) |
| 336 { | 325 { |
| 337 Node* innerNode = result.innerNode(); | 326 Node* innerNode = result.innerNode(); |
| 338 VisibleSelection newSelection; | 327 VisibleSelectionTemplate<Strategy> newSelection; |
| 339 | 328 |
| 340 if (!innerNode || !innerNode->layoutObject()) | 329 if (!innerNode || !innerNode->layoutObject()) |
| 341 return; | 330 return; |
| 342 | 331 |
| 343 VisiblePosition pos = createVisiblePosition(innerNode->layoutObject()->posit
ionForPoint(result.localPoint())); | 332 VisiblePositionTemplate<Strategy> pos = createVisiblePosition(fromPositionIn
DOMTree<Strategy>(innerNode->layoutObject()->positionForPoint(result.localPoint(
)))); |
| 344 if (pos.isNotNull()) { | 333 if (pos.isNotNull()) { |
| 345 const Position markerPosition = pos.deepEquivalent().parentAnchoredEquiv
alent(); | 334 const PositionAlgorithm<Strategy> markerPosition = pos.deepEquivalent().
parentAnchoredEquivalent(); |
| 346 DocumentMarkerVector markers = innerNode->document().markers().markersIn
Range(EphemeralRange(markerPosition), DocumentMarker::MisspellingMarkers()); | 335 DocumentMarkerVector markers = innerNode->document().markers().markersIn
Range(EphemeralRange(toPositionInDOMTree(markerPosition)), DocumentMarker::Missp
ellingMarkers()); |
| 347 if (markers.size() == 1) { | 336 if (markers.size() == 1) { |
| 348 Node* containerNode = markerPosition.computeContainerNode(); | 337 Node* containerNode = markerPosition.computeContainerNode(); |
| 349 const Position start(containerNode, markers[0]->startOffset()); | 338 const PositionAlgorithm<Strategy> start(containerNode, markers[0]->s
tartOffset()); |
| 350 const Position end(containerNode, markers[0]->endOffset()); | 339 const PositionAlgorithm<Strategy> end(containerNode, markers[0]->end
Offset()); |
| 351 newSelection = VisibleSelection(start, end); | 340 newSelection = VisibleSelectionTemplate<Strategy>(start, end); |
| 352 } | 341 } |
| 353 } | 342 } |
| 354 | 343 |
| 355 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne
wSelection.isRange()) | 344 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne
wSelection.isRange()) |
| 356 newSelection.appendTrailingWhitespace(); | 345 newSelection.appendTrailingWhitespace(); |
| 357 | 346 |
| 358 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); | 347 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); |
| 359 } | 348 } |
| 360 | 349 |
| 361 void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHi
tTestResults& result) | 350 void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHi
tTestResults& result) |
| 362 { | 351 { |
| 363 if (!m_mouseDownMayStartSelect) | 352 if (!m_mouseDownMayStartSelect) |
| 364 return; | 353 return; |
| 365 | 354 |
| 366 selectClosestWordFromHitTestResult(result.hitTestResult(), | 355 AppendTrailingWhitespace appendTrailingWhitespace = (result.event().clickCou
nt() == 2 && m_frame->editor().isSelectTrailingWhitespaceEnabled()) ? AppendTrai
lingWhitespace::ShouldAppend : AppendTrailingWhitespace::DontAppend; |
| 367 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingW
hitespaceEnabled()) ? AppendTrailingWhitespace::ShouldAppend : AppendTrailingWhi
tespace::DontAppend); | 356 |
| 357 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 358 return selectClosestWordFromHitTestResult<EditingInComposedTreeStrategy>
(result.hitTestResult(), appendTrailingWhitespace); |
| 359 selectClosestWordFromHitTestResult<EditingStrategy>(result.hitTestResult(),
appendTrailingWhitespace); |
| 368 } | 360 } |
| 369 | 361 |
| 362 template <typename Strategy> |
| 370 void SelectionController::selectClosestMisspellingFromMouseEvent(const MouseEven
tWithHitTestResults& result) | 363 void SelectionController::selectClosestMisspellingFromMouseEvent(const MouseEven
tWithHitTestResults& result) |
| 371 { | 364 { |
| 372 if (!m_mouseDownMayStartSelect) | 365 if (!m_mouseDownMayStartSelect) |
| 373 return; | 366 return; |
| 374 | 367 |
| 375 selectClosestMisspellingFromHitTestResult(result.hitTestResult(), | 368 selectClosestMisspellingFromHitTestResult<Strategy>(result.hitTestResult(), |
| 376 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingW
hitespaceEnabled()) ? AppendTrailingWhitespace::ShouldAppend : AppendTrailingWhi
tespace::DontAppend); | 369 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingW
hitespaceEnabled()) ? AppendTrailingWhitespace::ShouldAppend : AppendTrailingWhi
tespace::DontAppend); |
| 377 | 370 |
| 378 } | 371 } |
| 379 | 372 |
| 373 template <typename Strategy> |
| 380 void SelectionController::selectClosestWordOrLinkFromMouseEvent(const MouseEvent
WithHitTestResults& result) | 374 void SelectionController::selectClosestWordOrLinkFromMouseEvent(const MouseEvent
WithHitTestResults& result) |
| 381 { | 375 { |
| 382 if (!result.hitTestResult().isLiveLink()) | 376 if (!result.hitTestResult().isLiveLink()) |
| 383 return selectClosestWordFromMouseEvent(result); | 377 return selectClosestWordFromMouseEvent(result); |
| 384 | 378 |
| 385 Node* innerNode = result.innerNode(); | 379 Node* innerNode = result.innerNode(); |
| 386 | 380 |
| 387 if (!innerNode || !innerNode->layoutObject() || !m_mouseDownMayStartSelect) | 381 if (!innerNode || !innerNode->layoutObject() || !m_mouseDownMayStartSelect) |
| 388 return; | 382 return; |
| 389 | 383 |
| 390 VisibleSelection newSelection; | 384 VisibleSelectionTemplate<Strategy> newSelection; |
| 391 Element* URLElement = result.hitTestResult().URLElement(); | 385 Element* URLElement = result.hitTestResult().URLElement(); |
| 392 VisiblePosition pos = createVisiblePosition(innerNode->layoutObject()->posit
ionForPoint(result.localPoint())); | 386 const VisiblePositionTemplate<Strategy> pos = createVisiblePosition(fromPosi
tionInDOMTree<Strategy>(innerNode->layoutObject()->positionForPoint(result.local
Point()))); |
| 393 if (pos.isNotNull() && pos.deepEquivalent().anchorNode()->isDescendantOf(URL
Element)) | 387 if (pos.isNotNull() && pos.deepEquivalent().anchorNode()->isDescendantOf(URL
Element)) |
| 394 newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement)
; | 388 newSelection = VisibleSelectionTemplate<Strategy>::selectionFromContents
OfNode(URLElement); |
| 395 | 389 |
| 396 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); | 390 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); |
| 397 } | 391 } |
| 398 | 392 |
| 399 bool SelectionController::handleMousePressEventDoubleClick(const MouseEventWithH
itTestResults& event) | 393 bool SelectionController::handleMousePressEventDoubleClick(const MouseEventWithH
itTestResults& event) |
| 400 { | 394 { |
| 401 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventDoubleClick
"); | 395 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventDoubleClick
"); |
| 402 | 396 |
| 403 if (event.event().button() != LeftButton) | 397 if (event.event().button() != LeftButton) |
| 404 return false; | 398 return false; |
| 405 | 399 |
| 406 if (selection().isRange()) { | 400 if (selection().isRange()) { |
| 407 // A double-click when range is already selected | 401 // A double-click when range is already selected |
| 408 // should not change the selection. So, do not call | 402 // should not change the selection. So, do not call |
| 409 // selectClosestWordFromMouseEvent, but do set | 403 // selectClosestWordFromMouseEvent, but do set |
| 410 // m_beganSelectingText to prevent handleMouseReleaseEvent | 404 // m_beganSelectingText to prevent handleMouseReleaseEvent |
| 411 // from setting caret selection. | 405 // from setting caret selection. |
| 412 m_selectionState = SelectionState::ExtendedSelection; | 406 m_selectionState = SelectionState::ExtendedSelection; |
| 413 } else { | 407 } else { |
| 414 selectClosestWordFromMouseEvent(event); | 408 selectClosestWordFromMouseEvent(event); |
| 415 } | 409 } |
| 416 return true; | 410 return true; |
| 417 } | 411 } |
| 418 | 412 |
| 419 bool SelectionController::handleMousePressEventTripleClick(const MouseEventWithH
itTestResults& event) | 413 template <typename Strategy> |
| 414 bool SelectionController::handleMousePressEventTripleClickAlgorithm(const MouseE
ventWithHitTestResults& event) |
| 420 { | 415 { |
| 421 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventTripleClick
"); | 416 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventTripleClick
"); |
| 422 | 417 |
| 423 if (event.event().button() != LeftButton) | 418 if (event.event().button() != LeftButton) |
| 424 return false; | 419 return false; |
| 425 | 420 |
| 426 Node* innerNode = event.innerNode(); | 421 Node* innerNode = event.innerNode(); |
| 427 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) | 422 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) |
| 428 return false; | 423 return false; |
| 429 | 424 |
| 430 VisibleSelection newSelection; | 425 VisibleSelectionTemplate<Strategy> newSelection; |
| 431 VisiblePosition pos = createVisiblePosition(innerNode->layoutObject()->posit
ionForPoint(event.localPoint())); | 426 const VisiblePositionTemplate<Strategy> pos = createVisiblePosition(fromPosi
tionInDOMTree<Strategy>(innerNode->layoutObject()->positionForPoint(event.localP
oint()))); |
| 432 if (pos.isNotNull()) { | 427 if (pos.isNotNull()) { |
| 433 newSelection = VisibleSelection(pos); | 428 newSelection = VisibleSelectionTemplate<Strategy>(pos); |
| 434 expandSelectionUsingGranularity(newSelection, ParagraphGranularity); | 429 newSelection.expandUsingGranularity(ParagraphGranularity); |
| 435 } | 430 } |
| 436 | 431 |
| 437 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe
lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity); | 432 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe
lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity); |
| 438 } | 433 } |
| 439 | 434 |
| 435 bool SelectionController::handleMousePressEventTripleClick(const MouseEventWithH
itTestResults& event) |
| 436 { |
| 437 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 438 return handleMousePressEventTripleClickAlgorithm<EditingInComposedTreeSt
rategy>(event); |
| 439 return handleMousePressEventTripleClickAlgorithm<EditingStrategy>(event); |
| 440 } |
| 441 |
| 440 bool SelectionController::handleMousePressEventSingleClick(const MouseEventWithH
itTestResults& event) | 442 bool SelectionController::handleMousePressEventSingleClick(const MouseEventWithH
itTestResults& event) |
| 441 { | 443 { |
| 442 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) | 444 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 443 return handleMousePressEventSingleClickAlgorithm<EditingInComposedTreeSt
rategy>(event); | 445 return handleMousePressEventSingleClickAlgorithm<EditingInComposedTreeSt
rategy>(event); |
| 444 return handleMousePressEventSingleClickAlgorithm<EditingStrategy>(event); | 446 return handleMousePressEventSingleClickAlgorithm<EditingStrategy>(event); |
| 445 } | 447 } |
| 446 | 448 |
| 447 void SelectionController::handleMousePressEvent(const MouseEventWithHitTestResul
ts& event) | 449 void SelectionController::handleMousePressEvent(const MouseEventWithHitTestResul
ts& event) |
| 448 { | 450 { |
| 449 // If we got the event back, that must mean it wasn't prevented, | 451 // If we got the event back, that must mean it wasn't prevented, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 479 updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKnownM
ousePosition); | 481 updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKnownM
ousePosition); |
| 480 } | 482 } |
| 481 | 483 |
| 482 void SelectionController::updateSelectionForMouseDrag(const HitTestResult& hitTe
stResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint&
lastKnownMousePosition) | 484 void SelectionController::updateSelectionForMouseDrag(const HitTestResult& hitTe
stResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint&
lastKnownMousePosition) |
| 483 { | 485 { |
| 484 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) | 486 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 485 return updateSelectionForMouseDragAlgorithm<EditingInComposedTreeStrateg
y>(hitTestResult, mousePressNode, dragStartPos, lastKnownMousePosition); | 487 return updateSelectionForMouseDragAlgorithm<EditingInComposedTreeStrateg
y>(hitTestResult, mousePressNode, dragStartPos, lastKnownMousePosition); |
| 486 updateSelectionForMouseDragAlgorithm<EditingStrategy>(hitTestResult, mousePr
essNode, dragStartPos, lastKnownMousePosition); | 488 updateSelectionForMouseDragAlgorithm<EditingStrategy>(hitTestResult, mousePr
essNode, dragStartPos, lastKnownMousePosition); |
| 487 } | 489 } |
| 488 | 490 |
| 489 bool SelectionController::handleMouseReleaseEvent(const MouseEventWithHitTestRes
ults& event, const LayoutPoint& dragStartPos) | 491 template <typename Strategy> |
| 492 bool SelectionController::handleMouseReleaseEventAlgorithm(const MouseEventWithH
itTestResults& event, const LayoutPoint& dragStartPos) |
| 490 { | 493 { |
| 491 bool handled = false; | 494 bool handled = false; |
| 492 m_mouseDownMayStartSelect = false; | 495 m_mouseDownMayStartSelect = false; |
| 493 // Clear the selection if the mouse didn't move after the last mouse | 496 // Clear the selection if the mouse didn't move after the last mouse |
| 494 // press and it's not a context menu click. We do this so when clicking | 497 // press and it's not a context menu click. We do this so when clicking |
| 495 // on the selection, the selection goes away. However, if we are | 498 // on the selection, the selection goes away. However, if we are |
| 496 // editing, place the caret. | 499 // editing, place the caret. |
| 497 if (m_mouseDownWasSingleClickInSelection && m_selectionState != SelectionSta
te::ExtendedSelection | 500 if (m_mouseDownWasSingleClickInSelection && m_selectionState != SelectionSta
te::ExtendedSelection |
| 498 && dragStartPos == event.event().position() | 501 && dragStartPos == event.event().position() |
| 499 && selection().isRange() | 502 && selection().isRange() |
| 500 && event.event().button() != RightButton) { | 503 && event.event().button() != RightButton) { |
| 501 VisibleSelection newSelection; | 504 VisibleSelectionTemplate<Strategy> newSelection; |
| 502 Node* node = event.innerNode(); | 505 Node* node = event.innerNode(); |
| 503 bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBr
owsingEnabled(); | 506 bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBr
owsingEnabled(); |
| 504 if (node && node->layoutObject() && (caretBrowsing || node->hasEditableS
tyle())) { | 507 if (node && node->layoutObject() && (caretBrowsing || node->hasEditableS
tyle())) { |
| 505 VisiblePosition pos = createVisiblePosition(node->layoutObject()->po
sitionForPoint(event.localPoint())); | 508 const VisiblePositionTemplate<Strategy> pos = createVisiblePosition(
fromPositionInDOMTree<Strategy>(node->layoutObject()->positionForPoint(event.loc
alPoint()))); |
| 506 newSelection = VisibleSelection(pos); | 509 newSelection = VisibleSelectionTemplate<Strategy>(pos); |
| 507 } | 510 } |
| 508 | 511 |
| 509 setSelectionIfNeeded(selection(), newSelection); | 512 setSelectionIfNeeded(selection(), newSelection); |
| 510 | 513 |
| 511 handled = true; | 514 handled = true; |
| 512 } | 515 } |
| 513 | 516 |
| 514 selection().notifyLayoutObjectOfSelectionChange(UserTriggered); | 517 selection().notifyLayoutObjectOfSelectionChange(UserTriggered); |
| 515 | 518 |
| 516 selection().selectFrameElementInParentIfFullySelected(); | 519 selection().selectFrameElementInParentIfFullySelected(); |
| 517 | 520 |
| 518 if (event.event().button() == MiddleButton && !event.isOverLink()) { | 521 if (event.event().button() == MiddleButton && !event.isOverLink()) { |
| 519 // Ignore handled, since we want to paste to where the caret was placed
anyway. | 522 // Ignore handled, since we want to paste to where the caret was placed
anyway. |
| 520 handled = handlePasteGlobalSelection(event.event()) || handled; | 523 handled = handlePasteGlobalSelection(event.event()) || handled; |
| 521 } | 524 } |
| 522 | 525 |
| 523 return handled; | 526 return handled; |
| 524 } | 527 } |
| 525 | 528 |
| 529 bool SelectionController::handleMouseReleaseEvent(const MouseEventWithHitTestRes
ults& event, const LayoutPoint& dragStartPos) |
| 530 { |
| 531 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 532 return handleMouseReleaseEventAlgorithm<EditingInComposedTreeStrategy>(e
vent, dragStartPos); |
| 533 return handleMouseReleaseEventAlgorithm<EditingStrategy>(event, dragStartPos
); |
| 534 } |
| 526 | 535 |
| 527 bool SelectionController::handlePasteGlobalSelection(const PlatformMouseEvent& m
ouseEvent) | 536 bool SelectionController::handlePasteGlobalSelection(const PlatformMouseEvent& m
ouseEvent) |
| 528 { | 537 { |
| 529 // If the event was a middle click, attempt to copy global selection in afte
r | 538 // If the event was a middle click, attempt to copy global selection in afte
r |
| 530 // the newly set caret position. | 539 // the newly set caret position. |
| 531 // | 540 // |
| 532 // This code is called from either the mouse up or mouse down handling. Ther
e | 541 // This code is called from either the mouse up or mouse down handling. Ther
e |
| 533 // is some debate about when the global selection is pasted: | 542 // is some debate about when the global selection is pasted: |
| 534 // xterm: pastes on up. | 543 // xterm: pastes on up. |
| 535 // GTK: pastes on down. | 544 // GTK: pastes on down. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 548 if (!m_frame->page()) | 557 if (!m_frame->page()) |
| 549 return false; | 558 return false; |
| 550 Frame* focusFrame = m_frame->page()->focusController().focusedOrMainFrame(); | 559 Frame* focusFrame = m_frame->page()->focusController().focusedOrMainFrame(); |
| 551 // Do not paste here if the focus was moved somewhere else. | 560 // Do not paste here if the focus was moved somewhere else. |
| 552 if (m_frame == focusFrame && m_frame->editor().behavior().supportsGlobalSele
ction()) | 561 if (m_frame == focusFrame && m_frame->editor().behavior().supportsGlobalSele
ction()) |
| 553 return m_frame->editor().command("PasteGlobalSelection").execute(); | 562 return m_frame->editor().command("PasteGlobalSelection").execute(); |
| 554 | 563 |
| 555 return false; | 564 return false; |
| 556 } | 565 } |
| 557 | 566 |
| 558 bool SelectionController::handleGestureLongPress(const PlatformGestureEvent& ges
tureEvent, const HitTestResult& hitTestResult) | 567 template <typename Strategy> |
| 568 bool SelectionController::handleGestureLongPressAlgorithm(const PlatformGestureE
vent& gestureEvent, const HitTestResult& hitTestResult) |
| 559 { | 569 { |
| 560 if (hitTestResult.isLiveLink()) | 570 if (hitTestResult.isLiveLink()) |
| 561 return false; | 571 return false; |
| 562 | 572 |
| 563 #if OS(ANDROID) | 573 #if OS(ANDROID) |
| 564 bool shouldLongPressSelectWord = true; | 574 bool shouldLongPressSelectWord = true; |
| 565 #else | 575 #else |
| 566 bool shouldLongPressSelectWord = m_frame->settings() && m_frame->settings()-
>touchEditingEnabled(); | 576 bool shouldLongPressSelectWord = m_frame->settings() && m_frame->settings()-
>touchEditingEnabled(); |
| 567 #endif | 577 #endif |
| 568 if (!shouldLongPressSelectWord) | 578 if (!shouldLongPressSelectWord) |
| 569 return false; | 579 return false; |
| 570 | 580 |
| 571 Node* innerNode = hitTestResult.innerNode(); | 581 Node* innerNode = hitTestResult.innerNode(); |
| 572 #if OS(ANDROID) | 582 #if OS(ANDROID) |
| 573 bool innerNodeIsSelectable = innerNode && (innerNode->isContentEditable() ||
innerNode->isTextNode() || innerNode->canStartSelection()); | 583 bool innerNodeIsSelectable = innerNode && (innerNode->isContentEditable() ||
innerNode->isTextNode() || innerNode->canStartSelection()); |
| 574 #else | 584 #else |
| 575 bool innerNodeIsSelectable = innerNode && (innerNode->isContentEditable() ||
innerNode->isTextNode()); | 585 bool innerNodeIsSelectable = innerNode && (innerNode->isContentEditable() ||
innerNode->isTextNode()); |
| 576 #endif | 586 #endif |
| 577 if (!innerNodeIsSelectable) | 587 if (!innerNodeIsSelectable) |
| 578 return false; | 588 return false; |
| 579 | 589 |
| 580 selectClosestWordFromHitTestResult(hitTestResult, AppendTrailingWhitespace::
DontAppend); | 590 selectClosestWordFromHitTestResult<Strategy>(hitTestResult, AppendTrailingWh
itespace::DontAppend); |
| 581 if (!selection().isRange()) | 591 return selection().isRange(); |
| 582 return false; | 592 } |
| 583 return true; | 593 |
| 594 bool SelectionController::handleGestureLongPress(const PlatformGestureEvent& ges
tureEvent, const HitTestResult& hitTestResult) |
| 595 { |
| 596 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 597 return handleGestureLongPressAlgorithm<EditingInComposedTreeStrategy>(ge
stureEvent, hitTestResult); |
| 598 return handleGestureLongPressAlgorithm<EditingStrategy>(gestureEvent, hitTes
tResult); |
| 584 } | 599 } |
| 585 | 600 |
| 586 void SelectionController::sendContextMenuEvent(const MouseEventWithHitTestResult
s& mev, const LayoutPoint& position) | 601 void SelectionController::sendContextMenuEvent(const MouseEventWithHitTestResult
s& mev, const LayoutPoint& position) |
| 587 { | 602 { |
| 588 if (selection().contains(position) | 603 if (selection().contains(position) |
| 589 || mev.scrollbar() | 604 || mev.scrollbar() |
| 590 // FIXME: In the editable case, word selection sometimes selects content
that isn't underneath the mouse. | 605 // FIXME: In the editable case, word selection sometimes selects content
that isn't underneath the mouse. |
| 591 // If the selection is non-editable, we do word selection to make it eas
ier to use the contextual menu items | 606 // If the selection is non-editable, we do word selection to make it eas
ier to use the contextual menu items |
| 592 // available for text selections. But only if we're above text. | 607 // available for text selections. But only if we're above text. |
| 593 || !(selection().isContentEditable() || (mev.innerNode() && mev.innerNod
e()->isTextNode()))) | 608 || !(selection().isContentEditable() || (mev.innerNode() && mev.innerNod
e()->isTextNode()))) |
| 594 return; | 609 return; |
| 595 | 610 |
| 596 m_mouseDownMayStartSelect = true; // context menu events are always allowed
to perform a selection | 611 m_mouseDownMayStartSelect = true; // context menu events are always allowed
to perform a selection |
| 597 | 612 |
| 598 if (mev.hitTestResult().isMisspelled()) | 613 if (mev.hitTestResult().isMisspelled()) { |
| 599 selectClosestMisspellingFromMouseEvent(mev); | 614 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 600 else if (m_frame->editor().behavior().shouldSelectOnContextualMenuClick()) | 615 return selectClosestMisspellingFromMouseEvent<EditingInComposedTreeS
trategy>(mev); |
| 601 selectClosestWordOrLinkFromMouseEvent(mev); | 616 return selectClosestMisspellingFromMouseEvent<EditingStrategy>(mev); |
| 617 } |
| 618 |
| 619 if (!m_frame->editor().behavior().shouldSelectOnContextualMenuClick()) |
| 620 return; |
| 621 |
| 622 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 623 return selectClosestWordOrLinkFromMouseEvent<EditingInComposedTreeStrate
gy>(mev); |
| 624 selectClosestWordOrLinkFromMouseEvent<EditingStrategy>(mev); |
| 602 } | 625 } |
| 603 | 626 |
| 604 void SelectionController::passMousePressEventToSubframe(const MouseEventWithHitT
estResults& mev) | 627 template <typename Strategy> |
| 628 void SelectionController::passMousePressEventToSubframeAlgorithm(const MouseEven
tWithHitTestResults& mev) |
| 605 { | 629 { |
| 606 // If we're clicking into a frame that is selected, the frame will appear | 630 // If we're clicking into a frame that is selected, the frame will appear |
| 607 // greyed out even though we're clicking on the selection. This looks | 631 // greyed out even though we're clicking on the selection. This looks |
| 608 // really strange (having the whole frame be greyed out), so we deselect the | 632 // really strange (having the whole frame be greyed out), so we deselect the |
| 609 // selection. | 633 // selection. |
| 610 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position()); | 634 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position()); |
| 611 if (!selection().contains(p)) | 635 if (!selection().contains(p)) |
| 612 return; | 636 return; |
| 613 | 637 |
| 614 VisiblePosition visiblePos = createVisiblePosition( | 638 const VisiblePositionTemplate<Strategy> visiblePos = createVisiblePosition( |
| 615 mev.innerNode()->layoutObject()->positionForPoint(mev.localPoint())); | 639 fromPositionInDOMTree<Strategy>(mev.innerNode()->layoutObject()->positio
nForPoint(mev.localPoint()))); |
| 616 VisibleSelection newSelection(visiblePos); | 640 VisibleSelectionTemplate<Strategy> newSelection(visiblePos); |
| 617 selection().setSelection(newSelection); | 641 selection().setSelection(newSelection); |
| 618 } | 642 } |
| 619 | 643 |
| 644 void SelectionController::passMousePressEventToSubframe(const MouseEventWithHitT
estResults& mev) |
| 645 { |
| 646 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) |
| 647 return passMousePressEventToSubframeAlgorithm<EditingInComposedTreeStrat
egy>(mev); |
| 648 passMousePressEventToSubframeAlgorithm<EditingStrategy>(mev); |
| 649 } |
| 650 |
| 620 void SelectionController::initializeSelectionState() | 651 void SelectionController::initializeSelectionState() |
| 621 { | 652 { |
| 622 m_selectionState = SelectionState::HaveNotStartedSelection; | 653 m_selectionState = SelectionState::HaveNotStartedSelection; |
| 623 } | 654 } |
| 624 | 655 |
| 625 void SelectionController::setMouseDownMayStartSelect(bool mayStartSelect) | 656 void SelectionController::setMouseDownMayStartSelect(bool mayStartSelect) |
| 626 { | 657 { |
| 627 m_mouseDownMayStartSelect = mayStartSelect; | 658 m_mouseDownMayStartSelect = mayStartSelect; |
| 628 } | 659 } |
| 629 | 660 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 646 else | 677 else |
| 647 m_selectionState = SelectionState::HaveNotStartedSelection; | 678 m_selectionState = SelectionState::HaveNotStartedSelection; |
| 648 } | 679 } |
| 649 | 680 |
| 650 FrameSelection& SelectionController::selection() const | 681 FrameSelection& SelectionController::selection() const |
| 651 { | 682 { |
| 652 return m_frame->selection(); | 683 return m_frame->selection(); |
| 653 } | 684 } |
| 654 | 685 |
| 655 } // namespace blink | 686 } // namespace blink |
| OLD | NEW |