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

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

Issue 1195213002: Clean up the SelectionControl class with c++11 enum class (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 6 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
5 * Copyright (C) 2015 Google Inc. All rights reserved. 5 * Copyright (C) 2015 Google Inc. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
(...skipping 28 matching lines...) Expand all
39 #include "core/events/Event.h" 39 #include "core/events/Event.h"
40 #include "core/frame/FrameView.h" 40 #include "core/frame/FrameView.h"
41 #include "core/frame/LocalFrame.h" 41 #include "core/frame/LocalFrame.h"
42 #include "core/frame/Settings.h" 42 #include "core/frame/Settings.h"
43 #include "core/layout/LayoutView.h" 43 #include "core/layout/LayoutView.h"
44 #include "core/page/FocusController.h" 44 #include "core/page/FocusController.h"
45 #include "core/page/Page.h" 45 #include "core/page/Page.h"
46 #include "platform/RuntimeEnabledFeatures.h" 46 #include "platform/RuntimeEnabledFeatures.h"
47 47
48 namespace blink { 48 namespace blink {
49 PassOwnPtrWillBeRawPtr<SelectionController> SelectionController::create(LocalFra me& frame) 49
50 namespace {
51
52 void setSelectionIfNeeded(FrameSelection& selection, const VisibleSelection& new Selection)
50 { 53 {
51 return adoptPtrWillBeNoop(new SelectionController(frame)); 54 if (selection.selection() == newSelection)
55 return;
56 selection.setSelection(newSelection);
52 } 57 }
53 58
54 SelectionController::SelectionController(LocalFrame& frame) 59 bool dispatchSelectStart(Node* node)
55 : m_frame(&frame)
56 , m_mouseDownMayStartSelect(false)
57 , m_mouseDownWasSingleClickInSelection(false)
58 , m_selectionInitiationState(HaveNotStartedSelection)
59 {
60 }
61
62 DEFINE_TRACE(SelectionController)
63 {
64 visitor->trace(m_frame);
65 }
66
67 static void setSelectionIfNeeded(FrameSelection& selection, const VisibleSelecti on& newSelection)
68 {
69 if (selection.selection() != newSelection)
70 selection.setSelection(newSelection);
71 }
72
73 static inline bool dispatchSelectStart(Node* node)
74 { 60 {
75 if (!node || !node->layoutObject()) 61 if (!node || !node->layoutObject())
76 return true; 62 return true;
77 63
78 return node->dispatchEvent(Event::createCancelableBubble(EventTypeNames::sel ectstart)); 64 return node->dispatchEvent(Event::createCancelableBubble(EventTypeNames::sel ectstart));
79 } 65 }
80 66
81 template <typename Strategy> 67 template <typename Strategy>
82 VisibleSelection expandSelectionToRespectUserSelectAllAlgorithm(Node* targetNode , const VisibleSelection& selection) 68 VisibleSelection expandSelectionToRespectUserSelectAllAlgorithm(Node* targetNode , const VisibleSelection& selection)
83 { 69 {
84 using PositionType = typename Strategy::PositionType; 70 using PositionType = typename Strategy::PositionType;
85 71
86 Node* rootUserSelectAll = PositionType::rootUserSelectAllForNode(targetNode) ; 72 Node* rootUserSelectAll = PositionType::rootUserSelectAllForNode(targetNode) ;
87 if (!rootUserSelectAll) 73 if (!rootUserSelectAll)
88 return selection; 74 return selection;
89 75
90 VisibleSelection newSelection(selection); 76 VisibleSelection newSelection(selection);
91 newSelection.setBase(PositionType::beforeNode(rootUserSelectAll).upstream(Ca nCrossEditingBoundary)); 77 newSelection.setBase(PositionType::beforeNode(rootUserSelectAll).upstream(Ca nCrossEditingBoundary));
92 newSelection.setExtent(PositionType::afterNode(rootUserSelectAll).downstream (CanCrossEditingBoundary)); 78 newSelection.setExtent(PositionType::afterNode(rootUserSelectAll).downstream (CanCrossEditingBoundary));
93 79
94 return newSelection; 80 return newSelection;
95 } 81 }
96 82
97 static VisibleSelection expandSelectionToRespectUserSelectAll(Node* targetNode, const VisibleSelection& selection) 83 VisibleSelection expandSelectionToRespectUserSelectAll(Node* targetNode, const V isibleSelection& selection)
98 { 84 {
99 return expandSelectionToRespectUserSelectAllAlgorithm<VisibleSelection::InDO MTree>(targetNode, selection); 85 return expandSelectionToRespectUserSelectAllAlgorithm<VisibleSelection::InDO MTree>(targetNode, selection);
100 } 86 }
101 87
102 static bool expandSelectionUsingGranularity(VisibleSelection& selection, TextGra nularity granularity) 88 bool expandSelectionUsingGranularity(VisibleSelection& selection, TextGranularit y granularity)
103 { 89 {
104 return selection.expandUsingGranularity(granularity); 90 return selection.expandUsingGranularity(granularity);
105 } 91 }
106 92
107 bool SelectionController::updateSelectionForMouseDownDispatchingSelectStart(Node * targetNode, const VisibleSelection& selection, TextGranularity granularity) 93 int textDistance(const Position& start, const Position& end)
yosin_UTC9 2015/06/22 05:31:11 textDistance() is also templatized in ToT. Could y
Miyoung Shin(c) 2015/06/24 07:43:27 Ok.
108 { 94 {
109 if (Position::nodeIsUserSelectNone(targetNode)) 95 return TextIterator::rangeLength(start, end, true);
96 }
97
98 bool canMouseDownStartSelect(Node* node)
99 {
100 if (!node || !node->layoutObject())
101 return true;
102
103 if (!node->canStartSelection())
110 return false; 104 return false;
111 105
112 if (!dispatchSelectStart(targetNode))
113 return false;
114
115 if (selection.isRange()) {
116 m_selectionInitiationState = ExtendedSelection;
117 } else {
118 granularity = CharacterGranularity;
119 m_selectionInitiationState = PlacedCaret;
120 }
121
122 m_frame->selection().setNonDirectionalSelectionIfNeeded(selection, granulari ty);
123
124 return true; 106 return true;
125 } 107 }
126 108
127 void SelectionController::selectClosestWordFromHitTestResult(const HitTestResult & result, AppendTrailingWhitespace appendTrailingWhitespace) 109 } // namespace
128 {
129 Node* innerNode = result.innerNode();
130 VisibleSelection newSelection;
131
132 if (innerNode && innerNode->layoutObject()) {
133 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.l ocalPoint()));
134 if (pos.isNotNull()) {
135 newSelection = VisibleSelection(pos);
136 expandSelectionUsingGranularity(newSelection, WordGranularity);
137 }
138
139 if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSel ection.isRange())
140 newSelection.appendTrailingWhitespace();
141
142 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelec tionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
143 }
144 }
145
146 void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTes tResult& result, AppendTrailingWhitespace appendTrailingWhitespace)
147 {
148 Node* innerNode = result.innerNode();
149 VisibleSelection newSelection;
150
151 if (innerNode && innerNode->layoutObject()) {
152 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.l ocalPoint()));
153 Position start = pos.deepEquivalent();
154 Position end = pos.deepEquivalent();
155 if (pos.isNotNull()) {
156 DocumentMarkerVector markers = innerNode->document().markers().marke rsInRange(makeRange(pos, pos).get(), DocumentMarker::MisspellingMarkers());
157 if (markers.size() == 1) {
158 start.moveToOffset(markers[0]->startOffset());
159 end.moveToOffset(markers[0]->endOffset());
160 newSelection = VisibleSelection(start, end);
161 }
162 }
163
164 if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSel ection.isRange())
165 newSelection.appendTrailingWhitespace();
166
167 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelec tionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
168 }
169 }
170
171 void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHi tTestResults& result)
172 {
173 if (m_mouseDownMayStartSelect) {
174 selectClosestWordFromHitTestResult(result.hitTestResult(),
175 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrail ingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhi tespace);
176 }
177 }
178
179 void SelectionController::selectClosestMisspellingFromMouseEvent(const MouseEven tWithHitTestResults& result)
180 {
181 if (m_mouseDownMayStartSelect) {
182 selectClosestMisspellingFromHitTestResult(result.hitTestResult(),
183 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrail ingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhi tespace);
184 }
185 }
186
187 void SelectionController::selectClosestWordOrLinkFromMouseEvent(const MouseEvent WithHitTestResults& result)
188 {
189 if (!result.hitTestResult().isLiveLink())
190 return selectClosestWordFromMouseEvent(result);
191
192 Node* innerNode = result.innerNode();
193
194 if (innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect) {
195 VisibleSelection newSelection;
196 Element* URLElement = result.hitTestResult().URLElement();
197 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.l ocalPoint()));
198 if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescenda ntOf(URLElement))
199 newSelection = VisibleSelection::selectionFromContentsOfNode(URLElem ent);
200
201 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelec tionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
202 }
203 }
204
205 bool SelectionController::handleMousePressEventDoubleClick(const MouseEventWithH itTestResults& event)
206 {
207 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventDoubleClick ");
208
209 if (event.event().button() != LeftButton)
210 return false;
211
212 if (m_frame->selection().isRange()) {
213 // A double-click when range is already selected
214 // should not change the selection. So, do not call
215 // selectClosestWordFromMouseEvent, but do set
216 // m_beganSelectingText to prevent handleMouseReleaseEvent
217 // from setting caret selection.
218 m_selectionInitiationState = ExtendedSelection;
219 } else {
220 selectClosestWordFromMouseEvent(event);
221 }
222 return true;
223 }
224
225 bool SelectionController::handleMousePressEventTripleClick(const MouseEventWithH itTestResults& event)
226 {
227 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventTripleClick ");
228
229 if (event.event().button() != LeftButton)
230 return false;
231
232 Node* innerNode = event.innerNode();
233 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect))
234 return false;
235
236 VisibleSelection newSelection;
237 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(event.localP oint()));
238 if (pos.isNotNull()) {
239 newSelection = VisibleSelection(pos);
240 expandSelectionUsingGranularity(newSelection, ParagraphGranularity);
241 }
242
243 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity);
244 }
245
246 static int textDistance(const Position& start, const Position& end)
247 {
248 return TextIterator::rangeLength(start, end, true);
249 }
250
251 bool SelectionController::handleMousePressEventSingleClick(const MouseEventWithH itTestResults& event)
252 {
253 return handleMousePressEventSingleClickAlgorithm<VisibleSelection::InDOMTree >(event);
254 }
255 110
256 template <typename Strategy> 111 template <typename Strategy>
257 bool SelectionController::handleMousePressEventSingleClickAlgorithm(const MouseE ventWithHitTestResults& event) 112 bool SelectionController::handleMousePressEventSingleClickAlgorithm(const MouseE ventWithHitTestResults& event)
258 { 113 {
259 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventSingleClick "); 114 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventSingleClick ");
260 using PositionType = typename Strategy::PositionType; 115 using PositionType = typename Strategy::PositionType;
261 116
262 m_frame->document()->updateLayoutIgnorePendingStylesheets(); 117 m_frame->document()->updateLayoutIgnorePendingStylesheets();
263 Node* innerNode = event.innerNode(); 118 Node* innerNode = event.innerNode();
264 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) 119 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect))
265 return false; 120 return false;
266 121
267 // Extend the selection if the Shift key is down, unless the click is in a l ink. 122 // Extend the selection if the Shift key is down, unless the click is in a l ink.
268 bool extendSelection = event.event().shiftKey() && !event.isOverLink(); 123 bool extendSelection = event.event().shiftKey() && !event.isOverLink();
269 124
270 // Don't restart the selection when the mouse is pressed on an 125 // Don't restart the selection when the mouse is pressed on an
271 // existing selection so we can allow for text dragging. 126 // existing selection so we can allow for text dragging.
272 if (FrameView* view = m_frame->view()) { 127 if (FrameView* view = m_frame->view()) {
273 LayoutPoint vPoint = view->rootFrameToContents(event.event().position()) ; 128 LayoutPoint vPoint = view->rootFrameToContents(event.event().position()) ;
274 if (!extendSelection && m_frame->selection().contains(vPoint)) { 129 if (!extendSelection && selection().contains(vPoint)) {
275 m_mouseDownWasSingleClickInSelection = true; 130 m_mouseDownWasSingleClickInSelection = true;
276 return false; 131 return false;
277 } 132 }
278 } 133 }
279 134
280 VisiblePosition visiblePos(innerNode->layoutObject()->positionForPoint(event .localPoint())); 135 VisiblePosition visiblePos(innerNode->layoutObject()->positionForPoint(event .localPoint()));
281 if (visiblePos.isNull()) 136 if (visiblePos.isNull())
282 visiblePos = VisiblePosition(firstPositionInOrBeforeNode(innerNode), DOW NSTREAM); 137 visiblePos = VisiblePosition(firstPositionInOrBeforeNode(innerNode), DOW NSTREAM);
283 PositionType pos = Strategy::toPositionType(visiblePos.deepEquivalent()); 138 PositionType pos = Strategy::toPositionType(visiblePos.deepEquivalent());
284 139
285 VisibleSelection newSelection = m_frame->selection().selection(); 140 VisibleSelection newSelection = selection().selection();
286 TextGranularity granularity = CharacterGranularity; 141 TextGranularity granularity = CharacterGranularity;
287 142
288 if (extendSelection && newSelection.isCaretOrRange()) { 143 if (extendSelection && newSelection.isCaretOrRange()) {
289 VisibleSelection selectionInUserSelectAll(expandSelectionToRespectUserSe lectAll(innerNode, VisibleSelection(VisiblePosition(pos)))); 144 VisibleSelection selectionInUserSelectAll(expandSelectionToRespectUserSe lectAll(innerNode, VisibleSelection(VisiblePosition(pos))));
290 if (selectionInUserSelectAll.isRange()) { 145 if (selectionInUserSelectAll.isRange()) {
291 if (Strategy::selectionStart(selectionInUserSelectAll).compareTo(Str ategy::selectionStart(newSelection)) < 0) 146 if (Strategy::selectionStart(selectionInUserSelectAll).compareTo(Str ategy::selectionStart(newSelection)) < 0)
292 pos = Strategy::selectionStart(selectionInUserSelectAll); 147 pos = Strategy::selectionStart(selectionInUserSelectAll);
293 else if (Strategy::selectionEnd(newSelection).compareTo(Strategy::se lectionEnd(selectionInUserSelectAll)) < 0) 148 else if (Strategy::selectionEnd(newSelection).compareTo(Strategy::se lectionEnd(selectionInUserSelectAll)) < 0)
294 pos = Strategy::selectionEnd(selectionInUserSelectAll); 149 pos = Strategy::selectionEnd(selectionInUserSelectAll);
295 } 150 }
296 151
297 if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional() ) { 152 if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional() ) {
298 if (pos.isNotNull()) { 153 if (pos.isNotNull()) {
299 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click d eselects when selection 154 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click d eselects when selection
300 // was created right-to-left 155 // was created right-to-left
301 PositionType start = Strategy::selectionStart(newSelection); 156 PositionType start = Strategy::selectionStart(newSelection);
302 PositionType end = Strategy::selectionEnd(newSelection); 157 PositionType end = Strategy::selectionEnd(newSelection);
303 int distanceToStart = textDistance(start, pos); 158 int distanceToStart = textDistance(start, pos);
304 int distanceToEnd = textDistance(pos, end); 159 int distanceToEnd = textDistance(pos, end);
305 if (distanceToStart <= distanceToEnd) 160 if (distanceToStart <= distanceToEnd)
306 newSelection = VisibleSelection(end, pos); 161 newSelection = VisibleSelection(end, pos);
307 else 162 else
308 newSelection = VisibleSelection(start, pos); 163 newSelection = VisibleSelection(start, pos);
309 } 164 }
310 } else { 165 } else {
311 newSelection.setExtent(pos); 166 newSelection.setExtent(pos);
312 } 167 }
313 168
314 if (m_frame->selection().granularity() != CharacterGranularity) { 169 if (selection().granularity() != CharacterGranularity) {
315 granularity = m_frame->selection().granularity(); 170 granularity = selection().granularity();
316 expandSelectionUsingGranularity(newSelection, m_frame->selection().g ranularity()); 171 expandSelectionUsingGranularity(newSelection, selection().granularit y());
317 } 172 }
318 } else { 173 } else {
319 newSelection = expandSelectionToRespectUserSelectAll(innerNode, VisibleS election(visiblePos)); 174 newSelection = expandSelectionToRespectUserSelectAll(innerNode, VisibleS election(visiblePos));
320 } 175 }
321 176
322 // Updating the selection is considered side-effect of the event and so it d oesn't impact the handled state. 177 // Updating the selection is considered side-effect of the event and so it d oesn't impact the handled state.
323 updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, g ranularity); 178 updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, g ranularity);
324 return false; 179 return false;
325 } 180 }
326 181
327 static inline bool canMouseDownStartSelect(Node* node)
328 {
329 if (!node || !node->layoutObject())
330 return true;
331
332 if (!node->canStartSelection())
333 return false;
334
335 return true;
336 }
337
338 void SelectionController::handleMousePressEvent(const MouseEventWithHitTestResul ts& event)
339 {
340 // If we got the event back, that must mean it wasn't prevented,
341 // so it's allowed to start a drag or selection if it wasn't in a scrollbar.
342 m_mouseDownMayStartSelect = canMouseDownStartSelect(event.innerNode()) && !e vent.scrollbar();
343 m_mouseDownWasSingleClickInSelection = false;
344 }
345
346 void SelectionController::handleMouseDraggedEvent(const MouseEventWithHitTestRes ults& event, const IntPoint& mouseDownPos, const LayoutPoint& dragStartPos, Node * mousePressNode, const IntPoint& lastKnownMousePosition)
347 {
348 if (m_selectionInitiationState != ExtendedSelection) {
349 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active );
350 HitTestResult result(request, mouseDownPos);
351 m_frame->document()->layoutView()->hitTest(result);
352
353 updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKn ownMousePosition);
354 }
355 updateSelectionForMouseDrag(event.hitTestResult(), mousePressNode, dragStart Pos, lastKnownMousePosition);
356 }
357
358 void SelectionController::updateSelectionForMouseDrag(Node* mousePressNode, cons t LayoutPoint& dragStartPos, const IntPoint& lastKnownMousePosition)
359 {
360 FrameView* view = m_frame->view();
361 if (!view)
362 return;
363 LayoutView* layoutObject = m_frame->contentLayoutObject();
364 if (!layoutObject)
365 return;
366
367 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | H itTestRequest::Move);
368 HitTestResult result(request, view->rootFrameToContents(lastKnownMousePositi on));
369 layoutObject->hitTest(result);
370 updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKnownM ousePosition);
371 }
372
373 void SelectionController::updateSelectionForMouseDrag(const HitTestResult& hitTe stResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint& lastKnownMousePosition)
374 {
375 updateSelectionForMouseDragAlgorithm<VisibleSelection::InDOMTree>(hitTestRes ult, mousePressNode, dragStartPos, lastKnownMousePosition);
376 }
377
378 template <typename Strategy> 182 template <typename Strategy>
379 void SelectionController::updateSelectionForMouseDragAlgorithm(const HitTestResu lt& hitTestResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint& lastKnownMousePosition) 183 void SelectionController::updateSelectionForMouseDragAlgorithm(const HitTestResu lt& hitTestResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint& lastKnownMousePosition)
380 { 184 {
381 using PositionType = typename Strategy::PositionType; 185 using PositionType = typename Strategy::PositionType;
382 186
383 if (!m_mouseDownMayStartSelect) 187 if (!m_mouseDownMayStartSelect)
384 return; 188 return;
385 189
386 Node* target = hitTestResult.innerNode(); 190 Node* target = hitTestResult.innerNode();
387 if (!target) 191 if (!target)
388 return; 192 return;
389 193
390 VisiblePosition targetPosition = m_frame->selection().selection().visiblePos itionRespectingEditingBoundary(hitTestResult.localPoint(), target); 194 VisiblePosition targetPosition = selection().selection().visiblePositionResp ectingEditingBoundary(hitTestResult.localPoint(), target);
391 // Don't modify the selection if we're not on a node. 195 // Don't modify the selection if we're not on a node.
392 if (targetPosition.isNull()) 196 if (targetPosition.isNull())
393 return; 197 return;
394 198
395 // Restart the selection if this is the first mouse move. This work is usual ly 199 // Restart the selection if this is the first mouse move. This work is usual ly
396 // done in handleMousePressEvent, but not if the mouse press was on an exist ing selection. 200 // done in handleMousePressEvent, but not if the mouse press was on an exist ing selection.
397 VisibleSelection newSelection = m_frame->selection().selection(); 201 VisibleSelection newSelection = selection().selection();
398 202
399 // Special case to limit selection to the containing block for SVG text. 203 // Special case to limit selection to the containing block for SVG text.
400 // FIXME: Isn't there a better non-SVG-specific way to do this? 204 // FIXME: Isn't there a better non-SVG-specific way to do this?
401 if (Node* selectionBaseNode = Strategy::selectionBase(newSelection).deprecat edNode()) { 205 if (Node* selectionBaseNode = Strategy::selectionBase(newSelection).deprecat edNode()) {
402 if (LayoutObject* selectionBaseLayoutObject = selectionBaseNode->layoutO bject()) { 206 if (LayoutObject* selectionBaseLayoutObject = selectionBaseNode->layoutO bject()) {
403 if (selectionBaseLayoutObject->isSVGText()) { 207 if (selectionBaseLayoutObject->isSVGText()) {
404 if (target->layoutObject()->containingBlock() != selectionBaseLa youtObject->containingBlock()) 208 if (target->layoutObject()->containingBlock() != selectionBaseLa youtObject->containingBlock())
405 return; 209 return;
406 } 210 }
407 } 211 }
408 } 212 }
409 213
410 if (m_selectionInitiationState == HaveNotStartedSelection && !dispatchSelect Start(target)) 214 if (m_selectionState == SelectionState::HaveNotStartedSelection && !dispatch SelectStart(target))
411 return; 215 return;
412 216
413 if (m_selectionInitiationState != ExtendedSelection) { 217 if (m_selectionState != SelectionState::ExtendedSelection) {
414 // Always extend selection here because it's caused by a mouse drag 218 // Always extend selection here because it's caused by a mouse drag
415 m_selectionInitiationState = ExtendedSelection; 219 m_selectionState = SelectionState::ExtendedSelection;
416 newSelection = VisibleSelection(targetPosition); 220 newSelection = VisibleSelection(targetPosition);
417 } 221 }
418 222
419 if (RuntimeEnabledFeatures::userSelectAllEnabled()) { 223 if (RuntimeEnabledFeatures::userSelectAllEnabled()) {
420 Node* rootUserSelectAllForMousePressNode = Position::rootUserSelectAllFo rNode(mousePressNode); 224 Node* rootUserSelectAllForMousePressNode = Position::rootUserSelectAllFo rNode(mousePressNode);
421 if (rootUserSelectAllForMousePressNode && rootUserSelectAllForMousePress Node == Position::rootUserSelectAllForNode(target)) { 225 if (rootUserSelectAllForMousePressNode && rootUserSelectAllForMousePress Node == Position::rootUserSelectAllForNode(target)) {
422 newSelection.setBase(PositionType::beforeNode(rootUserSelectAllForMo usePressNode).upstream(CanCrossEditingBoundary)); 226 newSelection.setBase(PositionType::beforeNode(rootUserSelectAllForMo usePressNode).upstream(CanCrossEditingBoundary));
423 newSelection.setExtent(PositionType::afterNode(rootUserSelectAllForM ousePressNode).downstream(CanCrossEditingBoundary)); 227 newSelection.setExtent(PositionType::afterNode(rootUserSelectAllForM ousePressNode).downstream(CanCrossEditingBoundary));
424 } else { 228 } else {
425 // Reset base for user select all when base is inside user-select-al l area and extent < base. 229 // Reset base for user select all when base is inside user-select-al l area and extent < base.
426 if (rootUserSelectAllForMousePressNode) { 230 if (rootUserSelectAllForMousePressNode) {
427 PositionType eventPosition = Strategy::toPositionType(target->la youtObject()->positionForPoint(hitTestResult.localPoint()).position()); 231 PositionType eventPosition = Strategy::toPositionType(target->la youtObject()->positionForPoint(hitTestResult.localPoint()).position());
428 PositionType dragStartPosition = Strategy::toPositionType(mouseP ressNode->layoutObject()->positionForPoint(dragStartPos).position()); 232 PositionType dragStartPosition = Strategy::toPositionType(mouseP ressNode->layoutObject()->positionForPoint(dragStartPos).position());
429 if (eventPosition.compareTo(dragStartPosition) < 0) 233 if (eventPosition.compareTo(dragStartPosition) < 0)
430 newSelection.setBase(PositionType::afterNode(rootUserSelectA llForMousePressNode).downstream(CanCrossEditingBoundary)); 234 newSelection.setBase(PositionType::afterNode(rootUserSelectA llForMousePressNode).downstream(CanCrossEditingBoundary));
431 } 235 }
432 236
433 Node* rootUserSelectAllForTarget = Position::rootUserSelectAllForNod e(target); 237 Node* rootUserSelectAllForTarget = Position::rootUserSelectAllForNod e(target);
434 if (rootUserSelectAllForTarget && mousePressNode->layoutObject() && Strategy::toPositionType(target->layoutObject()->positionForPoint(hitTestResult. localPoint()).position()).compareTo(Strategy::toPositionType(mousePressNode->lay outObject()->positionForPoint(dragStartPos).position())) < 0) 238 if (rootUserSelectAllForTarget && mousePressNode->layoutObject() && Strategy::toPositionType(target->layoutObject()->positionForPoint(hitTestResult. localPoint()).position()).compareTo(Strategy::toPositionType(mousePressNode->lay outObject()->positionForPoint(dragStartPos).position())) < 0)
435 newSelection.setExtent(PositionType::beforeNode(rootUserSelectAl lForTarget).upstream(CanCrossEditingBoundary)); 239 newSelection.setExtent(PositionType::beforeNode(rootUserSelectAl lForTarget).upstream(CanCrossEditingBoundary));
436 else if (rootUserSelectAllForTarget && mousePressNode->layoutObject( )) 240 else if (rootUserSelectAllForTarget && mousePressNode->layoutObject( ))
437 newSelection.setExtent(PositionType::afterNode(rootUserSelectAll ForTarget).downstream(CanCrossEditingBoundary)); 241 newSelection.setExtent(PositionType::afterNode(rootUserSelectAll ForTarget).downstream(CanCrossEditingBoundary));
438 else 242 else
439 newSelection.setExtent(targetPosition); 243 newSelection.setExtent(targetPosition);
440 } 244 }
441 } else { 245 } else {
442 newSelection.setExtent(targetPosition); 246 newSelection.setExtent(targetPosition);
443 } 247 }
444 248
445 if (m_frame->selection().granularity() != CharacterGranularity) 249 if (selection().granularity() != CharacterGranularity)
446 expandSelectionUsingGranularity(newSelection, m_frame->selection().granu larity()); 250 expandSelectionUsingGranularity(newSelection, selection().granularity()) ;
447 251
448 m_frame->selection().setNonDirectionalSelectionIfNeeded(newSelection, m_fram e->selection().granularity(), 252 selection().setNonDirectionalSelectionIfNeeded(newSelection, selection().gra nularity(),
449 FrameSelection::AdjustEndpointsAtBidiBoundary); 253 FrameSelection::AdjustEndpointsAtBidiBoundary);
450 } 254 }
451 255
256 PassOwnPtrWillBeRawPtr<SelectionController> SelectionController::create(LocalFra me& frame)
yosin_UTC9 2015/06/22 05:31:10 Let's keep original source code location for them
Miyoung Shin(c) 2015/06/24 07:43:27 when picking up template codes, it looks like thes
257 {
258 return adoptPtrWillBeNoop(new SelectionController(frame));
259 }
260
261 SelectionController::SelectionController(LocalFrame& frame)
262 : m_frame(&frame)
263 , m_mouseDownMayStartSelect(false)
264 , m_mouseDownWasSingleClickInSelection(false)
265 , m_selectionState(SelectionState::HaveNotStartedSelection)
266 {
267 }
268
269 DEFINE_TRACE(SelectionController)
270 {
271 visitor->trace(m_frame);
272 }
273
274 bool SelectionController::updateSelectionForMouseDownDispatchingSelectStart(Node * targetNode, const VisibleSelection& visibleSelection, TextGranularity granular ity)
275 {
276 if (Position::nodeIsUserSelectNone(targetNode))
277 return false;
278
279 if (!dispatchSelectStart(targetNode))
280 return false;
281
282 if (visibleSelection.isRange()) {
283 m_selectionState = SelectionState::ExtendedSelection;
284 } else {
285 granularity = CharacterGranularity;
286 m_selectionState = SelectionState::PlacedCaret;
287 }
288
289 selection().setNonDirectionalSelectionIfNeeded(visibleSelection, granularity );
290
291 return true;
292 }
293
294 void SelectionController::selectClosestWordFromHitTestResult(const HitTestResult & result, AppendTrailingWhitespace appendTrailingWhitespace)
295 {
296 Node* innerNode = result.innerNode();
297 VisibleSelection newSelection;
298
299 if (!innerNode || !innerNode->layoutObject())
300 return;
301
302 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.local Point()));
303 if (pos.isNotNull()) {
304 newSelection = VisibleSelection(pos);
305 expandSelectionUsingGranularity(newSelection, WordGranularity);
306 }
307
308 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne wSelection.isRange())
309 newSelection.appendTrailingWhitespace();
310
311 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection ToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
312 }
313
314 void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTes tResult& result, AppendTrailingWhitespace appendTrailingWhitespace)
315 {
316 Node* innerNode = result.innerNode();
317 VisibleSelection newSelection;
318
319 if (!innerNode || !innerNode->layoutObject())
320 return;
321
322 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.local Point()));
323 Position start = pos.deepEquivalent();
324 Position end = pos.deepEquivalent();
325 if (pos.isNotNull()) {
326 DocumentMarkerVector markers = innerNode->document().markers().markersIn Range(makeRange(pos, pos).get(), DocumentMarker::MisspellingMarkers());
327 if (markers.size() == 1) {
328 start.moveToOffset(markers[0]->startOffset());
329 end.moveToOffset(markers[0]->endOffset());
330 newSelection = VisibleSelection(start, end);
331 }
332 }
333
334 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne wSelection.isRange())
335 newSelection.appendTrailingWhitespace();
336
337 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection ToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
338 }
339
340 void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHi tTestResults& result)
341 {
342 if (!m_mouseDownMayStartSelect)
343 return;
344
345 selectClosestWordFromHitTestResult(result.hitTestResult(),
346 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingW hitespaceEnabled()) ? AppendTrailingWhitespace::ShouldAppend : AppendTrailingWhi tespace::DontAppend);
347 }
348
349 void SelectionController::selectClosestMisspellingFromMouseEvent(const MouseEven tWithHitTestResults& result)
350 {
351 if (!m_mouseDownMayStartSelect)
352 return;
353
354 selectClosestMisspellingFromHitTestResult(result.hitTestResult(),
355 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingW hitespaceEnabled()) ? AppendTrailingWhitespace::ShouldAppend : AppendTrailingWhi tespace::DontAppend);
356 }
357
358 void SelectionController::selectClosestWordOrLinkFromMouseEvent(const MouseEvent WithHitTestResults& result)
359 {
360 if (!result.hitTestResult().isLiveLink())
361 return selectClosestWordFromMouseEvent(result);
362
363 Node* innerNode = result.innerNode();
364
365 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect))
366 return;
367
368 VisibleSelection newSelection;
369 Element* URLElement = result.hitTestResult().URLElement();
370 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.local Point()));
371 if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescendantOf (URLElement))
372 newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement) ;
373
374 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection ToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
375 }
376
377 bool SelectionController::handleMousePressEventSingleClick(const MouseEventWithH itTestResults& event)
378 {
379 return handleMousePressEventSingleClickAlgorithm<VisibleSelection::InDOMTree >(event);
380 }
381
382 bool SelectionController::handleMousePressEventDoubleClick(const MouseEventWithH itTestResults& event)
383 {
384 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventDoubleClick ");
385
386 if (event.event().button() != LeftButton)
387 return false;
388
389 if (selection().isRange()) {
390 // A double-click when range is already selected
391 // should not change the selection. So, do not call
392 // selectClosestWordFromMouseEvent, but do set
393 // m_beganSelectingText to prevent handleMouseReleaseEvent
394 // from setting caret selection.
395 m_selectionState = SelectionState::ExtendedSelection;
396 } else {
397 selectClosestWordFromMouseEvent(event);
398 }
399 return true;
400 }
401
402 bool SelectionController::handleMousePressEventTripleClick(const MouseEventWithH itTestResults& event)
403 {
404 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventTripleClick ");
405
406 if (event.event().button() != LeftButton)
407 return false;
408
409 Node* innerNode = event.innerNode();
410 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect))
411 return false;
412
413 VisibleSelection newSelection;
414 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(event.localP oint()));
415 if (pos.isNotNull()) {
416 newSelection = VisibleSelection(pos);
417 expandSelectionUsingGranularity(newSelection, ParagraphGranularity);
418 }
419
420 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity);
421 }
422
423 void SelectionController::handleMousePressEvent(const MouseEventWithHitTestResul ts& event)
424 {
425 // If we got the event back, that must mean it wasn't prevented,
426 // so it's allowed to start a drag or selection if it wasn't in a scrollbar.
427 m_mouseDownMayStartSelect = canMouseDownStartSelect(event.innerNode()) && !e vent.scrollbar();
428 m_mouseDownWasSingleClickInSelection = false;
429 }
430
431 void SelectionController::handleMouseDraggedEvent(const MouseEventWithHitTestRes ults& event, const IntPoint& mouseDownPos, const LayoutPoint& dragStartPos, Node * mousePressNode, const IntPoint& lastKnownMousePosition)
432 {
433 if (m_selectionState != SelectionState::ExtendedSelection) {
434 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active );
435 HitTestResult result(request, mouseDownPos);
436 m_frame->document()->layoutView()->hitTest(result);
437
438 updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKn ownMousePosition);
439 }
440 updateSelectionForMouseDrag(event.hitTestResult(), mousePressNode, dragStart Pos, lastKnownMousePosition);
441 }
442
443 void SelectionController::updateSelectionForMouseDrag(Node* mousePressNode, cons t LayoutPoint& dragStartPos, const IntPoint& lastKnownMousePosition)
444 {
445 FrameView* view = m_frame->view();
446 if (!view)
447 return;
448 LayoutView* layoutObject = m_frame->contentLayoutObject();
449 if (!layoutObject)
450 return;
451
452 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | H itTestRequest::Move);
453 HitTestResult result(request, view->rootFrameToContents(lastKnownMousePositi on));
454 layoutObject->hitTest(result);
455 updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKnownM ousePosition);
456 }
457
458 void SelectionController::updateSelectionForMouseDrag(const HitTestResult& hitTe stResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint& lastKnownMousePosition)
459 {
460 updateSelectionForMouseDragAlgorithm<VisibleSelection::InDOMTree>(hitTestRes ult, mousePressNode, dragStartPos, lastKnownMousePosition);
461 }
462
452 bool SelectionController::handleMouseReleaseEvent(const MouseEventWithHitTestRes ults& event, const LayoutPoint& dragStartPos) 463 bool SelectionController::handleMouseReleaseEvent(const MouseEventWithHitTestRes ults& event, const LayoutPoint& dragStartPos)
453 { 464 {
454 bool handled = false; 465 bool handled = false;
455 m_mouseDownMayStartSelect = false; 466 m_mouseDownMayStartSelect = false;
456 // Clear the selection if the mouse didn't move after the last mouse 467 // Clear the selection if the mouse didn't move after the last mouse
457 // press and it's not a context menu click. We do this so when clicking 468 // press and it's not a context menu click. We do this so when clicking
458 // on the selection, the selection goes away. However, if we are 469 // on the selection, the selection goes away. However, if we are
459 // editing, place the caret. 470 // editing, place the caret.
460 if (m_mouseDownWasSingleClickInSelection && m_selectionInitiationState != Ex tendedSelection 471 if (m_mouseDownWasSingleClickInSelection && m_selectionState != SelectionSta te::ExtendedSelection
461 && dragStartPos == event.event().position() 472 && dragStartPos == event.event().position()
462 && m_frame->selection().isRange() 473 && selection().isRange()
463 && event.event().button() != RightButton) { 474 && event.event().button() != RightButton) {
464 VisibleSelection newSelection; 475 VisibleSelection newSelection;
465 Node* node = event.innerNode(); 476 Node* node = event.innerNode();
466 bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBr owsingEnabled(); 477 bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBr owsingEnabled();
467 if (node && node->layoutObject() && (caretBrowsing || node->hasEditableS tyle())) { 478 if (node && node->layoutObject() && (caretBrowsing || node->hasEditableS tyle())) {
468 VisiblePosition pos = VisiblePosition(node->layoutObject()->position ForPoint(event.localPoint())); 479 VisiblePosition pos = VisiblePosition(node->layoutObject()->position ForPoint(event.localPoint()));
469 newSelection = VisibleSelection(pos); 480 newSelection = VisibleSelection(pos);
470 } 481 }
471 482
472 setSelectionIfNeeded(m_frame->selection(), newSelection); 483 setSelectionIfNeeded(selection(), newSelection);
473 484
474 handled = true; 485 handled = true;
475 } 486 }
476 487
477 m_frame->selection().notifyLayoutObjectOfSelectionChange(UserTriggered); 488 selection().notifyLayoutObjectOfSelectionChange(UserTriggered);
478 489
479 m_frame->selection().selectFrameElementInParentIfFullySelected(); 490 selection().selectFrameElementInParentIfFullySelected();
480 491
481 if (event.event().button() == MiddleButton && !event.isOverLink()) { 492 if (event.event().button() == MiddleButton && !event.isOverLink()) {
482 // Ignore handled, since we want to paste to where the caret was placed anyway. 493 // Ignore handled, since we want to paste to where the caret was placed anyway.
483 handled = handlePasteGlobalSelection(event.event()) || handled; 494 handled = handlePasteGlobalSelection(event.event()) || handled;
484 } 495 }
485 496
486 return handled; 497 return handled;
487 } 498 }
488 499
489
490 bool SelectionController::handlePasteGlobalSelection(const PlatformMouseEvent& m ouseEvent) 500 bool SelectionController::handlePasteGlobalSelection(const PlatformMouseEvent& m ouseEvent)
491 { 501 {
492 // If the event was a middle click, attempt to copy global selection in afte r 502 // If the event was a middle click, attempt to copy global selection in afte r
493 // the newly set caret position. 503 // the newly set caret position.
494 // 504 //
495 // This code is called from either the mouse up or mouse down handling. Ther e 505 // This code is called from either the mouse up or mouse down handling. Ther e
496 // is some debate about when the global selection is pasted: 506 // is some debate about when the global selection is pasted:
497 // xterm: pastes on up. 507 // xterm: pastes on up.
498 // GTK: pastes on down. 508 // GTK: pastes on down.
499 // Qt: pastes on up. 509 // Qt: pastes on up.
(...skipping 18 matching lines...) Expand all
518 return false; 528 return false;
519 } 529 }
520 530
521 bool SelectionController::handleGestureLongPress(const PlatformGestureEvent& ges tureEvent, const HitTestResult& hitTestResult) 531 bool SelectionController::handleGestureLongPress(const PlatformGestureEvent& ges tureEvent, const HitTestResult& hitTestResult)
522 { 532 {
523 #if OS(ANDROID) 533 #if OS(ANDROID)
524 bool shouldLongPressSelectWord = true; 534 bool shouldLongPressSelectWord = true;
525 #else 535 #else
526 bool shouldLongPressSelectWord = m_frame->settings() && m_frame->settings()- >touchEditingEnabled(); 536 bool shouldLongPressSelectWord = m_frame->settings() && m_frame->settings()- >touchEditingEnabled();
527 #endif 537 #endif
528 if (shouldLongPressSelectWord) { 538 if (!shouldLongPressSelectWord)
539 return false;
529 540
541 Node* innerNode = hitTestResult.innerNode();
542 if (hitTestResult.isLiveLink() || !innerNode || !(innerNode->isContentEditab le() || innerNode->isTextNode()
543 #if OS(ANDROID)
544 || innerNode->canStartSelection()
545 #endif
546 ))
547 return false;
530 548
531 Node* innerNode = hitTestResult.innerNode(); 549 selectClosestWordFromHitTestResult(hitTestResult, AppendTrailingWhitespace:: DontAppend);
532 if (!hitTestResult.isLiveLink() && innerNode && (innerNode->isContentEdi table() || innerNode->isTextNode() 550 if (!selection().isRange())
533 #if OS(ANDROID) 551 return false;
534 || innerNode->canStartSelection() 552
535 #endif 553 return true;
536 )) {
537 selectClosestWordFromHitTestResult(hitTestResult, DontAppendTrailing Whitespace);
538 if (m_frame->selection().isRange())
539 return true;
540 }
541 }
542 return false;
543 } 554 }
544 555
545 void SelectionController::sendContextMenuEvent(const MouseEventWithHitTestResult s& mev, const LayoutPoint& position) 556 void SelectionController::prepareForContextMenu(const MouseEventWithHitTestResul ts& mev, const LayoutPoint& position)
546 { 557 {
547 if (!m_frame->selection().contains(position) 558 if (selection().contains(position)
548 && !mev.scrollbar() 559 || mev.scrollbar()
549 // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse. 560 // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
550 // If the selection is non-editable, we do word selection to make it eas ier to use the contextual menu items 561 // If the selection is non-editable, we do word selection to make it eas ier to use the contextual menu items
551 // available for text selections. But only if we're above text. 562 // available for text selections. But only if we're above text.
552 && (m_frame->selection().isContentEditable() || (mev.innerNode() && mev. innerNode()->isTextNode()))) { 563 || !(selection().isContentEditable() || (mev.innerNode() && mev.innerNod e()->isTextNode())))
553 m_mouseDownMayStartSelect = true; // context menu events are always allo wed to perform a selection 564 return;
554 565
555 if (mev.hitTestResult().isMisspelled()) 566 m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
556 selectClosestMisspellingFromMouseEvent(mev); 567
557 else if (m_frame->editor().behavior().shouldSelectOnContextualMenuClick( )) 568 if (mev.hitTestResult().isMisspelled())
558 selectClosestWordOrLinkFromMouseEvent(mev); 569 selectClosestMisspellingFromMouseEvent(mev);
559 } 570 else if (m_frame->editor().behavior().shouldSelectOnContextualMenuClick())
571 selectClosestWordOrLinkFromMouseEvent(mev);
560 } 572 }
561 573
562 void SelectionController::passMousePressEventToSubframe(const MouseEventWithHitT estResults& mev) 574 void SelectionController::preparePassMousePressEventToSubframe(const MouseEventW ithHitTestResults& mev)
563 { 575 {
564 // If we're clicking into a frame that is selected, the frame will appear 576 // If we're clicking into a frame that is selected, the frame will appear
565 // greyed out even though we're clicking on the selection. This looks 577 // greyed out even though we're clicking on the selection. This looks
566 // really strange (having the whole frame be greyed out), so we deselect the 578 // really strange (having the whole frame be greyed out), so we deselect the
567 // selection. 579 // selection.
568 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position()); 580 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position());
569 if (m_frame->selection().contains(p)) { 581 if (!selection().contains(p))
570 VisiblePosition visiblePos( 582 return;
571 mev.innerNode()->layoutObject()->positionForPoint(mev.localPoint())) ; 583
572 VisibleSelection newSelection(visiblePos); 584 VisiblePosition visiblePos(
573 m_frame->selection().setSelection(newSelection); 585 mev.innerNode()->layoutObject()->positionForPoint(mev.localPoint()));
574 } 586 VisibleSelection newSelection(visiblePos);
587 selection().setSelection(newSelection);
575 } 588 }
576 589
577 void SelectionController::initializeSelectionState() 590 void SelectionController::initializeSelectionState()
578 { 591 {
579 m_selectionInitiationState = HaveNotStartedSelection; 592 m_selectionState = SelectionState::HaveNotStartedSelection;
580 } 593 }
581 594
582 void SelectionController::setMouseDownMayStartSelect(bool mayStartSelect) 595 void SelectionController::setMouseDownMayStartSelect(bool mayStartSelect)
583 { 596 {
584 m_mouseDownMayStartSelect = mayStartSelect; 597 m_mouseDownMayStartSelect = mayStartSelect;
585 } 598 }
586 599
587 bool SelectionController::mouseDownMayStartSelect() const 600 bool SelectionController::mouseDownMayStartSelect() const
588 { 601 {
589 return m_mouseDownMayStartSelect; 602 return m_mouseDownMayStartSelect;
590 } 603 }
591 604
592 bool SelectionController::mouseDownWasSingleClickInSelection() const 605 bool SelectionController::mouseDownWasSingleClickInSelection() const
593 { 606 {
594 return m_mouseDownWasSingleClickInSelection; 607 return m_mouseDownWasSingleClickInSelection;
595 } 608 }
596 609
610 FrameSelection& SelectionController::selection() const
611 {
612 return m_frame->selection();
613 }
614
597 } // namespace blink 615 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698