OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/html/HTMLInputElement.h" | 5 #include "core/html/HTMLInputElement.h" |
6 | 6 |
7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
| 8 #include "core/dom/IntersectionObserverController.h" |
8 #include "core/frame/FrameHost.h" | 9 #include "core/frame/FrameHost.h" |
9 #include "core/frame/FrameView.h" | 10 #include "core/frame/FrameView.h" |
10 #include "core/frame/VisualViewport.h" | 11 #include "core/frame/VisualViewport.h" |
11 #include "core/html/HTMLBodyElement.h" | 12 #include "core/html/HTMLBodyElement.h" |
12 #include "core/html/HTMLFormElement.h" | 13 #include "core/html/HTMLFormElement.h" |
13 #include "core/html/HTMLHtmlElement.h" | 14 #include "core/html/HTMLHtmlElement.h" |
14 #include "core/html/HTMLOptionElement.h" | 15 #include "core/html/HTMLOptionElement.h" |
15 #include "core/html/forms/DateTimeChooser.h" | 16 #include "core/html/forms/DateTimeChooser.h" |
| 17 #include "core/loader/EmptyClients.h" |
16 #include "core/testing/DummyPageHolder.h" | 18 #include "core/testing/DummyPageHolder.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
18 #include <memory> | 20 #include <memory> |
19 | 21 |
20 namespace blink { | 22 namespace blink { |
21 | 23 |
22 class HTMLInputElementTest : public testing::Test { | 24 class HTMLInputElementTest : public testing::Test { |
23 protected: | 25 protected: |
24 Document& document() { return m_pageHolder->document(); } | 26 Document& document() { return m_pageHolder->document(); } |
25 HTMLInputElement& testElement() | 27 HTMLInputElement& testElement() |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 document().view()->updateAllLifecyclePhases(); | 160 document().view()->updateAllLifecyclePhases(); |
159 HTMLInputElement* input = toHTMLInputElement(document().body()->firstChild()
); | 161 HTMLInputElement* input = toHTMLInputElement(document().body()->firstChild()
); |
160 | 162 |
161 DateTimeChooserParameters params; | 163 DateTimeChooserParameters params; |
162 bool success = input->setupDateTimeChooserParameters(params); | 164 bool success = input->setupDateTimeChooserParameters(params); |
163 EXPECT_TRUE(success); | 165 EXPECT_TRUE(success); |
164 EXPECT_EQ("date", params.type); | 166 EXPECT_EQ("date", params.type); |
165 EXPECT_EQ(IntRect(16, 16, 400, 100), params.anchorRectInScreen); | 167 EXPECT_EQ(IntRect(16, 16, 400, 100), params.anchorRectInScreen); |
166 } | 168 } |
167 | 169 |
| 170 class TestPasswordChromeClient : public EmptyChromeClient { |
| 171 public: |
| 172 static TestPasswordChromeClient* create() { return new TestPasswordChromeCli
ent; } |
| 173 ~TestPasswordChromeClient() override {} |
| 174 void passwordFieldBecameVisible(HTMLInputElement&) override { m_passwordFiel
dVisibleCalled = true; } |
| 175 bool passwordFieldVisibleCalled() { return m_passwordFieldVisibleCalled; } |
| 176 private: |
| 177 bool m_passwordFieldVisibleCalled = false; |
| 178 }; |
| 179 |
| 180 // Tests that ChromeClient::passwordFieldBecameVisible() is called when |
| 181 // a visible password field appears on the page. |
| 182 TEST_F(HTMLInputElementTest, PasswordVisibilityObserver) |
| 183 { |
| 184 Page::PageClients pageClients; |
| 185 fillWithEmptyClients(pageClients); |
| 186 TestPasswordChromeClient* chromeClientUnowned = TestPasswordChromeClient::cr
eate(); |
| 187 pageClients.chromeClient = chromeClientUnowned; |
| 188 |
| 189 std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create(IntSiz
e(2000, 2000), &pageClients); |
| 190 pageHolder->document().body()->setInnerHTML("<input type='password'>", ASSER
T_NO_EXCEPTION); |
| 191 pageHolder->document().view()->updateAllLifecyclePhases(); |
| 192 |
| 193 // Force the intersection observer callback to fire synchronously. |
| 194 ASSERT_TRUE(pageHolder->document().intersectionObserverController()); |
| 195 pageHolder->document().intersectionObserverController()->deliverIntersection
Observations(); |
| 196 |
| 197 EXPECT_TRUE(chromeClientUnowned->passwordFieldVisibleCalled()); |
| 198 } |
| 199 |
| 200 // Tests that ChromeClient::passwordFieldBecameVisible() is called when |
| 201 // a previously invisible password field becomes visible. |
| 202 TEST_F(HTMLInputElementTest, InvisiblePasswordFieldBecomesVisible) |
| 203 { |
| 204 Page::PageClients pageClients; |
| 205 fillWithEmptyClients(pageClients); |
| 206 TestPasswordChromeClient* chromeClientUnowned = TestPasswordChromeClient::cr
eate(); |
| 207 pageClients.chromeClient = chromeClientUnowned; |
| 208 |
| 209 std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create(IntSiz
e(2000, 2000), &pageClients); |
| 210 pageHolder->document().body()->setInnerHTML("<input type='password' style='d
isplay:none;'>", ASSERT_NO_EXCEPTION); |
| 211 pageHolder->document().view()->updateAllLifecyclePhases(); |
| 212 |
| 213 // Force the intersection observer callback to fire synchronously. |
| 214 ASSERT_TRUE(pageHolder->document().intersectionObserverController()); |
| 215 pageHolder->document().intersectionObserverController()->deliverIntersection
Observations(); |
| 216 |
| 217 // The callback should not fire for a hidden password field. |
| 218 EXPECT_FALSE(chromeClientUnowned->passwordFieldVisibleCalled()); |
| 219 |
| 220 // Now make the previously invisible password field visible. |
| 221 HTMLInputElement* input = toHTMLInputElement(pageHolder->document().body()->
firstChild()); |
| 222 input->setAttribute("style", "", ASSERT_NO_EXCEPTION); |
| 223 pageHolder->document().view()->updateAllLifecyclePhases(); |
| 224 pageHolder->document().intersectionObserverController()->deliverIntersection
Observations(); |
| 225 EXPECT_TRUE(chromeClientUnowned->passwordFieldVisibleCalled()); |
| 226 } |
| 227 |
| 228 // Tests that ChromeClient::passwordFieldBecameVisible() is called when |
| 229 // a previously non-password field becomes a password field. |
| 230 TEST_F(HTMLInputElementTest, NonPasswordFieldBecomesPassword) |
| 231 { |
| 232 Page::PageClients pageClients; |
| 233 fillWithEmptyClients(pageClients); |
| 234 TestPasswordChromeClient* chromeClientUnowned = TestPasswordChromeClient::cr
eate(); |
| 235 pageClients.chromeClient = chromeClientUnowned; |
| 236 |
| 237 std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create(IntSiz
e(2000, 2000), &pageClients); |
| 238 pageHolder->document().body()->setInnerHTML("<input type='text'>", ASSERT_NO
_EXCEPTION); |
| 239 pageHolder->document().view()->updateAllLifecyclePhases(); |
| 240 |
| 241 // With no password field on the page, an intersection observer has |
| 242 // not been created and the document does not have an |
| 243 // intersectionObserverController(). |
| 244 EXPECT_FALSE(pageHolder->document().intersectionObserverController()); |
| 245 EXPECT_FALSE(chromeClientUnowned->passwordFieldVisibleCalled()); |
| 246 |
| 247 // Now make the previously non-password field a password field. |
| 248 HTMLInputElement* input = toHTMLInputElement(pageHolder->document().body()->
firstChild()); |
| 249 input->setType("password"); |
| 250 pageHolder->document().view()->updateAllLifecyclePhases(); |
| 251 ASSERT_TRUE(pageHolder->document().intersectionObserverController()); |
| 252 pageHolder->document().intersectionObserverController()->deliverIntersection
Observations(); |
| 253 EXPECT_TRUE(chromeClientUnowned->passwordFieldVisibleCalled()); |
| 254 } |
| 255 |
| 256 // Tests that ChromeClient::passwordFieldBecameVisible() is *not* called |
| 257 // when a previously invisible password field becomes a visible |
| 258 // non-password field. |
| 259 TEST_F(HTMLInputElementTest, InvisiblePasswordFieldBecomesVisibleNonPasswordFiel
d) |
| 260 { |
| 261 Page::PageClients pageClients; |
| 262 fillWithEmptyClients(pageClients); |
| 263 TestPasswordChromeClient* chromeClientUnowned = TestPasswordChromeClient::cr
eate(); |
| 264 pageClients.chromeClient = chromeClientUnowned; |
| 265 |
| 266 std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create(IntSiz
e(2000, 2000), &pageClients); |
| 267 pageHolder->document().body()->setInnerHTML("<input type='password' style='d
isplay:none;'>", ASSERT_NO_EXCEPTION); |
| 268 pageHolder->document().view()->updateAllLifecyclePhases(); |
| 269 |
| 270 ASSERT_TRUE(pageHolder->document().intersectionObserverController()); |
| 271 pageHolder->document().intersectionObserverController()->deliverIntersection
Observations(); |
| 272 EXPECT_FALSE(chromeClientUnowned->passwordFieldVisibleCalled()); |
| 273 |
| 274 // Now make the previously invisible password field a visible non-password f
ield. |
| 275 HTMLInputElement* input = toHTMLInputElement(pageHolder->document().body()->
firstChild()); |
| 276 input->setType("text"); |
| 277 input->setAttribute("style", "", ASSERT_NO_EXCEPTION); |
| 278 pageHolder->document().view()->updateAllLifecyclePhases(); |
| 279 |
| 280 ASSERT_TRUE(pageHolder->document().intersectionObserverController()); |
| 281 pageHolder->document().intersectionObserverController()->deliverIntersection
Observations(); |
| 282 EXPECT_FALSE(chromeClientUnowned->passwordFieldVisibleCalled()); |
| 283 } |
| 284 |
168 } // namespace blink | 285 } // namespace blink |
OLD | NEW |