2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
32 #include "public/web/WebView.h"
34 #include "core/dom/Document.h"
35 #include "core/dom/Element.h"
36 #include "core/editing/FrameSelection.h"
37 #include "core/frame/EventHandlerRegistry.h"
38 #include "core/frame/FrameView.h"
39 #include "core/frame/LocalFrame.h"
40 #include "core/frame/Settings.h"
41 #include "core/html/HTMLDocument.h"
42 #include "core/html/HTMLIFrameElement.h"
43 #include "core/html/HTMLInputElement.h"
44 #include "core/html/HTMLTextAreaElement.h"
45 #include "core/loader/FrameLoadRequest.h"
46 #include "core/page/Chrome.h"
47 #include "core/page/Page.h"
48 #include "core/paint/LayerPainter.h"
49 #include "core/rendering/RenderLayer.h"
50 #include "core/rendering/RenderView.h"
51 #include "core/testing/URLTestHelpers.h"
52 #include "platform/KeyboardCodes.h"
53 #include "platform/geometry/IntSize.h"
54 #include "platform/graphics/Color.h"
55 #include "public/platform/Platform.h"
56 #include "public/platform/WebClipboard.h"
57 #include "public/platform/WebDragData.h"
58 #include "public/platform/WebSize.h"
59 #include "public/platform/WebThread.h"
60 #include "public/platform/WebUnitTestSupport.h"
61 #include "public/web/WebAutofillClient.h"
62 #include "public/web/WebContentDetectionResult.h"
63 #include "public/web/WebDateTimeChooserCompletion.h"
64 #include "public/web/WebDocument.h"
65 #include "public/web/WebDragOperation.h"
66 #include "public/web/WebElement.h"
67 #include "public/web/WebFrame.h"
68 #include "public/web/WebFrameClient.h"
69 #include "public/web/WebHitTestResult.h"
70 #include "public/web/WebInputEvent.h"
71 #include "public/web/WebScriptSource.h"
72 #include "public/web/WebSettings.h"
73 #include "public/web/WebViewClient.h"
74 #include "public/web/WebWidget.h"
75 #include "public/web/WebWidgetClient.h"
76 #include "third_party/skia/include/core/SkBitmap.h"
77 #include "third_party/skia/include/core/SkBitmapDevice.h"
78 #include "third_party/skia/include/core/SkCanvas.h"
79 #include "web/WebLocalFrameImpl.h"
80 #include "web/WebSettingsImpl.h"
81 #include "web/WebViewImpl.h"
82 #include "web/tests/FrameTestHelpers.h"
83 #include <gtest/gtest.h>
85 using namespace blink;
86 using blink::FrameTestHelpers::loadFrame;
87 using blink::FrameTestHelpers::runPendingTasks;
88 using blink::URLTestHelpers::toKURL;
92 enum HorizontalScrollbarState {
93 NoHorizontalScrollbar,
94 VisibleHorizontalScrollbar,
97 enum VerticalScrollbarState {
99 VisibleVerticalScrollbar,
104 void setWebView(WebView* webView) { m_webView = toWebViewImpl(webView); }
105 void setSize(const WebSize& newSize) { m_size = newSize; }
106 HorizontalScrollbarState horizontalScrollbarState() const
108 return m_webView->hasHorizontalScrollbar() ? VisibleHorizontalScrollbar: NoHorizontalScrollbar;
110 VerticalScrollbarState verticalScrollbarState() const
112 return m_webView->hasVerticalScrollbar() ? VisibleVerticalScrollbar : NoVerticalScrollbar;
114 int width() const { return m_size.width; }
115 int height() const { return m_size.height; }
119 WebViewImpl* m_webView;
122 class AutoResizeWebViewClient : public FrameTestHelpers::TestWebViewClient {
124 // WebViewClient methods
125 virtual void didAutoResize(const WebSize& newSize) { m_testData.setSize(newSize); }
128 TestData& testData() { return m_testData; }
134 class SaveImageFromDataURLWebViewClient : public FrameTestHelpers::TestWebViewClient {
136 // WebViewClient methods
137 virtual void saveImageFromDataURL(const WebString& dataURL) { m_dataURL = dataURL; }
140 const WebString& result() const { return m_dataURL; }
141 void reset() { m_dataURL = WebString(); }
147 class TapHandlingWebViewClient : public FrameTestHelpers::TestWebViewClient {
149 // WebViewClient methods
150 virtual void didHandleGestureEvent(const WebGestureEvent& event, bool eventCancelled)
152 if (event.type == WebInputEvent::GestureTap) {
155 } else if (event.type == WebInputEvent::GestureLongPress) {
156 m_longpressX = event.x;
157 m_longpressY = event.y;
169 int tapX() { return m_tapX; }
170 int tapY() { return m_tapY; }
171 int longpressX() { return m_longpressX; }
172 int longpressY() { return m_longpressY; }
181 class DateTimeChooserWebViewClient : public FrameTestHelpers::TestWebViewClient {
183 WebDateTimeChooserCompletion* chooserCompletion()
185 return m_chooserCompletion;
188 void clearChooserCompletion()
190 m_chooserCompletion = 0;
193 // WebViewClient methods
194 virtual bool openDateTimeChooser(const WebDateTimeChooserParams&, WebDateTimeChooserCompletion* chooser_completion) override
196 m_chooserCompletion = chooser_completion;
201 WebDateTimeChooserCompletion* m_chooserCompletion;
205 class WebViewTest : public testing::Test {
208 : m_baseURL("http://www.test.com/")
212 virtual void TearDown()
214 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
218 void registerMockedHttpURLLoad(const std::string& fileName)
220 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(fileName.c_str()));
223 void testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
224 const std::string& pageWidth, const std::string& pageHeight,
225 int expectedWidth, int expectedHeight,
226 HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState);
228 void testTextInputType(WebTextInputType expectedType, const std::string& htmlFile);
229 void testInputMode(const WebString& expectedInputMode, const std::string& htmlFile);
230 void testSelectionRootBounds(const char* htmlFile, float pageScaleFactor);
232 std::string m_baseURL;
233 FrameTestHelpers::WebViewHelper m_webViewHelper;
236 TEST_F(WebViewTest, SaveImageAt)
238 SaveImageFromDataURLWebViewClient client;
240 std::string url = m_baseURL + "image-with-data-url.html";
241 URLTestHelpers::registerMockedURLLoad(toKURL(url), "image-with-data-url.html");
242 WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
243 webView->resize(WebSize(400, 400));
246 webView->saveImageAt(WebPoint(1, 1));
247 EXPECT_EQ(WebString::fromUTF8("data:image/gif;base64"
248 ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), client.result());
251 webView->saveImageAt(WebPoint(1, 2));
252 EXPECT_EQ(WebString(), client.result());
254 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
257 TEST_F(WebViewTest, CopyImageAt)
259 std::string url = m_baseURL + "canvas-copy-image.html";
260 URLTestHelpers::registerMockedURLLoad(toKURL(url), "canvas-copy-image.html");
261 WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
262 webView->resize(WebSize(400, 400));
263 webView->copyImageAt(WebPoint(50, 50));
265 WebData data = Platform::current()->clipboard()->readImage(WebClipboard::Buffer());
266 WebImage image = WebImage::fromData(data, WebSize());
268 SkAutoLockPixels autoLock(image.getSkBitmap());
269 EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image.getSkBitmap().getColor(0, 0));
272 TEST_F(WebViewTest, SetBaseBackgroundColor)
274 const WebColor kWhite = 0xFFFFFFFF;
275 const WebColor kBlue = 0xFF0000FF;
276 const WebColor kDarkCyan = 0xFF227788;
277 const WebColor kTranslucentPutty = 0x80BFB196;
278 const WebColor kTransparent = 0x00000000;
280 WebViewImpl* webView = m_webViewHelper.initialize();
281 EXPECT_EQ(kWhite, webView->backgroundColor());
283 webView->setBaseBackgroundColor(kBlue);
284 EXPECT_EQ(kBlue, webView->backgroundColor());
286 WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
287 FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:#227788}</style></head></html>", baseURL);
288 EXPECT_EQ(kDarkCyan, webView->backgroundColor());
290 FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:rgba(255,0,0,0.5)}</style></head></html>", baseURL);
291 // Expected: red (50% alpha) blended atop base of kBlue.
292 EXPECT_EQ(0xFF7F0080, webView->backgroundColor());
294 webView->setBaseBackgroundColor(kTranslucentPutty);
295 // Expected: red (50% alpha) blended atop kTranslucentPutty. Note the alpha.
296 EXPECT_EQ(0xBFE93B32, webView->backgroundColor());
298 webView->setBaseBackgroundColor(kTransparent);
299 FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:transparent}</style></head></html>", baseURL);
300 // Expected: transparent on top of kTransparent will still be transparent.
301 EXPECT_EQ(kTransparent, webView->backgroundColor());
303 LocalFrame* frame = webView->mainFrameImpl()->frame();
305 // Creating a new frame view with the background color having 0 alpha.
306 frame->createView(IntSize(1024, 768), Color::transparent, true);
307 EXPECT_EQ(kTransparent, frame->view()->baseBackgroundColor());
309 Color kTransparentRed(100, 0, 0, 0);
310 frame->createView(IntSize(1024, 768), kTransparentRed, true);
311 EXPECT_EQ(kTransparentRed, frame->view()->baseBackgroundColor());
314 TEST_F(WebViewTest, SetBaseBackgroundColorBeforeMainFrame)
316 const WebColor kBlue = 0xFF0000FF;
317 FrameTestHelpers::TestWebViewClient webViewClient;
318 WebView* webView = WebViewImpl::create(&webViewClient);
319 EXPECT_NE(kBlue, webView->backgroundColor());
320 // webView does not have a frame yet, but we should still be able to set the background color.
321 webView->setBaseBackgroundColor(kBlue);
322 EXPECT_EQ(kBlue, webView->backgroundColor());
323 WebLocalFrameImpl* frame = WebLocalFrameImpl::create(0);
324 webView->setMainFrame(frame);
329 TEST_F(WebViewTest, SetBaseBackgroundColorAndBlendWithExistingContent)
331 const WebColor kAlphaRed = 0x80FF0000;
332 const WebColor kAlphaGreen = 0x8000FF00;
333 const int kWidth = 100;
334 const int kHeight = 100;
336 WebView* webView = m_webViewHelper.initialize();
338 // Set WebView background to green with alpha.
339 webView->setBaseBackgroundColor(kAlphaGreen);
340 webView->settings()->setShouldClearDocumentBackground(false);
341 webView->resize(WebSize(kWidth, kHeight));
344 // Set canvas background to red with alpha.
346 bitmap.allocN32Pixels(kWidth, kHeight);
347 SkCanvas canvas(bitmap);
348 canvas.clear(kAlphaRed);
350 GraphicsContext context(&canvas);
352 // Paint the root of the main frame in the way that CompositedLayerMapping would.
353 FrameView* view = m_webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
354 RenderLayer* rootLayer = view->renderView()->layer();
355 IntRect paintRect(0, 0, kWidth, kHeight);
356 LayerPaintingInfo paintingInfo(rootLayer, paintRect, PaintBehaviorNormal, LayoutSize());
357 LayerPainter(*rootLayer).paintLayerContents(&context, paintingInfo, PaintLayerPaintingCompositingAllPhases);
359 // The result should be a blend of red and green.
360 SkColor color = bitmap.getColor(kWidth / 2, kHeight / 2);
361 EXPECT_TRUE(redChannel(color));
362 EXPECT_TRUE(greenChannel(color));
365 TEST_F(WebViewTest, FocusIsInactive)
367 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
368 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "visible_iframe.html");
370 webView->setFocus(true);
371 webView->setIsActive(true);
372 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
373 EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
375 HTMLDocument* document = toHTMLDocument(frame->frame()->document());
376 EXPECT_TRUE(document->hasFocus());
377 webView->setFocus(false);
378 webView->setIsActive(false);
379 EXPECT_FALSE(document->hasFocus());
380 webView->setFocus(true);
381 webView->setIsActive(true);
382 EXPECT_TRUE(document->hasFocus());
383 webView->setFocus(true);
384 webView->setIsActive(false);
385 EXPECT_FALSE(document->hasFocus());
386 webView->setFocus(false);
387 webView->setIsActive(true);
388 EXPECT_FALSE(document->hasFocus());
391 TEST_F(WebViewTest, ActiveState)
393 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
394 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "visible_iframe.html");
396 ASSERT_TRUE(webView);
398 webView->setIsActive(true);
399 EXPECT_TRUE(webView->isActive());
401 webView->setIsActive(false);
402 EXPECT_FALSE(webView->isActive());
404 webView->setIsActive(true);
405 EXPECT_TRUE(webView->isActive());
408 TEST_F(WebViewTest, HitTestResultAtWithPageScale)
410 std::string url = m_baseURL + "specify_size.html?" + "50px" + ":" + "50px";
411 URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
412 WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
413 webView->resize(WebSize(100, 100));
414 WebPoint hitPoint(75, 75);
416 // Image is at top left quandrant, so should not hit it.
417 WebHitTestResult negativeResult = webView->hitTestResultAt(hitPoint);
418 ASSERT_EQ(WebNode::ElementNode, negativeResult.node().nodeType());
419 EXPECT_FALSE(negativeResult.node().to<WebElement>().hasHTMLTagName("img"));
420 negativeResult.reset();
422 // Scale page up 2x so image should occupy the whole viewport.
423 webView->setPageScaleFactor(2.0f);
424 WebHitTestResult positiveResult = webView->hitTestResultAt(hitPoint);
425 ASSERT_EQ(WebNode::ElementNode, positiveResult.node().nodeType());
426 EXPECT_TRUE(positiveResult.node().to<WebElement>().hasHTMLTagName("img"));
427 positiveResult.reset();
430 void WebViewTest::testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
431 const std::string& pageWidth, const std::string& pageHeight,
432 int expectedWidth, int expectedHeight,
433 HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState)
435 AutoResizeWebViewClient client;
436 std::string url = m_baseURL + "specify_size.html?" + pageWidth + ":" + pageHeight;
437 URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
438 WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
439 client.testData().setWebView(webView);
441 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
442 FrameView* frameView = frame->frame()->view();
444 EXPECT_FALSE(frameView->layoutPending());
445 EXPECT_FALSE(frameView->needsLayout());
447 webView->enableAutoResizeMode(minAutoResize, maxAutoResize);
448 EXPECT_TRUE(frameView->layoutPending());
449 EXPECT_TRUE(frameView->needsLayout());
452 EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
454 EXPECT_EQ(expectedWidth, client.testData().width());
455 EXPECT_EQ(expectedHeight, client.testData().height());
456 EXPECT_EQ(expectedHorizontalState, client.testData().horizontalScrollbarState());
457 EXPECT_EQ(expectedVerticalState, client.testData().verticalScrollbarState());
459 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
462 TEST_F(WebViewTest, AutoResizeMinimumSize)
464 WebSize minAutoResize(91, 56);
465 WebSize maxAutoResize(403, 302);
466 std::string pageWidth = "91px";
467 std::string pageHeight = "56px";
468 int expectedWidth = 91;
469 int expectedHeight = 56;
470 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
471 expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
474 TEST_F(WebViewTest, AutoResizeHeightOverflowAndFixedWidth)
476 WebSize minAutoResize(90, 95);
477 WebSize maxAutoResize(90, 100);
478 std::string pageWidth = "60px";
479 std::string pageHeight = "200px";
480 int expectedWidth = 90;
481 int expectedHeight = 100;
482 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
483 expectedWidth, expectedHeight, NoHorizontalScrollbar, VisibleVerticalScrollbar);
486 TEST_F(WebViewTest, AutoResizeFixedHeightAndWidthOverflow)
488 WebSize minAutoResize(90, 100);
489 WebSize maxAutoResize(200, 100);
490 std::string pageWidth = "300px";
491 std::string pageHeight = "80px";
492 int expectedWidth = 200;
493 int expectedHeight = 100;
494 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
495 expectedWidth, expectedHeight, VisibleHorizontalScrollbar, NoVerticalScrollbar);
498 // Next three tests disabled for https://bugs.webkit.org/show_bug.cgi?id=92318 .
499 // It seems we can run three AutoResize tests, then the next one breaks.
500 TEST_F(WebViewTest, AutoResizeInBetweenSizes)
502 WebSize minAutoResize(90, 95);
503 WebSize maxAutoResize(200, 300);
504 std::string pageWidth = "100px";
505 std::string pageHeight = "200px";
506 int expectedWidth = 100;
507 int expectedHeight = 200;
508 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
509 expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
512 TEST_F(WebViewTest, AutoResizeOverflowSizes)
514 WebSize minAutoResize(90, 95);
515 WebSize maxAutoResize(200, 300);
516 std::string pageWidth = "300px";
517 std::string pageHeight = "400px";
518 int expectedWidth = 200;
519 int expectedHeight = 300;
520 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
521 expectedWidth, expectedHeight, VisibleHorizontalScrollbar, VisibleVerticalScrollbar);
524 TEST_F(WebViewTest, AutoResizeMaxSize)
526 WebSize minAutoResize(90, 95);
527 WebSize maxAutoResize(200, 300);
528 std::string pageWidth = "200px";
529 std::string pageHeight = "300px";
530 int expectedWidth = 200;
531 int expectedHeight = 300;
532 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
533 expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
536 void WebViewTest::testTextInputType(WebTextInputType expectedType, const std::string& htmlFile)
538 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
539 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + htmlFile);
540 webView->setInitialFocus(false);
541 EXPECT_EQ(expectedType, webView->textInputInfo().type);
544 TEST_F(WebViewTest, TextInputType)
546 testTextInputType(WebTextInputTypeText, "input_field_default.html");
547 testTextInputType(WebTextInputTypePassword, "input_field_password.html");
548 testTextInputType(WebTextInputTypeEmail, "input_field_email.html");
549 testTextInputType(WebTextInputTypeSearch, "input_field_search.html");
550 testTextInputType(WebTextInputTypeNumber, "input_field_number.html");
551 testTextInputType(WebTextInputTypeTelephone, "input_field_tel.html");
552 testTextInputType(WebTextInputTypeURL, "input_field_url.html");
555 void WebViewTest::testInputMode(const WebString& expectedInputMode, const std::string& htmlFile)
557 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
558 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + htmlFile);
559 webView->setInitialFocus(false);
560 EXPECT_EQ(expectedInputMode, webView->textInputInfo().inputMode);
563 TEST_F(WebViewTest, InputMode)
565 testInputMode(WebString(), "input_mode_default.html");
566 testInputMode(WebString("unknown"), "input_mode_default_unknown.html");
567 testInputMode(WebString("verbatim"), "input_mode_default_verbatim.html");
568 testInputMode(WebString("verbatim"), "input_mode_type_text_verbatim.html");
569 testInputMode(WebString("verbatim"), "input_mode_type_search_verbatim.html");
570 testInputMode(WebString(), "input_mode_type_url_verbatim.html");
571 testInputMode(WebString("verbatim"), "input_mode_textarea_verbatim.html");
574 TEST_F(WebViewTest, TextInputInfoWithReplacedElements)
576 std::string url = m_baseURL + "div_with_image.html";
577 URLTestHelpers::registerMockedURLLoad(toKURL(url), "div_with_image.html");
578 WebView* webView = m_webViewHelper.initializeAndLoad(url);
579 webView->setInitialFocus(false);
580 WebTextInputInfo info = webView->textInputInfo();
582 EXPECT_EQ("foo\xef\xbf\xbc", info.value.utf8());
585 TEST_F(WebViewTest, SetEditableSelectionOffsetsAndTextInputInfo)
587 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
588 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
589 webView->setInitialFocus(false);
590 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
591 frame->setEditableSelectionOffsets(5, 13);
592 EXPECT_EQ("56789abc", frame->selectionAsText());
593 WebTextInputInfo info = webView->textInputInfo();
594 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
595 EXPECT_EQ(5, info.selectionStart);
596 EXPECT_EQ(13, info.selectionEnd);
597 EXPECT_EQ(-1, info.compositionStart);
598 EXPECT_EQ(-1, info.compositionEnd);
600 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_editable_populated.html"));
601 webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_editable_populated.html");
602 webView->setInitialFocus(false);
603 frame = toWebLocalFrameImpl(webView->mainFrame());
604 frame->setEditableSelectionOffsets(8, 19);
605 EXPECT_EQ("89abcdefghi", frame->selectionAsText());
606 info = webView->textInputInfo();
607 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
608 EXPECT_EQ(8, info.selectionStart);
609 EXPECT_EQ(19, info.selectionEnd);
610 EXPECT_EQ(-1, info.compositionStart);
611 EXPECT_EQ(-1, info.compositionEnd);
614 TEST_F(WebViewTest, ConfirmCompositionCursorPositionChange)
616 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
617 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
618 webView->setInitialFocus(false);
620 // Set up a composition that needs to be committed.
621 std::string compositionText("hello");
623 WebVector<WebCompositionUnderline> emptyUnderlines;
624 webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3);
626 WebTextInputInfo info = webView->textInputInfo();
627 EXPECT_EQ("hello", std::string(info.value.utf8().data()));
628 EXPECT_EQ(3, info.selectionStart);
629 EXPECT_EQ(3, info.selectionEnd);
630 EXPECT_EQ(0, info.compositionStart);
631 EXPECT_EQ(5, info.compositionEnd);
633 webView->confirmComposition(WebWidget::KeepSelection);
634 info = webView->textInputInfo();
635 EXPECT_EQ(3, info.selectionStart);
636 EXPECT_EQ(3, info.selectionEnd);
637 EXPECT_EQ(-1, info.compositionStart);
638 EXPECT_EQ(-1, info.compositionEnd);
640 webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3);
641 info = webView->textInputInfo();
642 EXPECT_EQ("helhellolo", std::string(info.value.utf8().data()));
643 EXPECT_EQ(6, info.selectionStart);
644 EXPECT_EQ(6, info.selectionEnd);
645 EXPECT_EQ(3, info.compositionStart);
646 EXPECT_EQ(8, info.compositionEnd);
648 webView->confirmComposition(WebWidget::DoNotKeepSelection);
649 info = webView->textInputInfo();
650 EXPECT_EQ(8, info.selectionStart);
651 EXPECT_EQ(8, info.selectionEnd);
652 EXPECT_EQ(-1, info.compositionStart);
653 EXPECT_EQ(-1, info.compositionEnd);
656 TEST_F(WebViewTest, InsertNewLinePlacementAfterConfirmComposition)
658 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html"));
659 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "text_area_populated.html");
660 webView->setInitialFocus(false);
662 WebVector<WebCompositionUnderline> emptyUnderlines;
664 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
665 frame->setEditableSelectionOffsets(4, 4);
666 frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
668 WebTextInputInfo info = webView->textInputInfo();
669 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
670 EXPECT_EQ(4, info.selectionStart);
671 EXPECT_EQ(4, info.selectionEnd);
672 EXPECT_EQ(8, info.compositionStart);
673 EXPECT_EQ(12, info.compositionEnd);
675 webView->confirmComposition(WebWidget::KeepSelection);
676 info = webView->textInputInfo();
677 EXPECT_EQ(4, info.selectionStart);
678 EXPECT_EQ(4, info.selectionEnd);
679 EXPECT_EQ(-1, info.compositionStart);
680 EXPECT_EQ(-1, info.compositionEnd);
682 std::string compositionText("\n");
683 webView->confirmComposition(WebString::fromUTF8(compositionText.c_str()));
684 info = webView->textInputInfo();
685 EXPECT_EQ(5, info.selectionStart);
686 EXPECT_EQ(5, info.selectionEnd);
687 EXPECT_EQ(-1, info.compositionStart);
688 EXPECT_EQ(-1, info.compositionEnd);
689 EXPECT_EQ("0123\n456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
692 TEST_F(WebViewTest, ExtendSelectionAndDelete)
694 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
695 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
696 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
697 webView->setInitialFocus(false);
698 frame->setEditableSelectionOffsets(10, 10);
699 frame->extendSelectionAndDelete(5, 8);
700 WebTextInputInfo info = webView->textInputInfo();
701 EXPECT_EQ("01234ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
702 EXPECT_EQ(5, info.selectionStart);
703 EXPECT_EQ(5, info.selectionEnd);
704 frame->extendSelectionAndDelete(10, 0);
705 info = webView->textInputInfo();
706 EXPECT_EQ("ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
709 TEST_F(WebViewTest, SetCompositionFromExistingText)
711 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
712 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
713 webView->setInitialFocus(false);
714 WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
715 underlines[0] = WebCompositionUnderline(0, 4, 0, false, 0);
716 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
717 frame->setEditableSelectionOffsets(4, 10);
718 frame->setCompositionFromExistingText(8, 12, underlines);
719 WebVector<WebCompositionUnderline> underlineResults = toWebViewImpl(webView)->compositionUnderlines();
720 EXPECT_EQ(8u, underlineResults[0].startOffset);
721 EXPECT_EQ(12u, underlineResults[0].endOffset);
722 WebTextInputInfo info = webView->textInputInfo();
723 EXPECT_EQ(4, info.selectionStart);
724 EXPECT_EQ(10, info.selectionEnd);
725 EXPECT_EQ(8, info.compositionStart);
726 EXPECT_EQ(12, info.compositionEnd);
727 WebVector<WebCompositionUnderline> emptyUnderlines;
728 frame->setCompositionFromExistingText(0, 0, emptyUnderlines);
729 info = webView->textInputInfo();
730 EXPECT_EQ(4, info.selectionStart);
731 EXPECT_EQ(10, info.selectionEnd);
732 EXPECT_EQ(-1, info.compositionStart);
733 EXPECT_EQ(-1, info.compositionEnd);
736 TEST_F(WebViewTest, SetCompositionFromExistingTextInTextArea)
738 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html"));
739 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "text_area_populated.html");
740 webView->setInitialFocus(false);
741 WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
742 underlines[0] = WebCompositionUnderline(0, 4, 0, false, 0);
743 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
744 frame->setEditableSelectionOffsets(27, 27);
745 std::string newLineText("\n");
746 webView->confirmComposition(WebString::fromUTF8(newLineText.c_str()));
747 WebTextInputInfo info = webView->textInputInfo();
748 EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data()));
750 frame->setEditableSelectionOffsets(31, 31);
751 frame->setCompositionFromExistingText(30, 34, underlines);
752 WebVector<WebCompositionUnderline> underlineResults = toWebViewImpl(webView)->compositionUnderlines();
753 EXPECT_EQ(2u, underlineResults[0].startOffset);
754 EXPECT_EQ(6u, underlineResults[0].endOffset);
755 info = webView->textInputInfo();
756 EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data()));
757 EXPECT_EQ(31, info.selectionStart);
758 EXPECT_EQ(31, info.selectionEnd);
759 EXPECT_EQ(30, info.compositionStart);
760 EXPECT_EQ(34, info.compositionEnd);
762 std::string compositionText("yolo");
763 webView->confirmComposition(WebString::fromUTF8(compositionText.c_str()));
764 info = webView->textInputInfo();
765 EXPECT_EQ("0123456789abcdefghijklmnopq\nrsyoloxyz", std::string(info.value.utf8().data()));
766 EXPECT_EQ(34, info.selectionStart);
767 EXPECT_EQ(34, info.selectionEnd);
768 EXPECT_EQ(-1, info.compositionStart);
769 EXPECT_EQ(-1, info.compositionEnd);
772 TEST_F(WebViewTest, SetEditableSelectionOffsetsKeepsComposition)
774 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
775 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
776 webView->setInitialFocus(false);
778 std::string compositionTextFirst("hello ");
779 std::string compositionTextSecond("world");
780 WebVector<WebCompositionUnderline> emptyUnderlines;
782 webView->confirmComposition(WebString::fromUTF8(compositionTextFirst.c_str()));
783 webView->setComposition(WebString::fromUTF8(compositionTextSecond.c_str()), emptyUnderlines, 5, 5);
785 WebTextInputInfo info = webView->textInputInfo();
786 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
787 EXPECT_EQ(11, info.selectionStart);
788 EXPECT_EQ(11, info.selectionEnd);
789 EXPECT_EQ(6, info.compositionStart);
790 EXPECT_EQ(11, info.compositionEnd);
792 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
793 frame->setEditableSelectionOffsets(6, 6);
794 info = webView->textInputInfo();
795 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
796 EXPECT_EQ(6, info.selectionStart);
797 EXPECT_EQ(6, info.selectionEnd);
798 EXPECT_EQ(6, info.compositionStart);
799 EXPECT_EQ(11, info.compositionEnd);
801 frame->setEditableSelectionOffsets(8, 8);
802 info = webView->textInputInfo();
803 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
804 EXPECT_EQ(8, info.selectionStart);
805 EXPECT_EQ(8, info.selectionEnd);
806 EXPECT_EQ(6, info.compositionStart);
807 EXPECT_EQ(11, info.compositionEnd);
809 frame->setEditableSelectionOffsets(11, 11);
810 info = webView->textInputInfo();
811 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
812 EXPECT_EQ(11, info.selectionStart);
813 EXPECT_EQ(11, info.selectionEnd);
814 EXPECT_EQ(6, info.compositionStart);
815 EXPECT_EQ(11, info.compositionEnd);
817 frame->setEditableSelectionOffsets(6, 11);
818 info = webView->textInputInfo();
819 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
820 EXPECT_EQ(6, info.selectionStart);
821 EXPECT_EQ(11, info.selectionEnd);
822 EXPECT_EQ(6, info.compositionStart);
823 EXPECT_EQ(11, info.compositionEnd);
825 frame->setEditableSelectionOffsets(2, 2);
826 info = webView->textInputInfo();
827 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
828 EXPECT_EQ(2, info.selectionStart);
829 EXPECT_EQ(2, info.selectionEnd);
830 EXPECT_EQ(-1, info.compositionStart);
831 EXPECT_EQ(-1, info.compositionEnd);
834 TEST_F(WebViewTest, IsSelectionAnchorFirst)
836 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
837 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
838 WebFrame* frame = webView->mainFrame();
840 webView->setPageScaleFactorLimits(1, 1);
841 webView->setInitialFocus(false);
842 frame->setEditableSelectionOffsets(4, 10);
843 EXPECT_TRUE(webView->isSelectionAnchorFirst());
846 webView->selectionBounds(anchor, focus);
847 frame->selectRange(WebPoint(focus.x, focus.y), WebPoint(anchor.x, anchor.y));
848 EXPECT_FALSE(webView->isSelectionAnchorFirst());
851 TEST_F(WebViewTest, HistoryResetScrollAndScaleState)
853 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html"));
854 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "hello_world.html");
855 webViewImpl->resize(WebSize(640, 480));
856 webViewImpl->layout();
857 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
858 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
860 // Make the page scale and scroll with the given paremeters.
861 webViewImpl->setPageScaleFactor(2.0f);
862 webViewImpl->setMainFrameScrollOffset(WebPoint(116, 84));
863 EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
864 EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
865 EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
866 LocalFrame* mainFrameLocal = toLocalFrame(webViewImpl->page()->mainFrame());
867 mainFrameLocal->loader().saveScrollState();
868 EXPECT_EQ(2.0f, mainFrameLocal->loader().currentItem()->pageScaleFactor());
869 EXPECT_EQ(116, mainFrameLocal->loader().currentItem()->scrollPoint().x());
870 EXPECT_EQ(84, mainFrameLocal->loader().currentItem()->scrollPoint().y());
872 // Confirm that resetting the page state resets the saved scroll position.
873 // The HistoryController treats a page scale factor of 0.0f as special and avoids
874 // restoring it to the WebView.
875 webViewImpl->resetScrollAndScaleState();
876 EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
877 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
878 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
879 EXPECT_EQ(0.0f, mainFrameLocal->loader().currentItem()->pageScaleFactor());
880 EXPECT_EQ(0, mainFrameLocal->loader().currentItem()->scrollPoint().x());
881 EXPECT_EQ(0, mainFrameLocal->loader().currentItem()->scrollPoint().y());
884 TEST_F(WebViewTest, BackForwardRestoreScroll)
886 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("back_forward_restore_scroll.html"));
887 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "back_forward_restore_scroll.html");
888 webViewImpl->resize(WebSize(640, 480));
889 webViewImpl->layout();
891 // Emulate a user scroll
892 webViewImpl->setMainFrameScrollOffset(WebPoint(0, 900));
893 LocalFrame* mainFrameLocal = toLocalFrame(webViewImpl->page()->mainFrame());
894 RefPtrWillBePersistent<HistoryItem> item1 = mainFrameLocal->loader().currentItem();
897 mainFrameLocal->loader().load(FrameLoadRequest(mainFrameLocal->document(), ResourceRequest(mainFrameLocal->document()->completeURL("#a"))));
898 RefPtrWillBePersistent<HistoryItem> item2 = mainFrameLocal->loader().currentItem();
900 // Go back, then forward, then back again.
901 mainFrameLocal->loader().loadHistoryItem(item1.get(), FrameLoadTypeBackForward, HistorySameDocumentLoad);
902 mainFrameLocal->loader().loadHistoryItem(item2.get(), FrameLoadTypeBackForward, HistorySameDocumentLoad);
903 mainFrameLocal->loader().loadHistoryItem(item1.get(), FrameLoadTypeBackForward, HistorySameDocumentLoad);
905 // Click a different anchor
906 mainFrameLocal->loader().load(FrameLoadRequest(mainFrameLocal->document(), ResourceRequest(mainFrameLocal->document()->completeURL("#b"))));
907 RefPtrWillBePersistent<HistoryItem> item3 = mainFrameLocal->loader().currentItem();
909 // Go back, then forward. The scroll position should be properly set on the forward navigation.
910 mainFrameLocal->loader().loadHistoryItem(item1.get(), FrameLoadTypeBackForward, HistorySameDocumentLoad);
911 mainFrameLocal->loader().loadHistoryItem(item3.get(), FrameLoadTypeBackForward, HistorySameDocumentLoad);
912 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
913 EXPECT_GT(webViewImpl->mainFrame()->scrollOffset().height, 2000);
916 class EnterFullscreenWebViewClient : public FrameTestHelpers::TestWebViewClient {
918 // WebViewClient methods
919 virtual bool enterFullScreen() { return true; }
920 virtual void exitFullScreen() { }
924 TEST_F(WebViewTest, EnterFullscreenResetScrollAndScaleState)
926 EnterFullscreenWebViewClient client;
927 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html"));
928 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "hello_world.html", true, 0, &client);
929 webViewImpl->resize(WebSize(640, 480));
930 webViewImpl->layout();
931 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
932 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
934 // Make the page scale and scroll with the given paremeters.
935 webViewImpl->setPageScaleFactor(2.0f);
936 webViewImpl->setMainFrameScrollOffset(WebPoint(116, 84));
937 EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
938 EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
939 EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
941 RefPtrWillBeRawPtr<Element> element = static_cast<PassRefPtrWillBeRawPtr<Element> >(webViewImpl->mainFrame()->document().body());
942 webViewImpl->enterFullScreenForElement(element.get());
943 webViewImpl->didEnterFullScreen();
945 // Page scale factor must be 1.0 during fullscreen for elements to be sized
947 EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
949 // Make sure fullscreen nesting doesn't disrupt scroll/scale saving.
950 RefPtrWillBeRawPtr<Element> otherElement = static_cast<PassRefPtrWillBeRawPtr<Element> >(webViewImpl->mainFrame()->document().head());
951 webViewImpl->enterFullScreenForElement(otherElement.get());
953 // Confirm that exiting fullscreen restores the parameters.
954 webViewImpl->didExitFullScreen();
955 EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
956 EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
957 EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
959 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
962 class PrintWebViewClient : public FrameTestHelpers::TestWebViewClient {
965 : m_printCalled(false)
969 // WebViewClient methods
970 virtual void printPage(WebLocalFrame*) override
972 m_printCalled = true;
975 bool printCalled() const { return m_printCalled; }
982 TEST_F(WebViewTest, PrintWithXHRInFlight)
984 PrintWebViewClient client;
985 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("print_with_xhr_inflight.html"));
986 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "print_with_xhr_inflight.html", true, 0, &client);
988 ASSERT_EQ(FrameStateComplete, toLocalFrame(webViewImpl->page()->mainFrame())->loader().state());
989 EXPECT_TRUE(client.printCalled());
990 m_webViewHelper.reset();
993 class DropTask : public WebThread::Task {
995 explicit DropTask(WebView* webView) : m_webView(webView)
999 virtual void run() override
1001 const WebPoint clientPoint(0, 0);
1002 const WebPoint screenPoint(0, 0);
1003 m_webView->dragTargetDrop(clientPoint, screenPoint, 0);
1007 WebView* const m_webView;
1009 static void DragAndDropURL(WebViewImpl* webView, const std::string& url)
1011 WebDragData dragData;
1012 dragData.initialize();
1014 WebDragData::Item item;
1015 item.storageType = WebDragData::Item::StorageTypeString;
1016 item.stringType = "text/uri-list";
1017 item.stringData = WebString::fromUTF8(url);
1018 dragData.addItem(item);
1020 const WebPoint clientPoint(0, 0);
1021 const WebPoint screenPoint(0, 0);
1022 webView->dragTargetDragEnter(dragData, clientPoint, screenPoint, WebDragOperationCopy, 0);
1023 Platform::current()->currentThread()->postTask(new DropTask(webView));
1024 FrameTestHelpers::pumpPendingRequestsDoNotUse(webView->mainFrame());
1027 TEST_F(WebViewTest, DragDropURL)
1029 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "foo.html");
1030 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "bar.html");
1032 const std::string fooUrl = m_baseURL + "foo.html";
1033 const std::string barUrl = m_baseURL + "bar.html";
1035 WebViewImpl* webView = m_webViewHelper.initializeAndLoad(fooUrl);
1037 ASSERT_TRUE(webView);
1039 // Drag and drop barUrl and verify that we've navigated to it.
1040 DragAndDropURL(webView, barUrl);
1041 EXPECT_EQ(barUrl, webView->mainFrame()->document().url().string().utf8());
1043 // Drag and drop fooUrl and verify that we've navigated back to it.
1044 DragAndDropURL(webView, fooUrl);
1045 EXPECT_EQ(fooUrl, webView->mainFrame()->document().url().string().utf8());
1047 // Disable navigation on drag-and-drop.
1048 webView->settingsImpl()->setNavigateOnDragDrop(false);
1050 // Attempt to drag and drop to barUrl and verify that no navigation has occurred.
1051 DragAndDropURL(webView, barUrl);
1052 EXPECT_EQ(fooUrl, webView->mainFrame()->document().url().string().utf8());
1055 class ContentDetectorClient : public FrameTestHelpers::TestWebViewClient {
1057 ContentDetectorClient() { reset(); }
1059 virtual WebContentDetectionResult detectContentAround(const WebHitTestResult& hitTest) override
1061 m_contentDetectionRequested = true;
1062 return m_contentDetectionResult;
1065 virtual void scheduleContentIntent(const WebURL& url) override
1067 m_scheduledIntentURL = url;
1070 virtual void cancelScheduledContentIntents() override
1072 m_pendingIntentsCancelled = true;
1077 m_contentDetectionRequested = false;
1078 m_pendingIntentsCancelled = false;
1079 m_scheduledIntentURL = WebURL();
1080 m_contentDetectionResult = WebContentDetectionResult();
1083 bool contentDetectionRequested() const { return m_contentDetectionRequested; }
1084 bool pendingIntentsCancelled() const { return m_pendingIntentsCancelled; }
1085 const WebURL& scheduledIntentURL() const { return m_scheduledIntentURL; }
1086 void setContentDetectionResult(const WebContentDetectionResult& result) { m_contentDetectionResult = result; }
1089 bool m_contentDetectionRequested;
1090 bool m_pendingIntentsCancelled;
1091 WebURL m_scheduledIntentURL;
1092 WebContentDetectionResult m_contentDetectionResult;
1095 static bool tapElementById(WebView* webView, WebInputEvent::Type type, const WebString& id)
1098 RefPtrWillBeRawPtr<Element> element = static_cast<PassRefPtrWillBeRawPtr<Element> >(webView->mainFrame()->document().getElementById(id));
1102 element->scrollIntoViewIfNeeded();
1103 IntPoint center = element->screenRect().center();
1105 WebGestureEvent event;
1107 event.x = center.x();
1108 event.y = center.y();
1110 webView->handleInputEvent(event);
1115 TEST_F(WebViewTest, DetectContentAroundPosition)
1117 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_listeners.html"));
1119 ContentDetectorClient client;
1120 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_listeners.html", true, 0, &client);
1121 webView->resize(WebSize(500, 300));
1125 WebString clickListener = WebString::fromUTF8("clickListener");
1126 WebString touchstartListener = WebString::fromUTF8("touchstartListener");
1127 WebString mousedownListener = WebString::fromUTF8("mousedownListener");
1128 WebString noListener = WebString::fromUTF8("noListener");
1129 WebString link = WebString::fromUTF8("link");
1131 // Ensure content detection is not requested for nodes listening to click,
1132 // mouse or touch events when we do simple taps.
1133 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, clickListener));
1134 EXPECT_FALSE(client.contentDetectionRequested());
1137 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, touchstartListener));
1138 EXPECT_FALSE(client.contentDetectionRequested());
1141 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, mousedownListener));
1142 EXPECT_FALSE(client.contentDetectionRequested());
1145 // Content detection should work normally without these event listeners.
1146 // The click listener in the body should be ignored as a special case.
1147 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
1148 EXPECT_TRUE(client.contentDetectionRequested());
1149 EXPECT_FALSE(client.scheduledIntentURL().isValid());
1151 WebURL intentURL = toKURL(m_baseURL);
1152 client.setContentDetectionResult(WebContentDetectionResult(WebRange(), WebString(), intentURL));
1153 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
1154 EXPECT_TRUE(client.scheduledIntentURL() == intentURL);
1156 // Tapping elsewhere should cancel the scheduled intent.
1157 WebGestureEvent event;
1158 event.type = WebInputEvent::GestureTap;
1159 webView->handleInputEvent(event);
1161 EXPECT_TRUE(client.pendingIntentsCancelled());
1163 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
1166 TEST_F(WebViewTest, ClientTapHandling)
1168 TapHandlingWebViewClient client;
1170 WebView* webView = m_webViewHelper.initializeAndLoad("about:blank", true, 0, &client);
1171 WebGestureEvent event;
1172 event.type = WebInputEvent::GestureTap;
1175 webView->handleInputEvent(event);
1177 EXPECT_EQ(3, client.tapX());
1178 EXPECT_EQ(8, client.tapY());
1180 event.type = WebInputEvent::GestureLongPress;
1183 webView->handleInputEvent(event);
1185 EXPECT_EQ(25, client.longpressX());
1186 EXPECT_EQ(7, client.longpressY());
1188 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
1192 TEST_F(WebViewTest, LongPressSelection)
1194 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
1196 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
1197 webView->resize(WebSize(500, 300));
1201 WebString target = WebString::fromUTF8("target");
1202 WebString onselectstartfalse = WebString::fromUTF8("onselectstartfalse");
1203 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1205 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, onselectstartfalse));
1206 EXPECT_EQ("", std::string(frame->selectionAsText().utf8().data()));
1207 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, target));
1208 EXPECT_EQ("testword", std::string(frame->selectionAsText().utf8().data()));
1211 TEST_F(WebViewTest, BlinkCaretOnTypingAfterLongPress)
1213 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("blink_caret_on_typing_after_long_press.html"));
1215 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "blink_caret_on_typing_after_long_press.html", true);
1216 webView->resize(WebSize(640, 480));
1220 WebString target = WebString::fromUTF8("target");
1221 WebLocalFrameImpl* mainFrame = toWebLocalFrameImpl(webView->mainFrame());
1223 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, target));
1224 EXPECT_TRUE(mainFrame->frame()->selection().isCaretBlinkingSuspended());
1226 WebKeyboardEvent keyEvent;
1227 keyEvent.type = WebInputEvent::RawKeyDown;
1228 webView->handleInputEvent(keyEvent);
1229 keyEvent.type = WebInputEvent::KeyUp;
1230 webView->handleInputEvent(keyEvent);
1231 EXPECT_FALSE(mainFrame->frame()->selection().isCaretBlinkingSuspended());
1235 TEST_F(WebViewTest, SelectionOnReadOnlyInput)
1237 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_readonly.html"));
1238 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "selection_readonly.html", true);
1239 webView->resize(WebSize(640, 480));
1243 std::string testWord = "This text should be selected.";
1245 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1246 EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));
1250 EXPECT_TRUE(toWebViewImpl(webView)->caretOrSelectionRange(&location, &length));
1251 EXPECT_EQ(location, 0UL);
1252 EXPECT_EQ(length, testWord.length());
1255 static void configueCompositingWebView(WebSettings* settings)
1257 settings->setAcceleratedCompositingEnabled(true);
1258 settings->setPreferCompositingToLCDTextEnabled(true);
1261 TEST_F(WebViewTest, ShowPressOnTransformedLink)
1263 OwnPtr<FrameTestHelpers::TestWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FrameTestHelpers::TestWebViewClient());
1264 FrameTestHelpers::WebViewHelper webViewHelper;
1265 WebViewImpl* webViewImpl = webViewHelper.initialize(true, 0, fakeCompositingWebViewClient.get(), &configueCompositingWebView);
1267 int pageWidth = 640;
1268 int pageHeight = 480;
1269 webViewImpl->resize(WebSize(pageWidth, pageHeight));
1271 WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
1272 FrameTestHelpers::loadHTMLString(webViewImpl->mainFrame(), "<a href='http://www.test.com' style='position: absolute; left: 20px; top: 20px; width: 200px; transform:translateZ(0);'>A link to highlight</a>", baseURL);
1274 WebGestureEvent event;
1275 event.type = WebInputEvent::GestureShowPress;
1279 // Just make sure we don't hit any asserts.
1280 webViewImpl->handleInputEvent(event);
1283 class MockAutofillClient : public WebAutofillClient {
1285 MockAutofillClient()
1286 : m_ignoreTextChanges(false)
1287 , m_textChangesWhileIgnored(0)
1288 , m_textChangesWhileNotIgnored(0)
1289 , m_userGestureNotificationsCount(0) { }
1291 virtual ~MockAutofillClient() { }
1293 virtual void setIgnoreTextChanges(bool ignore) override { m_ignoreTextChanges = ignore; }
1294 virtual void textFieldDidChange(const WebFormControlElement&) override
1296 if (m_ignoreTextChanges)
1297 ++m_textChangesWhileIgnored;
1299 ++m_textChangesWhileNotIgnored;
1301 virtual void firstUserGestureObserved() override { ++m_userGestureNotificationsCount; }
1303 void clearChangeCounts()
1305 m_textChangesWhileIgnored = 0;
1306 m_textChangesWhileNotIgnored = 0;
1309 int textChangesWhileIgnored() { return m_textChangesWhileIgnored; }
1310 int textChangesWhileNotIgnored() { return m_textChangesWhileNotIgnored; }
1311 int getUserGestureNotificationsCount() { return m_userGestureNotificationsCount; }
1314 bool m_ignoreTextChanges;
1315 int m_textChangesWhileIgnored;
1316 int m_textChangesWhileNotIgnored;
1317 int m_userGestureNotificationsCount;
1321 TEST_F(WebViewTest, LosingFocusDoesNotTriggerAutofillTextChange)
1323 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
1324 MockAutofillClient client;
1325 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
1326 webView->setAutofillClient(&client);
1327 webView->setInitialFocus(false);
1329 // Set up a composition that needs to be committed.
1330 WebVector<WebCompositionUnderline> emptyUnderlines;
1331 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1332 frame->setEditableSelectionOffsets(4, 10);
1333 frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
1334 WebTextInputInfo info = webView->textInputInfo();
1335 EXPECT_EQ(4, info.selectionStart);
1336 EXPECT_EQ(10, info.selectionEnd);
1337 EXPECT_EQ(8, info.compositionStart);
1338 EXPECT_EQ(12, info.compositionEnd);
1340 // Clear the focus and track that the subsequent composition commit does not trigger a
1341 // text changed notification for autofill.
1342 client.clearChangeCounts();
1343 webView->setFocus(false);
1344 EXPECT_EQ(1, client.textChangesWhileIgnored());
1345 EXPECT_EQ(0, client.textChangesWhileNotIgnored());
1347 webView->setAutofillClient(0);
1350 TEST_F(WebViewTest, ConfirmCompositionTriggersAutofillTextChange)
1352 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
1353 MockAutofillClient client;
1354 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
1355 webView->setAutofillClient(&client);
1356 webView->setInitialFocus(false);
1358 // Set up a composition that needs to be committed.
1359 std::string compositionText("testingtext");
1361 WebVector<WebCompositionUnderline> emptyUnderlines;
1362 webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 0, compositionText.length());
1364 WebTextInputInfo info = webView->textInputInfo();
1365 EXPECT_EQ(0, info.selectionStart);
1366 EXPECT_EQ((int) compositionText.length(), info.selectionEnd);
1367 EXPECT_EQ(0, info.compositionStart);
1368 EXPECT_EQ((int) compositionText.length(), info.compositionEnd);
1370 client.clearChangeCounts();
1371 webView->confirmComposition();
1372 EXPECT_EQ(0, client.textChangesWhileIgnored());
1373 EXPECT_EQ(1, client.textChangesWhileNotIgnored());
1375 webView->setAutofillClient(0);
1378 TEST_F(WebViewTest, SetCompositionFromExistingTextTriggersAutofillTextChange)
1380 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
1381 MockAutofillClient client;
1382 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html", true);
1383 webView->setAutofillClient(&client);
1384 webView->setInitialFocus(false);
1386 WebVector<WebCompositionUnderline> emptyUnderlines;
1388 client.clearChangeCounts();
1389 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1390 frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
1392 WebTextInputInfo info = webView->textInputInfo();
1393 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
1394 EXPECT_EQ(8, info.compositionStart);
1395 EXPECT_EQ(12, info.compositionEnd);
1397 EXPECT_EQ(0, client.textChangesWhileIgnored());
1398 EXPECT_EQ(0, client.textChangesWhileNotIgnored());
1400 WebDocument document = webView->mainFrame()->document();
1401 EXPECT_EQ(WebString::fromUTF8("none"), document.getElementById("inputEvent").firstChild().nodeValue());
1403 webView->setAutofillClient(0);
1406 TEST_F(WebViewTest, ShadowRoot)
1408 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("shadow_dom_test.html"));
1409 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "shadow_dom_test.html", true);
1411 WebDocument document = webViewImpl->mainFrame()->document();
1413 WebElement elementWithShadowRoot = document.getElementById("shadowroot");
1414 EXPECT_FALSE(elementWithShadowRoot.isNull());
1415 WebNode shadowRoot = elementWithShadowRoot.shadowRoot();
1416 EXPECT_FALSE(shadowRoot.isNull());
1419 WebElement elementWithoutShadowRoot = document.getElementById("noshadowroot");
1420 EXPECT_FALSE(elementWithoutShadowRoot.isNull());
1421 WebNode shadowRoot = elementWithoutShadowRoot.shadowRoot();
1422 EXPECT_TRUE(shadowRoot.isNull());
1426 class ViewCreatingWebViewClient : public FrameTestHelpers::TestWebViewClient {
1428 ViewCreatingWebViewClient()
1429 : m_didFocusCalled(false)
1433 // WebViewClient methods
1434 virtual WebView* createView(WebLocalFrame*, const WebURLRequest&, const WebWindowFeatures&, const WebString& name, WebNavigationPolicy, bool) override
1436 return m_webViewHelper.initialize(true, 0, 0);
1439 // WebWidgetClient methods
1440 virtual void didFocus() override
1442 m_didFocusCalled = true;
1445 bool didFocusCalled() const { return m_didFocusCalled; }
1446 WebView* createdWebView() const { return m_webViewHelper.webView(); }
1449 FrameTestHelpers::WebViewHelper m_webViewHelper;
1450 bool m_didFocusCalled;
1453 TEST_F(WebViewTest, FocusExistingFrameOnNavigate)
1455 ViewCreatingWebViewClient client;
1456 FrameTestHelpers::WebViewHelper m_webViewHelper;
1457 WebViewImpl* webViewImpl = m_webViewHelper.initialize(true, 0, &client);
1458 webViewImpl->page()->settings().setJavaScriptCanOpenWindowsAutomatically(true);
1459 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame());
1460 frame->setName("_start");
1462 // Make a request that will open a new window
1463 WebURLRequest webURLRequest;
1464 webURLRequest.initialize();
1465 FrameLoadRequest request(0, webURLRequest.toResourceRequest(), "_blank");
1466 toLocalFrame(webViewImpl->page()->mainFrame())->loader().load(request);
1467 ASSERT_TRUE(client.createdWebView());
1468 EXPECT_FALSE(client.didFocusCalled());
1470 // Make a request from the new window that will navigate the original window. The original window should be focused.
1471 WebURLRequest webURLRequestWithTargetStart;
1472 webURLRequestWithTargetStart.initialize();
1473 FrameLoadRequest requestWithTargetStart(0, webURLRequestWithTargetStart.toResourceRequest(), "_start");
1474 toLocalFrame(toWebViewImpl(client.createdWebView())->page()->mainFrame())->loader().load(requestWithTargetStart);
1475 EXPECT_TRUE(client.didFocusCalled());
1477 m_webViewHelper.reset(); // Remove dependency on locally scoped client.
1480 TEST_F(WebViewTest, DispatchesFocusOutFocusInOnViewToggleFocus)
1482 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "focusout_focusin_events.html");
1483 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "focusout_focusin_events.html", true, 0);
1485 webView->setFocus(true);
1486 webView->setFocus(false);
1487 webView->setFocus(true);
1489 WebElement element = webView->mainFrame()->document().getElementById("message");
1490 EXPECT_STREQ("focusoutfocusin", element.innerText().utf8().data());
1493 TEST_F(WebViewTest, DispatchesDomFocusOutDomFocusInOnViewToggleFocus)
1495 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "domfocusout_domfocusin_events.html");
1496 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "domfocusout_domfocusin_events.html", true, 0);
1498 webView->setFocus(true);
1499 webView->setFocus(false);
1500 webView->setFocus(true);
1502 WebElement element = webView->mainFrame()->document().getElementById("message");
1503 EXPECT_STREQ("DOMFocusOutDOMFocusIn", element.innerText().utf8().data());
1506 #if !ENABLE(INPUT_MULTIPLE_FIELDS_UI)
1507 static void openDateTimeChooser(WebView* webView, HTMLInputElement* inputElement)
1509 inputElement->focus();
1511 WebKeyboardEvent keyEvent;
1512 keyEvent.windowsKeyCode = VKEY_SPACE;
1513 keyEvent.type = WebInputEvent::RawKeyDown;
1514 keyEvent.setKeyIdentifierFromWindowsKeyCode();
1515 webView->handleInputEvent(keyEvent);
1517 keyEvent.type = WebInputEvent::KeyUp;
1518 webView->handleInputEvent(keyEvent);
1521 TEST_F(WebViewTest, ChooseValueFromDateTimeChooser)
1523 DateTimeChooserWebViewClient client;
1524 std::string url = m_baseURL + "date_time_chooser.html";
1525 URLTestHelpers::registerMockedURLLoad(toKURL(url), "date_time_chooser.html");
1526 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
1528 Document* document = webViewImpl->mainFrameImpl()->frame()->document();
1530 HTMLInputElement* inputElement;
1532 inputElement = toHTMLInputElement(document->getElementById("date"));
1533 openDateTimeChooser(webViewImpl, inputElement);
1534 client.chooserCompletion()->didChooseValue(0);
1535 client.clearChooserCompletion();
1536 EXPECT_STREQ("1970-01-01", inputElement->value().utf8().data());
1538 openDateTimeChooser(webViewImpl, inputElement);
1539 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1540 client.clearChooserCompletion();
1541 EXPECT_STREQ("", inputElement->value().utf8().data());
1543 inputElement = toHTMLInputElement(document->getElementById("datetimelocal"));
1544 openDateTimeChooser(webViewImpl, inputElement);
1545 client.chooserCompletion()->didChooseValue(0);
1546 client.clearChooserCompletion();
1547 EXPECT_STREQ("1970-01-01T00:00", inputElement->value().utf8().data());
1549 openDateTimeChooser(webViewImpl, inputElement);
1550 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1551 client.clearChooserCompletion();
1552 EXPECT_STREQ("", inputElement->value().utf8().data());
1554 inputElement = toHTMLInputElement(document->getElementById("month"));
1555 openDateTimeChooser(webViewImpl, inputElement);
1556 client.chooserCompletion()->didChooseValue(0);
1557 client.clearChooserCompletion();
1558 EXPECT_STREQ("1970-01", inputElement->value().utf8().data());
1560 openDateTimeChooser(webViewImpl, inputElement);
1561 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1562 client.clearChooserCompletion();
1563 EXPECT_STREQ("", inputElement->value().utf8().data());
1565 inputElement = toHTMLInputElement(document->getElementById("time"));
1566 openDateTimeChooser(webViewImpl, inputElement);
1567 client.chooserCompletion()->didChooseValue(0);
1568 client.clearChooserCompletion();
1569 EXPECT_STREQ("00:00", inputElement->value().utf8().data());
1571 openDateTimeChooser(webViewImpl, inputElement);
1572 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1573 client.clearChooserCompletion();
1574 EXPECT_STREQ("", inputElement->value().utf8().data());
1576 inputElement = toHTMLInputElement(document->getElementById("week"));
1577 openDateTimeChooser(webViewImpl, inputElement);
1578 client.chooserCompletion()->didChooseValue(0);
1579 client.clearChooserCompletion();
1580 EXPECT_STREQ("1970-W01", inputElement->value().utf8().data());
1582 openDateTimeChooser(webViewImpl, inputElement);
1583 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1584 client.clearChooserCompletion();
1585 EXPECT_STREQ("", inputElement->value().utf8().data());
1587 // Clear the WebViewClient from the webViewHelper to avoid use-after-free in the
1588 // WebViewHelper destructor.
1589 m_webViewHelper.reset();
1593 TEST_F(WebViewTest, DispatchesFocusBlurOnViewToggle)
1595 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "focus_blur_events.html");
1596 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "focus_blur_events.html", true, 0);
1598 webView->setFocus(true);
1599 webView->setFocus(false);
1600 webView->setFocus(true);
1602 WebElement element = webView->mainFrame()->document().getElementById("message");
1603 // Expect not to see duplication of events.
1604 EXPECT_STREQ("blurfocus", element.innerText().utf8().data());
1607 TEST_F(WebViewTest, SmartClipData)
1609 static const char* kExpectedClipText = "\nPrice 10,000,000won";
1610 static const char* kExpectedClipHtml =
1611 "<div id=\"div4\" style=\"padding: 10px; margin: 10px; border: 2px "
1612 "solid rgb(135, 206, 235); float: left; width: 190px; height: 30px; "
1613 "color: rgb(0, 0, 0); font-family: myahem; font-size: 8px; font-style: "
1614 "normal; font-variant: normal; font-weight: normal; letter-spacing: "
1615 "normal; line-height: normal; orphans: auto; text-align: start; "
1616 "text-indent: 0px; text-transform: none; white-space: normal; widows: "
1617 "auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;\">Air "
1618 "conditioner</div><div id=\"div5\" style=\"padding: 10px; margin: "
1619 "10px; border: 2px solid rgb(135, 206, 235); float: left; width: "
1620 "190px; height: 30px; color: rgb(0, 0, 0); font-family: myahem; "
1621 "font-size: 8px; font-style: normal; font-variant: normal; "
1622 "font-weight: normal; letter-spacing: normal; line-height: normal; "
1623 "orphans: auto; text-align: start; text-indent: 0px; text-transform: "
1624 "none; white-space: normal; widows: auto; word-spacing: 0px; "
1625 "-webkit-text-stroke-width: 0px;\">Price 10,000,000won</div>";
1629 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
1630 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("smartclip.html"));
1631 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "smartclip.html");
1632 webView->setPageScaleFactorLimits(1, 1);
1633 webView->resize(WebSize(500, 500));
1635 WebRect cropRect(300, 125, 152, 50);
1636 webView->extractSmartClipData(cropRect, clipText, clipHtml, clipRect);
1637 EXPECT_STREQ(kExpectedClipText, clipText.utf8().c_str());
1638 EXPECT_STREQ(kExpectedClipHtml, clipHtml.utf8().c_str());
1641 TEST_F(WebViewTest, SmartClipReturnsEmptyStringsWhenUserSelectIsNone)
1646 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
1647 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("smartclip_user_select_none.html"));
1648 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "smartclip_user_select_none.html");
1649 webView->setPageScaleFactorLimits(1, 1);
1650 webView->resize(WebSize(500, 500));
1652 WebRect cropRect(0, 0, 100, 100);
1653 webView->extractSmartClipData(cropRect, clipText, clipHtml, clipRect);
1654 EXPECT_STREQ("", clipText.utf8().c_str());
1655 EXPECT_STREQ("", clipHtml.utf8().c_str());
1658 class CreateChildCounterFrameClient : public FrameTestHelpers::TestWebFrameClient {
1660 CreateChildCounterFrameClient() : m_count(0) { }
1661 virtual WebFrame* createChildFrame(WebLocalFrame* parent, const WebString& frameName) override;
1663 int count() const { return m_count; }
1669 WebFrame* CreateChildCounterFrameClient::createChildFrame(WebLocalFrame* parent, const WebString& frameName)
1672 return TestWebFrameClient::createChildFrame(parent, frameName);
1675 TEST_F(WebViewTest, AddFrameInCloseUnload)
1677 CreateChildCounterFrameClient frameClient;
1678 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1679 m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
1680 m_webViewHelper.reset();
1681 EXPECT_EQ(0, frameClient.count());
1684 TEST_F(WebViewTest, AddFrameInCloseURLUnload)
1686 CreateChildCounterFrameClient frameClient;
1687 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1688 m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
1689 m_webViewHelper.webViewImpl()->mainFrame()->dispatchUnloadEvent();
1690 EXPECT_EQ(0, frameClient.count());
1691 m_webViewHelper.reset();
1694 TEST_F(WebViewTest, AddFrameInNavigateUnload)
1696 CreateChildCounterFrameClient frameClient;
1697 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1698 m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
1699 FrameTestHelpers::loadFrame(m_webViewHelper.webView()->mainFrame(), "about:blank");
1700 EXPECT_EQ(0, frameClient.count());
1701 m_webViewHelper.reset();
1704 TEST_F(WebViewTest, AddFrameInChildInNavigateUnload)
1706 CreateChildCounterFrameClient frameClient;
1707 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload_wrapper.html"));
1708 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1709 m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload_wrapper.html", true, &frameClient);
1710 FrameTestHelpers::loadFrame(m_webViewHelper.webView()->mainFrame(), "about:blank");
1711 EXPECT_EQ(1, frameClient.count());
1712 m_webViewHelper.reset();
1715 class TouchEventHandlerWebViewClient : public FrameTestHelpers::TestWebViewClient {
1717 // WebWidgetClient methods
1718 virtual void hasTouchEventHandlers(bool state) override
1720 m_hasTouchEventHandlerCount[state]++;
1724 TouchEventHandlerWebViewClient() : m_hasTouchEventHandlerCount()
1728 int getAndResetHasTouchEventHandlerCallCount(bool state)
1730 int value = m_hasTouchEventHandlerCount[state];
1731 m_hasTouchEventHandlerCount[state] = 0;
1736 int m_hasTouchEventHandlerCount[2];
1739 // This test verifies that WebWidgetClient::hasTouchEventHandlers is called
1740 // accordingly for various calls to EventHandlerRegistry::did{Add|Remove|
1741 // RemoveAll}EventHandler(..., TouchEvent). Verifying that those calls are made
1742 // correctly is the job of LayoutTests/fast/events/event-handler-count.html.
1743 TEST_F(WebViewTest, HasTouchEventHandlers)
1745 TouchEventHandlerWebViewClient client;
1746 std::string url = m_baseURL + "has_touch_event_handlers.html";
1747 URLTestHelpers::registerMockedURLLoad(toKURL(url), "has_touch_event_handlers.html");
1748 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
1749 const EventHandlerRegistry::EventHandlerClass touchEvent = EventHandlerRegistry::TouchEvent;
1751 // The page is initialized with at least one no-handlers call.
1752 // In practice we get two such calls because WebViewHelper::initializeAndLoad first
1753 // initializes and empty frame, and then loads a document into it, so there are two
1754 // FrameLoader::commitProvisionalLoad calls.
1755 EXPECT_GE(client.getAndResetHasTouchEventHandlerCallCount(false), 1);
1756 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1758 // Adding the first document handler results in a has-handlers call.
1759 Document* document = webViewImpl->mainFrameImpl()->frame()->document();
1760 EventHandlerRegistry* registry = &document->frameHost()->eventHandlerRegistry();
1761 registry->didAddEventHandler(*document, touchEvent);
1762 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1763 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1765 // Adding another handler has no effect.
1766 registry->didAddEventHandler(*document, touchEvent);
1767 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1768 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1770 // Removing the duplicate handler has no effect.
1771 registry->didRemoveEventHandler(*document, touchEvent);
1772 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1773 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1775 // Removing the final handler results in a no-handlers call.
1776 registry->didRemoveEventHandler(*document, touchEvent);
1777 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1778 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1780 // Adding a handler on a div results in a has-handlers call.
1781 Element* parentDiv = document->getElementById("parentdiv");
1783 registry->didAddEventHandler(*parentDiv, touchEvent);
1784 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1785 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1787 // Adding a duplicate handler on the div, clearing all document handlers
1788 // (of which there are none) and removing the extra handler on the div
1789 // all have no effect.
1790 registry->didAddEventHandler(*parentDiv, touchEvent);
1791 registry->didRemoveAllEventHandlers(*document);
1792 registry->didRemoveEventHandler(*parentDiv, touchEvent);
1793 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1794 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1796 // Removing the final handler on the div results in a no-handlers call.
1797 registry->didRemoveEventHandler(*parentDiv, touchEvent);
1798 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1799 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1801 // Adding two handlers then clearing them in a single call results in a
1802 // has-handlers then no-handlers call.
1803 registry->didAddEventHandler(*parentDiv, touchEvent);
1804 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1805 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1806 registry->didAddEventHandler(*parentDiv, touchEvent);
1807 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1808 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1809 registry->didRemoveAllEventHandlers(*parentDiv);
1810 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1811 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1813 // Adding a handler inside of a child iframe results in a has-handlers call.
1814 Element* childFrame = document->getElementById("childframe");
1816 Document* childDocument = toHTMLIFrameElement(childFrame)->contentDocument();
1817 Element* childDiv = childDocument->getElementById("childdiv");
1819 registry->didAddEventHandler(*childDiv, touchEvent);
1820 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1821 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1823 // Adding and clearing handlers in the parent doc or elsewhere in the child doc
1825 registry->didAddEventHandler(*document, touchEvent);
1826 registry->didAddEventHandler(*childFrame, touchEvent);
1827 registry->didAddEventHandler(*childDocument, touchEvent);
1828 registry->didRemoveAllEventHandlers(*document);
1829 registry->didRemoveAllEventHandlers(*childFrame);
1830 registry->didRemoveAllEventHandlers(*childDocument);
1831 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1832 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1834 // Removing the final handler inside the child frame results in a no-handlers call.
1835 registry->didRemoveAllEventHandlers(*childDiv);
1836 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1837 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1839 // Adding a handler inside the child frame results in a has-handlers call.
1840 registry->didAddEventHandler(*childDocument, touchEvent);
1841 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1842 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1844 // Adding a handler in the parent document and removing the one in the frame
1846 registry->didAddEventHandler(*childFrame, touchEvent);
1847 registry->didRemoveEventHandler(*childDocument, touchEvent);
1848 registry->didRemoveAllEventHandlers(*childDocument);
1849 registry->didRemoveAllEventHandlers(*document);
1850 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1851 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1853 // Now removing the handler in the parent document results in a no-handlers call.
1854 registry->didRemoveEventHandler(*childFrame, touchEvent);
1855 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1856 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1858 // Free the webView before the TouchEventHandlerWebViewClient gets freed.
1859 m_webViewHelper.reset();
1862 // This test checks that deleting nodes which have only non-JS-registered touch
1863 // handlers also removes them from the event handler registry. Note that this
1864 // is different from detaching and re-attaching the same node, which is covered
1865 // by layout tests under fast/events/.
1866 TEST_F(WebViewTest, DeleteElementWithRegisteredHandler)
1868 std::string url = m_baseURL + "simple_div.html";
1869 URLTestHelpers::registerMockedURLLoad(toKURL(url), "simple_div.html");
1870 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true);
1872 RefPtrWillBePersistent<Document> document = webViewImpl->mainFrameImpl()->frame()->document();
1873 Element* div = document->getElementById("div");
1874 EventHandlerRegistry& registry = document->frameHost()->eventHandlerRegistry();
1876 registry.didAddEventHandler(*div, EventHandlerRegistry::ScrollEvent);
1877 EXPECT_TRUE(registry.hasEventHandlers(EventHandlerRegistry::ScrollEvent));
1879 TrackExceptionState exceptionState;
1880 div->remove(exceptionState);
1882 // For oilpan we have to force a GC to ensure the event handlers have been removed when
1883 // checking below. We do a precise GC (collectAllGarbage does not scan the stack)
1884 // to ensure the div element dies. This is also why the Document is in a Persistent
1885 // since we want that to stay around.
1886 Heap::collectAllGarbage();
1888 EXPECT_FALSE(registry.hasEventHandlers(EventHandlerRegistry::ScrollEvent));
1891 static WebRect ExpectedRootBounds(Document* document, float scaleFactor)
1893 Element* element = document->getElementById("root");
1895 element = document->getElementById("target");
1896 if (element->hasTagName(HTMLNames::iframeTag))
1897 return ExpectedRootBounds(toHTMLIFrameElement(element)->contentDocument(), scaleFactor);
1899 IntRect boundingBox;
1900 if (element->hasTagName(HTMLNames::htmlTag))
1901 boundingBox = IntRect(IntPoint(0, 0), document->frame()->view()->contentsSize());
1903 boundingBox = element->pixelSnappedBoundingBox();
1904 boundingBox = document->frame()->view()->contentsToWindow(boundingBox);
1905 boundingBox.scale(scaleFactor);
1909 void WebViewTest::testSelectionRootBounds(const char* htmlFile, float pageScaleFactor)
1911 std::string url = m_baseURL + htmlFile;
1913 WebView* webView = m_webViewHelper.initializeAndLoad(url, true);
1914 webView->resize(WebSize(640, 480));
1915 webView->setPageScaleFactor(pageScaleFactor);
1919 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1920 EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
1921 HTMLDocument* document = toHTMLDocument(frame->frame()->document());
1923 WebRect expectedRootBounds = ExpectedRootBounds(document, webView->pageScaleFactor());
1924 WebRect actualRootBounds;
1925 webView->getSelectionRootBounds(actualRootBounds);
1926 ASSERT_EQ(expectedRootBounds, actualRootBounds);
1928 WebRect anchor, focus;
1929 webView->selectionBounds(anchor, focus);
1930 IntRect expectedIntRect = expectedRootBounds;
1931 ASSERT_TRUE(expectedIntRect.contains(anchor));
1932 // The "overflow" tests have the focus boundary outside of the element box.
1933 ASSERT_EQ(url.find("overflow") == std::string::npos, expectedIntRect.contains(focus));
1936 TEST_F(WebViewTest, GetSelectionRootBounds)
1938 // Register all the pages we will be using.
1939 registerMockedHttpURLLoad("select_range_basic.html");
1940 registerMockedHttpURLLoad("select_range_div_editable.html");
1941 registerMockedHttpURLLoad("select_range_scroll.html");
1942 registerMockedHttpURLLoad("select_range_span_editable.html");
1943 registerMockedHttpURLLoad("select_range_input.html");
1944 registerMockedHttpURLLoad("select_range_input_overflow.html");
1945 registerMockedHttpURLLoad("select_range_textarea.html");
1946 registerMockedHttpURLLoad("select_range_textarea_overflow.html");
1947 registerMockedHttpURLLoad("select_range_iframe.html");
1948 registerMockedHttpURLLoad("select_range_iframe_div_editable.html");
1949 registerMockedHttpURLLoad("select_range_iframe_scroll.html");
1950 registerMockedHttpURLLoad("select_range_iframe_span_editable.html");
1951 registerMockedHttpURLLoad("select_range_iframe_input.html");
1952 registerMockedHttpURLLoad("select_range_iframe_input_overflow.html");
1953 registerMockedHttpURLLoad("select_range_iframe_textarea.html");
1954 registerMockedHttpURLLoad("select_range_iframe_textarea_overflow.html");
1956 // Test with simple pages.
1957 testSelectionRootBounds("select_range_basic.html", 1.0f);
1958 testSelectionRootBounds("select_range_div_editable.html", 1.0f);
1959 testSelectionRootBounds("select_range_scroll.html", 1.0f);
1960 testSelectionRootBounds("select_range_span_editable.html", 1.0f);
1961 testSelectionRootBounds("select_range_input.html", 1.0f);
1962 testSelectionRootBounds("select_range_input_overflow.html", 1.0f);
1963 testSelectionRootBounds("select_range_textarea.html", 1.0f);
1964 testSelectionRootBounds("select_range_textarea_overflow.html", 1.0f);
1966 // Test with the same pages as above in iframes.
1967 testSelectionRootBounds("select_range_iframe.html", 1.0f);
1968 testSelectionRootBounds("select_range_iframe_div_editable.html", 1.0f);
1969 testSelectionRootBounds("select_range_iframe_scroll.html", 1.0f);
1970 testSelectionRootBounds("select_range_iframe_span_editable.html", 1.0f);
1971 testSelectionRootBounds("select_range_iframe_input.html", 1.0f);
1972 testSelectionRootBounds("select_range_iframe_input_overflow.html", 1.0f);
1973 testSelectionRootBounds("select_range_iframe_textarea.html", 1.0f);
1974 testSelectionRootBounds("select_range_iframe_textarea_overflow.html", 1.0f);
1976 // Basic page with scale factor.
1977 testSelectionRootBounds("select_range_basic.html", 0.0f);
1978 testSelectionRootBounds("select_range_basic.html", 0.1f);
1979 testSelectionRootBounds("select_range_basic.html", 1.5f);
1980 testSelectionRootBounds("select_range_basic.html", 2.0f);
1983 TEST_F(WebViewTest, GetSelectionRootBoundsBrokenHeight)
1985 WebSize contentSize = WebSize(640, 480);
1987 registerMockedHttpURLLoad("select_range_basic_broken_height.html");
1989 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "select_range_basic_broken_height.html", true);
1990 webView->resize(contentSize);
1991 webView->setPageScaleFactor(1.0f, WebPoint(0, 0));
1995 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1996 EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
1998 WebRect expectedRootBounds = WebRect(0, 0, contentSize.width, contentSize.height);
1999 WebRect actualRootBounds;
2000 webView->getSelectionRootBounds(actualRootBounds);
2001 ASSERT_EQ(expectedRootBounds, actualRootBounds);
2004 class NonUserInputTextUpdateWebViewClient : public FrameTestHelpers::TestWebViewClient {
2006 NonUserInputTextUpdateWebViewClient() : m_textIsUpdated(false) { }
2008 // WebWidgetClient methods
2009 virtual void didUpdateTextOfFocusedElementByNonUserInput() override
2011 m_textIsUpdated = true;
2016 m_textIsUpdated = false;
2019 bool textIsUpdated() const
2021 return m_textIsUpdated;
2025 int m_textIsUpdated;
2028 // This test verifies that WebWidgetClient::didUpdateTextOfFocusedElementByNonUserInput is
2029 // called iff value of a focused element is modified via script.
2030 TEST_F(WebViewTest, NonUserInputTextUpdate)
2032 NonUserInputTextUpdateWebViewClient client;
2033 std::string url = m_baseURL + "non_user_input_text_update.html";
2034 URLTestHelpers::registerMockedURLLoad(toKURL(url), "non_user_input_text_update.html");
2035 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
2036 webViewImpl->setInitialFocus(false);
2038 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame());
2039 HTMLDocument* document = toHTMLDocument(frame->frame()->document());
2042 // (A.1) Focused and value is changed by script.
2044 EXPECT_FALSE(client.textIsUpdated());
2046 HTMLInputElement* inputElement = toHTMLInputElement(document->getElementById("input"));
2047 document->setFocusedElement(inputElement);
2048 webViewImpl->setFocus(true);
2049 EXPECT_EQ(document->focusedElement(), static_cast<Element*>(inputElement));
2051 // Emulate value change from script.
2052 inputElement->setValue("testA");
2053 EXPECT_TRUE(client.textIsUpdated());
2054 WebTextInputInfo info = webViewImpl->textInputInfo();
2055 EXPECT_EQ("testA", std::string(info.value.utf8().data()));
2057 // (A.2) Focused and user input modifies value.
2059 EXPECT_FALSE(client.textIsUpdated());
2061 WebVector<WebCompositionUnderline> emptyUnderlines;
2062 webViewImpl->setComposition(WebString::fromUTF8("2"), emptyUnderlines, 1, 1);
2063 webViewImpl->confirmComposition(WebWidget::KeepSelection);
2064 EXPECT_FALSE(client.textIsUpdated());
2065 info = webViewImpl->textInputInfo();
2066 EXPECT_EQ("testA2", std::string(info.value.utf8().data()));
2068 // (A.3) Unfocused and value is changed by script.
2070 EXPECT_FALSE(client.textIsUpdated());
2071 document->setFocusedElement(nullptr);
2072 webViewImpl->setFocus(false);
2073 EXPECT_NE(document->focusedElement(), static_cast<Element*>(inputElement));
2074 inputElement->setValue("testA3");
2075 EXPECT_FALSE(client.textIsUpdated());
2078 // (B.1) Focused and value is changed by script.
2080 EXPECT_FALSE(client.textIsUpdated());
2081 HTMLTextAreaElement* textAreaElement = toHTMLTextAreaElement(document->getElementById("textarea"));
2082 document->setFocusedElement(textAreaElement);
2083 webViewImpl->setFocus(true);
2084 EXPECT_EQ(document->focusedElement(), static_cast<Element*>(textAreaElement));
2085 textAreaElement->setValue("testB");
2086 EXPECT_TRUE(client.textIsUpdated());
2087 info = webViewImpl->textInputInfo();
2088 EXPECT_EQ("testB", std::string(info.value.utf8().data()));
2090 // (B.2) Focused and user input modifies value.
2092 EXPECT_FALSE(client.textIsUpdated());
2093 webViewImpl->setComposition(WebString::fromUTF8("2"), emptyUnderlines, 1, 1);
2094 webViewImpl->confirmComposition(WebWidget::KeepSelection);
2095 info = webViewImpl->textInputInfo();
2096 EXPECT_EQ("testB2", std::string(info.value.utf8().data()));
2098 // (B.3) Unfocused and value is changed by script.
2100 EXPECT_FALSE(client.textIsUpdated());
2101 document->setFocusedElement(nullptr);
2102 webViewImpl->setFocus(false);
2103 EXPECT_NE(document->focusedElement(), static_cast<Element*>(textAreaElement));
2104 inputElement->setValue("testB3");
2105 EXPECT_FALSE(client.textIsUpdated());
2107 // Free the webView before freeing the NonUserInputTextUpdateWebViewClient.
2108 m_webViewHelper.reset();
2111 // Check that the WebAutofillClient is correctly notified about first user
2112 // gestures after load, following various input events.
2113 TEST_F(WebViewTest, FirstUserGestureObservedKeyEvent)
2115 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("form.html"));
2116 MockAutofillClient client;
2117 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "form.html", true);
2118 webView->setAutofillClient(&client);
2119 webView->setInitialFocus(false);
2121 EXPECT_EQ(0, client.getUserGestureNotificationsCount());
2123 WebKeyboardEvent keyEvent;
2124 keyEvent.windowsKeyCode = VKEY_SPACE;
2125 keyEvent.type = WebInputEvent::RawKeyDown;
2126 keyEvent.setKeyIdentifierFromWindowsKeyCode();
2127 webView->handleInputEvent(keyEvent);
2128 keyEvent.type = WebInputEvent::KeyUp;
2129 webView->handleInputEvent(keyEvent);
2131 EXPECT_EQ(1, client.getUserGestureNotificationsCount());
2132 webView->setAutofillClient(0);
2135 TEST_F(WebViewTest, FirstUserGestureObservedMouseEvent)
2137 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("form.html"));
2138 MockAutofillClient client;
2139 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "form.html", true);
2140 webView->setAutofillClient(&client);
2141 webView->setInitialFocus(false);
2143 EXPECT_EQ(0, client.getUserGestureNotificationsCount());
2145 WebMouseEvent mouseEvent;
2146 mouseEvent.button = WebMouseEvent::ButtonLeft;
2149 mouseEvent.clickCount = 1;
2150 mouseEvent.type = WebInputEvent::MouseDown;
2151 webView->handleInputEvent(mouseEvent);
2152 mouseEvent.type = WebInputEvent::MouseUp;
2153 webView->handleInputEvent(mouseEvent);
2155 EXPECT_EQ(1, client.getUserGestureNotificationsCount());
2156 webView->setAutofillClient(0);
2159 TEST_F(WebViewTest, FirstUserGestureObservedGestureTap)
2161 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
2162 MockAutofillClient client;
2163 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
2164 webView->setAutofillClient(&client);
2165 webView->setInitialFocus(false);
2167 EXPECT_EQ(0, client.getUserGestureNotificationsCount());
2169 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, WebString::fromUTF8("target")));
2171 EXPECT_EQ(1, client.getUserGestureNotificationsCount());
2172 webView->setAutofillClient(0);
2175 TEST_F(WebViewTest, CompareSelectAllToContentAsText)
2177 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
2178 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
2180 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
2181 frame->executeScript(WebScriptSource(WebString::fromUTF8("document.execCommand('SelectAll', false, null)")));
2182 std::string actual = frame->selectionAsText().utf8();
2184 const int kMaxOutputCharacters = 1024;
2185 std::string expected = frame->contentAsText(kMaxOutputCharacters).utf8();
2186 EXPECT_EQ(expected, actual);
2189 TEST_F(WebViewTest, AutoResizeSubtreeLayout)
2191 std::string url = m_baseURL + "subtree-layout.html";
2192 URLTestHelpers::registerMockedURLLoad(toKURL(url), "subtree-layout.html");
2193 WebView* webView = m_webViewHelper.initialize(true);
2195 webView->enableAutoResizeMode(WebSize(200, 200), WebSize(200, 200));
2196 loadFrame(webView->mainFrame(), url);
2198 FrameView* frameView = m_webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
2200 // Auto-resizing used to ASSERT(needsLayout()) in RenderBlockFlow::layout. This EXPECT is
2201 // merely a dummy. The real test is that we don't trigger asserts in debug builds.
2202 EXPECT_FALSE(frameView->needsLayout());