1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "web/ExternalPopupMenu.h"
8 #include "core/HTMLNames.h"
9 #include "core/dom/NodeComputedStyle.h"
10 #include "core/frame/FrameHost.h"
11 #include "core/frame/VisualViewport.h"
12 #include "core/html/HTMLSelectElement.h"
13 #include "core/layout/LayoutMenuList.h"
14 #include "core/page/Page.h"
15 #include "core/testing/DummyPageHolder.h"
16 #include "platform/PopupMenu.h"
17 #include "platform/testing/URLTestHelpers.h"
18 #include "public/platform/Platform.h"
19 #include "public/platform/WebUnitTestSupport.h"
20 #include "public/web/WebExternalPopupMenu.h"
21 #include "public/web/WebPopupMenuInfo.h"
22 #include "public/web/WebSettings.h"
23 #include "web/WebLocalFrameImpl.h"
24 #include "web/tests/FrameTestHelpers.h"
25 #include <gtest/gtest.h>
29 class ExternalPopupMenuDisplayNoneItemsTest
: public testing::Test
{
31 ExternalPopupMenuDisplayNoneItemsTest() { }
36 m_dummyPageHolder
= DummyPageHolder::create(IntSize(800, 600));
37 RefPtrWillBeRawPtr
<HTMLSelectElement
> element
= HTMLSelectElement::create(m_dummyPageHolder
->document());
38 // Set the 4th an 5th items to have "display: none" property
39 element
->setInnerHTML("<option><option><option><option style='display:none;'><option style='display:none;'><option><option>", ASSERT_NO_EXCEPTION
);
40 m_dummyPageHolder
->document().body()->appendChild(element
.get(), ASSERT_NO_EXCEPTION
);
41 m_ownerElement
= element
.release();
42 m_dummyPageHolder
->document().updateLayoutIgnorePendingStylesheets();
45 OwnPtr
<DummyPageHolder
> m_dummyPageHolder
;
46 RefPtrWillBePersistent
<HTMLSelectElement
> m_ownerElement
;
49 TEST_F(ExternalPopupMenuDisplayNoneItemsTest
, PopupMenuInfoSizeTest
)
51 WebPopupMenuInfo info
;
52 ExternalPopupMenu::getPopupMenuInfo(info
, *m_ownerElement
);
53 EXPECT_EQ(5U, info
.items
.size());
56 TEST_F(ExternalPopupMenuDisplayNoneItemsTest
, IndexMappingTest
)
58 // 6th indexed item in popupmenu would be the 4th item in ExternalPopupMenu,
60 EXPECT_EQ(4, ExternalPopupMenu::toExternalPopupMenuItemIndex(6, *m_ownerElement
));
61 EXPECT_EQ(6, ExternalPopupMenu::toPopupMenuItemIndex(4, *m_ownerElement
));
63 // Invalid index, methods should return -1.
64 EXPECT_EQ(-1, ExternalPopupMenu::toExternalPopupMenuItemIndex(8, *m_ownerElement
));
65 EXPECT_EQ(-1, ExternalPopupMenu::toPopupMenuItemIndex(8, *m_ownerElement
));
68 class ExternalPopupMenuWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
70 WebExternalPopupMenu
* createExternalPopupMenu(const WebPopupMenuInfo
&, WebExternalPopupMenuClient
*) override
72 return &m_mockWebExternalPopupMenu
;
74 WebRect
shownBounds() const
76 return m_mockWebExternalPopupMenu
.shownBounds();
79 class MockWebExternalPopupMenu
: public WebExternalPopupMenu
{
80 void show(const WebRect
& bounds
) override
82 m_shownBounds
= bounds
;
84 void close() override
{ }
87 WebRect
shownBounds() const
93 WebRect m_shownBounds
;
95 WebRect m_shownBounds
;
96 MockWebExternalPopupMenu m_mockWebExternalPopupMenu
;
99 class ExternalPopupMenuTest
: public testing::Test
{
101 ExternalPopupMenuTest() : m_baseURL("http://www.test.com") { }
104 void SetUp() override
106 m_helper
.initialize(false, &m_webFrameClient
, &m_webViewClient
);
107 webView()->setUseExternalPopupMenus(true);
109 void TearDown() override
111 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
114 void registerMockedURLLoad(const std::string
& fileName
)
116 URLTestHelpers::registerMockedURLLoad(URLTestHelpers::toKURL(m_baseURL
+ fileName
), WebString::fromUTF8(fileName
.c_str()), WebString::fromUTF8("popup/"), WebString::fromUTF8("text/html"));
119 void loadFrame(const std::string
& fileName
)
121 FrameTestHelpers::loadFrame(mainFrame(), m_baseURL
+ fileName
);
124 WebViewImpl
* webView() const { return m_helper
.webViewImpl(); }
125 const ExternalPopupMenuWebFrameClient
& client() const { return m_webFrameClient
; }
126 WebLocalFrameImpl
* mainFrame() const { return m_helper
.webViewImpl()->mainFrameImpl(); }
129 std::string m_baseURL
;
130 FrameTestHelpers::TestWebViewClient m_webViewClient
;
131 ExternalPopupMenuWebFrameClient m_webFrameClient
;
132 FrameTestHelpers::WebViewHelper m_helper
;
135 TEST_F(ExternalPopupMenuTest
, PopupAccountsForVisualViewportOffset
)
137 registerMockedURLLoad("select_mid_screen.html");
138 loadFrame("select_mid_screen.html");
140 webView()->resize(WebSize(100, 100));
143 HTMLSelectElement
* select
= toHTMLSelectElement(mainFrame()->frame()->document()->getElementById("select"));
144 LayoutMenuList
* menuList
= toLayoutMenuList(select
->layoutObject());
145 ASSERT_TRUE(menuList
);
147 VisualViewport
& visualViewport
= webView()->page()->frameHost().visualViewport();
149 IntRect rectInDocument
= menuList
->absoluteBoundingBoxRect();
151 webView()->setPageScaleFactor(2);
152 IntPoint
scrollDelta(20, 30);
153 visualViewport
.move(scrollDelta
);
157 EXPECT_EQ(rectInDocument
.x() - scrollDelta
.x(), client().shownBounds().x
);
158 EXPECT_EQ(rectInDocument
.y() - scrollDelta
.y(), client().shownBounds().y
);
161 TEST_F(ExternalPopupMenuTest
, DidAcceptIndex
)
163 registerMockedURLLoad("select.html");
164 loadFrame("select.html");
166 HTMLSelectElement
* select
= toHTMLSelectElement(mainFrame()->frame()->document()->getElementById("select"));
167 LayoutMenuList
* menuList
= toLayoutMenuList(select
->layoutObject());
168 ASSERT_TRUE(menuList
);
171 ASSERT_TRUE(select
->popupIsVisible());
173 WebExternalPopupMenuClient
* client
= static_cast<ExternalPopupMenu
*>(select
->popup());
174 client
->didAcceptIndex(2);
175 EXPECT_FALSE(select
->popupIsVisible());
176 ASSERT_STREQ("2", menuList
->text().utf8().data());
177 EXPECT_EQ(2, select
->selectedIndex());
180 TEST_F(ExternalPopupMenuTest
, DidAcceptIndices
)
182 registerMockedURLLoad("select.html");
183 loadFrame("select.html");
185 HTMLSelectElement
* select
= toHTMLSelectElement(mainFrame()->frame()->document()->getElementById("select"));
186 LayoutMenuList
* menuList
= toLayoutMenuList(select
->layoutObject());
187 ASSERT_TRUE(menuList
);
190 ASSERT_TRUE(select
->popupIsVisible());
192 WebExternalPopupMenuClient
* client
= static_cast<ExternalPopupMenu
*>(select
->popup());
193 int indices
[] = { 2 };
194 WebVector
<int> indicesVector(indices
, 1);
195 client
->didAcceptIndices(indicesVector
);
196 EXPECT_FALSE(select
->popupIsVisible());
197 EXPECT_STREQ("2", menuList
->text().utf8().data());
198 EXPECT_EQ(2, select
->selectedIndex());
201 TEST_F(ExternalPopupMenuTest
, DidAcceptIndicesClearSelect
)
203 registerMockedURLLoad("select.html");
204 loadFrame("select.html");
206 HTMLSelectElement
* select
= toHTMLSelectElement(mainFrame()->frame()->document()->getElementById("select"));
207 LayoutMenuList
* menuList
= toLayoutMenuList(select
->layoutObject());
208 ASSERT_TRUE(menuList
);
211 ASSERT_TRUE(select
->popupIsVisible());
213 WebExternalPopupMenuClient
* client
= static_cast<ExternalPopupMenu
*>(select
->popup());
214 WebVector
<int> indices
;
215 client
->didAcceptIndices(indices
);
216 EXPECT_FALSE(select
->popupIsVisible());
217 EXPECT_EQ(-1, select
->selectedIndex());