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

Side by Side Diff: Source/core/input/EventHandler.cpp

Issue 1113323002: [Reland] Refactor the selection code in EventHandler (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: rebase 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
« no previous file with comments | « Source/core/input/EventHandler.h ('k') | Source/core/input/EventHandlerTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 16 matching lines...) Expand all
27 27
28 #include "config.h" 28 #include "config.h"
29 #include "core/input/EventHandler.h" 29 #include "core/input/EventHandler.h"
30 30
31 #include "bindings/core/v8/ExceptionStatePlaceholder.h" 31 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
32 #include "core/HTMLNames.h" 32 #include "core/HTMLNames.h"
33 #include "core/InputTypeNames.h" 33 #include "core/InputTypeNames.h"
34 #include "core/clipboard/DataObject.h" 34 #include "core/clipboard/DataObject.h"
35 #include "core/clipboard/DataTransfer.h" 35 #include "core/clipboard/DataTransfer.h"
36 #include "core/dom/Document.h" 36 #include "core/dom/Document.h"
37 #include "core/dom/DocumentMarkerController.h"
38 #include "core/dom/TouchList.h" 37 #include "core/dom/TouchList.h"
39 #include "core/dom/shadow/ComposedTreeTraversal.h" 38 #include "core/dom/shadow/ComposedTreeTraversal.h"
40 #include "core/dom/shadow/ShadowRoot.h" 39 #include "core/dom/shadow/ShadowRoot.h"
41 #include "core/editing/Editor.h" 40 #include "core/editing/Editor.h"
42 #include "core/editing/FrameSelection.h" 41 #include "core/editing/FrameSelection.h"
43 #include "core/editing/htmlediting.h" 42 #include "core/editing/SelectionController.h"
44 #include "core/editing/iterators/TextIterator.h"
45 #include "core/events/EventPath.h" 43 #include "core/events/EventPath.h"
46 #include "core/events/KeyboardEvent.h" 44 #include "core/events/KeyboardEvent.h"
47 #include "core/events/MouseEvent.h" 45 #include "core/events/MouseEvent.h"
48 #include "core/events/TextEvent.h" 46 #include "core/events/TextEvent.h"
49 #include "core/events/TouchEvent.h" 47 #include "core/events/TouchEvent.h"
50 #include "core/events/WheelEvent.h" 48 #include "core/events/WheelEvent.h"
51 #include "core/fetch/ImageResource.h" 49 #include "core/fetch/ImageResource.h"
52 #include "core/frame/EventHandlerRegistry.h" 50 #include "core/frame/EventHandlerRegistry.h"
53 #include "core/frame/FrameHost.h" 51 #include "core/frame/FrameHost.h"
54 #include "core/frame/FrameView.h" 52 #include "core/frame/FrameView.h"
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 210
213 // FIXME: we should exclude the document in some cases, as part 211 // FIXME: we should exclude the document in some cases, as part
214 // of crbug.com/410974. 212 // of crbug.com/410974.
215 scrollChain.prepend(frame.document()->documentElement()); 213 scrollChain.prepend(frame.document()->documentElement());
216 } 214 }
217 215
218 EventHandler::EventHandler(LocalFrame* frame) 216 EventHandler::EventHandler(LocalFrame* frame)
219 : m_frame(frame) 217 : m_frame(frame)
220 , m_mousePressed(false) 218 , m_mousePressed(false)
221 , m_capturesDragging(false) 219 , m_capturesDragging(false)
222 , m_mouseDownMayStartSelect(false)
223 , m_mouseDownMayStartDrag(false) 220 , m_mouseDownMayStartDrag(false)
224 , m_mouseDownWasSingleClickInSelection(false) 221 , m_selectionController(SelectionController::create(*frame))
225 , m_selectionInitiationState(HaveNotStartedSelection)
226 , m_hoverTimer(this, &EventHandler::hoverTimerFired) 222 , m_hoverTimer(this, &EventHandler::hoverTimerFired)
227 , m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired) 223 , m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired)
228 , m_mouseDownMayStartAutoscroll(false) 224 , m_mouseDownMayStartAutoscroll(false)
229 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire d) 225 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire d)
230 , m_svgPan(false) 226 , m_svgPan(false)
231 , m_resizeScrollableArea(nullptr) 227 , m_resizeScrollableArea(nullptr)
232 , m_eventHandlerWillResetCapturingMouseEventsNode(0) 228 , m_eventHandlerWillResetCapturingMouseEventsNode(0)
233 , m_clickCount(0) 229 , m_clickCount(0)
234 , m_shouldOnlyFireDragOverEvent(false) 230 , m_shouldOnlyFireDragOverEvent(false)
235 , m_accumulatedRootOverscroll(FloatSize()) 231 , m_accumulatedRootOverscroll(FloatSize())
(...skipping 30 matching lines...) Expand all
266 visitor->trace(m_frameSetBeingResized); 262 visitor->trace(m_frameSetBeingResized);
267 visitor->trace(m_latchedWheelEventNode); 263 visitor->trace(m_latchedWheelEventNode);
268 visitor->trace(m_previousWheelScrolledNode); 264 visitor->trace(m_previousWheelScrolledNode);
269 visitor->trace(m_scrollbarHandlingScrollGesture); 265 visitor->trace(m_scrollbarHandlingScrollGesture);
270 visitor->trace(m_targetForTouchID); 266 visitor->trace(m_targetForTouchID);
271 visitor->trace(m_touchSequenceDocument); 267 visitor->trace(m_touchSequenceDocument);
272 visitor->trace(m_scrollGestureHandlingNode); 268 visitor->trace(m_scrollGestureHandlingNode);
273 visitor->trace(m_previousGestureScrolledNode); 269 visitor->trace(m_previousGestureScrolledNode);
274 visitor->trace(m_lastDeferredTapElement); 270 visitor->trace(m_lastDeferredTapElement);
275 visitor->trace(m_currentScrollChain); 271 visitor->trace(m_currentScrollChain);
272 visitor->trace(m_selectionController);
276 #endif 273 #endif
277 } 274 }
278 275
279 DragState& EventHandler::dragState() 276 DragState& EventHandler::dragState()
280 { 277 {
281 DEFINE_STATIC_LOCAL(Persistent<DragState>, state, (new DragState())); 278 DEFINE_STATIC_LOCAL(Persistent<DragState>, state, (new DragState()));
282 return *state; 279 return *state;
283 } 280 }
284 281
285 void EventHandler::clear() 282 void EventHandler::clear()
(...skipping 24 matching lines...) Expand all
310 m_previousWheelScrolledNode = nullptr; 307 m_previousWheelScrolledNode = nullptr;
311 m_targetForTouchID.clear(); 308 m_targetForTouchID.clear();
312 m_touchSequenceDocument.clear(); 309 m_touchSequenceDocument.clear();
313 m_touchSequenceUserGestureToken.clear(); 310 m_touchSequenceUserGestureToken.clear();
314 m_scrollGestureHandlingNode = nullptr; 311 m_scrollGestureHandlingNode = nullptr;
315 m_lastGestureScrollOverWidget = false; 312 m_lastGestureScrollOverWidget = false;
316 m_previousGestureScrolledNode = nullptr; 313 m_previousGestureScrolledNode = nullptr;
317 m_scrollbarHandlingScrollGesture = nullptr; 314 m_scrollbarHandlingScrollGesture = nullptr;
318 m_maxMouseMovedDuration = 0; 315 m_maxMouseMovedDuration = 0;
319 m_touchPressed = false; 316 m_touchPressed = false;
320 m_mouseDownMayStartSelect = false;
321 m_mouseDownMayStartDrag = false; 317 m_mouseDownMayStartDrag = false;
322 m_lastShowPressTimestamp = 0; 318 m_lastShowPressTimestamp = 0;
323 m_lastDeferredTapElement = nullptr; 319 m_lastDeferredTapElement = nullptr;
324 m_eventHandlerWillResetCapturingMouseEventsNode = false; 320 m_eventHandlerWillResetCapturingMouseEventsNode = false;
325 m_mouseDownWasSingleClickInSelection = false;
326 m_selectionInitiationState = HaveNotStartedSelection;
327 m_mouseDownMayStartAutoscroll = false; 321 m_mouseDownMayStartAutoscroll = false;
328 m_svgPan = false; 322 m_svgPan = false;
329 m_mouseDownPos = IntPoint(); 323 m_mouseDownPos = IntPoint();
330 m_mouseDownTimestamp = 0; 324 m_mouseDownTimestamp = 0;
331 m_longTapShouldInvokeContextMenu = false; 325 m_longTapShouldInvokeContextMenu = false;
332 m_dragStartPos = LayoutPoint(); 326 m_dragStartPos = LayoutPoint();
333 m_offsetFromResizeCorner = LayoutSize(); 327 m_offsetFromResizeCorner = LayoutSize();
334 m_mouseDown = PlatformMouseEvent(); 328 m_mouseDown = PlatformMouseEvent();
335 } 329 }
336 330
337 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved) 331 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved)
338 { 332 {
339 if (nodeToBeRemoved.containsIncludingShadowDOM(m_clickNode.get())) { 333 if (nodeToBeRemoved.containsIncludingShadowDOM(m_clickNode.get())) {
340 // We don't dispatch click events if the mousedown node is removed 334 // We don't dispatch click events if the mousedown node is removed
341 // before a mouseup event. It is compatible with IE and Firefox. 335 // before a mouseup event. It is compatible with IE and Firefox.
342 m_clickNode = nullptr; 336 m_clickNode = nullptr;
343 } 337 }
344 } 338 }
345 339
346 static void setSelectionIfNeeded(FrameSelection& selection, const VisibleSelecti on& newSelection)
347 {
348 if (selection.selection() != newSelection)
349 selection.setSelection(newSelection);
350 }
351
352 static inline bool dispatchSelectStart(Node* node)
353 {
354 if (!node || !node->layoutObject())
355 return true;
356
357 return node->dispatchEvent(Event::createCancelableBubble(EventTypeNames::sel ectstart));
358 }
359
360 static VisibleSelection expandSelectionToRespectUserSelectAll(Node* targetNode, const VisibleSelection& selection)
361 {
362 Node* rootUserSelectAll = Position::rootUserSelectAllForNode(targetNode);
363 if (!rootUserSelectAll)
364 return selection;
365
366 VisibleSelection newSelection(selection);
367 newSelection.setBase(positionBeforeNode(rootUserSelectAll).upstream(CanCross EditingBoundary));
368 newSelection.setExtent(positionAfterNode(rootUserSelectAll).downstream(CanCr ossEditingBoundary));
369
370 return newSelection;
371 }
372
373 bool EventHandler::updateSelectionForMouseDownDispatchingSelectStart(Node* targe tNode, const VisibleSelection& selection, TextGranularity granularity)
374 {
375 if (Position::nodeIsUserSelectNone(targetNode))
376 return false;
377
378 if (!dispatchSelectStart(targetNode))
379 return false;
380
381 if (selection.isRange()) {
382 m_selectionInitiationState = ExtendedSelection;
383 } else {
384 granularity = CharacterGranularity;
385 m_selectionInitiationState = PlacedCaret;
386 }
387
388 m_frame->selection().setNonDirectionalSelectionIfNeeded(selection, granulari ty);
389
390 return true;
391 }
392
393 void EventHandler::selectClosestWordFromHitTestResult(const HitTestResult& resul t, AppendTrailingWhitespace appendTrailingWhitespace)
394 {
395 Node* innerNode = result.innerNode();
396 VisibleSelection newSelection;
397
398 if (innerNode && innerNode->layoutObject()) {
399 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.l ocalPoint()));
400 if (pos.isNotNull()) {
401 newSelection = VisibleSelection(pos);
402 newSelection.expandUsingGranularity(WordGranularity);
403 }
404
405 if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSel ection.isRange())
406 newSelection.appendTrailingWhitespace();
407
408 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelec tionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
409 }
410 }
411
412 void EventHandler::selectClosestMisspellingFromHitTestResult(const HitTestResult & result, AppendTrailingWhitespace appendTrailingWhitespace)
413 {
414 Node* innerNode = result.innerNode();
415 VisibleSelection newSelection;
416
417 if (innerNode && innerNode->layoutObject()) {
418 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.l ocalPoint()));
419 Position start = pos.deepEquivalent();
420 Position end = pos.deepEquivalent();
421 if (pos.isNotNull()) {
422 DocumentMarkerVector markers = innerNode->document().markers().marke rsInRange(makeRange(pos, pos).get(), DocumentMarker::MisspellingMarkers());
423 if (markers.size() == 1) {
424 start.moveToOffset(markers[0]->startOffset());
425 end.moveToOffset(markers[0]->endOffset());
426 newSelection = VisibleSelection(start, end);
427 }
428 }
429
430 if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSel ection.isRange())
431 newSelection.appendTrailingWhitespace();
432
433 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelec tionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
434 }
435 }
436
437 void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestRe sults& result)
438 {
439 if (m_mouseDownMayStartSelect) {
440 selectClosestWordFromHitTestResult(result.hitTestResult(),
441 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrail ingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhi tespace);
442 }
443 }
444
445 void EventHandler::selectClosestMisspellingFromMouseEvent(const MouseEventWithHi tTestResults& result)
446 {
447 if (m_mouseDownMayStartSelect) {
448 selectClosestMisspellingFromHitTestResult(result.hitTestResult(),
449 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrail ingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhi tespace);
450 }
451 }
452
453 void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHit TestResults& result)
454 {
455 if (!result.hitTestResult().isLiveLink())
456 return selectClosestWordFromMouseEvent(result);
457
458 Node* innerNode = result.innerNode();
459
460 if (innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect) {
461 VisibleSelection newSelection;
462 Element* URLElement = result.hitTestResult().URLElement();
463 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(result.l ocalPoint()));
464 if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescenda ntOf(URLElement))
465 newSelection = VisibleSelection::selectionFromContentsOfNode(URLElem ent);
466
467 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelec tionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
468 }
469 }
470
471 bool EventHandler::handleMousePressEventDoubleClick(const MouseEventWithHitTestR esults& event)
472 {
473 TRACE_EVENT0("blink", "EventHandler::handleMousePressEventDoubleClick");
474
475 if (event.event().button() != LeftButton)
476 return false;
477
478 if (m_frame->selection().isRange()) {
479 // A double-click when range is already selected
480 // should not change the selection. So, do not call
481 // selectClosestWordFromMouseEvent, but do set
482 // m_beganSelectingText to prevent handleMouseReleaseEvent
483 // from setting caret selection.
484 m_selectionInitiationState = ExtendedSelection;
485 } else {
486 selectClosestWordFromMouseEvent(event);
487 }
488 return true;
489 }
490
491 bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestR esults& event)
492 {
493 TRACE_EVENT0("blink", "EventHandler::handleMousePressEventTripleClick");
494
495 if (event.event().button() != LeftButton)
496 return false;
497
498 Node* innerNode = event.innerNode();
499 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect))
500 return false;
501
502 VisibleSelection newSelection;
503 VisiblePosition pos(innerNode->layoutObject()->positionForPoint(event.localP oint()));
504 if (pos.isNotNull()) {
505 newSelection = VisibleSelection(pos);
506 newSelection.expandUsingGranularity(ParagraphGranularity);
507 }
508
509 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity);
510 }
511
512 static int textDistance(const Position& start, const Position& end)
513 {
514 RefPtrWillBeRawPtr<Range> range = Range::create(*start.document(), start, en d);
515 return TextIterator::rangeLength(range->startPosition(), range->endPosition( ), true);
516 }
517
518 bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR esults& event)
519 {
520 TRACE_EVENT0("blink", "EventHandler::handleMousePressEventSingleClick");
521
522 m_frame->document()->updateLayoutIgnorePendingStylesheets();
523 Node* innerNode = event.innerNode();
524 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect))
525 return false;
526
527 // Extend the selection if the Shift key is down, unless the click is in a l ink.
528 bool extendSelection = event.event().shiftKey() && !event.isOverLink();
529
530 // Don't restart the selection when the mouse is pressed on an
531 // existing selection so we can allow for text dragging.
532 if (FrameView* view = m_frame->view()) {
533 LayoutPoint vPoint = view->rootFrameToContents(event.event().position()) ;
534 if (!extendSelection && m_frame->selection().contains(vPoint)) {
535 m_mouseDownWasSingleClickInSelection = true;
536 return false;
537 }
538 }
539
540 VisiblePosition visiblePos(innerNode->layoutObject()->positionForPoint(event .localPoint()));
541 if (visiblePos.isNull())
542 visiblePos = VisiblePosition(firstPositionInOrBeforeNode(innerNode), DOW NSTREAM);
543 Position pos = visiblePos.deepEquivalent();
544
545 VisibleSelection newSelection = m_frame->selection().selection();
546 TextGranularity granularity = CharacterGranularity;
547
548 if (extendSelection && newSelection.isCaretOrRange()) {
549 VisibleSelection selectionInUserSelectAll(expandSelectionToRespectUserSe lectAll(innerNode, VisibleSelection(VisiblePosition(pos))));
550 if (selectionInUserSelectAll.isRange()) {
551 if (comparePositions(selectionInUserSelectAll.start(), newSelection. start()) < 0)
552 pos = selectionInUserSelectAll.start();
553 else if (comparePositions(newSelection.end(), selectionInUserSelectA ll.end()) < 0)
554 pos = selectionInUserSelectAll.end();
555 }
556
557 if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional() ) {
558 if (pos.isNotNull()) {
559 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click d eselects when selection
560 // was created right-to-left
561 Position start = newSelection.start();
562 Position end = newSelection.end();
563 int distanceToStart = textDistance(start, pos);
564 int distanceToEnd = textDistance(pos, end);
565 if (distanceToStart <= distanceToEnd)
566 newSelection = VisibleSelection(end, pos);
567 else
568 newSelection = VisibleSelection(start, pos);
569 }
570 } else {
571 newSelection.setExtent(pos);
572 }
573
574 if (m_frame->selection().granularity() != CharacterGranularity) {
575 granularity = m_frame->selection().granularity();
576 newSelection.expandUsingGranularity(m_frame->selection().granularity ());
577 }
578 } else {
579 newSelection = expandSelectionToRespectUserSelectAll(innerNode, VisibleS election(visiblePos));
580 }
581
582 // Updating the selection is considered side-effect of the event and so it d oesn't impact the handled state.
583 updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, g ranularity);
584 return false;
585 }
586
587 static inline bool canMouseDownStartSelect(Node* node)
588 {
589 if (!node || !node->layoutObject())
590 return true;
591
592 if (!node->canStartSelection())
593 return false;
594
595 return true;
596 }
597
598 bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve nt) 340 bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve nt)
599 { 341 {
600 TRACE_EVENT0("blink", "EventHandler::handleMousePressEvent"); 342 TRACE_EVENT0("blink", "EventHandler::handleMousePressEvent");
601 343
602 // Reset drag state. 344 // Reset drag state.
603 dragState().m_dragSrc = nullptr; 345 dragState().m_dragSrc = nullptr;
604 346
605 cancelFakeMouseMoveEvent(); 347 cancelFakeMouseMoveEvent();
606 348
607 m_frame->document()->updateLayoutIgnorePendingStylesheets(); 349 m_frame->document()->updateLayoutIgnorePendingStylesheets();
608 350
609 if (FrameView* frameView = m_frame->view()) { 351 if (FrameView* frameView = m_frame->view()) {
610 if (frameView->isPointInScrollbarCorner(event.event().position())) 352 if (frameView->isPointInScrollbarCorner(event.event().position()))
611 return false; 353 return false;
612 } 354 }
613 355
614 bool singleClick = event.event().clickCount() <= 1; 356 bool singleClick = event.event().clickCount() <= 1;
615 357
616 // If we got the event back, that must mean it wasn't prevented,
617 // so it's allowed to start a drag or selection if it wasn't in a scrollbar.
618 m_mouseDownMayStartSelect = canMouseDownStartSelect(event.innerNode()) && !e vent.scrollbar();
619
620 m_mouseDownMayStartDrag = singleClick; 358 m_mouseDownMayStartDrag = singleClick;
621 359
622 m_mouseDownWasSingleClickInSelection = false; 360 selectionController().handleMousePressEvent(event);
623 361
624 m_mouseDown = event.event(); 362 m_mouseDown = event.event();
625 363
626 if (m_frame->document()->isSVGDocument() && m_frame->document()->accessSVGEx tensions().zoomAndPanEnabled()) { 364 if (m_frame->document()->isSVGDocument() && m_frame->document()->accessSVGEx tensions().zoomAndPanEnabled()) {
627 if (event.event().shiftKey() && singleClick) { 365 if (event.event().shiftKey() && singleClick) {
628 m_svgPan = true; 366 m_svgPan = true;
629 m_frame->document()->accessSVGExtensions().startPan(m_frame->view()- >rootFrameToContents(event.event().position())); 367 m_frame->document()->accessSVGExtensions().startPan(m_frame->view()- >rootFrameToContents(event.event().position()));
630 return true; 368 return true;
631 } 369 }
632 } 370 }
633 371
634 // We don't do this at the start of mouse down handling, 372 // We don't do this at the start of mouse down handling,
635 // because we don't want to do it until we know we didn't hit a widget. 373 // because we don't want to do it until we know we didn't hit a widget.
636 if (singleClick) 374 if (singleClick)
637 focusDocumentView(); 375 focusDocumentView();
638 376
639 Node* innerNode = event.innerNode(); 377 Node* innerNode = event.innerNode();
640 378
641 m_mousePressNode = innerNode; 379 m_mousePressNode = innerNode;
642 m_dragStartPos = event.event().position(); 380 m_dragStartPos = event.event().position();
643 381
644 bool swallowEvent = false; 382 bool swallowEvent = false;
645 m_mousePressed = true; 383 m_mousePressed = true;
646 m_selectionInitiationState = HaveNotStartedSelection; 384 selectionController().initializeSelectionState();
647 385
648 if (event.event().clickCount() == 2) 386 if (event.event().clickCount() == 2)
649 swallowEvent = handleMousePressEventDoubleClick(event); 387 swallowEvent = selectionController().handleMousePressEventDoubleClick(ev ent);
650 else if (event.event().clickCount() >= 3) 388 else if (event.event().clickCount() >= 3)
651 swallowEvent = handleMousePressEventTripleClick(event); 389 swallowEvent = selectionController().handleMousePressEventTripleClick(ev ent);
652 else 390 else
653 swallowEvent = handleMousePressEventSingleClick(event); 391 swallowEvent = selectionController().handleMousePressEventSingleClick(ev ent);
654 392
655 m_mouseDownMayStartAutoscroll = m_mouseDownMayStartSelect 393 m_mouseDownMayStartAutoscroll = selectionController().mouseDownMayStartSelec t()
656 || (m_mousePressNode && m_mousePressNode->layoutBox() && m_mousePressNod e->layoutBox()->canBeProgramaticallyScrolled()); 394 || (m_mousePressNode && m_mousePressNode->layoutBox() && m_mousePressNod e->layoutBox()->canBeProgramaticallyScrolled());
657 395
658 return swallowEvent; 396 return swallowEvent;
659 } 397 }
660 398
661 bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e vent) 399 bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e vent)
662 { 400 {
663 TRACE_EVENT0("blink", "EventHandler::handleMouseDraggedEvent"); 401 TRACE_EVENT0("blink", "EventHandler::handleMouseDraggedEvent");
664 402
665 // While resetting m_mousePressed here may seem out of place, it turns out 403 // While resetting m_mousePressed here may seem out of place, it turns out
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 440
703 m_mouseDownMayStartDrag = false; 441 m_mouseDownMayStartDrag = false;
704 442
705 if (m_mouseDownMayStartAutoscroll && !panScrollInProgress()) { 443 if (m_mouseDownMayStartAutoscroll && !panScrollInProgress()) {
706 if (AutoscrollController* controller = autoscrollController()) { 444 if (AutoscrollController* controller = autoscrollController()) {
707 controller->startAutoscrollForSelection(layoutObject); 445 controller->startAutoscrollForSelection(layoutObject);
708 m_mouseDownMayStartAutoscroll = false; 446 m_mouseDownMayStartAutoscroll = false;
709 } 447 }
710 } 448 }
711 449
712 if (m_selectionInitiationState != ExtendedSelection) { 450 selectionController().handleMouseDraggedEvent(event, m_mouseDownPos, m_dragS tartPos, m_mousePressNode.get(), m_lastKnownMousePosition);
713 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active );
714 HitTestResult result(request, m_mouseDownPos);
715 m_frame->document()->layoutView()->hitTest(result);
716
717 updateSelectionForMouseDrag(result);
718 }
719 updateSelectionForMouseDrag(event.hitTestResult());
720 return true; 451 return true;
721 } 452 }
722 453
723 void EventHandler::updateSelectionForMouseDrag() 454 void EventHandler::updateSelectionForMouseDrag()
724 { 455 {
725 FrameView* view = m_frame->view(); 456 selectionController().updateSelectionForMouseDrag(m_mousePressNode.get(), m_ dragStartPos, m_lastKnownMousePosition);
726 if (!view)
727 return;
728 LayoutView* layoutObject = m_frame->contentLayoutObject();
729 if (!layoutObject)
730 return;
731
732 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | H itTestRequest::Move);
733 HitTestResult result(request, view->rootFrameToContents(m_lastKnownMousePosi tion));
734 layoutObject->hitTest(result);
735 updateSelectionForMouseDrag(result);
736 }
737
738 void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResul t)
739 {
740 if (!m_mouseDownMayStartSelect)
741 return;
742
743 Node* target = hitTestResult.innerNode();
744 if (!target)
745 return;
746
747 VisiblePosition targetPosition = m_frame->selection().selection().visiblePos itionRespectingEditingBoundary(hitTestResult.localPoint(), target);
748 // Don't modify the selection if we're not on a node.
749 if (targetPosition.isNull())
750 return;
751
752 // Restart the selection if this is the first mouse move. This work is usual ly
753 // done in handleMousePressEvent, but not if the mouse press was on an exist ing selection.
754 VisibleSelection newSelection = m_frame->selection().selection();
755
756 // Special case to limit selection to the containing block for SVG text.
757 // FIXME: Isn't there a better non-SVG-specific way to do this?
758 if (Node* selectionBaseNode = newSelection.base().deprecatedNode()) {
759 if (LayoutObject* selectionBaseLayoutObject = selectionBaseNode->layoutO bject()) {
760 if (selectionBaseLayoutObject->isSVGText()) {
761 if (target->layoutObject()->containingBlock() != selectionBaseLa youtObject->containingBlock())
762 return;
763 }
764 }
765 }
766
767 if (m_selectionInitiationState == HaveNotStartedSelection && !dispatchSelect Start(target))
768 return;
769
770 if (m_selectionInitiationState != ExtendedSelection) {
771 // Always extend selection here because it's caused by a mouse drag
772 m_selectionInitiationState = ExtendedSelection;
773 newSelection = VisibleSelection(targetPosition);
774 }
775
776 if (RuntimeEnabledFeatures::userSelectAllEnabled()) {
777 Node* rootUserSelectAllForMousePressNode = Position::rootUserSelectAllFo rNode(m_mousePressNode.get());
778 if (rootUserSelectAllForMousePressNode && rootUserSelectAllForMousePress Node == Position::rootUserSelectAllForNode(target)) {
779 newSelection.setBase(positionBeforeNode(rootUserSelectAllForMousePre ssNode).upstream(CanCrossEditingBoundary));
780 newSelection.setExtent(positionAfterNode(rootUserSelectAllForMousePr essNode).downstream(CanCrossEditingBoundary));
781 } else {
782 // Reset base for user select all when base is inside user-select-al l area and extent < base.
783 if (rootUserSelectAllForMousePressNode && comparePositions(target->l ayoutObject()->positionForPoint(hitTestResult.localPoint()), m_mousePressNode->l ayoutObject()->positionForPoint(m_dragStartPos)) < 0)
784 newSelection.setBase(positionAfterNode(rootUserSelectAllForMouse PressNode).downstream(CanCrossEditingBoundary));
785
786 Node* rootUserSelectAllForTarget = Position::rootUserSelectAllForNod e(target);
787 if (rootUserSelectAllForTarget && m_mousePressNode->layoutObject() & & comparePositions(target->layoutObject()->positionForPoint(hitTestResult.localP oint()), m_mousePressNode->layoutObject()->positionForPoint(m_dragStartPos)) < 0 )
788 newSelection.setExtent(positionBeforeNode(rootUserSelectAllForTa rget).upstream(CanCrossEditingBoundary));
789 else if (rootUserSelectAllForTarget && m_mousePressNode->layoutObjec t())
790 newSelection.setExtent(positionAfterNode(rootUserSelectAllForTar get).downstream(CanCrossEditingBoundary));
791 else
792 newSelection.setExtent(targetPosition);
793 }
794 } else {
795 newSelection.setExtent(targetPosition);
796 }
797
798 if (m_frame->selection().granularity() != CharacterGranularity)
799 newSelection.expandUsingGranularity(m_frame->selection().granularity());
800
801 m_frame->selection().setNonDirectionalSelectionIfNeeded(newSelection, m_fram e->selection().granularity(),
802 FrameSelection::AdjustEndpointsAtBidiBoundary);
803 } 457 }
804 458
805 bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e vent) 459 bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e vent)
806 { 460 {
807 AutoscrollController* controller = autoscrollController(); 461 AutoscrollController* controller = autoscrollController();
808 if (controller && controller->autoscrollInProgress()) 462 if (controller && controller->autoscrollInProgress())
809 stopAutoscroll(); 463 stopAutoscroll();
810 464
811 // Used to prevent mouseMoveEvent from initiating a drag before 465 // Used to prevent mouseMoveEvent from initiating a drag before
812 // the mouse is pressed again. 466 // the mouse is pressed again.
813 m_mousePressed = false; 467 m_mousePressed = false;
814 m_capturesDragging = false; 468 m_capturesDragging = false;
815 m_mouseDownMayStartDrag = false; 469 m_mouseDownMayStartDrag = false;
816 m_mouseDownMayStartSelect = false;
817 m_mouseDownMayStartAutoscroll = false; 470 m_mouseDownMayStartAutoscroll = false;
818 471
819 bool handled = false; 472 return selectionController().handleMouseReleaseEvent(event, m_dragStartPos);
820
821 // Clear the selection if the mouse didn't move after the last mouse
822 // press and it's not a context menu click. We do this so when clicking
823 // on the selection, the selection goes away. However, if we are
824 // editing, place the caret.
825 if (m_mouseDownWasSingleClickInSelection && m_selectionInitiationState != Ex tendedSelection
826 && m_dragStartPos == event.event().position()
827 && m_frame->selection().isRange()
828 && event.event().button() != RightButton) {
829 VisibleSelection newSelection;
830 Node* node = event.innerNode();
831 bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBr owsingEnabled();
832 if (node && node->layoutObject() && (caretBrowsing || node->hasEditableS tyle())) {
833 VisiblePosition pos = VisiblePosition(node->layoutObject()->position ForPoint(event.localPoint()));
834 newSelection = VisibleSelection(pos);
835 }
836
837 setSelectionIfNeeded(m_frame->selection(), newSelection);
838
839 handled = true;
840 }
841
842 m_frame->selection().notifyLayoutObjectOfSelectionChange(UserTriggered);
843
844 m_frame->selection().selectFrameElementInParentIfFullySelected();
845
846 if (event.event().button() == MiddleButton && !event.isOverLink()) {
847 // Ignore handled, since we want to paste to where the caret was placed anyway.
848 handled = handlePasteGlobalSelection(event.event()) || handled;
849 }
850
851 return handled;
852 } 473 }
853 474
854 #if OS(WIN) 475 #if OS(WIN)
855 476
856 void EventHandler::startPanScrolling(LayoutObject* layoutObject) 477 void EventHandler::startPanScrolling(LayoutObject* layoutObject)
857 { 478 {
858 if (!layoutObject->isBox()) 479 if (!layoutObject->isBox())
859 return; 480 return;
860 AutoscrollController* controller = autoscrollController(); 481 AutoscrollController* controller = autoscrollController();
861 if (!controller) 482 if (!controller)
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 854
1234 bool inResizer = false; 855 bool inResizer = false;
1235 LayoutObject* layoutObject = node ? node->layoutObject() : nullptr; 856 LayoutObject* layoutObject = node ? node->layoutObject() : nullptr;
1236 if (layoutObject && m_frame->view()) { 857 if (layoutObject && m_frame->view()) {
1237 DeprecatedPaintLayer* layer = layoutObject->enclosingLayer(); 858 DeprecatedPaintLayer* layer = layoutObject->enclosingLayer();
1238 inResizer = layer->scrollableArea() && layer->scrollableArea()->isPointI nResizeControl(result.roundedPointInMainFrame(), ResizerForPointer); 859 inResizer = layer->scrollableArea() && layer->scrollableArea()->isPointI nResizeControl(result.roundedPointInMainFrame(), ResizerForPointer);
1239 } 860 }
1240 861
1241 // During selection, use an I-beam no matter what we're over. 862 // During selection, use an I-beam no matter what we're over.
1242 // If a drag may be starting or we're capturing mouse events for a particula r node, don't treat this as a selection. 863 // If a drag may be starting or we're capturing mouse events for a particula r node, don't treat this as a selection.
1243 if (m_mousePressed && m_mouseDownMayStartSelect 864 if (m_mousePressed && selectionController().mouseDownMayStartSelect()
1244 && !m_mouseDownMayStartDrag 865 && !m_mouseDownMayStartDrag
1245 && m_frame->selection().isCaretOrRange() 866 && m_frame->selection().isCaretOrRange()
1246 && !m_capturingMouseEventsNode) { 867 && !m_capturingMouseEventsNode) {
1247 return iBeam; 868 return iBeam;
1248 } 869 }
1249 870
1250 if ((editable || (layoutObject && layoutObject->isText() && node->canStartSe lection())) && !inResizer && !result.scrollbar()) 871 if ((editable || (layoutObject && layoutObject->isText() && node->canStartSe lection())) && !inResizer && !result.scrollbar())
1251 return iBeam; 872 return iBeam;
1252 return pointerCursor(); 873 return pointerCursor();
1253 } 874 }
(...skipping 16 matching lines...) Expand all
1270 m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken = gestureIndicator.currentToken(); 891 m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken = gestureIndicator.currentToken();
1271 892
1272 cancelFakeMouseMoveEvent(); 893 cancelFakeMouseMoveEvent();
1273 if (m_eventHandlerWillResetCapturingMouseEventsNode) 894 if (m_eventHandlerWillResetCapturingMouseEventsNode)
1274 m_capturingMouseEventsNode = nullptr; 895 m_capturingMouseEventsNode = nullptr;
1275 m_mousePressed = true; 896 m_mousePressed = true;
1276 m_capturesDragging = true; 897 m_capturesDragging = true;
1277 setLastKnownMousePosition(mouseEvent); 898 setLastKnownMousePosition(mouseEvent);
1278 m_mouseDownTimestamp = mouseEvent.timestamp(); 899 m_mouseDownTimestamp = mouseEvent.timestamp();
1279 m_mouseDownMayStartDrag = false; 900 m_mouseDownMayStartDrag = false;
1280 m_mouseDownMayStartSelect = false; 901 selectionController().setMouseDownMayStartSelect(false);
1281 m_mouseDownMayStartAutoscroll = false; 902 m_mouseDownMayStartAutoscroll = false;
1282 if (FrameView* view = m_frame->view()) { 903 if (FrameView* view = m_frame->view()) {
1283 m_mouseDownPos = view->rootFrameToContents(mouseEvent.position()); 904 m_mouseDownPos = view->rootFrameToContents(mouseEvent.position());
1284 } else { 905 } else {
1285 invalidateClick(); 906 invalidateClick();
1286 return false; 907 return false;
1287 } 908 }
1288 909
1289 HitTestRequest request(HitTestRequest::Active); 910 HitTestRequest request(HitTestRequest::Active);
1290 // Save the document point we generate in case the window coordinate is inva lidated by what happens 911 // Save the document point we generate in case the window coordinate is inva lidated by what happens
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
1641 1262
1642 bool swallowMouseReleaseEvent = false; 1263 bool swallowMouseReleaseEvent = false;
1643 if (!swallowMouseUpEvent) 1264 if (!swallowMouseUpEvent)
1644 swallowMouseReleaseEvent = handleMouseReleaseEvent(mev); 1265 swallowMouseReleaseEvent = handleMouseReleaseEvent(mev);
1645 1266
1646 invalidateClick(); 1267 invalidateClick();
1647 1268
1648 return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent; 1269 return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
1649 } 1270 }
1650 1271
1651 bool EventHandler::handlePasteGlobalSelection(const PlatformMouseEvent& mouseEve nt)
1652 {
1653 // If the event was a middle click, attempt to copy global selection in afte r
1654 // the newly set caret position.
1655 //
1656 // This code is called from either the mouse up or mouse down handling. Ther e
1657 // is some debate about when the global selection is pasted:
1658 // xterm: pastes on up.
1659 // GTK: pastes on down.
1660 // Qt: pastes on up.
1661 // Firefox: pastes on up.
1662 // Chromium: pastes on up.
1663 //
1664 // There is something of a webcompat angle to this well, as highlighted by
1665 // crbug.com/14608. Pages can clear text boxes 'onclick' and, if we paste on
1666 // down then the text is pasted just before the onclick handler runs and
1667 // clears the text box. So it's important this happens after the event
1668 // handlers have been fired.
1669 if (mouseEvent.type() != PlatformEvent::MouseReleased)
1670 return false;
1671
1672 if (!m_frame->page())
1673 return false;
1674 Frame* focusFrame = m_frame->page()->focusController().focusedOrMainFrame();
1675 // Do not paste here if the focus was moved somewhere else.
1676 if (m_frame == focusFrame && m_frame->editor().behavior().supportsGlobalSele ction())
1677 return m_frame->editor().command("PasteGlobalSelection").execute();
1678
1679 return false;
1680 }
1681
1682
1683 bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTa rget, const PlatformMouseEvent& event, DataTransfer* dataTransfer) 1272 bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTa rget, const PlatformMouseEvent& event, DataTransfer* dataTransfer)
1684 { 1273 {
1685 FrameView* view = m_frame->view(); 1274 FrameView* view = m_frame->view();
1686 1275
1687 // FIXME: We might want to dispatch a dragleave even if the view is gone. 1276 // FIXME: We might want to dispatch a dragleave even if the view is gone.
1688 if (!view) 1277 if (!view)
1689 return false; 1278 return false;
1690 1279
1691 RefPtrWillBeRawPtr<MouseEvent> me = MouseEvent::create(eventType, 1280 RefPtrWillBeRawPtr<MouseEvent> me = MouseEvent::create(eventType,
1692 true, true, m_frame->document()->domWindow(), 1281 true, true, m_frame->document()->domWindow(),
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after
2508 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE vent); 2097 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE vent);
2509 m_mouseDownMayStartDrag = true; 2098 m_mouseDownMayStartDrag = true;
2510 dragState().m_dragSrc = nullptr; 2099 dragState().m_dragSrc = nullptr;
2511 m_mouseDownPos = m_frame->view()->rootFrameToContents(mouseDragEvent.pos ition()); 2100 m_mouseDownPos = m_frame->view()->rootFrameToContents(mouseDragEvent.pos ition());
2512 RefPtrWillBeRawPtr<FrameView> protector(m_frame->view()); 2101 RefPtrWillBeRawPtr<FrameView> protector(m_frame->view());
2513 if (handleDrag(mev, DragInitiator::Touch)) { 2102 if (handleDrag(mev, DragInitiator::Touch)) {
2514 m_longTapShouldInvokeContextMenu = true; 2103 m_longTapShouldInvokeContextMenu = true;
2515 return true; 2104 return true;
2516 } 2105 }
2517 } 2106 }
2518 #if OS(ANDROID) 2107
2519 bool shouldLongPressSelectWord = true; 2108 IntPoint hitTestPoint = m_frame->view()->rootFrameToContents(gestureEvent.po sition());
2520 #else 2109 HitTestResult result = hitTestResultAtPoint(hitTestPoint);
2521 bool shouldLongPressSelectWord = m_frame->settings() && m_frame->settings()- >touchEditingEnabled(); 2110 if (selectionController().handleGestureLongPress(gestureEvent, result)) {
2522 #endif 2111 focusDocumentView();
2523 if (shouldLongPressSelectWord) { 2112 return true;
2524 IntPoint hitTestPoint = m_frame->view()->rootFrameToContents(gestureEven t.position());
2525 HitTestResult result = hitTestResultAtPoint(hitTestPoint);
2526 Node* innerNode = result.innerNode();
2527 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode()
2528 #if OS(ANDROID)
2529 || innerNode->canStartSelection()
2530 #endif
2531 )) {
2532 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp ace);
2533 if (m_frame->selection().isRange()) {
2534 focusDocumentView();
2535 return true;
2536 }
2537 }
2538 } 2113 }
2114
2539 return sendContextMenuEventForGesture(targetedEvent); 2115 return sendContextMenuEventForGesture(targetedEvent);
2540 } 2116 }
2541 2117
2542 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta rgetedEvent) 2118 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta rgetedEvent)
2543 { 2119 {
2544 #if !OS(ANDROID) 2120 #if !OS(ANDROID)
2545 if (m_longTapShouldInvokeContextMenu) { 2121 if (m_longTapShouldInvokeContextMenu) {
2546 m_longTapShouldInvokeContextMenu = false; 2122 m_longTapShouldInvokeContextMenu = false;
2547 return sendContextMenuEventForGesture(targetedEvent); 2123 return sendContextMenuEventForGesture(targetedEvent);
2548 } 2124 }
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
3034 FrameView* v = m_frame->view(); 2610 FrameView* v = m_frame->view();
3035 if (!v) 2611 if (!v)
3036 return false; 2612 return false;
3037 2613
3038 // Clear mouse press state to avoid initiating a drag while context menu is up. 2614 // Clear mouse press state to avoid initiating a drag while context menu is up.
3039 m_mousePressed = false; 2615 m_mousePressed = false;
3040 LayoutPoint positionInContents = v->rootFrameToContents(event.position()); 2616 LayoutPoint positionInContents = v->rootFrameToContents(event.position());
3041 HitTestRequest request(HitTestRequest::Active); 2617 HitTestRequest request(HitTestRequest::Active);
3042 MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(re quest, positionInContents, event); 2618 MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(re quest, positionInContents, event);
3043 2619
3044 if (!m_frame->selection().contains(positionInContents) 2620 selectionController().sendContextMenuEvent(mev, positionInContents);
3045 && !mev.scrollbar()
3046 // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
3047 // If the selection is non-editable, we do word selection to make it eas ier to use the contextual menu items
3048 // available for text selections. But only if we're above text.
3049 && (m_frame->selection().isContentEditable() || (mev.innerNode() && mev. innerNode()->isTextNode()))) {
3050 m_mouseDownMayStartSelect = true; // context menu events are always allo wed to perform a selection
3051
3052 if (mev.hitTestResult().isMisspelled())
3053 selectClosestMisspellingFromMouseEvent(mev);
3054 else if (m_frame->editor().behavior().shouldSelectOnContextualMenuClick( ))
3055 selectClosestWordOrLinkFromMouseEvent(mev);
3056 }
3057 2621
3058 Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode() ; 2622 Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode() ;
3059 return !dispatchMouseEvent(EventTypeNames::contextmenu, targetNode, 0, event , false); 2623 return !dispatchMouseEvent(EventTypeNames::contextmenu, targetNode, 0, event , false);
3060 } 2624 }
3061 2625
3062 bool EventHandler::sendContextMenuEventForKey(Element* overrideTargetElement) 2626 bool EventHandler::sendContextMenuEventForKey(Element* overrideTargetElement)
3063 { 2627 {
3064 FrameView* view = m_frame->view(); 2628 FrameView* view = m_frame->view();
3065 if (!view) 2629 if (!view)
3066 return false; 2630 return false;
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
3555 dragState().m_dragSrc = m_frame->page()->dragController().draggableN ode(m_frame, node, m_mouseDownPos, selectionDragPolicy, dragState().m_dragType); 3119 dragState().m_dragSrc = m_frame->page()->dragController().draggableN ode(m_frame, node, m_mouseDownPos, selectionDragPolicy, dragState().m_dragType);
3556 } else { 3120 } else {
3557 dragState().m_dragSrc = nullptr; 3121 dragState().m_dragSrc = nullptr;
3558 } 3122 }
3559 3123
3560 if (!dragState().m_dragSrc) 3124 if (!dragState().m_dragSrc)
3561 m_mouseDownMayStartDrag = false; // no element is draggable 3125 m_mouseDownMayStartDrag = false; // no element is draggable
3562 } 3126 }
3563 3127
3564 if (!m_mouseDownMayStartDrag) 3128 if (!m_mouseDownMayStartDrag)
3565 return initiator == DragInitiator::Mouse && !mouseDownMayStartSelect() & & !m_mouseDownMayStartAutoscroll; 3129 return initiator == DragInitiator::Mouse && !selectionController().mouse DownMayStartSelect() && !m_mouseDownMayStartAutoscroll;
3566 3130
3567 // We are starting a text/image/url drag, so the cursor should be an arrow 3131 // We are starting a text/image/url drag, so the cursor should be an arrow
3568 // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and d rop (default to pointer). 3132 // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and d rop (default to pointer).
3569 m_frame->view()->setCursor(pointerCursor()); 3133 m_frame->view()->setCursor(pointerCursor());
3570 3134
3571 if (initiator == DragInitiator::Mouse && !dragHysteresisExceeded(event.event ().position())) 3135 if (initiator == DragInitiator::Mouse && !dragHysteresisExceeded(event.event ().position()))
3572 return true; 3136 return true;
3573 3137
3574 // Once we're past the hysteresis point, we don't want to treat this gesture as a click 3138 // Once we're past the hysteresis point, we don't want to treat this gesture as a click
3575 invalidateClick(); 3139 invalidateClick();
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
4140 3704
4141 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event) 3705 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
4142 { 3706 {
4143 m_mousePositionIsUnknown = false; 3707 m_mousePositionIsUnknown = false;
4144 m_lastKnownMousePosition = event.position(); 3708 m_lastKnownMousePosition = event.position();
4145 m_lastKnownMouseGlobalPosition = event.globalPosition(); 3709 m_lastKnownMouseGlobalPosition = event.globalPosition();
4146 } 3710 }
4147 3711
4148 bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& m ev, LocalFrame* subframe) 3712 bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& m ev, LocalFrame* subframe)
4149 { 3713 {
4150 // If we're clicking into a frame that is selected, the frame will appear 3714 selectionController().passMousePressEventToSubframe(mev);
4151 // greyed out even though we're clicking on the selection. This looks
4152 // really strange (having the whole frame be greyed out), so we deselect the
4153 // selection.
4154 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position());
4155 if (m_frame->selection().contains(p)) {
4156 VisiblePosition visiblePos(
4157 mev.innerNode()->layoutObject()->positionForPoint(mev.localPoint())) ;
4158 VisibleSelection newSelection(visiblePos);
4159 m_frame->selection().setSelection(newSelection);
4160 }
4161
4162 subframe->eventHandler().handleMousePressEvent(mev.event()); 3715 subframe->eventHandler().handleMousePressEvent(mev.event());
4163 return true; 3716 return true;
4164 } 3717 }
4165 3718
4166 bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& me v, LocalFrame* subframe, HitTestResult* hoveredNode) 3719 bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& me v, LocalFrame* subframe, HitTestResult* hoveredNode)
4167 { 3720 {
4168 if (m_mouseDownMayStartDrag) 3721 if (m_mouseDownMayStartDrag)
4169 return false; 3722 return false;
4170 subframe->eventHandler().handleMouseMoveOrLeaveEvent(mev.event(), hoveredNod e); 3723 subframe->eventHandler().handleMouseMoveOrLeaveEvent(mev.event(), hoveredNod e);
4171 return true; 3724 return true;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
4203 unsigned EventHandler::accessKeyModifiers() 3756 unsigned EventHandler::accessKeyModifiers()
4204 { 3757 {
4205 #if OS(MACOSX) 3758 #if OS(MACOSX)
4206 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; 3759 return PlatformEvent::CtrlKey | PlatformEvent::AltKey;
4207 #else 3760 #else
4208 return PlatformEvent::AltKey; 3761 return PlatformEvent::AltKey;
4209 #endif 3762 #endif
4210 } 3763 }
4211 3764
4212 } // namespace blink 3765 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/input/EventHandler.h ('k') | Source/core/input/EventHandlerTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698