| 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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 // existing selection so we can allow for text dragging. | 148 // existing selection so we can allow for text dragging. |
| 149 if (FrameView* view = m_frame->view()) { | 149 if (FrameView* view = m_frame->view()) { |
| 150 LayoutPoint vPoint = view->rootFrameToContents(event.event().position())
; | 150 LayoutPoint vPoint = view->rootFrameToContents(event.event().position())
; |
| 151 if (!extendSelection && selection().contains(vPoint)) { | 151 if (!extendSelection && selection().contains(vPoint)) { |
| 152 m_mouseDownWasSingleClickInSelection = true; | 152 m_mouseDownWasSingleClickInSelection = true; |
| 153 return false; | 153 return false; |
| 154 } | 154 } |
| 155 } | 155 } |
| 156 | 156 |
| 157 PositionWithAffinity eventPos = innerNode->layoutObject()->positionForPoint(
event.localPoint()); | 157 PositionWithAffinity eventPos = innerNode->layoutObject()->positionForPoint(
event.localPoint()); |
| 158 VisiblePosition visiblePos = visiblePositionOf(Strategy::toPositionType(even
tPos.position()), eventPos.affinity()); | 158 VisiblePosition visiblePos = createVisiblePosition(Strategy::toPositionType(
eventPos.position()), eventPos.affinity()); |
| 159 if (visiblePos.isNull()) | 159 if (visiblePos.isNull()) |
| 160 visiblePos = VisiblePosition(firstPositionInOrBeforeNode(innerNode)); | 160 visiblePos = VisiblePosition(firstPositionInOrBeforeNode(innerNode)); |
| 161 PositionType pos = Strategy::toPositionType(visiblePos.deepEquivalent()); | 161 PositionType pos = Strategy::toPositionType(visiblePos.deepEquivalent()); |
| 162 | 162 |
| 163 VisibleSelection newSelection = selection().selection(); | 163 VisibleSelection newSelection = selection().selection(); |
| 164 TextGranularity granularity = CharacterGranularity; | 164 TextGranularity granularity = CharacterGranularity; |
| 165 | 165 |
| 166 if (extendSelection && newSelection.isCaretOrRange()) { | 166 if (extendSelection && newSelection.isCaretOrRange()) { |
| 167 VisibleSelection selectionInUserSelectAll(expandSelectionToRespectUserSe
lectAll(innerNode, VisibleSelection(visiblePositionOf(pos)))); | 167 VisibleSelection selectionInUserSelectAll(expandSelectionToRespectUserSe
lectAll(innerNode, VisibleSelection(createVisiblePosition(pos)))); |
| 168 if (selectionInUserSelectAll.isRange()) { | 168 if (selectionInUserSelectAll.isRange()) { |
| 169 if (Strategy::selectionStart(selectionInUserSelectAll).compareTo(Str
ategy::selectionStart(newSelection)) < 0) | 169 if (Strategy::selectionStart(selectionInUserSelectAll).compareTo(Str
ategy::selectionStart(newSelection)) < 0) |
| 170 pos = Strategy::selectionStart(selectionInUserSelectAll); | 170 pos = Strategy::selectionStart(selectionInUserSelectAll); |
| 171 else if (Strategy::selectionEnd(newSelection).compareTo(Strategy::se
lectionEnd(selectionInUserSelectAll)) < 0) | 171 else if (Strategy::selectionEnd(newSelection).compareTo(Strategy::se
lectionEnd(selectionInUserSelectAll)) < 0) |
| 172 pos = Strategy::selectionEnd(selectionInUserSelectAll); | 172 pos = Strategy::selectionEnd(selectionInUserSelectAll); |
| 173 } | 173 } |
| 174 | 174 |
| 175 if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()
) { | 175 if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()
) { |
| 176 if (pos.isNotNull()) { | 176 if (pos.isNotNull()) { |
| 177 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click d
eselects when selection | 177 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click d
eselects when selection |
| (...skipping 30 matching lines...) Expand all Loading... |
| 208 using PositionType = typename Strategy::PositionType; | 208 using PositionType = typename Strategy::PositionType; |
| 209 | 209 |
| 210 if (!m_mouseDownMayStartSelect) | 210 if (!m_mouseDownMayStartSelect) |
| 211 return; | 211 return; |
| 212 | 212 |
| 213 Node* target = hitTestResult.innerNode(); | 213 Node* target = hitTestResult.innerNode(); |
| 214 if (!target) | 214 if (!target) |
| 215 return; | 215 return; |
| 216 | 216 |
| 217 PositionWithAffinity rawTargetPosition = selection().selection().positionRes
pectingEditingBoundary(hitTestResult.localPoint(), target); | 217 PositionWithAffinity rawTargetPosition = selection().selection().positionRes
pectingEditingBoundary(hitTestResult.localPoint(), target); |
| 218 VisiblePosition targetPosition = visiblePositionOf(Strategy::toPositionType(
rawTargetPosition.position()), rawTargetPosition.affinity()); | 218 VisiblePosition targetPosition = createVisiblePosition(Strategy::toPositionT
ype(rawTargetPosition.position()), rawTargetPosition.affinity()); |
| 219 // Don't modify the selection if we're not on a node. | 219 // Don't modify the selection if we're not on a node. |
| 220 if (targetPosition.isNull()) | 220 if (targetPosition.isNull()) |
| 221 return; | 221 return; |
| 222 | 222 |
| 223 // Restart the selection if this is the first mouse move. This work is usual
ly | 223 // Restart the selection if this is the first mouse move. This work is usual
ly |
| 224 // done in handleMousePressEvent, but not if the mouse press was on an exist
ing selection. | 224 // done in handleMousePressEvent, but not if the mouse press was on an exist
ing selection. |
| 225 VisibleSelection newSelection = selection().selection(); | 225 VisibleSelection newSelection = selection().selection(); |
| 226 | 226 |
| 227 // Special case to limit selection to the containing block for SVG text. | 227 // Special case to limit selection to the containing block for SVG text. |
| 228 // FIXME: Isn't there a better non-SVG-specific way to do this? | 228 // FIXME: Isn't there a better non-SVG-specific way to do this? |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 } | 306 } |
| 307 | 307 |
| 308 void SelectionController::selectClosestWordFromHitTestResult(const HitTestResult
& result, AppendTrailingWhitespace appendTrailingWhitespace) | 308 void SelectionController::selectClosestWordFromHitTestResult(const HitTestResult
& result, AppendTrailingWhitespace appendTrailingWhitespace) |
| 309 { | 309 { |
| 310 Node* innerNode = result.innerNode(); | 310 Node* innerNode = result.innerNode(); |
| 311 VisibleSelection newSelection; | 311 VisibleSelection newSelection; |
| 312 | 312 |
| 313 if (!innerNode || !innerNode->layoutObject()) | 313 if (!innerNode || !innerNode->layoutObject()) |
| 314 return; | 314 return; |
| 315 | 315 |
| 316 VisiblePosition pos = visiblePositionOf(innerNode->layoutObject()->positionF
orPoint(result.localPoint())); | 316 VisiblePosition pos = createVisiblePosition(innerNode->layoutObject()->posit
ionForPoint(result.localPoint())); |
| 317 if (pos.isNotNull()) { | 317 if (pos.isNotNull()) { |
| 318 newSelection = VisibleSelection(pos); | 318 newSelection = VisibleSelection(pos); |
| 319 expandSelectionUsingGranularity(newSelection, WordGranularity); | 319 expandSelectionUsingGranularity(newSelection, WordGranularity); |
| 320 } | 320 } |
| 321 | 321 |
| 322 #if OS(ANDROID) | 322 #if OS(ANDROID) |
| 323 // If node is not editable and doesn't have text except space, tab or | 323 // If node is not editable and doesn't have text except space, tab or |
| 324 // line break, do not select that 'empty' area. | 324 // line break, do not select that 'empty' area. |
| 325 if (!innerNode->hasEditableStyle()) { | 325 if (!innerNode->hasEditableStyle()) { |
| 326 EphemeralRangeTemplate<EditingInComposedTreeStrategy> range = VisibleSel
ection::InComposedTree::asRange(newSelection); | 326 EphemeralRangeTemplate<EditingInComposedTreeStrategy> range = VisibleSel
ection::InComposedTree::asRange(newSelection); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 337 } | 337 } |
| 338 | 338 |
| 339 void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTes
tResult& result, AppendTrailingWhitespace appendTrailingWhitespace) | 339 void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTes
tResult& result, AppendTrailingWhitespace appendTrailingWhitespace) |
| 340 { | 340 { |
| 341 Node* innerNode = result.innerNode(); | 341 Node* innerNode = result.innerNode(); |
| 342 VisibleSelection newSelection; | 342 VisibleSelection newSelection; |
| 343 | 343 |
| 344 if (!innerNode || !innerNode->layoutObject()) | 344 if (!innerNode || !innerNode->layoutObject()) |
| 345 return; | 345 return; |
| 346 | 346 |
| 347 VisiblePosition pos = visiblePositionOf(innerNode->layoutObject()->positionF
orPoint(result.localPoint())); | 347 VisiblePosition pos = createVisiblePosition(innerNode->layoutObject()->posit
ionForPoint(result.localPoint())); |
| 348 if (pos.isNotNull()) { | 348 if (pos.isNotNull()) { |
| 349 const Position markerPosition = pos.deepEquivalent().parentAnchoredEquiv
alent(); | 349 const Position markerPosition = pos.deepEquivalent().parentAnchoredEquiv
alent(); |
| 350 DocumentMarkerVector markers = innerNode->document().markers().markersIn
Range(EphemeralRange(markerPosition), DocumentMarker::MisspellingMarkers()); | 350 DocumentMarkerVector markers = innerNode->document().markers().markersIn
Range(EphemeralRange(markerPosition), DocumentMarker::MisspellingMarkers()); |
| 351 if (markers.size() == 1) { | 351 if (markers.size() == 1) { |
| 352 Node* containerNode = markerPosition.computeContainerNode(); | 352 Node* containerNode = markerPosition.computeContainerNode(); |
| 353 const Position start(containerNode, markers[0]->startOffset()); | 353 const Position start(containerNode, markers[0]->startOffset()); |
| 354 const Position end(containerNode, markers[0]->endOffset()); | 354 const Position end(containerNode, markers[0]->endOffset()); |
| 355 newSelection = VisibleSelection(start, end); | 355 newSelection = VisibleSelection(start, end); |
| 356 } | 356 } |
| 357 } | 357 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 386 if (!result.hitTestResult().isLiveLink()) | 386 if (!result.hitTestResult().isLiveLink()) |
| 387 return selectClosestWordFromMouseEvent(result); | 387 return selectClosestWordFromMouseEvent(result); |
| 388 | 388 |
| 389 Node* innerNode = result.innerNode(); | 389 Node* innerNode = result.innerNode(); |
| 390 | 390 |
| 391 if (!innerNode || !innerNode->layoutObject() || !m_mouseDownMayStartSelect) | 391 if (!innerNode || !innerNode->layoutObject() || !m_mouseDownMayStartSelect) |
| 392 return; | 392 return; |
| 393 | 393 |
| 394 VisibleSelection newSelection; | 394 VisibleSelection newSelection; |
| 395 Element* URLElement = result.hitTestResult().URLElement(); | 395 Element* URLElement = result.hitTestResult().URLElement(); |
| 396 VisiblePosition pos = visiblePositionOf(innerNode->layoutObject()->positionF
orPoint(result.localPoint())); | 396 VisiblePosition pos = createVisiblePosition(innerNode->layoutObject()->posit
ionForPoint(result.localPoint())); |
| 397 if (pos.isNotNull() && pos.deepEquivalent().anchorNode()->isDescendantOf(URL
Element)) | 397 if (pos.isNotNull() && pos.deepEquivalent().anchorNode()->isDescendantOf(URL
Element)) |
| 398 newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement)
; | 398 newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement)
; |
| 399 | 399 |
| 400 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); | 400 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); |
| 401 } | 401 } |
| 402 | 402 |
| 403 bool SelectionController::handleMousePressEventDoubleClick(const MouseEventWithH
itTestResults& event) | 403 bool SelectionController::handleMousePressEventDoubleClick(const MouseEventWithH
itTestResults& event) |
| 404 { | 404 { |
| 405 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventDoubleClick
"); | 405 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventDoubleClick
"); |
| 406 | 406 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 425 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventTripleClick
"); | 425 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventTripleClick
"); |
| 426 | 426 |
| 427 if (event.event().button() != LeftButton) | 427 if (event.event().button() != LeftButton) |
| 428 return false; | 428 return false; |
| 429 | 429 |
| 430 Node* innerNode = event.innerNode(); | 430 Node* innerNode = event.innerNode(); |
| 431 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) | 431 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) |
| 432 return false; | 432 return false; |
| 433 | 433 |
| 434 VisibleSelection newSelection; | 434 VisibleSelection newSelection; |
| 435 VisiblePosition pos = visiblePositionOf(innerNode->layoutObject()->positionF
orPoint(event.localPoint())); | 435 VisiblePosition pos = createVisiblePosition(innerNode->layoutObject()->posit
ionForPoint(event.localPoint())); |
| 436 if (pos.isNotNull()) { | 436 if (pos.isNotNull()) { |
| 437 newSelection = VisibleSelection(pos); | 437 newSelection = VisibleSelection(pos); |
| 438 expandSelectionUsingGranularity(newSelection, ParagraphGranularity); | 438 expandSelectionUsingGranularity(newSelection, ParagraphGranularity); |
| 439 } | 439 } |
| 440 | 440 |
| 441 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe
lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity); | 441 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe
lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity); |
| 442 } | 442 } |
| 443 | 443 |
| 444 bool SelectionController::handleMousePressEventSingleClick(const MouseEventWithH
itTestResults& event) | 444 bool SelectionController::handleMousePressEventSingleClick(const MouseEventWithH
itTestResults& event) |
| 445 { | 445 { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 // on the selection, the selection goes away. However, if we are | 499 // on the selection, the selection goes away. However, if we are |
| 500 // editing, place the caret. | 500 // editing, place the caret. |
| 501 if (m_mouseDownWasSingleClickInSelection && m_selectionState != SelectionSta
te::ExtendedSelection | 501 if (m_mouseDownWasSingleClickInSelection && m_selectionState != SelectionSta
te::ExtendedSelection |
| 502 && dragStartPos == event.event().position() | 502 && dragStartPos == event.event().position() |
| 503 && selection().isRange() | 503 && selection().isRange() |
| 504 && event.event().button() != RightButton) { | 504 && event.event().button() != RightButton) { |
| 505 VisibleSelection newSelection; | 505 VisibleSelection newSelection; |
| 506 Node* node = event.innerNode(); | 506 Node* node = event.innerNode(); |
| 507 bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBr
owsingEnabled(); | 507 bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBr
owsingEnabled(); |
| 508 if (node && node->layoutObject() && (caretBrowsing || node->hasEditableS
tyle())) { | 508 if (node && node->layoutObject() && (caretBrowsing || node->hasEditableS
tyle())) { |
| 509 VisiblePosition pos = visiblePositionOf(node->layoutObject()->positi
onForPoint(event.localPoint())); | 509 VisiblePosition pos = createVisiblePosition(node->layoutObject()->po
sitionForPoint(event.localPoint())); |
| 510 newSelection = VisibleSelection(pos); | 510 newSelection = VisibleSelection(pos); |
| 511 } | 511 } |
| 512 | 512 |
| 513 setSelectionIfNeeded(selection(), newSelection); | 513 setSelectionIfNeeded(selection(), newSelection); |
| 514 | 514 |
| 515 handled = true; | 515 handled = true; |
| 516 } | 516 } |
| 517 | 517 |
| 518 selection().notifyLayoutObjectOfSelectionChange(UserTriggered); | 518 selection().notifyLayoutObjectOfSelectionChange(UserTriggered); |
| 519 | 519 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 void SelectionController::passMousePressEventToSubframe(const MouseEventWithHitT
estResults& mev) | 608 void SelectionController::passMousePressEventToSubframe(const MouseEventWithHitT
estResults& mev) |
| 609 { | 609 { |
| 610 // If we're clicking into a frame that is selected, the frame will appear | 610 // If we're clicking into a frame that is selected, the frame will appear |
| 611 // greyed out even though we're clicking on the selection. This looks | 611 // greyed out even though we're clicking on the selection. This looks |
| 612 // really strange (having the whole frame be greyed out), so we deselect the | 612 // really strange (having the whole frame be greyed out), so we deselect the |
| 613 // selection. | 613 // selection. |
| 614 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position()); | 614 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position()); |
| 615 if (!selection().contains(p)) | 615 if (!selection().contains(p)) |
| 616 return; | 616 return; |
| 617 | 617 |
| 618 VisiblePosition visiblePos = visiblePositionOf( | 618 VisiblePosition visiblePos = createVisiblePosition( |
| 619 mev.innerNode()->layoutObject()->positionForPoint(mev.localPoint())); | 619 mev.innerNode()->layoutObject()->positionForPoint(mev.localPoint())); |
| 620 VisibleSelection newSelection(visiblePos); | 620 VisibleSelection newSelection(visiblePos); |
| 621 selection().setSelection(newSelection); | 621 selection().setSelection(newSelection); |
| 622 } | 622 } |
| 623 | 623 |
| 624 void SelectionController::initializeSelectionState() | 624 void SelectionController::initializeSelectionState() |
| 625 { | 625 { |
| 626 m_selectionState = SelectionState::HaveNotStartedSelection; | 626 m_selectionState = SelectionState::HaveNotStartedSelection; |
| 627 } | 627 } |
| 628 | 628 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 650 else | 650 else |
| 651 m_selectionState = SelectionState::HaveNotStartedSelection; | 651 m_selectionState = SelectionState::HaveNotStartedSelection; |
| 652 } | 652 } |
| 653 | 653 |
| 654 FrameSelection& SelectionController::selection() const | 654 FrameSelection& SelectionController::selection() const |
| 655 { | 655 { |
| 656 return m_frame->selection(); | 656 return m_frame->selection(); |
| 657 } | 657 } |
| 658 | 658 |
| 659 } // namespace blink | 659 } // namespace blink |
| OLD | NEW |