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

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
« no previous file with comments | « Source/core/page/EventHandler.h ('k') | no next file » | 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/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))
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 29 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_lastKnownMouseGlobalPosition);
Miyoung Shin(g) 2015/05/24 14:05:55 I figured out that I set the wrong |m_lastKnownMou
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 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 848
1228 bool inResizer = false; 849 bool inResizer = false;
1229 LayoutObject* layoutObject = node ? node->layoutObject() : nullptr; 850 LayoutObject* layoutObject = node ? node->layoutObject() : nullptr;
1230 if (layoutObject && m_frame->view()) { 851 if (layoutObject && m_frame->view()) {
1231 DeprecatedPaintLayer* layer = layoutObject->enclosingLayer(); 852 DeprecatedPaintLayer* layer = layoutObject->enclosingLayer();
1232 inResizer = layer->scrollableArea() && layer->scrollableArea()->isPointI nResizeControl(result.roundedPointInMainFrame(), ResizerForPointer); 853 inResizer = layer->scrollableArea() && layer->scrollableArea()->isPointI nResizeControl(result.roundedPointInMainFrame(), ResizerForPointer);
1233 } 854 }
1234 855
1235 // During selection, use an I-beam no matter what we're over. 856 // 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. 857 // 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 858 if (m_mousePressed && selectionController().mouseDownMayStartSelect()
1238 && !m_mouseDownMayStartDrag 859 && !m_mouseDownMayStartDrag
1239 && m_frame->selection().isCaretOrRange() 860 && m_frame->selection().isCaretOrRange()
1240 && !m_capturingMouseEventsNode) { 861 && !m_capturingMouseEventsNode) {
1241 return iBeam; 862 return iBeam;
1242 } 863 }
1243 864
1244 if ((editable || (layoutObject && layoutObject->isText() && node->canStartSe lection())) && !inResizer && !result.scrollbar()) 865 if ((editable || (layoutObject && layoutObject->isText() && node->canStartSe lection())) && !inResizer && !result.scrollbar())
1245 return iBeam; 866 return iBeam;
1246 return pointerCursor(); 867 return pointerCursor();
1247 } 868 }
(...skipping 16 matching lines...) Expand all
1264 m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken = gestureIndicator.currentToken(); 885 m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken = gestureIndicator.currentToken();
1265 886
1266 cancelFakeMouseMoveEvent(); 887 cancelFakeMouseMoveEvent();
1267 if (m_eventHandlerWillResetCapturingMouseEventsNode) 888 if (m_eventHandlerWillResetCapturingMouseEventsNode)
1268 m_capturingMouseEventsNode = nullptr; 889 m_capturingMouseEventsNode = nullptr;
1269 m_mousePressed = true; 890 m_mousePressed = true;
1270 m_capturesDragging = true; 891 m_capturesDragging = true;
1271 setLastKnownMousePosition(mouseEvent); 892 setLastKnownMousePosition(mouseEvent);
1272 m_mouseDownTimestamp = mouseEvent.timestamp(); 893 m_mouseDownTimestamp = mouseEvent.timestamp();
1273 m_mouseDownMayStartDrag = false; 894 m_mouseDownMayStartDrag = false;
1274 m_mouseDownMayStartSelect = false; 895 selectionController().setMouseDownMayStartSelect(false);
1275 m_mouseDownMayStartAutoscroll = false; 896 m_mouseDownMayStartAutoscroll = false;
1276 if (FrameView* view = m_frame->view()) { 897 if (FrameView* view = m_frame->view()) {
1277 m_mouseDownPos = view->rootFrameToContents(mouseEvent.position()); 898 m_mouseDownPos = view->rootFrameToContents(mouseEvent.position());
1278 } else { 899 } else {
1279 invalidateClick(); 900 invalidateClick();
1280 return false; 901 return false;
1281 } 902 }
1282 903
1283 HitTestRequest request(HitTestRequest::Active); 904 HitTestRequest request(HitTestRequest::Active);
1284 // Save the document point we generate in case the window coordinate is inva lidated by what happens 905 // 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 1257
1637 bool swallowMouseReleaseEvent = false; 1258 bool swallowMouseReleaseEvent = false;
1638 if (!swallowMouseUpEvent) 1259 if (!swallowMouseUpEvent)
1639 swallowMouseReleaseEvent = handleMouseReleaseEvent(mev); 1260 swallowMouseReleaseEvent = handleMouseReleaseEvent(mev);
1640 1261
1641 invalidateClick(); 1262 invalidateClick();
1642 1263
1643 return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent; 1264 return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
1644 } 1265 }
1645 1266
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) 1267 bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTa rget, const PlatformMouseEvent& event, DataTransfer* dataTransfer)
1679 { 1268 {
1680 FrameView* view = m_frame->view(); 1269 FrameView* view = m_frame->view();
1681 1270
1682 // FIXME: We might want to dispatch a dragleave even if the view is gone. 1271 // FIXME: We might want to dispatch a dragleave even if the view is gone.
1683 if (!view) 1272 if (!view)
1684 return false; 1273 return false;
1685 1274
1686 RefPtrWillBeRawPtr<MouseEvent> me = MouseEvent::create(eventType, 1275 RefPtrWillBeRawPtr<MouseEvent> me = MouseEvent::create(eventType,
1687 true, true, m_frame->document()->domWindow(), 1276 true, true, m_frame->document()->domWindow(),
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after
2503 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE vent); 2092 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE vent);
2504 m_mouseDownMayStartDrag = true; 2093 m_mouseDownMayStartDrag = true;
2505 dragState().m_dragSrc = nullptr; 2094 dragState().m_dragSrc = nullptr;
2506 m_mouseDownPos = m_frame->view()->rootFrameToContents(mouseDragEvent.pos ition()); 2095 m_mouseDownPos = m_frame->view()->rootFrameToContents(mouseDragEvent.pos ition());
2507 RefPtrWillBeRawPtr<FrameView> protector(m_frame->view()); 2096 RefPtrWillBeRawPtr<FrameView> protector(m_frame->view());
2508 if (handleDrag(mev, DragInitiator::Touch)) { 2097 if (handleDrag(mev, DragInitiator::Touch)) {
2509 m_longTapShouldInvokeContextMenu = true; 2098 m_longTapShouldInvokeContextMenu = true;
2510 return true; 2099 return true;
2511 } 2100 }
2512 } 2101 }
2513 #if OS(ANDROID) 2102
2514 bool shouldLongPressSelectWord = true; 2103 IntPoint hitTestPoint = m_frame->view()->rootFrameToContents(gestureEvent.po sition());
2515 #else 2104 HitTestResult result = hitTestResultAtPoint(hitTestPoint);
2516 bool shouldLongPressSelectWord = m_frame->settings() && m_frame->settings()- >touchEditingEnabled(); 2105 if (selectionController().handleGestureLongPress(gestureEvent, result))
2517 #endif 2106 return true;
2518 if (shouldLongPressSelectWord) { 2107
2519 IntPoint hitTestPoint = m_frame->view()->rootFrameToContents(gestureEven t.position());
2520 HitTestResult result = hitTestResultAtPoint(hitTestPoint);
2521 Node* innerNode = result.innerNode();
2522 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode()
2523 #if OS(ANDROID)
2524 || innerNode->canStartSelection()
2525 #endif
2526 )) {
2527 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp ace);
2528 if (m_frame->selection().isRange()) {
2529 focusDocumentView();
2530 return true;
2531 }
2532 }
2533 }
2534 return sendContextMenuEventForGesture(targetedEvent); 2108 return sendContextMenuEventForGesture(targetedEvent);
2535 } 2109 }
2536 2110
2537 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta rgetedEvent) 2111 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta rgetedEvent)
2538 { 2112 {
2539 #if !OS(ANDROID) 2113 #if !OS(ANDROID)
2540 if (m_longTapShouldInvokeContextMenu) { 2114 if (m_longTapShouldInvokeContextMenu) {
2541 m_longTapShouldInvokeContextMenu = false; 2115 m_longTapShouldInvokeContextMenu = false;
2542 return sendContextMenuEventForGesture(targetedEvent); 2116 return sendContextMenuEventForGesture(targetedEvent);
2543 } 2117 }
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
3000 FrameView* v = m_frame->view(); 2574 FrameView* v = m_frame->view();
3001 if (!v) 2575 if (!v)
3002 return false; 2576 return false;
3003 2577
3004 // Clear mouse press state to avoid initiating a drag while context menu is up. 2578 // Clear mouse press state to avoid initiating a drag while context menu is up.
3005 m_mousePressed = false; 2579 m_mousePressed = false;
3006 LayoutPoint positionInContents = v->rootFrameToContents(event.position()); 2580 LayoutPoint positionInContents = v->rootFrameToContents(event.position());
3007 HitTestRequest request(HitTestRequest::Active); 2581 HitTestRequest request(HitTestRequest::Active);
3008 MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(re quest, positionInContents, event); 2582 MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(re quest, positionInContents, event);
3009 2583
3010 if (!m_frame->selection().contains(positionInContents) 2584 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 2585
3024 Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode() ; 2586 Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode() ;
3025 return !dispatchMouseEvent(EventTypeNames::contextmenu, targetNode, 0, event , false); 2587 return !dispatchMouseEvent(EventTypeNames::contextmenu, targetNode, 0, event , false);
3026 } 2588 }
3027 2589
3028 bool EventHandler::sendContextMenuEventForKey(Element* overrideTargetElement) 2590 bool EventHandler::sendContextMenuEventForKey(Element* overrideTargetElement)
3029 { 2591 {
3030 FrameView* view = m_frame->view(); 2592 FrameView* view = m_frame->view();
3031 if (!view) 2593 if (!view)
3032 return false; 2594 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); 3083 dragState().m_dragSrc = m_frame->page()->dragController().draggableN ode(m_frame, node, m_mouseDownPos, selectionDragPolicy, dragState().m_dragType);
3522 } else { 3084 } else {
3523 dragState().m_dragSrc = nullptr; 3085 dragState().m_dragSrc = nullptr;
3524 } 3086 }
3525 3087
3526 if (!dragState().m_dragSrc) 3088 if (!dragState().m_dragSrc)
3527 m_mouseDownMayStartDrag = false; // no element is draggable 3089 m_mouseDownMayStartDrag = false; // no element is draggable
3528 } 3090 }
3529 3091
3530 if (!m_mouseDownMayStartDrag) 3092 if (!m_mouseDownMayStartDrag)
3531 return initiator == DragInitiator::Mouse && !mouseDownMayStartSelect() & & !m_mouseDownMayStartAutoscroll; 3093 return initiator == DragInitiator::Mouse && !selectionController().mouse DownMayStartSelect() && !m_mouseDownMayStartAutoscroll;
3532 3094
3533 // We are starting a text/image/url drag, so the cursor should be an arrow 3095 // 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). 3096 // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and d rop (default to pointer).
3535 m_frame->view()->setCursor(pointerCursor()); 3097 m_frame->view()->setCursor(pointerCursor());
3536 3098
3537 if (initiator == DragInitiator::Mouse && !dragHysteresisExceeded(event.event ().position())) 3099 if (initiator == DragInitiator::Mouse && !dragHysteresisExceeded(event.event ().position()))
3538 return true; 3100 return true;
3539 3101
3540 // Once we're past the hysteresis point, we don't want to treat this gesture as a click 3102 // Once we're past the hysteresis point, we don't want to treat this gesture as a click
3541 invalidateClick(); 3103 invalidateClick();
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
4106 3668
4107 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event) 3669 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
4108 { 3670 {
4109 m_mousePositionIsUnknown = false; 3671 m_mousePositionIsUnknown = false;
4110 m_lastKnownMousePosition = event.position(); 3672 m_lastKnownMousePosition = event.position();
4111 m_lastKnownMouseGlobalPosition = event.globalPosition(); 3673 m_lastKnownMouseGlobalPosition = event.globalPosition();
4112 } 3674 }
4113 3675
4114 bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& m ev, LocalFrame* subframe) 3676 bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& m ev, LocalFrame* subframe)
4115 { 3677 {
4116 // If we're clicking into a frame that is selected, the frame will appear 3678 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()); 3679 subframe->eventHandler().handleMousePressEvent(mev.event());
4129 return true; 3680 return true;
4130 } 3681 }
4131 3682
4132 bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& me v, LocalFrame* subframe, HitTestResult* hoveredNode) 3683 bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& me v, LocalFrame* subframe, HitTestResult* hoveredNode)
4133 { 3684 {
4134 if (m_mouseDownMayStartDrag) 3685 if (m_mouseDownMayStartDrag)
4135 return false; 3686 return false;
4136 subframe->eventHandler().handleMouseMoveOrLeaveEvent(mev.event(), hoveredNod e); 3687 subframe->eventHandler().handleMouseMoveOrLeaveEvent(mev.event(), hoveredNod e);
4137 return true; 3688 return true;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
4169 unsigned EventHandler::accessKeyModifiers() 3720 unsigned EventHandler::accessKeyModifiers()
4170 { 3721 {
4171 #if OS(MACOSX) 3722 #if OS(MACOSX)
4172 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; 3723 return PlatformEvent::CtrlKey | PlatformEvent::AltKey;
4173 #else 3724 #else
4174 return PlatformEvent::AltKey; 3725 return PlatformEvent::AltKey;
4175 #endif 3726 #endif
4176 } 3727 }
4177 3728
4178 } // namespace blink 3729 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/page/EventHandler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698