1 /* 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "WebView.h" 33 34 #include <gtest/gtest.h> 35 #include "FrameTestHelpers.h" 36 #include "URLTestHelpers.h" 37 #include "WebAutofillClient.h" 38 #include "WebContentDetectionResult.h" 39 #include "WebDocument.h" 40 #include "WebElement.h" 41 #include "WebFrame.h" 42 #include "WebFrameClient.h" 43 #include "WebFrameImpl.h" 44 #include "WebHelperPluginImpl.h" 45 #include "WebHitTestResult.h" 46 #include "WebInputEvent.h" 47 #include "WebSettings.h" 48 #include "WebViewClient.h" 49 #include "WebViewImpl.h" 50 #include "WebWidget.h" 51 #include "core/dom/Document.h" 52 #include "core/dom/Element.h" 53 #include "core/html/HTMLDocument.h" 54 #include "core/page/FrameView.h" 55 #include "public/platform/Platform.h" 56 #include "public/platform/WebSize.h" 57 #include "public/platform/WebThread.h" 58 #include "public/platform/WebUnitTestSupport.h" 59 #include "public/web/WebWidgetClient.h" 60 61 using namespace WebKit; 62 using WebKit::FrameTestHelpers::runPendingTasks; 63 using WebKit::URLTestHelpers::toKURL; 64 65 namespace { 66 67 enum HorizontalScrollbarState { 68 NoHorizontalScrollbar, 69 VisibleHorizontalScrollbar, 70 }; 71 72 enum VerticalScrollbarState { 73 NoVerticalScrollbar, 74 VisibleVerticalScrollbar, 75 }; 76 77 class TestData { 78 public: 79 void setWebView(WebView* webView) { m_webView = static_cast<WebViewImpl*>(webView); } 80 void setSize(const WebSize& newSize) { m_size = newSize; } 81 HorizontalScrollbarState horizontalScrollbarState() const 82 { 83 return m_webView->hasHorizontalScrollbar() ? VisibleHorizontalScrollbar: NoHorizontalScrollbar; 84 } 85 VerticalScrollbarState verticalScrollbarState() const 86 { 87 return m_webView->hasVerticalScrollbar() ? VisibleVerticalScrollbar : NoVerticalScrollbar; 88 } 89 int width() const { return m_size.width; } 90 int height() const { return m_size.height; } 91 92 private: 93 WebSize m_size; 94 WebViewImpl* m_webView; 95 }; 96 97 class AutoResizeWebViewClient : public WebViewClient { 98 public: 99 // WebViewClient methods 100 virtual void didAutoResize(const WebSize& newSize) { m_testData.setSize(newSize); } 101 102 // Local methods 103 TestData& testData() { return m_testData; } 104 105 private: 106 TestData m_testData; 107 }; 108 109 class FormChangeWebViewClient : public WebViewClient { 110 public: 111 // WebViewClient methods 112 virtual void didChangeFormState(const WebNode& node) 113 { 114 m_focused = node.focused(); 115 m_called = true; 116 } 117 118 // Local methods 119 void reset() 120 { 121 m_called = false; 122 m_focused = false; 123 } 124 bool called() { return m_called; } 125 bool focused() { return m_focused; } 126 127 private: 128 bool m_called; 129 bool m_focused; 130 }; 131 132 class TapHandlingWebViewClient : public WebViewClient { 133 public: 134 // WebViewClient methods 135 virtual void didHandleGestureEvent(const WebGestureEvent& event, bool eventCancelled) 136 { 137 if (event.type == WebInputEvent::GestureTap) { 138 m_tapX = event.x; 139 m_tapY = event.y; 140 } else if (event.type == WebInputEvent::GestureLongPress) { 141 m_longpressX = event.x; 142 m_longpressY = event.y; 143 } 144 } 145 146 // Local methods 147 void reset() 148 { 149 m_tapX = -1; 150 m_tapY = -1; 151 m_longpressX = -1; 152 m_longpressY = -1; 153 } 154 int tapX() { return m_tapX; } 155 int tapY() { return m_tapY; } 156 int longpressX() { return m_longpressX; } 157 int longpressY() { return m_longpressY; } 158 159 private: 160 int m_tapX; 161 int m_tapY; 162 int m_longpressX; 163 int m_longpressY; 164 }; 165 166 class HelperPluginCreatingWebViewClient : public WebViewClient { 167 public: 168 // WebViewClient methods 169 virtual WebKit::WebWidget* createPopupMenu(WebKit::WebPopupType popupType) OVERRIDE 170 { 171 EXPECT_EQ(WebPopupTypeHelperPlugin, popupType); 172 m_helperPluginWebWidget = WebKit::WebHelperPlugin::create(this); 173 // The caller owns the object, but we retain a pointer for use in closeWidgetSoon(). 174 return m_helperPluginWebWidget; 175 } 176 177 virtual void initializeHelperPluginWebFrame(WebKit::WebHelperPlugin* plugin) OVERRIDE 178 { 179 ASSERT_TRUE(m_webFrameClient); 180 plugin->initializeFrame(m_webFrameClient); 181 } 182 183 // WebWidgetClient methods 184 virtual void closeWidgetSoon() OVERRIDE 185 { 186 ASSERT_TRUE(m_helperPluginWebWidget); 187 m_helperPluginWebWidget->close(); 188 m_helperPluginWebWidget = 0; 189 } 190 191 // Local methods 192 HelperPluginCreatingWebViewClient() 193 : m_helperPluginWebWidget(0) 194 , m_webFrameClient(0) 195 { 196 } 197 198 void setWebFrameClient(WebFrameClient* client) { m_webFrameClient = client; } 199 200 private: 201 WebWidget* m_helperPluginWebWidget; 202 WebFrameClient* m_webFrameClient; 203 }; 204 205 class WebViewTest : public testing::Test { 206 public: 207 WebViewTest() 208 : m_baseURL("http://www.test.com/") 209 { 210 } 211 212 virtual void TearDown() 213 { 214 Platform::current()->unitTestSupport()->unregisterAllMockedURLs(); 215 } 216 217 protected: 218 void testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize, 219 const std::string& pageWidth, const std::string& pageHeight, 220 int expectedWidth, int expectedHeight, 221 HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState); 222 223 void testTextInputType(WebTextInputType expectedType, const std::string& htmlFile); 224 void testInputMode(const WebString& expectedInputMode, const std::string& htmlFile); 225 226 std::string m_baseURL; 227 }; 228 229 TEST_F(WebViewTest, SetBaseBackgroundColor) 230 { 231 const WebColor kWhite = 0xFFFFFFFF; 232 const WebColor kBlue = 0xFF0000FF; 233 const WebColor kDarkCyan = 0xFF227788; 234 const WebColor kTranslucentPutty = 0x80BFB196; 235 236 WebView* webView = FrameTestHelpers::createWebView(); 237 EXPECT_EQ(kWhite, webView->backgroundColor()); 238 239 webView->setBaseBackgroundColor(kBlue); 240 EXPECT_EQ(kBlue, webView->backgroundColor()); 241 242 WebURL baseURL = URLTestHelpers::toKURL("http://example.com/"); 243 webView->mainFrame()->loadHTMLString( 244 "<html><head><style>body {background-color:#227788}</style></head></html>", baseURL); 245 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests(); 246 EXPECT_EQ(kDarkCyan, webView->backgroundColor()); 247 248 webView->mainFrame()->loadHTMLString( 249 "<html><head><style>body {background-color:rgba(255,0,0,0.5)}</style></head></html>", baseURL); 250 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests(); 251 // Expected: red (50% alpha) blended atop base of kBlue. 252 EXPECT_EQ(0xFF7F0080, webView->backgroundColor()); 253 254 webView->setBaseBackgroundColor(kTranslucentPutty); 255 // Expected: red (50% alpha) blended atop kTranslucentPutty. Note the alpha. 256 EXPECT_EQ(0xBFE93B32, webView->backgroundColor()); 257 258 webView->close(); 259 } 260 261 TEST_F(WebViewTest, FocusIsInactive) 262 { 263 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html"); 264 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "visible_iframe.html"); 265 266 webView->setFocus(true); 267 webView->setIsActive(true); 268 WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame()); 269 EXPECT_TRUE(frame->frame()->document()->isHTMLDocument()); 270 271 WebCore::HTMLDocument* document = static_cast<WebCore::HTMLDocument*>(frame->frame()->document()); 272 EXPECT_TRUE(document->hasFocus()); 273 webView->setFocus(false); 274 webView->setIsActive(false); 275 EXPECT_FALSE(document->hasFocus()); 276 webView->setFocus(true); 277 webView->setIsActive(true); 278 EXPECT_TRUE(document->hasFocus()); 279 webView->setFocus(true); 280 webView->setIsActive(false); 281 EXPECT_FALSE(document->hasFocus()); 282 webView->setFocus(false); 283 webView->setIsActive(true); 284 EXPECT_FALSE(document->hasFocus()); 285 286 webView->close(); 287 } 288 289 TEST_F(WebViewTest, ActiveState) 290 { 291 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html"); 292 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "visible_iframe.html"); 293 294 ASSERT_TRUE(webView); 295 296 webView->setIsActive(true); 297 EXPECT_TRUE(webView->isActive()); 298 299 webView->setIsActive(false); 300 EXPECT_FALSE(webView->isActive()); 301 302 webView->setIsActive(true); 303 EXPECT_TRUE(webView->isActive()); 304 305 webView->close(); 306 } 307 308 TEST_F(WebViewTest, HitTestResultAtWithPageScale) 309 { 310 std::string url = m_baseURL + "specify_size.html?" + "50px" + ":" + "50px"; 311 URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html"); 312 WebView* webView = FrameTestHelpers::createWebViewAndLoad(url, true, 0); 313 webView->resize(WebSize(100, 100)); 314 WebPoint hitPoint(75, 75); 315 316 // Image is at top left quandrant, so should not hit it. 317 WebHitTestResult negativeResult = webView->hitTestResultAt(hitPoint); 318 ASSERT_EQ(WebNode::ElementNode, negativeResult.node().nodeType()); 319 EXPECT_FALSE(negativeResult.node().to<WebElement>().hasTagName("img")); 320 negativeResult.reset(); 321 322 // Scale page up 2x so image should occupy the whole viewport. 323 webView->setPageScaleFactor(2.0f, WebPoint(0, 0)); 324 WebHitTestResult positiveResult = webView->hitTestResultAt(hitPoint); 325 ASSERT_EQ(WebNode::ElementNode, positiveResult.node().nodeType()); 326 EXPECT_TRUE(positiveResult.node().to<WebElement>().hasTagName("img")); 327 positiveResult.reset(); 328 329 webView->close(); 330 } 331 332 void WebViewTest::testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize, 333 const std::string& pageWidth, const std::string& pageHeight, 334 int expectedWidth, int expectedHeight, 335 HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState) 336 { 337 AutoResizeWebViewClient client; 338 std::string url = m_baseURL + "specify_size.html?" + pageWidth + ":" + pageHeight; 339 URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html"); 340 WebView* webView = FrameTestHelpers::createWebViewAndLoad(url, true, 0, &client); 341 client.testData().setWebView(webView); 342 343 WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame()); 344 WebCore::FrameView* frameView = frame->frame()->view(); 345 frameView->layout(); 346 EXPECT_FALSE(frameView->layoutPending()); 347 EXPECT_FALSE(frameView->needsLayout()); 348 349 webView->enableAutoResizeMode(minAutoResize, maxAutoResize); 350 EXPECT_TRUE(frameView->layoutPending()); 351 EXPECT_TRUE(frameView->needsLayout()); 352 frameView->layout(); 353 354 EXPECT_TRUE(frame->frame()->document()->isHTMLDocument()); 355 356 EXPECT_EQ(expectedWidth, client.testData().width()); 357 EXPECT_EQ(expectedHeight, client.testData().height()); 358 EXPECT_EQ(expectedHorizontalState, client.testData().horizontalScrollbarState()); 359 EXPECT_EQ(expectedVerticalState, client.testData().verticalScrollbarState()); 360 361 webView->close(); 362 } 363 364 TEST_F(WebViewTest, DISABLED_AutoResizeMinimumSize) 365 { 366 WebSize minAutoResize(91, 56); 367 WebSize maxAutoResize(403, 302); 368 std::string pageWidth = "91px"; 369 std::string pageHeight = "56px"; 370 int expectedWidth = 91; 371 int expectedHeight = 56; 372 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight, 373 expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar); 374 } 375 376 TEST_F(WebViewTest, AutoResizeHeightOverflowAndFixedWidth) 377 { 378 WebSize minAutoResize(90, 95); 379 WebSize maxAutoResize(90, 100); 380 std::string pageWidth = "60px"; 381 std::string pageHeight = "200px"; 382 int expectedWidth = 90; 383 int expectedHeight = 100; 384 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight, 385 expectedWidth, expectedHeight, NoHorizontalScrollbar, VisibleVerticalScrollbar); 386 } 387 388 TEST_F(WebViewTest, AutoResizeFixedHeightAndWidthOverflow) 389 { 390 WebSize minAutoResize(90, 100); 391 WebSize maxAutoResize(200, 100); 392 std::string pageWidth = "300px"; 393 std::string pageHeight = "80px"; 394 int expectedWidth = 200; 395 int expectedHeight = 100; 396 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight, 397 expectedWidth, expectedHeight, VisibleHorizontalScrollbar, NoVerticalScrollbar); 398 } 399 400 // Next three tests disabled for https://bugs.webkit.org/show_bug.cgi?id=92318 . 401 // It seems we can run three AutoResize tests, then the next one breaks. 402 TEST_F(WebViewTest, DISABLED_AutoResizeInBetweenSizes) 403 { 404 WebSize minAutoResize(90, 95); 405 WebSize maxAutoResize(200, 300); 406 std::string pageWidth = "100px"; 407 std::string pageHeight = "200px"; 408 int expectedWidth = 100; 409 int expectedHeight = 200; 410 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight, 411 expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar); 412 } 413 414 TEST_F(WebViewTest, DISABLED_AutoResizeOverflowSizes) 415 { 416 WebSize minAutoResize(90, 95); 417 WebSize maxAutoResize(200, 300); 418 std::string pageWidth = "300px"; 419 std::string pageHeight = "400px"; 420 int expectedWidth = 200; 421 int expectedHeight = 300; 422 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight, 423 expectedWidth, expectedHeight, VisibleHorizontalScrollbar, VisibleVerticalScrollbar); 424 } 425 426 TEST_F(WebViewTest, DISABLED_AutoResizeMaxSize) 427 { 428 WebSize minAutoResize(90, 95); 429 WebSize maxAutoResize(200, 300); 430 std::string pageWidth = "200px"; 431 std::string pageHeight = "300px"; 432 int expectedWidth = 200; 433 int expectedHeight = 300; 434 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight, 435 expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar); 436 } 437 438 void WebViewTest::testTextInputType(WebTextInputType expectedType, const std::string& htmlFile) 439 { 440 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str())); 441 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + htmlFile); 442 webView->setInitialFocus(false); 443 EXPECT_EQ(expectedType, webView->textInputInfo().type); 444 webView->close(); 445 } 446 447 TEST_F(WebViewTest, TextInputType) 448 { 449 testTextInputType(WebTextInputTypeText, "input_field_default.html"); 450 testTextInputType(WebTextInputTypePassword, "input_field_password.html"); 451 testTextInputType(WebTextInputTypeEmail, "input_field_email.html"); 452 testTextInputType(WebTextInputTypeSearch, "input_field_search.html"); 453 testTextInputType(WebTextInputTypeNumber, "input_field_number.html"); 454 testTextInputType(WebTextInputTypeTelephone, "input_field_tel.html"); 455 testTextInputType(WebTextInputTypeURL, "input_field_url.html"); 456 } 457 458 void WebViewTest::testInputMode(const WebString& expectedInputMode, const std::string& htmlFile) 459 { 460 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str())); 461 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + htmlFile); 462 webView->setInitialFocus(false); 463 EXPECT_EQ(expectedInputMode, webView->textInputInfo().inputMode); 464 webView->close(); 465 } 466 467 TEST_F(WebViewTest, InputMode) 468 { 469 testInputMode(WebString(), "input_mode_default.html"); 470 testInputMode(WebString("unknown"), "input_mode_default_unknown.html"); 471 testInputMode(WebString("verbatim"), "input_mode_default_verbatim.html"); 472 testInputMode(WebString("verbatim"), "input_mode_type_text_verbatim.html"); 473 testInputMode(WebString("verbatim"), "input_mode_type_search_verbatim.html"); 474 testInputMode(WebString(), "input_mode_type_url_verbatim.html"); 475 testInputMode(WebString("verbatim"), "input_mode_textarea_verbatim.html"); 476 } 477 478 TEST_F(WebViewTest, SetEditableSelectionOffsetsAndTextInputInfo) 479 { 480 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html")); 481 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html"); 482 webView->setInitialFocus(false); 483 webView->setEditableSelectionOffsets(5, 13); 484 WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame()); 485 EXPECT_EQ("56789abc", frame->selectionAsText()); 486 WebTextInputInfo info = webView->textInputInfo(); 487 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value); 488 EXPECT_EQ(5, info.selectionStart); 489 EXPECT_EQ(13, info.selectionEnd); 490 EXPECT_EQ(-1, info.compositionStart); 491 EXPECT_EQ(-1, info.compositionEnd); 492 webView->close(); 493 494 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_editable_populated.html")); 495 webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "content_editable_populated.html"); 496 webView->setInitialFocus(false); 497 webView->setEditableSelectionOffsets(8, 19); 498 frame = static_cast<WebFrameImpl*>(webView->mainFrame()); 499 EXPECT_EQ("89abcdefghi", frame->selectionAsText()); 500 info = webView->textInputInfo(); 501 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value); 502 EXPECT_EQ(8, info.selectionStart); 503 EXPECT_EQ(19, info.selectionEnd); 504 EXPECT_EQ(-1, info.compositionStart); 505 EXPECT_EQ(-1, info.compositionEnd); 506 webView->close(); 507 } 508 509 TEST_F(WebViewTest, ConfirmCompositionCursorPositionChange) 510 { 511 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html")); 512 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html"); 513 webView->setInitialFocus(false); 514 515 // Set up a composition that needs to be committed. 516 std::string compositionText("hello"); 517 518 WebVector<WebCompositionUnderline> emptyUnderlines; 519 webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3); 520 521 WebTextInputInfo info = webView->textInputInfo(); 522 EXPECT_EQ("hello", std::string(info.value.utf8().data())); 523 EXPECT_EQ(3, info.selectionStart); 524 EXPECT_EQ(3, info.selectionEnd); 525 EXPECT_EQ(0, info.compositionStart); 526 EXPECT_EQ(5, info.compositionEnd); 527 528 webView->confirmComposition(WebWidget::KeepSelection); 529 info = webView->textInputInfo(); 530 EXPECT_EQ(3, info.selectionStart); 531 EXPECT_EQ(3, info.selectionEnd); 532 EXPECT_EQ(-1, info.compositionStart); 533 EXPECT_EQ(-1, info.compositionEnd); 534 535 webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3); 536 info = webView->textInputInfo(); 537 EXPECT_EQ("helhellolo", std::string(info.value.utf8().data())); 538 EXPECT_EQ(6, info.selectionStart); 539 EXPECT_EQ(6, info.selectionEnd); 540 EXPECT_EQ(3, info.compositionStart); 541 EXPECT_EQ(8, info.compositionEnd); 542 543 webView->confirmComposition(WebWidget::DoNotKeepSelection); 544 info = webView->textInputInfo(); 545 EXPECT_EQ(8, info.selectionStart); 546 EXPECT_EQ(8, info.selectionEnd); 547 EXPECT_EQ(-1, info.compositionStart); 548 EXPECT_EQ(-1, info.compositionEnd); 549 550 webView->close(); 551 } 552 553 TEST_F(WebViewTest, InsertNewLinePlacementAfterConfirmComposition) 554 { 555 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html")); 556 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "text_area_populated.html"); 557 webView->setInitialFocus(false); 558 559 WebVector<WebCompositionUnderline> emptyUnderlines; 560 561 webView->setEditableSelectionOffsets(4, 4); 562 webView->setCompositionFromExistingText(8, 12, emptyUnderlines); 563 564 WebTextInputInfo info = webView->textInputInfo(); 565 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data())); 566 EXPECT_EQ(4, info.selectionStart); 567 EXPECT_EQ(4, info.selectionEnd); 568 EXPECT_EQ(8, info.compositionStart); 569 EXPECT_EQ(12, info.compositionEnd); 570 571 webView->confirmComposition(WebWidget::KeepSelection); 572 info = webView->textInputInfo(); 573 EXPECT_EQ(4, info.selectionStart); 574 EXPECT_EQ(4, info.selectionEnd); 575 EXPECT_EQ(-1, info.compositionStart); 576 EXPECT_EQ(-1, info.compositionEnd); 577 578 std::string compositionText("\n"); 579 webView->confirmComposition(WebString::fromUTF8(compositionText.c_str())); 580 info = webView->textInputInfo(); 581 EXPECT_EQ(5, info.selectionStart); 582 EXPECT_EQ(5, info.selectionEnd); 583 EXPECT_EQ(-1, info.compositionStart); 584 EXPECT_EQ(-1, info.compositionEnd); 585 EXPECT_EQ("0123\n456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data())); 586 587 webView->close(); 588 } 589 590 TEST_F(WebViewTest, FormChange) 591 { 592 FormChangeWebViewClient client; 593 client.reset(); 594 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_set_value_while_focused.html")); 595 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_set_value_while_focused.html", true, 0, &client); 596 EXPECT_TRUE(client.called()); 597 EXPECT_TRUE(client.focused()); 598 client.reset(); 599 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_set_value_while_not_focused.html")); 600 webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_set_value_while_not_focused.html", true, 0, &client); 601 EXPECT_TRUE(client.called()); 602 EXPECT_FALSE(client.focused()); 603 webView->close(); 604 } 605 606 TEST_F(WebViewTest, ExtendSelectionAndDelete) 607 { 608 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html")); 609 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html"); 610 webView->setInitialFocus(false); 611 webView->setEditableSelectionOffsets(10, 10); 612 webView->extendSelectionAndDelete(5, 8); 613 WebTextInputInfo info = webView->textInputInfo(); 614 EXPECT_EQ("01234ijklmnopqrstuvwxyz", std::string(info.value.utf8().data())); 615 EXPECT_EQ(5, info.selectionStart); 616 EXPECT_EQ(5, info.selectionEnd); 617 webView->extendSelectionAndDelete(10, 0); 618 info = webView->textInputInfo(); 619 EXPECT_EQ("ijklmnopqrstuvwxyz", std::string(info.value.utf8().data())); 620 webView->close(); 621 } 622 623 TEST_F(WebViewTest, SetCompositionFromExistingText) 624 { 625 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html")); 626 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html"); 627 webView->setInitialFocus(false); 628 WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1)); 629 underlines[0] = WebKit::WebCompositionUnderline(0, 4, 0, false); 630 webView->setEditableSelectionOffsets(4, 10); 631 webView->setCompositionFromExistingText(8, 12, underlines); 632 WebVector<WebCompositionUnderline> underlineResults = static_cast<WebViewImpl*>(webView)->compositionUnderlines(); 633 EXPECT_EQ(8u, underlineResults[0].startOffset); 634 EXPECT_EQ(12u, underlineResults[0].endOffset); 635 WebTextInputInfo info = webView->textInputInfo(); 636 EXPECT_EQ(4, info.selectionStart); 637 EXPECT_EQ(10, info.selectionEnd); 638 EXPECT_EQ(8, info.compositionStart); 639 EXPECT_EQ(12, info.compositionEnd); 640 WebVector<WebCompositionUnderline> emptyUnderlines; 641 webView->setCompositionFromExistingText(0, 0, emptyUnderlines); 642 info = webView->textInputInfo(); 643 EXPECT_EQ(4, info.selectionStart); 644 EXPECT_EQ(10, info.selectionEnd); 645 EXPECT_EQ(-1, info.compositionStart); 646 EXPECT_EQ(-1, info.compositionEnd); 647 webView->close(); 648 } 649 650 TEST_F(WebViewTest, SetCompositionFromExistingTextInTextArea) 651 { 652 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html")); 653 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "text_area_populated.html"); 654 webView->setInitialFocus(false); 655 WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1)); 656 underlines[0] = WebKit::WebCompositionUnderline(0, 4, 0, false); 657 webView->setEditableSelectionOffsets(27, 27); 658 std::string newLineText("\n"); 659 webView->confirmComposition(WebString::fromUTF8(newLineText.c_str())); 660 WebTextInputInfo info = webView->textInputInfo(); 661 EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data())); 662 663 webView->setEditableSelectionOffsets(31, 31); 664 webView->setCompositionFromExistingText(30, 34, underlines); 665 WebVector<WebCompositionUnderline> underlineResults = static_cast<WebViewImpl*>(webView)->compositionUnderlines(); 666 EXPECT_EQ(2u, underlineResults[0].startOffset); 667 EXPECT_EQ(6u, underlineResults[0].endOffset); 668 info = webView->textInputInfo(); 669 EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data())); 670 EXPECT_EQ(31, info.selectionStart); 671 EXPECT_EQ(31, info.selectionEnd); 672 EXPECT_EQ(30, info.compositionStart); 673 EXPECT_EQ(34, info.compositionEnd); 674 675 std::string compositionText("yolo"); 676 webView->confirmComposition(WebString::fromUTF8(compositionText.c_str())); 677 info = webView->textInputInfo(); 678 EXPECT_EQ("0123456789abcdefghijklmnopq\nrsyoloxyz", std::string(info.value.utf8().data())); 679 EXPECT_EQ(34, info.selectionStart); 680 EXPECT_EQ(34, info.selectionEnd); 681 EXPECT_EQ(-1, info.compositionStart); 682 EXPECT_EQ(-1, info.compositionEnd); 683 webView->close(); 684 } 685 686 TEST_F(WebViewTest, SetEditableSelectionOffsetsKeepsComposition) 687 { 688 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html")); 689 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html"); 690 webView->setInitialFocus(false); 691 692 std::string compositionTextFirst("hello "); 693 std::string compositionTextSecond("world"); 694 WebVector<WebCompositionUnderline> emptyUnderlines; 695 696 webView->confirmComposition(WebString::fromUTF8(compositionTextFirst.c_str())); 697 webView->setComposition(WebString::fromUTF8(compositionTextSecond.c_str()), emptyUnderlines, 5, 5); 698 699 WebTextInputInfo info = webView->textInputInfo(); 700 EXPECT_EQ("hello world", std::string(info.value.utf8().data())); 701 EXPECT_EQ(11, info.selectionStart); 702 EXPECT_EQ(11, info.selectionEnd); 703 EXPECT_EQ(6, info.compositionStart); 704 EXPECT_EQ(11, info.compositionEnd); 705 706 webView->setEditableSelectionOffsets(6, 6); 707 info = webView->textInputInfo(); 708 EXPECT_EQ("hello world", std::string(info.value.utf8().data())); 709 EXPECT_EQ(6, info.selectionStart); 710 EXPECT_EQ(6, info.selectionEnd); 711 EXPECT_EQ(6, info.compositionStart); 712 EXPECT_EQ(11, info.compositionEnd); 713 714 webView->setEditableSelectionOffsets(8, 8); 715 info = webView->textInputInfo(); 716 EXPECT_EQ("hello world", std::string(info.value.utf8().data())); 717 EXPECT_EQ(8, info.selectionStart); 718 EXPECT_EQ(8, info.selectionEnd); 719 EXPECT_EQ(6, info.compositionStart); 720 EXPECT_EQ(11, info.compositionEnd); 721 722 webView->setEditableSelectionOffsets(11, 11); 723 info = webView->textInputInfo(); 724 EXPECT_EQ("hello world", std::string(info.value.utf8().data())); 725 EXPECT_EQ(11, info.selectionStart); 726 EXPECT_EQ(11, info.selectionEnd); 727 EXPECT_EQ(6, info.compositionStart); 728 EXPECT_EQ(11, info.compositionEnd); 729 730 webView->setEditableSelectionOffsets(6, 11); 731 info = webView->textInputInfo(); 732 EXPECT_EQ("hello world", std::string(info.value.utf8().data())); 733 EXPECT_EQ(6, info.selectionStart); 734 EXPECT_EQ(11, info.selectionEnd); 735 EXPECT_EQ(6, info.compositionStart); 736 EXPECT_EQ(11, info.compositionEnd); 737 738 webView->setEditableSelectionOffsets(2, 2); 739 info = webView->textInputInfo(); 740 EXPECT_EQ("hello world", std::string(info.value.utf8().data())); 741 EXPECT_EQ(2, info.selectionStart); 742 EXPECT_EQ(2, info.selectionEnd); 743 EXPECT_EQ(-1, info.compositionStart); 744 EXPECT_EQ(-1, info.compositionEnd); 745 webView->close(); 746 } 747 748 TEST_F(WebViewTest, IsSelectionAnchorFirst) 749 { 750 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html")); 751 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html"); 752 WebFrame* frame = webView->mainFrame(); 753 754 webView->setInitialFocus(false); 755 webView->setEditableSelectionOffsets(4, 10); 756 EXPECT_TRUE(webView->isSelectionAnchorFirst()); 757 WebRect anchor; 758 WebRect focus; 759 webView->selectionBounds(anchor, focus); 760 frame->selectRange(WebPoint(focus.x, focus.y), WebPoint(anchor.x, anchor.y)); 761 EXPECT_FALSE(webView->isSelectionAnchorFirst()); 762 webView->close(); 763 } 764 765 TEST_F(WebViewTest, HistoryResetScrollAndScaleState) 766 { 767 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html")); 768 WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(FrameTestHelpers::createWebViewAndLoad(m_baseURL + "hello_world.html")); 769 webViewImpl->resize(WebSize(640, 480)); 770 webViewImpl->layout(); 771 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width); 772 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height); 773 774 // Make the page scale and scroll with the given paremeters. 775 webViewImpl->setPageScaleFactor(2.0f, WebPoint(116, 84)); 776 EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor()); 777 EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width); 778 EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height); 779 webViewImpl->page()->mainFrame()->loader()->history()->saveDocumentAndScrollState(); 780 781 // Confirm that restoring the page state restores the parameters. 782 webViewImpl->setPageScaleFactor(1.5f, WebPoint(16, 24)); 783 EXPECT_EQ(1.5f, webViewImpl->pageScaleFactor()); 784 EXPECT_EQ(16, webViewImpl->mainFrame()->scrollOffset().width); 785 EXPECT_EQ(24, webViewImpl->mainFrame()->scrollOffset().height); 786 // WebViewImpl::setPageScaleFactor is performing user scrolls, which will set the 787 // wasScrolledByUser flag on the main frame, and prevent restoreScrollPositionAndViewState 788 // from restoring the scrolling position. 789 webViewImpl->page()->mainFrame()->view()->setWasScrolledByUser(false); 790 webViewImpl->page()->mainFrame()->loader()->history()->restoreScrollPositionAndViewState(); 791 EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor()); 792 EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width); 793 EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height); 794 webViewImpl->page()->mainFrame()->loader()->history()->saveDocumentAndScrollState(); 795 796 // Confirm that resetting the page state resets the saved scroll position. 797 // The HistoryController treats a page scale factor of 0.0f as special and avoids 798 // restoring it to the WebView. 799 webViewImpl->resetScrollAndScaleState(); 800 EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor()); 801 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width); 802 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height); 803 webViewImpl->page()->mainFrame()->loader()->history()->restoreScrollPositionAndViewState(); 804 EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor()); 805 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width); 806 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height); 807 webViewImpl->close(); 808 } 809 810 class EnterFullscreenWebViewClient : public WebViewClient { 811 public: 812 // WebViewClient methods 813 virtual bool enterFullScreen() { return true; } 814 virtual void exitFullScreen() { } 815 }; 816 817 818 TEST_F(WebViewTest, EnterFullscreenResetScrollAndScaleState) 819 { 820 EnterFullscreenWebViewClient client; 821 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html")); 822 WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(FrameTestHelpers::createWebViewAndLoad(m_baseURL + "hello_world.html", true, 0, &client)); 823 webViewImpl->settings()->setFullScreenEnabled(true); 824 webViewImpl->resize(WebSize(640, 480)); 825 webViewImpl->layout(); 826 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width); 827 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height); 828 829 // Make the page scale and scroll with the given paremeters. 830 webViewImpl->setPageScaleFactor(2.0f, WebPoint(116, 84)); 831 EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor()); 832 EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width); 833 EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height); 834 835 RefPtr<WebCore::Element> element = static_cast<PassRefPtr<WebCore::Element> >(webViewImpl->mainFrame()->document().body()); 836 webViewImpl->enterFullScreenForElement(element.get()); 837 webViewImpl->willEnterFullScreen(); 838 webViewImpl->didEnterFullScreen(); 839 840 // Page scale factor must be 1.0 during fullscreen for elements to be sized 841 // properly. 842 EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor()); 843 844 // Make sure fullscreen nesting doesn't disrupt scroll/scale saving. 845 RefPtr<WebCore::Element> otherElement = static_cast<PassRefPtr<WebCore::Element> >(webViewImpl->mainFrame()->document().head()); 846 webViewImpl->enterFullScreenForElement(otherElement.get()); 847 848 // Confirm that exiting fullscreen restores the parameters. 849 webViewImpl->willExitFullScreen(); 850 webViewImpl->didExitFullScreen(); 851 EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor()); 852 EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width); 853 EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height); 854 855 webViewImpl->close(); 856 } 857 858 class ContentDetectorClient : public WebViewClient { 859 public: 860 ContentDetectorClient() { reset(); } 861 862 virtual WebContentDetectionResult detectContentAround(const WebHitTestResult& hitTest) OVERRIDE 863 { 864 m_contentDetectionRequested = true; 865 return m_contentDetectionResult; 866 } 867 868 virtual void scheduleContentIntent(const WebURL& url) OVERRIDE 869 { 870 m_scheduledIntentURL = url; 871 } 872 873 virtual void cancelScheduledContentIntents() OVERRIDE 874 { 875 m_pendingIntentsCancelled = true; 876 } 877 878 void reset() 879 { 880 m_contentDetectionRequested = false; 881 m_pendingIntentsCancelled = false; 882 m_scheduledIntentURL = WebURL(); 883 m_contentDetectionResult = WebContentDetectionResult(); 884 } 885 886 bool contentDetectionRequested() const { return m_contentDetectionRequested; } 887 bool pendingIntentsCancelled() const { return m_pendingIntentsCancelled; } 888 const WebURL& scheduledIntentURL() const { return m_scheduledIntentURL; } 889 void setContentDetectionResult(const WebContentDetectionResult& result) { m_contentDetectionResult = result; } 890 891 private: 892 bool m_contentDetectionRequested; 893 bool m_pendingIntentsCancelled; 894 WebURL m_scheduledIntentURL; 895 WebContentDetectionResult m_contentDetectionResult; 896 }; 897 898 static bool tapElementById(WebView* webView, WebInputEvent::Type type, const WebString& id) 899 { 900 ASSERT(webView); 901 RefPtr<WebCore::Element> element = static_cast<PassRefPtr<WebCore::Element> >(webView->mainFrame()->document().getElementById(id)); 902 if (!element) 903 return false; 904 905 element->scrollIntoViewIfNeeded(); 906 WebCore::IntPoint center = element->screenRect().center(); 907 908 WebGestureEvent event; 909 event.type = type; 910 event.x = center.x(); 911 event.y = center.y(); 912 913 webView->handleInputEvent(event); 914 runPendingTasks(); 915 return true; 916 } 917 918 TEST_F(WebViewTest, DetectContentAroundPosition) 919 { 920 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_listeners.html")); 921 922 ContentDetectorClient client; 923 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "content_listeners.html", true, 0, &client); 924 webView->resize(WebSize(500, 300)); 925 webView->layout(); 926 runPendingTasks(); 927 928 WebString clickListener = WebString::fromUTF8("clickListener"); 929 WebString touchstartListener = WebString::fromUTF8("touchstartListener"); 930 WebString mousedownListener = WebString::fromUTF8("mousedownListener"); 931 WebString noListener = WebString::fromUTF8("noListener"); 932 WebString link = WebString::fromUTF8("link"); 933 934 // Ensure content detection is not requested for nodes listening to click, 935 // mouse or touch events when we do simple taps. 936 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, clickListener)); 937 EXPECT_FALSE(client.contentDetectionRequested()); 938 client.reset(); 939 940 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, touchstartListener)); 941 EXPECT_FALSE(client.contentDetectionRequested()); 942 client.reset(); 943 944 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, mousedownListener)); 945 EXPECT_FALSE(client.contentDetectionRequested()); 946 client.reset(); 947 948 // Content detection should work normally without these event listeners. 949 // The click listener in the body should be ignored as a special case. 950 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener)); 951 EXPECT_TRUE(client.contentDetectionRequested()); 952 EXPECT_FALSE(client.scheduledIntentURL().isValid()); 953 954 WebURL intentURL = toKURL(m_baseURL); 955 client.setContentDetectionResult(WebContentDetectionResult(WebRange(), WebString(), intentURL)); 956 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener)); 957 EXPECT_TRUE(client.scheduledIntentURL() == intentURL); 958 959 // Tapping elsewhere should cancel the scheduled intent. 960 WebGestureEvent event; 961 event.type = WebInputEvent::GestureTap; 962 webView->handleInputEvent(event); 963 runPendingTasks(); 964 EXPECT_TRUE(client.pendingIntentsCancelled()); 965 webView->close(); 966 } 967 968 TEST_F(WebViewTest, ClientTapHandling) 969 { 970 TapHandlingWebViewClient client; 971 client.reset(); 972 WebView* webView = FrameTestHelpers::createWebViewAndLoad("about:blank", true, 0, &client); 973 WebGestureEvent event; 974 event.type = WebInputEvent::GestureTap; 975 event.x = 3; 976 event.y = 8; 977 webView->handleInputEvent(event); 978 runPendingTasks(); 979 EXPECT_EQ(3, client.tapX()); 980 EXPECT_EQ(8, client.tapY()); 981 client.reset(); 982 event.type = WebInputEvent::GestureLongPress; 983 event.x = 25; 984 event.y = 7; 985 webView->handleInputEvent(event); 986 runPendingTasks(); 987 EXPECT_EQ(25, client.longpressX()); 988 EXPECT_EQ(7, client.longpressY()); 989 webView->close(); 990 } 991 992 #if OS(ANDROID) 993 TEST_F(WebViewTest, LongPressSelection) 994 { 995 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html")); 996 997 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "longpress_selection.html", true); 998 webView->resize(WebSize(500, 300)); 999 webView->layout(); 1000 runPendingTasks(); 1001 1002 WebString target = WebString::fromUTF8("target"); 1003 WebString onselectstartfalse = WebString::fromUTF8("onselectstartfalse"); 1004 WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame()); 1005 1006 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, onselectstartfalse)); 1007 EXPECT_EQ("", std::string(frame->selectionAsText().utf8().data())); 1008 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, target)); 1009 EXPECT_EQ("testword", std::string(frame->selectionAsText().utf8().data())); 1010 webView->close(); 1011 } 1012 #endif 1013 1014 TEST_F(WebViewTest, SelectionOnDisabledInput) 1015 { 1016 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_disabled.html")); 1017 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "selection_disabled.html", true); 1018 webView->resize(WebSize(640, 480)); 1019 webView->layout(); 1020 runPendingTasks(); 1021 1022 std::string testWord = "This text should be selected."; 1023 1024 WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame()); 1025 EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data())); 1026 1027 size_t location; 1028 size_t length; 1029 WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(webView); 1030 1031 EXPECT_TRUE(webViewImpl->caretOrSelectionRange(&location, &length)); 1032 EXPECT_EQ(location, 0UL); 1033 EXPECT_EQ(length, testWord.length()); 1034 1035 webView->close(); 1036 } 1037 1038 TEST_F(WebViewTest, SelectionOnReadOnlyInput) 1039 { 1040 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_readonly.html")); 1041 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "selection_readonly.html", true); 1042 webView->resize(WebSize(640, 480)); 1043 webView->layout(); 1044 runPendingTasks(); 1045 1046 std::string testWord = "This text should be selected."; 1047 1048 WebFrameImpl* frame = static_cast<WebFrameImpl*>(webView->mainFrame()); 1049 EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data())); 1050 1051 size_t location; 1052 size_t length; 1053 WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(webView); 1054 1055 EXPECT_TRUE(webViewImpl->caretOrSelectionRange(&location, &length)); 1056 EXPECT_EQ(location, 0UL); 1057 EXPECT_EQ(length, testWord.length()); 1058 1059 webView->close(); 1060 } 1061 1062 class MockAutofillClient : public WebAutofillClient { 1063 public: 1064 MockAutofillClient() 1065 : m_ignoreTextChanges(false) 1066 , m_textChangesWhileIgnored(0) 1067 , m_textChangesWhileNotIgnored(0) { } 1068 1069 virtual ~MockAutofillClient() { } 1070 1071 virtual void setIgnoreTextChanges(bool ignore) OVERRIDE { m_ignoreTextChanges = ignore; } 1072 virtual void textFieldDidChange(const WebInputElement&) OVERRIDE 1073 { 1074 if (m_ignoreTextChanges) 1075 ++m_textChangesWhileIgnored; 1076 else 1077 ++m_textChangesWhileNotIgnored; 1078 } 1079 1080 void clearChangeCounts() 1081 { 1082 m_textChangesWhileIgnored = 0; 1083 m_textChangesWhileNotIgnored = 0; 1084 } 1085 1086 int textChangesWhileIgnored() { return m_textChangesWhileIgnored; } 1087 int textChangesWhileNotIgnored() { return m_textChangesWhileNotIgnored; } 1088 1089 private: 1090 bool m_ignoreTextChanges; 1091 int m_textChangesWhileIgnored; 1092 int m_textChangesWhileNotIgnored; 1093 }; 1094 1095 1096 TEST_F(WebViewTest, LosingFocusDoesNotTriggerAutofillTextChange) 1097 { 1098 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html")); 1099 MockAutofillClient client; 1100 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html"); 1101 webView->setAutofillClient(&client); 1102 webView->setInitialFocus(false); 1103 1104 // Set up a composition that needs to be committed. 1105 WebVector<WebCompositionUnderline> emptyUnderlines; 1106 webView->setEditableSelectionOffsets(4, 10); 1107 webView->setCompositionFromExistingText(8, 12, emptyUnderlines); 1108 WebTextInputInfo info = webView->textInputInfo(); 1109 EXPECT_EQ(4, info.selectionStart); 1110 EXPECT_EQ(10, info.selectionEnd); 1111 EXPECT_EQ(8, info.compositionStart); 1112 EXPECT_EQ(12, info.compositionEnd); 1113 1114 // Clear the focus and track that the subsequent composition commit does not trigger a 1115 // text changed notification for autofill. 1116 client.clearChangeCounts(); 1117 webView->setFocus(false); 1118 EXPECT_EQ(1, client.textChangesWhileIgnored()); 1119 EXPECT_EQ(0, client.textChangesWhileNotIgnored()); 1120 1121 webView->setAutofillClient(0); 1122 webView->close(); 1123 } 1124 1125 TEST_F(WebViewTest, ConfirmCompositionTriggersAutofillTextChange) 1126 { 1127 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html")); 1128 MockAutofillClient client; 1129 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html"); 1130 webView->setAutofillClient(&client); 1131 webView->setInitialFocus(false); 1132 1133 // Set up a composition that needs to be committed. 1134 std::string compositionText("testingtext"); 1135 1136 WebVector<WebCompositionUnderline> emptyUnderlines; 1137 webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 0, compositionText.length()); 1138 1139 WebTextInputInfo info = webView->textInputInfo(); 1140 EXPECT_EQ(0, info.selectionStart); 1141 EXPECT_EQ((int) compositionText.length(), info.selectionEnd); 1142 EXPECT_EQ(0, info.compositionStart); 1143 EXPECT_EQ((int) compositionText.length(), info.compositionEnd); 1144 1145 client.clearChangeCounts(); 1146 webView->confirmComposition(); 1147 EXPECT_EQ(0, client.textChangesWhileIgnored()); 1148 EXPECT_EQ(1, client.textChangesWhileNotIgnored()); 1149 1150 webView->setAutofillClient(0); 1151 webView->close(); 1152 } 1153 1154 TEST_F(WebViewTest, SetCompositionFromExistingTextTriggersAutofillTextChange) 1155 { 1156 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html")); 1157 MockAutofillClient client; 1158 WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "input_field_populated.html", true); 1159 webView->setAutofillClient(&client); 1160 webView->setInitialFocus(false); 1161 1162 WebVector<WebCompositionUnderline> emptyUnderlines; 1163 1164 client.clearChangeCounts(); 1165 webView->setCompositionFromExistingText(8, 12, emptyUnderlines); 1166 1167 WebTextInputInfo info = webView->textInputInfo(); 1168 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data())); 1169 EXPECT_EQ(8, info.compositionStart); 1170 EXPECT_EQ(12, info.compositionEnd); 1171 1172 EXPECT_EQ(0, client.textChangesWhileIgnored()); 1173 EXPECT_EQ(0, client.textChangesWhileNotIgnored()); 1174 1175 WebDocument document = webView->mainFrame()->document(); 1176 EXPECT_EQ(WebString::fromUTF8("none"), document.getElementById("inputEvent").firstChild().nodeValue()); 1177 1178 webView->setAutofillClient(0); 1179 webView->close(); 1180 } 1181 1182 TEST_F(WebViewTest, ShadowRoot) 1183 { 1184 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("shadow_dom_test.html")); 1185 WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(FrameTestHelpers::createWebViewAndLoad(m_baseURL + "shadow_dom_test.html", true)); 1186 1187 WebDocument document = webViewImpl->mainFrame()->document(); 1188 { 1189 WebElement elementWithShadowRoot = document.getElementById("shadowroot"); 1190 EXPECT_FALSE(elementWithShadowRoot.isNull()); 1191 WebNode shadowRoot = elementWithShadowRoot.shadowRoot(); 1192 EXPECT_FALSE(shadowRoot.isNull()); 1193 } 1194 { 1195 WebElement elementWithoutShadowRoot = document.getElementById("noshadowroot"); 1196 EXPECT_FALSE(elementWithoutShadowRoot.isNull()); 1197 WebNode shadowRoot = elementWithoutShadowRoot.shadowRoot(); 1198 EXPECT_TRUE(shadowRoot.isNull()); 1199 } 1200 webViewImpl->close(); 1201 } 1202 1203 TEST_F(WebViewTest, HelperPlugin) 1204 { 1205 HelperPluginCreatingWebViewClient client; 1206 WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(FrameTestHelpers::createWebView(true, 0, &client)); 1207 1208 WebFrameImpl* frame = static_cast<WebFrameImpl*>(webViewImpl->mainFrame()); 1209 client.setWebFrameClient(frame->client()); 1210 1211 WebHelperPluginImpl* helperPlugin = webViewImpl->createHelperPlugin("dummy-plugin-type", frame->document()); 1212 EXPECT_TRUE(helperPlugin); 1213 EXPECT_EQ(0, helperPlugin->getPlugin()); // Invalid plugin type means no plugin. 1214 1215 webViewImpl->closeHelperPluginSoon(helperPlugin); 1216 1217 webViewImpl->close(); 1218 } 1219 1220 } 1221