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.
34 #include <gtest/gtest.h>
35 #include "FrameTestHelpers.h"
36 #include "URLTestHelpers.h"
37 #include "WebAutofillClient.h"
38 #include "WebContentDetectionResult.h"
39 #include "WebDateTimeChooserCompletion.h"
40 #include "WebDocument.h"
41 #include "WebElement.h"
43 #include "WebFrameClient.h"
44 #include "WebFrameImpl.h"
45 #include "WebHitTestResult.h"
46 #include "WebInputEvent.h"
47 #include "WebSettings.h"
48 #include "WebSettingsImpl.h"
49 #include "WebViewClient.h"
50 #include "WebViewImpl.h"
51 #include "WebWidget.h"
52 #include "core/dom/Document.h"
53 #include "core/dom/Element.h"
54 #include "core/html/HTMLDocument.h"
55 #include "core/html/HTMLIFrameElement.h"
56 #include "core/html/HTMLInputElement.h"
57 #include "core/loader/FrameLoadRequest.h"
58 #include "core/frame/FrameView.h"
59 #include "core/page/Chrome.h"
60 #include "core/frame/Settings.h"
61 #include "platform/KeyboardCodes.h"
62 #include "platform/graphics/Color.h"
63 #include "public/platform/Platform.h"
64 #include "public/platform/WebDragData.h"
65 #include "public/platform/WebSize.h"
66 #include "public/platform/WebThread.h"
67 #include "public/platform/WebUnitTestSupport.h"
68 #include "public/web/WebDragOperation.h"
69 #include "public/web/WebWidgetClient.h"
70 #include "third_party/skia/include/core/SkBitmap.h"
71 #include "third_party/skia/include/core/SkBitmapDevice.h"
72 #include "third_party/skia/include/core/SkCanvas.h"
74 using namespace blink;
75 using blink::FrameTestHelpers::runPendingTasks;
76 using blink::URLTestHelpers::toKURL;
80 enum HorizontalScrollbarState {
81 NoHorizontalScrollbar,
82 VisibleHorizontalScrollbar,
85 enum VerticalScrollbarState {
87 VisibleVerticalScrollbar,
92 void setWebView(WebView* webView) { m_webView = toWebViewImpl(webView); }
93 void setSize(const WebSize& newSize) { m_size = newSize; }
94 HorizontalScrollbarState horizontalScrollbarState() const
96 return m_webView->hasHorizontalScrollbar() ? VisibleHorizontalScrollbar: NoHorizontalScrollbar;
98 VerticalScrollbarState verticalScrollbarState() const
100 return m_webView->hasVerticalScrollbar() ? VisibleVerticalScrollbar : NoVerticalScrollbar;
102 int width() const { return m_size.width; }
103 int height() const { return m_size.height; }
107 WebViewImpl* m_webView;
110 class AutoResizeWebViewClient : public WebViewClient {
112 // WebViewClient methods
113 virtual void didAutoResize(const WebSize& newSize) { m_testData.setSize(newSize); }
116 TestData& testData() { return m_testData; }
122 class TapHandlingWebViewClient : public WebViewClient {
124 // WebViewClient methods
125 virtual void didHandleGestureEvent(const WebGestureEvent& event, bool eventCancelled)
127 if (event.type == WebInputEvent::GestureTap) {
130 } else if (event.type == WebInputEvent::GestureLongPress) {
131 m_longpressX = event.x;
132 m_longpressY = event.y;
144 int tapX() { return m_tapX; }
145 int tapY() { return m_tapY; }
146 int longpressX() { return m_longpressX; }
147 int longpressY() { return m_longpressY; }
156 class FakeCompositingWebViewClient : public WebViewClient {
158 virtual ~FakeCompositingWebViewClient()
162 virtual void initializeLayerTreeView() OVERRIDE
164 m_layerTreeView = adoptPtr(Platform::current()->unitTestSupport()->createLayerTreeViewForTesting(WebUnitTestSupport::TestViewTypeUnitTest));
165 ASSERT(m_layerTreeView);
168 virtual WebLayerTreeView* layerTreeView() OVERRIDE
170 return m_layerTreeView.get();
174 OwnPtr<WebLayerTreeView> m_layerTreeView;
177 class DateTimeChooserWebViewClient : public WebViewClient {
179 WebDateTimeChooserCompletion* chooserCompletion()
181 return m_chooserCompletion;
184 void clearChooserCompletion()
186 m_chooserCompletion = 0;
189 // WebViewClient methods
190 virtual bool openDateTimeChooser(const WebDateTimeChooserParams&, WebDateTimeChooserCompletion* chooser_completion) OVERRIDE
192 m_chooserCompletion = chooser_completion;
197 WebDateTimeChooserCompletion* m_chooserCompletion;
201 class WebViewTest : public testing::Test {
204 : m_baseURL("http://www.test.com/")
208 virtual void TearDown()
210 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
214 void registerMockedHttpURLLoad(const std::string& fileName)
216 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(fileName.c_str()));
219 void testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
220 const std::string& pageWidth, const std::string& pageHeight,
221 int expectedWidth, int expectedHeight,
222 HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState);
224 void testTextInputType(WebTextInputType expectedType, const std::string& htmlFile);
225 void testInputMode(const WebString& expectedInputMode, const std::string& htmlFile);
226 void testSelectionRootBounds(const char* htmlFile, float pageScaleFactor);
228 std::string m_baseURL;
229 FrameTestHelpers::WebViewHelper m_webViewHelper;
232 TEST_F(WebViewTest, SetBaseBackgroundColor)
234 const WebColor kWhite = 0xFFFFFFFF;
235 const WebColor kBlue = 0xFF0000FF;
236 const WebColor kDarkCyan = 0xFF227788;
237 const WebColor kTranslucentPutty = 0x80BFB196;
239 WebView* webView = m_webViewHelper.initialize();
240 EXPECT_EQ(kWhite, webView->backgroundColor());
242 webView->setBaseBackgroundColor(kBlue);
243 EXPECT_EQ(kBlue, webView->backgroundColor());
245 WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
246 webView->mainFrame()->loadHTMLString(
247 "<html><head><style>body {background-color:#227788}</style></head></html>", baseURL);
248 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
249 EXPECT_EQ(kDarkCyan, webView->backgroundColor());
251 webView->mainFrame()->loadHTMLString(
252 "<html><head><style>body {background-color:rgba(255,0,0,0.5)}</style></head></html>", baseURL);
253 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
254 // Expected: red (50% alpha) blended atop base of kBlue.
255 EXPECT_EQ(0xFF7F0080, webView->backgroundColor());
257 webView->setBaseBackgroundColor(kTranslucentPutty);
258 // Expected: red (50% alpha) blended atop kTranslucentPutty. Note the alpha.
259 EXPECT_EQ(0xBFE93B32, webView->backgroundColor());
262 TEST_F(WebViewTest, SetBaseBackgroundColorBeforeMainFrame)
264 const WebColor kBlue = 0xFF0000FF;
265 WebView* webView = WebViewImpl::create(0);
266 EXPECT_NE(kBlue, webView->backgroundColor());
267 // webView does not have a frame yet, but we should still be able to set the background color.
268 webView->setBaseBackgroundColor(kBlue);
269 EXPECT_EQ(kBlue, webView->backgroundColor());
272 TEST_F(WebViewTest, SetBaseBackgroundColorAndBlendWithExistingContent)
274 const WebColor kAlphaRed = 0x80FF0000;
275 const WebColor kAlphaGreen = 0x8000FF00;
276 const int kWidth = 100;
277 const int kHeight = 100;
279 // Set WebView background to green with alpha.
280 WebView* webView = m_webViewHelper.initialize();
281 webView->setBaseBackgroundColor(kAlphaGreen);
282 webView->settings()->setShouldClearDocumentBackground(false);
283 webView->resize(WebSize(kWidth, kHeight));
286 // Set canvas background to red with alpha.
288 ASSERT_TRUE(bitmap.allocN32Pixels(kWidth, kHeight));
289 SkCanvas canvas(bitmap);
290 canvas.clear(kAlphaRed);
291 webView->paint(&canvas, WebRect(0, 0, kWidth, kHeight));
293 // The result should be a blend of red and green.
294 SkColor color = bitmap.getColor(kWidth / 2, kHeight / 2);
295 EXPECT_TRUE(WebCore::redChannel(color));
296 EXPECT_TRUE(WebCore::greenChannel(color));
299 TEST_F(WebViewTest, FocusIsInactive)
301 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
302 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "visible_iframe.html");
304 webView->setFocus(true);
305 webView->setIsActive(true);
306 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
307 EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
309 WebCore::HTMLDocument* document = WebCore::toHTMLDocument(frame->frame()->document());
310 EXPECT_TRUE(document->hasFocus());
311 webView->setFocus(false);
312 webView->setIsActive(false);
313 EXPECT_FALSE(document->hasFocus());
314 webView->setFocus(true);
315 webView->setIsActive(true);
316 EXPECT_TRUE(document->hasFocus());
317 webView->setFocus(true);
318 webView->setIsActive(false);
319 EXPECT_FALSE(document->hasFocus());
320 webView->setFocus(false);
321 webView->setIsActive(true);
322 EXPECT_FALSE(document->hasFocus());
325 TEST_F(WebViewTest, ActiveState)
327 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "visible_iframe.html");
328 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "visible_iframe.html");
330 ASSERT_TRUE(webView);
332 webView->setIsActive(true);
333 EXPECT_TRUE(webView->isActive());
335 webView->setIsActive(false);
336 EXPECT_FALSE(webView->isActive());
338 webView->setIsActive(true);
339 EXPECT_TRUE(webView->isActive());
342 TEST_F(WebViewTest, HitTestResultAtWithPageScale)
344 std::string url = m_baseURL + "specify_size.html?" + "50px" + ":" + "50px";
345 URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
346 WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
347 webView->resize(WebSize(100, 100));
348 WebPoint hitPoint(75, 75);
350 // Image is at top left quandrant, so should not hit it.
351 WebHitTestResult negativeResult = webView->hitTestResultAt(hitPoint);
352 ASSERT_EQ(WebNode::ElementNode, negativeResult.node().nodeType());
353 EXPECT_FALSE(negativeResult.node().to<WebElement>().hasTagName("img"));
354 negativeResult.reset();
356 // Scale page up 2x so image should occupy the whole viewport.
357 webView->setPageScaleFactor(2.0f, WebPoint(0, 0));
358 WebHitTestResult positiveResult = webView->hitTestResultAt(hitPoint);
359 ASSERT_EQ(WebNode::ElementNode, positiveResult.node().nodeType());
360 EXPECT_TRUE(positiveResult.node().to<WebElement>().hasTagName("img"));
361 positiveResult.reset();
364 void WebViewTest::testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
365 const std::string& pageWidth, const std::string& pageHeight,
366 int expectedWidth, int expectedHeight,
367 HorizontalScrollbarState expectedHorizontalState, VerticalScrollbarState expectedVerticalState)
369 AutoResizeWebViewClient client;
370 std::string url = m_baseURL + "specify_size.html?" + pageWidth + ":" + pageHeight;
371 URLTestHelpers::registerMockedURLLoad(toKURL(url), "specify_size.html");
372 WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
373 client.testData().setWebView(webView);
375 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
376 WebCore::FrameView* frameView = frame->frame()->view();
378 EXPECT_FALSE(frameView->layoutPending());
379 EXPECT_FALSE(frameView->needsLayout());
381 webView->enableAutoResizeMode(minAutoResize, maxAutoResize);
382 EXPECT_TRUE(frameView->layoutPending());
383 EXPECT_TRUE(frameView->needsLayout());
386 EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
388 EXPECT_EQ(expectedWidth, client.testData().width());
389 EXPECT_EQ(expectedHeight, client.testData().height());
390 EXPECT_EQ(expectedHorizontalState, client.testData().horizontalScrollbarState());
391 EXPECT_EQ(expectedVerticalState, client.testData().verticalScrollbarState());
393 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
396 TEST_F(WebViewTest, DISABLED_AutoResizeMinimumSize)
398 WebSize minAutoResize(91, 56);
399 WebSize maxAutoResize(403, 302);
400 std::string pageWidth = "91px";
401 std::string pageHeight = "56px";
402 int expectedWidth = 91;
403 int expectedHeight = 56;
404 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
405 expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
408 TEST_F(WebViewTest, AutoResizeHeightOverflowAndFixedWidth)
410 WebSize minAutoResize(90, 95);
411 WebSize maxAutoResize(90, 100);
412 std::string pageWidth = "60px";
413 std::string pageHeight = "200px";
414 int expectedWidth = 90;
415 int expectedHeight = 100;
416 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
417 expectedWidth, expectedHeight, NoHorizontalScrollbar, VisibleVerticalScrollbar);
420 TEST_F(WebViewTest, AutoResizeFixedHeightAndWidthOverflow)
422 WebSize minAutoResize(90, 100);
423 WebSize maxAutoResize(200, 100);
424 std::string pageWidth = "300px";
425 std::string pageHeight = "80px";
426 int expectedWidth = 200;
427 int expectedHeight = 100;
428 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
429 expectedWidth, expectedHeight, VisibleHorizontalScrollbar, NoVerticalScrollbar);
432 // Next three tests disabled for https://bugs.webkit.org/show_bug.cgi?id=92318 .
433 // It seems we can run three AutoResize tests, then the next one breaks.
434 TEST_F(WebViewTest, DISABLED_AutoResizeInBetweenSizes)
436 WebSize minAutoResize(90, 95);
437 WebSize maxAutoResize(200, 300);
438 std::string pageWidth = "100px";
439 std::string pageHeight = "200px";
440 int expectedWidth = 100;
441 int expectedHeight = 200;
442 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
443 expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
446 TEST_F(WebViewTest, DISABLED_AutoResizeOverflowSizes)
448 WebSize minAutoResize(90, 95);
449 WebSize maxAutoResize(200, 300);
450 std::string pageWidth = "300px";
451 std::string pageHeight = "400px";
452 int expectedWidth = 200;
453 int expectedHeight = 300;
454 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
455 expectedWidth, expectedHeight, VisibleHorizontalScrollbar, VisibleVerticalScrollbar);
458 TEST_F(WebViewTest, DISABLED_AutoResizeMaxSize)
460 WebSize minAutoResize(90, 95);
461 WebSize maxAutoResize(200, 300);
462 std::string pageWidth = "200px";
463 std::string pageHeight = "300px";
464 int expectedWidth = 200;
465 int expectedHeight = 300;
466 testAutoResize(minAutoResize, maxAutoResize, pageWidth, pageHeight,
467 expectedWidth, expectedHeight, NoHorizontalScrollbar, NoVerticalScrollbar);
470 void WebViewTest::testTextInputType(WebTextInputType expectedType, const std::string& htmlFile)
472 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
473 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + htmlFile);
474 webView->setInitialFocus(false);
475 EXPECT_EQ(expectedType, webView->textInputInfo().type);
478 TEST_F(WebViewTest, TextInputType)
480 testTextInputType(WebTextInputTypeText, "input_field_default.html");
481 testTextInputType(WebTextInputTypePassword, "input_field_password.html");
482 testTextInputType(WebTextInputTypeEmail, "input_field_email.html");
483 testTextInputType(WebTextInputTypeSearch, "input_field_search.html");
484 testTextInputType(WebTextInputTypeNumber, "input_field_number.html");
485 testTextInputType(WebTextInputTypeTelephone, "input_field_tel.html");
486 testTextInputType(WebTextInputTypeURL, "input_field_url.html");
489 void WebViewTest::testInputMode(const WebString& expectedInputMode, const std::string& htmlFile)
491 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(htmlFile.c_str()));
492 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + htmlFile);
493 webView->setInitialFocus(false);
494 EXPECT_EQ(expectedInputMode, webView->textInputInfo().inputMode);
497 TEST_F(WebViewTest, InputMode)
499 testInputMode(WebString(), "input_mode_default.html");
500 testInputMode(WebString("unknown"), "input_mode_default_unknown.html");
501 testInputMode(WebString("verbatim"), "input_mode_default_verbatim.html");
502 testInputMode(WebString("verbatim"), "input_mode_type_text_verbatim.html");
503 testInputMode(WebString("verbatim"), "input_mode_type_search_verbatim.html");
504 testInputMode(WebString(), "input_mode_type_url_verbatim.html");
505 testInputMode(WebString("verbatim"), "input_mode_textarea_verbatim.html");
508 TEST_F(WebViewTest, SetEditableSelectionOffsetsAndTextInputInfo)
510 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
511 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
512 webView->setInitialFocus(false);
513 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
514 frame->setEditableSelectionOffsets(5, 13);
515 EXPECT_EQ("56789abc", frame->selectionAsText());
516 WebTextInputInfo info = webView->textInputInfo();
517 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
518 EXPECT_EQ(5, info.selectionStart);
519 EXPECT_EQ(13, info.selectionEnd);
520 EXPECT_EQ(-1, info.compositionStart);
521 EXPECT_EQ(-1, info.compositionEnd);
523 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_editable_populated.html"));
524 webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_editable_populated.html");
525 webView->setInitialFocus(false);
526 frame = toWebFrameImpl(webView->mainFrame());
527 frame->setEditableSelectionOffsets(8, 19);
528 EXPECT_EQ("89abcdefghi", frame->selectionAsText());
529 info = webView->textInputInfo();
530 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
531 EXPECT_EQ(8, info.selectionStart);
532 EXPECT_EQ(19, info.selectionEnd);
533 EXPECT_EQ(-1, info.compositionStart);
534 EXPECT_EQ(-1, info.compositionEnd);
537 TEST_F(WebViewTest, ConfirmCompositionCursorPositionChange)
539 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
540 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
541 webView->setInitialFocus(false);
543 // Set up a composition that needs to be committed.
544 std::string compositionText("hello");
546 WebVector<WebCompositionUnderline> emptyUnderlines;
547 webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3);
549 WebTextInputInfo info = webView->textInputInfo();
550 EXPECT_EQ("hello", std::string(info.value.utf8().data()));
551 EXPECT_EQ(3, info.selectionStart);
552 EXPECT_EQ(3, info.selectionEnd);
553 EXPECT_EQ(0, info.compositionStart);
554 EXPECT_EQ(5, info.compositionEnd);
556 webView->confirmComposition(WebWidget::KeepSelection);
557 info = webView->textInputInfo();
558 EXPECT_EQ(3, info.selectionStart);
559 EXPECT_EQ(3, info.selectionEnd);
560 EXPECT_EQ(-1, info.compositionStart);
561 EXPECT_EQ(-1, info.compositionEnd);
563 webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 3, 3);
564 info = webView->textInputInfo();
565 EXPECT_EQ("helhellolo", std::string(info.value.utf8().data()));
566 EXPECT_EQ(6, info.selectionStart);
567 EXPECT_EQ(6, info.selectionEnd);
568 EXPECT_EQ(3, info.compositionStart);
569 EXPECT_EQ(8, info.compositionEnd);
571 webView->confirmComposition(WebWidget::DoNotKeepSelection);
572 info = webView->textInputInfo();
573 EXPECT_EQ(8, info.selectionStart);
574 EXPECT_EQ(8, info.selectionEnd);
575 EXPECT_EQ(-1, info.compositionStart);
576 EXPECT_EQ(-1, info.compositionEnd);
579 TEST_F(WebViewTest, InsertNewLinePlacementAfterConfirmComposition)
581 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html"));
582 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "text_area_populated.html");
583 webView->setInitialFocus(false);
585 WebVector<WebCompositionUnderline> emptyUnderlines;
587 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
588 frame->setEditableSelectionOffsets(4, 4);
589 frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
591 WebTextInputInfo info = webView->textInputInfo();
592 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
593 EXPECT_EQ(4, info.selectionStart);
594 EXPECT_EQ(4, info.selectionEnd);
595 EXPECT_EQ(8, info.compositionStart);
596 EXPECT_EQ(12, info.compositionEnd);
598 webView->confirmComposition(WebWidget::KeepSelection);
599 info = webView->textInputInfo();
600 EXPECT_EQ(4, info.selectionStart);
601 EXPECT_EQ(4, info.selectionEnd);
602 EXPECT_EQ(-1, info.compositionStart);
603 EXPECT_EQ(-1, info.compositionEnd);
605 std::string compositionText("\n");
606 webView->confirmComposition(WebString::fromUTF8(compositionText.c_str()));
607 info = webView->textInputInfo();
608 EXPECT_EQ(5, info.selectionStart);
609 EXPECT_EQ(5, info.selectionEnd);
610 EXPECT_EQ(-1, info.compositionStart);
611 EXPECT_EQ(-1, info.compositionEnd);
612 EXPECT_EQ("0123\n456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
615 TEST_F(WebViewTest, ExtendSelectionAndDelete)
617 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
618 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
619 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
620 webView->setInitialFocus(false);
621 frame->setEditableSelectionOffsets(10, 10);
622 frame->extendSelectionAndDelete(5, 8);
623 WebTextInputInfo info = webView->textInputInfo();
624 EXPECT_EQ("01234ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
625 EXPECT_EQ(5, info.selectionStart);
626 EXPECT_EQ(5, info.selectionEnd);
627 frame->extendSelectionAndDelete(10, 0);
628 info = webView->textInputInfo();
629 EXPECT_EQ("ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
632 TEST_F(WebViewTest, SetCompositionFromExistingText)
634 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
635 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
636 webView->setInitialFocus(false);
637 WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
638 underlines[0] = blink::WebCompositionUnderline(0, 4, 0, false);
639 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
640 frame->setEditableSelectionOffsets(4, 10);
641 frame->setCompositionFromExistingText(8, 12, underlines);
642 WebVector<WebCompositionUnderline> underlineResults = toWebViewImpl(webView)->compositionUnderlines();
643 EXPECT_EQ(8u, underlineResults[0].startOffset);
644 EXPECT_EQ(12u, underlineResults[0].endOffset);
645 WebTextInputInfo info = webView->textInputInfo();
646 EXPECT_EQ(4, info.selectionStart);
647 EXPECT_EQ(10, info.selectionEnd);
648 EXPECT_EQ(8, info.compositionStart);
649 EXPECT_EQ(12, info.compositionEnd);
650 WebVector<WebCompositionUnderline> emptyUnderlines;
651 frame->setCompositionFromExistingText(0, 0, emptyUnderlines);
652 info = webView->textInputInfo();
653 EXPECT_EQ(4, info.selectionStart);
654 EXPECT_EQ(10, info.selectionEnd);
655 EXPECT_EQ(-1, info.compositionStart);
656 EXPECT_EQ(-1, info.compositionEnd);
659 TEST_F(WebViewTest, SetCompositionFromExistingTextInTextArea)
661 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("text_area_populated.html"));
662 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "text_area_populated.html");
663 webView->setInitialFocus(false);
664 WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
665 underlines[0] = blink::WebCompositionUnderline(0, 4, 0, false);
666 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
667 frame->setEditableSelectionOffsets(27, 27);
668 std::string newLineText("\n");
669 webView->confirmComposition(WebString::fromUTF8(newLineText.c_str()));
670 WebTextInputInfo info = webView->textInputInfo();
671 EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data()));
673 frame->setEditableSelectionOffsets(31, 31);
674 frame->setCompositionFromExistingText(30, 34, underlines);
675 WebVector<WebCompositionUnderline> underlineResults = toWebViewImpl(webView)->compositionUnderlines();
676 EXPECT_EQ(2u, underlineResults[0].startOffset);
677 EXPECT_EQ(6u, underlineResults[0].endOffset);
678 info = webView->textInputInfo();
679 EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data()));
680 EXPECT_EQ(31, info.selectionStart);
681 EXPECT_EQ(31, info.selectionEnd);
682 EXPECT_EQ(30, info.compositionStart);
683 EXPECT_EQ(34, info.compositionEnd);
685 std::string compositionText("yolo");
686 webView->confirmComposition(WebString::fromUTF8(compositionText.c_str()));
687 info = webView->textInputInfo();
688 EXPECT_EQ("0123456789abcdefghijklmnopq\nrsyoloxyz", std::string(info.value.utf8().data()));
689 EXPECT_EQ(34, info.selectionStart);
690 EXPECT_EQ(34, info.selectionEnd);
691 EXPECT_EQ(-1, info.compositionStart);
692 EXPECT_EQ(-1, info.compositionEnd);
695 TEST_F(WebViewTest, SetEditableSelectionOffsetsKeepsComposition)
697 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
698 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
699 webView->setInitialFocus(false);
701 std::string compositionTextFirst("hello ");
702 std::string compositionTextSecond("world");
703 WebVector<WebCompositionUnderline> emptyUnderlines;
705 webView->confirmComposition(WebString::fromUTF8(compositionTextFirst.c_str()));
706 webView->setComposition(WebString::fromUTF8(compositionTextSecond.c_str()), emptyUnderlines, 5, 5);
708 WebTextInputInfo info = webView->textInputInfo();
709 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
710 EXPECT_EQ(11, info.selectionStart);
711 EXPECT_EQ(11, info.selectionEnd);
712 EXPECT_EQ(6, info.compositionStart);
713 EXPECT_EQ(11, info.compositionEnd);
715 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
716 frame->setEditableSelectionOffsets(6, 6);
717 info = webView->textInputInfo();
718 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
719 EXPECT_EQ(6, info.selectionStart);
720 EXPECT_EQ(6, info.selectionEnd);
721 EXPECT_EQ(6, info.compositionStart);
722 EXPECT_EQ(11, info.compositionEnd);
724 frame->setEditableSelectionOffsets(8, 8);
725 info = webView->textInputInfo();
726 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
727 EXPECT_EQ(8, info.selectionStart);
728 EXPECT_EQ(8, info.selectionEnd);
729 EXPECT_EQ(6, info.compositionStart);
730 EXPECT_EQ(11, info.compositionEnd);
732 frame->setEditableSelectionOffsets(11, 11);
733 info = webView->textInputInfo();
734 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
735 EXPECT_EQ(11, info.selectionStart);
736 EXPECT_EQ(11, info.selectionEnd);
737 EXPECT_EQ(6, info.compositionStart);
738 EXPECT_EQ(11, info.compositionEnd);
740 frame->setEditableSelectionOffsets(6, 11);
741 info = webView->textInputInfo();
742 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
743 EXPECT_EQ(6, info.selectionStart);
744 EXPECT_EQ(11, info.selectionEnd);
745 EXPECT_EQ(6, info.compositionStart);
746 EXPECT_EQ(11, info.compositionEnd);
748 frame->setEditableSelectionOffsets(2, 2);
749 info = webView->textInputInfo();
750 EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
751 EXPECT_EQ(2, info.selectionStart);
752 EXPECT_EQ(2, info.selectionEnd);
753 EXPECT_EQ(-1, info.compositionStart);
754 EXPECT_EQ(-1, info.compositionEnd);
757 TEST_F(WebViewTest, IsSelectionAnchorFirst)
759 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
760 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
761 WebFrame* frame = webView->mainFrame();
763 webView->setInitialFocus(false);
764 frame->setEditableSelectionOffsets(4, 10);
765 EXPECT_TRUE(webView->isSelectionAnchorFirst());
768 webView->selectionBounds(anchor, focus);
769 frame->selectRange(WebPoint(focus.x, focus.y), WebPoint(anchor.x, anchor.y));
770 EXPECT_FALSE(webView->isSelectionAnchorFirst());
773 TEST_F(WebViewTest, HistoryResetScrollAndScaleState)
775 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html"));
776 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "hello_world.html");
777 webViewImpl->resize(WebSize(640, 480));
778 webViewImpl->layout();
779 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
780 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
782 // Make the page scale and scroll with the given paremeters.
783 webViewImpl->setPageScaleFactor(2.0f, WebPoint(116, 84));
784 EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
785 EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
786 EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
787 webViewImpl->page()->mainFrame()->loader().saveScrollState();
788 EXPECT_EQ(2.0f, webViewImpl->page()->mainFrame()->loader().currentItem()->pageScaleFactor());
789 EXPECT_EQ(116, webViewImpl->page()->mainFrame()->loader().currentItem()->scrollPoint().x());
790 EXPECT_EQ(84, webViewImpl->page()->mainFrame()->loader().currentItem()->scrollPoint().y());
792 // Confirm that resetting the page state resets the saved scroll position.
793 // The HistoryController treats a page scale factor of 0.0f as special and avoids
794 // restoring it to the WebView.
795 webViewImpl->resetScrollAndScaleState();
796 EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
797 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
798 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
799 EXPECT_EQ(0.0f, webViewImpl->page()->mainFrame()->loader().currentItem()->pageScaleFactor());
800 EXPECT_EQ(0, webViewImpl->page()->mainFrame()->loader().currentItem()->scrollPoint().x());
801 EXPECT_EQ(0, webViewImpl->page()->mainFrame()->loader().currentItem()->scrollPoint().y());
804 class EnterFullscreenWebViewClient : public WebViewClient {
806 // WebViewClient methods
807 virtual bool enterFullScreen() { return true; }
808 virtual void exitFullScreen() { }
812 TEST_F(WebViewTest, EnterFullscreenResetScrollAndScaleState)
814 EnterFullscreenWebViewClient client;
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", true, 0, &client);
817 webViewImpl->settings()->setFullScreenEnabled(true);
818 webViewImpl->resize(WebSize(640, 480));
819 webViewImpl->layout();
820 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
821 EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
823 // Make the page scale and scroll with the given paremeters.
824 webViewImpl->setPageScaleFactor(2.0f, 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);
829 RefPtr<WebCore::Element> element = static_cast<PassRefPtr<WebCore::Element> >(webViewImpl->mainFrame()->document().body());
830 webViewImpl->enterFullScreenForElement(element.get());
831 webViewImpl->willEnterFullScreen();
832 webViewImpl->didEnterFullScreen();
834 // Page scale factor must be 1.0 during fullscreen for elements to be sized
836 EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
838 // Make sure fullscreen nesting doesn't disrupt scroll/scale saving.
839 RefPtr<WebCore::Element> otherElement = static_cast<PassRefPtr<WebCore::Element> >(webViewImpl->mainFrame()->document().head());
840 webViewImpl->enterFullScreenForElement(otherElement.get());
842 // Confirm that exiting fullscreen restores the parameters.
843 webViewImpl->willExitFullScreen();
844 webViewImpl->didExitFullScreen();
845 EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
846 EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
847 EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
849 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
852 static void DragAndDropURL(WebViewImpl* webView, const std::string& url)
854 blink::WebDragData dragData;
855 dragData.initialize();
857 WebDragData::Item item;
858 item.storageType = WebDragData::Item::StorageTypeString;
859 item.stringType = "text/uri-list";
860 item.stringData = WebString::fromUTF8(url);
861 dragData.addItem(item);
863 const WebPoint clientPoint(0, 0);
864 const WebPoint screenPoint(0, 0);
865 webView->dragTargetDragEnter(dragData, clientPoint, screenPoint, blink::WebDragOperationCopy, 0);
866 webView->dragTargetDrop(clientPoint, screenPoint, 0);
867 FrameTestHelpers::runPendingTasks();
868 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
871 TEST_F(WebViewTest, DragDropURL)
873 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "foo.html");
874 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "bar.html");
876 const std::string fooUrl = m_baseURL + "foo.html";
877 const std::string barUrl = m_baseURL + "bar.html";
879 WebViewImpl* webView = m_webViewHelper.initializeAndLoad(fooUrl);
881 ASSERT_TRUE(webView);
883 // Drag and drop barUrl and verify that we've navigated to it.
884 DragAndDropURL(webView, barUrl);
885 EXPECT_EQ(barUrl, webView->mainFrame()->document().url().string().utf8());
887 // Drag and drop fooUrl and verify that we've navigated back to it.
888 DragAndDropURL(webView, fooUrl);
889 EXPECT_EQ(fooUrl, webView->mainFrame()->document().url().string().utf8());
891 // Disable navigation on drag-and-drop.
892 webView->settingsImpl()->setNavigateOnDragDrop(false);
894 // Attempt to drag and drop to barUrl and verify that no navigation has occurred.
895 DragAndDropURL(webView, barUrl);
896 EXPECT_EQ(fooUrl, webView->mainFrame()->document().url().string().utf8());
899 class ContentDetectorClient : public WebViewClient {
901 ContentDetectorClient() { reset(); }
903 virtual WebContentDetectionResult detectContentAround(const WebHitTestResult& hitTest) OVERRIDE
905 m_contentDetectionRequested = true;
906 return m_contentDetectionResult;
909 virtual void scheduleContentIntent(const WebURL& url) OVERRIDE
911 m_scheduledIntentURL = url;
914 virtual void cancelScheduledContentIntents() OVERRIDE
916 m_pendingIntentsCancelled = true;
921 m_contentDetectionRequested = false;
922 m_pendingIntentsCancelled = false;
923 m_scheduledIntentURL = WebURL();
924 m_contentDetectionResult = WebContentDetectionResult();
927 bool contentDetectionRequested() const { return m_contentDetectionRequested; }
928 bool pendingIntentsCancelled() const { return m_pendingIntentsCancelled; }
929 const WebURL& scheduledIntentURL() const { return m_scheduledIntentURL; }
930 void setContentDetectionResult(const WebContentDetectionResult& result) { m_contentDetectionResult = result; }
933 bool m_contentDetectionRequested;
934 bool m_pendingIntentsCancelled;
935 WebURL m_scheduledIntentURL;
936 WebContentDetectionResult m_contentDetectionResult;
939 static bool tapElementById(WebView* webView, WebInputEvent::Type type, const WebString& id)
942 RefPtr<WebCore::Element> element = static_cast<PassRefPtr<WebCore::Element> >(webView->mainFrame()->document().getElementById(id));
946 element->scrollIntoViewIfNeeded();
947 WebCore::IntPoint center = element->screenRect().center();
949 WebGestureEvent event;
951 event.x = center.x();
952 event.y = center.y();
954 webView->handleInputEvent(event);
959 TEST_F(WebViewTest, DetectContentAroundPosition)
961 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_listeners.html"));
963 ContentDetectorClient client;
964 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_listeners.html", true, 0, &client);
965 webView->resize(WebSize(500, 300));
969 WebString clickListener = WebString::fromUTF8("clickListener");
970 WebString touchstartListener = WebString::fromUTF8("touchstartListener");
971 WebString mousedownListener = WebString::fromUTF8("mousedownListener");
972 WebString noListener = WebString::fromUTF8("noListener");
973 WebString link = WebString::fromUTF8("link");
975 // Ensure content detection is not requested for nodes listening to click,
976 // mouse or touch events when we do simple taps.
977 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, clickListener));
978 EXPECT_FALSE(client.contentDetectionRequested());
981 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, touchstartListener));
982 EXPECT_FALSE(client.contentDetectionRequested());
985 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, mousedownListener));
986 EXPECT_FALSE(client.contentDetectionRequested());
989 // Content detection should work normally without these event listeners.
990 // The click listener in the body should be ignored as a special case.
991 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
992 EXPECT_TRUE(client.contentDetectionRequested());
993 EXPECT_FALSE(client.scheduledIntentURL().isValid());
995 WebURL intentURL = toKURL(m_baseURL);
996 client.setContentDetectionResult(WebContentDetectionResult(WebRange(), WebString(), intentURL));
997 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, noListener));
998 EXPECT_TRUE(client.scheduledIntentURL() == intentURL);
1000 // Tapping elsewhere should cancel the scheduled intent.
1001 WebGestureEvent event;
1002 event.type = WebInputEvent::GestureTap;
1003 webView->handleInputEvent(event);
1005 EXPECT_TRUE(client.pendingIntentsCancelled());
1007 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
1010 TEST_F(WebViewTest, ClientTapHandling)
1012 TapHandlingWebViewClient client;
1014 WebView* webView = m_webViewHelper.initializeAndLoad("about:blank", true, 0, &client);
1015 WebGestureEvent event;
1016 event.type = WebInputEvent::GestureTap;
1019 webView->handleInputEvent(event);
1021 EXPECT_EQ(3, client.tapX());
1022 EXPECT_EQ(8, client.tapY());
1024 event.type = WebInputEvent::GestureLongPress;
1027 webView->handleInputEvent(event);
1029 EXPECT_EQ(25, client.longpressX());
1030 EXPECT_EQ(7, client.longpressY());
1032 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
1036 TEST_F(WebViewTest, LongPressSelection)
1038 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
1040 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
1041 webView->resize(WebSize(500, 300));
1045 WebString target = WebString::fromUTF8("target");
1046 WebString onselectstartfalse = WebString::fromUTF8("onselectstartfalse");
1047 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
1049 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, onselectstartfalse));
1050 EXPECT_EQ("", std::string(frame->selectionAsText().utf8().data()));
1051 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, target));
1052 EXPECT_EQ("testword", std::string(frame->selectionAsText().utf8().data()));
1056 TEST_F(WebViewTest, SelectionOnDisabledInput)
1058 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_disabled.html"));
1059 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "selection_disabled.html", true);
1060 webView->resize(WebSize(640, 480));
1064 std::string testWord = "This text should be selected.";
1066 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
1067 EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));
1071 EXPECT_TRUE(toWebViewImpl(webView)->caretOrSelectionRange(&location, &length));
1072 EXPECT_EQ(location, 0UL);
1073 EXPECT_EQ(length, testWord.length());
1076 TEST_F(WebViewTest, SelectionOnReadOnlyInput)
1078 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_readonly.html"));
1079 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "selection_readonly.html", true);
1080 webView->resize(WebSize(640, 480));
1084 std::string testWord = "This text should be selected.";
1086 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
1087 EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));
1091 EXPECT_TRUE(toWebViewImpl(webView)->caretOrSelectionRange(&location, &length));
1092 EXPECT_EQ(location, 0UL);
1093 EXPECT_EQ(length, testWord.length());
1096 static void configueCompositingWebView(WebSettings* settings)
1098 settings->setForceCompositingMode(true);
1099 settings->setAcceleratedCompositingEnabled(true);
1100 settings->setAcceleratedCompositingForFixedPositionEnabled(true);
1101 settings->setAcceleratedCompositingForOverflowScrollEnabled(true);
1102 settings->setAcceleratedCompositingForScrollableFramesEnabled(true);
1103 settings->setCompositedScrollingForFramesEnabled(true);
1106 TEST_F(WebViewTest, ShowPressOnTransformedLink)
1108 OwnPtr<FakeCompositingWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FakeCompositingWebViewClient());
1109 FrameTestHelpers::WebViewHelper webViewHelper;
1110 WebViewImpl* webViewImpl = webViewHelper.initialize(true, 0, fakeCompositingWebViewClient.get(), &configueCompositingWebView);
1112 int pageWidth = 640;
1113 int pageHeight = 480;
1114 webViewImpl->resize(WebSize(pageWidth, pageHeight));
1116 WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
1117 webViewImpl->mainFrame()->loadHTMLString(
1118 "<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);
1119 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
1121 WebGestureEvent event;
1122 event.type = WebInputEvent::GestureShowPress;
1126 // Just make sure we don't hit any asserts.
1127 webViewImpl->handleInputEvent(event);
1130 class MockAutofillClient : public WebAutofillClient {
1132 MockAutofillClient()
1133 : m_ignoreTextChanges(false)
1134 , m_textChangesWhileIgnored(0)
1135 , m_textChangesWhileNotIgnored(0) { }
1137 virtual ~MockAutofillClient() { }
1139 virtual void setIgnoreTextChanges(bool ignore) OVERRIDE { m_ignoreTextChanges = ignore; }
1140 virtual void textFieldDidChange(const WebFormControlElement&) OVERRIDE
1142 if (m_ignoreTextChanges)
1143 ++m_textChangesWhileIgnored;
1145 ++m_textChangesWhileNotIgnored;
1148 void clearChangeCounts()
1150 m_textChangesWhileIgnored = 0;
1151 m_textChangesWhileNotIgnored = 0;
1154 int textChangesWhileIgnored() { return m_textChangesWhileIgnored; }
1155 int textChangesWhileNotIgnored() { return m_textChangesWhileNotIgnored; }
1158 bool m_ignoreTextChanges;
1159 int m_textChangesWhileIgnored;
1160 int m_textChangesWhileNotIgnored;
1164 TEST_F(WebViewTest, LosingFocusDoesNotTriggerAutofillTextChange)
1166 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
1167 MockAutofillClient client;
1168 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
1169 webView->setAutofillClient(&client);
1170 webView->setInitialFocus(false);
1172 // Set up a composition that needs to be committed.
1173 WebVector<WebCompositionUnderline> emptyUnderlines;
1174 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
1175 frame->setEditableSelectionOffsets(4, 10);
1176 frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
1177 WebTextInputInfo info = webView->textInputInfo();
1178 EXPECT_EQ(4, info.selectionStart);
1179 EXPECT_EQ(10, info.selectionEnd);
1180 EXPECT_EQ(8, info.compositionStart);
1181 EXPECT_EQ(12, info.compositionEnd);
1183 // Clear the focus and track that the subsequent composition commit does not trigger a
1184 // text changed notification for autofill.
1185 client.clearChangeCounts();
1186 webView->setFocus(false);
1187 EXPECT_EQ(1, client.textChangesWhileIgnored());
1188 EXPECT_EQ(0, client.textChangesWhileNotIgnored());
1190 webView->setAutofillClient(0);
1193 TEST_F(WebViewTest, ConfirmCompositionTriggersAutofillTextChange)
1195 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
1196 MockAutofillClient client;
1197 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
1198 webView->setAutofillClient(&client);
1199 webView->setInitialFocus(false);
1201 // Set up a composition that needs to be committed.
1202 std::string compositionText("testingtext");
1204 WebVector<WebCompositionUnderline> emptyUnderlines;
1205 webView->setComposition(WebString::fromUTF8(compositionText.c_str()), emptyUnderlines, 0, compositionText.length());
1207 WebTextInputInfo info = webView->textInputInfo();
1208 EXPECT_EQ(0, info.selectionStart);
1209 EXPECT_EQ((int) compositionText.length(), info.selectionEnd);
1210 EXPECT_EQ(0, info.compositionStart);
1211 EXPECT_EQ((int) compositionText.length(), info.compositionEnd);
1213 client.clearChangeCounts();
1214 webView->confirmComposition();
1215 EXPECT_EQ(0, client.textChangesWhileIgnored());
1216 EXPECT_EQ(1, client.textChangesWhileNotIgnored());
1218 webView->setAutofillClient(0);
1221 TEST_F(WebViewTest, SetCompositionFromExistingTextTriggersAutofillTextChange)
1223 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
1224 MockAutofillClient client;
1225 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html", true);
1226 webView->setAutofillClient(&client);
1227 webView->setInitialFocus(false);
1229 WebVector<WebCompositionUnderline> emptyUnderlines;
1231 client.clearChangeCounts();
1232 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
1233 frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
1235 WebTextInputInfo info = webView->textInputInfo();
1236 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
1237 EXPECT_EQ(8, info.compositionStart);
1238 EXPECT_EQ(12, info.compositionEnd);
1240 EXPECT_EQ(0, client.textChangesWhileIgnored());
1241 EXPECT_EQ(0, client.textChangesWhileNotIgnored());
1243 WebDocument document = webView->mainFrame()->document();
1244 EXPECT_EQ(WebString::fromUTF8("none"), document.getElementById("inputEvent").firstChild().nodeValue());
1246 webView->setAutofillClient(0);
1249 TEST_F(WebViewTest, ShadowRoot)
1251 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("shadow_dom_test.html"));
1252 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "shadow_dom_test.html", true);
1254 WebDocument document = webViewImpl->mainFrame()->document();
1256 WebElement elementWithShadowRoot = document.getElementById("shadowroot");
1257 EXPECT_FALSE(elementWithShadowRoot.isNull());
1258 WebNode shadowRoot = elementWithShadowRoot.shadowRoot();
1259 EXPECT_FALSE(shadowRoot.isNull());
1262 WebElement elementWithoutShadowRoot = document.getElementById("noshadowroot");
1263 EXPECT_FALSE(elementWithoutShadowRoot.isNull());
1264 WebNode shadowRoot = elementWithoutShadowRoot.shadowRoot();
1265 EXPECT_TRUE(shadowRoot.isNull());
1269 class ViewCreatingWebViewClient : public WebViewClient {
1271 ViewCreatingWebViewClient()
1272 : m_didFocusCalled(false)
1276 // WebViewClient methods
1277 virtual WebView* createView(WebFrame*, const WebURLRequest&, const WebWindowFeatures&, const WebString& name, WebNavigationPolicy, bool) OVERRIDE
1279 return m_webViewHelper.initialize(true, 0, 0);
1282 // WebWidgetClient methods
1283 virtual void didFocus() OVERRIDE
1285 m_didFocusCalled = true;
1288 bool didFocusCalled() const { return m_didFocusCalled; }
1289 WebView* createdWebView() const { return m_webViewHelper.webView(); }
1292 FrameTestHelpers::WebViewHelper m_webViewHelper;
1293 bool m_didFocusCalled;
1296 TEST_F(WebViewTest, FocusExistingFrameOnNavigate)
1298 ViewCreatingWebViewClient client;
1299 FrameTestHelpers::WebViewHelper m_webViewHelper;
1300 WebViewImpl* webViewImpl = m_webViewHelper.initialize(true, 0, &client);
1301 webViewImpl->page()->settings().setJavaScriptCanOpenWindowsAutomatically(true);
1302 WebFrameImpl* frame = toWebFrameImpl(webViewImpl->mainFrame());
1303 frame->setName("_start");
1305 // Make a request that will open a new window
1306 WebURLRequest webURLRequest;
1307 webURLRequest.initialize();
1308 WebCore::FrameLoadRequest request(0, webURLRequest.toResourceRequest(), "_blank");
1309 webViewImpl->page()->mainFrame()->loader().load(request);
1310 ASSERT_TRUE(client.createdWebView());
1311 EXPECT_FALSE(client.didFocusCalled());
1313 // Make a request from the new window that will navigate the original window. The original window should be focused.
1314 WebURLRequest webURLRequestWithTargetStart;
1315 webURLRequestWithTargetStart.initialize();
1316 WebCore::FrameLoadRequest requestWithTargetStart(0, webURLRequestWithTargetStart.toResourceRequest(), "_start");
1317 toWebViewImpl(client.createdWebView())->page()->mainFrame()->loader().load(requestWithTargetStart);
1318 EXPECT_TRUE(client.didFocusCalled());
1320 m_webViewHelper.reset(); // Remove dependency on locally scoped client.
1323 TEST_F(WebViewTest, DispatchesFocusOutFocusInOnViewToggleFocus)
1325 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "focusout_focusin_events.html");
1326 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "focusout_focusin_events.html", true, 0);
1328 webView->setFocus(true);
1329 webView->setFocus(false);
1330 webView->setFocus(true);
1332 WebElement element = webView->mainFrame()->document().getElementById("message");
1333 EXPECT_STREQ("focusoutfocusin", element.innerText().utf8().data());
1336 TEST_F(WebViewTest, DispatchesDomFocusOutDomFocusInOnViewToggleFocus)
1338 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "domfocusout_domfocusin_events.html");
1339 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "domfocusout_domfocusin_events.html", true, 0);
1341 webView->setFocus(true);
1342 webView->setFocus(false);
1343 webView->setFocus(true);
1345 WebElement element = webView->mainFrame()->document().getElementById("message");
1346 EXPECT_STREQ("DOMFocusOutDOMFocusIn", element.innerText().utf8().data());
1349 #if !ENABLE(INPUT_MULTIPLE_FIELDS_UI)
1350 static void openDateTimeChooser(WebView* webView, WebCore::HTMLInputElement* inputElement)
1352 inputElement->focus();
1354 WebKeyboardEvent keyEvent;
1355 keyEvent.windowsKeyCode = WebCore::VKEY_SPACE;
1356 keyEvent.type = WebInputEvent::RawKeyDown;
1357 keyEvent.setKeyIdentifierFromWindowsKeyCode();
1358 webView->handleInputEvent(keyEvent);
1360 keyEvent.type = WebInputEvent::KeyUp;
1361 webView->handleInputEvent(keyEvent);
1364 TEST_F(WebViewTest, ChooseValueFromDateTimeChooser)
1366 DateTimeChooserWebViewClient client;
1367 std::string url = m_baseURL + "date_time_chooser.html";
1368 URLTestHelpers::registerMockedURLLoad(toKURL(url), "date_time_chooser.html");
1369 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
1371 WebCore::Document* document = webViewImpl->mainFrameImpl()->frame()->document();
1373 WebCore::HTMLInputElement* inputElement;
1375 inputElement = toHTMLInputElement(document->getElementById("date"));
1376 openDateTimeChooser(webViewImpl, inputElement);
1377 client.chooserCompletion()->didChooseValue(0);
1378 client.clearChooserCompletion();
1379 EXPECT_STREQ("1970-01-01", inputElement->value().utf8().data());
1381 openDateTimeChooser(webViewImpl, inputElement);
1382 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1383 client.clearChooserCompletion();
1384 EXPECT_STREQ("", inputElement->value().utf8().data());
1386 inputElement = toHTMLInputElement(document->getElementById("datetimelocal"));
1387 openDateTimeChooser(webViewImpl, inputElement);
1388 client.chooserCompletion()->didChooseValue(0);
1389 client.clearChooserCompletion();
1390 EXPECT_STREQ("1970-01-01T00:00", inputElement->value().utf8().data());
1392 openDateTimeChooser(webViewImpl, inputElement);
1393 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1394 client.clearChooserCompletion();
1395 EXPECT_STREQ("", inputElement->value().utf8().data());
1397 inputElement = toHTMLInputElement(document->getElementById("month"));
1398 openDateTimeChooser(webViewImpl, inputElement);
1399 client.chooserCompletion()->didChooseValue(0);
1400 client.clearChooserCompletion();
1401 EXPECT_STREQ("1970-01", inputElement->value().utf8().data());
1403 openDateTimeChooser(webViewImpl, inputElement);
1404 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1405 client.clearChooserCompletion();
1406 EXPECT_STREQ("", inputElement->value().utf8().data());
1408 inputElement = toHTMLInputElement(document->getElementById("time"));
1409 openDateTimeChooser(webViewImpl, inputElement);
1410 client.chooserCompletion()->didChooseValue(0);
1411 client.clearChooserCompletion();
1412 EXPECT_STREQ("00:00", inputElement->value().utf8().data());
1414 openDateTimeChooser(webViewImpl, inputElement);
1415 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1416 client.clearChooserCompletion();
1417 EXPECT_STREQ("", inputElement->value().utf8().data());
1419 inputElement = toHTMLInputElement(document->getElementById("week"));
1420 openDateTimeChooser(webViewImpl, inputElement);
1421 client.chooserCompletion()->didChooseValue(0);
1422 client.clearChooserCompletion();
1423 EXPECT_STREQ("1970-W01", inputElement->value().utf8().data());
1425 openDateTimeChooser(webViewImpl, inputElement);
1426 client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
1427 client.clearChooserCompletion();
1428 EXPECT_STREQ("", inputElement->value().utf8().data());
1432 TEST_F(WebViewTest, DispatchesFocusBlurOnViewToggle)
1434 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "focus_blur_events.html");
1435 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "focus_blur_events.html", true, 0);
1437 webView->setFocus(true);
1438 webView->setFocus(false);
1439 webView->setFocus(true);
1441 WebElement element = webView->mainFrame()->document().getElementById("message");
1442 // Expect not to see duplication of events.
1443 EXPECT_STREQ("blurfocus", element.innerText().utf8().data());
1446 TEST_F(WebViewTest, SmartClipData)
1448 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
1449 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("smartclip.html"));
1450 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "smartclip.html");
1451 webView->resize(WebSize(500, 500));
1453 WebRect cropRect(300, 125, 100, 50);
1455 // FIXME: We should test the structure of the data we get back.
1456 EXPECT_FALSE(webView->getSmartClipData(cropRect).isEmpty());
1459 class CreateChildCounterFrameClient : public FrameTestHelpers::TestWebFrameClient {
1461 CreateChildCounterFrameClient() : m_count(0) { }
1462 virtual WebFrame* createChildFrame(WebFrame* parent, const WebString& frameName) OVERRIDE;
1464 int count() const { return m_count; }
1470 WebFrame* CreateChildCounterFrameClient::createChildFrame(WebFrame* parent, const WebString& frameName)
1473 return TestWebFrameClient::createChildFrame(parent, frameName);
1476 TEST_F(WebViewTest, AddFrameInCloseUnload)
1478 CreateChildCounterFrameClient frameClient;
1479 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1480 m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
1481 m_webViewHelper.reset();
1482 EXPECT_EQ(0, frameClient.count());
1485 TEST_F(WebViewTest, AddFrameInCloseURLUnload)
1487 CreateChildCounterFrameClient frameClient;
1488 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1489 m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
1490 m_webViewHelper.webViewImpl()->dispatchUnloadEvent();
1491 EXPECT_EQ(0, frameClient.count());
1492 m_webViewHelper.reset();
1495 TEST_F(WebViewTest, AddFrameInNavigateUnload)
1497 CreateChildCounterFrameClient frameClient;
1498 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1499 m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
1500 FrameTestHelpers::loadFrame(m_webViewHelper.webView()->mainFrame(), "about:blank");
1501 EXPECT_EQ(0, frameClient.count());
1502 m_webViewHelper.reset();
1505 TEST_F(WebViewTest, AddFrameInChildInNavigateUnload)
1507 CreateChildCounterFrameClient frameClient;
1508 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload_wrapper.html"));
1509 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
1510 m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload_wrapper.html", true, &frameClient);
1511 FrameTestHelpers::loadFrame(m_webViewHelper.webView()->mainFrame(), "about:blank");
1512 EXPECT_EQ(1, frameClient.count());
1513 m_webViewHelper.reset();
1516 class TouchEventHandlerWebViewClient : public WebViewClient {
1518 // WebWidgetClient methods
1519 virtual void hasTouchEventHandlers(bool state) OVERRIDE
1521 m_hasTouchEventHandlerCount[state]++;
1525 TouchEventHandlerWebViewClient() : m_hasTouchEventHandlerCount()
1529 int getAndResetHasTouchEventHandlerCallCount(bool state)
1531 int value = m_hasTouchEventHandlerCount[state];
1532 m_hasTouchEventHandlerCount[state] = 0;
1537 int m_hasTouchEventHandlerCount[2];
1540 // This test verifies that WebWidgetClient::hasTouchEventHandlers is called accordingly for various
1541 // calls to Document::did{Add|Remove|Clear}TouchEventHandler. Verifying that those calls are made
1542 // correctly is the job of LayoutTests/fast/events/touch/touch-handler-count.html.
1543 TEST_F(WebViewTest, HasTouchEventHandlers)
1545 TouchEventHandlerWebViewClient client;
1546 std::string url = m_baseURL + "has_touch_event_handlers.html";
1547 URLTestHelpers::registerMockedURLLoad(toKURL(url), "has_touch_event_handlers.html");
1548 WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
1550 // The page is initialized with at least one no-handlers call.
1551 // In practice we get two such calls because WebViewHelper::initializeAndLoad first
1552 // initializes and empty frame, and then loads a document into it, so there are two
1553 // FrameLoader::commitProvisionalLoad calls.
1554 EXPECT_GE(client.getAndResetHasTouchEventHandlerCallCount(false), 1);
1555 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1557 // Adding the first document handler results in a has-handlers call.
1558 WebCore::Document* document = webViewImpl->mainFrameImpl()->frame()->document();
1559 document->didAddTouchEventHandler(document);
1560 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1561 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1563 // Adding another handler has no effect.
1564 document->didAddTouchEventHandler(document);
1565 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1566 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1568 // Removing the duplicate handler has no effect.
1569 document->didRemoveTouchEventHandler(document);
1570 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1571 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1573 // Removing the final handler results in a no-handlers call.
1574 document->didRemoveTouchEventHandler(document);
1575 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1576 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1578 // Adding a handler on a div results in a has-handlers call.
1579 WebCore::Element* parentDiv = document->getElementById("parentdiv");
1581 document->didAddTouchEventHandler(parentDiv);
1582 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1583 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1585 // Adding a duplicate handler on the div, clearing all document handlers
1586 // (of which there are none) and removing the extra handler on the div
1587 // all have no effect.
1588 document->didAddTouchEventHandler(parentDiv);
1589 document->didClearTouchEventHandlers(document);
1590 document->didRemoveTouchEventHandler(parentDiv);
1591 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1592 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1594 // Removing the final handler on the div results in a no-handlers call.
1595 document->didRemoveTouchEventHandler(parentDiv);
1596 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1597 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1599 // Adding two handlers then clearing them in a single call results in a
1600 // has-handlers then no-handlers call.
1601 document->didAddTouchEventHandler(parentDiv);
1602 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1603 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1604 document->didAddTouchEventHandler(parentDiv);
1605 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1606 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1607 document->didClearTouchEventHandlers(parentDiv);
1608 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1609 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1611 // Adding a handler inside of a child iframe results in a has-handlers call.
1612 WebCore::Element* childFrame = document->getElementById("childframe");
1614 WebCore::Document* childDocument = toHTMLIFrameElement(childFrame)->contentDocument();
1615 WebCore::Element* childDiv = childDocument->getElementById("childdiv");
1617 childDocument->didAddTouchEventHandler(childDiv);
1618 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1619 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1621 // Adding and clearing handlers in the parent doc or elsewhere in the child doc
1623 document->didAddTouchEventHandler(document);
1624 document->didAddTouchEventHandler(childFrame);
1625 childDocument->didAddTouchEventHandler(childDocument);
1626 document->didClearTouchEventHandlers(document);
1627 document->didClearTouchEventHandlers(childFrame);
1628 childDocument->didClearTouchEventHandlers(childDocument);
1629 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1630 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1632 // Removing the final handler inside the child frame results in a no-handlers call.
1633 childDocument->didRemoveTouchEventHandler(childDiv);
1634 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1635 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1637 // Adding a handler inside the child frame results in a has-handlers call.
1638 childDocument->didAddTouchEventHandler(childDocument);
1639 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1640 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
1642 // Adding a handler in the parent document and removing the one in the frame
1644 document->didAddTouchEventHandler(childFrame);
1645 childDocument->didRemoveTouchEventHandler(childDocument);
1646 childDocument->didClearTouchEventHandlers(childDocument);
1647 document->didClearTouchEventHandlers(document);
1648 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
1649 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1651 // Now removing the handler in the parent document results in a no-handlers call.
1652 document->didRemoveTouchEventHandler(childFrame);
1653 EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
1654 EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
1657 static WebRect ExpectedRootBounds(WebCore::Document* document, float scaleFactor)
1659 WebCore::Element* element = document->getElementById("root");
1661 element = document->getElementById("target");
1662 if (element->hasTagName(WebCore::HTMLNames::iframeTag))
1663 return ExpectedRootBounds(toHTMLIFrameElement(element)->contentDocument(), scaleFactor);
1665 WebCore::IntRect boundingBox = element->pixelSnappedBoundingBox();
1666 boundingBox = document->frame()->view()->contentsToWindow(boundingBox);
1667 boundingBox.scale(scaleFactor);
1671 void WebViewTest::testSelectionRootBounds(const char* htmlFile, float pageScaleFactor)
1673 std::string url = m_baseURL + htmlFile;
1675 WebView* webView = m_webViewHelper.initializeAndLoad(url, true);
1676 webView->resize(WebSize(640, 480));
1677 webView->setPageScaleFactor(pageScaleFactor, WebPoint(0, 0));
1681 WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
1682 EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
1683 WebCore::HTMLDocument* document = WebCore::toHTMLDocument(frame->frame()->document());
1685 WebRect expectedRootBounds = ExpectedRootBounds(document, webView->pageScaleFactor());
1686 WebRect actualRootBounds;
1687 webView->getSelectionRootBounds(actualRootBounds);
1688 ASSERT_EQ(expectedRootBounds, actualRootBounds);
1690 WebRect anchor, focus;
1691 webView->selectionBounds(anchor, focus);
1692 WebCore::IntRect expectedIntRect = expectedRootBounds;
1693 ASSERT_TRUE(expectedIntRect.contains(anchor));
1694 // The "overflow" tests have the focus boundary outside of the element box.
1695 ASSERT_EQ(url.find("overflow") == std::string::npos, expectedIntRect.contains(focus));
1698 TEST_F(WebViewTest, GetSelectionRootBounds)
1700 // Register all the pages we will be using.
1701 registerMockedHttpURLLoad("select_range_basic.html");
1702 registerMockedHttpURLLoad("select_range_div_editable.html");
1703 registerMockedHttpURLLoad("select_range_scroll.html");
1704 registerMockedHttpURLLoad("select_range_span_editable.html");
1705 registerMockedHttpURLLoad("select_range_input.html");
1706 registerMockedHttpURLLoad("select_range_input_overflow.html");
1707 registerMockedHttpURLLoad("select_range_textarea.html");
1708 registerMockedHttpURLLoad("select_range_textarea_overflow.html");
1709 registerMockedHttpURLLoad("select_range_iframe.html");
1710 registerMockedHttpURLLoad("select_range_iframe_div_editable.html");
1711 registerMockedHttpURLLoad("select_range_iframe_scroll.html");
1712 registerMockedHttpURLLoad("select_range_iframe_span_editable.html");
1713 registerMockedHttpURLLoad("select_range_iframe_input.html");
1714 registerMockedHttpURLLoad("select_range_iframe_input_overflow.html");
1715 registerMockedHttpURLLoad("select_range_iframe_textarea.html");
1716 registerMockedHttpURLLoad("select_range_iframe_textarea_overflow.html");
1718 // Test with simple pages.
1719 testSelectionRootBounds("select_range_basic.html", 1.0f);
1720 testSelectionRootBounds("select_range_div_editable.html", 1.0f);
1721 testSelectionRootBounds("select_range_scroll.html", 1.0f);
1722 testSelectionRootBounds("select_range_span_editable.html", 1.0f);
1723 testSelectionRootBounds("select_range_input.html", 1.0f);
1724 testSelectionRootBounds("select_range_input_overflow.html", 1.0f);
1725 testSelectionRootBounds("select_range_textarea.html", 1.0f);
1726 testSelectionRootBounds("select_range_textarea_overflow.html", 1.0f);
1728 // Test with the same pages as above in iframes.
1729 testSelectionRootBounds("select_range_iframe.html", 1.0f);
1730 testSelectionRootBounds("select_range_iframe_div_editable.html", 1.0f);
1731 testSelectionRootBounds("select_range_iframe_scroll.html", 1.0f);
1732 testSelectionRootBounds("select_range_iframe_span_editable.html", 1.0f);
1733 testSelectionRootBounds("select_range_iframe_input.html", 1.0f);
1734 testSelectionRootBounds("select_range_iframe_input_overflow.html", 1.0f);
1735 testSelectionRootBounds("select_range_iframe_textarea.html", 1.0f);
1736 testSelectionRootBounds("select_range_iframe_textarea_overflow.html", 1.0f);
1738 // Basic page with scale factor.
1739 testSelectionRootBounds("select_range_basic.html", 0.0f);
1740 testSelectionRootBounds("select_range_basic.html", 0.1f);
1741 testSelectionRootBounds("select_range_basic.html", 1.5f);
1742 testSelectionRootBounds("select_range_basic.html", 2.0f);