OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights |
| 3 * reserved. |
3 * | 4 * |
4 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
6 * are met: | 7 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
11 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
12 * | 13 * |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 SelectionDirection direction) { | 82 SelectionDirection direction) { |
82 if (alter != FrameSelection::AlterationExtend) | 83 if (alter != FrameSelection::AlterationExtend) |
83 return; | 84 return; |
84 | 85 |
85 Position start = m_selection.start(); | 86 Position start = m_selection.start(); |
86 Position end = m_selection.end(); | 87 Position end = m_selection.end(); |
87 | 88 |
88 bool baseIsStart = true; | 89 bool baseIsStart = true; |
89 | 90 |
90 if (m_selection.isDirectional()) { | 91 if (m_selection.isDirectional()) { |
91 // Make base and extent match start and end so we extend the user-visible se
lection. | 92 // Make base and extent match start and end so we extend the user-visible |
92 // This only matters for cases where base and extend point to different posi
tions than | 93 // selection. This only matters for cases where base and extend point to |
93 // start and end (e.g. after a double-click to select a word). | 94 // different positions than start and end (e.g. after a double-click to |
| 95 // select a word). |
94 if (m_selection.isBaseFirst()) | 96 if (m_selection.isBaseFirst()) |
95 baseIsStart = true; | 97 baseIsStart = true; |
96 else | 98 else |
97 baseIsStart = false; | 99 baseIsStart = false; |
98 } else { | 100 } else { |
99 switch (direction) { | 101 switch (direction) { |
100 case DirectionRight: | 102 case DirectionRight: |
101 if (directionOfSelection() == LTR) | 103 if (directionOfSelection() == LTR) |
102 baseIsStart = true; | 104 baseIsStart = true; |
103 else | 105 else |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 CanCrossEditingBoundary)); | 189 CanCrossEditingBoundary)); |
188 } | 190 } |
189 | 191 |
190 VisiblePosition SelectionModifier::modifyExtendingRight( | 192 VisiblePosition SelectionModifier::modifyExtendingRight( |
191 TextGranularity granularity) { | 193 TextGranularity granularity) { |
192 VisiblePosition pos = | 194 VisiblePosition pos = |
193 createVisiblePosition(m_selection.extent(), m_selection.affinity()); | 195 createVisiblePosition(m_selection.extent(), m_selection.affinity()); |
194 | 196 |
195 // The difference between modifyExtendingRight and modifyExtendingForward is: | 197 // The difference between modifyExtendingRight and modifyExtendingForward is: |
196 // modifyExtendingForward always extends forward logically. | 198 // modifyExtendingForward always extends forward logically. |
197 // modifyExtendingRight behaves the same as modifyExtendingForward except for
extending character or word, | 199 // modifyExtendingRight behaves the same as modifyExtendingForward except for |
198 // it extends forward logically if the enclosing block is LTR direction, | 200 // extending character or word, it extends forward logically if the enclosing |
199 // but it extends backward logically if the enclosing block is RTL direction. | 201 // block is LTR direction, but it extends backward logically if the enclosing |
| 202 // block is RTL direction. |
200 switch (granularity) { | 203 switch (granularity) { |
201 case CharacterGranularity: | 204 case CharacterGranularity: |
202 if (directionOfEnclosingBlock() == LTR) | 205 if (directionOfEnclosingBlock() == LTR) |
203 pos = nextPositionOf(pos, CanSkipOverEditingBoundary); | 206 pos = nextPositionOf(pos, CanSkipOverEditingBoundary); |
204 else | 207 else |
205 pos = previousPositionOf(pos, CanSkipOverEditingBoundary); | 208 pos = previousPositionOf(pos, CanSkipOverEditingBoundary); |
206 break; | 209 break; |
207 case WordGranularity: | 210 case WordGranularity: |
208 if (directionOfEnclosingBlock() == LTR) | 211 if (directionOfEnclosingBlock() == LTR) |
209 pos = nextWordPositionForPlatform(pos); | 212 pos = nextWordPositionForPlatform(pos); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 break; | 334 break; |
332 case WordGranularity: | 335 case WordGranularity: |
333 pos = nextWordPositionForPlatform( | 336 pos = nextWordPositionForPlatform( |
334 createVisiblePosition(m_selection.extent(), m_selection.affinity())); | 337 createVisiblePosition(m_selection.extent(), m_selection.affinity())); |
335 break; | 338 break; |
336 case SentenceGranularity: | 339 case SentenceGranularity: |
337 pos = nextSentencePosition( | 340 pos = nextSentencePosition( |
338 createVisiblePosition(m_selection.extent(), m_selection.affinity())); | 341 createVisiblePosition(m_selection.extent(), m_selection.affinity())); |
339 break; | 342 break; |
340 case LineGranularity: { | 343 case LineGranularity: { |
341 // down-arrowing from a range selection that ends at the start of a line n
eeds | 344 // down-arrowing from a range selection that ends at the start of a line |
342 // to leave the selection at that line start (no need to call nextLinePosi
tion!) | 345 // needs to leave the selection at that line start (no need to call |
| 346 // nextLinePosition!) |
343 pos = endForPlatform(); | 347 pos = endForPlatform(); |
344 if (!m_selection.isRange() || !isStartOfLine(pos)) | 348 if (!m_selection.isRange() || !isStartOfLine(pos)) |
345 pos = nextLinePosition( | 349 pos = nextLinePosition( |
346 pos, lineDirectionPointForBlockDirectionNavigation(START)); | 350 pos, lineDirectionPointForBlockDirectionNavigation(START)); |
347 break; | 351 break; |
348 } | 352 } |
349 case ParagraphGranularity: | 353 case ParagraphGranularity: |
350 pos = nextParagraphPosition( | 354 pos = nextParagraphPosition( |
351 endForPlatform(), | 355 endForPlatform(), |
352 lineDirectionPointForBlockDirectionNavigation(START)); | 356 lineDirectionPointForBlockDirectionNavigation(START)); |
(...skipping 18 matching lines...) Expand all Loading... |
371 return pos; | 375 return pos; |
372 } | 376 } |
373 | 377 |
374 VisiblePosition SelectionModifier::modifyExtendingLeft( | 378 VisiblePosition SelectionModifier::modifyExtendingLeft( |
375 TextGranularity granularity) { | 379 TextGranularity granularity) { |
376 VisiblePosition pos = | 380 VisiblePosition pos = |
377 createVisiblePosition(m_selection.extent(), m_selection.affinity()); | 381 createVisiblePosition(m_selection.extent(), m_selection.affinity()); |
378 | 382 |
379 // The difference between modifyExtendingLeft and modifyExtendingBackward is: | 383 // The difference between modifyExtendingLeft and modifyExtendingBackward is: |
380 // modifyExtendingBackward always extends backward logically. | 384 // modifyExtendingBackward always extends backward logically. |
381 // modifyExtendingLeft behaves the same as modifyExtendingBackward except for
extending character or word, | 385 // modifyExtendingLeft behaves the same as modifyExtendingBackward except for |
382 // it extends backward logically if the enclosing block is LTR direction, | 386 // extending character or word, it extends backward logically if the enclosing |
383 // but it extends forward logically if the enclosing block is RTL direction. | 387 // block is LTR direction, but it extends forward logically if the enclosing |
| 388 // block is RTL direction. |
384 switch (granularity) { | 389 switch (granularity) { |
385 case CharacterGranularity: | 390 case CharacterGranularity: |
386 if (directionOfEnclosingBlock() == LTR) | 391 if (directionOfEnclosingBlock() == LTR) |
387 pos = previousPositionOf(pos, CanSkipOverEditingBoundary); | 392 pos = previousPositionOf(pos, CanSkipOverEditingBoundary); |
388 else | 393 else |
389 pos = nextPositionOf(pos, CanSkipOverEditingBoundary); | 394 pos = nextPositionOf(pos, CanSkipOverEditingBoundary); |
390 break; | 395 break; |
391 case WordGranularity: | 396 case WordGranularity: |
392 if (directionOfEnclosingBlock() == LTR) | 397 if (directionOfEnclosingBlock() == LTR) |
393 pos = previousWordPosition(pos); | 398 pos = previousWordPosition(pos); |
(...skipping 17 matching lines...) Expand all Loading... |
411 } | 416 } |
412 adjustPositionForUserSelectAll(pos, !(directionOfEnclosingBlock() == LTR)); | 417 adjustPositionForUserSelectAll(pos, !(directionOfEnclosingBlock() == LTR)); |
413 return pos; | 418 return pos; |
414 } | 419 } |
415 | 420 |
416 VisiblePosition SelectionModifier::modifyExtendingBackward( | 421 VisiblePosition SelectionModifier::modifyExtendingBackward( |
417 TextGranularity granularity) { | 422 TextGranularity granularity) { |
418 VisiblePosition pos = | 423 VisiblePosition pos = |
419 createVisiblePosition(m_selection.extent(), m_selection.affinity()); | 424 createVisiblePosition(m_selection.extent(), m_selection.affinity()); |
420 | 425 |
421 // Extending a selection backward by word or character from just after a table
selects | 426 // Extending a selection backward by word or character from just after a table |
422 // the table. This "makes sense" from the user perspective, esp. when deletin
g. | 427 // selects the table. This "makes sense" from the user perspective, esp. when |
423 // It was done here instead of in VisiblePosition because we want VPs to itera
te | 428 // deleting. It was done here instead of in VisiblePosition because we want |
424 // over everything. | 429 // VPs to iterate over everything. |
425 switch (granularity) { | 430 switch (granularity) { |
426 case CharacterGranularity: | 431 case CharacterGranularity: |
427 pos = previousPositionOf(pos, CanSkipOverEditingBoundary); | 432 pos = previousPositionOf(pos, CanSkipOverEditingBoundary); |
428 break; | 433 break; |
429 case WordGranularity: | 434 case WordGranularity: |
430 pos = previousWordPosition(pos); | 435 pos = previousWordPosition(pos); |
431 break; | 436 break; |
432 case SentenceGranularity: | 437 case SentenceGranularity: |
433 pos = previousSentencePosition(pos); | 438 pos = previousSentencePosition(pos); |
434 break; | 439 break; |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 return false; | 628 return false; |
624 | 629 |
625 if (isSpatialNavigationEnabled(frame())) { | 630 if (isSpatialNavigationEnabled(frame())) { |
626 if (!wasRange && alter == FrameSelection::AlterationMove && | 631 if (!wasRange && alter == FrameSelection::AlterationMove && |
627 position.deepEquivalent() == originalStartPosition.deepEquivalent()) | 632 position.deepEquivalent() == originalStartPosition.deepEquivalent()) |
628 return false; | 633 return false; |
629 } | 634 } |
630 | 635 |
631 // Some of the above operations set an xPosForVerticalArrowNavigation. | 636 // Some of the above operations set an xPosForVerticalArrowNavigation. |
632 // Setting a selection will clear it, so save it to possibly restore later. | 637 // Setting a selection will clear it, so save it to possibly restore later. |
633 // Note: the START position type is arbitrary because it is unused, it would b
e | 638 // Note: the START position type is arbitrary because it is unused, it would |
634 // the requested position type if there were no xPosForVerticalArrowNavigation
set. | 639 // be the requested position type if there were no |
| 640 // xPosForVerticalArrowNavigation set. |
635 LayoutUnit x = lineDirectionPointForBlockDirectionNavigation(START); | 641 LayoutUnit x = lineDirectionPointForBlockDirectionNavigation(START); |
636 m_selection.setIsDirectional(shouldAlwaysUseDirectionalSelection(frame()) || | 642 m_selection.setIsDirectional(shouldAlwaysUseDirectionalSelection(frame()) || |
637 alter == FrameSelection::AlterationExtend); | 643 alter == FrameSelection::AlterationExtend); |
638 | 644 |
639 switch (alter) { | 645 switch (alter) { |
640 case FrameSelection::AlterationMove: | 646 case FrameSelection::AlterationMove: |
641 m_selection = | 647 m_selection = |
642 createVisibleSelection(position, m_selection.isDirectional()); | 648 createVisibleSelection(position, m_selection.isDirectional()); |
643 break; | 649 break; |
644 case FrameSelection::AlterationExtend: | 650 case FrameSelection::AlterationExtend: |
645 | 651 |
646 if (!m_selection.isCaret() && (granularity == WordGranularity || | 652 if (!m_selection.isCaret() && (granularity == WordGranularity || |
647 granularity == ParagraphGranularity || | 653 granularity == ParagraphGranularity || |
648 granularity == LineGranularity) && | 654 granularity == LineGranularity) && |
649 frame() && | 655 frame() && |
650 !frame() | 656 !frame() |
651 ->editor() | 657 ->editor() |
652 .behavior() | 658 .behavior() |
653 .shouldExtendSelectionByWordOrLineAcrossCaret()) { | 659 .shouldExtendSelectionByWordOrLineAcrossCaret()) { |
654 // Don't let the selection go across the base position directly. Needed
to match mac | 660 // Don't let the selection go across the base position directly. Needed |
655 // behavior when, for instance, word-selecting backwards starting with t
he caret in | 661 // to match mac behavior when, for instance, word-selecting backwards |
656 // the middle of a word and then word-selecting forward, leaving the car
et in the | 662 // starting with the caret in the middle of a word and then |
657 // same place where it was, instead of directly selecting to the end of
the word. | 663 // word-selecting forward, leaving the caret in the same place where it |
| 664 // was, instead of directly selecting to the end of the word. |
658 VisibleSelection newSelection = m_selection; | 665 VisibleSelection newSelection = m_selection; |
659 newSelection.setExtent(position); | 666 newSelection.setExtent(position); |
660 if (m_selection.isBaseFirst() != newSelection.isBaseFirst()) | 667 if (m_selection.isBaseFirst() != newSelection.isBaseFirst()) |
661 position = m_selection.visibleBase(); | 668 position = m_selection.visibleBase(); |
662 } | 669 } |
663 | 670 |
664 // Standard Mac behavior when extending to a boundary is grow the | 671 // Standard Mac behavior when extending to a boundary is grow the |
665 // selection rather than leaving the base in place and moving the | 672 // selection rather than leaving the base in place and moving the |
666 // extent. Matches NSTextView. | 673 // extent. Matches NSTextView. |
667 if (!frame() || | 674 if (!frame() || |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 visiblePosition.toPositionWithAffinity(), layoutObject); | 800 visiblePosition.toPositionWithAffinity(), layoutObject); |
794 if (localRect.isEmpty() || !layoutObject) | 801 if (localRect.isEmpty() || !layoutObject) |
795 return LayoutUnit(); | 802 return LayoutUnit(); |
796 | 803 |
797 // This ignores transforms on purpose, for now. Vertical navigation is done | 804 // This ignores transforms on purpose, for now. Vertical navigation is done |
798 // without consulting transforms, so that 'up' in transformed text is 'up' | 805 // without consulting transforms, so that 'up' in transformed text is 'up' |
799 // relative to the text, not absolute 'up'. | 806 // relative to the text, not absolute 'up'. |
800 FloatPoint caretPoint = | 807 FloatPoint caretPoint = |
801 layoutObject->localToAbsolute(FloatPoint(localRect.location())); | 808 layoutObject->localToAbsolute(FloatPoint(localRect.location())); |
802 LayoutObject* containingBlock = layoutObject->containingBlock(); | 809 LayoutObject* containingBlock = layoutObject->containingBlock(); |
803 if (!containingBlock) | 810 if (!containingBlock) { |
804 containingBlock = | 811 // Just use ourselves to determine the writing mode if we have no containing |
805 layoutObject; // Just use ourselves to determine the writing mode if we
have no containing block. | 812 // block. |
| 813 containingBlock = layoutObject; |
| 814 } |
806 return LayoutUnit(containingBlock->isHorizontalWritingMode() | 815 return LayoutUnit(containingBlock->isHorizontalWritingMode() |
807 ? caretPoint.x() | 816 ? caretPoint.x() |
808 : caretPoint.y()); | 817 : caretPoint.y()); |
809 } | 818 } |
810 | 819 |
811 LayoutUnit SelectionModifier::lineDirectionPointForBlockDirectionNavigation( | 820 LayoutUnit SelectionModifier::lineDirectionPointForBlockDirectionNavigation( |
812 EPositionType type) { | 821 EPositionType type) { |
813 LayoutUnit x; | 822 LayoutUnit x; |
814 | 823 |
815 if (m_selection.isNone()) | 824 if (m_selection.isNone()) |
(...skipping 15 matching lines...) Expand all Loading... |
831 break; | 840 break; |
832 } | 841 } |
833 | 842 |
834 LocalFrame* frame = pos.document()->frame(); | 843 LocalFrame* frame = pos.document()->frame(); |
835 if (!frame) | 844 if (!frame) |
836 return x; | 845 return x; |
837 | 846 |
838 if (m_xPosForVerticalArrowNavigation == NoXPosForVerticalArrowNavigation()) { | 847 if (m_xPosForVerticalArrowNavigation == NoXPosForVerticalArrowNavigation()) { |
839 VisiblePosition visiblePosition = | 848 VisiblePosition visiblePosition = |
840 createVisiblePosition(pos, m_selection.affinity()); | 849 createVisiblePosition(pos, m_selection.affinity()); |
841 // VisiblePosition creation can fail here if a node containing the selection
becomes visibility:hidden | 850 // VisiblePosition creation can fail here if a node containing the selection |
842 // after the selection is created and before this function is called. | 851 // becomes visibility:hidden after the selection is created and before this |
| 852 // function is called. |
843 x = lineDirectionPointForBlockDirectionNavigationOf(visiblePosition); | 853 x = lineDirectionPointForBlockDirectionNavigationOf(visiblePosition); |
844 m_xPosForVerticalArrowNavigation = x; | 854 m_xPosForVerticalArrowNavigation = x; |
845 } else { | 855 } else { |
846 x = m_xPosForVerticalArrowNavigation; | 856 x = m_xPosForVerticalArrowNavigation; |
847 } | 857 } |
848 | 858 |
849 return x; | 859 return x; |
850 } | 860 } |
851 | 861 |
852 DEFINE_TRACE(SelectionModifier) { | 862 DEFINE_TRACE(SelectionModifier) { |
853 visitor->trace(m_frame); | 863 visitor->trace(m_frame); |
854 visitor->trace(m_selection); | 864 visitor->trace(m_selection); |
855 } | 865 } |
856 | 866 |
857 } // namespace blink | 867 } // namespace blink |
OLD | NEW |