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 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 { | 296 { |
297 Node* innerNode = result.innerNode(); | 297 Node* innerNode = result.innerNode(); |
298 VisibleSelectionInFlatTree newSelection; | 298 VisibleSelectionInFlatTree newSelection; |
299 | 299 |
300 if (!innerNode || !innerNode->layoutObject()) | 300 if (!innerNode || !innerNode->layoutObject()) |
301 return; | 301 return; |
302 | 302 |
303 // Special-case image local offset to always be zero, to avoid triggering | 303 // Special-case image local offset to always be zero, to avoid triggering |
304 // LayoutReplaced::positionFromPoint's advancement of the position at the | 304 // LayoutReplaced::positionFromPoint's advancement of the position at the |
305 // mid-point of the the image (which was intended for mouse-drag selection | 305 // mid-point of the the image (which was intended for mouse-drag selection |
306 // and isn't desirable for long-press). | 306 // and isn't desirable for touch). |
307 HitTestResult adjustedHitTestResult = result; | 307 HitTestResult adjustedHitTestResult = result; |
308 if (selectInputEventType == SelectInputEventType::GestureLongPress && result
.image()) | 308 if (selectInputEventType == SelectInputEventType::Touch && result.image()) |
309 adjustedHitTestResult.setNodeAndPosition(result.innerNode(), LayoutPoint
(0, 0)); | 309 adjustedHitTestResult.setNodeAndPosition(result.innerNode(), LayoutPoint
(0, 0)); |
310 | 310 |
311 const VisiblePositionInFlatTree& pos = visiblePositionOfHitTestResult(adjust
edHitTestResult); | 311 const VisiblePositionInFlatTree& pos = visiblePositionOfHitTestResult(adjust
edHitTestResult); |
312 if (pos.isNotNull()) { | 312 if (pos.isNotNull()) { |
313 newSelection = VisibleSelectionInFlatTree(pos); | 313 newSelection = VisibleSelectionInFlatTree(pos); |
314 newSelection.expandUsingGranularity(WordGranularity); | 314 newSelection.expandUsingGranularity(WordGranularity); |
315 } | 315 } |
316 | 316 |
317 if (selectInputEventType == SelectInputEventType::GestureLongPress) { | 317 if (selectInputEventType == SelectInputEventType::Touch) { |
318 // If node doesn't have text except space, tab or line break, do not | 318 // If node doesn't have text except space, tab or line break, do not |
319 // select that 'empty' area. | 319 // select that 'empty' area. |
320 EphemeralRangeInFlatTree range(newSelection.start(), newSelection.end())
; | 320 EphemeralRangeInFlatTree range(newSelection.start(), newSelection.end())
; |
321 const String& str = plainText(range, TextIteratorEmitsObjectReplacementC
haracter); | 321 const String& str = plainText(range, TextIteratorEmitsObjectReplacementC
haracter); |
322 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace()) | 322 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace()) |
323 return; | 323 return; |
| 324 |
| 325 if (newSelection.rootEditableElement() && pos.deepEquivalent() == Visibl
ePositionInFlatTree::lastPositionInNode(newSelection.rootEditableElement()).deep
Equivalent()) |
| 326 return; |
324 } | 327 } |
325 | 328 |
326 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne
wSelection.isRange()) | 329 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne
wSelection.isRange()) |
327 newSelection.appendTrailingWhitespace(); | 330 newSelection.appendTrailingWhitespace(); |
328 | 331 |
329 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); | 332 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); |
330 } | 333 } |
331 | 334 |
332 void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTes
tResult& result, AppendTrailingWhitespace appendTrailingWhitespace) | 335 void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTes
tResult& result, AppendTrailingWhitespace appendTrailingWhitespace) |
333 { | 336 { |
(...skipping 21 matching lines...) Expand all Loading... |
355 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); | 358 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); |
356 } | 359 } |
357 | 360 |
358 void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHi
tTestResults& result) | 361 void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHi
tTestResults& result) |
359 { | 362 { |
360 if (!m_mouseDownMayStartSelect) | 363 if (!m_mouseDownMayStartSelect) |
361 return; | 364 return; |
362 | 365 |
363 AppendTrailingWhitespace appendTrailingWhitespace = (result.event().clickCou
nt() == 2 && m_frame->editor().isSelectTrailingWhitespaceEnabled()) ? AppendTrai
lingWhitespace::ShouldAppend : AppendTrailingWhitespace::DontAppend; | 366 AppendTrailingWhitespace appendTrailingWhitespace = (result.event().clickCou
nt() == 2 && m_frame->editor().isSelectTrailingWhitespaceEnabled()) ? AppendTrai
lingWhitespace::ShouldAppend : AppendTrailingWhitespace::DontAppend; |
364 | 367 |
365 return selectClosestWordFromHitTestResult(result.hitTestResult(), appendTrai
lingWhitespace, SelectInputEventType::Mouse); | 368 return selectClosestWordFromHitTestResult(result.hitTestResult(), appendTrai
lingWhitespace, result.event().fromTouch() ? SelectInputEventType::Touch : Selec
tInputEventType::Mouse); |
366 } | 369 } |
367 | 370 |
368 void SelectionController::selectClosestMisspellingFromMouseEvent(const MouseEven
tWithHitTestResults& result) | 371 void SelectionController::selectClosestMisspellingFromMouseEvent(const MouseEven
tWithHitTestResults& result) |
369 { | 372 { |
370 if (!m_mouseDownMayStartSelect) | 373 if (!m_mouseDownMayStartSelect) |
371 return; | 374 return; |
372 | 375 |
373 selectClosestMisspellingFromHitTestResult(result.hitTestResult(), | 376 selectClosestMisspellingFromHitTestResult(result.hitTestResult(), |
374 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingW
hitespaceEnabled()) ? AppendTrailingWhitespace::ShouldAppend : AppendTrailingWhi
tespace::DontAppend); | 377 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingW
hitespaceEnabled()) ? AppendTrailingWhitespace::ShouldAppend : AppendTrailingWhi
tespace::DontAppend); |
375 | 378 |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 if (!selection().isAvailable()) | 575 if (!selection().isAvailable()) |
573 return false; | 576 return false; |
574 if (hitTestResult.isLiveLink()) | 577 if (hitTestResult.isLiveLink()) |
575 return false; | 578 return false; |
576 | 579 |
577 Node* innerNode = hitTestResult.innerNode(); | 580 Node* innerNode = hitTestResult.innerNode(); |
578 bool innerNodeIsSelectable = innerNode && (innerNode->isContentEditable() ||
innerNode->isTextNode() || innerNode->canStartSelection()); | 581 bool innerNodeIsSelectable = innerNode && (innerNode->isContentEditable() ||
innerNode->isTextNode() || innerNode->canStartSelection()); |
579 if (!innerNodeIsSelectable) | 582 if (!innerNodeIsSelectable) |
580 return false; | 583 return false; |
581 | 584 |
582 selectClosestWordFromHitTestResult(hitTestResult, AppendTrailingWhitespace::
DontAppend, SelectInputEventType::GestureLongPress); | 585 selectClosestWordFromHitTestResult(hitTestResult, AppendTrailingWhitespace::
DontAppend, SelectInputEventType::Touch); |
583 if (!selection().isAvailable()) { | 586 if (!selection().isAvailable()) { |
584 // "editing/selection/longpress-selection-in-iframe-removed-crash.html" | 587 // "editing/selection/longpress-selection-in-iframe-removed-crash.html" |
585 // reach here. | 588 // reach here. |
586 return false; | 589 return false; |
587 } | 590 } |
588 return selection().isRange(); | 591 return selection().isRange(); |
589 } | 592 } |
590 | 593 |
591 void SelectionController::sendContextMenuEvent(const MouseEventWithHitTestResult
s& mev, const LayoutPoint& position) | 594 void SelectionController::sendContextMenuEvent(const MouseEventWithHitTestResult
s& mev, const LayoutPoint& position) |
592 { | 595 { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 { | 664 { |
662 return m_frame->selection(); | 665 return m_frame->selection(); |
663 } | 666 } |
664 | 667 |
665 bool isLinkSelection(const MouseEventWithHitTestResults& event) | 668 bool isLinkSelection(const MouseEventWithHitTestResults& event) |
666 { | 669 { |
667 return event.event().altKey() && event.isOverLink(); | 670 return event.event().altKey() && event.isOverLink(); |
668 } | 671 } |
669 | 672 |
670 } // namespace blink | 673 } // namespace blink |
OLD | NEW |