| 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 | 144 |
| 145 VisiblePositionInFlatTree visiblePos = visiblePositionOfHitTestResult(event.
hitTestResult()); | 145 VisiblePositionInFlatTree visiblePos = visiblePositionOfHitTestResult(event.
hitTestResult()); |
| 146 if (visiblePos.isNull()) | 146 if (visiblePos.isNull()) |
| 147 visiblePos = createVisiblePosition(PositionInFlatTree::firstPositionInOr
BeforeNode(innerNode)); | 147 visiblePos = createVisiblePosition(PositionInFlatTree::firstPositionInOr
BeforeNode(innerNode)); |
| 148 PositionInFlatTree pos = visiblePos.deepEquivalent(); | 148 PositionInFlatTree pos = visiblePos.deepEquivalent(); |
| 149 | 149 |
| 150 VisibleSelectionInFlatTree newSelection = selection().visibleSelection<Editi
ngInFlatTreeStrategy>(); | 150 VisibleSelectionInFlatTree newSelection = selection().visibleSelection<Editi
ngInFlatTreeStrategy>(); |
| 151 TextGranularity granularity = CharacterGranularity; | 151 TextGranularity granularity = CharacterGranularity; |
| 152 | 152 |
| 153 if (extendSelection && !newSelection.isNone()) { | 153 if (extendSelection && !newSelection.isNone()) { |
| 154 const VisibleSelectionInFlatTree selectionInUserSelectAll(expandSelectio
nToRespectUserSelectAll(innerNode, VisibleSelectionInFlatTree(createVisiblePosit
ion(pos)))); | 154 const VisibleSelectionInFlatTree selectionInUserSelectAll(expandSelectio
nToRespectUserSelectAll(innerNode, createVisibleSelectionDeprecated(createVisibl
ePosition(pos)))); |
| 155 if (selectionInUserSelectAll.isRange()) { | 155 if (selectionInUserSelectAll.isRange()) { |
| 156 if (selectionInUserSelectAll.start().compareTo(newSelection.start())
< 0) | 156 if (selectionInUserSelectAll.start().compareTo(newSelection.start())
< 0) |
| 157 pos = selectionInUserSelectAll.start(); | 157 pos = selectionInUserSelectAll.start(); |
| 158 else if (newSelection.end().compareTo(selectionInUserSelectAll.end()
) < 0) | 158 else if (newSelection.end().compareTo(selectionInUserSelectAll.end()
) < 0) |
| 159 pos = selectionInUserSelectAll.end(); | 159 pos = selectionInUserSelectAll.end(); |
| 160 } | 160 } |
| 161 | 161 |
| 162 if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()
) { | 162 if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()
) { |
| 163 if (pos.isNotNull()) { | 163 if (pos.isNotNull()) { |
| 164 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click | 164 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click |
| 165 // deselects when selection was created right-to-left | 165 // deselects when selection was created right-to-left |
| 166 const PositionInFlatTree start = newSelection.start(); | 166 const PositionInFlatTree start = newSelection.start(); |
| 167 const PositionInFlatTree end = newSelection.end(); | 167 const PositionInFlatTree end = newSelection.end(); |
| 168 int distanceToStart = textDistance(start, pos); | 168 int distanceToStart = textDistance(start, pos); |
| 169 int distanceToEnd = textDistance(pos, end); | 169 int distanceToEnd = textDistance(pos, end); |
| 170 if (distanceToStart <= distanceToEnd) | 170 if (distanceToStart <= distanceToEnd) |
| 171 newSelection = VisibleSelectionInFlatTree(end, pos); | 171 newSelection = createVisibleSelectionDeprecated(end, pos); |
| 172 else | 172 else |
| 173 newSelection = VisibleSelectionInFlatTree(start, pos); | 173 newSelection = createVisibleSelectionDeprecated(start, pos); |
| 174 } | 174 } |
| 175 } else { | 175 } else { |
| 176 newSelection.setExtent(pos); | 176 newSelection.setExtent(pos); |
| 177 } | 177 } |
| 178 | 178 |
| 179 if (selection().granularity() != CharacterGranularity) { | 179 if (selection().granularity() != CharacterGranularity) { |
| 180 granularity = selection().granularity(); | 180 granularity = selection().granularity(); |
| 181 newSelection.expandUsingGranularity(selection().granularity()); | 181 newSelection.expandUsingGranularity(selection().granularity()); |
| 182 } | 182 } |
| 183 } else if (m_selectionState != SelectionState::ExtendedSelection) { | 183 } else if (m_selectionState != SelectionState::ExtendedSelection) { |
| 184 newSelection = expandSelectionToRespectUserSelectAll(innerNode, VisibleS
electionInFlatTree(visiblePos)); | 184 newSelection = expandSelectionToRespectUserSelectAll(innerNode, createVi
sibleSelectionDeprecated(visiblePos)); |
| 185 } | 185 } |
| 186 | 186 |
| 187 // Updating the selection is considered side-effect of the event and so it d
oesn't impact the handled state. | 187 // Updating the selection is considered side-effect of the event and so it d
oesn't impact the handled state. |
| 188 updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, g
ranularity); | 188 updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, g
ranularity); |
| 189 return false; | 189 return false; |
| 190 } | 190 } |
| 191 | 191 |
| 192 void SelectionController::updateSelectionForMouseDrag(const HitTestResult& hitTe
stResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint&
lastKnownMousePosition) | 192 void SelectionController::updateSelectionForMouseDrag(const HitTestResult& hitTe
stResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint&
lastKnownMousePosition) |
| 193 { | 193 { |
| 194 if (!m_mouseDownMayStartSelect) | 194 if (!m_mouseDownMayStartSelect) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 if (m_selectionState == SelectionState::HaveNotStartedSelection && dispatchS
electStart(target) != DispatchEventResult::NotCanceled) | 226 if (m_selectionState == SelectionState::HaveNotStartedSelection && dispatchS
electStart(target) != DispatchEventResult::NotCanceled) |
| 227 return; | 227 return; |
| 228 | 228 |
| 229 // TODO(yosin) We should check |mousePressNode|, |targetPosition|, and | 229 // TODO(yosin) We should check |mousePressNode|, |targetPosition|, and |
| 230 // |newSelection| are valid for |m_frame->document()|. | 230 // |newSelection| are valid for |m_frame->document()|. |
| 231 // |dispatchSelectStart()| can change them by "selectstart" event handler. | 231 // |dispatchSelectStart()| can change them by "selectstart" event handler. |
| 232 | 232 |
| 233 if (m_selectionState != SelectionState::ExtendedSelection) { | 233 if (m_selectionState != SelectionState::ExtendedSelection) { |
| 234 // Always extend selection here because it's caused by a mouse drag | 234 // Always extend selection here because it's caused by a mouse drag |
| 235 m_selectionState = SelectionState::ExtendedSelection; | 235 m_selectionState = SelectionState::ExtendedSelection; |
| 236 newSelection = VisibleSelectionInFlatTree(targetPosition); | 236 newSelection = createVisibleSelectionDeprecated(targetPosition); |
| 237 } | 237 } |
| 238 | 238 |
| 239 if (RuntimeEnabledFeatures::userSelectAllEnabled()) { | 239 if (RuntimeEnabledFeatures::userSelectAllEnabled()) { |
| 240 // TODO(yosin) Should we use |Strategy::rootUserSelectAllForNode()|? | 240 // TODO(yosin) Should we use |Strategy::rootUserSelectAllForNode()|? |
| 241 Node* const rootUserSelectAllForMousePressNode = EditingInFlatTreeStrate
gy::rootUserSelectAllForNode(mousePressNode); | 241 Node* const rootUserSelectAllForMousePressNode = EditingInFlatTreeStrate
gy::rootUserSelectAllForNode(mousePressNode); |
| 242 Node* const rootUserSelectAllForTarget = EditingInFlatTreeStrategy::root
UserSelectAllForNode(target); | 242 Node* const rootUserSelectAllForTarget = EditingInFlatTreeStrategy::root
UserSelectAllForNode(target); |
| 243 if (rootUserSelectAllForMousePressNode && rootUserSelectAllForMousePress
Node == rootUserSelectAllForTarget) { | 243 if (rootUserSelectAllForMousePressNode && rootUserSelectAllForMousePress
Node == rootUserSelectAllForTarget) { |
| 244 newSelection.setBase(mostBackwardCaretPosition(PositionInFlatTree::b
eforeNode(rootUserSelectAllForMousePressNode), CanCrossEditingBoundary)); | 244 newSelection.setBase(mostBackwardCaretPosition(PositionInFlatTree::b
eforeNode(rootUserSelectAllForMousePressNode), CanCrossEditingBoundary)); |
| 245 newSelection.setExtent(mostForwardCaretPosition(PositionInFlatTree::
afterNode(rootUserSelectAllForMousePressNode), CanCrossEditingBoundary)); | 245 newSelection.setExtent(mostForwardCaretPosition(PositionInFlatTree::
afterNode(rootUserSelectAllForMousePressNode), CanCrossEditingBoundary)); |
| 246 } else { | 246 } else { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 // Special-case image local offset to always be zero, to avoid triggering | 308 // Special-case image local offset to always be zero, to avoid triggering |
| 309 // LayoutReplaced::positionFromPoint's advancement of the position at the | 309 // LayoutReplaced::positionFromPoint's advancement of the position at the |
| 310 // mid-point of the the image (which was intended for mouse-drag selection | 310 // mid-point of the the image (which was intended for mouse-drag selection |
| 311 // and isn't desirable for touch). | 311 // and isn't desirable for touch). |
| 312 HitTestResult adjustedHitTestResult = result; | 312 HitTestResult adjustedHitTestResult = result; |
| 313 if (selectInputEventType == SelectInputEventType::Touch && result.image()) | 313 if (selectInputEventType == SelectInputEventType::Touch && result.image()) |
| 314 adjustedHitTestResult.setNodeAndPosition(result.innerNode(), LayoutPoint
(0, 0)); | 314 adjustedHitTestResult.setNodeAndPosition(result.innerNode(), LayoutPoint
(0, 0)); |
| 315 | 315 |
| 316 const VisiblePositionInFlatTree& pos = visiblePositionOfHitTestResult(adjust
edHitTestResult); | 316 const VisiblePositionInFlatTree& pos = visiblePositionOfHitTestResult(adjust
edHitTestResult); |
| 317 if (pos.isNotNull()) { | 317 if (pos.isNotNull()) { |
| 318 newSelection = VisibleSelectionInFlatTree(pos); | 318 newSelection = createVisibleSelectionDeprecated(pos); |
| 319 newSelection.expandUsingGranularity(WordGranularity); | 319 newSelection.expandUsingGranularity(WordGranularity); |
| 320 } | 320 } |
| 321 | 321 |
| 322 if (selectInputEventType == SelectInputEventType::Touch) { | 322 if (selectInputEventType == SelectInputEventType::Touch) { |
| 323 // If node doesn't have text except space, tab or line break, do not | 323 // If node doesn't have text except space, tab or line break, do not |
| 324 // select that 'empty' area. | 324 // select that 'empty' area. |
| 325 EphemeralRangeInFlatTree range(newSelection.start(), newSelection.end())
; | 325 EphemeralRangeInFlatTree range(newSelection.start(), newSelection.end())
; |
| 326 const String& str = plainText(range, hasEditableStyle(*innerNode) ? Text
IteratorEmitsObjectReplacementCharacter : TextIteratorDefaultBehavior); | 326 const String& str = plainText(range, hasEditableStyle(*innerNode) ? Text
IteratorEmitsObjectReplacementCharacter : TextIteratorDefaultBehavior); |
| 327 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace()) | 327 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace()) |
| 328 return; | 328 return; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 346 return; | 346 return; |
| 347 | 347 |
| 348 const VisiblePositionInFlatTree& pos = visiblePositionOfHitTestResult(result
); | 348 const VisiblePositionInFlatTree& pos = visiblePositionOfHitTestResult(result
); |
| 349 if (pos.isNotNull()) { | 349 if (pos.isNotNull()) { |
| 350 const PositionInFlatTree& markerPosition = pos.deepEquivalent().parentAn
choredEquivalent(); | 350 const PositionInFlatTree& markerPosition = pos.deepEquivalent().parentAn
choredEquivalent(); |
| 351 DocumentMarkerVector markers = innerNode->document().markers().markersIn
Range(EphemeralRange(toPositionInDOMTree(markerPosition)), DocumentMarker::Missp
ellingMarkers()); | 351 DocumentMarkerVector markers = innerNode->document().markers().markersIn
Range(EphemeralRange(toPositionInDOMTree(markerPosition)), DocumentMarker::Missp
ellingMarkers()); |
| 352 if (markers.size() == 1) { | 352 if (markers.size() == 1) { |
| 353 Node* containerNode = markerPosition.computeContainerNode(); | 353 Node* containerNode = markerPosition.computeContainerNode(); |
| 354 const PositionInFlatTree start(containerNode, markers[0]->startOffse
t()); | 354 const PositionInFlatTree start(containerNode, markers[0]->startOffse
t()); |
| 355 const PositionInFlatTree end(containerNode, markers[0]->endOffset())
; | 355 const PositionInFlatTree end(containerNode, markers[0]->endOffset())
; |
| 356 newSelection = VisibleSelectionInFlatTree(start, end); | 356 newSelection = createVisibleSelectionDeprecated(start, end); |
| 357 } | 357 } |
| 358 } | 358 } |
| 359 | 359 |
| 360 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne
wSelection.isRange()) | 360 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne
wSelection.isRange()) |
| 361 newSelection.appendTrailingWhitespace(); | 361 newSelection.appendTrailingWhitespace(); |
| 362 | 362 |
| 363 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); | 363 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); |
| 364 } | 364 } |
| 365 | 365 |
| 366 void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHi
tTestResults& result) | 366 void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHi
tTestResults& result) |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 if (event.event().pointerProperties().button != WebPointerProperties::Button
::Left) | 445 if (event.event().pointerProperties().button != WebPointerProperties::Button
::Left) |
| 446 return false; | 446 return false; |
| 447 | 447 |
| 448 Node* innerNode = event.innerNode(); | 448 Node* innerNode = event.innerNode(); |
| 449 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) | 449 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) |
| 450 return false; | 450 return false; |
| 451 | 451 |
| 452 VisibleSelectionInFlatTree newSelection; | 452 VisibleSelectionInFlatTree newSelection; |
| 453 const VisiblePositionInFlatTree& pos = visiblePositionOfHitTestResult(event.
hitTestResult()); | 453 const VisiblePositionInFlatTree& pos = visiblePositionOfHitTestResult(event.
hitTestResult()); |
| 454 if (pos.isNotNull()) { | 454 if (pos.isNotNull()) { |
| 455 newSelection = VisibleSelectionInFlatTree(pos); | 455 newSelection = createVisibleSelectionDeprecated(pos); |
| 456 newSelection.expandUsingGranularity(ParagraphGranularity); | 456 newSelection.expandUsingGranularity(ParagraphGranularity); |
| 457 } | 457 } |
| 458 | 458 |
| 459 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe
lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity); | 459 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe
lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity); |
| 460 } | 460 } |
| 461 | 461 |
| 462 void SelectionController::handleMousePressEvent(const MouseEventWithHitTestResul
ts& event) | 462 void SelectionController::handleMousePressEvent(const MouseEventWithHitTestResul
ts& event) |
| 463 { | 463 { |
| 464 // If we got the event back, that must mean it wasn't prevented, | 464 // If we got the event back, that must mean it wasn't prevented, |
| 465 // so it's allowed to start a drag or selection if it wasn't in a scrollbar. | 465 // so it's allowed to start a drag or selection if it wasn't in a scrollbar. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 && event.event().pointerProperties().button != WebPointerProperties::But
ton::Right) { | 523 && event.event().pointerProperties().button != WebPointerProperties::But
ton::Right) { |
| 524 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesh
eets | 524 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesh
eets |
| 525 // needs to be audited. See http://crbug.com/590369 for more details. | 525 // needs to be audited. See http://crbug.com/590369 for more details. |
| 526 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 526 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 527 | 527 |
| 528 VisibleSelectionInFlatTree newSelection; | 528 VisibleSelectionInFlatTree newSelection; |
| 529 Node* node = event.innerNode(); | 529 Node* node = event.innerNode(); |
| 530 bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBr
owsingEnabled(); | 530 bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBr
owsingEnabled(); |
| 531 if (node && node->layoutObject() && (caretBrowsing || hasEditableStyle(*
node))) { | 531 if (node && node->layoutObject() && (caretBrowsing || hasEditableStyle(*
node))) { |
| 532 const VisiblePositionInFlatTree pos = visiblePositionOfHitTestResult
(event.hitTestResult()); | 532 const VisiblePositionInFlatTree pos = visiblePositionOfHitTestResult
(event.hitTestResult()); |
| 533 newSelection = VisibleSelectionInFlatTree(pos); | 533 newSelection = createVisibleSelectionDeprecated(pos); |
| 534 } | 534 } |
| 535 | 535 |
| 536 setSelectionIfNeeded(selection(), newSelection); | 536 setSelectionIfNeeded(selection(), newSelection); |
| 537 | 537 |
| 538 handled = true; | 538 handled = true; |
| 539 } | 539 } |
| 540 | 540 |
| 541 selection().notifyLayoutObjectOfSelectionChange(UserTriggered); | 541 selection().notifyLayoutObjectOfSelectionChange(UserTriggered); |
| 542 | 542 |
| 543 selection().selectFrameElementInParentIfFullySelected(); | 543 selection().selectFrameElementInParentIfFullySelected(); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 // selection. | 647 // selection. |
| 648 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position()); | 648 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position()); |
| 649 if (!selection().contains(p)) | 649 if (!selection().contains(p)) |
| 650 return; | 650 return; |
| 651 | 651 |
| 652 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 652 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
| 653 // needs to be audited. See http://crbug.com/590369 for more details. | 653 // needs to be audited. See http://crbug.com/590369 for more details. |
| 654 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 654 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 655 | 655 |
| 656 const VisiblePositionInFlatTree& visiblePos = visiblePositionOfHitTestResult
(mev.hitTestResult()); | 656 const VisiblePositionInFlatTree& visiblePos = visiblePositionOfHitTestResult
(mev.hitTestResult()); |
| 657 VisibleSelectionInFlatTree newSelection(visiblePos); | 657 VisibleSelectionInFlatTree newSelection = createVisibleSelectionDeprecated(v
isiblePos); |
| 658 selection().setSelection(newSelection); | 658 selection().setSelection(newSelection); |
| 659 } | 659 } |
| 660 | 660 |
| 661 void SelectionController::initializeSelectionState() | 661 void SelectionController::initializeSelectionState() |
| 662 { | 662 { |
| 663 m_selectionState = SelectionState::HaveNotStartedSelection; | 663 m_selectionState = SelectionState::HaveNotStartedSelection; |
| 664 } | 664 } |
| 665 | 665 |
| 666 void SelectionController::setMouseDownMayStartSelect(bool mayStartSelect) | 666 void SelectionController::setMouseDownMayStartSelect(bool mayStartSelect) |
| 667 { | 667 { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 698 return event.event().altKey() && event.isOverLink(); | 698 return event.event().altKey() && event.isOverLink(); |
| 699 } | 699 } |
| 700 | 700 |
| 701 bool isExtendingSelection(const MouseEventWithHitTestResults& event) | 701 bool isExtendingSelection(const MouseEventWithHitTestResults& event) |
| 702 { | 702 { |
| 703 bool isMouseDownOnLinkOrImage = event.isOverLink() || event.hitTestResult().
image(); | 703 bool isMouseDownOnLinkOrImage = event.isOverLink() || event.hitTestResult().
image(); |
| 704 return event.event().shiftKey() && !isMouseDownOnLinkOrImage; | 704 return event.event().shiftKey() && !isMouseDownOnLinkOrImage; |
| 705 } | 705 } |
| 706 | 706 |
| 707 } // namespace blink | 707 } // namespace blink |
| OLD | NEW |