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

Side by Side Diff: Source/core/page/EventHandler.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
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/page/EventHandler.h" 29 #include "core/page/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 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 211
214 // FIXME: we should exclude the document in some cases, as part 212 // FIXME: we should exclude the document in some cases, as part
215 // of crbug.com/410974. 213 // of crbug.com/410974.
216 scrollChain.prepend(frame.document()->documentElement()); 214 scrollChain.prepend(frame.document()->documentElement());
217 } 215 }
218 216
219 EventHandler::EventHandler(LocalFrame* frame) 217 EventHandler::EventHandler(LocalFrame* frame)
220 : m_frame(frame) 218 : m_frame(frame)
221 , m_mousePressed(false) 219 , m_mousePressed(false)
222 , m_capturesDragging(false) 220 , m_capturesDragging(false)
223 , m_mouseDownMayStartSelect(false)
224 , m_mouseDownMayStartDrag(false) 221 , m_mouseDownMayStartDrag(false)
225 , m_mouseDownWasSingleClickInSelection(false) 222 , m_selectionController(SelectionController::create(frame, &frame->selection ()))
yosin_UTC9 2015/05/19 09:41:19 nit: We don't need to pass |FrameSelection| in sec
Miyoung Shin(g) 2015/05/19 16:12:51 Done.
226 , m_selectionInitiationState(HaveNotStartedSelection)
227 , m_hoverTimer(this, &EventHandler::hoverTimerFired) 223 , m_hoverTimer(this, &EventHandler::hoverTimerFired)
228 , m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired) 224 , m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired)
229 , m_mouseDownMayStartAutoscroll(false) 225 , m_mouseDownMayStartAutoscroll(false)
230 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire d) 226 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire d)
231 , m_svgPan(false) 227 , m_svgPan(false)
232 , m_resizeScrollableArea(nullptr) 228 , m_resizeScrollableArea(nullptr)
233 , m_eventHandlerWillResetCapturingMouseEventsNode(0) 229 , m_eventHandlerWillResetCapturingMouseEventsNode(0)
234 , m_clickCount(0) 230 , m_clickCount(0)
235 , m_shouldOnlyFireDragOverEvent(false) 231 , m_shouldOnlyFireDragOverEvent(false)
236 , m_mousePositionIsUnknown(true) 232 , m_mousePositionIsUnknown(true)
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 m_previousWheelScrolledNode = nullptr; 306 m_previousWheelScrolledNode = nullptr;
311 m_targetForTouchID.clear(); 307 m_targetForTouchID.clear();
312 m_touchSequenceDocument.clear(); 308 m_touchSequenceDocument.clear();
313 m_touchSequenceUserGestureToken.clear(); 309 m_touchSequenceUserGestureToken.clear();
314 m_scrollGestureHandlingNode = nullptr; 310 m_scrollGestureHandlingNode = nullptr;
315 m_lastGestureScrollOverWidget = false; 311 m_lastGestureScrollOverWidget = false;
316 m_previousGestureScrolledNode = nullptr; 312 m_previousGestureScrolledNode = nullptr;
317 m_scrollbarHandlingScrollGesture = nullptr; 313 m_scrollbarHandlingScrollGesture = nullptr;
318 m_maxMouseMovedDuration = 0; 314 m_maxMouseMovedDuration = 0;
319 m_touchPressed = false; 315 m_touchPressed = false;
320 m_mouseDownMayStartSelect = false;
321 m_mouseDownMayStartDrag = false; 316 m_mouseDownMayStartDrag = false;
322 m_lastShowPressTimestamp = 0; 317 m_lastShowPressTimestamp = 0;
323 m_lastDeferredTapElement = nullptr; 318 m_lastDeferredTapElement = nullptr;
324 m_eventHandlerWillResetCapturingMouseEventsNode = false; 319 m_eventHandlerWillResetCapturingMouseEventsNode = false;
325 m_mouseDownWasSingleClickInSelection = false;
326 m_selectionInitiationState = HaveNotStartedSelection;
327 m_mouseDownMayStartAutoscroll = false; 320 m_mouseDownMayStartAutoscroll = false;
328 m_svgPan = false; 321 m_svgPan = false;
329 m_mouseDownPos = IntPoint(); 322 m_mouseDownPos = IntPoint();
330 m_mouseDownTimestamp = 0; 323 m_mouseDownTimestamp = 0;
331 m_longTapShouldInvokeContextMenu = false; 324 m_longTapShouldInvokeContextMenu = false;
332 m_dragStartPos = LayoutPoint(); 325 m_dragStartPos = LayoutPoint();
333 m_offsetFromResizeCorner = LayoutSize(); 326 m_offsetFromResizeCorner = LayoutSize();
334 m_mouseDown = PlatformMouseEvent(); 327 m_mouseDown = PlatformMouseEvent();
328
329 selectionController().clear();
yosin_UTC9 2015/05/19 09:41:19 nit: We don't need to call |clear()| here. |Select
Miyoung Shin(g) 2015/05/19 16:12:51 Done.
335 } 330 }
336 331
337 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved) 332 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved)
338 { 333 {
339 if (nodeToBeRemoved.containsIncludingShadowDOM(m_clickNode.get())) { 334 if (nodeToBeRemoved.containsIncludingShadowDOM(m_clickNode.get())) {
340 // We don't dispatch click events if the mousedown node is removed 335 // We don't dispatch click events if the mousedown node is removed
341 // before a mouseup event. It is compatible with IE and Firefox. 336 // before a mouseup event. It is compatible with IE and Firefox.
342 m_clickNode = nullptr; 337 m_clickNode = nullptr;
343 } 338 }
344 } 339 }
345 340
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) 341 bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve nt)
599 { 342 {
600 TRACE_EVENT0("blink", "EventHandler::handleMousePressEvent"); 343 TRACE_EVENT0("blink", "EventHandler::handleMousePressEvent");
601 344
602 // Reset drag state. 345 // Reset drag state.
603 dragState().m_dragSrc = nullptr; 346 dragState().m_dragSrc = nullptr;
604 347
605 cancelFakeMouseMoveEvent(); 348 cancelFakeMouseMoveEvent();
606 349
607 m_frame->document()->updateLayoutIgnorePendingStylesheets(); 350 m_frame->document()->updateLayoutIgnorePendingStylesheets();
608 351
609 if (FrameView* frameView = m_frame->view()) { 352 if (FrameView* frameView = m_frame->view()) {
610 if (frameView->isPointInScrollbarCorner(event.event().position())) 353 if (frameView->isPointInScrollbarCorner(event.event().position()))
611 return false; 354 return false;
612 } 355 }
613 356
614 bool singleClick = event.event().clickCount() <= 1; 357 bool singleClick = event.event().clickCount() <= 1;
615 358
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; 359 m_mouseDownMayStartDrag = singleClick;
621 360
622 m_mouseDownWasSingleClickInSelection = false; 361 selectionController().handleMousePressEvent(event);
623 362
624 m_mouseDown = event.event(); 363 m_mouseDown = event.event();
625 364
626 if (m_frame->document()->isSVGDocument() && m_frame->document()->accessSVGEx tensions().zoomAndPanEnabled()) { 365 if (m_frame->document()->isSVGDocument() && m_frame->document()->accessSVGEx tensions().zoomAndPanEnabled()) {
627 if (event.event().shiftKey() && singleClick) { 366 if (event.event().shiftKey() && singleClick) {
628 m_svgPan = true; 367 m_svgPan = true;
629 m_frame->document()->accessSVGExtensions().startPan(m_frame->view()- >rootFrameToContents(event.event().position())); 368 m_frame->document()->accessSVGExtensions().startPan(m_frame->view()- >rootFrameToContents(event.event().position()));
630 return true; 369 return true;
631 } 370 }
632 } 371 }
633 372
634 // We don't do this at the start of mouse down handling, 373 // 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. 374 // because we don't want to do it until we know we didn't hit a widget.
636 if (singleClick) 375 if (singleClick)
637 focusDocumentView(); 376 focusDocumentView();
638 377
639 Node* innerNode = event.innerNode(); 378 Node* innerNode = event.innerNode();
640 379
641 m_mousePressNode = innerNode; 380 m_mousePressNode = innerNode;
642 m_dragStartPos = event.event().position(); 381 m_dragStartPos = event.event().position();
643 382
644 bool swallowEvent = false; 383 bool swallowEvent = false;
645 m_mousePressed = true; 384 m_mousePressed = true;
646 m_selectionInitiationState = HaveNotStartedSelection; 385 selectionController().initializeSelectionState();
647 386
648 if (event.event().clickCount() == 2) 387 if (event.event().clickCount() == 2)
649 swallowEvent = handleMousePressEventDoubleClick(event); 388 swallowEvent = selectionController().handleMousePressEventDoubleClick(ev ent);
650 else if (event.event().clickCount() >= 3) 389 else if (event.event().clickCount() >= 3)
651 swallowEvent = handleMousePressEventTripleClick(event); 390 swallowEvent = selectionController().handleMousePressEventTripleClick(ev ent);
652 else 391 else
653 swallowEvent = handleMousePressEventSingleClick(event); 392 swallowEvent = selectionController().handleMousePressEventSingleClick(ev ent);
654 393
655 m_mouseDownMayStartAutoscroll = m_mouseDownMayStartSelect 394 m_mouseDownMayStartAutoscroll = selectionController().mouseDownMayStartSelec t()
656 || (m_mousePressNode && m_mousePressNode->layoutBox() && m_mousePressNod e->layoutBox()->canBeProgramaticallyScrolled()); 395 || (m_mousePressNode && m_mousePressNode->layoutBox() && m_mousePressNod e->layoutBox()->canBeProgramaticallyScrolled());
657 396
658 return swallowEvent; 397 return swallowEvent;
659 } 398 }
660 399
661 bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e vent) 400 bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e vent)
662 { 401 {
663 TRACE_EVENT0("blink", "EventHandler::handleMouseDraggedEvent"); 402 TRACE_EVENT0("blink", "EventHandler::handleMouseDraggedEvent");
664 403
665 // While resetting m_mousePressed here may seem out of place, it turns out 404 // 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 441
703 m_mouseDownMayStartDrag = false; 442 m_mouseDownMayStartDrag = false;
704 443
705 if (m_mouseDownMayStartAutoscroll && !panScrollInProgress()) { 444 if (m_mouseDownMayStartAutoscroll && !panScrollInProgress()) {
706 if (AutoscrollController* controller = autoscrollController()) { 445 if (AutoscrollController* controller = autoscrollController()) {
707 controller->startAutoscrollForSelection(layoutObject); 446 controller->startAutoscrollForSelection(layoutObject);
708 m_mouseDownMayStartAutoscroll = false; 447 m_mouseDownMayStartAutoscroll = false;
709 } 448 }
710 } 449 }
711 450
712 if (m_selectionInitiationState != ExtendedSelection) { 451 selectionController().handleMouseDraggedEvent(event, m_mouseDownPos, m_dragS tartPos, m_mousePressNode, 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; 452 return true;
721 } 453 }
722 454
723 void EventHandler::updateSelectionForMouseDrag() 455 void EventHandler::updateSelectionForMouseDrag()
724 { 456 {
725 FrameView* view = m_frame->view(); 457 selectionController().updateSelectionForMouseDrag(m_mousePressNode, m_dragSt artPos, m_lastKnownMouseGlobalPosition);
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 } 458 }
804 459
805 bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e vent) 460 bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e vent)
806 { 461 {
807 AutoscrollController* controller = autoscrollController(); 462 AutoscrollController* controller = autoscrollController();
808 if (controller && controller->autoscrollInProgress()) 463 if (controller && controller->autoscrollInProgress())
809 stopAutoscroll(); 464 stopAutoscroll();
810 465
811 // Used to prevent mouseMoveEvent from initiating a drag before 466 // Used to prevent mouseMoveEvent from initiating a drag before
812 // the mouse is pressed again. 467 // the mouse is pressed again.
813 m_mousePressed = false; 468 m_mousePressed = false;
814 m_capturesDragging = false; 469 m_capturesDragging = false;
815 m_mouseDownMayStartDrag = false; 470 m_mouseDownMayStartDrag = false;
816 m_mouseDownMayStartSelect = false;
817 m_mouseDownMayStartAutoscroll = false; 471 m_mouseDownMayStartAutoscroll = false;
818 472
819 bool handled = false; 473 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 } 474 }
853 475
854 #if OS(WIN) 476 #if OS(WIN)
855 477
856 void EventHandler::startPanScrolling(LayoutObject* layoutObject) 478 void EventHandler::startPanScrolling(LayoutObject* layoutObject)
857 { 479 {
858 if (!layoutObject->isBox()) 480 if (!layoutObject->isBox())
859 return; 481 return;
860 AutoscrollController* controller = autoscrollController(); 482 AutoscrollController* controller = autoscrollController();
861 if (!controller) 483 if (!controller)
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 849
1228 bool inResizer = false; 850 bool inResizer = false;
1229 LayoutObject* layoutObject = node ? node->layoutObject() : nullptr; 851 LayoutObject* layoutObject = node ? node->layoutObject() : nullptr;
1230 if (layoutObject && m_frame->view()) { 852 if (layoutObject && m_frame->view()) {
1231 DeprecatedPaintLayer* layer = layoutObject->enclosingLayer(); 853 DeprecatedPaintLayer* layer = layoutObject->enclosingLayer();
1232 inResizer = layer->scrollableArea() && layer->scrollableArea()->isPointI nResizeControl(result.roundedPointInMainFrame(), ResizerForPointer); 854 inResizer = layer->scrollableArea() && layer->scrollableArea()->isPointI nResizeControl(result.roundedPointInMainFrame(), ResizerForPointer);
1233 } 855 }
1234 856
1235 // During selection, use an I-beam no matter what we're over. 857 // During selection, use an I-beam no matter what we're over.
1236 // If a drag may be starting or we're capturing mouse events for a particula r node, don't treat this as a selection. 858 // If a drag may be starting or we're capturing mouse events for a particula r node, don't treat this as a selection.
1237 if (m_mousePressed && m_mouseDownMayStartSelect 859 if (m_mousePressed && selectionController().mouseDownMayStartSelect()
1238 && !m_mouseDownMayStartDrag 860 && !m_mouseDownMayStartDrag
1239 && m_frame->selection().isCaretOrRange() 861 && m_frame->selection().isCaretOrRange()
1240 && !m_capturingMouseEventsNode) { 862 && !m_capturingMouseEventsNode) {
1241 return iBeam; 863 return iBeam;
1242 } 864 }
1243 865
1244 if ((editable || (layoutObject && layoutObject->isText() && node->canStartSe lection())) && !inResizer && !result.scrollbar()) 866 if ((editable || (layoutObject && layoutObject->isText() && node->canStartSe lection())) && !inResizer && !result.scrollbar())
1245 return iBeam; 867 return iBeam;
1246 return pointerCursor(); 868 return pointerCursor();
1247 } 869 }
(...skipping 16 matching lines...) Expand all
1264 m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken = gestureIndicator.currentToken(); 886 m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken = gestureIndicator.currentToken();
1265 887
1266 cancelFakeMouseMoveEvent(); 888 cancelFakeMouseMoveEvent();
1267 if (m_eventHandlerWillResetCapturingMouseEventsNode) 889 if (m_eventHandlerWillResetCapturingMouseEventsNode)
1268 m_capturingMouseEventsNode = nullptr; 890 m_capturingMouseEventsNode = nullptr;
1269 m_mousePressed = true; 891 m_mousePressed = true;
1270 m_capturesDragging = true; 892 m_capturesDragging = true;
1271 setLastKnownMousePosition(mouseEvent); 893 setLastKnownMousePosition(mouseEvent);
1272 m_mouseDownTimestamp = mouseEvent.timestamp(); 894 m_mouseDownTimestamp = mouseEvent.timestamp();
1273 m_mouseDownMayStartDrag = false; 895 m_mouseDownMayStartDrag = false;
1274 m_mouseDownMayStartSelect = false; 896 selectionController().setMouseDownMayStartSelect(false);
1275 m_mouseDownMayStartAutoscroll = false; 897 m_mouseDownMayStartAutoscroll = false;
1276 if (FrameView* view = m_frame->view()) { 898 if (FrameView* view = m_frame->view()) {
1277 m_mouseDownPos = view->rootFrameToContents(mouseEvent.position()); 899 m_mouseDownPos = view->rootFrameToContents(mouseEvent.position());
1278 } else { 900 } else {
1279 invalidateClick(); 901 invalidateClick();
1280 return false; 902 return false;
1281 } 903 }
1282 904
1283 HitTestRequest request(HitTestRequest::Active); 905 HitTestRequest request(HitTestRequest::Active);
1284 // Save the document point we generate in case the window coordinate is inva lidated by what happens 906 // Save the document point we generate in case the window coordinate is inva lidated by what happens
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1636 1258
1637 bool swallowMouseReleaseEvent = false; 1259 bool swallowMouseReleaseEvent = false;
1638 if (!swallowMouseUpEvent) 1260 if (!swallowMouseUpEvent)
1639 swallowMouseReleaseEvent = handleMouseReleaseEvent(mev); 1261 swallowMouseReleaseEvent = handleMouseReleaseEvent(mev);
1640 1262
1641 invalidateClick(); 1263 invalidateClick();
1642 1264
1643 return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent; 1265 return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
1644 } 1266 }
1645 1267
1646 bool EventHandler::handlePasteGlobalSelection(const PlatformMouseEvent& mouseEve nt)
1647 {
1648 // If the event was a middle click, attempt to copy global selection in afte r
1649 // the newly set caret position.
1650 //
1651 // This code is called from either the mouse up or mouse down handling. Ther e
1652 // is some debate about when the global selection is pasted:
1653 // xterm: pastes on up.
1654 // GTK: pastes on down.
1655 // Qt: pastes on up.
1656 // Firefox: pastes on up.
1657 // Chromium: pastes on up.
1658 //
1659 // There is something of a webcompat angle to this well, as highlighted by
1660 // crbug.com/14608. Pages can clear text boxes 'onclick' and, if we paste on
1661 // down then the text is pasted just before the onclick handler runs and
1662 // clears the text box. So it's important this happens after the event
1663 // handlers have been fired.
1664 if (mouseEvent.type() != PlatformEvent::MouseReleased)
1665 return false;
1666
1667 if (!m_frame->page())
1668 return false;
1669 Frame* focusFrame = m_frame->page()->focusController().focusedOrMainFrame();
1670 // Do not paste here if the focus was moved somewhere else.
1671 if (m_frame == focusFrame && m_frame->editor().behavior().supportsGlobalSele ction())
1672 return m_frame->editor().command("PasteGlobalSelection").execute();
1673
1674 return false;
1675 }
1676
1677
1678 bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTa rget, const PlatformMouseEvent& event, DataTransfer* dataTransfer) 1268 bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTa rget, const PlatformMouseEvent& event, DataTransfer* dataTransfer)
1679 { 1269 {
1680 FrameView* view = m_frame->view(); 1270 FrameView* view = m_frame->view();
1681 1271
1682 // FIXME: We might want to dispatch a dragleave even if the view is gone. 1272 // FIXME: We might want to dispatch a dragleave even if the view is gone.
1683 if (!view) 1273 if (!view)
1684 return false; 1274 return false;
1685 1275
1686 RefPtrWillBeRawPtr<MouseEvent> me = MouseEvent::create(eventType, 1276 RefPtrWillBeRawPtr<MouseEvent> me = MouseEvent::create(eventType,
1687 true, true, m_frame->document()->domWindow(), 1277 true, true, m_frame->document()->domWindow(),
(...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after
2517 #endif 2107 #endif
2518 if (shouldLongPressSelectWord) { 2108 if (shouldLongPressSelectWord) {
2519 IntPoint hitTestPoint = m_frame->view()->rootFrameToContents(gestureEven t.position()); 2109 IntPoint hitTestPoint = m_frame->view()->rootFrameToContents(gestureEven t.position());
2520 HitTestResult result = hitTestResultAtPoint(hitTestPoint); 2110 HitTestResult result = hitTestResultAtPoint(hitTestPoint);
2521 Node* innerNode = result.innerNode(); 2111 Node* innerNode = result.innerNode();
2522 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode() 2112 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode()
2523 #if OS(ANDROID) 2113 #if OS(ANDROID)
2524 || innerNode->canStartSelection() 2114 || innerNode->canStartSelection()
2525 #endif 2115 #endif
2526 )) { 2116 )) {
2527 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp ace); 2117 selectionController().selectClosestWordFromHitTestResult(result, Don tAppendTrailingWhitespace);
2528 if (m_frame->selection().isRange()) { 2118 if (m_frame->selection().isRange()) {
2529 focusDocumentView(); 2119 focusDocumentView();
2530 return true; 2120 return true;
2531 } 2121 }
2532 } 2122 }
2533 } 2123 }
2534 return sendContextMenuEventForGesture(targetedEvent); 2124 return sendContextMenuEventForGesture(targetedEvent);
2535 } 2125 }
2536 2126
2537 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta rgetedEvent) 2127 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta rgetedEvent)
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
3000 FrameView* v = m_frame->view(); 2590 FrameView* v = m_frame->view();
3001 if (!v) 2591 if (!v)
3002 return false; 2592 return false;
3003 2593
3004 // Clear mouse press state to avoid initiating a drag while context menu is up. 2594 // Clear mouse press state to avoid initiating a drag while context menu is up.
3005 m_mousePressed = false; 2595 m_mousePressed = false;
3006 LayoutPoint positionInContents = v->rootFrameToContents(event.position()); 2596 LayoutPoint positionInContents = v->rootFrameToContents(event.position());
3007 HitTestRequest request(HitTestRequest::Active); 2597 HitTestRequest request(HitTestRequest::Active);
3008 MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(re quest, positionInContents, event); 2598 MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(re quest, positionInContents, event);
3009 2599
3010 if (!m_frame->selection().contains(positionInContents) 2600 selectionController().prepareForContextMenu(mev, positionInContents);
3011 && !mev.scrollbar()
3012 // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
3013 // If the selection is non-editable, we do word selection to make it eas ier to use the contextual menu items
3014 // available for text selections. But only if we're above text.
3015 && (m_frame->selection().isContentEditable() || (mev.innerNode() && mev. innerNode()->isTextNode()))) {
3016 m_mouseDownMayStartSelect = true; // context menu events are always allo wed to perform a selection
3017
3018 if (mev.hitTestResult().isMisspelled())
3019 selectClosestMisspellingFromMouseEvent(mev);
3020 else if (m_frame->editor().behavior().shouldSelectOnContextualMenuClick( ))
3021 selectClosestWordOrLinkFromMouseEvent(mev);
3022 }
3023 2601
3024 Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode() ; 2602 Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode() ;
3025 return !dispatchMouseEvent(EventTypeNames::contextmenu, targetNode, 0, event , false); 2603 return !dispatchMouseEvent(EventTypeNames::contextmenu, targetNode, 0, event , false);
3026 } 2604 }
3027 2605
3028 bool EventHandler::sendContextMenuEventForKey(Element* overrideTargetElement) 2606 bool EventHandler::sendContextMenuEventForKey(Element* overrideTargetElement)
3029 { 2607 {
3030 FrameView* view = m_frame->view(); 2608 FrameView* view = m_frame->view();
3031 if (!view) 2609 if (!view)
3032 return false; 2610 return false;
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
3521 dragState().m_dragSrc = m_frame->page()->dragController().draggableN ode(m_frame, node, m_mouseDownPos, selectionDragPolicy, dragState().m_dragType); 3099 dragState().m_dragSrc = m_frame->page()->dragController().draggableN ode(m_frame, node, m_mouseDownPos, selectionDragPolicy, dragState().m_dragType);
3522 } else { 3100 } else {
3523 dragState().m_dragSrc = nullptr; 3101 dragState().m_dragSrc = nullptr;
3524 } 3102 }
3525 3103
3526 if (!dragState().m_dragSrc) 3104 if (!dragState().m_dragSrc)
3527 m_mouseDownMayStartDrag = false; // no element is draggable 3105 m_mouseDownMayStartDrag = false; // no element is draggable
3528 } 3106 }
3529 3107
3530 if (!m_mouseDownMayStartDrag) 3108 if (!m_mouseDownMayStartDrag)
3531 return initiator == DragInitiator::Mouse && !mouseDownMayStartSelect() & & !m_mouseDownMayStartAutoscroll; 3109 return initiator == DragInitiator::Mouse && !selectionController().mouse DownMayStartSelect() && !m_mouseDownMayStartAutoscroll;
3532 3110
3533 // We are starting a text/image/url drag, so the cursor should be an arrow 3111 // We are starting a text/image/url drag, so the cursor should be an arrow
3534 // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and d rop (default to pointer). 3112 // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and d rop (default to pointer).
3535 m_frame->view()->setCursor(pointerCursor()); 3113 m_frame->view()->setCursor(pointerCursor());
3536 3114
3537 if (initiator == DragInitiator::Mouse && !dragHysteresisExceeded(event.event ().position())) 3115 if (initiator == DragInitiator::Mouse && !dragHysteresisExceeded(event.event ().position()))
3538 return true; 3116 return true;
3539 3117
3540 // Once we're past the hysteresis point, we don't want to treat this gesture as a click 3118 // Once we're past the hysteresis point, we don't want to treat this gesture as a click
3541 invalidateClick(); 3119 invalidateClick();
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
4106 3684
4107 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event) 3685 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
4108 { 3686 {
4109 m_mousePositionIsUnknown = false; 3687 m_mousePositionIsUnknown = false;
4110 m_lastKnownMousePosition = event.position(); 3688 m_lastKnownMousePosition = event.position();
4111 m_lastKnownMouseGlobalPosition = event.globalPosition(); 3689 m_lastKnownMouseGlobalPosition = event.globalPosition();
4112 } 3690 }
4113 3691
4114 bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& m ev, LocalFrame* subframe) 3692 bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& m ev, LocalFrame* subframe)
4115 { 3693 {
4116 // If we're clicking into a frame that is selected, the frame will appear 3694 selectionController().preparePassMousePressEventToSubframe(mev);
4117 // greyed out even though we're clicking on the selection. This looks
4118 // really strange (having the whole frame be greyed out), so we deselect the
4119 // selection.
4120 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position());
4121 if (m_frame->selection().contains(p)) {
4122 VisiblePosition visiblePos(
4123 mev.innerNode()->layoutObject()->positionForPoint(mev.localPoint())) ;
4124 VisibleSelection newSelection(visiblePos);
4125 m_frame->selection().setSelection(newSelection);
4126 }
4127
4128 subframe->eventHandler().handleMousePressEvent(mev.event()); 3695 subframe->eventHandler().handleMousePressEvent(mev.event());
4129 return true; 3696 return true;
4130 } 3697 }
4131 3698
4132 bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& me v, LocalFrame* subframe, HitTestResult* hoveredNode) 3699 bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& me v, LocalFrame* subframe, HitTestResult* hoveredNode)
4133 { 3700 {
4134 if (m_mouseDownMayStartDrag) 3701 if (m_mouseDownMayStartDrag)
4135 return false; 3702 return false;
4136 subframe->eventHandler().handleMouseMoveOrLeaveEvent(mev.event(), hoveredNod e); 3703 subframe->eventHandler().handleMouseMoveOrLeaveEvent(mev.event(), hoveredNod e);
4137 return true; 3704 return true;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
4169 unsigned EventHandler::accessKeyModifiers() 3736 unsigned EventHandler::accessKeyModifiers()
4170 { 3737 {
4171 #if OS(MACOSX) 3738 #if OS(MACOSX)
4172 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; 3739 return PlatformEvent::CtrlKey | PlatformEvent::AltKey;
4173 #else 3740 #else
4174 return PlatformEvent::AltKey; 3741 return PlatformEvent::AltKey;
4175 #endif 3742 #endif
4176 } 3743 }
4177 3744
4178 } // namespace blink 3745 } // namespace blink
OLDNEW
« Source/core/editing/SelectionController.cpp ('K') | « Source/core/page/EventHandler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698