Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: Source/core/editing/GranularityStrategy.cpp

Issue 1123563003: Improving direction-based selection strategy. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/editing/GranularityStrategy.h ('k') | Source/core/editing/VisibleSelection.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/editing/GranularityStrategy.h" 6 #include "core/editing/GranularityStrategy.h"
7 7
8 #include "core/editing/FrameSelection.h"
8 #include "core/editing/htmlediting.h" 9 #include "core/editing/htmlediting.h"
10 #include "core/layout/HitTestRequest.h"
11 #include "core/layout/HitTestResult.h"
12 #include "core/layout/LayoutView.h"
13 #include "core/paint/DeprecatedPaintLayer.h"
14
9 15
10 namespace blink { 16 namespace blink {
17 namespace {
18
19 VisiblePosition visiblePositionForFramePoint(const IntPoint& framePoint, LocalFr ame* frame)
20 {
21 HitTestRequest request = HitTestRequest::Move | HitTestRequest::ReadOnly | H itTestRequest::Active | HitTestRequest::IgnoreClipping;
22 HitTestResult result(request, framePoint);
23 frame->document()->layoutView()->layer()->hitTest(result);
24
25 if (Node* node = result.innerNode())
26 return frame->selection().selection().visiblePositionRespectingEditingBo undary(result.localPoint(), node);
27 return VisiblePosition();
28 }
29 }
11 30
12 GranularityStrategy::GranularityStrategy() { } 31 GranularityStrategy::GranularityStrategy() { }
13 32
14 GranularityStrategy::~GranularityStrategy() { } 33 GranularityStrategy::~GranularityStrategy() { }
15 34
16 CharacterGranularityStrategy::CharacterGranularityStrategy() { } 35 CharacterGranularityStrategy::CharacterGranularityStrategy() { }
17 36
18 CharacterGranularityStrategy::~CharacterGranularityStrategy() { } 37 CharacterGranularityStrategy::~CharacterGranularityStrategy() { }
19 38
20 SelectionStrategy CharacterGranularityStrategy::GetType() const 39 SelectionStrategy CharacterGranularityStrategy::GetType() const
21 { 40 {
22 return SelectionStrategy::Character; 41 return SelectionStrategy::Character;
23 } 42 }
24 43
25 void CharacterGranularityStrategy::Clear() { }; 44 void CharacterGranularityStrategy::Clear() { };
26 45
27 VisibleSelection CharacterGranularityStrategy::updateExtent(const VisiblePositio n& extentPosition, const VisibleSelection& selection) 46 VisibleSelection CharacterGranularityStrategy::updateExtent(const IntPoint& fram ePoint, LocalFrame* frame)
28 { 47 {
48 const VisiblePosition& extentPosition = visiblePositionForFramePoint(framePo int, frame);
49 const VisibleSelection& selection = frame->selection().selection();
50 if (selection.visibleBase() == extentPosition)
51 return selection;
29 return VisibleSelection(selection.visibleBase(), extentPosition); 52 return VisibleSelection(selection.visibleBase(), extentPosition);
30 } 53 }
31 54
32 DirectionGranularityStrategy::DirectionGranularityStrategy() 55 DirectionGranularityStrategy::DirectionGranularityStrategy()
33 : m_granularity(CharacterGranularity) 56 : m_granularity(CharacterGranularity)
34 , m_lastMoveShrunkSelection(false) { } 57 , m_lastMoveShrunkSelection(false)
58 , m_offset(0) { }
35 59
36 DirectionGranularityStrategy::~DirectionGranularityStrategy() { } 60 DirectionGranularityStrategy::~DirectionGranularityStrategy() { }
37 61
38 SelectionStrategy DirectionGranularityStrategy::GetType() const 62 SelectionStrategy DirectionGranularityStrategy::GetType() const
39 { 63 {
40 return SelectionStrategy::Direction; 64 return SelectionStrategy::Direction;
41 } 65 }
42 66
43 void DirectionGranularityStrategy::Clear() 67 void DirectionGranularityStrategy::Clear()
44 { 68 {
45 m_granularity = CharacterGranularity; 69 m_granularity = CharacterGranularity;
46 m_lastMoveShrunkSelection = false; 70 m_lastMoveShrunkSelection = false;
71 m_offset = 0;
47 } 72 }
48 73
49 VisiblePosition DirectionGranularityStrategy::nextWordBound( 74 VisiblePosition DirectionGranularityStrategy::nextWordBound(
50 const VisiblePosition& pos, 75 const VisiblePosition& pos,
51 SearchDirection direction, 76 SearchDirection direction,
52 BoundAdjust wordBoundAdjust) 77 BoundAdjust wordBoundAdjust)
53 { 78 {
54 bool nextBoundIfOnBound = wordBoundAdjust == BoundAdjust::NextBoundIfOnBoun d; 79 bool nextBoundIfOnBound = wordBoundAdjust == BoundAdjust::NextBoundIfOnBoun d;
55 if (direction == SearchDirection::SearchForward) { 80 if (direction == SearchDirection::SearchForward) {
56 EWordSide wordSide = nextBoundIfOnBound ? RightWordIfOnBoundary : LeftWo rdIfOnBoundary; 81 EWordSide wordSide = nextBoundIfOnBound ? RightWordIfOnBoundary : LeftWo rdIfOnBoundary;
57 return endOfWord(pos, wordSide); 82 return endOfWord(pos, wordSide);
58 } 83 }
59 EWordSide wordSide = nextBoundIfOnBound ? LeftWordIfOnBoundary : RightWordIf OnBoundary; 84 EWordSide wordSide = nextBoundIfOnBound ? LeftWordIfOnBoundary : RightWordIf OnBoundary;
60 return startOfWord(pos, wordSide); 85 return startOfWord(pos, wordSide);
61 } 86 }
62 87
63 VisibleSelection DirectionGranularityStrategy::updateExtent(const VisiblePositio n& extentPosition, const VisibleSelection& selection) 88 VisibleSelection DirectionGranularityStrategy::updateExtent(const IntPoint& exte ntPoint, LocalFrame* frame)
64 { 89 {
65 if (extentPosition == selection.visibleExtent()) 90 // Apply the offset if needed
91 IntPoint offsetExtentPoint = extentPoint;
92 if (m_offset != 0) {
93 int dx = extentPoint.x() - m_extentPoint.x();
94 if (m_offset > 0 && dx > 0)
95 m_offset = std::max(0, m_offset - dx);
96 else if (m_offset < 0 && dx < 0)
97 m_offset = std::min(0, m_offset - dx);
98 offsetExtentPoint.move(m_offset, 0);
99 }
100 m_extentPoint = extentPoint;
101
102 VisiblePosition extentPosition = visiblePositionForFramePoint(offsetExtentPo int, frame);
103 const VisibleSelection& selection = frame->selection().selection();
104
105 if (selection.visibleBase() == extentPosition || extentPosition == selection .visibleExtent())
66 return selection; 106 return selection;
67 107
68 const VisiblePosition base = selection.visibleBase(); 108 const VisiblePosition base = selection.visibleBase();
69 const VisiblePosition oldExtentWithGranularity = selection.isBaseFirst() ? s election.visibleEnd() : selection.visibleStart(); 109 const VisiblePosition oldExtentWithGranularity = selection.isBaseFirst() ? s election.visibleEnd() : selection.visibleStart();
70 110
71 int extentBaseOrder = comparePositions(extentPosition, base); 111 int extentBaseOrder = comparePositions(extentPosition, base);
72 int oldExtentBaseOrder = comparePositions(oldExtentWithGranularity, base); 112 int oldExtentBaseOrder = comparePositions(oldExtentWithGranularity, base);
73 113
74 bool extentBaseOrderSwitched = (extentBaseOrder > 0 && oldExtentBaseOrder < 0) 114 bool extentBaseOrderSwitched = (extentBaseOrder > 0 && oldExtentBaseOrder < 0)
75 || (extentBaseOrder < 0 && oldExtentBaseOrder > 0); 115 || (extentBaseOrder < 0 && oldExtentBaseOrder > 0);
(...skipping 25 matching lines...) Expand all
101 } 141 }
102 142
103 bool expandedBeyondWordBoundary; 143 bool expandedBeyondWordBoundary;
104 if (extentBaseOrder > 0) 144 if (extentBaseOrder > 0)
105 expandedBeyondWordBoundary = comparePositions(extentPosition, currentWor dBoundary) > 0; 145 expandedBeyondWordBoundary = comparePositions(extentPosition, currentWor dBoundary) > 0;
106 else 146 else
107 expandedBeyondWordBoundary = comparePositions(extentPosition, currentWor dBoundary) < 0; 147 expandedBeyondWordBoundary = comparePositions(extentPosition, currentWor dBoundary) < 0;
108 if (expandedBeyondWordBoundary) { 148 if (expandedBeyondWordBoundary) {
109 m_granularity = WordGranularity; 149 m_granularity = WordGranularity;
110 } else if (thisMoveShrunkSelection) { 150 } else if (thisMoveShrunkSelection) {
151 // If the offset is 0, we may need to update it and apply the offset to the extent.
152 if (m_offset == 0) {
153 if (extentBaseOrder > 0) {
154 if (selection.end() != selection.extent())
155 m_offset = selection.visibleEnd().absoluteCaretBounds().x() - selection.visibleExtent().absoluteCaretBounds().x();
156 } else {
157 if (selection.start() != selection.extent())
158 m_offset = selection.visibleStart().absoluteCaretBounds().x( ) - selection.visibleExtent().absoluteCaretBounds().x();
159 }
160 if (m_offset != 0) {
161 offsetExtentPoint.move(m_offset, 0);
162 extentPosition = visiblePositionForFramePoint(offsetExtentPoint, frame);
163 }
164 }
111 m_granularity = CharacterGranularity; 165 m_granularity = CharacterGranularity;
112 m_lastMoveShrunkSelection = true; 166 m_lastMoveShrunkSelection = true;
113 } 167 }
114 168
115 m_lastMoveShrunkSelection = thisMoveShrunkSelection; 169 m_lastMoveShrunkSelection = thisMoveShrunkSelection;
116 VisibleSelection newSelection = selection; 170 VisibleSelection newSelection = selection;
117 newSelection.setExtent(extentPosition); 171
118 if (m_granularity == WordGranularity) { 172 if (m_granularity == CharacterGranularity) {
119 if (extentBaseOrder > 0) 173 newSelection.setExtent(extentPosition);
174 } else {
175 // Need to adjust extent by one position for the purposes of setting the
176 // selection if the length of the current word is greater than 3.
177 // This is so that the selection only expands to the end of the word whe n
178 // the extent moves beyond the first character for words that are more
179 // than 3 characters long.
180 bool adjustExtent = false;
181 Position boundBeforeExtent = nextWordBound(extentPosition, SearchDirecti on::SearchBackwards, BoundAdjust::CurrentPosIfOnBound).deepEquivalent();
182 if (boundBeforeExtent != extentPosition.deepEquivalent()) {
183 Position boundAfterExtent = nextWordBound(extentPosition, SearchDire ction::SearchForward, BoundAdjust::CurrentPosIfOnBound).deepEquivalent();
184 int wordLength = boundAfterExtent.offsetInContainerNode() - boundBef oreExtent.offsetInContainerNode();
185 adjustExtent = wordLength > 3;
186 }
187
188 if (extentBaseOrder > 0) {
189 newSelection.setExtent(adjustExtent ? extentPosition.previous() : ex tentPosition);
120 newSelection.setEndRespectingGranularity(m_granularity, LeftWordIfOn Boundary); 190 newSelection.setEndRespectingGranularity(m_granularity, LeftWordIfOn Boundary);
121 else 191 } else {
192 newSelection.setExtent(adjustExtent ? extentPosition.next() : extent Position);
122 newSelection.setStartRespectingGranularity(m_granularity, RightWordI fOnBoundary); 193 newSelection.setStartRespectingGranularity(m_granularity, RightWordI fOnBoundary);
194 }
195 newSelection.setWithoutValidation(newSelection.base(), extentPosition.de epEquivalent(), newSelection.start(), newSelection.end());
mfomitchev 2015/05/01 23:31:51 Note we actually only need to set the extent witho
123 } 196 }
124 197
125 return newSelection; 198 return newSelection;
126 } 199 }
127 200
128 } // namespace blink 201 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/editing/GranularityStrategy.h ('k') | Source/core/editing/VisibleSelection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698