| /* |
| * Copyright (C) 2012 Google Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following disclaimer |
| * in the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name of Google Inc. nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "third_party/blink/public/web/web_plugin_container.h" |
| |
| #include <memory> |
| #include <string> |
| |
| #include "build/build_config.h" |
| #include "cc/layers/layer.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/blink/public/common/frame/frame_owner_element_type.h" |
| #include "third_party/blink/public/platform/platform.h" |
| #include "third_party/blink/public/platform/web_coalesced_input_event.h" |
| #include "third_party/blink/public/platform/web_mouse_wheel_event.h" |
| #include "third_party/blink/public/platform/web_pointer_event.h" |
| #include "third_party/blink/public/platform/web_url_loader_mock_factory.h" |
| #include "third_party/blink/public/web/web_document.h" |
| #include "third_party/blink/public/web/web_element.h" |
| #include "third_party/blink/public/web/web_local_frame_client.h" |
| #include "third_party/blink/public/web/web_plugin_params.h" |
| #include "third_party/blink/public/web/web_print_params.h" |
| #include "third_party/blink/public/web/web_settings.h" |
| #include "third_party/blink/public/web/web_view.h" |
| #include "third_party/blink/renderer/core/clipboard/system_clipboard.h" |
| #include "third_party/blink/renderer/core/dom/element.h" |
| #include "third_party/blink/renderer/core/events/keyboard_event.h" |
| #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h" |
| #include "third_party/blink/renderer/core/exported/web_view_impl.h" |
| #include "third_party/blink/renderer/core/frame/event_handler_registry.h" |
| #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" |
| #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" |
| #include "third_party/blink/renderer/core/html/html_element.h" |
| #include "third_party/blink/renderer/core/layout/layout_object.h" |
| #include "third_party/blink/renderer/core/page/page.h" |
| #include "third_party/blink/renderer/core/testing/fake_web_plugin.h" |
| #include "third_party/blink/renderer/platform/graphics/graphics_context.h" |
| #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h" |
| #include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h" |
| #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" |
| #include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h" |
| #include "third_party/blink/renderer/platform/keyboard_codes.h" |
| #include "third_party/blink/renderer/platform/scheduler/public/thread.h" |
| #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" |
| #include "third_party/blink/renderer/platform/testing/scoped_fake_plugin_registry.h" |
| #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" |
| #include "third_party/blink/renderer/platform/testing/url_test_helpers.h" |
| |
| using blink::test::RunPendingTasks; |
| |
| namespace blink { |
| |
| class WebPluginContainerTest : public testing::Test { |
| public: |
| WebPluginContainerTest() : base_url_("http://www.test.com/") {} |
| |
| void TearDown() override { |
| Platform::Current() |
| ->GetURLLoaderMockFactory() |
| ->UnregisterAllURLsAndClearMemoryCache(); |
| } |
| |
| void CalculateGeometry(WebPluginContainerImpl* plugin_container_impl, |
| IntRect& window_rect, |
| IntRect& clip_rect, |
| IntRect& unobscured_rect) { |
| plugin_container_impl->CalculateGeometry(window_rect, clip_rect, |
| unobscured_rect); |
| } |
| |
| void RegisterMockedURL( |
| const std::string& file_name, |
| const std::string& mime_type = std::string("text/html")) { |
| url_test_helpers::RegisterMockedURLLoadFromBase( |
| WebString::FromUTF8(base_url_), test::CoreTestDataPath(), |
| WebString::FromUTF8(file_name), WebString::FromUTF8(mime_type)); |
| } |
| |
| void UpdateAllLifecyclePhases(WebViewImpl* web_view) { |
| web_view->MainFrameWidget()->UpdateAllLifecyclePhases( |
| WebWidget::LifecycleUpdateReason::kTest); |
| } |
| |
| protected: |
| ScopedFakePluginRegistry fake_plugins_; |
| std::string base_url_; |
| }; |
| |
| namespace { |
| |
| #if defined(OS_MACOSX) |
| const WebInputEvent::Modifiers kEditingModifier = WebInputEvent::kMetaKey; |
| #else |
| const WebInputEvent::Modifiers kEditingModifier = WebInputEvent::kControlKey; |
| #endif |
| |
| template <typename T> |
| class CustomPluginWebFrameClient |
| : public frame_test_helpers::TestWebFrameClient { |
| public: |
| WebPlugin* CreatePlugin(const WebPluginParams& params) override { |
| return new T(params); |
| } |
| }; |
| |
| class TestPluginWebFrameClient; |
| |
| // Subclass of FakeWebPlugin that has a selection of 'x' as plain text and 'y' |
| // as markup text. |
| class TestPlugin : public FakeWebPlugin { |
| public: |
| TestPlugin(const WebPluginParams& params, |
| TestPluginWebFrameClient* test_client) |
| : FakeWebPlugin(params), test_client_(test_client) {} |
| |
| bool HasSelection() const override { return true; } |
| WebString SelectionAsText() const override { return WebString("x"); } |
| WebString SelectionAsMarkup() const override { return WebString("y"); } |
| bool SupportsPaginatedPrint() override { return true; } |
| int PrintBegin(const WebPrintParams& print_params) override { return 1; } |
| void PrintPage(int page_number, cc::PaintCanvas*) override; |
| |
| private: |
| ~TestPlugin() override = default; |
| |
| TestPluginWebFrameClient* const test_client_; |
| }; |
| |
| // Subclass of FakeWebPlugin used for testing edit commands, so HasSelection() |
| // and CanEditText() return true by default. |
| class TestPluginWithEditableText : public FakeWebPlugin { |
| public: |
| static TestPluginWithEditableText* FromContainer(WebElement* element) { |
| WebPlugin* plugin = |
| ToWebPluginContainerImpl(element->PluginContainer())->Plugin(); |
| return static_cast<TestPluginWithEditableText*>(plugin); |
| } |
| |
| explicit TestPluginWithEditableText(const WebPluginParams& params) |
| : FakeWebPlugin(params), cut_called_(false), paste_called_(false) {} |
| |
| bool HasSelection() const override { return true; } |
| bool CanEditText() const override { return true; } |
| bool ExecuteEditCommand(const WebString& name) override { |
| return ExecuteEditCommand(name, WebString()); |
| } |
| bool ExecuteEditCommand(const WebString& name, |
| const WebString& value) override { |
| if (name == "Cut") { |
| cut_called_ = true; |
| return true; |
| } |
| if (name == "Paste" || name == "PasteAndMatchStyle") { |
| paste_called_ = true; |
| return true; |
| } |
| return false; |
| } |
| |
| bool IsCutCalled() const { return cut_called_; } |
| bool IsPasteCalled() const { return paste_called_; } |
| void ResetEditCommandState() { |
| cut_called_ = false; |
| paste_called_ = false; |
| } |
| |
| private: |
| ~TestPluginWithEditableText() override = default; |
| |
| bool cut_called_; |
| bool paste_called_; |
| }; |
| |
| class TestPluginWebFrameClient : public frame_test_helpers::TestWebFrameClient { |
| WebLocalFrame* CreateChildFrame(WebLocalFrame* parent, |
| WebTreeScopeType scope, |
| const WebString& name, |
| const WebString& fallback_name, |
| WebSandboxFlags sandbox_flags, |
| const ParsedFeaturePolicy& container_policy, |
| const WebFrameOwnerProperties&, |
| FrameOwnerElementType owner_type) override { |
| return CreateLocalChild(*parent, scope, |
| std::make_unique<TestPluginWebFrameClient>()); |
| } |
| |
| WebPlugin* CreatePlugin(const WebPluginParams& params) override { |
| if (params.mime_type == "application/x-webkit-test-webplugin" || |
| params.mime_type == "application/pdf") { |
| if (has_editable_text_) |
| return new TestPluginWithEditableText(params); |
| |
| return new TestPlugin(params, this); |
| } |
| return WebLocalFrameClient::CreatePlugin(params); |
| } |
| |
| public: |
| void OnPrintPage() { printed_page_ = true; } |
| bool PrintedAtLeastOnePage() const { return printed_page_; } |
| void SetHasEditableText(bool has_editable_text) { |
| has_editable_text_ = has_editable_text; |
| } |
| |
| private: |
| bool printed_page_ = false; |
| bool has_editable_text_ = false; |
| }; |
| |
| void TestPlugin::PrintPage(int page_number, cc::PaintCanvas* canvas) { |
| DCHECK(test_client_); |
| test_client_->OnPrintPage(); |
| } |
| |
| void EnablePlugins(WebView* web_view, const WebSize& size) { |
| DCHECK(web_view); |
| web_view->GetSettings()->SetPluginsEnabled(true); |
| web_view->MainFrameWidget()->Resize(size); |
| web_view->MainFrameWidget()->UpdateAllLifecyclePhases( |
| WebWidget::LifecycleUpdateReason::kTest); |
| RunPendingTasks(); |
| } |
| |
| WebPluginContainer* GetWebPluginContainer(WebViewImpl* web_view, |
| const WebString& id) { |
| WebElement element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById(id); |
| return element.PluginContainer(); |
| } |
| |
| String ReadClipboard() { |
| // Run all tasks in a message loop to allow asynchronous clipboard writing |
| // to happen before reading from it synchronously. |
| test::RunPendingTasks(); |
| return SystemClipboard::GetInstance().ReadPlainText(); |
| } |
| |
| void ClearClipboardBuffer() { |
| SystemClipboard::GetInstance().WritePlainText(String("")); |
| EXPECT_EQ(String(""), ReadClipboard()); |
| } |
| |
| void CreateAndHandleKeyboardEvent(WebElement* plugin_container_one_element, |
| WebInputEvent::Modifiers modifier_key, |
| int key_code) { |
| WebKeyboardEvent web_keyboard_event( |
| WebInputEvent::kRawKeyDown, modifier_key, |
| WebInputEvent::GetStaticTimeStampForTests()); |
| web_keyboard_event.windows_key_code = key_code; |
| KeyboardEvent* key_event = KeyboardEvent::Create(web_keyboard_event, nullptr); |
| ToWebPluginContainerImpl(plugin_container_one_element->PluginContainer()) |
| ->HandleEvent(*key_event); |
| } |
| |
| void ExecuteContextMenuCommand(WebViewImpl* web_view, |
| const WebString& command_name) { |
| auto event = frame_test_helpers::CreateMouseEvent( |
| WebMouseEvent::kMouseDown, WebMouseEvent::Button::kRight, |
| WebPoint(30, 30), 0); |
| event.click_count = 1; |
| |
| web_view->HandleInputEvent(WebCoalescedInputEvent(event)); |
| EXPECT_TRUE( |
| web_view->MainFrame()->ToWebLocalFrame()->ExecuteCommand(command_name)); |
| } |
| |
| } // namespace |
| |
| TEST_F(WebPluginContainerTest, WindowToLocalPointTest) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebPluginContainer* plugin_container_one = |
| GetWebPluginContainer(web_view, WebString::FromUTF8("translated-plugin")); |
| DCHECK(plugin_container_one); |
| WebPoint point1 = |
| plugin_container_one->RootFrameToLocalPoint(WebPoint(10, 10)); |
| ASSERT_EQ(0, point1.x); |
| ASSERT_EQ(0, point1.y); |
| WebPoint point2 = |
| plugin_container_one->RootFrameToLocalPoint(WebPoint(100, 100)); |
| ASSERT_EQ(90, point2.x); |
| ASSERT_EQ(90, point2.y); |
| |
| WebPluginContainer* plugin_container_two = |
| GetWebPluginContainer(web_view, WebString::FromUTF8("rotated-plugin")); |
| DCHECK(plugin_container_two); |
| WebPoint point3 = |
| plugin_container_two->RootFrameToLocalPoint(WebPoint(0, 10)); |
| ASSERT_EQ(10, point3.x); |
| ASSERT_EQ(0, point3.y); |
| WebPoint point4 = |
| plugin_container_two->RootFrameToLocalPoint(WebPoint(-10, 10)); |
| ASSERT_EQ(10, point4.x); |
| ASSERT_EQ(10, point4.y); |
| } |
| |
| TEST_F(WebPluginContainerTest, PluginDocumentPluginIsFocused) { |
| RegisterMockedURL("test.pdf", "application/pdf"); |
| |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "test.pdf", &plugin_web_frame_client); |
| DCHECK(web_view); |
| UpdateAllLifecyclePhases(web_view); |
| |
| WebDocument document = web_view->MainFrameImpl()->GetDocument(); |
| EXPECT_TRUE(document.IsPluginDocument()); |
| WebPluginContainer* plugin_container = |
| GetWebPluginContainer(web_view, "plugin"); |
| EXPECT_EQ(document.FocusedElement(), plugin_container->GetElement()); |
| } |
| |
| TEST_F(WebPluginContainerTest, IFramePluginDocumentNotFocused) { |
| RegisterMockedURL("test.pdf", "application/pdf"); |
| RegisterMockedURL("iframe_pdf.html", "text/html"); |
| |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "iframe_pdf.html", &plugin_web_frame_client); |
| DCHECK(web_view); |
| UpdateAllLifecyclePhases(web_view); |
| |
| WebDocument document = web_view->MainFrameImpl()->GetDocument(); |
| WebLocalFrame* iframe = |
| web_view->MainFrame()->FirstChild()->ToWebLocalFrame(); |
| EXPECT_TRUE(iframe->GetDocument().IsPluginDocument()); |
| WebPluginContainer* plugin_container = |
| iframe->GetDocument().GetElementById("plugin").PluginContainer(); |
| EXPECT_NE(document.FocusedElement(), plugin_container->GetElement()); |
| EXPECT_NE(iframe->GetDocument().FocusedElement(), |
| plugin_container->GetElement()); |
| } |
| |
| TEST_F(WebPluginContainerTest, PrintOnePage) { |
| RegisterMockedURL("test.pdf", "application/pdf"); |
| |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "test.pdf", &plugin_web_frame_client); |
| DCHECK(web_view); |
| UpdateAllLifecyclePhases(web_view); |
| RunPendingTasks(); |
| WebLocalFrame* frame = web_view->MainFrameImpl(); |
| |
| WebPrintParams print_params; |
| print_params.print_content_area.width = 500; |
| print_params.print_content_area.height = 500; |
| |
| frame->PrintBegin(print_params); |
| PaintRecorder recorder; |
| frame->PrintPage(0, recorder.beginRecording(IntRect())); |
| frame->PrintEnd(); |
| DCHECK(plugin_web_frame_client.PrintedAtLeastOnePage()); |
| } |
| |
| TEST_F(WebPluginContainerTest, PrintAllPages) { |
| RegisterMockedURL("test.pdf", "application/pdf"); |
| |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "test.pdf", &plugin_web_frame_client); |
| DCHECK(web_view); |
| UpdateAllLifecyclePhases(web_view); |
| RunPendingTasks(); |
| WebLocalFrame* frame = web_view->MainFrameImpl(); |
| |
| WebPrintParams print_params; |
| print_params.print_content_area.width = 500; |
| print_params.print_content_area.height = 500; |
| |
| frame->PrintBegin(print_params); |
| PaintRecorder recorder; |
| frame->PrintPagesForTesting(recorder.beginRecording(IntRect()), WebSize()); |
| frame->PrintEnd(); |
| DCHECK(plugin_web_frame_client.PrintedAtLeastOnePage()); |
| } |
| |
| TEST_F(WebPluginContainerTest, LocalToWindowPointTest) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebPluginContainer* plugin_container_one = |
| GetWebPluginContainer(web_view, WebString::FromUTF8("translated-plugin")); |
| DCHECK(plugin_container_one); |
| WebPoint point1 = plugin_container_one->LocalToRootFramePoint(WebPoint(0, 0)); |
| ASSERT_EQ(10, point1.x); |
| ASSERT_EQ(10, point1.y); |
| WebPoint point2 = |
| plugin_container_one->LocalToRootFramePoint(WebPoint(90, 90)); |
| ASSERT_EQ(100, point2.x); |
| ASSERT_EQ(100, point2.y); |
| |
| WebPluginContainer* plugin_container_two = |
| GetWebPluginContainer(web_view, WebString::FromUTF8("rotated-plugin")); |
| DCHECK(plugin_container_two); |
| WebPoint point3 = |
| plugin_container_two->LocalToRootFramePoint(WebPoint(10, 0)); |
| ASSERT_EQ(0, point3.x); |
| ASSERT_EQ(10, point3.y); |
| WebPoint point4 = |
| plugin_container_two->LocalToRootFramePoint(WebPoint(10, 10)); |
| ASSERT_EQ(-10, point4.x); |
| ASSERT_EQ(10, point4.y); |
| } |
| |
| // Verifies executing the command 'Copy' results in copying to the clipboard. |
| TEST_F(WebPluginContainerTest, Copy) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| web_view->MainFrameImpl() |
| ->GetDocument() |
| .Unwrap<Document>() |
| ->body() |
| ->getElementById("translated-plugin") |
| ->focus(); |
| EXPECT_TRUE(web_view->MainFrame()->ToWebLocalFrame()->ExecuteCommand("Copy")); |
| EXPECT_EQ(String("x"), ReadClipboard()); |
| ClearClipboardBuffer(); |
| } |
| |
| TEST_F(WebPluginContainerTest, CopyFromContextMenu) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| // Make sure the right-click + command works in common scenario. |
| ExecuteContextMenuCommand(web_view, "Copy"); |
| EXPECT_EQ(String("x"), ReadClipboard()); |
| ClearClipboardBuffer(); |
| |
| auto event = frame_test_helpers::CreateMouseEvent( |
| WebMouseEvent::kMouseDown, WebMouseEvent::Button::kRight, |
| WebPoint(30, 30), 0); |
| event.click_count = 1; |
| |
| // Now, let's try a more complex scenario: |
| // 1) open the context menu. This will focus the plugin. |
| web_view->HandleInputEvent(WebCoalescedInputEvent(event)); |
| // 2) document blurs the plugin, because it can. |
| web_view->ClearFocusedElement(); |
| // 3) Copy should still operate on the context node, even though the focus had |
| // shifted. |
| EXPECT_TRUE(web_view->MainFrameImpl()->ExecuteCommand("Copy")); |
| EXPECT_EQ(String("x"), ReadClipboard()); |
| ClearClipboardBuffer(); |
| } |
| |
| // Verifies |Ctrl-C| and |Ctrl-Insert| keyboard events, results in copying to |
| // the clipboard. |
| TEST_F(WebPluginContainerTest, CopyInsertKeyboardEventsTest) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("translated-plugin")); |
| WebInputEvent::Modifiers modifier_key = static_cast<WebInputEvent::Modifiers>( |
| kEditingModifier | WebInputEvent::kNumLockOn | WebInputEvent::kIsLeft); |
| CreateAndHandleKeyboardEvent(&plugin_container_one_element, modifier_key, |
| VKEY_C); |
| EXPECT_EQ(String("x"), ReadClipboard()); |
| ClearClipboardBuffer(); |
| |
| CreateAndHandleKeyboardEvent(&plugin_container_one_element, modifier_key, |
| VKEY_INSERT); |
| EXPECT_EQ(String("x"), ReadClipboard()); |
| ClearClipboardBuffer(); |
| } |
| |
| // Verifies |Ctrl-X| and |Shift-Delete| keyboard events, results in the "Cut" |
| // command being invoked. |
| TEST_F(WebPluginContainerTest, CutDeleteKeyboardEventsTest) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| |
| // Use TestPluginWithEditableText for testing "Cut". |
| plugin_web_frame_client.SetHasEditableText(true); |
| |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("translated-plugin")); |
| |
| WebInputEvent::Modifiers modifier_key = static_cast<WebInputEvent::Modifiers>( |
| kEditingModifier | WebInputEvent::kNumLockOn | WebInputEvent::kIsLeft); |
| CreateAndHandleKeyboardEvent(&plugin_container_one_element, modifier_key, |
| VKEY_X); |
| |
| // Check that "Cut" command is invoked. |
| auto* test_plugin = |
| TestPluginWithEditableText::FromContainer(&plugin_container_one_element); |
| EXPECT_TRUE(test_plugin->IsCutCalled()); |
| |
| // Reset Cut status for next time. |
| test_plugin->ResetEditCommandState(); |
| |
| modifier_key = static_cast<WebInputEvent::Modifiers>( |
| WebInputEvent::kShiftKey | WebInputEvent::kNumLockOn | |
| WebInputEvent::kIsLeft); |
| |
| CreateAndHandleKeyboardEvent(&plugin_container_one_element, modifier_key, |
| VKEY_DELETE); |
| |
| // Check that "Cut" command is invoked. |
| EXPECT_TRUE(test_plugin->IsCutCalled()); |
| } |
| |
| // Verifies |Ctrl-V| and |Shift-Insert| keyboard events, results in the "Paste" |
| // command being invoked. |
| TEST_F(WebPluginContainerTest, PasteInsertKeyboardEventsTest) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| |
| // Use TestPluginWithEditableText for testing "Paste". |
| plugin_web_frame_client.SetHasEditableText(true); |
| |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("translated-plugin")); |
| |
| WebInputEvent::Modifiers modifier_key = static_cast<WebInputEvent::Modifiers>( |
| kEditingModifier | WebInputEvent::kNumLockOn | WebInputEvent::kIsLeft); |
| CreateAndHandleKeyboardEvent(&plugin_container_one_element, modifier_key, |
| VKEY_V); |
| |
| // Check that "Paste" command is invoked. |
| auto* test_plugin = |
| TestPluginWithEditableText::FromContainer(&plugin_container_one_element); |
| EXPECT_TRUE(test_plugin->IsPasteCalled()); |
| |
| // Reset Paste status for next time. |
| test_plugin->ResetEditCommandState(); |
| |
| modifier_key = static_cast<WebInputEvent::Modifiers>( |
| WebInputEvent::kShiftKey | WebInputEvent::kNumLockOn | |
| WebInputEvent::kIsLeft); |
| |
| CreateAndHandleKeyboardEvent(&plugin_container_one_element, modifier_key, |
| VKEY_INSERT); |
| |
| // Check that "Paste" command is invoked. |
| EXPECT_TRUE(test_plugin->IsPasteCalled()); |
| } |
| |
| // Verifies |Ctrl-Shift-V| keyboard event results in the "PasteAndMatchStyle" |
| // command being invoked. |
| TEST_F(WebPluginContainerTest, PasteAndMatchStyleKeyboardEventsTest) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| |
| // Use TestPluginWithEditableText for testing "PasteAndMatchStyle". |
| plugin_web_frame_client.SetHasEditableText(true); |
| |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("translated-plugin")); |
| |
| WebInputEvent::Modifiers modifier_key = static_cast<WebInputEvent::Modifiers>( |
| kEditingModifier | WebInputEvent::kShiftKey | WebInputEvent::kNumLockOn | |
| WebInputEvent::kIsLeft); |
| CreateAndHandleKeyboardEvent(&plugin_container_one_element, modifier_key, |
| VKEY_V); |
| |
| // Check that "PasteAndMatchStyle" command is invoked. |
| auto* test_plugin = |
| TestPluginWithEditableText::FromContainer(&plugin_container_one_element); |
| EXPECT_TRUE(test_plugin->IsPasteCalled()); |
| } |
| |
| TEST_F(WebPluginContainerTest, CutFromContextMenu) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| |
| // Use TestPluginWithEditableText for testing "Cut". |
| plugin_web_frame_client.SetHasEditableText(true); |
| |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("translated-plugin")); |
| |
| ExecuteContextMenuCommand(web_view, "Cut"); |
| auto* test_plugin = |
| TestPluginWithEditableText::FromContainer(&plugin_container_one_element); |
| EXPECT_TRUE(test_plugin->IsCutCalled()); |
| } |
| |
| TEST_F(WebPluginContainerTest, PasteFromContextMenu) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| |
| // Use TestPluginWithEditableText for testing "Paste". |
| plugin_web_frame_client.SetHasEditableText(true); |
| |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("translated-plugin")); |
| |
| ExecuteContextMenuCommand(web_view, "Paste"); |
| auto* test_plugin = |
| TestPluginWithEditableText::FromContainer(&plugin_container_one_element); |
| EXPECT_TRUE(test_plugin->IsPasteCalled()); |
| } |
| |
| TEST_F(WebPluginContainerTest, PasteAndMatchStyleFromContextMenu) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| |
| // Use TestPluginWithEditableText for testing "Paste". |
| plugin_web_frame_client.SetHasEditableText(true); |
| |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("translated-plugin")); |
| |
| ExecuteContextMenuCommand(web_view, "PasteAndMatchStyle"); |
| auto* test_plugin = |
| TestPluginWithEditableText::FromContainer(&plugin_container_one_element); |
| EXPECT_TRUE(test_plugin->IsPasteCalled()); |
| } |
| |
| // A class to facilitate testing that events are correctly received by plugins. |
| class EventTestPlugin : public FakeWebPlugin { |
| public: |
| explicit EventTestPlugin(const WebPluginParams& params) |
| : FakeWebPlugin(params), |
| last_event_type_(WebInputEvent::kUndefined), |
| last_event_modifiers_(WebInputEvent::kNoModifiers) {} |
| |
| WebInputEventResult HandleInputEvent( |
| const WebCoalescedInputEvent& coalesced_event, |
| WebCursorInfo&) override { |
| const WebInputEvent& event = coalesced_event.Event(); |
| coalesced_event_count_ = coalesced_event.CoalescedEventSize(); |
| last_event_type_ = event.GetType(); |
| last_event_modifiers_ = event.GetModifiers(); |
| if (WebInputEvent::IsMouseEventType(event.GetType()) || |
| event.GetType() == WebInputEvent::kMouseWheel) { |
| const WebMouseEvent& mouse_event = |
| static_cast<const WebMouseEvent&>(event); |
| last_event_location_ = IntPoint(mouse_event.PositionInWidget().x, |
| mouse_event.PositionInWidget().y); |
| } else if (WebInputEvent::IsTouchEventType(event.GetType())) { |
| const WebTouchEvent& touch_event = |
| static_cast<const WebTouchEvent&>(event); |
| if (touch_event.touches_length == 1) { |
| last_event_location_ = |
| IntPoint(touch_event.touches[0].PositionInWidget().x, |
| touch_event.touches[0].PositionInWidget().y); |
| } else { |
| last_event_location_ = IntPoint(); |
| } |
| } |
| |
| return WebInputEventResult::kHandledSystem; |
| } |
| WebInputEvent::Type GetLastInputEventType() { return last_event_type_; } |
| |
| IntPoint GetLastEventLocation() { return last_event_location_; } |
| |
| int GetLastEventModifiers() { return last_event_modifiers_; } |
| |
| void ClearLastEventType() { last_event_type_ = WebInputEvent::kUndefined; } |
| |
| size_t GetCoalescedEventCount() { return coalesced_event_count_; } |
| |
| private: |
| ~EventTestPlugin() override = default; |
| |
| size_t coalesced_event_count_; |
| WebInputEvent::Type last_event_type_; |
| IntPoint last_event_location_; |
| int last_event_modifiers_; |
| }; |
| |
| TEST_F(WebPluginContainerTest, GestureLongPressReachesPlugin) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| CustomPluginWebFrameClient<EventTestPlugin> plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("translated-plugin")); |
| WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( |
| plugin_container_one_element.PluginContainer()) |
| ->Plugin(); |
| EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); |
| |
| WebGestureEvent event(WebInputEvent::kGestureLongPress, |
| WebInputEvent::kNoModifiers, |
| WebInputEvent::GetStaticTimeStampForTests(), |
| kWebGestureDeviceTouchscreen); |
| |
| // First, send an event that doesn't hit the plugin to verify that the |
| // plugin doesn't receive it. |
| event.SetPositionInWidget(WebFloatPoint(0, 0)); |
| |
| web_view->HandleInputEvent(WebCoalescedInputEvent(event)); |
| RunPendingTasks(); |
| |
| EXPECT_EQ(WebInputEvent::kUndefined, test_plugin->GetLastInputEventType()); |
| |
| // Next, send an event that does hit the plugin, and verify it does receive |
| // it. |
| WebRect rect = plugin_container_one_element.BoundsInViewport(); |
| event.SetPositionInWidget( |
| WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2)); |
| |
| web_view->HandleInputEvent(WebCoalescedInputEvent(event)); |
| RunPendingTasks(); |
| |
| EXPECT_EQ(WebInputEvent::kGestureLongPress, |
| test_plugin->GetLastInputEventType()); |
| } |
| |
| TEST_F(WebPluginContainerTest, MouseEventButtons) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| CustomPluginWebFrameClient<EventTestPlugin> plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("translated-plugin")); |
| WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( |
| plugin_container_one_element.PluginContainer()) |
| ->Plugin(); |
| EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); |
| |
| WebMouseEvent event = frame_test_helpers::CreateMouseEvent( |
| WebMouseEvent::kMouseMove, WebMouseEvent::Button::kNoButton, |
| WebPoint(30, 30), |
| WebInputEvent::kMiddleButtonDown | WebInputEvent::kShiftKey); |
| |
| WebRect rect = plugin_container_one_element.BoundsInViewport(); |
| event.SetPositionInWidget(rect.x + rect.width / 2, rect.y + rect.height / 2); |
| |
| web_view->HandleInputEvent(WebCoalescedInputEvent(event)); |
| RunPendingTasks(); |
| |
| EXPECT_EQ(WebInputEvent::kMouseMove, test_plugin->GetLastInputEventType()); |
| EXPECT_EQ(WebInputEvent::kMiddleButtonDown | WebInputEvent::kShiftKey, |
| test_plugin->GetLastEventModifiers()); |
| } |
| |
| TEST_F(WebPluginContainerTest, MouseWheelEventTranslated) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| CustomPluginWebFrameClient<EventTestPlugin> plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("translated-plugin")); |
| WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( |
| plugin_container_one_element.PluginContainer()) |
| ->Plugin(); |
| EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); |
| |
| WebMouseWheelEvent event(WebInputEvent::kMouseWheel, |
| WebInputEvent::kNoModifiers, |
| WebInputEvent::GetStaticTimeStampForTests()); |
| |
| WebRect rect = plugin_container_one_element.BoundsInViewport(); |
| event.SetPositionInWidget(rect.x + rect.width / 2, rect.y + rect.height / 2); |
| |
| web_view->HandleInputEvent(WebCoalescedInputEvent(event)); |
| RunPendingTasks(); |
| |
| EXPECT_EQ(WebInputEvent::kMouseWheel, test_plugin->GetLastInputEventType()); |
| EXPECT_EQ(rect.width / 2, test_plugin->GetLastEventLocation().X()); |
| EXPECT_EQ(rect.height / 2, test_plugin->GetLastEventLocation().Y()); |
| } |
| |
| TEST_F(WebPluginContainerTest, TouchEventScrolled) { |
| RegisterMockedURL("plugin_scroll.html"); |
| // Must outlive |web_view_helper|. |
| CustomPluginWebFrameClient<EventTestPlugin> plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_scroll.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| web_view->SmoothScroll(0, 200, 0); |
| UpdateAllLifecyclePhases(web_view); |
| RunPendingTasks(); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("scrolled-plugin")); |
| plugin_container_one_element.PluginContainer()->RequestTouchEventType( |
| WebPluginContainer::kTouchEventRequestTypeRaw); |
| WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( |
| plugin_container_one_element.PluginContainer()) |
| ->Plugin(); |
| EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); |
| |
| WebRect rect = plugin_container_one_element.BoundsInViewport(); |
| WebPointerEvent event( |
| WebInputEvent::kPointerDown, |
| WebPointerProperties( |
| 1, WebPointerProperties::PointerType::kTouch, |
| WebPointerProperties::Button::kLeft, |
| WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2), |
| WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2)), |
| 1.0f, 1.0f); |
| |
| web_view->HandleInputEvent(WebCoalescedInputEvent(event)); |
| web_view->DispatchBufferedTouchEvents(); |
| RunPendingTasks(); |
| |
| EXPECT_EQ(WebInputEvent::kTouchStart, test_plugin->GetLastInputEventType()); |
| EXPECT_EQ(rect.width / 2, test_plugin->GetLastEventLocation().X()); |
| EXPECT_EQ(rect.height / 2, test_plugin->GetLastEventLocation().Y()); |
| } |
| |
| TEST_F(WebPluginContainerTest, TouchEventScrolledWithCoalescedTouches) { |
| RegisterMockedURL("plugin_scroll.html"); |
| // Must outlive |web_view_helper|. |
| CustomPluginWebFrameClient<EventTestPlugin> plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_scroll.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| web_view->SmoothScroll(0, 200, 0); |
| UpdateAllLifecyclePhases(web_view); |
| RunPendingTasks(); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("scrolled-plugin")); |
| plugin_container_one_element.PluginContainer()->RequestTouchEventType( |
| WebPluginContainer::kTouchEventRequestTypeRawLowLatency); |
| WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( |
| plugin_container_one_element.PluginContainer()) |
| ->Plugin(); |
| EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); |
| |
| { |
| WebRect rect = plugin_container_one_element.BoundsInViewport(); |
| WebPointerEvent event( |
| WebInputEvent::kPointerDown, |
| WebPointerProperties( |
| 1, WebPointerProperties::PointerType::kTouch, |
| WebPointerProperties::Button::kLeft, |
| WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2), |
| WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2)), |
| 1.0f, 1.0f); |
| |
| WebCoalescedInputEvent coalesced_event(event); |
| |
| web_view->HandleInputEvent(coalesced_event); |
| web_view->DispatchBufferedTouchEvents(); |
| RunPendingTasks(); |
| |
| EXPECT_EQ(static_cast<const size_t>(1), |
| test_plugin->GetCoalescedEventCount()); |
| EXPECT_EQ(WebInputEvent::kTouchStart, test_plugin->GetLastInputEventType()); |
| EXPECT_EQ(rect.width / 2, test_plugin->GetLastEventLocation().X()); |
| EXPECT_EQ(rect.height / 2, test_plugin->GetLastEventLocation().Y()); |
| } |
| |
| { |
| WebRect rect = plugin_container_one_element.BoundsInViewport(); |
| WebPointerEvent event1( |
| WebInputEvent::kPointerMove, |
| WebPointerProperties(1, WebPointerProperties::PointerType::kTouch, |
| WebPointerProperties::Button::kLeft, |
| WebFloatPoint(rect.x + rect.width / 2 + 1, |
| rect.y + rect.height / 2 + 1), |
| WebFloatPoint(rect.x + rect.width / 2 + 1, |
| rect.y + rect.height / 2 + 1)), |
| 1.0f, 1.0f); |
| |
| WebCoalescedInputEvent coalesced_event(event1); |
| |
| WebPointerEvent event2( |
| WebInputEvent::kPointerMove, |
| WebPointerProperties(1, WebPointerProperties::PointerType::kTouch, |
| WebPointerProperties::Button::kLeft, |
| WebFloatPoint(rect.x + rect.width / 2 + 2, |
| rect.y + rect.height / 2 + 2), |
| WebFloatPoint(rect.x + rect.width / 2 + 2, |
| rect.y + rect.height / 2 + 2)), |
| 1.0f, 1.0f); |
| WebPointerEvent event3( |
| WebInputEvent::kPointerMove, |
| WebPointerProperties(1, WebPointerProperties::PointerType::kTouch, |
| WebPointerProperties::Button::kLeft, |
| WebFloatPoint(rect.x + rect.width / 2 + 3, |
| rect.y + rect.height / 2 + 3), |
| WebFloatPoint(rect.x + rect.width / 2 + 3, |
| rect.y + rect.height / 2 + 3)), |
| 1.0f, 1.0f); |
| |
| coalesced_event.AddCoalescedEvent(event2); |
| coalesced_event.AddCoalescedEvent(event3); |
| |
| web_view->HandleInputEvent(coalesced_event); |
| web_view->DispatchBufferedTouchEvents(); |
| RunPendingTasks(); |
| |
| EXPECT_EQ(static_cast<const size_t>(3), |
| test_plugin->GetCoalescedEventCount()); |
| EXPECT_EQ(WebInputEvent::kTouchMove, test_plugin->GetLastInputEventType()); |
| EXPECT_EQ(rect.width / 2 + 1, test_plugin->GetLastEventLocation().X()); |
| EXPECT_EQ(rect.height / 2 + 1, test_plugin->GetLastEventLocation().Y()); |
| } |
| } |
| |
| TEST_F(WebPluginContainerTest, MouseWheelEventScrolled) { |
| RegisterMockedURL("plugin_scroll.html"); |
| // Must outlive |web_view_helper|. |
| CustomPluginWebFrameClient<EventTestPlugin> plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_scroll.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| web_view->SmoothScroll(0, 200, 0); |
| UpdateAllLifecyclePhases(web_view); |
| RunPendingTasks(); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("scrolled-plugin")); |
| plugin_container_one_element.PluginContainer()->RequestTouchEventType( |
| WebPluginContainer::kTouchEventRequestTypeRaw); |
| WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( |
| plugin_container_one_element.PluginContainer()) |
| ->Plugin(); |
| EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); |
| |
| WebMouseWheelEvent event(WebInputEvent::kMouseWheel, |
| WebInputEvent::kNoModifiers, |
| WebInputEvent::GetStaticTimeStampForTests()); |
| |
| WebRect rect = plugin_container_one_element.BoundsInViewport(); |
| event.SetPositionInWidget(rect.x + rect.width / 2, rect.y + rect.height / 2); |
| |
| web_view->HandleInputEvent(WebCoalescedInputEvent(event)); |
| RunPendingTasks(); |
| |
| EXPECT_EQ(WebInputEvent::kMouseWheel, test_plugin->GetLastInputEventType()); |
| EXPECT_EQ(rect.width / 2, test_plugin->GetLastEventLocation().X()); |
| EXPECT_EQ(rect.height / 2, test_plugin->GetLastEventLocation().Y()); |
| } |
| |
| TEST_F(WebPluginContainerTest, MouseEventScrolled) { |
| RegisterMockedURL("plugin_scroll.html"); |
| // Must outlive |web_view_helper|. |
| CustomPluginWebFrameClient<EventTestPlugin> plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_scroll.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| web_view->SmoothScroll(0, 200, 0); |
| UpdateAllLifecyclePhases(web_view); |
| RunPendingTasks(); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("scrolled-plugin")); |
| plugin_container_one_element.PluginContainer()->RequestTouchEventType( |
| WebPluginContainer::kTouchEventRequestTypeRaw); |
| WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( |
| plugin_container_one_element.PluginContainer()) |
| ->Plugin(); |
| EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); |
| |
| WebMouseEvent event(WebInputEvent::kMouseMove, WebInputEvent::kNoModifiers, |
| WebInputEvent::GetStaticTimeStampForTests()); |
| |
| WebRect rect = plugin_container_one_element.BoundsInViewport(); |
| event.SetPositionInWidget(rect.x + rect.width / 2, rect.y + rect.height / 2); |
| |
| web_view->HandleInputEvent(WebCoalescedInputEvent(event)); |
| RunPendingTasks(); |
| |
| EXPECT_EQ(WebInputEvent::kMouseMove, test_plugin->GetLastInputEventType()); |
| EXPECT_EQ(rect.width / 2, test_plugin->GetLastEventLocation().X()); |
| EXPECT_EQ(rect.height / 2, test_plugin->GetLastEventLocation().Y()); |
| } |
| |
| TEST_F(WebPluginContainerTest, MouseEventZoomed) { |
| RegisterMockedURL("plugin_scroll.html"); |
| // Must outlive |web_view_helper|. |
| CustomPluginWebFrameClient<EventTestPlugin> plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_scroll.html", &plugin_web_frame_client); |
| DCHECK(web_view); |
| web_view->GetSettings()->SetPluginsEnabled(true); |
| web_view->MainFrameWidget()->Resize(WebSize(300, 300)); |
| web_view->SetPageScaleFactor(2); |
| web_view->SmoothScroll(0, 300, 0); |
| UpdateAllLifecyclePhases(web_view); |
| RunPendingTasks(); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("scrolled-plugin")); |
| plugin_container_one_element.PluginContainer()->RequestTouchEventType( |
| WebPluginContainer::kTouchEventRequestTypeRaw); |
| WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( |
| plugin_container_one_element.PluginContainer()) |
| ->Plugin(); |
| EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); |
| |
| WebMouseEvent event(WebInputEvent::kMouseMove, WebInputEvent::kNoModifiers, |
| WebInputEvent::GetStaticTimeStampForTests()); |
| |
| WebRect rect = plugin_container_one_element.BoundsInViewport(); |
| event.SetPositionInWidget(rect.x + rect.width / 2, rect.y + rect.height / 2); |
| |
| web_view->HandleInputEvent(WebCoalescedInputEvent(event)); |
| RunPendingTasks(); |
| |
| // rect.width/height divided by 4 because the rect is in viewport bounds and |
| // there is a scale of 2 set. |
| EXPECT_EQ(WebInputEvent::kMouseMove, test_plugin->GetLastInputEventType()); |
| EXPECT_EQ(rect.width / 4, test_plugin->GetLastEventLocation().X()); |
| EXPECT_EQ(rect.height / 4, test_plugin->GetLastEventLocation().Y()); |
| } |
| |
| TEST_F(WebPluginContainerTest, MouseWheelEventZoomed) { |
| RegisterMockedURL("plugin_scroll.html"); |
| // Must outlive |web_view_helper|. |
| CustomPluginWebFrameClient<EventTestPlugin> plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_scroll.html", &plugin_web_frame_client); |
| DCHECK(web_view); |
| web_view->GetSettings()->SetPluginsEnabled(true); |
| web_view->MainFrameWidget()->Resize(WebSize(300, 300)); |
| web_view->SetPageScaleFactor(2); |
| web_view->SmoothScroll(0, 300, 0); |
| UpdateAllLifecyclePhases(web_view); |
| RunPendingTasks(); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("scrolled-plugin")); |
| plugin_container_one_element.PluginContainer()->RequestTouchEventType( |
| WebPluginContainer::kTouchEventRequestTypeRaw); |
| WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( |
| plugin_container_one_element.PluginContainer()) |
| ->Plugin(); |
| EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); |
| |
| WebMouseWheelEvent event(WebInputEvent::kMouseWheel, |
| WebInputEvent::kNoModifiers, |
| WebInputEvent::GetStaticTimeStampForTests()); |
| |
| WebRect rect = plugin_container_one_element.BoundsInViewport(); |
| event.SetPositionInWidget(rect.x + rect.width / 2, rect.y + rect.height / 2); |
| |
| web_view->HandleInputEvent(WebCoalescedInputEvent(event)); |
| RunPendingTasks(); |
| |
| // rect.width/height divided by 4 because the rect is in viewport bounds and |
| // there is a scale of 2 set. |
| EXPECT_EQ(WebInputEvent::kMouseWheel, test_plugin->GetLastInputEventType()); |
| EXPECT_EQ(rect.width / 4, test_plugin->GetLastEventLocation().X()); |
| EXPECT_EQ(rect.height / 4, test_plugin->GetLastEventLocation().Y()); |
| } |
| |
| TEST_F(WebPluginContainerTest, TouchEventZoomed) { |
| RegisterMockedURL("plugin_scroll.html"); |
| // Must outlive |web_view_helper|. |
| CustomPluginWebFrameClient<EventTestPlugin> plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_scroll.html", &plugin_web_frame_client); |
| DCHECK(web_view); |
| web_view->GetSettings()->SetPluginsEnabled(true); |
| web_view->Resize(WebSize(300, 300)); |
| web_view->SetPageScaleFactor(2); |
| web_view->SmoothScroll(0, 300, 0); |
| UpdateAllLifecyclePhases(web_view); |
| RunPendingTasks(); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("scrolled-plugin")); |
| plugin_container_one_element.PluginContainer()->RequestTouchEventType( |
| WebPluginContainer::kTouchEventRequestTypeRaw); |
| WebPlugin* plugin = static_cast<WebPluginContainerImpl*>( |
| plugin_container_one_element.PluginContainer()) |
| ->Plugin(); |
| EventTestPlugin* test_plugin = static_cast<EventTestPlugin*>(plugin); |
| |
| WebRect rect = plugin_container_one_element.BoundsInViewport(); |
| WebPointerEvent event( |
| WebInputEvent::kPointerDown, |
| WebPointerProperties( |
| 1, WebPointerProperties::PointerType::kTouch, |
| WebPointerProperties::Button::kLeft, |
| WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2), |
| WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2)), |
| 1.0f, 1.0f); |
| |
| web_view->HandleInputEvent(WebCoalescedInputEvent(event)); |
| web_view->DispatchBufferedTouchEvents(); |
| RunPendingTasks(); |
| |
| // rect.width/height divided by 4 because the rect is in viewport bounds and |
| // there is a scale of 2 set. |
| EXPECT_EQ(WebInputEvent::kTouchStart, test_plugin->GetLastInputEventType()); |
| EXPECT_EQ(rect.width / 4, test_plugin->GetLastEventLocation().X()); |
| EXPECT_EQ(rect.height / 4, test_plugin->GetLastEventLocation().Y()); |
| } |
| |
| // Verify that isRectTopmost returns false when the document is detached. |
| TEST_F(WebPluginContainerTest, IsRectTopmostTest) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebPluginContainerImpl* plugin_container_impl = |
| ToWebPluginContainerImpl(GetWebPluginContainer( |
| web_view, WebString::FromUTF8("translated-plugin"))); |
| plugin_container_impl->SetFrameRect(IntRect(0, 0, 300, 300)); |
| |
| WebRect rect = plugin_container_impl->GetElement().BoundsInViewport(); |
| EXPECT_TRUE(plugin_container_impl->IsRectTopmost(rect)); |
| |
| // Cause the plugin's frame to be detached. |
| web_view_helper.Reset(); |
| |
| EXPECT_FALSE(plugin_container_impl->IsRectTopmost(rect)); |
| } |
| |
| // Verify that IsRectTopmost works with odd and even dimensions. |
| TEST_F(WebPluginContainerTest, IsRectTopmostTestWithOddAndEvenDimensions) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebPluginContainerImpl* even_plugin_container_impl = |
| ToWebPluginContainerImpl(GetWebPluginContainer( |
| web_view, WebString::FromUTF8("translated-plugin"))); |
| even_plugin_container_impl->SetFrameRect(IntRect(0, 0, 300, 300)); |
| auto even_rect = even_plugin_container_impl->GetElement().BoundsInViewport(); |
| EXPECT_TRUE(even_plugin_container_impl->IsRectTopmost(even_rect)); |
| |
| WebPluginContainerImpl* odd_plugin_container_impl = |
| ToWebPluginContainerImpl(GetWebPluginContainer( |
| web_view, WebString::FromUTF8("odd-dimensions-plugin"))); |
| odd_plugin_container_impl->SetFrameRect(IntRect(0, 0, 300, 300)); |
| auto odd_rect = odd_plugin_container_impl->GetElement().BoundsInViewport(); |
| EXPECT_TRUE(odd_plugin_container_impl->IsRectTopmost(odd_rect)); |
| } |
| |
| TEST_F(WebPluginContainerTest, ClippedRectsForIframedElement) { |
| RegisterMockedURL("plugin_container.html"); |
| RegisterMockedURL("plugin_containing_page.html"); |
| |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebView* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_containing_page.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebElement plugin_element = web_view->MainFrame() |
| ->FirstChild() |
| ->ToWebLocalFrame() |
| ->GetDocument() |
| .GetElementById("translated-plugin"); |
| WebPluginContainerImpl* plugin_container_impl = |
| ToWebPluginContainerImpl(plugin_element.PluginContainer()); |
| |
| DCHECK(plugin_container_impl); |
| |
| IntRect window_rect, clip_rect, unobscured_rect; |
| CalculateGeometry(plugin_container_impl, window_rect, clip_rect, |
| unobscured_rect); |
| EXPECT_EQ(IntRect(20, 220, 40, 40), window_rect); |
| EXPECT_EQ(IntRect(0, 0, 40, 40), clip_rect); |
| EXPECT_EQ(IntRect(0, 0, 40, 40), unobscured_rect); |
| |
| // Cause the plugin's frame to be detached. |
| web_view_helper.Reset(); |
| } |
| |
| TEST_F(WebPluginContainerTest, ClippedRectsForShiftedIframedElement) { |
| RegisterMockedURL("plugin_hidden_before_scroll.html"); |
| RegisterMockedURL("shifted_plugin_containing_page.html"); |
| |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "shifted_plugin_containing_page.html", |
| &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| UpdateAllLifecyclePhases(web_view); |
| WebLocalFrame* iframe = |
| web_view->MainFrame()->FirstChild()->ToWebLocalFrame(); |
| WebElement plugin_element = |
| iframe->GetDocument().GetElementById("plugin-hidden-before-scroll"); |
| WebPluginContainerImpl* plugin_container_impl = |
| ToWebPluginContainerImpl(plugin_element.PluginContainer()); |
| |
| DCHECK(plugin_container_impl); |
| |
| IntSize plugin_size(40, 40); |
| IntSize iframe_size(40, 40); |
| |
| IntPoint iframe_offset_in_root_frame(0, 300); |
| IntPoint plugin_offset_in_iframe(0, 40); |
| |
| auto compute_expected_values = [=](IntSize root_document_scroll_to, |
| IntSize iframe_scroll_to) { |
| IntPoint offset_in_iframe = plugin_offset_in_iframe - iframe_scroll_to; |
| IntPoint offset_in_root_document = |
| iframe_offset_in_root_frame - root_document_scroll_to; |
| // window_rect is a plugin rectangle in the root frame coordinates. |
| IntRect expected_window_rect = |
| IntRect(offset_in_root_document + offset_in_iframe, plugin_size); |
| |
| // unobscured_rect is the visible part of the plugin, inside the iframe. |
| IntRect expected_unobscured_rect(IntPoint(iframe_scroll_to), iframe_size); |
| expected_unobscured_rect.Intersect({plugin_offset_in_iframe, plugin_size}); |
| expected_unobscured_rect.MoveBy(-plugin_offset_in_iframe); |
| |
| // clip_rect is the visible part of the unobscured_rect, inside the |
| // root_frame. |
| IntRect expected_clip_rect = expected_unobscured_rect; |
| expected_clip_rect.MoveBy(expected_window_rect.Location()); |
| expected_clip_rect.Intersect({{0, 0}, IntSize(300, 300)}); |
| expected_clip_rect.MoveBy(-expected_window_rect.Location()); |
| |
| return std::make_tuple(expected_window_rect, expected_clip_rect, |
| expected_unobscured_rect); |
| }; |
| |
| IntSize root_document_scrolls_to[] = {IntSize(0, 0), |
| IntSize(0, 20), |
| IntSize(0, 300), |
| IntSize(0, 320), |
| IntSize(0, 340)}; |
| |
| IntSize iframe_scrolls_to[] = {IntSize(0, 0), |
| IntSize(0, 20), |
| IntSize(0, 40), |
| IntSize(0, 60), |
| IntSize(0, 80)}; |
| |
| for (auto& root_document_scroll_to : root_document_scrolls_to) { |
| for (auto& iframe_scroll_to : iframe_scrolls_to) { |
| web_view->SmoothScroll(root_document_scroll_to.Width(), |
| root_document_scroll_to.Height(), 0); |
| iframe->SetScrollOffset(iframe_scroll_to); |
| UpdateAllLifecyclePhases(web_view); |
| RunPendingTasks(); |
| |
| auto expected_values = |
| compute_expected_values(root_document_scroll_to, iframe_scroll_to); |
| |
| IntRect window_rect, clip_rect, unobscured_rect; |
| CalculateGeometry(plugin_container_impl, window_rect, clip_rect, |
| unobscured_rect); |
| |
| EXPECT_EQ(std::get<0>(expected_values), window_rect); |
| EXPECT_EQ(std::get<1>(expected_values), clip_rect); |
| |
| // It seems that CalculateGeometry calculates x and y values for empty |
| // rectangles slightly differently, but these values are not important in |
| // the empty case. |
| if(std::get<2>(expected_values).IsEmpty()) |
| EXPECT_TRUE(unobscured_rect.IsEmpty()); |
| else |
| EXPECT_EQ(std::get<2>(expected_values), unobscured_rect); |
| } |
| } |
| |
| // Cause the plugin's frame to be detached. |
| web_view_helper.Reset(); |
| } |
| |
| TEST_F(WebPluginContainerTest, ClippedRectsForSubpixelPositionedPlugin) { |
| RegisterMockedURL("plugin_container.html"); |
| |
| // Must outlive |web_view_helper|. |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebElement plugin_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| "subpixel-positioned-plugin"); |
| WebPluginContainerImpl* plugin_container_impl = |
| ToWebPluginContainerImpl(plugin_element.PluginContainer()); |
| |
| DCHECK(plugin_container_impl); |
| |
| IntRect window_rect, clip_rect, unobscured_rect; |
| CalculateGeometry(plugin_container_impl, window_rect, clip_rect, |
| unobscured_rect); |
| EXPECT_EQ(IntRect(0, 0, 40, 40), window_rect); |
| EXPECT_EQ(IntRect(0, 0, 40, 40), clip_rect); |
| EXPECT_EQ(IntRect(0, 0, 40, 40), unobscured_rect); |
| |
| // Cause the plugin's frame to be detached. |
| web_view_helper.Reset(); |
| } |
| |
| TEST_F(WebPluginContainerTest, TopmostAfterDetachTest) { |
| static WebRect topmost_rect(10, 10, 40, 40); |
| |
| // Plugin that checks isRectTopmost in destroy(). |
| class TopmostPlugin : public FakeWebPlugin { |
| public: |
| explicit TopmostPlugin(const WebPluginParams& params) |
| : FakeWebPlugin(params) {} |
| |
| bool IsRectTopmost() { return Container()->IsRectTopmost(topmost_rect); } |
| |
| void Destroy() override { |
| // In destroy, IsRectTopmost is no longer valid. |
| EXPECT_FALSE(Container()->IsRectTopmost(topmost_rect)); |
| FakeWebPlugin::Destroy(); |
| } |
| |
| private: |
| ~TopmostPlugin() override = default; |
| }; |
| |
| RegisterMockedURL("plugin_container.html"); |
| // The client must outlive WebViewHelper. |
| CustomPluginWebFrameClient<TopmostPlugin> plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebPluginContainerImpl* plugin_container_impl = |
| ToWebPluginContainerImpl(GetWebPluginContainer( |
| web_view, WebString::FromUTF8("translated-plugin"))); |
| plugin_container_impl->SetFrameRect(IntRect(0, 0, 300, 300)); |
| |
| EXPECT_TRUE(plugin_container_impl->IsRectTopmost(topmost_rect)); |
| |
| TopmostPlugin* test_plugin = |
| static_cast<TopmostPlugin*>(plugin_container_impl->Plugin()); |
| EXPECT_TRUE(test_plugin->IsRectTopmost()); |
| |
| // Cause the plugin's frame to be detached. |
| web_view_helper.Reset(); |
| |
| EXPECT_FALSE(plugin_container_impl->IsRectTopmost(topmost_rect)); |
| } |
| |
| namespace { |
| |
| class CompositedPlugin : public FakeWebPlugin { |
| public: |
| explicit CompositedPlugin(const WebPluginParams& params) |
| : FakeWebPlugin(params), layer_(cc::Layer::Create()) {} |
| |
| cc::Layer* GetCcLayer() const { return layer_.get(); } |
| |
| // WebPlugin |
| |
| bool Initialize(WebPluginContainer* container) override { |
| if (!FakeWebPlugin::Initialize(container)) |
| return false; |
| container->SetCcLayer(layer_.get(), false); |
| return true; |
| } |
| |
| void Destroy() override { |
| Container()->SetCcLayer(nullptr, false); |
| FakeWebPlugin::Destroy(); |
| } |
| |
| private: |
| ~CompositedPlugin() override = default; |
| |
| scoped_refptr<cc::Layer> layer_; |
| }; |
| |
| } // namespace |
| |
| TEST_F(WebPluginContainerTest, CompositedPluginCAP) { |
| ScopedCompositeAfterPaintForTest enable_cap(true); |
| RegisterMockedURL("plugin.html"); |
| // Must outlive |web_view_helper| |
| CustomPluginWebFrameClient<CompositedPlugin> web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin.html", &web_frame_client); |
| EnablePlugins(web_view, WebSize(800, 600)); |
| |
| WebPluginContainerImpl* container = static_cast<WebPluginContainerImpl*>( |
| GetWebPluginContainer(web_view, WebString::FromUTF8("plugin"))); |
| ASSERT_TRUE(container); |
| const auto* plugin = |
| static_cast<const CompositedPlugin*>(container->Plugin()); |
| |
| std::unique_ptr<PaintController> paint_controller = PaintController::Create(); |
| paint_controller->UpdateCurrentPaintChunkProperties( |
| base::nullopt, PropertyTreeState::Root()); |
| GraphicsContext graphics_context(*paint_controller); |
| container->Paint(graphics_context, kGlobalPaintNormalPhase, |
| CullRect(IntRect(10, 10, 400, 300))); |
| paint_controller->CommitNewDisplayItems(); |
| |
| const auto& display_items = |
| paint_controller->GetPaintArtifact().GetDisplayItemList(); |
| ASSERT_EQ(1u, display_items.size()); |
| ASSERT_EQ(DisplayItem::kForeignLayerPlugin, display_items[0].GetType()); |
| const auto& foreign_layer_display_item = |
| static_cast<const ForeignLayerDisplayItem&>(display_items[0]); |
| EXPECT_EQ(plugin->GetCcLayer(), foreign_layer_display_item.GetLayer()); |
| } |
| |
| TEST_F(WebPluginContainerTest, NeedsWheelEvents) { |
| RegisterMockedURL("plugin_container.html"); |
| // Must outlive |web_view_helper| |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "plugin_container.html", &plugin_web_frame_client); |
| EnablePlugins(web_view, WebSize(300, 300)); |
| |
| WebElement plugin_container_one_element = |
| web_view->MainFrameImpl()->GetDocument().GetElementById( |
| WebString::FromUTF8("translated-plugin")); |
| plugin_container_one_element.PluginContainer()->SetWantsWheelEvents(true); |
| |
| RunPendingTasks(); |
| EXPECT_TRUE(web_view->MainFrameImpl() |
| ->GetFrame() |
| ->GetEventHandlerRegistry() |
| .HasEventHandlers(EventHandlerRegistry::kWheelEventBlocking)); |
| } |
| |
| TEST_F(WebPluginContainerTest, IFramePluginDocumentDisplayNone) { |
| RegisterMockedURL("test.pdf", "application/pdf"); |
| RegisterMockedURL("iframe_pdf_display_none.html", "text/html"); |
| |
| TestPluginWebFrameClient plugin_web_frame_client; |
| frame_test_helpers::WebViewHelper web_view_helper; |
| WebViewImpl* web_view = web_view_helper.InitializeAndLoad( |
| base_url_ + "iframe_pdf_display_none.html", &plugin_web_frame_client); |
| UpdateAllLifecyclePhases(web_view); |
| |
| WebFrame* web_iframe = web_view->MainFrame()->FirstChild(); |
| LocalFrame* iframe = ToLocalFrame(WebFrame::ToCoreFrame(*web_iframe)); |
| EXPECT_TRUE(iframe->GetWebPluginContainer()); |
| } |
| |
| } // namespace blink |