OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "config.h" |
| 6 #include "core/editing/GranularityStrategy.h" |
| 7 |
| 8 #include "core/editing/htmlediting.h" |
| 9 |
| 10 namespace blink { |
| 11 |
| 12 GranularityStrategy::GranularityStrategy() { } |
| 13 |
| 14 GranularityStrategy::~GranularityStrategy() { } |
| 15 |
| 16 CharacterGranularityStrategy::CharacterGranularityStrategy() { } |
| 17 |
| 18 CharacterGranularityStrategy::~CharacterGranularityStrategy() { } |
| 19 |
| 20 SelectionStrategy CharacterGranularityStrategy::GetType() const |
| 21 { |
| 22 return SelectionStrategy::Character; |
| 23 } |
| 24 |
| 25 void CharacterGranularityStrategy::Clear() { }; |
| 26 |
| 27 VisibleSelection CharacterGranularityStrategy::updateExtent(const VisiblePositio
n& extentPosition, const VisibleSelection& selection) |
| 28 { |
| 29 return VisibleSelection(selection.visibleBase(), extentPosition); |
| 30 } |
| 31 |
| 32 DirectionGranularityStrategy::DirectionGranularityStrategy() |
| 33 : m_granularity(CharacterGranularity) |
| 34 , m_lastMoveShrunkSelection(false) { } |
| 35 |
| 36 DirectionGranularityStrategy::~DirectionGranularityStrategy() { } |
| 37 |
| 38 SelectionStrategy DirectionGranularityStrategy::GetType() const |
| 39 { |
| 40 return SelectionStrategy::Direction; |
| 41 } |
| 42 |
| 43 void DirectionGranularityStrategy::Clear() |
| 44 { |
| 45 m_granularity = CharacterGranularity; |
| 46 m_lastMoveShrunkSelection = false; |
| 47 } |
| 48 |
| 49 VisiblePosition DirectionGranularityStrategy::nextWordBound( |
| 50 const VisiblePosition& pos, |
| 51 SearchDirection direction, |
| 52 BoundAdjust wordBoundAdjust) |
| 53 { |
| 54 bool nextBoundIfOnBound = wordBoundAdjust == BoundAdjust::NextBoundIfOnBoun
d; |
| 55 if (direction == SearchDirection::SearchForward) { |
| 56 EWordSide wordSide = nextBoundIfOnBound ? RightWordIfOnBoundary : LeftWo
rdIfOnBoundary; |
| 57 return endOfWord(pos, wordSide); |
| 58 } |
| 59 EWordSide wordSide = nextBoundIfOnBound ? LeftWordIfOnBoundary : RightWordIf
OnBoundary; |
| 60 return startOfWord(pos, wordSide); |
| 61 } |
| 62 |
| 63 VisibleSelection DirectionGranularityStrategy::updateExtent(const VisiblePositio
n& extentPosition, const VisibleSelection& selection) |
| 64 { |
| 65 if (extentPosition == selection.visibleExtent()) |
| 66 return selection; |
| 67 |
| 68 const VisiblePosition base = selection.visibleBase(); |
| 69 const VisiblePosition oldExtentWithGranularity = selection.isBaseFirst() ? s
election.visibleEnd() : selection.visibleStart(); |
| 70 |
| 71 int extentBaseOrder = comparePositions(extentPosition, base); |
| 72 int oldExtentBaseOrder = comparePositions(oldExtentWithGranularity, base); |
| 73 |
| 74 bool extentBaseOrderSwitched = (extentBaseOrder > 0 && oldExtentBaseOrder <
0) |
| 75 || (extentBaseOrder < 0 && oldExtentBaseOrder > 0); |
| 76 |
| 77 // Determine the boundary of the 'current word', i.e. the boundary extending |
| 78 // beyond which should change the granularity to WordGranularity. |
| 79 // If the last move has shrunk the selection and is now exactly on the word |
| 80 // boundary - we need to take the next bound as the bound of the "current |
| 81 // word". |
| 82 VisiblePosition currentWordBoundary = nextWordBound( |
| 83 oldExtentWithGranularity, |
| 84 oldExtentBaseOrder > 0 ? SearchDirection::SearchForward : SearchDirectio
n::SearchBackwards, |
| 85 m_lastMoveShrunkSelection ? BoundAdjust::NextBoundIfOnBound : BoundAdjus
t::CurrentPosIfOnBound); |
| 86 |
| 87 bool thisMoveShrunkSelection = (extentBaseOrder > 0 && comparePositions(exte
ntPosition, selection.visibleExtent()) < 0) |
| 88 || (extentBaseOrder < 0 && comparePositions(extentPosition, selection.vi
sibleExtent()) > 0); |
| 89 // If the extent-base order was switched, then the selection is now |
| 90 // expanding in a different direction than before. Therefore we need to |
| 91 // calculate the boundary of the 'current word' in this new direction in |
| 92 // order to be able to tell if the selection expanded beyond it. |
| 93 if (extentBaseOrderSwitched) { |
| 94 currentWordBoundary = nextWordBound( |
| 95 base, |
| 96 extentBaseOrder > 0 ? SearchDirection::SearchForward : SearchDirecti
on::SearchBackwards, |
| 97 BoundAdjust::NextBoundIfOnBound); |
| 98 m_granularity = CharacterGranularity; |
| 99 // When the base/extent order switches it doesn't count as shrinking sel
ection. |
| 100 thisMoveShrunkSelection = false; |
| 101 } |
| 102 |
| 103 bool expandedBeyondWordBoundary; |
| 104 if (extentBaseOrder > 0) |
| 105 expandedBeyondWordBoundary = comparePositions(extentPosition, currentWor
dBoundary) > 0; |
| 106 else |
| 107 expandedBeyondWordBoundary = comparePositions(extentPosition, currentWor
dBoundary) < 0; |
| 108 if (expandedBeyondWordBoundary) { |
| 109 m_granularity = WordGranularity; |
| 110 } else if (thisMoveShrunkSelection) { |
| 111 m_granularity = CharacterGranularity; |
| 112 m_lastMoveShrunkSelection = true; |
| 113 } |
| 114 |
| 115 m_lastMoveShrunkSelection = thisMoveShrunkSelection; |
| 116 VisibleSelection newSelection = selection; |
| 117 newSelection.setExtent(extentPosition); |
| 118 if (m_granularity == WordGranularity) { |
| 119 if (extentBaseOrder > 0) |
| 120 newSelection.setEndRespectingGranularity(m_granularity, LeftWordIfOn
Boundary); |
| 121 else |
| 122 newSelection.setStartRespectingGranularity(m_granularity, RightWordI
fOnBoundary); |
| 123 } |
| 124 |
| 125 return newSelection; |
| 126 } |
| 127 |
| 128 } // namespace blink |
OLD | NEW |