| 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 |