| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights |
| 3 * reserved. | 3 * reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 m_xPosForVerticalArrowNavigation(xPosForVerticalArrowNavigation) {} | 54 m_xPosForVerticalArrowNavigation(xPosForVerticalArrowNavigation) {} |
| 55 | 55 |
| 56 SelectionModifier::SelectionModifier(const LocalFrame& frame, | 56 SelectionModifier::SelectionModifier(const LocalFrame& frame, |
| 57 const VisibleSelection& selection) | 57 const VisibleSelection& selection) |
| 58 : SelectionModifier(frame, selection, NoXPosForVerticalArrowNavigation()) {} | 58 : SelectionModifier(frame, selection, NoXPosForVerticalArrowNavigation()) {} |
| 59 | 59 |
| 60 TextDirection SelectionModifier::directionOfEnclosingBlock() const { | 60 TextDirection SelectionModifier::directionOfEnclosingBlock() const { |
| 61 return blink::directionOfEnclosingBlock(m_selection.extent()); | 61 return blink::directionOfEnclosingBlock(m_selection.extent()); |
| 62 } | 62 } |
| 63 | 63 |
| 64 TextDirection SelectionModifier::directionOfSelection() const { | 64 static TextDirection directionOf(const VisibleSelection& visibleSelection) { |
| 65 InlineBox* startBox = nullptr; | 65 InlineBox* startBox = nullptr; |
| 66 InlineBox* endBox = nullptr; | 66 InlineBox* endBox = nullptr; |
| 67 // Cache the VisiblePositions because visibleStart() and visibleEnd() | 67 // Cache the VisiblePositions because visibleStart() and visibleEnd() |
| 68 // can cause layout, which has the potential to invalidate lineboxes. | 68 // can cause layout, which has the potential to invalidate lineboxes. |
| 69 VisiblePosition startPosition = m_selection.visibleStart(); | 69 const VisiblePosition& startPosition = visibleSelection.visibleStart(); |
| 70 VisiblePosition endPosition = m_selection.visibleEnd(); | 70 const VisiblePosition& endPosition = visibleSelection.visibleEnd(); |
| 71 if (startPosition.isNotNull()) | 71 if (startPosition.isNotNull()) |
| 72 startBox = computeInlineBoxPosition(startPosition).inlineBox; | 72 startBox = computeInlineBoxPosition(startPosition).inlineBox; |
| 73 if (endPosition.isNotNull()) | 73 if (endPosition.isNotNull()) |
| 74 endBox = computeInlineBoxPosition(endPosition).inlineBox; | 74 endBox = computeInlineBoxPosition(endPosition).inlineBox; |
| 75 if (startBox && endBox && startBox->direction() == endBox->direction()) | 75 if (startBox && endBox && startBox->direction() == endBox->direction()) |
| 76 return startBox->direction(); | 76 return startBox->direction(); |
| 77 | 77 |
| 78 return directionOfEnclosingBlock(); | 78 return directionOfEnclosingBlock(visibleSelection.extent()); |
| 79 } | 79 } |
| 80 | 80 |
| 81 void SelectionModifier::willBeModified(EAlteration alter, | 81 TextDirection SelectionModifier::directionOfSelection() const { |
| 82 SelectionDirection direction) { | 82 return directionOf(m_selection); |
| 83 if (alter != FrameSelection::AlterationExtend) | 83 } |
| 84 return; | |
| 85 | 84 |
| 86 Position start = m_selection.start(); | 85 static bool isBaseStart(const VisibleSelection& visibleSelection, |
| 87 Position end = m_selection.end(); | 86 SelectionDirection direction) { |
| 88 | 87 if (visibleSelection.isDirectional()) { |
| 89 bool baseIsStart = true; | |
| 90 | |
| 91 if (m_selection.isDirectional()) { | |
| 92 // Make base and extent match start and end so we extend the user-visible | 88 // Make base and extent match start and end so we extend the user-visible |
| 93 // selection. This only matters for cases where base and extend point to | 89 // selection. This only matters for cases where base and extend point to |
| 94 // different positions than start and end (e.g. after a double-click to | 90 // different positions than start and end (e.g. after a double-click to |
| 95 // select a word). | 91 // select a word). |
| 96 if (m_selection.isBaseFirst()) | 92 return visibleSelection.isBaseFirst(); |
| 97 baseIsStart = true; | |
| 98 else | |
| 99 baseIsStart = false; | |
| 100 } else { | |
| 101 switch (direction) { | |
| 102 case DirectionRight: | |
| 103 if (directionOfSelection() == TextDirection::kLtr) | |
| 104 baseIsStart = true; | |
| 105 else | |
| 106 baseIsStart = false; | |
| 107 break; | |
| 108 case DirectionForward: | |
| 109 baseIsStart = true; | |
| 110 break; | |
| 111 case DirectionLeft: | |
| 112 if (directionOfSelection() == TextDirection::kLtr) | |
| 113 baseIsStart = false; | |
| 114 else | |
| 115 baseIsStart = true; | |
| 116 break; | |
| 117 case DirectionBackward: | |
| 118 baseIsStart = false; | |
| 119 break; | |
| 120 } | |
| 121 } | 93 } |
| 122 if (baseIsStart) { | 94 switch (direction) { |
| 123 m_selection.setBase(start); | 95 case DirectionRight: |
| 124 m_selection.setExtent(end); | 96 return directionOf(visibleSelection) == TextDirection::kLtr; |
| 125 } else { | 97 case DirectionForward: |
| 126 m_selection.setBase(end); | 98 return true; |
| 127 m_selection.setExtent(start); | 99 case DirectionLeft: |
| 100 return directionOf(visibleSelection) != TextDirection::kLtr; |
| 101 case DirectionBackward: |
| 102 return false; |
| 128 } | 103 } |
| 104 NOTREACHED() << "We should handle " << direction; |
| 105 return true; |
| 106 } |
| 107 |
| 108 // This function returns |SelectionInDOMTree| from start and end position of |
| 109 // |visibleSelection| with |direction| and ordering of base and extent to |
| 110 // handle base/extent don't match to start/end, e.g. granularity != character, |
| 111 // and start/end adjustment in |visibleSelection::validate()| for range |
| 112 // selection. |
| 113 static SelectionInDOMTree prepareToExtendSeelction( |
| 114 const VisibleSelection& visibleSelection, |
| 115 SelectionDirection direction) { |
| 116 if (visibleSelection.start().isNull()) |
| 117 return visibleSelection.asSelection(); |
| 118 const bool baseIsStart = isBaseStart(visibleSelection, direction); |
| 119 return SelectionInDOMTree::Builder(visibleSelection.asSelection()) |
| 120 .collapse(baseIsStart ? visibleSelection.start() : visibleSelection.end()) |
| 121 .extend(baseIsStart ? visibleSelection.end() : visibleSelection.start()) |
| 122 .build(); |
| 129 } | 123 } |
| 130 | 124 |
| 131 VisiblePosition SelectionModifier::positionForPlatform(bool isGetStart) const { | 125 VisiblePosition SelectionModifier::positionForPlatform(bool isGetStart) const { |
| 132 Settings* settings = frame() ? frame()->settings() : nullptr; | 126 Settings* settings = frame() ? frame()->settings() : nullptr; |
| 133 if (settings && settings->getEditingBehaviorType() == EditingMacBehavior) | 127 if (settings && settings->getEditingBehaviorType() == EditingMacBehavior) |
| 134 return isGetStart ? m_selection.visibleStart() : m_selection.visibleEnd(); | 128 return isGetStart ? m_selection.visibleStart() : m_selection.visibleEnd(); |
| 135 // Linux and Windows always extend selections from the extent endpoint. | 129 // Linux and Windows always extend selections from the extent endpoint. |
| 136 // FIXME: VisibleSelection should be fixed to ensure as an invariant that | 130 // FIXME: VisibleSelection should be fixed to ensure as an invariant that |
| 137 // base/extent always point to the same nodes as start/end, but which points | 131 // base/extent always point to the same nodes as start/end, but which points |
| 138 // to which depends on the value of isBaseFirst. Then this can be changed | 132 // to which depends on the value of isBaseFirst. Then this can be changed |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 selection->setExtent(newStart); | 580 selection->setExtent(newStart); |
| 587 } | 581 } |
| 588 | 582 |
| 589 bool SelectionModifier::modify(EAlteration alter, | 583 bool SelectionModifier::modify(EAlteration alter, |
| 590 SelectionDirection direction, | 584 SelectionDirection direction, |
| 591 TextGranularity granularity) { | 585 TextGranularity granularity) { |
| 592 DCHECK(!frame()->document()->needsLayoutTreeUpdate()); | 586 DCHECK(!frame()->document()->needsLayoutTreeUpdate()); |
| 593 DocumentLifecycle::DisallowTransitionScope disallowTransition( | 587 DocumentLifecycle::DisallowTransitionScope disallowTransition( |
| 594 frame()->document()->lifecycle()); | 588 frame()->document()->lifecycle()); |
| 595 | 589 |
| 596 willBeModified(alter, direction); | 590 if (alter == FrameSelection::AlterationExtend) { |
| 591 m_selection = createVisibleSelection( |
| 592 prepareToExtendSeelction(m_selection, direction)); |
| 593 } |
| 597 | 594 |
| 598 bool wasRange = m_selection.isRange(); | 595 bool wasRange = m_selection.isRange(); |
| 599 VisiblePosition originalStartPosition = m_selection.visibleStart(); | 596 VisiblePosition originalStartPosition = m_selection.visibleStart(); |
| 600 VisiblePosition position; | 597 VisiblePosition position; |
| 601 switch (direction) { | 598 switch (direction) { |
| 602 case DirectionRight: | 599 case DirectionRight: |
| 603 if (alter == FrameSelection::AlterationMove) | 600 if (alter == FrameSelection::AlterationMove) |
| 604 position = modifyMovingRight(granularity); | 601 position = modifyMovingRight(granularity); |
| 605 else | 602 else |
| 606 position = modifyExtendingRight(granularity); | 603 position = modifyExtendingRight(granularity); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 bool SelectionModifier::modifyWithPageGranularity(EAlteration alter, | 711 bool SelectionModifier::modifyWithPageGranularity(EAlteration alter, |
| 715 unsigned verticalDistance, | 712 unsigned verticalDistance, |
| 716 VerticalDirection direction) { | 713 VerticalDirection direction) { |
| 717 if (!verticalDistance) | 714 if (!verticalDistance) |
| 718 return false; | 715 return false; |
| 719 | 716 |
| 720 DCHECK(!frame()->document()->needsLayoutTreeUpdate()); | 717 DCHECK(!frame()->document()->needsLayoutTreeUpdate()); |
| 721 DocumentLifecycle::DisallowTransitionScope disallowTransition( | 718 DocumentLifecycle::DisallowTransitionScope disallowTransition( |
| 722 frame()->document()->lifecycle()); | 719 frame()->document()->lifecycle()); |
| 723 | 720 |
| 724 willBeModified(alter, direction == FrameSelection::DirectionUp | 721 if (alter == FrameSelection::AlterationExtend) { |
| 725 ? DirectionBackward | 722 m_selection = createVisibleSelection(prepareToExtendSeelction( |
| 726 : DirectionForward); | 723 m_selection, direction == FrameSelection::DirectionUp |
| 724 ? DirectionBackward |
| 725 : DirectionForward)); |
| 726 } |
| 727 | 727 |
| 728 VisiblePosition pos; | 728 VisiblePosition pos; |
| 729 LayoutUnit xPos; | 729 LayoutUnit xPos; |
| 730 switch (alter) { | 730 switch (alter) { |
| 731 case FrameSelection::AlterationMove: | 731 case FrameSelection::AlterationMove: |
| 732 pos = createVisiblePosition(direction == FrameSelection::DirectionUp | 732 pos = createVisiblePosition(direction == FrameSelection::DirectionUp |
| 733 ? m_selection.start() | 733 ? m_selection.start() |
| 734 : m_selection.end(), | 734 : m_selection.end(), |
| 735 m_selection.affinity()); | 735 m_selection.affinity()); |
| 736 xPos = lineDirectionPointForBlockDirectionNavigation( | 736 xPos = lineDirectionPointForBlockDirectionNavigation( |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 x = lineDirectionPointForBlockDirectionNavigationOf(visiblePosition); | 863 x = lineDirectionPointForBlockDirectionNavigationOf(visiblePosition); |
| 864 m_xPosForVerticalArrowNavigation = x; | 864 m_xPosForVerticalArrowNavigation = x; |
| 865 } else { | 865 } else { |
| 866 x = m_xPosForVerticalArrowNavigation; | 866 x = m_xPosForVerticalArrowNavigation; |
| 867 } | 867 } |
| 868 | 868 |
| 869 return x; | 869 return x; |
| 870 } | 870 } |
| 871 | 871 |
| 872 } // namespace blink | 872 } // namespace blink |
| OLD | NEW |