Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/input/EventHandler.h" | 5 #include "core/input/EventHandler.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
| 9 #include "core/dom/Range.h" | 9 #include "core/dom/Range.h" |
| 10 #include "core/editing/Editor.h" | 10 #include "core/editing/Editor.h" |
| 11 #include "core/editing/FrameSelection.h" | 11 #include "core/editing/FrameSelection.h" |
| 12 #include "core/frame/FrameView.h" | 12 #include "core/frame/FrameView.h" |
| 13 #include "core/frame/LocalFrame.h" | 13 #include "core/frame/LocalFrame.h" |
| 14 #include "core/frame/Settings.h" | 14 #include "core/frame/Settings.h" |
| 15 #include "core/loader/EmptyClients.h" | 15 #include "core/loader/EmptyClients.h" |
| 16 #include "core/page/AutoscrollController.h" | 16 #include "core/page/AutoscrollController.h" |
| 17 #include "core/page/Page.h" | 17 #include "core/page/Page.h" |
| 18 #include "core/testing/DummyPageHolder.h" | 18 #include "core/testing/DummyPageHolder.h" |
| 19 #include "platform/testing/HistogramTester.h" | |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 20 | 21 |
| 21 namespace blink { | 22 namespace blink { |
| 22 | 23 |
| 23 class EventHandlerTest : public ::testing::Test { | 24 class EventHandlerTest : public ::testing::Test { |
| 24 protected: | 25 protected: |
| 25 void SetUp() override; | 26 void SetUp() override; |
| 26 | 27 |
| 27 Page& page() const { return m_dummyPageHolder->page(); } | 28 Page& page() const { return m_dummyPageHolder->page(); } |
| 28 Document& document() const { return m_dummyPageHolder->document(); } | 29 Document& document() const { return m_dummyPageHolder->document(); } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 WebInputEvent::NoModifiers, | 73 WebInputEvent::NoModifiers, |
| 73 TimeTicks::Now().InSeconds()) { | 74 TimeTicks::Now().InSeconds()) { |
| 74 clickCount = clickCountParam; | 75 clickCount = clickCountParam; |
| 75 button = buttonParam; | 76 button = buttonParam; |
| 76 setPositionInWidget(positionParam.x(), positionParam.y()); | 77 setPositionInWidget(positionParam.x(), positionParam.y()); |
| 77 setPositionInScreen(positionParam.x(), positionParam.y()); | 78 setPositionInScreen(positionParam.x(), positionParam.y()); |
| 78 m_frameScale = 1; | 79 m_frameScale = 1; |
| 79 } | 80 } |
| 80 }; | 81 }; |
| 81 | 82 |
| 83 class ScrollBeginEventBuilder : public WebGestureEvent { | |
| 84 public: | |
| 85 ScrollBeginEventBuilder(IntPoint position, | |
| 86 FloatPoint delta, | |
| 87 WebGestureDevice device) | |
| 88 : WebGestureEvent() { | |
| 89 m_type = WebInputEvent::GestureScrollBegin; | |
| 90 x = globalX = position.x(); | |
| 91 y = globalY = position.y(); | |
| 92 data.scrollBegin.deltaYHint = delta.y(); | |
| 93 sourceDevice = device; | |
| 94 m_frameScale = 1; | |
| 95 } | |
| 96 }; | |
| 97 | |
| 98 class ScrollEndEventBuilder : public WebGestureEvent { | |
| 99 public: | |
| 100 ScrollEndEventBuilder() : WebGestureEvent() { | |
| 101 m_type = WebInputEvent::GestureScrollEnd; | |
| 102 m_frameScale = 1; | |
| 103 } | |
| 104 }; | |
| 105 | |
| 82 void EventHandlerTest::SetUp() { | 106 void EventHandlerTest::SetUp() { |
| 83 m_dummyPageHolder = DummyPageHolder::create(IntSize(300, 400)); | 107 m_dummyPageHolder = DummyPageHolder::create(IntSize(300, 400)); |
| 84 } | 108 } |
| 85 | 109 |
| 86 void EventHandlerTest::setHtmlInnerHTML(const char* htmlContent) { | 110 void EventHandlerTest::setHtmlInnerHTML(const char* htmlContent) { |
| 87 document().documentElement()->setInnerHTML(String::fromUTF8(htmlContent)); | 111 document().documentElement()->setInnerHTML(String::fromUTF8(htmlContent)); |
| 88 document().view()->updateAllLifecyclePhases(); | 112 document().view()->updateAllLifecyclePhases(); |
| 89 } | 113 } |
| 90 | 114 |
| 91 TEST_F(EventHandlerTest, dragSelectionAfterScroll) { | 115 TEST_F(EventHandlerTest, dragSelectionAfterScroll) { |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 WebInputEvent::MouseUp, WebFloatPoint(100, 50), WebFloatPoint(200, 250), | 478 WebInputEvent::MouseUp, WebFloatPoint(100, 50), WebFloatPoint(200, 250), |
| 455 WebPointerProperties::Button::Left, 1, WebInputEvent::NoModifiers, | 479 WebPointerProperties::Button::Left, 1, WebInputEvent::NoModifiers, |
| 456 TimeTicks::Now().InSeconds()); | 480 TimeTicks::Now().InSeconds()); |
| 457 mouseUpEvent.setFrameScale(1); | 481 mouseUpEvent.setFrameScale(1); |
| 458 document().frame()->eventHandler().dragSourceEndedAt(mouseUpEvent, | 482 document().frame()->eventHandler().dragSourceEndedAt(mouseUpEvent, |
| 459 DragOperationNone); | 483 DragOperationNone); |
| 460 | 484 |
| 461 // This test passes if it doesn't crash. | 485 // This test passes if it doesn't crash. |
| 462 } | 486 } |
| 463 | 487 |
| 488 TEST_F(EventHandlerTest, NonCompositedMainThreadScrollingReasonTest) { | |
| 489 setHtmlInnerHTML( | |
| 490 "<style>.box { overflow:scroll; width: 100px; height: 100px; }" | |
| 491 " .translucent { opacity: 0.5; }" | |
| 492 " .spacer { height: 1000px; }" | |
| 493 " .composited { will-change: transform; }" | |
| 494 " .hidden { overflow: hidden; }" | |
| 495 "</style>" | |
| 496 "<div id='box' class='translucent box'><div class='spacer'></div></div>" | |
| 497 "<div class='composited translucent box'>" | |
| 498 " <div class='spacer'></div>" | |
| 499 "</div>"); | |
| 500 | |
| 501 page().settings().setAcceleratedCompositingEnabled(true); | |
| 502 document().view()->setParentVisible(true); | |
| 503 document().view()->setSelfVisible(true); | |
| 504 document().view()->updateAllLifecyclePhases(); | |
| 505 | |
| 506 HistogramTester histogramTester; | |
| 507 | |
| 508 // Test touch scroll. | |
| 509 ScrollBeginEventBuilder touchScrollBegin( | |
| 510 IntPoint(50, 50), FloatPoint(0.f, 1.f), WebGestureDeviceTouchscreen); | |
| 511 ScrollEndEventBuilder touchScrollEnd; | |
| 512 document().frame()->eventHandler().handleGestureEvent(touchScrollBegin); | |
| 513 document().frame()->eventHandler().handleGestureEvent(touchScrollEnd); | |
| 514 histogramTester.expectBucketCount("Renderer4.MainThreadGestureScrollReason", | |
| 515 17, 1); | |
| 516 | |
| 517 document().frame()->eventHandler().handleGestureEvent(touchScrollBegin); | |
| 518 document().frame()->eventHandler().handleGestureEvent(touchScrollEnd); | |
| 519 histogramTester.expectBucketCount("Renderer4.MainThreadGestureScrollReason", | |
| 520 17, 2); | |
| 521 | |
| 522 // Test wheel scroll. | |
| 523 ScrollBeginEventBuilder wheelScrollBegin( | |
| 524 IntPoint(50, 50), FloatPoint(0.f, 1.f), WebGestureDeviceTouchpad); | |
| 525 ScrollEndEventBuilder wheelScrollEnd; | |
| 526 document().frame()->eventHandler().handleGestureEvent(wheelScrollBegin); | |
| 527 document().frame()->eventHandler().handleGestureEvent(wheelScrollEnd); | |
| 528 histogramTester.expectBucketCount("Renderer4.MainThreadWheelScrollReason", 17, | |
| 529 1); | |
| 530 histogramTester.expectBucketCount("Renderer4.MainThreadWheelScrollReason", 19, | |
| 531 1); | |
| 532 histogramTester.expectTotalCount("Renderer4.MainThreadWheelScrollReason", 2); | |
| 533 | |
| 534 Element* box = document().getElementById("box"); | |
| 535 box->setAttribute("class", "hidden"); | |
|
bokan
2017/04/07 17:39:03
This is testing my request for non-scrollable area
yigu
2017/04/07 19:26:27
Done.
| |
| 536 document().view()->updateAllLifecyclePhases(); | |
| 537 document().frame()->eventHandler().handleGestureEvent(wheelScrollBegin); | |
| 538 document().frame()->eventHandler().handleGestureEvent(wheelScrollEnd); | |
| 539 histogramTester.expectTotalCount("Renderer4.MainThreadWheelScrollReason", 2); | |
| 540 | |
| 541 wheelScrollBegin.y = wheelScrollBegin.globalY = 150; | |
| 542 document().frame()->eventHandler().handleGestureEvent(wheelScrollBegin); | |
| 543 document().frame()->eventHandler().handleGestureEvent(wheelScrollEnd); | |
| 544 histogramTester.expectBucketCount("Renderer4.MainThreadWheelScrollReason", 17, | |
|
bokan
2017/04/07 17:39:03
Please use names for the bucket constants here. Yo
yigu
2017/04/07 19:26:27
Done.
| |
| 545 1); | |
| 546 } | |
| 547 | |
| 548 TEST_F(EventHandlerTest, | |
| 549 NonCompositedMainThreadScrollingReasonWithNestedScrollersTest) { | |
| 550 setHtmlInnerHTML( | |
| 551 "<style>.container { overflow:scroll; width: 200px; height: 200px; }" | |
|
bokan
2017/04/07 17:39:03
nit: .container should be on new line
yigu
2017/04/07 19:26:27
Done.
| |
| 552 " .box { overflow:scroll; width: 100px; height: 100px; }" | |
| 553 " .translucent { opacity: 0.5; }" | |
| 554 " .with-border-radius { border: 5px solid; border-radius: 5px; }" | |
| 555 " .spacer { height: 1000px; }" | |
| 556 " .composited { will-change: transform; }" | |
| 557 "</style>" | |
| 558 "<div id='container' class='translucent container'>" | |
| 559 " <div class='composited box'>" | |
| 560 " <div class='box with-border-radius'>" | |
|
bokan
2017/04/07 17:39:03
You're testing the non-scrollable case here as wel
yigu
2017/04/07 19:26:27
Done.
| |
| 561 " <div class='spacer'></div>" | |
| 562 " </div>" | |
| 563 " </div>" | |
| 564 " <div class='composited translucent box'></div>" | |
| 565 "</div>"); | |
| 566 | |
| 567 page().settings().setAcceleratedCompositingEnabled(true); | |
| 568 document().view()->setParentVisible(true); | |
| 569 document().view()->setSelfVisible(true); | |
| 570 document().view()->updateAllLifecyclePhases(); | |
| 571 | |
| 572 HistogramTester histogramTester; | |
| 573 | |
| 574 ScrollBeginEventBuilder wheelScrollBegin( | |
| 575 IntPoint(50, 50), FloatPoint(0.f, 1.f), WebGestureDeviceTouchpad); | |
| 576 ScrollEndEventBuilder wheelScrollEnd; | |
| 577 document().frame()->eventHandler().handleGestureEvent(wheelScrollBegin); | |
| 578 document().frame()->eventHandler().handleGestureEvent(wheelScrollEnd); | |
| 579 histogramTester.expectBucketCount("Renderer4.MainThreadWheelScrollReason", 17, | |
| 580 1); | |
| 581 histogramTester.expectBucketCount("Renderer4.MainThreadWheelScrollReason", 19, | |
| 582 1); | |
| 583 histogramTester.expectBucketCount("Renderer4.MainThreadWheelScrollReason", 20, | |
| 584 1); | |
| 585 histogramTester.expectTotalCount("Renderer4.MainThreadWheelScrollReason", 3); | |
| 586 | |
| 587 Element* container = document().getElementById("container"); | |
| 588 container->setAttribute("class", "composited"); | |
|
bokan
2017/04/07 17:39:03
Ditto for the will-change bit here. Split it out i
yigu
2017/04/07 19:26:27
Done.
| |
| 589 document().view()->updateAllLifecyclePhases(); | |
| 590 wheelScrollBegin.y = wheelScrollBegin.globalY = 150; | |
| 591 document().frame()->eventHandler().handleGestureEvent(wheelScrollBegin); | |
| 592 document().frame()->eventHandler().handleGestureEvent(wheelScrollEnd); | |
| 593 histogramTester.expectTotalCount("Renderer4.MainThreadWheelScrollReason", 3); | |
| 594 } | |
| 595 | |
| 464 class TooltipCapturingChromeClient : public EmptyChromeClient { | 596 class TooltipCapturingChromeClient : public EmptyChromeClient { |
| 465 public: | 597 public: |
| 466 TooltipCapturingChromeClient() {} | 598 TooltipCapturingChromeClient() {} |
| 467 | 599 |
| 468 void setToolTip(LocalFrame&, const String& str, TextDirection) override { | 600 void setToolTip(LocalFrame&, const String& str, TextDirection) override { |
| 469 m_lastToolTip = str; | 601 m_lastToolTip = str; |
| 470 } | 602 } |
| 471 | 603 |
| 472 String& lastToolTip() { return m_lastToolTip; } | 604 String& lastToolTip() { return m_lastToolTip; } |
| 473 | 605 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 514 WebInputEvent::MouseLeave, WebFloatPoint(0, 0), WebFloatPoint(0, 0), | 646 WebInputEvent::MouseLeave, WebFloatPoint(0, 0), WebFloatPoint(0, 0), |
| 515 WebPointerProperties::Button::NoButton, 0, WebInputEvent::NoModifiers, | 647 WebPointerProperties::Button::NoButton, 0, WebInputEvent::NoModifiers, |
| 516 TimeTicks::Now().InSeconds()); | 648 TimeTicks::Now().InSeconds()); |
| 517 mouseLeaveEvent.setFrameScale(1); | 649 mouseLeaveEvent.setFrameScale(1); |
| 518 document().frame()->eventHandler().handleMouseLeaveEvent(mouseLeaveEvent); | 650 document().frame()->eventHandler().handleMouseLeaveEvent(mouseLeaveEvent); |
| 519 | 651 |
| 520 EXPECT_EQ(WTF::String(), lastToolTip()); | 652 EXPECT_EQ(WTF::String(), lastToolTip()); |
| 521 } | 653 } |
| 522 | 654 |
| 523 } // namespace blink | 655 } // namespace blink |
| OLD | NEW |