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

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

Issue 1113323002: [Reland] Refactor the selection code in EventHandler (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
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "config.h"
29 #include "core/editing/SelectionController.h"
30
31 #include "core/HTMLNames.h"
32 #include "core/dom/Document.h"
33 #include "core/dom/DocumentMarkerController.h"
34 #include "core/editing/Editor.h"
35 #include "core/editing/FrameSelection.h"
36 #include "core/editing/htmlediting.h"
37 #include "core/editing/iterators/TextIterator.h"
38 #include "core/events/Event.h"
39 #include "core/frame/FrameView.h"
40 #include "core/frame/LocalFrame.h"
41 #include "core/frame/Settings.h"
42 #include "core/layout/LayoutView.h"
43 #include "core/page/FocusController.h"
44 #include "core/page/Page.h"
45 #include "platform/RuntimeEnabledFeatures.h"
46
47 namespace blink {
48
49 static void setSelectionIfNeeded(FrameSelection& selection, const VisibleSelecti on& newSelection)
50 {
51 if (selection.selection() != newSelection)
52 selection.setSelection(newSelection);
53 }
54
55 static inline bool dispatchSelectStart(Node* node)
56 {
57 if (!node || !node->layoutObject())
58 return true;
59
60 return node->dispatchEvent(Event::createCancelableBubble(EventTypeNames::sel ectstart));
61 }
62
63 static VisibleSelection expandSelectionToRespectUserSelectAll(Node* targetNode, const VisibleSelection& selection)
64 {
65 Node* rootUserSelectAll = Position::rootUserSelectAllForNode(targetNode);
66 if (!rootUserSelectAll)
67 return selection;
68
69 VisibleSelection newSelection(selection);
70 newSelection.setBase(positionBeforeNode(rootUserSelectAll).upstream(CanCross EditingBoundary));
71 newSelection.setExtent(positionAfterNode(rootUserSelectAll).downstream(CanCr ossEditingBoundary));
72
73 return newSelection;
74 }
75
76 static inline bool canMouseDownStartSelect(Node* node)
77 {
78 if (!node || !node->layoutObject())
79 return true;
80
81 if (!node->canStartSelection())
82 return false;
83
84 return true;
85 }
86
87 static int textDistance(const Position& start, const Position& end)
88 {
89 RefPtrWillBeRawPtr<Range> range = Range::create(*start.document(), start, en d);
90 return TextIterator::rangeLength(range->startPosition(), range->endPosition( ), true);
91 }
92
93 PassOwnPtr<SelectionController> SelectionController::create(LocalFrame* frame, F rameSelection* selection)
94 {
95 return adoptPtr(new SelectionController(frame, selection));
96 }
97
98 SelectionController::SelectionController(LocalFrame* frame, FrameSelection* sele ction)
99 : m_frame(frame)
100 , m_selection(selection)
101 , m_mouseDownMayStartSelect(false)
102 , m_singleClickInSelection(false)
103 , m_selectionState(SelectionState::HaveNotStartedSelection)
104 {
105
106 }
107
108 SelectionController::~SelectionController()
109 {
110 }
111
112 void SelectionController::clear()
113 {
114 m_mouseDownMayStartSelect = false;
115 m_singleClickInSelection = false;
116 m_selectionState = SelectionState::HaveNotStartedSelection;
117 }
118
119 bool SelectionController::updateSelectionForMouseDownDispatchingSelectStart(Node * targetNode, const VisibleSelection& visibleSelection, TextGranularity granular ity)
120 {
121 if (Position::nodeIsUserSelectNone(targetNode))
122 return false;
123
124 if (!dispatchSelectStart(targetNode))
125 return false;
126
127 if (visibleSelection.isRange()) {
128 m_selectionState = SelectionState::ExtendedSelection;
129 } else {
130 granularity = CharacterGranularity;
131 m_selectionState = SelectionState::PlacedCaret;
132 }
133
134 selection().setNonDirectionalSelectionIfNeeded(visibleSelection, granularity );
135
136 return true;
137 }
138
139 void SelectionController::selectClosestWordFromHitTestResult(const HitTestResult & result, AppendTrailingWhitespace appendTrailingWhitespace)
140 {
141 Node* innerNode = result.innerNode();
142 VisibleSelection newSelection;
143
144 if (innerNode && innerNode->layoutObject()) {
145 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.l ocalPoint()));
146 if (pos.isNotNull()) {
147 newSelection = VisibleSelection(pos);
148 newSelection.expandUsingGranularity(WordGranularity);
149 }
150
151 if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSel ection.isRange())
152 newSelection.appendTrailingWhitespace();
153
154 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelec tionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
155 }
156 }
157
158 void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTes tResult& result, AppendTrailingWhitespace appendTrailingWhitespace)
159 {
160 Node* innerNode = result.innerNode();
161 VisibleSelection newSelection;
162
163 if (innerNode && innerNode->layoutObject()) {
164 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.l ocalPoint()));
165 Position start = pos.deepEquivalent();
166 Position end = pos.deepEquivalent();
167 if (pos.isNotNull()) {
168 DocumentMarkerVector markers = innerNode->document().markers().marke rsInRange(makeRange(pos, pos).get(), DocumentMarker::MisspellingMarkers());
169 if (markers.size() == 1) {
170 start.moveToOffset(markers[0]->startOffset());
171 end.moveToOffset(markers[0]->endOffset());
172 newSelection = VisibleSelection(start, end);
173 }
174 }
175
176 if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSel ection.isRange())
177 newSelection.appendTrailingWhitespace();
178
179 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelec tionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
180 }
181 }
182
183 void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHi tTestResults& result)
184 {
185 if (m_mouseDownMayStartSelect) {
186 selectClosestWordFromHitTestResult(result.hitTestResult(),
187 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrail ingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhi tespace);
188 }
189 }
190
191 void SelectionController::selectClosestMisspellingFromMouseEvent(const MouseEven tWithHitTestResults& result)
192 {
193 if (m_mouseDownMayStartSelect) {
194 selectClosestMisspellingFromHitTestResult(result.hitTestResult(),
195 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrail ingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhi tespace);
196 }
197 }
198
199 void SelectionController::selectClosestWordOrLinkFromMouseEvent(const MouseEvent WithHitTestResults& result)
200 {
201 if (!result.hitTestResult().isLiveLink())
202 return selectClosestWordFromMouseEvent(result);
203
204 Node* innerNode = result.innerNode();
205
206 if (innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect) {
207 VisibleSelection newSelection;
208 Element* URLElement = result.hitTestResult().URLElement();
209 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.l ocalPoint()));
210 if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescenda ntOf(URLElement))
211 newSelection = VisibleSelection::selectionFromContentsOfNode(URLElem ent);
212
213 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelec tionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
214 }
215 }
216
217 void SelectionController::handleMousePressEvent(const MouseEventWithHitTestResul ts& event)
218 {
219 // If we got the event back, that must mean it wasn't prevented,
220 // so it's allowed to start a drag or selection if it wasn't in a scrollbar.
221 m_mouseDownMayStartSelect = canMouseDownStartSelect(event.innerNode()) && !e vent.scrollbar();
222 m_singleClickInSelection = false;
223 }
224
225 bool SelectionController::handleMousePressEventDoubleClick(const MouseEventWithH itTestResults& event)
226 {
227 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventDoubleClick ");
228
229 if (event.event().button() != LeftButton)
230 return false;
231
232 if (selection().isRange()) {
233 // A double-click when range is already selected
234 // should not change the selection. So, do not call
235 // selectClosestWordFromMouseEvent, but do set
236 // m_beganSelectingText to prevent handleMouseReleaseEvent
237 // from setting caret selection.
238 m_selectionState = SelectionState::ExtendedSelection;
239 } else {
240 selectClosestWordFromMouseEvent(event);
241 }
242 return true;
243 }
244
245 bool SelectionController::handleMousePressEventTripleClick(const MouseEventWithH itTestResults& event)
246 {
247 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventTripleClick ");
248
249 if (event.event().button() != LeftButton)
250 return false;
251
252 Node* innerNode = event.innerNode();
253 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect))
254 return false;
255
256 VisibleSelection newSelection;
257 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(event.localP oint()));
258 if (pos.isNotNull()) {
259 newSelection = VisibleSelection(pos);
260 newSelection.expandUsingGranularity(ParagraphGranularity);
261 }
262
263 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity);
264 }
265
266 bool SelectionController::handleMousePressEventSingleClick(const MouseEventWithH itTestResults& event)
267 {
268 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventSingleClick ");
269
270 m_frame->document()->updateLayoutIgnorePendingStylesheets();
271 Node* innerNode = event.innerNode();
272 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect))
273 return false;
274
275 // Extend the selection if the Shift key is down, unless the click is in a l ink.
276 bool extendSelection = event.event().shiftKey() && !event.isOverLink();
277
278 // Don't restart the selection when the mouse is pressed on an
279 // existing selection so we can allow for text dragging.
280 if (FrameView* view = m_frame->view()) {
281 LayoutPoint vPoint = view->rootFrameToContents(event.event().position()) ;
282 if (!extendSelection && selection().contains(vPoint)) {
283 m_singleClickInSelection = true;
284 return false;
285 }
286 }
287
288 VisiblePosition visiblePos(innerNode->layoutObject()->positionForPoint(event .localPoint()));
289 if (visiblePos.isNull())
290 visiblePos = VisiblePosition(firstPositionInOrBeforeNode(innerNode), DOW NSTREAM);
291 Position pos = visiblePos.deepEquivalent();
292
293 VisibleSelection newSelection = selection().selection();
294 TextGranularity granularity = CharacterGranularity;
295
296 if (extendSelection && newSelection.isCaretOrRange()) {
297 VisibleSelection selectionInUserSelectAll(expandSelectionToRespectUserSe lectAll(innerNode, VisibleSelection(VisiblePosition(pos))));
298 if (selectionInUserSelectAll.isRange()) {
299 if (comparePositions(selectionInUserSelectAll.start(), newSelection. start()) < 0)
300 pos = selectionInUserSelectAll.start();
301 else if (comparePositions(newSelection.end(), selectionInUserSelectA ll.end()) < 0)
302 pos = selectionInUserSelectAll.end();
303 }
304
305 if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional() ) {
306 if (pos.isNotNull()) {
307 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click d eselects when selection
308 // was created right-to-left
309 Position start = newSelection.start();
310 Position end = newSelection.end();
311 int distanceToStart = textDistance(start, pos);
312 int distanceToEnd = textDistance(pos, end);
313 if (distanceToStart <= distanceToEnd)
314 newSelection = VisibleSelection(end, pos);
315 else
316 newSelection = VisibleSelection(start, pos);
317 }
318 } else {
319 newSelection.setExtent(pos);
320 }
321
322 if (selection().granularity() != CharacterGranularity) {
323 granularity = selection().granularity();
324 newSelection.expandUsingGranularity(selection().granularity());
325 }
326 } else if (m_selectionState != SelectionState::ExtendedSelection) {
327 newSelection = expandSelectionToRespectUserSelectAll(innerNode, VisibleS election(visiblePos));
328 }
329
330 // Updating the selection is considered side-effect of the event and so it d oesn't impact the handled state.
331 updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, g ranularity);
332 return false;
333 }
334
335 void SelectionController::handleMouseDraggedEvent(const MouseEventWithHitTestRes ults& event, const IntPoint& mouseDownPos, const LayoutPoint& dragStartPos, cons t RefPtr<Node> mousePressNode, const IntPoint& lastKnownMousePosition)
336 {
337 if (m_selectionState != SelectionState::ExtendedSelection) {
338 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active );
339 HitTestResult result(request, mouseDownPos);
340 m_frame->document()->layoutView()->hitTest(result);
341
342 updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKn ownMousePosition);
343 }
344 updateSelectionForMouseDrag(event.hitTestResult(), mousePressNode, dragStart Pos, lastKnownMousePosition);
345 }
346
347 bool SelectionController::handleMouseReleaseEvent(const MouseEventWithHitTestRes ults& event, const LayoutPoint& dragStartPos)
348 {
349 bool handled = false;
350 m_mouseDownMayStartSelect = false;
351 // Clear the selection if the mouse didn't move after the last mouse
352 // press and it's not a context menu click. We do this so when clicking
353 // on the selection, the selection goes away. However, if we are
354 // editing, place the caret.
355 if (m_singleClickInSelection && m_selectionState != SelectionState::Extended Selection
356 && dragStartPos == event.event().position()
357 && selection().isRange()
358 && event.event().button() != RightButton) {
359 VisibleSelection newSelection;
360 Node* node = event.innerNode();
361 bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBr owsingEnabled();
362 if (node && node->layoutObject() && (caretBrowsing || node->hasEditableS tyle())) {
363 VisiblePosition pos = VisiblePosition(node->layoutObject()->position ForPoint(event.localPoint()));
364 newSelection = VisibleSelection(pos);
365 }
366
367 setSelectionIfNeeded(selection(), newSelection);
368
369 handled = true;
370 }
371
372 selection().notifyLayoutObjectOfSelectionChange(UserTriggered);
373
374 selection().selectFrameElementInParentIfFullySelected();
375
376 if (event.event().button() == MiddleButton && !event.isOverLink()) {
377 // Ignore handled, since we want to paste to where the caret was placed anyway.
378 handled = handlePasteGlobalSelection(event.event()) || handled;
379 }
380
381 return handled;
382 }
383
384 bool SelectionController::handlePasteGlobalSelection(const PlatformMouseEvent& m ouseEvent)
385 {
386 // If the event was a middle click, attempt to copy global selection in afte r
387 // the newly set caret position.
388 //
389 // This code is called from either the mouse up or mouse down handling. Ther e
390 // is some debate about when the global selection is pasted:
391 // xterm: pastes on up.
392 // GTK: pastes on down.
393 // Qt: pastes on up.
394 // Firefox: pastes on up.
395 // Chromium: pastes on up.
396 //
397 // There is something of a webcompat angle to this well, as highlighted by
398 // crbug.com/14608. Pages can clear text boxes 'onclick' and, if we paste on
399 // down then the text is pasted just before the onclick handler runs and
400 // clears the text box. So it's important this happens after the event
401 // handlers have been fired.
402 if (mouseEvent.type() != PlatformEvent::MouseReleased)
403 return false;
404
405 if (!m_frame->page())
406 return false;
407 Frame* focusFrame = m_frame->page()->focusController().focusedOrMainFrame();
408 // Do not paste here if the focus was moved somewhere else.
409 if (m_frame == focusFrame && m_frame->editor().behavior().supportsGlobalSele ction())
410 return m_frame->editor().command("PasteGlobalSelection").execute();
411
412 return false;
413 }
414
415 void SelectionController::updateSelectionForMouseDrag(const RefPtr<Node> mousePr essNode, const LayoutPoint& dragStartPos, const IntPoint& lastKnownMousePosition )
416 {
417 FrameView* view = m_frame->view();
418 if (!view)
419 return;
420 LayoutView* layoutObject = m_frame->contentLayoutObject();
421 if (!layoutObject)
422 return;
423
424 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | H itTestRequest::Move);
425 HitTestResult result(request, view->rootFrameToContents(lastKnownMousePositi on));
426 layoutObject->hitTest(result);
427 updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKnownM ousePosition);
428 }
429
430 void SelectionController::updateSelectionForMouseDrag(const HitTestResult& hitTe stResult, const RefPtr<Node> mousePressNode, const LayoutPoint& dragStartPos, co nst IntPoint& lastKnownMousePosition)
431 {
432 if (!m_mouseDownMayStartSelect)
433 return;
434
435 Node* target = hitTestResult.innerNode();
436 if (!target)
437 return;
438
439 VisiblePosition targetPosition = selection().selection().visiblePositionResp ectingEditingBoundary(hitTestResult.localPoint(), target);
440 // Don't modify the selection if we're not on a node.
441 if (targetPosition.isNull())
442 return;
443
444 // Restart the selection if this is the first mouse move. This work is usual ly
445 // done in handleMousePressEvent, but not if the mouse press was on an exist ing selection.
446 VisibleSelection newSelection = selection().selection();
447
448 // Special case to limit selection to the containing block for SVG text.
449 // FIXME: Isn't there a better non-SVG-specific way to do this?
450 if (Node* selectionBaseNode = newSelection.base().deprecatedNode()) {
451 if (LayoutObject* selectionBaseLayoutObject = selectionBaseNode->layoutO bject()) {
452 if (selectionBaseLayoutObject->isSVGText()) {
453 if (target->layoutObject()->containingBlock() != selectionBaseLa youtObject->containingBlock())
454 return;
455 }
456 }
457 }
458
459 if (m_selectionState == SelectionState::HaveNotStartedSelection && !dispatch SelectStart(target))
460 return;
461
462 if (m_selectionState != SelectionState::ExtendedSelection) {
463 // Always extend selection here because it's caused by a mouse drag
464 m_selectionState = SelectionState::ExtendedSelection;
465 newSelection = VisibleSelection(targetPosition);
466 }
467
468 if (RuntimeEnabledFeatures::userSelectAllEnabled()) {
469 Node* rootUserSelectAllForMousePressNode = Position::rootUserSelectAllFo rNode(mousePressNode.get());
470 if (rootUserSelectAllForMousePressNode && rootUserSelectAllForMousePress Node == Position::rootUserSelectAllForNode(target)) {
471 newSelection.setBase(positionBeforeNode(rootUserSelectAllForMousePre ssNode).upstream(CanCrossEditingBoundary));
472 newSelection.setExtent(positionAfterNode(rootUserSelectAllForMousePr essNode).downstream(CanCrossEditingBoundary));
473 } else {
474 // Reset base for user select all when base is inside user-select-al l area and extent < base.
475 if (rootUserSelectAllForMousePressNode && comparePositions(target->l ayoutObject()->positionForPoint(hitTestResult.localPoint()), mousePressNode->lay outObject()->positionForPoint(dragStartPos)) < 0)
476 newSelection.setBase(positionAfterNode(rootUserSelectAllForMouse PressNode).downstream(CanCrossEditingBoundary));
477
478 Node* rootUserSelectAllForTarget = Position::rootUserSelectAllForNod e(target);
479 if (rootUserSelectAllForTarget && mousePressNode->layoutObject() && comparePositions(target->layoutObject()->positionForPoint(hitTestResult.localPoi nt()), mousePressNode->layoutObject()->positionForPoint(dragStartPos)) < 0)
480 newSelection.setExtent(positionBeforeNode(rootUserSelectAllForTa rget).upstream(CanCrossEditingBoundary));
481 else if (rootUserSelectAllForTarget && mousePressNode->layoutObject( ))
482 newSelection.setExtent(positionAfterNode(rootUserSelectAllForTar get).downstream(CanCrossEditingBoundary));
483 else
484 newSelection.setExtent(targetPosition);
485 }
486 } else {
487 newSelection.setExtent(targetPosition);
488 }
489
490 if (selection().granularity() != CharacterGranularity)
491 newSelection.expandUsingGranularity(selection().granularity());
492
493 selection().setNonDirectionalSelectionIfNeeded(newSelection, selection().gra nularity(),
494 FrameSelection::AdjustEndpointsAtBidiBoundary);
495 }
496
497
498 void SelectionController::prepareForContextMenu(const MouseEventWithHitTestResul ts& mev, const LayoutPoint& position)
499 {
500 if (selection().contains(position)
501 || mev.scrollbar()
502 // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
503 // If the selection is non-editable, we do word selection to make it eas ier to use the contextual menu items
504 // available for text selections. But only if we're above text.
505 || !(selection().isContentEditable() || (mev.innerNode() && mev.innerNod e()->isTextNode())))
506 return;
507
508 m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
509
510 if (mev.hitTestResult().isMisspelled())
yosin_UTC9 2015/05/19 09:41:19 nit: Let's use early return pattern.
Miyoung Shin(g) 2015/05/19 16:12:50 Done.
511 selectClosestMisspellingFromMouseEvent(mev);
512 else if (m_frame->editor().behavior().shouldSelectOnContextualMenuClick())
513 selectClosestWordOrLinkFromMouseEvent(mev);
514 }
515
516 void SelectionController::preparePassMousePressEventToSubframe(MouseEventWithHit TestResults& mev)
517 {
518 // If we're clicking into a frame that is selected, the frame will appear
519 // greyed out even though we're clicking on the selection. This looks
520 // really strange (having the whole frame be greyed out), so we deselect the
521 // selection.
522 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position());
523 if (!selection().contains(p))
524 return;
525
526 VisiblePosition visiblePos(
527 mev.innerNode()->layoutObject()->positionForPoint(mev.localPoint()));
528 VisibleSelection newSelection(visiblePos);
529 selection().setSelection(newSelection);
530 }
531
532 void SelectionController::initializeSelectionState()
533 {
534 m_selectionState = SelectionState::HaveNotStartedSelection;
535 }
536
537 void SelectionController::setMouseDownMayStartSelect(bool mayStartSelect)
538 {
539 m_mouseDownMayStartSelect = mayStartSelect;
540 }
541
542 bool SelectionController::mouseDownMayStartSelect() const
543 {
544 return m_mouseDownMayStartSelect;
545 }
546
547 bool SelectionController::singleClickInSelection() const
548 {
549 return m_singleClickInSelection;
550 }
551
552 FrameSelection& SelectionController::selection() const
553 {
554 return *m_selection;
555 }
556
557 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698