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/rendering/RenderLayer.h"
49 #include "core/rendering/RenderView.h"
50 #include "platform/KeyboardCodes.h"
51 #include "platform/geometry/IntSize.h"
52 #include "platform/graphics/Color.h"
53 #include "public/platform/Platform.h"
54 #include "public/platform/WebClipboard.h"
55 #include "public/platform/WebDragData.h"
56 #include "public/platform/WebSize.h"
57 #include "public/platform/WebThread.h"
58 #include "public/platform/WebUnitTestSupport.h"
59 #include "public/web/WebAutofillClient.h"
60 #include "public/web/WebContentDetectionResult.h"
61 #include "public/web/WebDateTimeChooserCompletion.h"
62 #include "public/web/WebDocument.h"
63 #include "public/web/WebDragOperation.h"
64 #include "public/web/WebElement.h"
65 #include "public/web/WebFrame.h"
66 #include "public/web/WebFrameClient.h"
67 #include "public/web/WebHitTestResult.h"
68 #include "public/web/WebInputEvent.h"
69 #include "public/web/WebScriptSource.h"
70 #include "public/web/WebSettings.h"
71 #include "public/web/WebViewClient.h"
72 #include "public/web/WebWidget.h"
73 #include "public/web/WebWidgetClient.h"
74 #include "third_party/skia/include/core/SkBitmap.h"
75 #include "third_party/skia/include/core/SkBitmapDevice.h"
76 #include "third_party/skia/include/core/SkCanvas.h"
77 #include "web/WebLocalFrameImpl.h"
78 #include "web/WebSettingsImpl.h"
79 #include "web/WebViewImpl.h"
80 #include "web/tests/FrameTestHelpers.h"
81 #include "web/tests/URLTestHelpers.h"
82 #include <gtest/gtest.h>
84 using namespace blink;
85 using blink::FrameTestHelpers::runPendingTasks;
86 using blink::URLTestHelpers::toKURL;
90 enum HorizontalScrollbarState {
91 NoHorizontalScrollbar,
92 VisibleHorizontalScrollbar,
95 enum VerticalScrollbarState {
97 VisibleVerticalScrollbar,
102 void setWebView(WebView* webView) { m_webView = toWebViewImpl(webView); }
103 void setSize(const WebSize& newSize) { m_size = newSize; }
104 HorizontalScrollbarState horizontalScrollbarState() const
106 return m_webView->hasHorizontalScrollbar() ? VisibleHorizontalScrollbar: NoHorizontalScrollbar;
108 VerticalScrollbarState verticalScrollbarState() const
110 return m_webView->hasVerticalScrollbar() ? VisibleVerticalScrollbar : NoVerticalScrollbar;
112 int width() const { return m_size.width; }
113 int height() const { return m_size.height; }
117 WebViewImpl* m_webView;
120 class AutoResizeWebViewClient : public FrameTestHelpers::TestWebViewClient {
122 // WebViewClient methods
123 virtual void didAutoResize(const WebSize& newSize) { m_testData.setSize(newSize); }
126 TestData& testData() { return m_testData; }
132 class TapHandlingWebViewClient : public FrameTestHelpers::TestWebViewClient {
134 // WebViewClient methods
135 virtual void didHandleGestureEvent(const WebGestureEvent& event, bool eventCancelled)
137 if (event.type == WebInputEvent::GestureTap) {
140 } else if (event.type == WebInputEvent::GestureLongPress) {
141 m_longpressX = event.x;
142 m_longpressY = event.y;
154 int tapX() { return m_tapX; }
155 int tapY() { return m_tapY; }
156 int longpressX() { return m_longpressX; }
157 int longpressY() { return m_longpressY; }
166 class DateTimeChooserWebViewClient : public FrameTestHelpers::TestWebViewClient {
168 WebDateTimeChooserCompletion* chooserCompletion()
170 return m_chooserCompletion;
173 void clearChooserCompletion()
175 m_chooserCompletion = 0;
178 // WebViewClient methods
179 virtual bool openDateTimeChooser(const WebDateTimeChooserParams&, WebDateTimeChooserCompletion* chooser_completion) OVERRIDE
181 m_chooserCompletion = chooser_completion;
186 WebDateTimeChooserCompletion* m_chooserCompletion;
190 class WebViewTest : public testing::Test {
193 : m_baseURL("http://www.test.com/")
197 virtual void TearDown()
199 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
203 void registerMockedHttpURLLoad(const std::string& fileName)
205 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(fileName.c_str()));
208 void testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
209 const std::string& pageWidth, const std::string& pageHeight,
210 int expectedWidth, int expectedHeight,
211 HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState);
213 void testTextInputType(WebTextInputType expectedType, const std::string& htmlFile);
214 void testInputMode(const WebString& expectedInputMode, const std::string& htmlFile);
215 void testSelectionRootBounds(const char* htmlFile, float pageScaleFactor);
217 std::string m_baseURL;
218 FrameTestHelpers::WebViewHelper m_webViewHelper;
221 TEST_F(WebViewTest, CopyImageAt)
223 std::string url = m_baseURL + "canvas-copy-image.html";
224 URLTestHelpers::registerMockedURLLoad(toKURL(url), "canvas-copy-image.html");
225 WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
226 webView->resize(WebSize(400, 400));
227 webView->copyImageAt(WebPoint(50, 50));
229 blink::WebData data = blink::Platform::current()->clipboard()->readImage(blink::WebClipboard::Buffer());
230 blink::WebImage image = blink::WebImage::fromData(data, WebSize());
232 SkAutoLockPixels autoLock(image.getSkBitmap());
233 EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image.getSkBitmap().getColor(0, 0));
236 TEST_F(WebViewTest, SetBaseBackgroundColor)
238 const WebColor kWhite = 0xFFFFFFFF;
239 const WebColor kBlue = 0xFF0000FF;
240 const WebColor kDarkCyan = 0xFF227788;
241 const WebColor kTranslucentPutty = 0x80BFB196;
242 const WebColor kTransparent = 0x00000000;
244 WebViewImpl* webView = m_webViewHelper.initialize();
245 EXPECT_EQ(kWhite, webView->backgroundColor());
247 webView->setBaseBackgroundColor(kBlue);
248 EXPECT_EQ(kBlue, webView->backgroundColor());
250 WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
251 FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:#227788}</style></head></html>", baseURL);
252 EXPECT_EQ(kDarkCyan, webView->backgroundColor());
254 FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:rgba(255,0,0,0.5)}</style></head></html>", baseURL);
255 // Expected: red (50% alpha) blended atop base of kBlue.
256 EXPECT_EQ(0xFF7F0080, webView->backgroundColor());
258 webView->setBaseBackgroundColor(kTranslucentPutty);
259 // Expected: red (50% alpha) blended atop kTranslucentPutty. Note the alpha.
260 EXPECT_EQ(0xBFE93B32, webView->backgroundColor());
262 webView->setBaseBackgroundColor(kTransparent);
263 FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:transparent}</style></head></html>", baseURL);
264 // Expected: transparent on top of kTransparent will still be transparent.
265 EXPECT_EQ(kTransparent, webView->backgroundColor());
267 blink::LocalFrame* frame = webView->mainFrameImpl()->frame();
269 // Creating a new frame view with the background color having 0 alpha.
270 frame->createView(blink::IntSize(1024, 768), blink::Color::transparent, true);
271 EXPECT_EQ(kTransparent, frame->view()->baseBackgroundColor());
273 blink::Color kTransparentRed(100, 0, 0, 0);
274 frame->createView(blink::IntSize(1024, 768), kTransparentRed, true);
275 EXPECT_EQ(kTransparentRed, frame->view()->baseBackgroundColor());
278 TEST_F(WebViewTest, SetBaseBackgroundColorBeforeMainFrame)
280 const WebColor kBlue = 0xFF0000FF;
281 FrameTestHelpers::TestWebViewClient webViewClient;
282 WebView* webView = WebViewImpl::create(&webViewClient);
283 EXPECT_NE(kBlue, webView->backgroundColor());
284 // webView does not have a frame yet, but we should still be able to set the background color.
285 webView->setBaseBackgroundColor(kBlue);
286 EXPECT_EQ(kBlue, webView->backgroundColor());
287 webView->setMainFrame(WebLocalFrameImpl::create(0));
291 TEST_F(WebViewTest, SetBaseBackgroundColorAndBlendWithExistingContent)
293 const WebColor kAlphaRed = 0x80FF0000;
294 const WebColor kAlphaGreen = 0x8000FF00;
295 const int kWidth = 100;
296 const int kHeight = 100;
298 WebView* webView = m_webViewHelper.initialize();
300 // Set WebView background to green with alpha.
301 webView->setBaseBackgroundColor(kAlphaGreen);
302 webView->settings()->setShouldClearDocumentBackground(false);
303 webView->resize(WebSize(kWidth, kHeight));
306 // Set canvas background to red with alpha.
308 ASSERT_TRUE(bitmap.allocN32Pixels(kWidth, kHeight));
309 SkCanvas canvas(bitmap);
310 canvas.clear(kAlphaRed);
312 blink::GraphicsContext context(&canvas);
314 // Paint the root of the main frame in the way that CompositedLayerMapping would.
315 blink::FrameView* view = m_webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
316 blink::RenderLayer* rootLayer = view->renderView()->layer();
317 blink::IntRect paintRect(0, 0, kWidth, kHeight);
318 blink::LayerPaintingInfo paintingInfo(rootLayer, paintRect, blink::PaintBehaviorNormal, blink::LayoutSize());
319 rootLayer->paintLayerContents(&context, paintingInfo, blink::PaintLayerPaintingCompositingAllPhases);
321 // The result should be a blend of red and green.
322 SkColor color = bitmap.getColor(kWidth / 2, kHeight / 2);
323 EXPECT_TRUE(blink::redChannel(color));
324 EXPECT_TRUE(blink::greenChannel(color));
327 TEST_F(WebViewTest, FocusIsInactive)
329 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
330 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "visible_iframe.html");
332 webView->setFocus(true);
333 webView->setIsActive(true);
334 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
335 EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
337 blink::HTMLDocument* document = blink::toHTMLDocument(frame->frame()->document());
338 EXPECT_TRUE(document->hasFocus());
339 webView->setFocus(false);
340 webView->setIsActive(false);
341 EXPECT_FALSE(document->hasFocus());
342 webView->setFocus(true);
343 webView->setIsActive(true);
344 EXPECT_TRUE(document->hasFocus());
345 webView->setFocus(true);
346 webView->setIsActive(false);
347 EXPECT_FALSE(document->hasFocus());
348 webView->setFocus(false);
349 webView->setIsActive(true);
350 EXPECT_FALSE(document->hasFocus());
353 TEST_F(WebViewTest, ActiveState)
355 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
356 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "visible_iframe.html");
358 ASSERT_TRUE(webView);
360 webView->setIsActive(true);
361 EXPECT_TRUE(webView->isActive());
363 webView->setIsActive(false);
364 EXPECT_FALSE(webView->isActive());
366 webView->setIsActive(true);
367 EXPECT_TRUE(webView->isActive());
370 TEST_F(WebViewTest, HitTestResultAtWithPageScale)
372 std::string url = m_baseURL + "specify_size.html?" + "50px" + ":" + "50px";
373 URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
374 WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
375 webView->resize(WebSize(100, 100));
376 WebPoint hitPoint(75, 75);
378 // Image is at top left quandrant, so should not hit it.
379 WebHitTestResult negativeResult = webView->hitTestResultAt(hitPoint);
380 ASSERT_EQ(WebNode::ElementNode, negativeResult.node().nodeType());
381 EXPECT_FALSE(negativeResult.node().to<WebElement>().hasHTMLTagName("img"));
382 negativeResult.reset();
384 // Scale page up 2x so image should occupy the whole viewport.
385 webView->setPageScaleFactor(2.0f);
386 WebHitTestResult positiveResult = webView->hitTestResultAt(hitPoint);
387 ASSERT_EQ(WebNode::ElementNode, positiveResult.node().nodeType());
388 EXPECT_TRUE(positiveResult.node().to<WebElement>().hasHTMLTagName("img"));
389 positiveResult.reset();
392 void WebViewTest::testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
393 const std::string& pageWidth, const std::string& pageHeight,
394 int expectedWidth, int expectedHeight,
395 HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState)
397 AutoResizeWebViewClient client;
398 std::string url = m_baseURL + "specify_size.html?" + pageWidth + ":" + pageHeight;
399 URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
400 WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
401 client.testData().setWebView(webView);
403 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
404 blink::FrameView* frameView = frame->frame()->view();
406 EXPECT_FALSE(frameView->layoutPending());
407 EXPECT_FALSE(frameView->needsLayout());
409 webView->enableAutoResizeMode(minAutoResize, maxAutoResize);
410 EXPECT_TRUE(frameView->layoutPending());
411 EXPECT_TRUE(frameView->needsLayout());
414 EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
416 EXPECT_EQ(expectedWidth, client.testData().width());
417 EXPECT_EQ(expectedHeight, client.testData().height());
418 EXPECT_EQ(expectedHorizontalState, client.testData().horizontalScrollbarState());
419 EXPECT_EQ(expectedVerticalState, client.testData().verticalScrollbarState());
421 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
424 TEST_F(WebViewTest, DISABLED_AutoResizeMinimumSize)
426 WebSize minAutoResize(91, 56);
427 WebSize maxAutoResize(403, 302);
428 std::string pageWidth = "91px";
429 std::string pageHeight = "56px";
430 int expectedWidth = 91;
431 int expectedHeight = 56;
432 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
433 expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
436 TEST_F(WebViewTest, AutoResizeHeightOverflowAndFixedWidth)
438 WebSize minAutoResize(90, 95);
439 WebSize maxAutoResize(90, 100);
440 std::string pageWidth = "60px";
441 std::string pageHeight = "200px";
442 int expectedWidth = 90;
443 int expectedHeight = 100;
444 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
445 expectedWidth, expectedHeight, NoHorizontalScrollbar, VisibleVerticalScrollbar);
448 TEST_F(WebViewTest, AutoResizeFixedHeightAndWidthOverflow)
450 WebSize minAutoResize(90, 100);
451 WebSize maxAutoResize(200, 100);
452 std::string pageWidth = "300px";
453 std::string pageHeight = "80px";
454 int expectedWidth = 200;
455 int expectedHeight = 100;
456 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
457 expectedWidth, expectedHeight, VisibleHorizontalScrollbar, NoVerticalScrollbar);
460 // Next three tests disabled for https://bugs.webkit.org/show_bug.cgi?id=92318 .
461 // It seems we can run three AutoResize tests, then the next one breaks.
462 TEST_F(WebViewTest, DISABLED_AutoResizeInBetweenSizes)
464 WebSize minAutoResize(90, 95);
465 WebSize maxAutoResize(200, 300);
466 std::string pageWidth = "100px";
467 std::string pageHeight = "200px";
468 int expectedWidth = 100;
469 int expectedHeight = 200;
470 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
471 expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
474 TEST_F(WebViewTest, DISABLED_AutoResizeOverflowSizes)
476 WebSize minAutoResize(90, 95);
477 WebSize maxAutoResize(200, 300);
478 std::string pageWidth = "300px";
479 std::string pageHeight = "400px";
480 int expectedWidth = 200;
481 int expectedHeight = 300;
482 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
483 expectedWidth, expectedHeight, VisibleHorizontalScrollbar, VisibleVerticalScrollbar);
486 TEST_F(WebViewTest, DISABLED_AutoResizeMaxSize)
488 WebSize minAutoResize(90, 95);
489 WebSize maxAutoResize(200, 300);
490 std::string pageWidth = "200px";
491 std::string pageHeight = "300px";
492 int expectedWidth = 200;
493 int expectedHeight = 300;
494 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
495 expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
498 void WebViewTest::testTextInputType(WebTextInputType expectedType, const std::string& htmlFile)
500 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
501 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + htmlFile);
502 webView->setInitialFocus(false);
503 EXPECT_EQ(expectedType, webView->textInputInfo().type);
506 TEST_F(WebViewTest, TextInputType)
508 testTextInputType(WebTextInputTypeText, "input_field_default.html");
509 testTextInputType(WebTextInputTypePassword, "input_field_password.html");
510 testTextInputType(WebTextInputTypeEmail, "input_field_email.html");
511 testTextInputType(WebTextInputTypeSearch, "input_field_search.html");
512 testTextInputType(WebTextInputTypeNumber, "input_field_number.html");
513 testTextInputType(WebTextInputTypeTelephone, "input_field_tel.html");
514 testTextInputType(WebTextInputTypeURL, "input_field_url.html");
517 void WebViewTest::testInputMode(const WebString& expectedInputMode, const std::string& htmlFile)
519 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
520 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + htmlFile);
521 webView->setInitialFocus(false);
522 EXPECT_EQ(expectedInputMode, webView->textInputInfo().inputMode);
525 TEST_F(WebViewTest, InputMode)
527 testInputMode(WebString(), "input_mode_default.html");
528 testInputMode(WebString("unknown"), "input_mode_default_unknown.html");
529 testInputMode(WebString("verbatim"), "input_mode_default_verbatim.html");
530 testInputMode(WebString("verbatim"), "input_mode_type_text_verbatim.html");
531 testInputMode(WebString("verbatim"), "input_mode_type_search_verbatim.html");
532 testInputMode(WebString(), "input_mode_type_url_verbatim.html");
533 testInputMode(WebString("verbatim"), "input_mode_textarea_verbatim.html");
536 TEST_F(WebViewTest, TextInputInfoWithReplacedElements)
538 std::string url = m_baseURL + "div_with_image.html";
539 URLTestHelpers::registerMockedURLLoad(toKURL(url), "div_with_image.html");
540 WebView* webView = m_webViewHelper.initializeAndLoad(url);
541 webView->setInitialFocus(false);
542 WebTextInputInfo info = webView->textInputInfo();
544 EXPECT_EQ("foo\xef\xbf\xbc", info.value.utf8());
547 TEST_F(WebViewTest, SetEditableSelectionOffsetsAndTextInputInfo)
549 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
550 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
551 webView->setInitialFocus(false);
552 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
553 frame->setEditableSelectionOffsets(5, 13);
554 EXPECT_EQ("56789abc", frame->selectionAsText());
555 WebTextInputInfo info = webView->textInputInfo();
556 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
557 EXPECT_EQ(5, info.selectionStart);
558 EXPECT_EQ(13, info.selectionEnd);
559 EXPECT_EQ(-1, info.compositionStart);
560 EXPECT_EQ(-1, info.compositionEnd);
562 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_editable_populated.html"));
563 webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_editable_populated.html");
564 webView->setInitialFocus(false);
565 frame = toWebLocalFrameImpl(webView->mainFrame());
566 frame->setEditableSelectionOffsets(8, 19);
567 EXPECT_EQ("89abcdefghi", frame->selectionAsText());
568 info = webView->textInputInfo();
569 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
570 EXPECT_EQ(8, info.selectionStart);
571 EXPECT_EQ(19, info.selectionEnd);
572 EXPECT_EQ(-1, info.compositionStart);
573 EXPECT_EQ(-1, info.compositionEnd);
576 TEST_F(WebViewTest, ConfirmCompositionCursorPositionChange)
578 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
579 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
580 webView->setInitialFocus(false);
582 // Set up a composition that needs to be committed.
583 std::string compositionText("hello");
585 WebVector<WebCompositionUnderline> emptyUnderlines;
586 webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3);
588 WebTextInputInfo info = webView->textInputInfo();
589 EXPECT_EQ("hello", std::string(info.value.utf8().data()));
590 EXPECT_EQ(3, info.selectionStart);
591 EXPECT_EQ(3, info.selectionEnd);
592 EXPECT_EQ(0, info.compositionStart);
593 EXPECT_EQ(5, info.compositionEnd);
595 webView->confirmComposition(WebWidget::KeepSelection);
596 info = webView->textInputInfo();
597 EXPECT_EQ(3, info.selectionStart);
598 EXPECT_EQ(3, info.selectionEnd);
599 EXPECT_EQ(-1, info.compositionStart);
600 EXPECT_EQ(-1, info.compositionEnd);
602 webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3);
603 info = webView->textInputInfo();
604 EXPECT_EQ("helhellolo", std::string(info.value.utf8().data()));
605 EXPECT_EQ(6, info.selectionStart);
606 EXPECT_EQ(6, info.selectionEnd);
607 EXPECT_EQ(3, info.compositionStart);
608 EXPECT_EQ(8, info.compositionEnd);
610 webView->confirmComposition(WebWidget::DoNotKeepSelection);
611 info = webView->textInputInfo();
612 EXPECT_EQ(8, info.selectionStart);
613 EXPECT_EQ(8, info.selectionEnd);
614 EXPECT_EQ(-1, info.compositionStart);
615 EXPECT_EQ(-1, info.compositionEnd);
618 TEST_F(WebViewTest, InsertNewLinePlacementAfterConfirmComposition)
620 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html"));
621 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "text_area_populated.html");
622 webView->setInitialFocus(false);
624 WebVector<WebCompositionUnderline> emptyUnderlines;
626 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
627 frame->setEditableSelectionOffsets(4, 4);
628 frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
630 WebTextInputInfo info = webView->textInputInfo();
631 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
632 EXPECT_EQ(4, info.selectionStart);
633 EXPECT_EQ(4, info.selectionEnd);
634 EXPECT_EQ(8, info.compositionStart);
635 EXPECT_EQ(12, info.compositionEnd);
637 webView->confirmComposition(WebWidget::KeepSelection);
638 info = webView->textInputInfo();
639 EXPECT_EQ(4, info.selectionStart);
640 EXPECT_EQ(4, info.selectionEnd);
641 EXPECT_EQ(-1, info.compositionStart);
642 EXPECT_EQ(-1, info.compositionEnd);
644 std::string compositionText("\n");
645 webView->confirmComposition(WebString::fromUTF8(compositionText.c_str()));
646 info = webView->textInputInfo();
647 EXPECT_EQ(5, info.selectionStart);
648 EXPECT_EQ(5, info.selectionEnd);
649 EXPECT_EQ(-1, info.compositionStart);
650 EXPECT_EQ(-1, info.compositionEnd);
651 EXPECT_EQ("0123\n456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
654 TEST_F(WebViewTest, ExtendSelectionAndDelete)
656 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
657 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
658 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
659 webView->setInitialFocus(false);
660 frame->setEditableSelectionOffsets(10, 10);
661 frame->extendSelectionAndDelete(5, 8);
662 WebTextInputInfo info = webView->textInputInfo();
663 EXPECT_EQ("01234ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
664 EXPECT_EQ(5, info.selectionStart);
665 EXPECT_EQ(5, info.selectionEnd);
666 frame->extendSelectionAndDelete(10, 0);
667 info = webView->textInputInfo();
668 EXPECT_EQ("ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
671 TEST_F(WebViewTest, SetCompositionFromExistingText)
673 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
674 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
675 webView->setInitialFocus(false);
676 WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
677 underlines[0] = blink::WebCompositionUnderline(0, 4, 0, false, 0);
678 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
679 frame->setEditableSelectionOffsets(4, 10);
680 frame->setCompositionFromExistingText(8, 12, underlines);
681 WebVector<WebCompositionUnderline> underlineResults = toWebViewImpl(webView)->compositionUnderlines();
682 EXPECT_EQ(8u, underlineResults[0].startOffset);
683 EXPECT_EQ(12u, underlineResults[0].endOffset);
684 WebTextInputInfo info = webView->textInputInfo();
685 EXPECT_EQ(4, info.selectionStart);
686 EXPECT_EQ(10, info.selectionEnd);
687 EXPECT_EQ(8, info.compositionStart);
688 EXPECT_EQ(12, info.compositionEnd);
689 WebVector<WebCompositionUnderline> emptyUnderlines;
690 frame->setCompositionFromExistingText(0, 0, emptyUnderlines);
691 info = webView->textInputInfo();
692 EXPECT_EQ(4, info.selectionStart);
693 EXPECT_EQ(10, info.selectionEnd);
694 EXPECT_EQ(-1, info.compositionStart);
695 EXPECT_EQ(-1, info.compositionEnd);
698 TEST_F(WebViewTest, SetCompositionFromExistingTextInTextArea)
700 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html"));
701 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "text_area_populated.html");
702 webView->setInitialFocus(false);
703 WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
704 underlines[0] = blink::WebCompositionUnderline(0, 4, 0, false, 0);
705 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
706 frame->setEditableSelectionOffsets(27, 27);
707 std::string newLineText("\n");
708 webView->confirmComposition(WebString::fromUTF8(newLineText.c_str()));
709 WebTextInputInfo info = webView->textInputInfo();
710 EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data()));
712 frame->setEditableSelectionOffsets(31, 31);
713 frame->setCompositionFromExistingText(30, 34, underlines);
714 WebVector<WebCompositionUnderline> underlineResults = toWebViewImpl(webView)->compositionUnderlines();
715 EXPECT_EQ(2u, underlineResults[0].startOffset);
716 EXPECT_EQ(6u, underlineResults[0].endOffset);
717 info = webView->textInputInfo();
718 EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data()));
719 EXPECT_EQ(31, info.selectionStart);
720 EXPECT_EQ(31, info.selectionEnd);
721 EXPECT_EQ(30, info.compositionStart);
722 EXPECT_EQ(34, info.compositionEnd);
724 std::string compositionText("yolo");
725 webView->confirmComposition(WebString::fromUTF8(compositionText.c_str()));
726 info = webView->textInputInfo();
727 EXPECT_EQ("0123456789abcdefghijklmnopq\nrsyoloxyz", std::string(info.value.utf8().data()));
728 EXPECT_EQ(34, info.selectionStart);
729 EXPECT_EQ(34, info.selectionEnd);
730 EXPECT_EQ(-1, info.compositionStart);
731 EXPECT_EQ(-1, info.compositionEnd);
734 TEST_F(WebViewTest, SetEditableSelectionOffsetsKeepsComposition)
736 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
737 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
738 webView->setInitialFocus(false);
740 std::string compositionTextFirst("hello ");
741 std::string compositionTextSecond("world");
742 WebVector<WebCompositionUnderline> emptyUnderlines;
744 webView->confirmComposition(WebString::fromUTF8(compositionTextFirst.c_str()));
745 webView->setComposition(WebString::fromUTF8(compositionTextSecond.c_str()), emptyUnderlines, 5, 5);
747 WebTextInputInfo info = webView->textInputInfo();
748 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
749 EXPECT_EQ(11, info.selectionStart);
750 EXPECT_EQ(11, info.selectionEnd);
751 EXPECT_EQ(6, info.compositionStart);
752 EXPECT_EQ(11, info.compositionEnd);
754 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
755 frame->setEditableSelectionOffsets(6, 6);
756 info = webView->textInputInfo();
757 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
758 EXPECT_EQ(6, info.selectionStart);
759 EXPECT_EQ(6, info.selectionEnd);
760 EXPECT_EQ(6, info.compositionStart);
761 EXPECT_EQ(11, info.compositionEnd);
763 frame->setEditableSelectionOffsets(8, 8);
764 info = webView->textInputInfo();
765 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
766 EXPECT_EQ(8, info.selectionStart);
767 EXPECT_EQ(8, info.selectionEnd);
768 EXPECT_EQ(6, info.compositionStart);
769 EXPECT_EQ(11, info.compositionEnd);
771 frame->setEditableSelectionOffsets(11, 11);
772 info = webView->textInputInfo();
773 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
774 EXPECT_EQ(11, info.selectionStart);
775 EXPECT_EQ(11, info.selectionEnd);
776 EXPECT_EQ(6, info.compositionStart);
777 EXPECT_EQ(11, info.compositionEnd);
779 frame->setEditableSelectionOffsets(6, 11);
780 info = webView->textInputInfo();
781 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
782 EXPECT_EQ(6, info.selectionStart);
783 EXPECT_EQ(11, info.selectionEnd);
784 EXPECT_EQ(6, info.compositionStart);
785 EXPECT_EQ(11, info.compositionEnd);
787 frame->setEditableSelectionOffsets(2, 2);
788 info = webView->textInputInfo();
789 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
790 EXPECT_EQ(2, info.selectionStart);
791 EXPECT_EQ(2, info.selectionEnd);
792 EXPECT_EQ(-1, info.compositionStart);
793 EXPECT_EQ(-1, info.compositionEnd);
796 TEST_F(WebViewTest, IsSelectionAnchorFirst)
798 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
799 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
800 WebFrame* frame = webView->mainFrame();
802 webView->setPageScaleFactorLimits(1, 1);
803 webView->setInitialFocus(false);
804 frame->setEditableSelectionOffsets(4, 10);
805 EXPECT_TRUE(webView->isSelectionAnchorFirst());
808 webView->selectionBounds(anchor, focus);
809 frame->selectRange(WebPoint(focus.x, focus.y), WebPoint(anchor.x, anchor.y));
810 EXPECT_FALSE(webView->isSelectionAnchorFirst());
813 TEST_F(WebViewTest, HistoryResetScrollAndScaleState)
815 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html"));
816 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "hello_world.html");
817 webViewImpl->resize(WebSize(640, 480));
818 webViewImpl->layout();
819 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
820 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
822 // Make the page scale and scroll with the given paremeters.
823 webViewImpl->setPageScaleFactor(2.0f);
824 webViewImpl->setMainFrameScrollOffset(WebPoint(116, 84));
825 EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
826 EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
827 EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
828 blink::LocalFrame* mainFrameLocal = toLocalFrame(webViewImpl->page()->mainFrame());
829 mainFrameLocal->loader().saveScrollState();
830 EXPECT_EQ(2.0f, mainFrameLocal->loader().currentItem()->pageScaleFactor());
831 EXPECT_EQ(116, mainFrameLocal->loader().currentItem()->scrollPoint().x());
832 EXPECT_EQ(84, mainFrameLocal->loader().currentItem()->scrollPoint().y());
834 // Confirm that resetting the page state resets the saved scroll position.
835 // The HistoryController treats a page scale factor of 0.0f as special and avoids
836 // restoring it to the WebView.
837 webViewImpl->resetScrollAndScaleState();
838 EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
839 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
840 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
841 EXPECT_EQ(0.0f, mainFrameLocal->loader().currentItem()->pageScaleFactor());
842 EXPECT_EQ(0, mainFrameLocal->loader().currentItem()->scrollPoint().x());
843 EXPECT_EQ(0, mainFrameLocal->loader().currentItem()->scrollPoint().y());
846 TEST_F(WebViewTest, BackForwardRestoreScroll)
848 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("back_forward_restore_scroll.html"));
849 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "back_forward_restore_scroll.html");
850 webViewImpl->resize(WebSize(640, 480));
851 webViewImpl->layout();
853 // Emulate a user scroll
854 webViewImpl->setMainFrameScrollOffset(WebPoint(0, 900));
855 blink::LocalFrame* mainFrameLocal = toLocalFrame(webViewImpl->page()->mainFrame());
856 RefPtr<blink::HistoryItem> item1 = mainFrameLocal->loader().currentItem();
859 mainFrameLocal->loader().load(blink::FrameLoadRequest(mainFrameLocal->document(), blink::ResourceRequest(mainFrameLocal->document()->completeURL("#a"))));
860 RefPtr<blink::HistoryItem> item2 = mainFrameLocal->loader().currentItem();
862 // Go back, then forward, then back again.
863 mainFrameLocal->loader().loadHistoryItem(item1.get(), blink::HistorySameDocumentLoad);
864 mainFrameLocal->loader().loadHistoryItem(item2.get(), blink::HistorySameDocumentLoad);
865 mainFrameLocal->loader().loadHistoryItem(item1.get(), blink::HistorySameDocumentLoad);
867 // Click a different anchor
868 mainFrameLocal->loader().load(blink::FrameLoadRequest(mainFrameLocal->document(), blink::ResourceRequest(mainFrameLocal->document()->completeURL("#b"))));
869 RefPtr<blink::HistoryItem> item3 = mainFrameLocal->loader().currentItem();
871 // Go back, then forward. The scroll position should be properly set on the forward navigation.
872 mainFrameLocal->loader().loadHistoryItem(item1.get(), blink::HistorySameDocumentLoad);
873 mainFrameLocal->loader().loadHistoryItem(item3.get(), blink::HistorySameDocumentLoad);
874 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
875 EXPECT_GT(webViewImpl->mainFrame()->scrollOffset().height, 2000);
878 class EnterFullscreenWebViewClient : public FrameTestHelpers::TestWebViewClient {
880 // WebViewClient methods
881 virtual bool enterFullScreen() { return true; }
882 virtual void exitFullScreen() { }
886 TEST_F(WebViewTest, EnterFullscreenResetScrollAndScaleState)
888 EnterFullscreenWebViewClient client;
889 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html"));
890 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "hello_world.html", true, 0, &client);
891 webViewImpl->resize(WebSize(640, 480));
892 webViewImpl->layout();
893 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
894 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
896 // Make the page scale and scroll with the given paremeters.
897 webViewImpl->setPageScaleFactor(2.0f);
898 webViewImpl->setMainFrameScrollOffset(WebPoint(116, 84));
899 EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
900 EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
901 EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
903 RefPtrWillBeRawPtr<blink::Element> element = static_cast<PassRefPtrWillBeRawPtr<blink::Element> >(webViewImpl->mainFrame()->document().body());
904 webViewImpl->enterFullScreenForElement(element.get());
905 webViewImpl->willEnterFullScreen();
906 webViewImpl->didEnterFullScreen();
908 // Page scale factor must be 1.0 during fullscreen for elements to be sized
910 EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
912 // Make sure fullscreen nesting doesn't disrupt scroll/scale saving.
913 RefPtrWillBeRawPtr<blink::Element> otherElement = static_cast<PassRefPtrWillBeRawPtr<blink::Element> >(webViewImpl->mainFrame()->document().head());
914 webViewImpl->enterFullScreenForElement(otherElement.get());
916 // Confirm that exiting fullscreen restores the parameters.
917 webViewImpl->willExitFullScreen();
918 webViewImpl->didExitFullScreen();
919 EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
920 EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
921 EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
923 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
926 class PrintWebViewClient : public FrameTestHelpers::TestWebViewClient {
929 : m_printCalled(false)
933 // WebViewClient methods
934 virtual void printPage(WebLocalFrame*) OVERRIDE
936 m_printCalled = true;
939 bool printCalled() const { return m_printCalled; }
946 TEST_F(WebViewTest, PrintWithXHRInFlight)
948 PrintWebViewClient client;
949 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("print_with_xhr_inflight.html"));
950 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "print_with_xhr_inflight.html", true, 0, &client);
952 ASSERT_EQ(blink::FrameStateComplete, toLocalFrame(webViewImpl->page()->mainFrame())->loader().state());
953 EXPECT_TRUE(client.printCalled());
954 m_webViewHelper.reset();
957 class DropTask : public WebThread::Task {
959 explicit DropTask(WebView* webView) : m_webView(webView)
963 virtual void run() OVERRIDE
965 const WebPoint clientPoint(0, 0);
966 const WebPoint screenPoint(0, 0);
967 m_webView->dragTargetDrop(clientPoint, screenPoint, 0);
971 WebView* const m_webView;
973 static void DragAndDropURL(WebViewImpl* webView, const std::string& url)
975 blink::WebDragData dragData;
976 dragData.initialize();
978 WebDragData::Item item;
979 item.storageType = WebDragData::Item::StorageTypeString;
980 item.stringType = "text/uri-list";
981 item.stringData = WebString::fromUTF8(url);
982 dragData.addItem(item);
984 const WebPoint clientPoint(0, 0);
985 const WebPoint screenPoint(0, 0);
986 webView->dragTargetDragEnter(dragData, clientPoint, screenPoint, blink::WebDragOperationCopy, 0);
987 Platform::current()->currentThread()->postTask(new DropTask(webView));
988 FrameTestHelpers::pumpPendingRequestsDoNotUse(webView->mainFrame());
991 TEST_F(WebViewTest, DragDropURL)
993 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "foo.html");
994 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "bar.html");
996 const std::string fooUrl = m_baseURL + "foo.html";
997 const std::string barUrl = m_baseURL + "bar.html";
999 WebViewImpl* webView = m_webViewHelper.initializeAndLoad(fooUrl);
1001 ASSERT_TRUE(webView);
1003 // Drag and drop barUrl and verify that we've navigated to it.
1004 DragAndDropURL(webView, barUrl);
1005 EXPECT_EQ(barUrl, webView->mainFrame()->document().url().string().utf8());
1007 // Drag and drop fooUrl and verify that we've navigated back to it.
1008 DragAndDropURL(webView, fooUrl);
1009 EXPECT_EQ(fooUrl, webView->mainFrame()->document().url().string().utf8());
1011 // Disable navigation on drag-and-drop.
1012 webView->settingsImpl()->setNavigateOnDragDrop(false);
1014 // Attempt to drag and drop to barUrl and verify that no navigation has occurred.
1015 DragAndDropURL(webView, barUrl);
1016 EXPECT_EQ(fooUrl, webView->mainFrame()->document().url().string().utf8());
1019 class ContentDetectorClient : public FrameTestHelpers::TestWebViewClient {
1021 ContentDetectorClient() { reset(); }
1023 virtual WebContentDetectionResult detectContentAround(const WebHitTestResult& hitTest) OVERRIDE
1025 m_contentDetectionRequested = true;
1026 return m_contentDetectionResult;
1029 virtual void scheduleContentIntent(const WebURL& url) OVERRIDE
1031 m_scheduledIntentURL = url;
1034 virtual void cancelScheduledContentIntents() OVERRIDE
1036 m_pendingIntentsCancelled = true;
1041 m_contentDetectionRequested = false;
1042 m_pendingIntentsCancelled = false;
1043 m_scheduledIntentURL = WebURL();
1044 m_contentDetectionResult = WebContentDetectionResult();
1047 bool contentDetectionRequested() const { return m_contentDetectionRequested; }
1048 bool pendingIntentsCancelled() const { return m_pendingIntentsCancelled; }
1049 const WebURL& scheduledIntentURL() const { return m_scheduledIntentURL; }
1050 void setContentDetectionResult(const WebContentDetectionResult& result) { m_contentDetectionResult = result; }
1053 bool m_contentDetectionRequested;
1054 bool m_pendingIntentsCancelled;
1055 WebURL m_scheduledIntentURL;
1056 WebContentDetectionResult m_contentDetectionResult;
1059 static bool tapElementById(WebView* webView, WebInputEvent::Type type, const WebString& id)
1062 RefPtrWillBeRawPtr<blink::Element> element = static_cast<PassRefPtrWillBeRawPtr<blink::Element> >(webView->mainFrame()->document().getElementById(id));
1066 element->scrollIntoViewIfNeeded();
1067 blink::IntPoint center = element->screenRect().center();
1069 WebGestureEvent event;
1071 event.x = center.x();
1072 event.y = center.y();
1074 webView->handleInputEvent(event);
1079 TEST_F(WebViewTest, DetectContentAroundPosition)
1081 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_listeners.html"));
1083 ContentDetectorClient client;
1084 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_listeners.html", true, 0, &client);
1085 webView->resize(WebSize(500, 300));
1089 WebString clickListener = WebString::fromUTF8("clickListener");
1090 WebString touchstartListener = WebString::fromUTF8("touchstartListener");
1091 WebString mousedownListener = WebString::fromUTF8("mousedownListener");
1092 WebString noListener = WebString::fromUTF8("noListener");
1093 WebString link = WebString::fromUTF8("link");
1095 // Ensure content detection is not requested for nodes listening to click,
1096 // mouse or touch events when we do simple taps.
1097 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, clickListener));
1098 EXPECT_FALSE(client.contentDetectionRequested());
1101 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, touchstartListener));
1102 EXPECT_FALSE(client.contentDetectionRequested());
1105 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, mousedownListener));
1106 EXPECT_FALSE(client.contentDetectionRequested());
1109 // Content detection should work normally without these event listeners.
1110 // The click listener in the body should be ignored as a special case.
1111 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
1112 EXPECT_TRUE(client.contentDetectionRequested());
1113 EXPECT_FALSE(client.scheduledIntentURL().isValid());
1115 WebURL intentURL = toKURL(m_baseURL);
1116 client.setContentDetectionResult(WebContentDetectionResult(WebRange(), WebString(), intentURL));
1117 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
1118 EXPECT_TRUE(client.scheduledIntentURL() == intentURL);
1120 // Tapping elsewhere should cancel the scheduled intent.
1121 WebGestureEvent event;
1122 event.type = WebInputEvent::GestureTap;
1123 webView->handleInputEvent(event);
1125 EXPECT_TRUE(client.pendingIntentsCancelled());
1127 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
1130 TEST_F(WebViewTest, ClientTapHandling)
1132 TapHandlingWebViewClient client;
1134 WebView* webView = m_webViewHelper.initializeAndLoad("about:blank", true, 0, &client);
1135 WebGestureEvent event;
1136 event.type = WebInputEvent::GestureTap;
1139 webView->handleInputEvent(event);
1141 EXPECT_EQ(3, client.tapX());
1142 EXPECT_EQ(8, client.tapY());
1144 event.type = WebInputEvent::GestureLongPress;
1147 webView->handleInputEvent(event);
1149 EXPECT_EQ(25, client.longpressX());
1150 EXPECT_EQ(7, client.longpressY());
1152 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
1156 TEST_F(WebViewTest, LongPressSelection)
1158 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
1160 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
1161 webView->resize(WebSize(500, 300));
1165 WebString target = WebString::fromUTF8("target");
1166 WebString onselectstartfalse = WebString::fromUTF8("onselectstartfalse");
1167 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1169 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, onselectstartfalse));
1170 EXPECT_EQ("", std::string(frame->selectionAsText().utf8().data()));
1171 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, target));
1172 EXPECT_EQ("testword", std::string(frame->selectionAsText().utf8().data()));
1175 TEST_F(WebViewTest, BlinkCaretOnTypingAfterLongPress)
1177 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("blink_caret_on_typing_after_long_press.html"));
1179 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "blink_caret_on_typing_after_long_press.html", true);
1180 webView->resize(WebSize(640, 480));
1184 WebString target = WebString::fromUTF8("target");
1185 WebLocalFrameImpl* mainFrame = toWebLocalFrameImpl(webView->mainFrame());
1187 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, target));
1188 EXPECT_TRUE(mainFrame->frame()->selection().isCaretBlinkingSuspended());
1190 WebKeyboardEvent keyEvent;
1191 keyEvent.type = WebInputEvent::RawKeyDown;
1192 webView->handleInputEvent(keyEvent);
1193 keyEvent.type = WebInputEvent::KeyUp;
1194 webView->handleInputEvent(keyEvent);
1195 EXPECT_FALSE(mainFrame->frame()->selection().isCaretBlinkingSuspended());
1199 TEST_F(WebViewTest, SelectionOnDisabledInput)
1201 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_disabled.html"));
1202 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "selection_disabled.html", true);
1203 webView->resize(WebSize(640, 480));
1207 std::string testWord = "This text should be selected.";
1209 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1210 EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));
1214 EXPECT_TRUE(toWebViewImpl(webView)->caretOrSelectionRange(&location, &length));
1215 EXPECT_EQ(location, 0UL);
1216 EXPECT_EQ(length, testWord.length());
1219 TEST_F(WebViewTest, SelectionOnReadOnlyInput)
1221 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_readonly.html"));
1222 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "selection_readonly.html", true);
1223 webView->resize(WebSize(640, 480));
1227 std::string testWord = "This text should be selected.";
1229 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1230 EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));
1234 EXPECT_TRUE(toWebViewImpl(webView)->caretOrSelectionRange(&location, &length));
1235 EXPECT_EQ(location, 0UL);
1236 EXPECT_EQ(length, testWord.length());
1239 static void configueCompositingWebView(WebSettings* settings)
1241 settings->setAcceleratedCompositingEnabled(true);
1242 settings->setAcceleratedCompositingForFixedPositionEnabled(true);
1243 settings->setAcceleratedCompositingForOverflowScrollEnabled(true);
1244 settings->setCompositedScrollingForFramesEnabled(true);
1247 TEST_F(WebViewTest, ShowPressOnTransformedLink)
1249 OwnPtr<FrameTestHelpers::TestWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FrameTestHelpers::TestWebViewClient());
1250 FrameTestHelpers::WebViewHelper webViewHelper;
1251 WebViewImpl* webViewImpl = webViewHelper.initialize(true, 0, fakeCompositingWebViewClient.get(), &configueCompositingWebView);
1253 int pageWidth = 640;
1254 int pageHeight = 480;
1255 webViewImpl->resize(WebSize(pageWidth, pageHeight));
1257 WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
1258 FrameTestHelpers::loadHTMLString(webViewImpl->mainFrame(), "<a href='http://www.test.com' style='position: absolute; left: 20px; top: 20px; width: 200px; -webkit-transform:translateZ(0);'>A link to highlight</a>", baseURL);
1260 WebGestureEvent event;
1261 event.type = WebInputEvent::GestureShowPress;
1265 // Just make sure we don't hit any asserts.
1266 webViewImpl->handleInputEvent(event);
1269 class MockAutofillClient : public WebAutofillClient {
1271 MockAutofillClient()
1272 : m_ignoreTextChanges(false)
1273 , m_textChangesWhileIgnored(0)
1274 , m_textChangesWhileNotIgnored(0)
1275 , m_userGestureNotificationsCount(0) { }
1277 virtual ~MockAutofillClient() { }
1279 virtual void setIgnoreTextChanges(bool ignore) OVERRIDE { m_ignoreTextChanges = ignore; }
1280 virtual void textFieldDidChange(const WebFormControlElement&) OVERRIDE
1282 if (m_ignoreTextChanges)
1283 ++m_textChangesWhileIgnored;
1285 ++m_textChangesWhileNotIgnored;
1287 virtual void firstUserGestureObserved() OVERRIDE { ++m_userGestureNotificationsCount; }
1289 void clearChangeCounts()
1291 m_textChangesWhileIgnored = 0;
1292 m_textChangesWhileNotIgnored = 0;
1295 int textChangesWhileIgnored() { return m_textChangesWhileIgnored; }
1296 int textChangesWhileNotIgnored() { return m_textChangesWhileNotIgnored; }
1297 int getUserGestureNotificationsCount() { return m_userGestureNotificationsCount; }
1300 bool m_ignoreTextChanges;
1301 int m_textChangesWhileIgnored;
1302 int m_textChangesWhileNotIgnored;
1303 int m_userGestureNotificationsCount;
1307 TEST_F(WebViewTest, LosingFocusDoesNotTriggerAutofillTextChange)
1309 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
1310 MockAutofillClient client;
1311 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
1312 webView->setAutofillClient(&client);
1313 webView->setInitialFocus(false);
1315 // Set up a composition that needs to be committed.
1316 WebVector<WebCompositionUnderline> emptyUnderlines;
1317 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1318 frame->setEditableSelectionOffsets(4, 10);
1319 frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
1320 WebTextInputInfo info = webView->textInputInfo();
1321 EXPECT_EQ(4, info.selectionStart);
1322 EXPECT_EQ(10, info.selectionEnd);
1323 EXPECT_EQ(8, info.compositionStart);
1324 EXPECT_EQ(12, info.compositionEnd);
1326 // Clear the focus and track that the subsequent composition commit does not trigger a
1327 // text changed notification for autofill.
1328 client.clearChangeCounts();
1329 webView->setFocus(false);
1330 EXPECT_EQ(1, client.textChangesWhileIgnored());
1331 EXPECT_EQ(0, client.textChangesWhileNotIgnored());
1333 webView->setAutofillClient(0);
1336 TEST_F(WebViewTest, ConfirmCompositionTriggersAutofillTextChange)
1338 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
1339 MockAutofillClient client;
1340 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
1341 webView->setAutofillClient(&client);
1342 webView->setInitialFocus(false);
1344 // Set up a composition that needs to be committed.
1345 std::string compositionText("testingtext");
1347 WebVector<WebCompositionUnderline> emptyUnderlines;
1348 webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 0, compositionText.length());
1350 WebTextInputInfo info = webView->textInputInfo();
1351 EXPECT_EQ(0, info.selectionStart);
1352 EXPECT_EQ((int) compositionText.length(), info.selectionEnd);
1353 EXPECT_EQ(0, info.compositionStart);
1354 EXPECT_EQ((int) compositionText.length(), info.compositionEnd);
1356 client.clearChangeCounts();
1357 webView->confirmComposition();
1358 EXPECT_EQ(0, client.textChangesWhileIgnored());
1359 EXPECT_EQ(1, client.textChangesWhileNotIgnored());
1361 webView->setAutofillClient(0);
1364 TEST_F(WebViewTest, SetCompositionFromExistingTextTriggersAutofillTextChange)
1366 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
1367 MockAutofillClient client;
1368 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html", true);
1369 webView->setAutofillClient(&client);
1370 webView->setInitialFocus(false);
1372 WebVector<WebCompositionUnderline> emptyUnderlines;
1374 client.clearChangeCounts();
1375 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1376 frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
1378 WebTextInputInfo info = webView->textInputInfo();
1379 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
1380 EXPECT_EQ(8, info.compositionStart);
1381 EXPECT_EQ(12, info.compositionEnd);
1383 EXPECT_EQ(0, client.textChangesWhileIgnored());
1384 EXPECT_EQ(0, client.textChangesWhileNotIgnored());
1386 WebDocument document = webView->mainFrame()->document();
1387 EXPECT_EQ(WebString::fromUTF8("none"), document.getElementById("inputEvent").firstChild().nodeValue());
1389 webView->setAutofillClient(0);
1392 TEST_F(WebViewTest, ShadowRoot)
1394 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("shadow_dom_test.html"));
1395 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "shadow_dom_test.html", true);
1397 WebDocument document = webViewImpl->mainFrame()->document();
1399 WebElement elementWithShadowRoot = document.getElementById("shadowroot");
1400 EXPECT_FALSE(elementWithShadowRoot.isNull());
1401 WebNode shadowRoot = elementWithShadowRoot.shadowRoot();
1402 EXPECT_FALSE(shadowRoot.isNull());
1405 WebElement elementWithoutShadowRoot = document.getElementById("noshadowroot");
1406 EXPECT_FALSE(elementWithoutShadowRoot.isNull());
1407 WebNode shadowRoot = elementWithoutShadowRoot.shadowRoot();
1408 EXPECT_TRUE(shadowRoot.isNull());
1412 class ViewCreatingWebViewClient : public FrameTestHelpers::TestWebViewClient {
1414 ViewCreatingWebViewClient()
1415 : m_didFocusCalled(false)
1419 // WebViewClient methods
1420 virtual WebView* createView(WebLocalFrame*, const WebURLRequest&, const WebWindowFeatures&, const WebString& name, WebNavigationPolicy, bool) OVERRIDE
1422 return m_webViewHelper.initialize(true, 0, 0);
1425 // WebWidgetClient methods
1426 virtual void didFocus() OVERRIDE
1428 m_didFocusCalled = true;
1431 bool didFocusCalled() const { return m_didFocusCalled; }
1432 WebView* createdWebView() const { return m_webViewHelper.webView(); }
1435 FrameTestHelpers::WebViewHelper m_webViewHelper;
1436 bool m_didFocusCalled;
1439 TEST_F(WebViewTest, FocusExistingFrameOnNavigate)
1441 ViewCreatingWebViewClient client;
1442 FrameTestHelpers::WebViewHelper m_webViewHelper;
1443 WebViewImpl* webViewImpl = m_webViewHelper.initialize(true, 0, &client);
1444 webViewImpl->page()->settings().setJavaScriptCanOpenWindowsAutomatically(true);
1445 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame());
1446 frame->setName("_start");
1448 // Make a request that will open a new window
1449 WebURLRequest webURLRequest;
1450 webURLRequest.initialize();
1451 blink::FrameLoadRequest request(0, webURLRequest.toResourceRequest(), "_blank");
1452 toLocalFrame(webViewImpl->page()->mainFrame())->loader().load(request);
1453 ASSERT_TRUE(client.createdWebView());
1454 EXPECT_FALSE(client.didFocusCalled());
1456 // Make a request from the new window that will navigate the original window. The original window should be focused.
1457 WebURLRequest webURLRequestWithTargetStart;
1458 webURLRequestWithTargetStart.initialize();
1459 blink::FrameLoadRequest requestWithTargetStart(0, webURLRequestWithTargetStart.toResourceRequest(), "_start");
1460 toLocalFrame(toWebViewImpl(client.createdWebView())->page()->mainFrame())->loader().load(requestWithTargetStart);
1461 EXPECT_TRUE(client.didFocusCalled());
1463 m_webViewHelper.reset(); // Remove dependency on locally scoped client.
1466 TEST_F(WebViewTest, DispatchesFocusOutFocusInOnViewToggleFocus)
1468 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "focusout_focusin_events.html");
1469 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "focusout_focusin_events.html", true, 0);
1471 webView->setFocus(true);
1472 webView->setFocus(false);
1473 webView->setFocus(true);
1475 WebElement element = webView->mainFrame()->document().getElementById("message");
1476 EXPECT_STREQ("focusoutfocusin", element.innerText().utf8().data());
1479 TEST_F(WebViewTest, DispatchesDomFocusOutDomFocusInOnViewToggleFocus)
1481 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "domfocusout_domfocusin_events.html");
1482 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "domfocusout_domfocusin_events.html", true, 0);
1484 webView->setFocus(true);
1485 webView->setFocus(false);
1486 webView->setFocus(true);
1488 WebElement element = webView->mainFrame()->document().getElementById("message");
1489 EXPECT_STREQ("DOMFocusOutDOMFocusIn", element.innerText().utf8().data());
1492 #if !ENABLE(INPUT_MULTIPLE_FIELDS_UI)
1493 static void openDateTimeChooser(WebView* webView, blink::HTMLInputElement* inputElement)
1495 inputElement->focus();
1497 WebKeyboardEvent keyEvent;
1498 keyEvent.windowsKeyCode = blink::VKEY_SPACE;
1499 keyEvent.type = WebInputEvent::RawKeyDown;
1500 keyEvent.setKeyIdentifierFromWindowsKeyCode();
1501 webView->handleInputEvent(keyEvent);
1503 keyEvent.type = WebInputEvent::KeyUp;
1504 webView->handleInputEvent(keyEvent);
1507 TEST_F(WebViewTest, ChooseValueFromDateTimeChooser)
1509 DateTimeChooserWebViewClient client;
1510 std::string url = m_baseURL + "date_time_chooser.html";
1511 URLTestHelpers::registerMockedURLLoad(toKURL(url), "date_time_chooser.html");
1512 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
1514 blink::Document* document = webViewImpl->mainFrameImpl()->frame()->document();
1516 blink::HTMLInputElement* inputElement;
1518 inputElement = toHTMLInputElement(document->getElementById("date"));
1519 openDateTimeChooser(webViewImpl, inputElement);
1520 client.chooserCompletion()->didChooseValue(0);
1521 client.clearChooserCompletion();
1522 EXPECT_STREQ("1970-01-01", inputElement->value().utf8().data());
1524 openDateTimeChooser(webViewImpl, inputElement);
1525 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1526 client.clearChooserCompletion();
1527 EXPECT_STREQ("", inputElement->value().utf8().data());
1529 inputElement = toHTMLInputElement(document->getElementById("datetimelocal"));
1530 openDateTimeChooser(webViewImpl, inputElement);
1531 client.chooserCompletion()->didChooseValue(0);
1532 client.clearChooserCompletion();
1533 EXPECT_STREQ("1970-01-01T00:00", inputElement->value().utf8().data());
1535 openDateTimeChooser(webViewImpl, inputElement);
1536 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1537 client.clearChooserCompletion();
1538 EXPECT_STREQ("", inputElement->value().utf8().data());
1540 inputElement = toHTMLInputElement(document->getElementById("month"));
1541 openDateTimeChooser(webViewImpl, inputElement);
1542 client.chooserCompletion()->didChooseValue(0);
1543 client.clearChooserCompletion();
1544 EXPECT_STREQ("1970-01", inputElement->value().utf8().data());
1546 openDateTimeChooser(webViewImpl, inputElement);
1547 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1548 client.clearChooserCompletion();
1549 EXPECT_STREQ("", inputElement->value().utf8().data());
1551 inputElement = toHTMLInputElement(document->getElementById("time"));
1552 openDateTimeChooser(webViewImpl, inputElement);
1553 client.chooserCompletion()->didChooseValue(0);
1554 client.clearChooserCompletion();
1555 EXPECT_STREQ("00:00", inputElement->value().utf8().data());
1557 openDateTimeChooser(webViewImpl, inputElement);
1558 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1559 client.clearChooserCompletion();
1560 EXPECT_STREQ("", inputElement->value().utf8().data());
1562 inputElement = toHTMLInputElement(document->getElementById("week"));
1563 openDateTimeChooser(webViewImpl, inputElement);
1564 client.chooserCompletion()->didChooseValue(0);
1565 client.clearChooserCompletion();
1566 EXPECT_STREQ("1970-W01", inputElement->value().utf8().data());
1568 openDateTimeChooser(webViewImpl, inputElement);
1569 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1570 client.clearChooserCompletion();
1571 EXPECT_STREQ("", inputElement->value().utf8().data());
1573 // Clear the WebViewClient from the webViewHelper to avoid use-after-free in the
1574 // WebViewHelper destructor.
1575 m_webViewHelper.reset();
1579 TEST_F(WebViewTest, DispatchesFocusBlurOnViewToggle)
1581 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "focus_blur_events.html");
1582 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "focus_blur_events.html", true, 0);
1584 webView->setFocus(true);
1585 webView->setFocus(false);
1586 webView->setFocus(true);
1588 WebElement element = webView->mainFrame()->document().getElementById("message");
1589 // Expect not to see duplication of events.
1590 EXPECT_STREQ("blurfocus", element.innerText().utf8().data());
1593 TEST_F(WebViewTest, SmartClipData)
1595 static const char* kExpectedClipText = "\nPrice 10,000,000won";
1596 static const char* kExpectedClipHtml =
1597 "<div id=\"div4\" style=\"padding: 10px; margin: 10px; border: 2px "
1598 "solid rgb(135, 206, 235); float: left; width: 190px; height: 30px; "
1599 "color: rgb(0, 0, 0); font-family: myahem; font-size: 8px; font-style: "
1600 "normal; font-variant: normal; font-weight: normal; letter-spacing: "
1601 "normal; line-height: normal; orphans: auto; text-align: start; "
1602 "text-indent: 0px; text-transform: none; white-space: normal; widows: "
1603 "auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;\">Air "
1604 "conditioner</div><div id=\"div5\" style=\"padding: 10px; margin: "
1605 "10px; border: 2px solid rgb(135, 206, 235); float: left; width: "
1606 "190px; height: 30px; color: rgb(0, 0, 0); font-family: myahem; "
1607 "font-size: 8px; font-style: normal; font-variant: normal; "
1608 "font-weight: normal; letter-spacing: normal; line-height: normal; "
1609 "orphans: auto; text-align: start; text-indent: 0px; text-transform: "
1610 "none; white-space: normal; widows: auto; word-spacing: 0px; "
1611 "-webkit-text-stroke-width: 0px;\">Price 10,000,000won</div>";
1615 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
1616 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("smartclip.html"));
1617 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "smartclip.html");
1618 webView->setPageScaleFactorLimits(1, 1);
1619 webView->resize(WebSize(500, 500));
1621 WebRect cropRect(300, 125, 100, 50);
1622 webView->extractSmartClipData(cropRect, clipText, clipHtml, clipRect);
1623 EXPECT_STREQ(kExpectedClipText, clipText.utf8().c_str());
1624 EXPECT_STREQ(kExpectedClipHtml, clipHtml.utf8().c_str());
1627 class CreateChildCounterFrameClient : public FrameTestHelpers::TestWebFrameClient {
1629 CreateChildCounterFrameClient() : m_count(0) { }
1630 virtual WebFrame* createChildFrame(WebLocalFrame* parent, const WebString& frameName) OVERRIDE;
1632 int count() const { return m_count; }
1638 WebFrame* CreateChildCounterFrameClient::createChildFrame(WebLocalFrame* parent, const WebString& frameName)
1641 return TestWebFrameClient::createChildFrame(parent, frameName);
1644 TEST_F(WebViewTest, AddFrameInCloseUnload)
1646 CreateChildCounterFrameClient frameClient;
1647 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1648 m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
1649 m_webViewHelper.reset();
1650 EXPECT_EQ(0, frameClient.count());
1653 TEST_F(WebViewTest, AddFrameInCloseURLUnload)
1655 CreateChildCounterFrameClient frameClient;
1656 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1657 m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
1658 m_webViewHelper.webViewImpl()->mainFrame()->dispatchUnloadEvent();
1659 EXPECT_EQ(0, frameClient.count());
1660 m_webViewHelper.reset();
1663 TEST_F(WebViewTest, AddFrameInNavigateUnload)
1665 CreateChildCounterFrameClient frameClient;
1666 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1667 m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
1668 FrameTestHelpers::loadFrame(m_webViewHelper.webView()->mainFrame(), "about:blank");
1669 EXPECT_EQ(0, frameClient.count());
1670 m_webViewHelper.reset();
1673 TEST_F(WebViewTest, AddFrameInChildInNavigateUnload)
1675 CreateChildCounterFrameClient frameClient;
1676 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload_wrapper.html"));
1677 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1678 m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload_wrapper.html", true, &frameClient);
1679 FrameTestHelpers::loadFrame(m_webViewHelper.webView()->mainFrame(), "about:blank");
1680 EXPECT_EQ(1, frameClient.count());
1681 m_webViewHelper.reset();
1684 class TouchEventHandlerWebViewClient : public FrameTestHelpers::TestWebViewClient {
1686 // WebWidgetClient methods
1687 virtual void hasTouchEventHandlers(bool state) OVERRIDE
1689 m_hasTouchEventHandlerCount[state]++;
1693 TouchEventHandlerWebViewClient() : m_hasTouchEventHandlerCount()
1697 int getAndResetHasTouchEventHandlerCallCount(bool state)
1699 int value = m_hasTouchEventHandlerCount[state];
1700 m_hasTouchEventHandlerCount[state] = 0;
1705 int m_hasTouchEventHandlerCount[2];
1708 // This test verifies that WebWidgetClient::hasTouchEventHandlers is called
1709 // accordingly for various calls to EventHandlerRegistry::did{Add|Remove|
1710 // RemoveAll}EventHandler(..., TouchEvent). Verifying that those calls are made
1711 // correctly is the job of LayoutTests/fast/events/event-handler-count.html.
1712 TEST_F(WebViewTest, HasTouchEventHandlers)
1714 TouchEventHandlerWebViewClient client;
1715 std::string url = m_baseURL + "has_touch_event_handlers.html";
1716 URLTestHelpers::registerMockedURLLoad(toKURL(url), "has_touch_event_handlers.html");
1717 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
1718 const blink::EventHandlerRegistry::EventHandlerClass touchEvent = blink::EventHandlerRegistry::TouchEvent;
1720 // The page is initialized with at least one no-handlers call.
1721 // In practice we get two such calls because WebViewHelper::initializeAndLoad first
1722 // initializes and empty frame, and then loads a document into it, so there are two
1723 // FrameLoader::commitProvisionalLoad calls.
1724 EXPECT_GE(client.getAndResetHasTouchEventHandlerCallCount(false), 1);
1725 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1727 // Adding the first document handler results in a has-handlers call.
1728 blink::Document* document = webViewImpl->mainFrameImpl()->frame()->document();
1729 blink::EventHandlerRegistry* registry = &document->frameHost()->eventHandlerRegistry();
1730 registry->didAddEventHandler(*document, touchEvent);
1731 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1732 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1734 // Adding another handler has no effect.
1735 registry->didAddEventHandler(*document, touchEvent);
1736 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1737 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1739 // Removing the duplicate handler has no effect.
1740 registry->didRemoveEventHandler(*document, touchEvent);
1741 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1742 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1744 // Removing the final handler results in a no-handlers call.
1745 registry->didRemoveEventHandler(*document, touchEvent);
1746 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1747 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1749 // Adding a handler on a div results in a has-handlers call.
1750 blink::Element* parentDiv = document->getElementById("parentdiv");
1752 registry->didAddEventHandler(*parentDiv, touchEvent);
1753 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1754 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1756 // Adding a duplicate handler on the div, clearing all document handlers
1757 // (of which there are none) and removing the extra handler on the div
1758 // all have no effect.
1759 registry->didAddEventHandler(*parentDiv, touchEvent);
1760 registry->didRemoveAllEventHandlers(*document);
1761 registry->didRemoveEventHandler(*parentDiv, touchEvent);
1762 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1763 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1765 // Removing the final handler on the div results in a no-handlers call.
1766 registry->didRemoveEventHandler(*parentDiv, touchEvent);
1767 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1768 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1770 // Adding two handlers then clearing them in a single call results in a
1771 // has-handlers then no-handlers call.
1772 registry->didAddEventHandler(*parentDiv, touchEvent);
1773 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1774 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1775 registry->didAddEventHandler(*parentDiv, touchEvent);
1776 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1777 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1778 registry->didRemoveAllEventHandlers(*parentDiv);
1779 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1780 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1782 // Adding a handler inside of a child iframe results in a has-handlers call.
1783 blink::Element* childFrame = document->getElementById("childframe");
1785 blink::Document* childDocument = toHTMLIFrameElement(childFrame)->contentDocument();
1786 blink::Element* childDiv = childDocument->getElementById("childdiv");
1788 registry->didAddEventHandler(*childDiv, touchEvent);
1789 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1790 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1792 // Adding and clearing handlers in the parent doc or elsewhere in the child doc
1794 registry->didAddEventHandler(*document, touchEvent);
1795 registry->didAddEventHandler(*childFrame, touchEvent);
1796 registry->didAddEventHandler(*childDocument, touchEvent);
1797 registry->didRemoveAllEventHandlers(*document);
1798 registry->didRemoveAllEventHandlers(*childFrame);
1799 registry->didRemoveAllEventHandlers(*childDocument);
1800 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1801 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1803 // Removing the final handler inside the child frame results in a no-handlers call.
1804 registry->didRemoveAllEventHandlers(*childDiv);
1805 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1806 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1808 // Adding a handler inside the child frame results in a has-handlers call.
1809 registry->didAddEventHandler(*childDocument, touchEvent);
1810 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1811 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1813 // Adding a handler in the parent document and removing the one in the frame
1815 registry->didAddEventHandler(*childFrame, touchEvent);
1816 registry->didRemoveEventHandler(*childDocument, touchEvent);
1817 registry->didRemoveAllEventHandlers(*childDocument);
1818 registry->didRemoveAllEventHandlers(*document);
1819 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1820 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1822 // Now removing the handler in the parent document results in a no-handlers call.
1823 registry->didRemoveEventHandler(*childFrame, touchEvent);
1824 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1825 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1827 // Free the webView before the TouchEventHandlerWebViewClient gets freed.
1828 m_webViewHelper.reset();
1831 // This test checks that deleting nodes which have only non-JS-registered touch
1832 // handlers also removes them from the event handler registry. Note that this
1833 // is different from detaching and re-attaching the same node, which is covered
1834 // by layout tests under fast/events/.
1835 TEST_F(WebViewTest, DeleteElementWithRegisteredHandler)
1837 std::string url = m_baseURL + "simple_div.html";
1838 URLTestHelpers::registerMockedURLLoad(toKURL(url), "simple_div.html");
1839 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true);
1841 RefPtrWillBePersistent<blink::Document> document = webViewImpl->mainFrameImpl()->frame()->document();
1842 blink::Element* div = document->getElementById("div");
1843 blink::EventHandlerRegistry& registry = document->frameHost()->eventHandlerRegistry();
1845 registry.didAddEventHandler(*div, blink::EventHandlerRegistry::ScrollEvent);
1846 EXPECT_TRUE(registry.hasEventHandlers(blink::EventHandlerRegistry::ScrollEvent));
1848 blink::TrackExceptionState exceptionState;
1849 div->remove(exceptionState);
1851 // For oilpan we have to force a GC to ensure the event handlers have been removed when
1852 // checking below. We do a precise GC (collectAllGarbage does not scan the stack)
1853 // to ensure the div element dies. This is also why the Document is in a Persistent
1854 // since we want that to stay around.
1855 Heap::collectAllGarbage();
1857 EXPECT_FALSE(registry.hasEventHandlers(blink::EventHandlerRegistry::ScrollEvent));
1860 static WebRect ExpectedRootBounds(blink::Document* document, float scaleFactor)
1862 blink::Element* element = document->getElementById("root");
1864 element = document->getElementById("target");
1865 if (element->hasTagName(blink::HTMLNames::iframeTag))
1866 return ExpectedRootBounds(toHTMLIFrameElement(element)->contentDocument(), scaleFactor);
1868 blink::IntRect boundingBox;
1869 if (element->hasTagName(blink::HTMLNames::htmlTag))
1870 boundingBox = blink::IntRect(blink::IntPoint(0, 0), document->frame()->view()->contentsSize());
1872 boundingBox = element->pixelSnappedBoundingBox();
1873 boundingBox = document->frame()->view()->contentsToWindow(boundingBox);
1874 boundingBox.scale(scaleFactor);
1878 void WebViewTest::testSelectionRootBounds(const char* htmlFile, float pageScaleFactor)
1880 std::string url = m_baseURL + htmlFile;
1882 WebView* webView = m_webViewHelper.initializeAndLoad(url, true);
1883 webView->resize(WebSize(640, 480));
1884 webView->setPageScaleFactor(pageScaleFactor);
1888 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1889 EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
1890 blink::HTMLDocument* document = blink::toHTMLDocument(frame->frame()->document());
1892 WebRect expectedRootBounds = ExpectedRootBounds(document, webView->pageScaleFactor());
1893 WebRect actualRootBounds;
1894 webView->getSelectionRootBounds(actualRootBounds);
1895 ASSERT_EQ(expectedRootBounds, actualRootBounds);
1897 WebRect anchor, focus;
1898 webView->selectionBounds(anchor, focus);
1899 blink::IntRect expectedIntRect = expectedRootBounds;
1900 ASSERT_TRUE(expectedIntRect.contains(anchor));
1901 // The "overflow" tests have the focus boundary outside of the element box.
1902 ASSERT_EQ(url.find("overflow") == std::string::npos, expectedIntRect.contains(focus));
1905 TEST_F(WebViewTest, GetSelectionRootBounds)
1907 // Register all the pages we will be using.
1908 registerMockedHttpURLLoad("select_range_basic.html");
1909 registerMockedHttpURLLoad("select_range_div_editable.html");
1910 registerMockedHttpURLLoad("select_range_scroll.html");
1911 registerMockedHttpURLLoad("select_range_span_editable.html");
1912 registerMockedHttpURLLoad("select_range_input.html");
1913 registerMockedHttpURLLoad("select_range_input_overflow.html");
1914 registerMockedHttpURLLoad("select_range_textarea.html");
1915 registerMockedHttpURLLoad("select_range_textarea_overflow.html");
1916 registerMockedHttpURLLoad("select_range_iframe.html");
1917 registerMockedHttpURLLoad("select_range_iframe_div_editable.html");
1918 registerMockedHttpURLLoad("select_range_iframe_scroll.html");
1919 registerMockedHttpURLLoad("select_range_iframe_span_editable.html");
1920 registerMockedHttpURLLoad("select_range_iframe_input.html");
1921 registerMockedHttpURLLoad("select_range_iframe_input_overflow.html");
1922 registerMockedHttpURLLoad("select_range_iframe_textarea.html");
1923 registerMockedHttpURLLoad("select_range_iframe_textarea_overflow.html");
1925 // Test with simple pages.
1926 testSelectionRootBounds("select_range_basic.html", 1.0f);
1927 testSelectionRootBounds("select_range_div_editable.html", 1.0f);
1928 testSelectionRootBounds("select_range_scroll.html", 1.0f);
1929 testSelectionRootBounds("select_range_span_editable.html", 1.0f);
1930 testSelectionRootBounds("select_range_input.html", 1.0f);
1931 testSelectionRootBounds("select_range_input_overflow.html", 1.0f);
1932 testSelectionRootBounds("select_range_textarea.html", 1.0f);
1933 testSelectionRootBounds("select_range_textarea_overflow.html", 1.0f);
1935 // Test with the same pages as above in iframes.
1936 testSelectionRootBounds("select_range_iframe.html", 1.0f);
1937 testSelectionRootBounds("select_range_iframe_div_editable.html", 1.0f);
1938 testSelectionRootBounds("select_range_iframe_scroll.html", 1.0f);
1939 testSelectionRootBounds("select_range_iframe_span_editable.html", 1.0f);
1940 testSelectionRootBounds("select_range_iframe_input.html", 1.0f);
1941 testSelectionRootBounds("select_range_iframe_input_overflow.html", 1.0f);
1942 testSelectionRootBounds("select_range_iframe_textarea.html", 1.0f);
1943 testSelectionRootBounds("select_range_iframe_textarea_overflow.html", 1.0f);
1945 // Basic page with scale factor.
1946 testSelectionRootBounds("select_range_basic.html", 0.0f);
1947 testSelectionRootBounds("select_range_basic.html", 0.1f);
1948 testSelectionRootBounds("select_range_basic.html", 1.5f);
1949 testSelectionRootBounds("select_range_basic.html", 2.0f);
1952 TEST_F(WebViewTest, GetSelectionRootBoundsBrokenHeight)
1954 WebSize contentSize = WebSize(640, 480);
1956 registerMockedHttpURLLoad("select_range_basic_broken_height.html");
1958 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "select_range_basic_broken_height.html", true);
1959 webView->resize(contentSize);
1960 webView->setPageScaleFactor(1.0f, WebPoint(0, 0));
1964 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
1965 EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
1967 WebRect expectedRootBounds = WebRect(0, 0, contentSize.width, contentSize.height);
1968 WebRect actualRootBounds;
1969 webView->getSelectionRootBounds(actualRootBounds);
1970 ASSERT_EQ(expectedRootBounds, actualRootBounds);
1973 class NonUserInputTextUpdateWebViewClient : public FrameTestHelpers::TestWebViewClient {
1975 NonUserInputTextUpdateWebViewClient() : m_textIsUpdated(false) { }
1977 // WebWidgetClient methods
1978 virtual void didUpdateTextOfFocusedElementByNonUserInput() OVERRIDE
1980 m_textIsUpdated = true;
1985 m_textIsUpdated = false;
1988 bool textIsUpdated() const
1990 return m_textIsUpdated;
1994 int m_textIsUpdated;
1997 // This test verifies that WebWidgetClient::didUpdateTextOfFocusedElementByNonUserInput is
1998 // called iff value of a focused element is modified via script.
1999 TEST_F(WebViewTest, NonUserInputTextUpdate)
2001 NonUserInputTextUpdateWebViewClient client;
2002 std::string url = m_baseURL + "non_user_input_text_update.html";
2003 URLTestHelpers::registerMockedURLLoad(toKURL(url), "non_user_input_text_update.html");
2004 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
2005 webViewImpl->setInitialFocus(false);
2007 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame());
2008 blink::HTMLDocument* document = blink::toHTMLDocument(frame->frame()->document());
2011 // (A.1) Focused and value is changed by script.
2013 EXPECT_FALSE(client.textIsUpdated());
2015 blink::HTMLInputElement* inputElement = toHTMLInputElement(document->getElementById("input"));
2016 document->setFocusedElement(inputElement);
2017 webViewImpl->setFocus(true);
2018 EXPECT_EQ(document->focusedElement(), static_cast<blink::Element*>(inputElement));
2020 // Emulate value change from script.
2021 inputElement->setValue("testA");
2022 EXPECT_TRUE(client.textIsUpdated());
2023 WebTextInputInfo info = webViewImpl->textInputInfo();
2024 EXPECT_EQ("testA", std::string(info.value.utf8().data()));
2026 // (A.2) Focused and user input modifies value.
2028 EXPECT_FALSE(client.textIsUpdated());
2030 WebVector<WebCompositionUnderline> emptyUnderlines;
2031 webViewImpl->setComposition(WebString::fromUTF8("2"), emptyUnderlines, 1, 1);
2032 webViewImpl->confirmComposition(WebWidget::KeepSelection);
2033 EXPECT_FALSE(client.textIsUpdated());
2034 info = webViewImpl->textInputInfo();
2035 EXPECT_EQ("testA2", std::string(info.value.utf8().data()));
2037 // (A.3) Unfocused and value is changed by script.
2039 EXPECT_FALSE(client.textIsUpdated());
2040 document->setFocusedElement(nullptr);
2041 webViewImpl->setFocus(false);
2042 EXPECT_NE(document->focusedElement(), static_cast<blink::Element*>(inputElement));
2043 inputElement->setValue("testA3");
2044 EXPECT_FALSE(client.textIsUpdated());
2047 // (B.1) Focused and value is changed by script.
2049 EXPECT_FALSE(client.textIsUpdated());
2050 blink::HTMLTextAreaElement* textAreaElement = toHTMLTextAreaElement(document->getElementById("textarea"));
2051 document->setFocusedElement(textAreaElement);
2052 webViewImpl->setFocus(true);
2053 EXPECT_EQ(document->focusedElement(), static_cast<blink::Element*>(textAreaElement));
2054 textAreaElement->setValue("testB");
2055 EXPECT_TRUE(client.textIsUpdated());
2056 info = webViewImpl->textInputInfo();
2057 EXPECT_EQ("testB", std::string(info.value.utf8().data()));
2059 // (B.2) Focused and user input modifies value.
2061 EXPECT_FALSE(client.textIsUpdated());
2062 webViewImpl->setComposition(WebString::fromUTF8("2"), emptyUnderlines, 1, 1);
2063 webViewImpl->confirmComposition(WebWidget::KeepSelection);
2064 info = webViewImpl->textInputInfo();
2065 EXPECT_EQ("testB2", std::string(info.value.utf8().data()));
2067 // (B.3) Unfocused and value is changed by script.
2069 EXPECT_FALSE(client.textIsUpdated());
2070 document->setFocusedElement(nullptr);
2071 webViewImpl->setFocus(false);
2072 EXPECT_NE(document->focusedElement(), static_cast<blink::Element*>(textAreaElement));
2073 inputElement->setValue("testB3");
2074 EXPECT_FALSE(client.textIsUpdated());
2076 // Free the webView before freeing the NonUserInputTextUpdateWebViewClient.
2077 m_webViewHelper.reset();
2080 // Check that the WebAutofillClient is correctly notified about first user
2081 // gestures after load, following various input events.
2082 TEST_F(WebViewTest, FirstUserGestureObservedKeyEvent)
2084 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("form.html"));
2085 MockAutofillClient client;
2086 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "form.html", true);
2087 webView->setAutofillClient(&client);
2088 webView->setInitialFocus(false);
2090 EXPECT_EQ(0, client.getUserGestureNotificationsCount());
2092 WebKeyboardEvent keyEvent;
2093 keyEvent.windowsKeyCode = blink::VKEY_SPACE;
2094 keyEvent.type = WebInputEvent::RawKeyDown;
2095 keyEvent.setKeyIdentifierFromWindowsKeyCode();
2096 webView->handleInputEvent(keyEvent);
2097 keyEvent.type = WebInputEvent::KeyUp;
2098 webView->handleInputEvent(keyEvent);
2100 EXPECT_EQ(1, client.getUserGestureNotificationsCount());
2101 webView->setAutofillClient(0);
2104 TEST_F(WebViewTest, FirstUserGestureObservedMouseEvent)
2106 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("form.html"));
2107 MockAutofillClient client;
2108 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "form.html", true);
2109 webView->setAutofillClient(&client);
2110 webView->setInitialFocus(false);
2112 EXPECT_EQ(0, client.getUserGestureNotificationsCount());
2114 WebMouseEvent mouseEvent;
2115 mouseEvent.button = WebMouseEvent::ButtonLeft;
2118 mouseEvent.clickCount = 1;
2119 mouseEvent.type = WebInputEvent::MouseDown;
2120 webView->handleInputEvent(mouseEvent);
2121 mouseEvent.type = WebInputEvent::MouseUp;
2122 webView->handleInputEvent(mouseEvent);
2124 EXPECT_EQ(1, client.getUserGestureNotificationsCount());
2125 webView->setAutofillClient(0);
2128 TEST_F(WebViewTest, FirstUserGestureObservedGestureTap)
2130 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
2131 MockAutofillClient client;
2132 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
2133 webView->setAutofillClient(&client);
2134 webView->setInitialFocus(false);
2136 EXPECT_EQ(0, client.getUserGestureNotificationsCount());
2138 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, WebString::fromUTF8("target")));
2140 EXPECT_EQ(1, client.getUserGestureNotificationsCount());
2141 webView->setAutofillClient(0);
2144 TEST_F(WebViewTest, CompareSelectAllToContentAsText)
2146 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
2147 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
2149 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
2150 frame->executeScript(WebScriptSource(WebString::fromUTF8("document.execCommand('SelectAll', false, null)")));
2151 std::string actual = frame->selectionAsText().utf8();
2153 const int kMaxOutputCharacters = 1024;
2154 std::string expected = frame->contentAsText(kMaxOutputCharacters).utf8();
2155 EXPECT_EQ(expected, actual);