Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |