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 "bindings/core/v8/V8Document.h"
35 #include "core/dom/Document.h"
36 #include "core/dom/Element.h"
37 #include "core/editing/FrameSelection.h"
38 #include "core/editing/markers/DocumentMarkerController.h"
39 #include "core/frame/EventHandlerRegistry.h"
40 #include "core/frame/FrameHost.h"
41 #include "core/frame/FrameView.h"
42 #include "core/frame/LocalFrame.h"
43 #include "core/frame/Settings.h"
44 #include "core/frame/VisualViewport.h"
45 #include "core/html/HTMLDocument.h"
46 #include "core/html/HTMLIFrameElement.h"
47 #include "core/html/HTMLInputElement.h"
48 #include "core/html/HTMLTextAreaElement.h"
49 #include "core/layout/LayoutView.h"
50 #include "core/loader/DocumentLoader.h"
51 #include "core/loader/FrameLoadRequest.h"
52 #include "core/page/Page.h"
53 #include "core/paint/DeprecatedPaintLayer.h"
54 #include "core/paint/DeprecatedPaintLayerPainter.h"
55 #include "core/timing/DOMWindowPerformance.h"
56 #include "core/timing/Performance.h"
57 #include "core/timing/PerformanceCompositeTiming.h"
58 #include "platform/KeyboardCodes.h"
59 #include "platform/UserGestureIndicator.h"
60 #include "platform/geometry/IntSize.h"
61 #include "platform/graphics/Color.h"
62 #include "platform/graphics/GraphicsContext.h"
63 #include "platform/graphics/paint/SkPictureBuilder.h"
64 #include "platform/testing/URLTestHelpers.h"
65 #include "platform/testing/UnitTestHelpers.h"
66 #include "public/platform/Platform.h"
67 #include "public/platform/WebClipboard.h"
68 #include "public/platform/WebDisplayMode.h"
69 #include "public/platform/WebDragData.h"
70 #include "public/platform/WebSize.h"
71 #include "public/platform/WebThread.h"
72 #include "public/platform/WebUnitTestSupport.h"
73 #include "public/web/WebAutofillClient.h"
74 #include "public/web/WebContentDetectionResult.h"
75 #include "public/web/WebDateTimeChooserCompletion.h"
76 #include "public/web/WebDeviceEmulationParams.h"
77 #include "public/web/WebDocument.h"
78 #include "public/web/WebDragOperation.h"
79 #include "public/web/WebElement.h"
80 #include "public/web/WebFrame.h"
81 #include "public/web/WebFrameClient.h"
82 #include "public/web/WebHitTestResult.h"
83 #include "public/web/WebInputEvent.h"
84 #include "public/web/WebScriptSource.h"
85 #include "public/web/WebSettings.h"
86 #include "public/web/WebTreeScopeType.h"
87 #include "public/web/WebViewClient.h"
88 #include "public/web/WebWidget.h"
89 #include "public/web/WebWidgetClient.h"
90 #include "third_party/skia/include/core/SkBitmap.h"
91 #include "third_party/skia/include/core/SkBitmapDevice.h"
92 #include "third_party/skia/include/core/SkCanvas.h"
93 #include "web/WebLocalFrameImpl.h"
94 #include "web/WebSettingsImpl.h"
95 #include "web/WebViewImpl.h"
96 #include "web/tests/FrameTestHelpers.h"
97 #include <gtest/gtest.h>
99 using blink::FrameTestHelpers::loadFrame
;
100 using blink::URLTestHelpers::toKURL
;
101 using blink::URLTestHelpers::registerMockedURLLoad
;
102 using blink::testing::runPendingTasks
;
106 enum HorizontalScrollbarState
{
107 NoHorizontalScrollbar
,
108 VisibleHorizontalScrollbar
,
111 enum VerticalScrollbarState
{
113 VisibleVerticalScrollbar
,
118 void setWebView(WebView
* webView
) { m_webView
= toWebViewImpl(webView
); }
119 void setSize(const WebSize
& newSize
) { m_size
= newSize
; }
120 HorizontalScrollbarState
horizontalScrollbarState() const
122 return m_webView
->hasHorizontalScrollbar() ? VisibleHorizontalScrollbar
: NoHorizontalScrollbar
;
124 VerticalScrollbarState
verticalScrollbarState() const
126 return m_webView
->hasVerticalScrollbar() ? VisibleVerticalScrollbar
: NoVerticalScrollbar
;
128 int width() const { return m_size
.width
; }
129 int height() const { return m_size
.height
; }
133 WebViewImpl
* m_webView
;
136 class AutoResizeWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
138 // WebViewClient methods
139 void didAutoResize(const WebSize
& newSize
) override
{ m_testData
.setSize(newSize
); }
142 TestData
& testData() { return m_testData
; }
148 class SaveImageFromDataURLWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
150 // WebViewClient methods
151 void saveImageFromDataURL(const WebString
& dataURL
) override
{ m_dataURL
= dataURL
; }
154 const WebString
& result() const { return m_dataURL
; }
155 void reset() { m_dataURL
= WebString(); }
161 class TapHandlingWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
163 // WebViewClient methods
164 void didHandleGestureEvent(const WebGestureEvent
& event
, bool eventCancelled
) override
166 if (event
.type
== WebInputEvent::GestureTap
) {
169 } else if (event
.type
== WebInputEvent::GestureLongPress
) {
170 m_longpressX
= event
.x
;
171 m_longpressY
= event
.y
;
183 int tapX() { return m_tapX
; }
184 int tapY() { return m_tapY
; }
185 int longpressX() { return m_longpressX
; }
186 int longpressY() { return m_longpressY
; }
195 class DateTimeChooserWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
197 WebDateTimeChooserCompletion
* chooserCompletion()
199 return m_chooserCompletion
;
202 void clearChooserCompletion()
204 m_chooserCompletion
= 0;
207 // WebViewClient methods
208 bool openDateTimeChooser(const WebDateTimeChooserParams
&, WebDateTimeChooserCompletion
* chooser_completion
) override
210 m_chooserCompletion
= chooser_completion
;
215 WebDateTimeChooserCompletion
* m_chooserCompletion
;
219 class WebViewTest
: public ::testing::Test
{
222 : m_baseURL("http://www.test.com/")
226 void TearDown() override
228 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
232 void registerMockedHttpURLLoad(const std::string
& fileName
)
234 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8(fileName
.c_str()));
237 void testAutoResize(const WebSize
& minAutoResize
, const WebSize
& maxAutoResize
,
238 const std::string
& pageWidth
, const std::string
& pageHeight
,
239 int expectedWidth
, int expectedHeight
,
240 HorizontalScrollbarState expectedHorizontalState
, VerticalScrollbarState expectedVerticalState
);
242 void testTextInputType(WebTextInputType expectedType
, const std::string
& htmlFile
);
243 void testInputMode(const WebString
& expectedInputMode
, const std::string
& htmlFile
);
245 std::string m_baseURL
;
246 FrameTestHelpers::WebViewHelper m_webViewHelper
;
249 TEST_F(WebViewTest
, SaveImageAt
)
251 SaveImageFromDataURLWebViewClient client
;
253 std::string url
= m_baseURL
+ "image-with-data-url.html";
254 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "image-with-data-url.html");
255 WebViewImpl
* webView
= m_webViewHelper
.initializeAndLoad(url
, true, 0, &client
);
256 webView
->resize(WebSize(400, 400));
260 webView
->saveImageAt(WebPoint(1, 1));
261 EXPECT_EQ(WebString::fromUTF8("data:image/gif;base64"
262 ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), client
.result());
265 webView
->saveImageAt(WebPoint(1, 2));
266 EXPECT_EQ(WebString(), client
.result());
268 webView
->setPageScaleFactor(4);
269 webView
->setVisualViewportOffset(WebFloatPoint(1, 1));
272 webView
->saveImageAt(WebPoint(3, 3));
273 EXPECT_EQ(WebString::fromUTF8("data:image/gif;base64"
274 ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), client
.result());
276 m_webViewHelper
.reset(); // Explicitly reset to break dependency on locally scoped client.
279 TEST_F(WebViewTest
, SaveImageWithImageMap
)
281 SaveImageFromDataURLWebViewClient client
;
283 std::string url
= m_baseURL
+ "image-map.html";
284 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "image-map.html");
285 WebView
* webView
= m_webViewHelper
.initializeAndLoad(url
, true, 0, &client
);
286 webView
->resize(WebSize(400, 400));
289 webView
->saveImageAt(WebPoint(25, 25));
290 EXPECT_EQ(WebString::fromUTF8("data:image/gif;base64"
291 ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), client
.result());
294 webView
->saveImageAt(WebPoint(75, 25));
295 EXPECT_EQ(WebString::fromUTF8("data:image/gif;base64"
296 ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), client
.result());
299 webView
->saveImageAt(WebPoint(125, 25));
300 EXPECT_EQ(WebString(), client
.result());
302 m_webViewHelper
.reset(); // Explicitly reset to break dependency on locally scoped client.
305 TEST_F(WebViewTest
, CopyImageAt
)
307 std::string url
= m_baseURL
+ "canvas-copy-image.html";
308 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "canvas-copy-image.html");
309 WebView
* webView
= m_webViewHelper
.initializeAndLoad(url
, true, 0);
310 webView
->resize(WebSize(400, 400));
312 uint64_t sequence
= Platform::current()->clipboard()->sequenceNumber(WebClipboard::BufferStandard
);
314 webView
->copyImageAt(WebPoint(50, 50));
316 EXPECT_NE(sequence
, Platform::current()->clipboard()->sequenceNumber(WebClipboard::BufferStandard
));
318 WebData data
= Platform::current()->clipboard()->readImage(WebClipboard::Buffer());
319 WebImage image
= WebImage::fromData(data
, WebSize());
321 SkAutoLockPixels
autoLock(image
.getSkBitmap());
322 EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image
.getSkBitmap().getColor(0, 0));
325 TEST_F(WebViewTest
, CopyImageAtWithPinchZoom
)
327 std::string url
= m_baseURL
+ "canvas-copy-image.html";
328 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "canvas-copy-image.html");
329 WebViewImpl
* webView
= m_webViewHelper
.initializeAndLoad(url
, true, 0);
330 webView
->resize(WebSize(400, 400));
332 webView
->setPageScaleFactor(2);
333 webView
->setVisualViewportOffset(WebFloatPoint(200, 200));
335 uint64_t sequence
= Platform::current()->clipboard()->sequenceNumber(WebClipboard::BufferStandard
);
337 webView
->copyImageAt(WebPoint(0, 0));
339 EXPECT_NE(sequence
, Platform::current()->clipboard()->sequenceNumber(WebClipboard::BufferStandard
));
341 WebData data
= Platform::current()->clipboard()->readImage(WebClipboard::Buffer());
342 WebImage image
= WebImage::fromData(data
, WebSize());
344 SkAutoLockPixels
autoLock(image
.getSkBitmap());
345 EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image
.getSkBitmap().getColor(0, 0));
348 TEST_F(WebViewTest
, CopyImageWithImageMap
)
350 SaveImageFromDataURLWebViewClient client
;
352 std::string url
= m_baseURL
+ "image-map.html";
353 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "image-map.html");
354 WebView
* webView
= m_webViewHelper
.initializeAndLoad(url
, true, 0, &client
);
355 webView
->resize(WebSize(400, 400));
358 webView
->saveImageAt(WebPoint(25, 25));
359 EXPECT_EQ(WebString::fromUTF8("data:image/gif;base64"
360 ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), client
.result());
363 webView
->saveImageAt(WebPoint(75, 25));
364 EXPECT_EQ(WebString::fromUTF8("data:image/gif;base64"
365 ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), client
.result());
368 webView
->saveImageAt(WebPoint(125, 25));
369 EXPECT_EQ(WebString(), client
.result());
371 m_webViewHelper
.reset(); // Explicitly reset to break dependency on locally scoped client.
374 static bool hitTestIsContentEditable(WebView
* view
, int x
, int y
)
376 WebPoint
hitPoint(x
, y
);
377 WebHitTestResult hitTestResult
= view
->hitTestResultAt(hitPoint
);
378 return hitTestResult
.isContentEditable();
381 static std::string
hitTestElementId(WebView
* view
, int x
, int y
)
383 WebPoint
hitPoint(x
, y
);
384 WebHitTestResult hitTestResult
= view
->hitTestResultAt(hitPoint
);
385 return hitTestResult
.node().to
<WebElement
>().getAttribute("id").utf8();
388 TEST_F(WebViewTest
, HitTestContentEditableImageMaps
)
390 std::string url
= m_baseURL
+ "content-editable-image-maps.html";
391 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "content-editable-image-maps.html");
392 WebView
* webView
= m_webViewHelper
.initializeAndLoad(url
, true, 0);
393 webView
->resize(WebSize(500, 500));
395 EXPECT_EQ("areaANotEditable", hitTestElementId(webView
, 25, 25));
396 EXPECT_FALSE(hitTestIsContentEditable(webView
, 25, 25));
397 EXPECT_EQ("imageANotEditable", hitTestElementId(webView
, 75, 25));
398 EXPECT_FALSE(hitTestIsContentEditable(webView
, 75, 25));
400 EXPECT_EQ("areaBNotEditable", hitTestElementId(webView
, 25, 125));
401 EXPECT_FALSE(hitTestIsContentEditable(webView
, 25, 125));
402 EXPECT_EQ("imageBEditable", hitTestElementId(webView
, 75, 125));
403 EXPECT_TRUE(hitTestIsContentEditable(webView
, 75, 125));
405 EXPECT_EQ("areaCNotEditable", hitTestElementId(webView
, 25, 225));
406 EXPECT_FALSE(hitTestIsContentEditable(webView
, 25, 225));
407 EXPECT_EQ("imageCNotEditable", hitTestElementId(webView
, 75, 225));
408 EXPECT_FALSE(hitTestIsContentEditable(webView
, 75, 225));
410 EXPECT_EQ("areaDEditable", hitTestElementId(webView
, 25, 325));
411 EXPECT_TRUE(hitTestIsContentEditable(webView
, 25, 325));
412 EXPECT_EQ("imageDNotEditable", hitTestElementId(webView
, 75, 325));
413 EXPECT_FALSE(hitTestIsContentEditable(webView
, 75, 325));
416 static std::string
hitTestAbsoluteUrl(WebView
* view
, int x
, int y
)
418 WebPoint
hitPoint(x
, y
);
419 WebHitTestResult hitTestResult
= view
->hitTestResultAt(hitPoint
);
420 return hitTestResult
.absoluteImageURL().string().utf8();
423 static WebElement
hitTestUrlElement(WebView
* view
, int x
, int y
)
425 WebPoint
hitPoint(x
, y
);
426 WebHitTestResult hitTestResult
= view
->hitTestResultAt(hitPoint
);
427 return hitTestResult
.urlElement();
430 TEST_F(WebViewTest
, ImageMapUrls
)
432 std::string url
= m_baseURL
+ "image-map.html";
433 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "image-map.html");
434 WebView
* webView
= m_webViewHelper
.initializeAndLoad(url
, true, 0);
435 webView
->resize(WebSize(400, 400));
437 std::string imageUrl
= "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=";
439 EXPECT_EQ("area", hitTestElementId(webView
, 25, 25));
440 EXPECT_EQ("area", hitTestUrlElement(webView
, 25, 25).getAttribute("id").utf8());
441 EXPECT_EQ(imageUrl
, hitTestAbsoluteUrl(webView
, 25, 25));
443 EXPECT_EQ("image", hitTestElementId(webView
, 75, 25));
444 EXPECT_TRUE(hitTestUrlElement(webView
, 75, 25).isNull());
445 EXPECT_EQ(imageUrl
, hitTestAbsoluteUrl(webView
, 75, 25));
448 TEST_F(WebViewTest
, SetBaseBackgroundColor
)
450 const WebColor kWhite
= 0xFFFFFFFF;
451 const WebColor kBlue
= 0xFF0000FF;
452 const WebColor kDarkCyan
= 0xFF227788;
453 const WebColor kTranslucentPutty
= 0x80BFB196;
454 const WebColor kTransparent
= 0x00000000;
456 WebViewImpl
* webView
= m_webViewHelper
.initialize();
457 EXPECT_EQ(kWhite
, webView
->backgroundColor());
459 webView
->setBaseBackgroundColor(kBlue
);
460 EXPECT_EQ(kBlue
, webView
->backgroundColor());
462 WebURL baseURL
= URLTestHelpers::toKURL("http://example.com/");
463 FrameTestHelpers::loadHTMLString(webView
->mainFrame(), "<html><head><style>body {background-color:#227788}</style></head></html>", baseURL
);
464 EXPECT_EQ(kDarkCyan
, webView
->backgroundColor());
466 FrameTestHelpers::loadHTMLString(webView
->mainFrame(), "<html><head><style>body {background-color:rgba(255,0,0,0.5)}</style></head></html>", baseURL
);
467 // Expected: red (50% alpha) blended atop base of kBlue.
468 EXPECT_EQ(0xFF7F0080, webView
->backgroundColor());
470 webView
->setBaseBackgroundColor(kTranslucentPutty
);
471 // Expected: red (50% alpha) blended atop kTranslucentPutty. Note the alpha.
472 EXPECT_EQ(0xBFE93B32, webView
->backgroundColor());
474 webView
->setBaseBackgroundColor(kTransparent
);
475 FrameTestHelpers::loadHTMLString(webView
->mainFrame(), "<html><head><style>body {background-color:transparent}</style></head></html>", baseURL
);
476 // Expected: transparent on top of kTransparent will still be transparent.
477 EXPECT_EQ(kTransparent
, webView
->backgroundColor());
479 LocalFrame
* frame
= webView
->mainFrameImpl()->frame();
480 // The detach() and dispose() calls are a hack to prevent this test
481 // from violating invariants about frame state during navigation/detach.
482 frame
->document()->detach();
484 // Creating a new frame view with the background color having 0 alpha.
485 frame
->createView(IntSize(1024, 768), Color::transparent
, true);
486 EXPECT_EQ(kTransparent
, frame
->view()->baseBackgroundColor());
487 frame
->view()->dispose();
489 Color
kTransparentRed(100, 0, 0, 0);
490 frame
->createView(IntSize(1024, 768), kTransparentRed
, true);
491 EXPECT_EQ(kTransparentRed
, frame
->view()->baseBackgroundColor());
492 frame
->view()->dispose();
495 TEST_F(WebViewTest
, SetBaseBackgroundColorBeforeMainFrame
)
497 const WebColor kBlue
= 0xFF0000FF;
498 FrameTestHelpers::TestWebViewClient webViewClient
;
499 WebView
* webView
= WebViewImpl::create(&webViewClient
);
500 EXPECT_NE(kBlue
, webView
->backgroundColor());
501 // webView does not have a frame yet, but we should still be able to set the background color.
502 webView
->setBaseBackgroundColor(kBlue
);
503 EXPECT_EQ(kBlue
, webView
->backgroundColor());
504 WebLocalFrameImpl
* frame
= WebLocalFrameImpl::create(WebTreeScopeType::Document
, nullptr);
505 webView
->setMainFrame(frame
);
510 TEST_F(WebViewTest
, SetBaseBackgroundColorAndBlendWithExistingContent
)
512 const WebColor kAlphaRed
= 0x80FF0000;
513 const WebColor kAlphaGreen
= 0x8000FF00;
514 const int kWidth
= 100;
515 const int kHeight
= 100;
517 WebView
* webView
= m_webViewHelper
.initialize();
519 // Set WebView background to green with alpha.
520 webView
->setBaseBackgroundColor(kAlphaGreen
);
521 webView
->settings()->setShouldClearDocumentBackground(false);
522 webView
->resize(WebSize(kWidth
, kHeight
));
525 // Set canvas background to red with alpha.
527 bitmap
.allocN32Pixels(kWidth
, kHeight
);
528 SkCanvas
canvas(bitmap
);
529 canvas
.clear(kAlphaRed
);
531 SkPictureBuilder
pictureBuilder(FloatRect(0, 0, kWidth
, kHeight
));
533 // Paint the root of the main frame in the way that CompositedLayerMapping would.
534 FrameView
* view
= m_webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
535 DeprecatedPaintLayer
* rootLayer
= view
->layoutView()->layer();
536 LayoutRect
paintRect(0, 0, kWidth
, kHeight
);
537 DeprecatedPaintLayerPaintingInfo
paintingInfo(rootLayer
, paintRect
, GlobalPaintNormalPhase
, LayoutSize());
538 DeprecatedPaintLayerPainter(*rootLayer
).paintLayerContents(&pictureBuilder
.context(), paintingInfo
, PaintLayerPaintingCompositingAllPhases
);
540 pictureBuilder
.endRecording()->playback(&canvas
);
542 // The result should be a blend of red and green.
543 SkColor color
= bitmap
.getColor(kWidth
/ 2, kHeight
/ 2);
544 EXPECT_TRUE(redChannel(color
));
545 EXPECT_TRUE(greenChannel(color
));
548 TEST_F(WebViewTest
, FocusIsInactive
)
550 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), "visible_iframe.html");
551 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "visible_iframe.html");
553 webView
->setFocus(true);
554 webView
->setIsActive(true);
555 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
556 EXPECT_TRUE(frame
->frame()->document()->isHTMLDocument());
558 HTMLDocument
* document
= toHTMLDocument(frame
->frame()->document());
559 EXPECT_TRUE(document
->hasFocus());
560 webView
->setFocus(false);
561 webView
->setIsActive(false);
562 EXPECT_FALSE(document
->hasFocus());
563 webView
->setFocus(true);
564 webView
->setIsActive(true);
565 EXPECT_TRUE(document
->hasFocus());
566 webView
->setFocus(true);
567 webView
->setIsActive(false);
568 EXPECT_FALSE(document
->hasFocus());
569 webView
->setFocus(false);
570 webView
->setIsActive(true);
571 EXPECT_FALSE(document
->hasFocus());
574 TEST_F(WebViewTest
, ActiveState
)
576 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), "visible_iframe.html");
577 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "visible_iframe.html");
579 ASSERT_TRUE(webView
);
581 webView
->setIsActive(true);
582 EXPECT_TRUE(webView
->isActive());
584 webView
->setIsActive(false);
585 EXPECT_FALSE(webView
->isActive());
587 webView
->setIsActive(true);
588 EXPECT_TRUE(webView
->isActive());
591 TEST_F(WebViewTest
, HitTestResultAtWithPageScale
)
593 std::string url
= m_baseURL
+ "specify_size.html?" + "50px" + ":" + "50px";
594 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "specify_size.html");
595 WebView
* webView
= m_webViewHelper
.initializeAndLoad(url
, true, 0);
596 webView
->resize(WebSize(100, 100));
597 WebPoint
hitPoint(75, 75);
599 // Image is at top left quandrant, so should not hit it.
600 WebHitTestResult negativeResult
= webView
->hitTestResultAt(hitPoint
);
601 ASSERT_EQ(WebNode::ElementNode
, negativeResult
.node().nodeType());
602 EXPECT_FALSE(negativeResult
.node().to
<WebElement
>().hasHTMLTagName("img"));
603 negativeResult
.reset();
605 // Scale page up 2x so image should occupy the whole viewport.
606 webView
->setPageScaleFactor(2.0f
);
607 WebHitTestResult positiveResult
= webView
->hitTestResultAt(hitPoint
);
608 ASSERT_EQ(WebNode::ElementNode
, positiveResult
.node().nodeType());
609 EXPECT_TRUE(positiveResult
.node().to
<WebElement
>().hasHTMLTagName("img"));
610 positiveResult
.reset();
613 TEST_F(WebViewTest
, HitTestResultAtWithPageScaleAndPan
)
615 std::string url
= m_baseURL
+ "specify_size.html?" + "50px" + ":" + "50px";
616 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "specify_size.html");
617 WebView
* webView
= m_webViewHelper
.initialize(true);
618 loadFrame(webView
->mainFrame(), url
);
619 webView
->resize(WebSize(100, 100));
620 WebPoint
hitPoint(75, 75);
622 // Image is at top left quandrant, so should not hit it.
623 WebHitTestResult negativeResult
= webView
->hitTestResultAt(hitPoint
);
624 ASSERT_EQ(WebNode::ElementNode
, negativeResult
.node().nodeType());
625 EXPECT_FALSE(negativeResult
.node().to
<WebElement
>().hasHTMLTagName("img"));
626 negativeResult
.reset();
628 // Scale page up 2x so image should occupy the whole viewport.
629 webView
->setPageScaleFactor(2.0f
);
630 WebHitTestResult positiveResult
= webView
->hitTestResultAt(hitPoint
);
631 ASSERT_EQ(WebNode::ElementNode
, positiveResult
.node().nodeType());
632 EXPECT_TRUE(positiveResult
.node().to
<WebElement
>().hasHTMLTagName("img"));
633 positiveResult
.reset();
635 // Pan around the zoomed in page so the image is not visible in viewport.
636 webView
->setVisualViewportOffset(WebFloatPoint(100, 100));
637 WebHitTestResult negativeResult2
= webView
->hitTestResultAt(hitPoint
);
638 ASSERT_EQ(WebNode::ElementNode
, negativeResult2
.node().nodeType());
639 EXPECT_FALSE(negativeResult2
.node().to
<WebElement
>().hasHTMLTagName("img"));
640 negativeResult2
.reset();
643 TEST_F(WebViewTest
, HitTestResultForTapWithTapArea
)
645 std::string url
= m_baseURL
+ "hit_test.html";
646 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "hit_test.html");
647 WebView
* webView
= m_webViewHelper
.initializeAndLoad(url
, true, 0);
648 webView
->resize(WebSize(100, 100));
649 WebPoint
hitPoint(55, 55);
651 // Image is at top left quandrant, so should not hit it.
652 WebHitTestResult negativeResult
= webView
->hitTestResultAt(hitPoint
);
653 ASSERT_EQ(WebNode::ElementNode
, negativeResult
.node().nodeType());
654 EXPECT_FALSE(negativeResult
.node().to
<WebElement
>().hasHTMLTagName("img"));
655 negativeResult
.reset();
657 // The tap area is 20 by 20 square, centered at 55, 55.
658 WebSize
tapArea(20, 20);
659 WebHitTestResult positiveResult
= webView
->hitTestResultForTap(hitPoint
, tapArea
);
660 ASSERT_EQ(WebNode::ElementNode
, positiveResult
.node().nodeType());
661 EXPECT_TRUE(positiveResult
.node().to
<WebElement
>().hasHTMLTagName("img"));
662 positiveResult
.reset();
664 // Move the hit point the image is just outside the tapped area now.
665 hitPoint
= WebPoint(61, 61);
666 WebHitTestResult negativeResult2
= webView
->hitTestResultForTap(hitPoint
, tapArea
);
667 ASSERT_EQ(WebNode::ElementNode
, negativeResult2
.node().nodeType());
668 EXPECT_FALSE(negativeResult2
.node().to
<WebElement
>().hasHTMLTagName("img"));
669 negativeResult2
.reset();
672 TEST_F(WebViewTest
, HitTestResultForTapWithTapAreaPageScaleAndPan
)
674 std::string url
= m_baseURL
+ "hit_test.html";
675 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "hit_test.html");
676 WebView
* webView
= m_webViewHelper
.initialize(true);
677 loadFrame(webView
->mainFrame(), url
);
678 webView
->resize(WebSize(100, 100));
679 WebPoint
hitPoint(55, 55);
681 // Image is at top left quandrant, so should not hit it.
682 WebHitTestResult negativeResult
= webView
->hitTestResultAt(hitPoint
);
683 ASSERT_EQ(WebNode::ElementNode
, negativeResult
.node().nodeType());
684 EXPECT_FALSE(negativeResult
.node().to
<WebElement
>().hasHTMLTagName("img"));
685 negativeResult
.reset();
687 // The tap area is 20 by 20 square, centered at 55, 55.
688 WebSize
tapArea(20, 20);
689 WebHitTestResult positiveResult
= webView
->hitTestResultForTap(hitPoint
, tapArea
);
690 ASSERT_EQ(WebNode::ElementNode
, positiveResult
.node().nodeType());
691 EXPECT_TRUE(positiveResult
.node().to
<WebElement
>().hasHTMLTagName("img"));
692 positiveResult
.reset();
694 // Zoom in and pan around the page so the image is not visible in viewport.
695 webView
->setPageScaleFactor(2.0f
);
696 webView
->setVisualViewportOffset(WebFloatPoint(100, 100));
697 WebHitTestResult negativeResult2
= webView
->hitTestResultForTap(hitPoint
, tapArea
);
698 ASSERT_EQ(WebNode::ElementNode
, negativeResult2
.node().nodeType());
699 EXPECT_FALSE(negativeResult2
.node().to
<WebElement
>().hasHTMLTagName("img"));
700 negativeResult2
.reset();
703 void WebViewTest::testAutoResize(const WebSize
& minAutoResize
, const WebSize
& maxAutoResize
,
704 const std::string
& pageWidth
, const std::string
& pageHeight
,
705 int expectedWidth
, int expectedHeight
,
706 HorizontalScrollbarState expectedHorizontalState
, VerticalScrollbarState expectedVerticalState
)
708 AutoResizeWebViewClient client
;
709 std::string url
= m_baseURL
+ "specify_size.html?" + pageWidth
+ ":" + pageHeight
;
710 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "specify_size.html");
711 WebView
* webView
= m_webViewHelper
.initializeAndLoad(url
, true, 0, &client
);
712 client
.testData().setWebView(webView
);
714 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
715 FrameView
* frameView
= frame
->frame()->view();
717 EXPECT_FALSE(frameView
->layoutPending());
718 EXPECT_FALSE(frameView
->needsLayout());
720 webView
->enableAutoResizeMode(minAutoResize
, maxAutoResize
);
721 EXPECT_TRUE(frameView
->layoutPending());
722 EXPECT_TRUE(frameView
->needsLayout());
725 EXPECT_TRUE(frame
->frame()->document()->isHTMLDocument());
727 EXPECT_EQ(expectedWidth
, client
.testData().width());
728 EXPECT_EQ(expectedHeight
, client
.testData().height());
730 // Android disables main frame scrollbars.
732 EXPECT_EQ(expectedHorizontalState
, client
.testData().horizontalScrollbarState());
733 EXPECT_EQ(expectedVerticalState
, client
.testData().verticalScrollbarState());
736 m_webViewHelper
.reset(); // Explicitly reset to break dependency on locally scoped client.
739 TEST_F(WebViewTest
, AutoResizeMinimumSize
)
741 WebSize
minAutoResize(91, 56);
742 WebSize
maxAutoResize(403, 302);
743 std::string pageWidth
= "91px";
744 std::string pageHeight
= "56px";
745 int expectedWidth
= 91;
746 int expectedHeight
= 56;
747 testAutoResize(minAutoResize
, maxAutoResize
, pageWidth
, pageHeight
,
748 expectedWidth
, expectedHeight
, NoHorizontalScrollbar
, NoVerticalScrollbar
);
751 TEST_F(WebViewTest
, AutoResizeHeightOverflowAndFixedWidth
)
753 WebSize
minAutoResize(90, 95);
754 WebSize
maxAutoResize(90, 100);
755 std::string pageWidth
= "60px";
756 std::string pageHeight
= "200px";
757 int expectedWidth
= 90;
758 int expectedHeight
= 100;
759 testAutoResize(minAutoResize
, maxAutoResize
, pageWidth
, pageHeight
,
760 expectedWidth
, expectedHeight
, NoHorizontalScrollbar
, VisibleVerticalScrollbar
);
763 TEST_F(WebViewTest
, AutoResizeFixedHeightAndWidthOverflow
)
765 WebSize
minAutoResize(90, 100);
766 WebSize
maxAutoResize(200, 100);
767 std::string pageWidth
= "300px";
768 std::string pageHeight
= "80px";
769 int expectedWidth
= 200;
770 int expectedHeight
= 100;
771 testAutoResize(minAutoResize
, maxAutoResize
, pageWidth
, pageHeight
,
772 expectedWidth
, expectedHeight
, VisibleHorizontalScrollbar
, NoVerticalScrollbar
);
775 // Next three tests disabled for https://bugs.webkit.org/show_bug.cgi?id=92318 .
776 // It seems we can run three AutoResize tests, then the next one breaks.
777 TEST_F(WebViewTest
, AutoResizeInBetweenSizes
)
779 WebSize
minAutoResize(90, 95);
780 WebSize
maxAutoResize(200, 300);
781 std::string pageWidth
= "100px";
782 std::string pageHeight
= "200px";
783 int expectedWidth
= 100;
784 int expectedHeight
= 200;
785 testAutoResize(minAutoResize
, maxAutoResize
, pageWidth
, pageHeight
,
786 expectedWidth
, expectedHeight
, NoHorizontalScrollbar
, NoVerticalScrollbar
);
789 TEST_F(WebViewTest
, AutoResizeOverflowSizes
)
791 WebSize
minAutoResize(90, 95);
792 WebSize
maxAutoResize(200, 300);
793 std::string pageWidth
= "300px";
794 std::string pageHeight
= "400px";
795 int expectedWidth
= 200;
796 int expectedHeight
= 300;
797 testAutoResize(minAutoResize
, maxAutoResize
, pageWidth
, pageHeight
,
798 expectedWidth
, expectedHeight
, VisibleHorizontalScrollbar
, VisibleVerticalScrollbar
);
801 TEST_F(WebViewTest
, AutoResizeMaxSize
)
803 WebSize
minAutoResize(90, 95);
804 WebSize
maxAutoResize(200, 300);
805 std::string pageWidth
= "200px";
806 std::string pageHeight
= "300px";
807 int expectedWidth
= 200;
808 int expectedHeight
= 300;
809 testAutoResize(minAutoResize
, maxAutoResize
, pageWidth
, pageHeight
,
810 expectedWidth
, expectedHeight
, NoHorizontalScrollbar
, NoVerticalScrollbar
);
813 void WebViewTest::testTextInputType(WebTextInputType expectedType
, const std::string
& htmlFile
)
815 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8(htmlFile
.c_str()));
816 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ htmlFile
);
817 webView
->setInitialFocus(false);
818 EXPECT_EQ(expectedType
, webView
->textInputInfo().type
);
821 TEST_F(WebViewTest
, TextInputType
)
823 testTextInputType(WebTextInputTypeText
, "input_field_default.html");
824 testTextInputType(WebTextInputTypePassword
, "input_field_password.html");
825 testTextInputType(WebTextInputTypeEmail
, "input_field_email.html");
826 testTextInputType(WebTextInputTypeSearch
, "input_field_search.html");
827 testTextInputType(WebTextInputTypeNumber
, "input_field_number.html");
828 testTextInputType(WebTextInputTypeTelephone
, "input_field_tel.html");
829 testTextInputType(WebTextInputTypeURL
, "input_field_url.html");
832 void WebViewTest::testInputMode(const WebString
& expectedInputMode
, const std::string
& htmlFile
)
834 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8(htmlFile
.c_str()));
835 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ htmlFile
);
836 webView
->setInitialFocus(false);
837 EXPECT_EQ(expectedInputMode
, webView
->textInputInfo().inputMode
);
840 TEST_F(WebViewTest
, InputMode
)
842 testInputMode(WebString(), "input_mode_default.html");
843 testInputMode(WebString("unknown"), "input_mode_default_unknown.html");
844 testInputMode(WebString("verbatim"), "input_mode_default_verbatim.html");
845 testInputMode(WebString("verbatim"), "input_mode_type_text_verbatim.html");
846 testInputMode(WebString("verbatim"), "input_mode_type_search_verbatim.html");
847 testInputMode(WebString(), "input_mode_type_url_verbatim.html");
848 testInputMode(WebString("verbatim"), "input_mode_textarea_verbatim.html");
851 TEST_F(WebViewTest
, TextInputInfoWithReplacedElements
)
853 std::string url
= m_baseURL
+ "div_with_image.html";
854 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "div_with_image.html");
855 WebView
* webView
= m_webViewHelper
.initializeAndLoad(url
);
856 webView
->setInitialFocus(false);
857 WebTextInputInfo info
= webView
->textInputInfo();
859 EXPECT_EQ("foo\xef\xbf\xbc", info
.value
.utf8());
862 TEST_F(WebViewTest
, SetEditableSelectionOffsetsAndTextInputInfo
)
864 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("input_field_populated.html"));
865 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "input_field_populated.html");
866 webView
->setInitialFocus(false);
867 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
868 frame
->setEditableSelectionOffsets(5, 13);
869 EXPECT_EQ("56789abc", frame
->selectionAsText());
870 WebTextInputInfo info
= webView
->textInputInfo();
871 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info
.value
);
872 EXPECT_EQ(5, info
.selectionStart
);
873 EXPECT_EQ(13, info
.selectionEnd
);
874 EXPECT_EQ(-1, info
.compositionStart
);
875 EXPECT_EQ(-1, info
.compositionEnd
);
877 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("content_editable_populated.html"));
878 webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "content_editable_populated.html");
879 webView
->setInitialFocus(false);
880 frame
= toWebLocalFrameImpl(webView
->mainFrame());
881 frame
->setEditableSelectionOffsets(8, 19);
882 EXPECT_EQ("89abcdefghi", frame
->selectionAsText());
883 info
= webView
->textInputInfo();
884 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info
.value
);
885 EXPECT_EQ(8, info
.selectionStart
);
886 EXPECT_EQ(19, info
.selectionEnd
);
887 EXPECT_EQ(-1, info
.compositionStart
);
888 EXPECT_EQ(-1, info
.compositionEnd
);
891 TEST_F(WebViewTest
, ConfirmCompositionCursorPositionChange
)
893 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("input_field_populated.html"));
894 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "input_field_populated.html");
895 webView
->setInitialFocus(false);
897 // Set up a composition that needs to be committed.
898 std::string
compositionText("hello");
900 WebVector
<WebCompositionUnderline
> emptyUnderlines
;
901 webView
->setComposition(WebString::fromUTF8(compositionText
.c_str()), emptyUnderlines
, 3, 3);
903 WebTextInputInfo info
= webView
->textInputInfo();
904 EXPECT_EQ("hello", std::string(info
.value
.utf8().data()));
905 EXPECT_EQ(3, info
.selectionStart
);
906 EXPECT_EQ(3, info
.selectionEnd
);
907 EXPECT_EQ(0, info
.compositionStart
);
908 EXPECT_EQ(5, info
.compositionEnd
);
910 webView
->confirmComposition(WebWidget::KeepSelection
);
911 info
= webView
->textInputInfo();
912 EXPECT_EQ(3, info
.selectionStart
);
913 EXPECT_EQ(3, info
.selectionEnd
);
914 EXPECT_EQ(-1, info
.compositionStart
);
915 EXPECT_EQ(-1, info
.compositionEnd
);
917 webView
->setComposition(WebString::fromUTF8(compositionText
.c_str()), emptyUnderlines
, 3, 3);
918 info
= webView
->textInputInfo();
919 EXPECT_EQ("helhellolo", std::string(info
.value
.utf8().data()));
920 EXPECT_EQ(6, info
.selectionStart
);
921 EXPECT_EQ(6, info
.selectionEnd
);
922 EXPECT_EQ(3, info
.compositionStart
);
923 EXPECT_EQ(8, info
.compositionEnd
);
925 webView
->confirmComposition(WebWidget::DoNotKeepSelection
);
926 info
= webView
->textInputInfo();
927 EXPECT_EQ(8, info
.selectionStart
);
928 EXPECT_EQ(8, info
.selectionEnd
);
929 EXPECT_EQ(-1, info
.compositionStart
);
930 EXPECT_EQ(-1, info
.compositionEnd
);
933 TEST_F(WebViewTest
, InsertNewLinePlacementAfterConfirmComposition
)
935 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("text_area_populated.html"));
936 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "text_area_populated.html");
937 webView
->setInitialFocus(false);
939 WebVector
<WebCompositionUnderline
> emptyUnderlines
;
941 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
942 frame
->setEditableSelectionOffsets(4, 4);
943 frame
->setCompositionFromExistingText(8, 12, emptyUnderlines
);
945 WebTextInputInfo info
= webView
->textInputInfo();
946 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info
.value
.utf8().data()));
947 EXPECT_EQ(4, info
.selectionStart
);
948 EXPECT_EQ(4, info
.selectionEnd
);
949 EXPECT_EQ(8, info
.compositionStart
);
950 EXPECT_EQ(12, info
.compositionEnd
);
952 webView
->confirmComposition(WebWidget::KeepSelection
);
953 info
= webView
->textInputInfo();
954 EXPECT_EQ(4, info
.selectionStart
);
955 EXPECT_EQ(4, info
.selectionEnd
);
956 EXPECT_EQ(-1, info
.compositionStart
);
957 EXPECT_EQ(-1, info
.compositionEnd
);
959 std::string
compositionText("\n");
960 webView
->confirmComposition(WebString::fromUTF8(compositionText
.c_str()));
961 info
= webView
->textInputInfo();
962 EXPECT_EQ(5, info
.selectionStart
);
963 EXPECT_EQ(5, info
.selectionEnd
);
964 EXPECT_EQ(-1, info
.compositionStart
);
965 EXPECT_EQ(-1, info
.compositionEnd
);
966 EXPECT_EQ("0123\n456789abcdefghijklmnopqrstuvwxyz", std::string(info
.value
.utf8().data()));
969 TEST_F(WebViewTest
, ExtendSelectionAndDelete
)
971 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("input_field_populated.html"));
972 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "input_field_populated.html");
973 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
974 webView
->setInitialFocus(false);
975 frame
->setEditableSelectionOffsets(10, 10);
976 frame
->extendSelectionAndDelete(5, 8);
977 WebTextInputInfo info
= webView
->textInputInfo();
978 EXPECT_EQ("01234ijklmnopqrstuvwxyz", std::string(info
.value
.utf8().data()));
979 EXPECT_EQ(5, info
.selectionStart
);
980 EXPECT_EQ(5, info
.selectionEnd
);
981 frame
->extendSelectionAndDelete(10, 0);
982 info
= webView
->textInputInfo();
983 EXPECT_EQ("ijklmnopqrstuvwxyz", std::string(info
.value
.utf8().data()));
986 TEST_F(WebViewTest
, SetCompositionFromExistingText
)
988 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("input_field_populated.html"));
989 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "input_field_populated.html");
990 webView
->setInitialFocus(false);
991 WebVector
<WebCompositionUnderline
> underlines(static_cast<size_t>(1));
992 underlines
[0] = WebCompositionUnderline(0, 4, 0, false, 0);
993 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
994 frame
->setEditableSelectionOffsets(4, 10);
995 frame
->setCompositionFromExistingText(8, 12, underlines
);
996 WebTextInputInfo info
= webView
->textInputInfo();
997 EXPECT_EQ(4, info
.selectionStart
);
998 EXPECT_EQ(10, info
.selectionEnd
);
999 EXPECT_EQ(8, info
.compositionStart
);
1000 EXPECT_EQ(12, info
.compositionEnd
);
1001 WebVector
<WebCompositionUnderline
> emptyUnderlines
;
1002 frame
->setCompositionFromExistingText(0, 0, emptyUnderlines
);
1003 info
= webView
->textInputInfo();
1004 EXPECT_EQ(4, info
.selectionStart
);
1005 EXPECT_EQ(10, info
.selectionEnd
);
1006 EXPECT_EQ(-1, info
.compositionStart
);
1007 EXPECT_EQ(-1, info
.compositionEnd
);
1010 TEST_F(WebViewTest
, SetCompositionFromExistingTextInTextArea
)
1012 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("text_area_populated.html"));
1013 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "text_area_populated.html");
1014 webView
->setInitialFocus(false);
1015 WebVector
<WebCompositionUnderline
> underlines(static_cast<size_t>(1));
1016 underlines
[0] = WebCompositionUnderline(0, 4, 0, false, 0);
1017 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
1018 frame
->setEditableSelectionOffsets(27, 27);
1019 std::string
newLineText("\n");
1020 webView
->confirmComposition(WebString::fromUTF8(newLineText
.c_str()));
1021 WebTextInputInfo info
= webView
->textInputInfo();
1022 EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info
.value
.utf8().data()));
1024 frame
->setEditableSelectionOffsets(31, 31);
1025 frame
->setCompositionFromExistingText(30, 34, underlines
);
1026 info
= webView
->textInputInfo();
1027 EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info
.value
.utf8().data()));
1028 EXPECT_EQ(31, info
.selectionStart
);
1029 EXPECT_EQ(31, info
.selectionEnd
);
1030 EXPECT_EQ(30, info
.compositionStart
);
1031 EXPECT_EQ(34, info
.compositionEnd
);
1033 std::string
compositionText("yolo");
1034 webView
->confirmComposition(WebString::fromUTF8(compositionText
.c_str()));
1035 info
= webView
->textInputInfo();
1036 EXPECT_EQ("0123456789abcdefghijklmnopq\nrsyoloxyz", std::string(info
.value
.utf8().data()));
1037 EXPECT_EQ(34, info
.selectionStart
);
1038 EXPECT_EQ(34, info
.selectionEnd
);
1039 EXPECT_EQ(-1, info
.compositionStart
);
1040 EXPECT_EQ(-1, info
.compositionEnd
);
1043 TEST_F(WebViewTest
, SetCompositionFromExistingTextInRichText
)
1045 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("content_editable_rich_text.html"));
1046 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "content_editable_rich_text.html");
1047 webView
->setInitialFocus(false);
1048 WebVector
<WebCompositionUnderline
> underlines(static_cast<size_t>(1));
1049 underlines
[0] = WebCompositionUnderline(0, 4, 0, false, 0);
1050 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
1051 frame
->setEditableSelectionOffsets(1, 1);
1052 WebDocument document
= webView
->mainFrame()->document();
1053 EXPECT_FALSE(document
.getElementById("bold").isNull());
1054 frame
->setCompositionFromExistingText(0, 4, underlines
);
1055 EXPECT_FALSE(document
.getElementById("bold").isNull());
1058 TEST_F(WebViewTest
, SetEditableSelectionOffsetsKeepsComposition
)
1060 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("input_field_populated.html"));
1061 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "input_field_populated.html");
1062 webView
->setInitialFocus(false);
1064 std::string
compositionTextFirst("hello ");
1065 std::string
compositionTextSecond("world");
1066 WebVector
<WebCompositionUnderline
> emptyUnderlines
;
1068 webView
->confirmComposition(WebString::fromUTF8(compositionTextFirst
.c_str()));
1069 webView
->setComposition(WebString::fromUTF8(compositionTextSecond
.c_str()), emptyUnderlines
, 5, 5);
1071 WebTextInputInfo info
= webView
->textInputInfo();
1072 EXPECT_EQ("hello world", std::string(info
.value
.utf8().data()));
1073 EXPECT_EQ(11, info
.selectionStart
);
1074 EXPECT_EQ(11, info
.selectionEnd
);
1075 EXPECT_EQ(6, info
.compositionStart
);
1076 EXPECT_EQ(11, info
.compositionEnd
);
1078 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
1079 frame
->setEditableSelectionOffsets(6, 6);
1080 info
= webView
->textInputInfo();
1081 EXPECT_EQ("hello world", std::string(info
.value
.utf8().data()));
1082 EXPECT_EQ(6, info
.selectionStart
);
1083 EXPECT_EQ(6, info
.selectionEnd
);
1084 EXPECT_EQ(6, info
.compositionStart
);
1085 EXPECT_EQ(11, info
.compositionEnd
);
1087 frame
->setEditableSelectionOffsets(8, 8);
1088 info
= webView
->textInputInfo();
1089 EXPECT_EQ("hello world", std::string(info
.value
.utf8().data()));
1090 EXPECT_EQ(8, info
.selectionStart
);
1091 EXPECT_EQ(8, info
.selectionEnd
);
1092 EXPECT_EQ(6, info
.compositionStart
);
1093 EXPECT_EQ(11, info
.compositionEnd
);
1095 frame
->setEditableSelectionOffsets(11, 11);
1096 info
= webView
->textInputInfo();
1097 EXPECT_EQ("hello world", std::string(info
.value
.utf8().data()));
1098 EXPECT_EQ(11, info
.selectionStart
);
1099 EXPECT_EQ(11, info
.selectionEnd
);
1100 EXPECT_EQ(6, info
.compositionStart
);
1101 EXPECT_EQ(11, info
.compositionEnd
);
1103 frame
->setEditableSelectionOffsets(6, 11);
1104 info
= webView
->textInputInfo();
1105 EXPECT_EQ("hello world", std::string(info
.value
.utf8().data()));
1106 EXPECT_EQ(6, info
.selectionStart
);
1107 EXPECT_EQ(11, info
.selectionEnd
);
1108 EXPECT_EQ(6, info
.compositionStart
);
1109 EXPECT_EQ(11, info
.compositionEnd
);
1111 frame
->setEditableSelectionOffsets(2, 2);
1112 info
= webView
->textInputInfo();
1113 EXPECT_EQ("hello world", std::string(info
.value
.utf8().data()));
1114 EXPECT_EQ(2, info
.selectionStart
);
1115 EXPECT_EQ(2, info
.selectionEnd
);
1116 EXPECT_EQ(-1, info
.compositionStart
);
1117 EXPECT_EQ(-1, info
.compositionEnd
);
1120 TEST_F(WebViewTest
, IsSelectionAnchorFirst
)
1122 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("input_field_populated.html"));
1123 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "input_field_populated.html");
1124 WebFrame
* frame
= webView
->mainFrame();
1126 webView
->setInitialFocus(false);
1127 frame
->setEditableSelectionOffsets(4, 10);
1128 EXPECT_TRUE(webView
->isSelectionAnchorFirst());
1131 webView
->selectionBounds(anchor
, focus
);
1132 frame
->selectRange(WebPoint(focus
.x
, focus
.y
), WebPoint(anchor
.x
, anchor
.y
));
1133 EXPECT_FALSE(webView
->isSelectionAnchorFirst());
1136 TEST_F(WebViewTest
, ExitingDeviceEmulationResetsPageScale
)
1138 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("200-by-300.html"));
1139 WebViewImpl
* webViewImpl
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "200-by-300.html");
1140 webViewImpl
->resize(WebSize(200, 300));
1142 float pageScaleExpected
= webViewImpl
->pageScaleFactor();
1144 WebDeviceEmulationParams params
;
1145 params
.screenPosition
= WebDeviceEmulationParams::Desktop
;
1146 params
.deviceScaleFactor
= 0;
1147 params
.fitToView
= false;
1148 params
.offset
= WebFloatPoint();
1151 webViewImpl
->enableDeviceEmulation(params
);
1153 webViewImpl
->setPageScaleFactor(2);
1155 webViewImpl
->disableDeviceEmulation();
1157 EXPECT_EQ(pageScaleExpected
, webViewImpl
->pageScaleFactor());
1160 TEST_F(WebViewTest
, HistoryResetScrollAndScaleState
)
1162 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("200-by-300.html"));
1163 WebViewImpl
* webViewImpl
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "200-by-300.html");
1164 webViewImpl
->resize(WebSize(100, 150));
1165 webViewImpl
->layout();
1166 EXPECT_EQ(0, webViewImpl
->mainFrame()->scrollOffset().width
);
1167 EXPECT_EQ(0, webViewImpl
->mainFrame()->scrollOffset().height
);
1169 // Make the page scale and scroll with the given paremeters.
1170 webViewImpl
->setPageScaleFactor(2.0f
);
1171 webViewImpl
->mainFrame()->setScrollOffset(WebSize(94, 111));
1172 EXPECT_EQ(2.0f
, webViewImpl
->pageScaleFactor());
1173 EXPECT_EQ(94, webViewImpl
->mainFrame()->scrollOffset().width
);
1174 EXPECT_EQ(111, webViewImpl
->mainFrame()->scrollOffset().height
);
1175 LocalFrame
* mainFrameLocal
= toLocalFrame(webViewImpl
->page()->mainFrame());
1176 mainFrameLocal
->loader().saveScrollState();
1177 EXPECT_EQ(2.0f
, mainFrameLocal
->loader().currentItem()->pageScaleFactor());
1178 EXPECT_EQ(94, mainFrameLocal
->loader().currentItem()->scrollPoint().x());
1179 EXPECT_EQ(111, mainFrameLocal
->loader().currentItem()->scrollPoint().y());
1181 // Confirm that resetting the page state resets the saved scroll position.
1182 webViewImpl
->resetScrollAndScaleState();
1183 EXPECT_EQ(1.0f
, webViewImpl
->pageScaleFactor());
1184 EXPECT_EQ(0, webViewImpl
->mainFrame()->scrollOffset().width
);
1185 EXPECT_EQ(0, webViewImpl
->mainFrame()->scrollOffset().height
);
1186 EXPECT_EQ(1.0f
, mainFrameLocal
->loader().currentItem()->pageScaleFactor());
1187 EXPECT_EQ(0, mainFrameLocal
->loader().currentItem()->scrollPoint().x());
1188 EXPECT_EQ(0, mainFrameLocal
->loader().currentItem()->scrollPoint().y());
1191 TEST_F(WebViewTest
, BackForwardRestoreScroll
)
1193 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("back_forward_restore_scroll.html"));
1194 WebViewImpl
* webViewImpl
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "back_forward_restore_scroll.html");
1195 webViewImpl
->resize(WebSize(640, 480));
1196 webViewImpl
->layout();
1198 // Emulate a user scroll
1199 webViewImpl
->mainFrame()->setScrollOffset(WebSize(0, 900));
1200 LocalFrame
* mainFrameLocal
= toLocalFrame(webViewImpl
->page()->mainFrame());
1201 RefPtrWillBePersistent
<HistoryItem
> item1
= mainFrameLocal
->loader().currentItem();
1204 mainFrameLocal
->loader().load(FrameLoadRequest(mainFrameLocal
->document(), ResourceRequest(mainFrameLocal
->document()->completeURL("#a"))));
1205 RefPtrWillBePersistent
<HistoryItem
> item2
= mainFrameLocal
->loader().currentItem();
1207 // Go back, then forward, then back again.
1208 mainFrameLocal
->loader().load(
1209 FrameLoadRequest(nullptr, FrameLoader::resourceRequestFromHistoryItem(
1210 item1
.get(), UseProtocolCachePolicy
)),
1211 FrameLoadTypeBackForward
, item1
.get(), HistorySameDocumentLoad
);
1212 mainFrameLocal
->loader().load(
1213 FrameLoadRequest(nullptr, FrameLoader::resourceRequestFromHistoryItem(
1214 item2
.get(), UseProtocolCachePolicy
)),
1215 FrameLoadTypeBackForward
, item2
.get(), HistorySameDocumentLoad
);
1216 mainFrameLocal
->loader().load(
1217 FrameLoadRequest(nullptr, FrameLoader::resourceRequestFromHistoryItem(
1218 item1
.get(), UseProtocolCachePolicy
)),
1219 FrameLoadTypeBackForward
, item1
.get(), HistorySameDocumentLoad
);
1221 // Click a different anchor
1222 mainFrameLocal
->loader().load(FrameLoadRequest(mainFrameLocal
->document(), ResourceRequest(mainFrameLocal
->document()->completeURL("#b"))));
1223 RefPtrWillBePersistent
<HistoryItem
> item3
= mainFrameLocal
->loader().currentItem();
1225 // Go back, then forward. The scroll position should be properly set on the forward navigation.
1226 mainFrameLocal
->loader().load(
1227 FrameLoadRequest(nullptr, FrameLoader::resourceRequestFromHistoryItem(
1228 item1
.get(), UseProtocolCachePolicy
)),
1229 FrameLoadTypeBackForward
, item1
.get(), HistorySameDocumentLoad
);
1230 mainFrameLocal
->loader().load(
1231 FrameLoadRequest(nullptr, FrameLoader::resourceRequestFromHistoryItem(
1232 item3
.get(), UseProtocolCachePolicy
)),
1233 FrameLoadTypeBackForward
, item3
.get(), HistorySameDocumentLoad
);
1234 EXPECT_EQ(0, webViewImpl
->mainFrame()->scrollOffset().width
);
1235 EXPECT_GT(webViewImpl
->mainFrame()->scrollOffset().height
, 2000);
1238 TEST_F(WebViewTest
, EnterFullscreenResetScrollAndScaleState
)
1240 FrameTestHelpers::TestWebViewClient client
;
1241 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("200-by-300.html"));
1242 WebViewImpl
* webViewImpl
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "200-by-300.html", true, 0, &client
);
1243 webViewImpl
->resize(WebSize(100, 150));
1244 webViewImpl
->layout();
1245 EXPECT_EQ(0, webViewImpl
->mainFrame()->scrollOffset().width
);
1246 EXPECT_EQ(0, webViewImpl
->mainFrame()->scrollOffset().height
);
1248 // Make the page scale and scroll with the given paremeters.
1249 webViewImpl
->setPageScaleFactor(2.0f
);
1250 webViewImpl
->mainFrame()->setScrollOffset(WebSize(94, 111));
1251 webViewImpl
->setVisualViewportOffset(WebFloatPoint(12, 20));
1252 EXPECT_EQ(2.0f
, webViewImpl
->pageScaleFactor());
1253 EXPECT_EQ(94, webViewImpl
->mainFrame()->scrollOffset().width
);
1254 EXPECT_EQ(111, webViewImpl
->mainFrame()->scrollOffset().height
);
1255 EXPECT_EQ(12, webViewImpl
->visualViewportOffset().x
);
1256 EXPECT_EQ(20, webViewImpl
->visualViewportOffset().y
);
1258 RefPtrWillBeRawPtr
<Element
> element
= static_cast<PassRefPtrWillBeRawPtr
<Element
>>(webViewImpl
->mainFrame()->document().body());
1259 webViewImpl
->enterFullScreenForElement(element
.get());
1260 webViewImpl
->didEnterFullScreen();
1262 // Page scale factor must be 1.0 during fullscreen for elements to be sized
1264 EXPECT_EQ(1.0f
, webViewImpl
->pageScaleFactor());
1266 // Make sure fullscreen nesting doesn't disrupt scroll/scale saving.
1267 RefPtrWillBeRawPtr
<Element
> otherElement
= static_cast<PassRefPtrWillBeRawPtr
<Element
>>(webViewImpl
->mainFrame()->document().head());
1268 webViewImpl
->enterFullScreenForElement(otherElement
.get());
1270 // Confirm that exiting fullscreen restores the parameters.
1271 webViewImpl
->didExitFullScreen();
1272 EXPECT_EQ(2.0f
, webViewImpl
->pageScaleFactor());
1273 EXPECT_EQ(94, webViewImpl
->mainFrame()->scrollOffset().width
);
1274 EXPECT_EQ(111, webViewImpl
->mainFrame()->scrollOffset().height
);
1275 EXPECT_EQ(12, webViewImpl
->visualViewportOffset().x
);
1276 EXPECT_EQ(20, webViewImpl
->visualViewportOffset().y
);
1278 m_webViewHelper
.reset(); // Explicitly reset to break dependency on locally scoped client.
1281 class PrintWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
1283 PrintWebViewClient()
1284 : m_printCalled(false)
1288 // WebViewClient methods
1289 void printPage(WebLocalFrame
*) override
1291 m_printCalled
= true;
1294 bool printCalled() const { return m_printCalled
; }
1301 TEST_F(WebViewTest
, PrintWithXHRInFlight
)
1303 PrintWebViewClient client
;
1304 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("print_with_xhr_inflight.html"));
1305 WebViewImpl
* webViewImpl
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "print_with_xhr_inflight.html", true, 0, &client
);
1307 ASSERT_TRUE(toLocalFrame(webViewImpl
->page()->mainFrame())->document()->loadEventFinished());
1308 EXPECT_TRUE(client
.printCalled());
1309 m_webViewHelper
.reset();
1312 class DropTask
: public WebTaskRunner::Task
{
1314 explicit DropTask(WebView
* webView
) : m_webView(webView
)
1320 const WebPoint
clientPoint(0, 0);
1321 const WebPoint
screenPoint(0, 0);
1322 m_webView
->dragTargetDrop(clientPoint
, screenPoint
, 0);
1326 WebView
* const m_webView
;
1328 static void DragAndDropURL(WebViewImpl
* webView
, const std::string
& url
)
1330 WebDragData dragData
;
1331 dragData
.initialize();
1333 WebDragData::Item item
;
1334 item
.storageType
= WebDragData::Item::StorageTypeString
;
1335 item
.stringType
= "text/uri-list";
1336 item
.stringData
= WebString::fromUTF8(url
);
1337 dragData
.addItem(item
);
1339 const WebPoint
clientPoint(0, 0);
1340 const WebPoint
screenPoint(0, 0);
1341 webView
->dragTargetDragEnter(dragData
, clientPoint
, screenPoint
, WebDragOperationCopy
, 0);
1342 Platform::current()->currentThread()->taskRunner()->postTask(FROM_HERE
, new DropTask(webView
));
1343 FrameTestHelpers::pumpPendingRequestsDoNotUse(webView
->mainFrame());
1346 TEST_F(WebViewTest
, DragDropURL
)
1348 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), "foo.html");
1349 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), "bar.html");
1351 const std::string fooUrl
= m_baseURL
+ "foo.html";
1352 const std::string barUrl
= m_baseURL
+ "bar.html";
1354 WebViewImpl
* webView
= m_webViewHelper
.initializeAndLoad(fooUrl
);
1356 ASSERT_TRUE(webView
);
1358 // Drag and drop barUrl and verify that we've navigated to it.
1359 DragAndDropURL(webView
, barUrl
);
1360 EXPECT_EQ(barUrl
, webView
->mainFrame()->document().url().string().utf8());
1362 // Drag and drop fooUrl and verify that we've navigated back to it.
1363 DragAndDropURL(webView
, fooUrl
);
1364 EXPECT_EQ(fooUrl
, webView
->mainFrame()->document().url().string().utf8());
1366 // Disable navigation on drag-and-drop.
1367 webView
->settingsImpl()->setNavigateOnDragDrop(false);
1369 // Attempt to drag and drop to barUrl and verify that no navigation has occurred.
1370 DragAndDropURL(webView
, barUrl
);
1371 EXPECT_EQ(fooUrl
, webView
->mainFrame()->document().url().string().utf8());
1374 class ContentDetectorClient
: public FrameTestHelpers::TestWebViewClient
{
1376 ContentDetectorClient() { reset(); }
1378 WebContentDetectionResult
detectContentAround(const WebHitTestResult
& hitTest
) override
1380 m_contentDetectionRequested
= true;
1381 return m_contentDetectionResult
;
1384 void scheduleContentIntent(const WebURL
& url
) override
1386 m_scheduledIntentURL
= url
;
1389 void cancelScheduledContentIntents() override
1391 m_pendingIntentsCancelled
= true;
1396 m_contentDetectionRequested
= false;
1397 m_pendingIntentsCancelled
= false;
1398 m_scheduledIntentURL
= WebURL();
1399 m_contentDetectionResult
= WebContentDetectionResult();
1402 bool contentDetectionRequested() const { return m_contentDetectionRequested
; }
1403 bool pendingIntentsCancelled() const { return m_pendingIntentsCancelled
; }
1404 const WebURL
& scheduledIntentURL() const { return m_scheduledIntentURL
; }
1405 void setContentDetectionResult(const WebContentDetectionResult
& result
) { m_contentDetectionResult
= result
; }
1408 bool m_contentDetectionRequested
;
1409 bool m_pendingIntentsCancelled
;
1410 WebURL m_scheduledIntentURL
;
1411 WebContentDetectionResult m_contentDetectionResult
;
1414 static bool tapElementById(WebView
* webView
, WebInputEvent::Type type
, const WebString
& id
)
1417 RefPtrWillBeRawPtr
<Element
> element
= static_cast<PassRefPtrWillBeRawPtr
<Element
>>(webView
->mainFrame()->document().getElementById(id
));
1421 element
->scrollIntoViewIfNeeded();
1423 // TODO(bokan): Technically incorrect, event positions should be in viewport space. crbug.com/371902.
1424 IntPoint center
= element
->screenRect().center();
1426 WebGestureEvent event
;
1428 event
.x
= center
.x();
1429 event
.y
= center
.y();
1431 webView
->handleInputEvent(event
);
1436 TEST_F(WebViewTest
, DetectContentAroundPosition
)
1438 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("content_listeners.html"));
1440 ContentDetectorClient client
;
1441 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "content_listeners.html", true, 0, &client
);
1442 webView
->resize(WebSize(500, 300));
1446 WebString clickListener
= WebString::fromUTF8("clickListener");
1447 WebString touchstartListener
= WebString::fromUTF8("touchstartListener");
1448 WebString mousedownListener
= WebString::fromUTF8("mousedownListener");
1449 WebString noListener
= WebString::fromUTF8("noListener");
1450 WebString link
= WebString::fromUTF8("link");
1452 // Ensure content detection is not requested for nodes listening to click,
1453 // mouse or touch events when we do simple taps.
1454 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureTap
, clickListener
));
1455 EXPECT_FALSE(client
.contentDetectionRequested());
1458 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureTap
, touchstartListener
));
1459 EXPECT_FALSE(client
.contentDetectionRequested());
1462 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureTap
, mousedownListener
));
1463 EXPECT_FALSE(client
.contentDetectionRequested());
1466 // Content detection should work normally without these event listeners.
1467 // The click listener in the body should be ignored as a special case.
1468 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureTap
, noListener
));
1469 EXPECT_TRUE(client
.contentDetectionRequested());
1470 EXPECT_FALSE(client
.scheduledIntentURL().isValid());
1472 WebURL intentURL
= toKURL(m_baseURL
);
1473 client
.setContentDetectionResult(WebContentDetectionResult(WebRange(), WebString(), intentURL
));
1474 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureTap
, noListener
));
1475 EXPECT_TRUE(client
.scheduledIntentURL() == intentURL
);
1477 // Tapping elsewhere should cancel the scheduled intent.
1478 WebGestureEvent event
;
1479 event
.type
= WebInputEvent::GestureTap
;
1480 webView
->handleInputEvent(event
);
1482 EXPECT_TRUE(client
.pendingIntentsCancelled());
1484 m_webViewHelper
.reset(); // Explicitly reset to break dependency on locally scoped client.
1487 TEST_F(WebViewTest
, ClientTapHandling
)
1489 TapHandlingWebViewClient client
;
1491 WebView
* webView
= m_webViewHelper
.initializeAndLoad("about:blank", true, 0, &client
);
1492 WebGestureEvent event
;
1493 event
.type
= WebInputEvent::GestureTap
;
1496 webView
->handleInputEvent(event
);
1498 EXPECT_EQ(3, client
.tapX());
1499 EXPECT_EQ(8, client
.tapY());
1501 event
.type
= WebInputEvent::GestureLongPress
;
1504 webView
->handleInputEvent(event
);
1506 EXPECT_EQ(25, client
.longpressX());
1507 EXPECT_EQ(7, client
.longpressY());
1509 m_webViewHelper
.reset(); // Explicitly reset to break dependency on locally scoped client.
1512 TEST_F(WebViewTest
, ClientTapHandlingNullWebViewClient
)
1514 WebViewImpl
* webView
= WebViewImpl::create(nullptr);
1515 WebLocalFrame
* localFrame
= WebLocalFrame::create(WebTreeScopeType::Document
, nullptr);
1516 webView
->setMainFrame(localFrame
);
1517 WebGestureEvent event
;
1518 event
.type
= WebInputEvent::GestureTap
;
1521 EXPECT_FALSE(webView
->handleInputEvent(event
));
1523 // Explicitly close as the frame as no frame client to do so on frameDetached().
1524 localFrame
->close();
1528 TEST_F(WebViewTest
, LongPressSelection
)
1530 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("longpress_selection.html"));
1532 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "longpress_selection.html", true);
1533 webView
->resize(WebSize(500, 300));
1537 WebString target
= WebString::fromUTF8("target");
1538 WebString onselectstartfalse
= WebString::fromUTF8("onselectstartfalse");
1539 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
1541 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureLongPress
, onselectstartfalse
));
1542 EXPECT_EQ("", std::string(frame
->selectionAsText().utf8().data()));
1543 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureLongPress
, target
));
1544 EXPECT_EQ("testword", std::string(frame
->selectionAsText().utf8().data()));
1547 TEST_F(WebViewTest
, BlinkCaretOnTypingAfterLongPress
)
1549 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("blink_caret_on_typing_after_long_press.html"));
1551 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "blink_caret_on_typing_after_long_press.html", true);
1552 webView
->resize(WebSize(640, 480));
1556 WebString target
= WebString::fromUTF8("target");
1557 WebLocalFrameImpl
* mainFrame
= toWebLocalFrameImpl(webView
->mainFrame());
1559 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureLongPress
, target
));
1560 EXPECT_TRUE(mainFrame
->frame()->selection().isCaretBlinkingSuspended());
1562 WebKeyboardEvent keyEvent
;
1563 keyEvent
.type
= WebInputEvent::RawKeyDown
;
1564 webView
->handleInputEvent(keyEvent
);
1565 keyEvent
.type
= WebInputEvent::KeyUp
;
1566 webView
->handleInputEvent(keyEvent
);
1567 EXPECT_FALSE(mainFrame
->frame()->selection().isCaretBlinkingSuspended());
1571 TEST_F(WebViewTest
, SelectionOnReadOnlyInput
)
1573 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("selection_readonly.html"));
1574 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "selection_readonly.html", true);
1575 webView
->resize(WebSize(640, 480));
1579 std::string testWord
= "This text should be selected.";
1581 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
1582 EXPECT_EQ(testWord
, std::string(frame
->selectionAsText().utf8().data()));
1586 EXPECT_TRUE(toWebViewImpl(webView
)->caretOrSelectionRange(&location
, &length
));
1587 EXPECT_EQ(location
, 0UL);
1588 EXPECT_EQ(length
, testWord
.length());
1591 static void configueCompositingWebView(WebSettings
* settings
)
1593 settings
->setAcceleratedCompositingEnabled(true);
1594 settings
->setPreferCompositingToLCDTextEnabled(true);
1597 TEST_F(WebViewTest
, ShowPressOnTransformedLink
)
1599 OwnPtr
<FrameTestHelpers::TestWebViewClient
> fakeCompositingWebViewClient
= adoptPtr(new FrameTestHelpers::TestWebViewClient());
1600 FrameTestHelpers::WebViewHelper webViewHelper
;
1601 WebViewImpl
* webViewImpl
= webViewHelper
.initialize(true, 0, fakeCompositingWebViewClient
.get(), &configueCompositingWebView
);
1603 int pageWidth
= 640;
1604 int pageHeight
= 480;
1605 webViewImpl
->resize(WebSize(pageWidth
, pageHeight
));
1607 WebURL baseURL
= URLTestHelpers::toKURL("http://example.com/");
1608 FrameTestHelpers::loadHTMLString(webViewImpl
->mainFrame(), "<a href='http://www.test.com' style='position: absolute; left: 20px; top: 20px; width: 200px; transform:translateZ(0);'>A link to highlight</a>", baseURL
);
1610 WebGestureEvent event
;
1611 event
.type
= WebInputEvent::GestureShowPress
;
1615 // Just make sure we don't hit any asserts.
1616 webViewImpl
->handleInputEvent(event
);
1619 class MockAutofillClient
: public WebAutofillClient
{
1621 MockAutofillClient()
1622 : m_ignoreTextChanges(false)
1623 , m_textChangesFromUserGesture(0)
1624 , m_textChangesWhileIgnored(0)
1625 , m_textChangesWhileNotIgnored(0)
1626 , m_userGestureNotificationsCount(0) {}
1628 ~MockAutofillClient() override
{}
1630 void setIgnoreTextChanges(bool ignore
) override
{ m_ignoreTextChanges
= ignore
; }
1631 void textFieldDidChange(const WebFormControlElement
&) override
1633 if (m_ignoreTextChanges
)
1634 ++m_textChangesWhileIgnored
;
1636 ++m_textChangesWhileNotIgnored
;
1638 if (UserGestureIndicator::processingUserGesture())
1639 ++m_textChangesFromUserGesture
;
1641 void firstUserGestureObserved() override
{ ++m_userGestureNotificationsCount
; }
1643 void clearChangeCounts()
1645 m_textChangesWhileIgnored
= 0;
1646 m_textChangesWhileNotIgnored
= 0;
1649 int textChangesFromUserGesture() { return m_textChangesFromUserGesture
; }
1650 int textChangesWhileIgnored() { return m_textChangesWhileIgnored
; }
1651 int textChangesWhileNotIgnored() { return m_textChangesWhileNotIgnored
; }
1652 int getUserGestureNotificationsCount() { return m_userGestureNotificationsCount
; }
1655 bool m_ignoreTextChanges
;
1656 int m_textChangesFromUserGesture
;
1657 int m_textChangesWhileIgnored
;
1658 int m_textChangesWhileNotIgnored
;
1659 int m_userGestureNotificationsCount
;
1663 TEST_F(WebViewTest
, LosingFocusDoesNotTriggerAutofillTextChange
)
1665 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("input_field_populated.html"));
1666 MockAutofillClient client
;
1667 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "input_field_populated.html");
1668 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
1669 frame
->setAutofillClient(&client
);
1670 webView
->setInitialFocus(false);
1672 // Set up a composition that needs to be committed.
1673 WebVector
<WebCompositionUnderline
> emptyUnderlines
;
1674 frame
->setEditableSelectionOffsets(4, 10);
1675 frame
->setCompositionFromExistingText(8, 12, emptyUnderlines
);
1676 WebTextInputInfo info
= webView
->textInputInfo();
1677 EXPECT_EQ(4, info
.selectionStart
);
1678 EXPECT_EQ(10, info
.selectionEnd
);
1679 EXPECT_EQ(8, info
.compositionStart
);
1680 EXPECT_EQ(12, info
.compositionEnd
);
1682 // Clear the focus and track that the subsequent composition commit does not trigger a
1683 // text changed notification for autofill.
1684 client
.clearChangeCounts();
1685 webView
->setFocus(false);
1686 EXPECT_EQ(0, client
.textChangesWhileNotIgnored());
1688 frame
->setAutofillClient(0);
1691 static void verifySelectionAndComposition(WebView
* webView
, int selectionStart
, int selectionEnd
, int compositionStart
, int compositionEnd
, const char* failMessage
)
1693 WebTextInputInfo info
= webView
->textInputInfo();
1694 EXPECT_EQ(selectionStart
, info
.selectionStart
) << failMessage
;
1695 EXPECT_EQ(selectionEnd
, info
.selectionEnd
) << failMessage
;
1696 EXPECT_EQ(compositionStart
, info
.compositionStart
) << failMessage
;
1697 EXPECT_EQ(compositionEnd
, info
.compositionEnd
) << failMessage
;
1700 TEST_F(WebViewTest
, CompositionNotCancelledByBackspace
)
1702 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("composition_not_cancelled_by_backspace.html"));
1703 MockAutofillClient client
;
1704 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "composition_not_cancelled_by_backspace.html");
1705 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
1706 frame
->setAutofillClient(&client
);
1707 webView
->setInitialFocus(false);
1709 // Test both input elements.
1710 for (int i
= 0; i
< 2; ++i
) {
1711 // Select composition and do sanity check.
1712 WebVector
<WebCompositionUnderline
> emptyUnderlines
;
1713 frame
->setEditableSelectionOffsets(6, 6);
1714 EXPECT_TRUE(webView
->setComposition("fghij", emptyUnderlines
, 0, 5));
1715 frame
->setEditableSelectionOffsets(11, 11);
1716 verifySelectionAndComposition(webView
, 11, 11, 6, 11, "initial case");
1718 // Press Backspace and verify composition didn't get cancelled. This is to verify the fix
1719 // for crbug.com/429916.
1720 WebKeyboardEvent keyEvent
;
1721 keyEvent
.windowsKeyCode
= VKEY_BACK
;
1722 keyEvent
.setKeyIdentifierFromWindowsKeyCode();
1723 keyEvent
.type
= WebInputEvent::RawKeyDown
;
1724 webView
->handleInputEvent(keyEvent
);
1726 frame
->setEditableSelectionOffsets(6, 6);
1727 EXPECT_TRUE(webView
->setComposition("fghi", emptyUnderlines
, 0, 4));
1728 frame
->setEditableSelectionOffsets(10, 10);
1729 verifySelectionAndComposition(webView
, 10, 10, 6, 10, "after pressing Backspace");
1731 keyEvent
.type
= WebInputEvent::KeyUp
;
1732 webView
->handleInputEvent(keyEvent
);
1734 webView
->advanceFocus(false);
1737 frame
->setAutofillClient(0);
1740 TEST_F(WebViewTest
, ConfirmCompositionTriggersAutofillTextChange
)
1742 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("input_field_populated.html"));
1743 MockAutofillClient client
;
1744 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "input_field_populated.html");
1745 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
1746 frame
->setAutofillClient(&client
);
1747 webView
->setInitialFocus(false);
1749 // Set up a composition that needs to be committed.
1750 std::string
compositionText("testingtext");
1752 WebVector
<WebCompositionUnderline
> emptyUnderlines
;
1753 webView
->setComposition(WebString::fromUTF8(compositionText
.c_str()), emptyUnderlines
, 0, compositionText
.length());
1755 WebTextInputInfo info
= webView
->textInputInfo();
1756 EXPECT_EQ(0, info
.selectionStart
);
1757 EXPECT_EQ((int) compositionText
.length(), info
.selectionEnd
);
1758 EXPECT_EQ(0, info
.compositionStart
);
1759 EXPECT_EQ((int) compositionText
.length(), info
.compositionEnd
);
1761 client
.clearChangeCounts();
1762 webView
->confirmComposition();
1763 EXPECT_EQ(0, client
.textChangesWhileIgnored());
1764 EXPECT_EQ(1, client
.textChangesWhileNotIgnored());
1766 frame
->setAutofillClient(0);
1769 TEST_F(WebViewTest
, SetCompositionFromExistingTextTriggersAutofillTextChange
)
1771 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("input_field_populated.html"));
1772 MockAutofillClient client
;
1773 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "input_field_populated.html", true);
1774 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
1775 frame
->setAutofillClient(&client
);
1776 webView
->setInitialFocus(false);
1778 WebVector
<WebCompositionUnderline
> emptyUnderlines
;
1780 client
.clearChangeCounts();
1781 frame
->setCompositionFromExistingText(8, 12, emptyUnderlines
);
1783 WebTextInputInfo info
= webView
->textInputInfo();
1784 EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info
.value
.utf8().data()));
1785 EXPECT_EQ(8, info
.compositionStart
);
1786 EXPECT_EQ(12, info
.compositionEnd
);
1788 EXPECT_EQ(0, client
.textChangesWhileIgnored());
1789 EXPECT_EQ(0, client
.textChangesWhileNotIgnored());
1791 WebDocument document
= webView
->mainFrame()->document();
1792 EXPECT_EQ(WebString::fromUTF8("none"), document
.getElementById("inputEvent").firstChild().nodeValue());
1794 frame
->setAutofillClient(0);
1797 class ViewCreatingWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
1799 ViewCreatingWebViewClient()
1800 : m_didFocusCalled(false)
1804 // WebViewClient methods
1805 WebView
* createView(WebLocalFrame
*, const WebURLRequest
&, const WebWindowFeatures
&, const WebString
& name
, WebNavigationPolicy
, bool) override
1807 return m_webViewHelper
.initialize(true, 0, 0);
1810 // WebWidgetClient methods
1811 void didFocus() override
1813 m_didFocusCalled
= true;
1816 bool didFocusCalled() const { return m_didFocusCalled
; }
1817 WebView
* createdWebView() const { return m_webViewHelper
.webView(); }
1820 FrameTestHelpers::WebViewHelper m_webViewHelper
;
1821 bool m_didFocusCalled
;
1824 TEST_F(WebViewTest
, DoNotFocusCurrentFrameOnNavigateFromLocalFrame
)
1826 ViewCreatingWebViewClient client
;
1827 FrameTestHelpers::WebViewHelper m_webViewHelper
;
1828 WebViewImpl
* webViewImpl
= m_webViewHelper
.initialize(true, 0, &client
);
1829 webViewImpl
->page()->settings().setJavaScriptCanOpenWindowsAutomatically(true);
1831 WebURL baseURL
= URLTestHelpers::toKURL("http://example.com/");
1832 FrameTestHelpers::loadHTMLString(webViewImpl
->mainFrame(), "<html><body><iframe src=\"about:blank\"></iframe></body></html>", baseURL
);
1834 // Make a request from a local frame.
1835 WebURLRequest webURLRequestWithTargetStart
;
1836 webURLRequestWithTargetStart
.initialize();
1837 LocalFrame
* localFrame
= toWebLocalFrameImpl(webViewImpl
->mainFrame()->firstChild())->frame();
1838 FrameLoadRequest
requestWithTargetStart(localFrame
->document(), webURLRequestWithTargetStart
.toResourceRequest(), "_top");
1839 localFrame
->loader().load(requestWithTargetStart
);
1840 EXPECT_FALSE(client
.didFocusCalled());
1842 m_webViewHelper
.reset(); // Remove dependency on locally scoped client.
1845 TEST_F(WebViewTest
, FocusExistingFrameOnNavigate
)
1847 ViewCreatingWebViewClient client
;
1848 FrameTestHelpers::WebViewHelper m_webViewHelper
;
1849 WebViewImpl
* webViewImpl
= m_webViewHelper
.initialize(true, 0, &client
);
1850 webViewImpl
->page()->settings().setJavaScriptCanOpenWindowsAutomatically(true);
1851 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webViewImpl
->mainFrame());
1852 frame
->setName("_start");
1854 // Make a request that will open a new window
1855 WebURLRequest webURLRequest
;
1856 webURLRequest
.initialize();
1857 FrameLoadRequest
request(0, webURLRequest
.toResourceRequest(), "_blank");
1858 toLocalFrame(webViewImpl
->page()->mainFrame())->loader().load(request
);
1859 ASSERT_TRUE(client
.createdWebView());
1860 EXPECT_FALSE(client
.didFocusCalled());
1862 // Make a request from the new window that will navigate the original window. The original window should be focused.
1863 WebURLRequest webURLRequestWithTargetStart
;
1864 webURLRequestWithTargetStart
.initialize();
1865 FrameLoadRequest
requestWithTargetStart(0, webURLRequestWithTargetStart
.toResourceRequest(), "_start");
1866 toLocalFrame(toWebViewImpl(client
.createdWebView())->page()->mainFrame())->loader().load(requestWithTargetStart
);
1867 EXPECT_TRUE(client
.didFocusCalled());
1869 m_webViewHelper
.reset(); // Remove dependency on locally scoped client.
1872 TEST_F(WebViewTest
, DispatchesFocusOutFocusInOnViewToggleFocus
)
1874 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), "focusout_focusin_events.html");
1875 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "focusout_focusin_events.html", true, 0);
1877 webView
->setFocus(true);
1878 webView
->setFocus(false);
1879 webView
->setFocus(true);
1881 WebElement element
= webView
->mainFrame()->document().getElementById("message");
1882 EXPECT_STREQ("focusoutfocusin", element
.textContent().utf8().data());
1885 TEST_F(WebViewTest
, DispatchesDomFocusOutDomFocusInOnViewToggleFocus
)
1887 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), "domfocusout_domfocusin_events.html");
1888 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "domfocusout_domfocusin_events.html", true, 0);
1890 webView
->setFocus(true);
1891 webView
->setFocus(false);
1892 webView
->setFocus(true);
1894 WebElement element
= webView
->mainFrame()->document().getElementById("message");
1895 EXPECT_STREQ("DOMFocusOutDOMFocusIn", element
.textContent().utf8().data());
1898 #if !ENABLE(INPUT_MULTIPLE_FIELDS_UI)
1899 static void openDateTimeChooser(WebView
* webView
, HTMLInputElement
* inputElement
)
1901 inputElement
->focus();
1903 WebKeyboardEvent keyEvent
;
1904 keyEvent
.windowsKeyCode
= VKEY_SPACE
;
1905 keyEvent
.type
= WebInputEvent::RawKeyDown
;
1906 keyEvent
.setKeyIdentifierFromWindowsKeyCode();
1907 webView
->handleInputEvent(keyEvent
);
1909 keyEvent
.type
= WebInputEvent::KeyUp
;
1910 webView
->handleInputEvent(keyEvent
);
1913 TEST_F(WebViewTest
, ChooseValueFromDateTimeChooser
)
1915 DateTimeChooserWebViewClient client
;
1916 std::string url
= m_baseURL
+ "date_time_chooser.html";
1917 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "date_time_chooser.html");
1918 WebViewImpl
* webViewImpl
= m_webViewHelper
.initializeAndLoad(url
, true, 0, &client
);
1920 Document
* document
= webViewImpl
->mainFrameImpl()->frame()->document();
1922 HTMLInputElement
* inputElement
;
1924 inputElement
= toHTMLInputElement(document
->getElementById("date"));
1925 openDateTimeChooser(webViewImpl
, inputElement
);
1926 client
.chooserCompletion()->didChooseValue(0);
1927 client
.clearChooserCompletion();
1928 EXPECT_STREQ("1970-01-01", inputElement
->value().utf8().data());
1930 openDateTimeChooser(webViewImpl
, inputElement
);
1931 client
.chooserCompletion()->didChooseValue(std::numeric_limits
<double>::quiet_NaN());
1932 client
.clearChooserCompletion();
1933 EXPECT_STREQ("", inputElement
->value().utf8().data());
1935 inputElement
= toHTMLInputElement(document
->getElementById("datetimelocal"));
1936 openDateTimeChooser(webViewImpl
, inputElement
);
1937 client
.chooserCompletion()->didChooseValue(0);
1938 client
.clearChooserCompletion();
1939 EXPECT_STREQ("1970-01-01T00:00", inputElement
->value().utf8().data());
1941 openDateTimeChooser(webViewImpl
, inputElement
);
1942 client
.chooserCompletion()->didChooseValue(std::numeric_limits
<double>::quiet_NaN());
1943 client
.clearChooserCompletion();
1944 EXPECT_STREQ("", inputElement
->value().utf8().data());
1946 inputElement
= toHTMLInputElement(document
->getElementById("month"));
1947 openDateTimeChooser(webViewImpl
, inputElement
);
1948 client
.chooserCompletion()->didChooseValue(0);
1949 client
.clearChooserCompletion();
1950 EXPECT_STREQ("1970-01", inputElement
->value().utf8().data());
1952 openDateTimeChooser(webViewImpl
, inputElement
);
1953 client
.chooserCompletion()->didChooseValue(std::numeric_limits
<double>::quiet_NaN());
1954 client
.clearChooserCompletion();
1955 EXPECT_STREQ("", inputElement
->value().utf8().data());
1957 inputElement
= toHTMLInputElement(document
->getElementById("time"));
1958 openDateTimeChooser(webViewImpl
, inputElement
);
1959 client
.chooserCompletion()->didChooseValue(0);
1960 client
.clearChooserCompletion();
1961 EXPECT_STREQ("00:00", inputElement
->value().utf8().data());
1963 openDateTimeChooser(webViewImpl
, inputElement
);
1964 client
.chooserCompletion()->didChooseValue(std::numeric_limits
<double>::quiet_NaN());
1965 client
.clearChooserCompletion();
1966 EXPECT_STREQ("", inputElement
->value().utf8().data());
1968 inputElement
= toHTMLInputElement(document
->getElementById("week"));
1969 openDateTimeChooser(webViewImpl
, inputElement
);
1970 client
.chooserCompletion()->didChooseValue(0);
1971 client
.clearChooserCompletion();
1972 EXPECT_STREQ("1970-W01", inputElement
->value().utf8().data());
1974 openDateTimeChooser(webViewImpl
, inputElement
);
1975 client
.chooserCompletion()->didChooseValue(std::numeric_limits
<double>::quiet_NaN());
1976 client
.clearChooserCompletion();
1977 EXPECT_STREQ("", inputElement
->value().utf8().data());
1979 // Clear the WebViewClient from the webViewHelper to avoid use-after-free in the
1980 // WebViewHelper destructor.
1981 m_webViewHelper
.reset();
1985 TEST_F(WebViewTest
, DispatchesFocusBlurOnViewToggle
)
1987 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), "focus_blur_events.html");
1988 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "focus_blur_events.html", true, 0);
1990 webView
->setFocus(true);
1991 webView
->setFocus(false);
1992 webView
->setFocus(true);
1994 WebElement element
= webView
->mainFrame()->document().getElementById("message");
1995 // Expect not to see duplication of events.
1996 EXPECT_STREQ("blurfocus", element
.textContent().utf8().data());
1999 TEST_F(WebViewTest
, SmartClipData
)
2001 static const char* kExpectedClipText
= "\nPrice 10,000,000won";
2002 static const char* kExpectedClipHtml
=
2003 "<div id=\"div4\" style=\"padding: 10px; margin: 10px; border: 2px "
2004 "solid skyblue; float: left; width: 190px; height: 30px; "
2005 "color: rgb(0, 0, 0); font-family: myahem; font-size: 8px; font-style: "
2006 "normal; font-variant: normal; font-weight: normal; letter-spacing: "
2007 "normal; line-height: normal; orphans: auto; text-align: start; "
2008 "text-indent: 0px; text-transform: none; white-space: normal; widows: "
2009 "1; word-spacing: 0px; -webkit-text-stroke-width: 0px;\">Air "
2010 "conditioner</div><div id=\"div5\" style=\"padding: 10px; margin: "
2011 "10px; border: 2px solid skyblue; float: left; width: "
2012 "190px; height: 30px; color: rgb(0, 0, 0); font-family: myahem; "
2013 "font-size: 8px; font-style: normal; font-variant: normal; "
2014 "font-weight: normal; letter-spacing: normal; line-height: normal; "
2015 "orphans: auto; text-align: start; text-indent: 0px; text-transform: "
2016 "none; white-space: normal; widows: 1; word-spacing: 0px; "
2017 "-webkit-text-stroke-width: 0px;\">Price 10,000,000won</div>";
2021 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("Ahem.ttf"));
2022 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("smartclip.html"));
2023 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "smartclip.html");
2024 webView
->resize(WebSize(500, 500));
2026 WebRect
cropRect(300, 125, 152, 50);
2027 webView
->extractSmartClipData(cropRect
, clipText
, clipHtml
, clipRect
);
2028 EXPECT_STREQ(kExpectedClipText
, clipText
.utf8().c_str());
2029 EXPECT_STREQ(kExpectedClipHtml
, clipHtml
.utf8().c_str());
2032 TEST_F(WebViewTest
, SmartClipDataWithPinchZoom
)
2034 static const char* kExpectedClipText
= "\nPrice 10,000,000won";
2035 static const char* kExpectedClipHtml
=
2036 "<div id=\"div4\" style=\"padding: 10px; margin: 10px; border: 2px "
2037 "solid skyblue; float: left; width: 190px; height: 30px; "
2038 "color: rgb(0, 0, 0); font-family: myahem; font-size: 8px; font-style: "
2039 "normal; font-variant: normal; font-weight: normal; letter-spacing: "
2040 "normal; line-height: normal; orphans: auto; text-align: start; "
2041 "text-indent: 0px; text-transform: none; white-space: normal; widows: "
2042 "1; word-spacing: 0px; -webkit-text-stroke-width: 0px;\">Air "
2043 "conditioner</div><div id=\"div5\" style=\"padding: 10px; margin: "
2044 "10px; border: 2px solid skyblue; float: left; width: "
2045 "190px; height: 30px; color: rgb(0, 0, 0); font-family: myahem; "
2046 "font-size: 8px; font-style: normal; font-variant: normal; "
2047 "font-weight: normal; letter-spacing: normal; line-height: normal; "
2048 "orphans: auto; text-align: start; text-indent: 0px; text-transform: "
2049 "none; white-space: normal; widows: 1; word-spacing: 0px; "
2050 "-webkit-text-stroke-width: 0px;\">Price 10,000,000won</div>";
2054 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("Ahem.ttf"));
2055 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("smartclip.html"));
2056 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "smartclip.html");
2057 webView
->resize(WebSize(500, 500));
2059 webView
->setPageScaleFactor(1.5);
2060 webView
->setVisualViewportOffset(WebFloatPoint(167, 100));
2061 WebRect
cropRect(200, 38, 228, 75);
2062 webView
->extractSmartClipData(cropRect
, clipText
, clipHtml
, clipRect
);
2063 EXPECT_STREQ(kExpectedClipText
, clipText
.utf8().c_str());
2064 EXPECT_STREQ(kExpectedClipHtml
, clipHtml
.utf8().c_str());
2067 TEST_F(WebViewTest
, SmartClipReturnsEmptyStringsWhenUserSelectIsNone
)
2072 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("Ahem.ttf"));
2073 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("smartclip_user_select_none.html"));
2074 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "smartclip_user_select_none.html");
2075 webView
->resize(WebSize(500, 500));
2077 WebRect
cropRect(0, 0, 100, 100);
2078 webView
->extractSmartClipData(cropRect
, clipText
, clipHtml
, clipRect
);
2079 EXPECT_STREQ("", clipText
.utf8().c_str());
2080 EXPECT_STREQ("", clipHtml
.utf8().c_str());
2083 class CreateChildCounterFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
2085 CreateChildCounterFrameClient() : m_count(0) { }
2086 WebFrame
* createChildFrame(WebLocalFrame
* parent
, WebTreeScopeType
, const WebString
& frameName
, WebSandboxFlags
) override
;
2088 int count() const { return m_count
; }
2094 WebFrame
* CreateChildCounterFrameClient::createChildFrame(WebLocalFrame
* parent
, WebTreeScopeType scope
, const WebString
& frameName
, WebSandboxFlags sandboxFlags
)
2097 return TestWebFrameClient::createChildFrame(parent
, scope
, frameName
, sandboxFlags
);
2100 TEST_F(WebViewTest
, ChangeDisplayMode
)
2102 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("display_mode.html"));
2103 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "display_mode.html", true);
2105 std::string content
= webView
->mainFrame()->contentAsText(21).utf8();
2106 EXPECT_EQ("regular-ui", content
);
2108 webView
->setDisplayMode(WebDisplayModeMinimalUi
);
2109 content
= webView
->mainFrame()->contentAsText(21).utf8();
2110 EXPECT_EQ("minimal-ui", content
);
2111 m_webViewHelper
.reset();
2114 TEST_F(WebViewTest
, AddFrameInCloseUnload
)
2116 CreateChildCounterFrameClient frameClient
;
2117 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
2118 m_webViewHelper
.initializeAndLoad(m_baseURL
+ "add_frame_in_unload.html", true, &frameClient
);
2119 m_webViewHelper
.reset();
2120 EXPECT_EQ(0, frameClient
.count());
2123 TEST_F(WebViewTest
, AddFrameInCloseURLUnload
)
2125 CreateChildCounterFrameClient frameClient
;
2126 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
2127 m_webViewHelper
.initializeAndLoad(m_baseURL
+ "add_frame_in_unload.html", true, &frameClient
);
2128 m_webViewHelper
.webViewImpl()->mainFrame()->dispatchUnloadEvent();
2129 EXPECT_EQ(0, frameClient
.count());
2130 m_webViewHelper
.reset();
2133 TEST_F(WebViewTest
, AddFrameInNavigateUnload
)
2135 CreateChildCounterFrameClient frameClient
;
2136 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
2137 m_webViewHelper
.initializeAndLoad(m_baseURL
+ "add_frame_in_unload.html", true, &frameClient
);
2138 FrameTestHelpers::loadFrame(m_webViewHelper
.webView()->mainFrame(), "about:blank");
2139 EXPECT_EQ(0, frameClient
.count());
2140 m_webViewHelper
.reset();
2143 TEST_F(WebViewTest
, AddFrameInChildInNavigateUnload
)
2145 CreateChildCounterFrameClient frameClient
;
2146 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("add_frame_in_unload_wrapper.html"));
2147 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
2148 m_webViewHelper
.initializeAndLoad(m_baseURL
+ "add_frame_in_unload_wrapper.html", true, &frameClient
);
2149 FrameTestHelpers::loadFrame(m_webViewHelper
.webView()->mainFrame(), "about:blank");
2150 EXPECT_EQ(1, frameClient
.count());
2151 m_webViewHelper
.reset();
2154 class TouchEventHandlerWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
2156 // WebWidgetClient methods
2157 void hasTouchEventHandlers(bool state
) override
2159 m_hasTouchEventHandlerCount
[state
]++;
2163 TouchEventHandlerWebViewClient() : m_hasTouchEventHandlerCount()
2167 int getAndResetHasTouchEventHandlerCallCount(bool state
)
2169 int value
= m_hasTouchEventHandlerCount
[state
];
2170 m_hasTouchEventHandlerCount
[state
] = 0;
2175 int m_hasTouchEventHandlerCount
[2];
2178 // This test verifies that WebWidgetClient::hasTouchEventHandlers is called
2179 // accordingly for various calls to EventHandlerRegistry::did{Add|Remove|
2180 // RemoveAll}EventHandler(..., TouchEvent). Verifying that those calls are made
2181 // correctly is the job of LayoutTests/fast/events/event-handler-count.html.
2182 TEST_F(WebViewTest
, HasTouchEventHandlers
)
2184 TouchEventHandlerWebViewClient client
;
2185 std::string url
= m_baseURL
+ "has_touch_event_handlers.html";
2186 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "has_touch_event_handlers.html");
2187 WebViewImpl
* webViewImpl
= m_webViewHelper
.initializeAndLoad(url
, true, 0, &client
);
2188 const EventHandlerRegistry::EventHandlerClass touchEvent
= EventHandlerRegistry::TouchEvent
;
2190 // The page is initialized with at least one no-handlers call.
2191 // In practice we get two such calls because WebViewHelper::initializeAndLoad first
2192 // initializes and empty frame, and then loads a document into it, so there are two
2193 // FrameLoader::commitProvisionalLoad calls.
2194 EXPECT_GE(client
.getAndResetHasTouchEventHandlerCallCount(false), 1);
2195 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(true));
2197 // Adding the first document handler results in a has-handlers call.
2198 Document
* document
= webViewImpl
->mainFrameImpl()->frame()->document();
2199 EventHandlerRegistry
* registry
= &document
->frameHost()->eventHandlerRegistry();
2200 registry
->didAddEventHandler(*document
, touchEvent
);
2201 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(false));
2202 EXPECT_EQ(1, client
.getAndResetHasTouchEventHandlerCallCount(true));
2204 // Adding another handler has no effect.
2205 registry
->didAddEventHandler(*document
, touchEvent
);
2206 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(false));
2207 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(true));
2209 // Removing the duplicate handler has no effect.
2210 registry
->didRemoveEventHandler(*document
, touchEvent
);
2211 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(false));
2212 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(true));
2214 // Removing the final handler results in a no-handlers call.
2215 registry
->didRemoveEventHandler(*document
, touchEvent
);
2216 EXPECT_EQ(1, client
.getAndResetHasTouchEventHandlerCallCount(false));
2217 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(true));
2219 // Adding a handler on a div results in a has-handlers call.
2220 Element
* parentDiv
= document
->getElementById("parentdiv");
2222 registry
->didAddEventHandler(*parentDiv
, touchEvent
);
2223 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(false));
2224 EXPECT_EQ(1, client
.getAndResetHasTouchEventHandlerCallCount(true));
2226 // Adding a duplicate handler on the div, clearing all document handlers
2227 // (of which there are none) and removing the extra handler on the div
2228 // all have no effect.
2229 registry
->didAddEventHandler(*parentDiv
, touchEvent
);
2230 registry
->didRemoveAllEventHandlers(*document
);
2231 registry
->didRemoveEventHandler(*parentDiv
, touchEvent
);
2232 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(false));
2233 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(true));
2235 // Removing the final handler on the div results in a no-handlers call.
2236 registry
->didRemoveEventHandler(*parentDiv
, touchEvent
);
2237 EXPECT_EQ(1, client
.getAndResetHasTouchEventHandlerCallCount(false));
2238 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(true));
2240 // Adding two handlers then clearing them in a single call results in a
2241 // has-handlers then no-handlers call.
2242 registry
->didAddEventHandler(*parentDiv
, touchEvent
);
2243 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(false));
2244 EXPECT_EQ(1, client
.getAndResetHasTouchEventHandlerCallCount(true));
2245 registry
->didAddEventHandler(*parentDiv
, touchEvent
);
2246 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(false));
2247 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(true));
2248 registry
->didRemoveAllEventHandlers(*parentDiv
);
2249 EXPECT_EQ(1, client
.getAndResetHasTouchEventHandlerCallCount(false));
2250 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(true));
2252 // Adding a handler inside of a child iframe results in a has-handlers call.
2253 Element
* childFrame
= document
->getElementById("childframe");
2255 Document
* childDocument
= toHTMLIFrameElement(childFrame
)->contentDocument();
2256 Element
* childDiv
= childDocument
->getElementById("childdiv");
2258 registry
->didAddEventHandler(*childDiv
, touchEvent
);
2259 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(false));
2260 EXPECT_EQ(1, client
.getAndResetHasTouchEventHandlerCallCount(true));
2262 // Adding and clearing handlers in the parent doc or elsewhere in the child doc
2264 registry
->didAddEventHandler(*document
, touchEvent
);
2265 registry
->didAddEventHandler(*childFrame
, touchEvent
);
2266 registry
->didAddEventHandler(*childDocument
, touchEvent
);
2267 registry
->didRemoveAllEventHandlers(*document
);
2268 registry
->didRemoveAllEventHandlers(*childFrame
);
2269 registry
->didRemoveAllEventHandlers(*childDocument
);
2270 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(false));
2271 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(true));
2273 // Removing the final handler inside the child frame results in a no-handlers call.
2274 registry
->didRemoveAllEventHandlers(*childDiv
);
2275 EXPECT_EQ(1, client
.getAndResetHasTouchEventHandlerCallCount(false));
2276 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(true));
2278 // Adding a handler inside the child frame results in a has-handlers call.
2279 registry
->didAddEventHandler(*childDocument
, touchEvent
);
2280 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(false));
2281 EXPECT_EQ(1, client
.getAndResetHasTouchEventHandlerCallCount(true));
2283 // Adding a handler in the parent document and removing the one in the frame
2285 registry
->didAddEventHandler(*childFrame
, touchEvent
);
2286 registry
->didRemoveEventHandler(*childDocument
, touchEvent
);
2287 registry
->didRemoveAllEventHandlers(*childDocument
);
2288 registry
->didRemoveAllEventHandlers(*document
);
2289 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(false));
2290 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(true));
2292 // Now removing the handler in the parent document results in a no-handlers call.
2293 registry
->didRemoveEventHandler(*childFrame
, touchEvent
);
2294 EXPECT_EQ(1, client
.getAndResetHasTouchEventHandlerCallCount(false));
2295 EXPECT_EQ(0, client
.getAndResetHasTouchEventHandlerCallCount(true));
2297 // Free the webView before the TouchEventHandlerWebViewClient gets freed.
2298 m_webViewHelper
.reset();
2301 // This test checks that deleting nodes which have only non-JS-registered touch
2302 // handlers also removes them from the event handler registry. Note that this
2303 // is different from detaching and re-attaching the same node, which is covered
2304 // by layout tests under fast/events/.
2305 TEST_F(WebViewTest
, DeleteElementWithRegisteredHandler
)
2307 std::string url
= m_baseURL
+ "simple_div.html";
2308 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "simple_div.html");
2309 WebViewImpl
* webViewImpl
= m_webViewHelper
.initializeAndLoad(url
, true);
2311 RefPtrWillBePersistent
<Document
> document
= webViewImpl
->mainFrameImpl()->frame()->document();
2312 Element
* div
= document
->getElementById("div");
2313 EventHandlerRegistry
& registry
= document
->frameHost()->eventHandlerRegistry();
2315 registry
.didAddEventHandler(*div
, EventHandlerRegistry::ScrollEvent
);
2316 EXPECT_TRUE(registry
.hasEventHandlers(EventHandlerRegistry::ScrollEvent
));
2318 TrackExceptionState exceptionState
;
2319 div
->remove(exceptionState
);
2321 // For oilpan we have to force a GC to ensure the event handlers have been removed when
2322 // checking below. We do a precise GC (collectAllGarbage does not scan the stack)
2323 // to ensure the div element dies. This is also why the Document is in a Persistent
2324 // since we want that to stay around.
2325 Heap::collectAllGarbage();
2327 EXPECT_FALSE(registry
.hasEventHandlers(EventHandlerRegistry::ScrollEvent
));
2330 class NonUserInputTextUpdateWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
2332 NonUserInputTextUpdateWebViewClient() : m_textIsUpdated(false) { }
2334 // WebWidgetClient methods
2335 void didUpdateTextOfFocusedElementByNonUserInput() override
2337 m_textIsUpdated
= true;
2342 m_textIsUpdated
= false;
2345 bool textIsUpdated() const
2347 return m_textIsUpdated
;
2351 int m_textIsUpdated
;
2354 // This test verifies the text input flags are correctly exposed to script.
2355 TEST_F(WebViewTest
, TextInputFlags
)
2357 NonUserInputTextUpdateWebViewClient client
;
2358 std::string url
= m_baseURL
+ "text_input_flags.html";
2359 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "text_input_flags.html");
2360 WebViewImpl
* webViewImpl
= m_webViewHelper
.initializeAndLoad(url
, true, 0, &client
);
2361 webViewImpl
->setInitialFocus(false);
2363 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webViewImpl
->mainFrame());
2364 HTMLDocument
* document
= toHTMLDocument(frame
->frame()->document());
2367 // (A.1) Verifies autocorrect/autocomplete/spellcheck flags are Off and
2368 // autocapitalize is set to none.
2369 HTMLInputElement
* inputElement
= toHTMLInputElement(document
->getElementById("input"));
2370 document
->setFocusedElement(inputElement
);
2371 webViewImpl
->setFocus(true);
2372 WebTextInputInfo info
= webViewImpl
->textInputInfo();
2374 WebTextInputFlagAutocompleteOff
| WebTextInputFlagAutocorrectOff
| WebTextInputFlagSpellcheckOff
| WebTextInputFlagAutocapitalizeNone
,
2377 // (A.2) Verifies autocorrect/autocomplete/spellcheck flags are On and
2378 // autocapitalize is set to sentences.
2379 inputElement
= toHTMLInputElement(document
->getElementById("input2"));
2380 document
->setFocusedElement(inputElement
);
2381 webViewImpl
->setFocus(true);
2382 info
= webViewImpl
->textInputInfo();
2384 WebTextInputFlagAutocompleteOn
| WebTextInputFlagAutocorrectOn
| WebTextInputFlagSpellcheckOn
| WebTextInputFlagAutocapitalizeSentences
,
2387 // (B) <textarea> Verifies the default text input flags are
2388 // WebTextInputFlagAutocapitalizeSentences.
2389 HTMLTextAreaElement
* textAreaElement
= toHTMLTextAreaElement(document
->getElementById("textarea"));
2390 document
->setFocusedElement(textAreaElement
);
2391 webViewImpl
->setFocus(true);
2392 info
= webViewImpl
->textInputInfo();
2393 EXPECT_EQ(WebTextInputFlagAutocapitalizeSentences
, info
.flags
);
2395 // Free the webView before freeing the NonUserInputTextUpdateWebViewClient.
2396 m_webViewHelper
.reset();
2399 // This test verifies that WebWidgetClient::didUpdateTextOfFocusedElementByNonUserInput is
2400 // called iff value of a focused element is modified via script.
2401 TEST_F(WebViewTest
, NonUserInputTextUpdate
)
2403 NonUserInputTextUpdateWebViewClient client
;
2404 std::string url
= m_baseURL
+ "non_user_input_text_update.html";
2405 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "non_user_input_text_update.html");
2406 WebViewImpl
* webViewImpl
= m_webViewHelper
.initializeAndLoad(url
, true, 0, &client
);
2407 webViewImpl
->setInitialFocus(false);
2409 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webViewImpl
->mainFrame());
2410 HTMLDocument
* document
= toHTMLDocument(frame
->frame()->document());
2413 // (A.1) Focused and value is changed by script.
2415 EXPECT_FALSE(client
.textIsUpdated());
2417 HTMLInputElement
* inputElement
= toHTMLInputElement(document
->getElementById("input"));
2418 document
->setFocusedElement(inputElement
);
2419 webViewImpl
->setFocus(true);
2420 EXPECT_EQ(document
->focusedElement(), static_cast<Element
*>(inputElement
));
2422 // Emulate value change from script.
2423 inputElement
->setValue("testA");
2424 EXPECT_TRUE(client
.textIsUpdated());
2425 WebTextInputInfo info
= webViewImpl
->textInputInfo();
2426 EXPECT_EQ("testA", std::string(info
.value
.utf8().data()));
2428 // (A.2) Focused and user input modifies value.
2430 EXPECT_FALSE(client
.textIsUpdated());
2432 WebVector
<WebCompositionUnderline
> emptyUnderlines
;
2433 webViewImpl
->setComposition(WebString::fromUTF8("2"), emptyUnderlines
, 1, 1);
2434 webViewImpl
->confirmComposition(WebWidget::KeepSelection
);
2435 EXPECT_FALSE(client
.textIsUpdated());
2436 info
= webViewImpl
->textInputInfo();
2437 EXPECT_EQ("testA2", std::string(info
.value
.utf8().data()));
2439 // (A.3) Unfocused and value is changed by script.
2441 EXPECT_FALSE(client
.textIsUpdated());
2442 document
->setFocusedElement(nullptr);
2443 webViewImpl
->setFocus(false);
2444 EXPECT_NE(document
->focusedElement(), static_cast<Element
*>(inputElement
));
2445 inputElement
->setValue("testA3");
2446 EXPECT_FALSE(client
.textIsUpdated());
2449 // (B.1) Focused and value is changed by script.
2451 EXPECT_FALSE(client
.textIsUpdated());
2452 HTMLTextAreaElement
* textAreaElement
= toHTMLTextAreaElement(document
->getElementById("textarea"));
2453 document
->setFocusedElement(textAreaElement
);
2454 webViewImpl
->setFocus(true);
2455 EXPECT_EQ(document
->focusedElement(), static_cast<Element
*>(textAreaElement
));
2456 textAreaElement
->setValue("testB");
2457 EXPECT_TRUE(client
.textIsUpdated());
2458 info
= webViewImpl
->textInputInfo();
2459 EXPECT_EQ("testB", std::string(info
.value
.utf8().data()));
2461 // (B.2) Focused and user input modifies value.
2463 EXPECT_FALSE(client
.textIsUpdated());
2464 webViewImpl
->setComposition(WebString::fromUTF8("2"), emptyUnderlines
, 1, 1);
2465 webViewImpl
->confirmComposition(WebWidget::KeepSelection
);
2466 info
= webViewImpl
->textInputInfo();
2467 EXPECT_EQ("testB2", std::string(info
.value
.utf8().data()));
2469 // (B.3) Unfocused and value is changed by script.
2471 EXPECT_FALSE(client
.textIsUpdated());
2472 document
->setFocusedElement(nullptr);
2473 webViewImpl
->setFocus(false);
2474 EXPECT_NE(document
->focusedElement(), static_cast<Element
*>(textAreaElement
));
2475 inputElement
->setValue("testB3");
2476 EXPECT_FALSE(client
.textIsUpdated());
2478 // Free the webView before freeing the NonUserInputTextUpdateWebViewClient.
2479 m_webViewHelper
.reset();
2482 // Check that the WebAutofillClient is correctly notified about first user
2483 // gestures after load, following various input events.
2484 TEST_F(WebViewTest
, FirstUserGestureObservedKeyEvent
)
2486 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("form.html"));
2487 MockAutofillClient client
;
2488 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "form.html", true);
2489 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
2490 frame
->setAutofillClient(&client
);
2491 webView
->setInitialFocus(false);
2493 EXPECT_EQ(0, client
.getUserGestureNotificationsCount());
2495 WebKeyboardEvent keyEvent
;
2496 keyEvent
.windowsKeyCode
= VKEY_SPACE
;
2497 keyEvent
.type
= WebInputEvent::RawKeyDown
;
2498 keyEvent
.setKeyIdentifierFromWindowsKeyCode();
2499 webView
->handleInputEvent(keyEvent
);
2500 keyEvent
.type
= WebInputEvent::KeyUp
;
2501 webView
->handleInputEvent(keyEvent
);
2503 EXPECT_EQ(1, client
.getUserGestureNotificationsCount());
2504 frame
->setAutofillClient(0);
2507 TEST_F(WebViewTest
, FirstUserGestureObservedMouseEvent
)
2509 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("form.html"));
2510 MockAutofillClient client
;
2511 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "form.html", true);
2512 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
2513 frame
->setAutofillClient(&client
);
2514 webView
->setInitialFocus(false);
2516 EXPECT_EQ(0, client
.getUserGestureNotificationsCount());
2518 WebMouseEvent mouseEvent
;
2519 mouseEvent
.button
= WebMouseEvent::ButtonLeft
;
2522 mouseEvent
.clickCount
= 1;
2523 mouseEvent
.type
= WebInputEvent::MouseDown
;
2524 webView
->handleInputEvent(mouseEvent
);
2525 mouseEvent
.type
= WebInputEvent::MouseUp
;
2526 webView
->handleInputEvent(mouseEvent
);
2528 EXPECT_EQ(1, client
.getUserGestureNotificationsCount());
2529 frame
->setAutofillClient(0);
2532 TEST_F(WebViewTest
, FirstUserGestureObservedGestureTap
)
2534 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("longpress_selection.html"));
2535 MockAutofillClient client
;
2536 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "longpress_selection.html", true);
2537 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
2538 frame
->setAutofillClient(&client
);
2539 webView
->setInitialFocus(false);
2541 EXPECT_EQ(0, client
.getUserGestureNotificationsCount());
2543 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureTap
, WebString::fromUTF8("target")));
2545 EXPECT_EQ(1, client
.getUserGestureNotificationsCount());
2546 frame
->setAutofillClient(0);
2549 TEST_F(WebViewTest
, CompositionIsUserGesture
)
2551 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("input_field_populated.html"));
2552 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "input_field_populated.html");
2553 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
2554 MockAutofillClient client
;
2555 frame
->setAutofillClient(&client
);
2556 webView
->setInitialFocus(false);
2558 EXPECT_TRUE(webView
->setComposition(WebString::fromUTF8(std::string("hello").c_str()), WebVector
<WebCompositionUnderline
>(), 3, 3));
2559 EXPECT_EQ(1, client
.textChangesFromUserGesture());
2560 EXPECT_FALSE(UserGestureIndicator::processingUserGesture());
2561 EXPECT_TRUE(frame
->hasMarkedText());
2563 frame
->setAutofillClient(0);
2566 TEST_F(WebViewTest
, CompareSelectAllToContentAsText
)
2568 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("longpress_selection.html"));
2569 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ "longpress_selection.html", true);
2571 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
2572 frame
->executeScript(WebScriptSource(WebString::fromUTF8("document.execCommand('SelectAll', false, null)")));
2573 std::string actual
= frame
->selectionAsText().utf8();
2575 const int kMaxOutputCharacters
= 1024;
2576 std::string expected
= frame
->contentAsText(kMaxOutputCharacters
).utf8();
2577 EXPECT_EQ(expected
, actual
);
2580 TEST_F(WebViewTest
, AutoResizeSubtreeLayout
)
2582 std::string url
= m_baseURL
+ "subtree-layout.html";
2583 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "subtree-layout.html");
2584 WebView
* webView
= m_webViewHelper
.initialize(true);
2586 webView
->enableAutoResizeMode(WebSize(200, 200), WebSize(200, 200));
2587 loadFrame(webView
->mainFrame(), url
);
2589 FrameView
* frameView
= m_webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
2591 // Auto-resizing used to ASSERT(needsLayout()) in LayoutBlockFlow::layout. This EXPECT is
2592 // merely a dummy. The real test is that we don't trigger asserts in debug builds.
2593 EXPECT_FALSE(frameView
->needsLayout());
2596 TEST_F(WebViewTest
, PreferredSize
)
2598 std::string url
= m_baseURL
+ "specify_size.html?100px:100px";
2599 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "specify_size.html");
2600 WebView
* webView
= m_webViewHelper
.initializeAndLoad(url
, true);
2602 WebSize size
= webView
->contentsPreferredMinimumSize();
2603 EXPECT_EQ(100, size
.width
);
2604 EXPECT_EQ(100, size
.height
);
2606 webView
->setZoomLevel(WebView::zoomFactorToZoomLevel(2.0));
2607 size
= webView
->contentsPreferredMinimumSize();
2608 EXPECT_EQ(200, size
.width
);
2609 EXPECT_EQ(200, size
.height
);
2611 // Verify that both width and height are rounded (in this case up)
2612 webView
->setZoomLevel(WebView::zoomFactorToZoomLevel(0.9995));
2613 size
= webView
->contentsPreferredMinimumSize();
2614 EXPECT_EQ(100, size
.width
);
2615 EXPECT_EQ(100, size
.height
);
2617 // Verify that both width and height are rounded (in this case down)
2618 webView
->setZoomLevel(WebView::zoomFactorToZoomLevel(1.0005));
2619 size
= webView
->contentsPreferredMinimumSize();
2620 EXPECT_EQ(100, size
.width
);
2621 EXPECT_EQ(100, size
.height
);
2623 url
= m_baseURL
+ "specify_size.html?1.5px:1.5px";
2624 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "specify_size.html");
2625 webView
= m_webViewHelper
.initializeAndLoad(url
, true);
2627 webView
->setZoomLevel(WebView::zoomFactorToZoomLevel(1));
2628 size
= webView
->contentsPreferredMinimumSize();
2629 EXPECT_EQ(2, size
.width
);
2630 EXPECT_EQ(2, size
.height
);
2633 TEST_F(WebViewTest
, PreferredSizeDirtyLayout
)
2635 std::string url
= m_baseURL
+ "specify_size.html?100px:100px";
2636 URLTestHelpers::registerMockedURLLoad(toKURL(url
), "specify_size.html");
2637 WebView
* webView
= m_webViewHelper
.initializeAndLoad(url
, true);
2638 WebElement documentElement
= webView
->mainFrame()->document().documentElement();
2640 WebSize size
= webView
->contentsPreferredMinimumSize();
2641 EXPECT_EQ(100, size
.width
);
2642 EXPECT_EQ(100, size
.height
);
2644 bool setStyle
= documentElement
.setAttribute("style", "display: none");
2645 EXPECT_TRUE(setStyle
);
2647 size
= webView
->contentsPreferredMinimumSize();
2648 EXPECT_EQ(0, size
.width
);
2649 EXPECT_EQ(0, size
.height
);
2652 class UnhandledTapWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
2654 void showUnhandledTapUIIfNeeded(const WebPoint
& tappedPosition
, const WebNode
& tappedNode
, bool pageChanged
) override
2657 m_tappedPosition
= tappedPosition
;
2658 m_tappedNode
= tappedNode
;
2659 m_pageChanged
= pageChanged
;
2661 bool getWasCalled() const { return m_wasCalled
; }
2662 int getTappedXPos() const { return m_tappedPosition
.x(); }
2663 int getTappedYPos() const { return m_tappedPosition
.y(); }
2664 bool isTappedNodeNull() const { return m_tappedNode
.isNull(); }
2665 const WebNode
& getWebNode() const { return m_tappedNode
; }
2666 bool getPageChanged() const { return m_pageChanged
; }
2669 m_wasCalled
= false;
2670 m_tappedPosition
= IntPoint();
2671 m_tappedNode
= WebNode();
2672 m_pageChanged
= false;
2675 bool m_wasCalled
= false;
2676 IntPoint m_tappedPosition
;
2677 WebNode m_tappedNode
;
2678 bool m_pageChanged
= false;
2681 TEST_F(WebViewTest
, ShowUnhandledTapUIIfNeeded
)
2683 std::string testFile
= "show_unhandled_tap.html";
2684 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("Ahem.ttf"));
2685 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8(testFile
));
2686 UnhandledTapWebViewClient client
;
2687 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ testFile
, true, 0, &client
);
2688 webView
->resize(WebSize(500, 300));
2692 // Scroll the bottom into view so we can distinguish window coordinates from document coordinates.
2693 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureTap
, WebString::fromUTF8("bottom")));
2694 EXPECT_TRUE(client
.getWasCalled());
2695 EXPECT_EQ(64, client
.getTappedXPos());
2696 EXPECT_EQ(278, client
.getTappedYPos());
2697 EXPECT_FALSE(client
.isTappedNodeNull());
2698 EXPECT_TRUE(client
.getWebNode().isTextNode());
2700 // Test basic tap handling and notification.
2702 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureTap
, WebString::fromUTF8("target")));
2703 EXPECT_TRUE(client
.getWasCalled());
2704 EXPECT_EQ(144, client
.getTappedXPos());
2705 EXPECT_EQ(82, client
.getTappedYPos());
2706 EXPECT_FALSE(client
.isTappedNodeNull());
2707 EXPECT_TRUE(client
.getWebNode().isTextNode());
2708 // Make sure the returned text node has the parent element that was our target.
2709 EXPECT_EQ(webView
->mainFrame()->document().getElementById("target"), client
.getWebNode().parentNode());
2711 // Test correct conversion of coordinates to viewport space under pinch-zoom.
2712 webView
->setPageScaleFactor(2);
2713 webView
->setVisualViewportOffset(WebFloatPoint(50, 20));
2715 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureTap
, WebString::fromUTF8("target")));
2716 EXPECT_TRUE(client
.getWasCalled());
2717 EXPECT_EQ(188, client
.getTappedXPos());
2718 EXPECT_EQ(124, client
.getTappedYPos());
2720 m_webViewHelper
.reset(); // Remove dependency on locally scoped client.
2723 #define TEST_EACH_MOUSEEVENT(handler, EXPECT) \
2724 frame->executeScript(WebScriptSource("setTest('mousedown-" handler "');")); \
2725 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, WebString::fromUTF8("target"))); \
2726 EXPECT_##EXPECT(client.getPageChanged()); \
2728 frame->executeScript(WebScriptSource("setTest('mouseup-" handler "');")); \
2729 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, WebString::fromUTF8("target"))); \
2730 EXPECT_##EXPECT(client.getPageChanged()); \
2732 frame->executeScript(WebScriptSource("setTest('mousemove-" handler "');")); \
2733 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, WebString::fromUTF8("target"))); \
2734 EXPECT_##EXPECT(client.getPageChanged()); \
2736 frame->executeScript(WebScriptSource("setTest('click-" handler "');")); \
2737 EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, WebString::fromUTF8("target"))); \
2738 EXPECT_##EXPECT(client.getPageChanged());
2740 TEST_F(WebViewTest
, ShowUnhandledTapUIIfNeededWithMutateDom
)
2742 std::string testFile
= "show_unhandled_tap.html";
2743 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("Ahem.ttf"));
2744 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8(testFile
));
2745 UnhandledTapWebViewClient client
;
2746 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ testFile
, true, 0, &client
);
2747 webView
->resize(WebSize(500, 300));
2750 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
2752 // Test dom mutation.
2753 TEST_EACH_MOUSEEVENT("mutateDom", TRUE
);
2755 // Test without any DOM mutation.
2757 frame
->executeScript(WebScriptSource("setTest('none');"));
2758 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureTap
, WebString::fromUTF8("target")));
2759 EXPECT_FALSE(client
.getPageChanged());
2761 m_webViewHelper
.reset(); // Remove dependency on locally scoped client.
2764 TEST_F(WebViewTest
, ShowUnhandledTapUIIfNeededWithMutateStyle
)
2766 std::string testFile
= "show_unhandled_tap.html";
2767 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("Ahem.ttf"));
2768 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8(testFile
));
2769 UnhandledTapWebViewClient client
;
2770 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ testFile
, true, 0, &client
);
2771 webView
->resize(WebSize(500, 300));
2774 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
2776 // Test style mutation.
2777 TEST_EACH_MOUSEEVENT("mutateStyle", TRUE
);
2779 // Test checkbox:indeterminate style mutation.
2780 TEST_EACH_MOUSEEVENT("mutateIndeterminate", TRUE
);
2782 // Test click div with :active style but it is not covered for now.
2784 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureTap
, WebString::fromUTF8("style_active")));
2785 EXPECT_FALSE(client
.getPageChanged());
2787 // Test without any style mutation.
2789 frame
->executeScript(WebScriptSource("setTest('none');"));
2790 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureTap
, WebString::fromUTF8("target")));
2791 EXPECT_FALSE(client
.getPageChanged());
2793 m_webViewHelper
.reset(); // Remove dependency on locally scoped client.
2796 TEST_F(WebViewTest
, ShowUnhandledTapUIIfNeededWithPreventDefault
)
2798 std::string testFile
= "show_unhandled_tap.html";
2799 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8("Ahem.ttf"));
2800 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8(testFile
));
2801 UnhandledTapWebViewClient client
;
2802 WebView
* webView
= m_webViewHelper
.initializeAndLoad(m_baseURL
+ testFile
, true, 0, &client
);
2803 webView
->resize(WebSize(500, 300));
2806 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webView
->mainFrame());
2809 TEST_EACH_MOUSEEVENT("preventDefault", FALSE
);
2811 // Test without any preventDefault.
2813 frame
->executeScript(WebScriptSource("setTest('none');"));
2814 EXPECT_TRUE(tapElementById(webView
, WebInputEvent::GestureTap
, WebString::fromUTF8("target")));
2815 EXPECT_TRUE(client
.getWasCalled());
2817 m_webViewHelper
.reset(); // Remove dependency on locally scoped client.
2820 // Test 3 frames, all on the same layer (i.e. [1 2 3])
2821 TEST_F(WebViewTest
, TestPushFrameTimingRequestRectsToGraphicsLayer1
)
2823 std::string url
= m_baseURL
+ "frame_timing_inner.html?100px:100px";
2824 registerMockedURLLoad(toKURL(url
), "frame_timing_inner.html");
2825 url
= m_baseURL
+ "frame_timing_inner.html?200px:200px";
2826 registerMockedURLLoad(toKURL(url
), "frame_timing_inner.html");
2827 url
= m_baseURL
+ "frame_timing_inner.html?300px:300px";
2828 registerMockedURLLoad(toKURL(url
), "frame_timing_inner.html");
2829 url
= m_baseURL
+ "frame_timing_1.html";
2830 registerMockedURLLoad(toKURL(url
), "frame_timing_1.html");
2832 WebView
* webView
= m_webViewHelper
.initialize(true);
2833 loadFrame(webView
->mainFrame(), url
);
2835 webView
->resize(WebSize(800, 600));
2838 WebViewImpl
* webViewImpl
= toWebViewImpl(webView
);
2840 Frame
* frame
= webViewImpl
->page()->mainFrame();
2841 int64_t id
= frame
->frameID();
2843 EXPECT_EQ(3u, frame
->tree().childCount());
2845 WebVector
<std::pair
<int64_t, WebRect
>> frameTimingRequests
=
2846 toLocalFrame(frame
)->document()
2847 ->layoutView()->enclosingLayer()
2848 ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries()
2849 ->graphicsLayerBacking()->platformLayer()->frameTimingRequests();
2851 EXPECT_EQ(4u, frameTimingRequests
.size());
2852 EXPECT_EQ(id
+ 0, frameTimingRequests
[0].first
);
2853 EXPECT_EQ(WebRect(0, 0, 800, 600), frameTimingRequests
[0].second
);
2854 EXPECT_EQ(id
+ 1, frameTimingRequests
[1].first
);
2855 EXPECT_EQ(WebRect(2, 2, 100, 100), frameTimingRequests
[1].second
);
2856 EXPECT_EQ(id
+ 2, frameTimingRequests
[2].first
);
2857 EXPECT_EQ(WebRect(106, 2, 200, 200), frameTimingRequests
[2].second
);
2858 EXPECT_EQ(id
+ 3, frameTimingRequests
[3].first
);
2859 EXPECT_EQ(WebRect(310, 2, 300, 300), frameTimingRequests
[3].second
);
2862 // Test 3 frames, where frame 2 is on a different GraphicsLayer (i.e. [1 2' 3])
2863 TEST_F(WebViewTest
, TestPushFrameTimingRequestRectsToGraphicsLayer2
)
2865 std::string url
= m_baseURL
+ "frame_timing_inner.html?100px:100px";
2866 registerMockedURLLoad(toKURL(url
), "frame_timing_inner.html");
2867 url
= m_baseURL
+ "frame_timing_inner.html?200px:200px";
2868 registerMockedURLLoad(toKURL(url
), "frame_timing_inner.html");
2869 url
= m_baseURL
+ "frame_timing_inner.html?300px:300px";
2870 registerMockedURLLoad(toKURL(url
), "frame_timing_inner.html");
2871 url
= m_baseURL
+ "frame_timing_2.html";
2872 registerMockedURLLoad(toKURL(url
), "frame_timing_2.html");
2874 WebView
* webView
= m_webViewHelper
.initialize(true);
2875 loadFrame(webView
->mainFrame(), url
);
2877 webView
->resize(WebSize(800, 600));
2880 WebViewImpl
* webViewImpl
= toWebViewImpl(webView
);
2882 Frame
* frame
= webViewImpl
->page()->mainFrame();
2883 int64_t id
= frame
->frameID();
2885 EXPECT_EQ(3u, frame
->tree().childCount());
2887 const WebLayer
* graphicsLayer1
=
2888 toLocalFrame(webViewImpl
->page()->mainFrame())->document()
2889 ->layoutView()->enclosingLayer()
2890 ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries()
2891 ->graphicsLayerBacking()->platformLayer();
2892 WebVector
<std::pair
<int64_t, WebRect
>> frameTimingRequests1
=
2893 graphicsLayer1
->frameTimingRequests();
2895 EXPECT_EQ(3u, frameTimingRequests1
.size());
2896 EXPECT_EQ(id
+ 0, frameTimingRequests1
[0].first
);
2897 EXPECT_EQ(WebRect(0, 0, 800, 600), frameTimingRequests1
[0].second
);
2898 EXPECT_EQ(id
+ 1, frameTimingRequests1
[1].first
);
2899 EXPECT_EQ(WebRect(2, 2, 100, 100), frameTimingRequests1
[1].second
);
2900 EXPECT_EQ(id
+ 3, frameTimingRequests1
[2].first
);
2901 EXPECT_EQ(WebRect(310, 2, 300, 300), frameTimingRequests1
[2].second
);
2903 const WebLayer
* graphicsLayer2
= nullptr;
2904 for (Frame
* frame
= webViewImpl
->page()->mainFrame(); frame
;
2905 frame
= frame
->tree().traverseNext()) {
2906 graphicsLayer2
= toLocalFrame(frame
)->document()->layoutView()
2908 ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries()
2909 ->graphicsLayerBacking()->platformLayer();
2910 if (graphicsLayer2
!= graphicsLayer1
)
2913 WebVector
<std::pair
<int64_t, WebRect
>> frameTimingRequests2
=
2914 graphicsLayer2
->frameTimingRequests();
2915 EXPECT_EQ(1u, frameTimingRequests2
.size());
2916 EXPECT_EQ(id
+ 2, frameTimingRequests2
[0].first
);
2917 EXPECT_EQ(WebRect(2, 2, 200, 200), frameTimingRequests2
[0].second
);
2921 // Test nested frames (i.e. [1 2'[4 5'] 3])
2922 TEST_F(WebViewTest
, TestPushFrameTimingRequestRectsToGraphicsLayer3
)
2924 std::string url
= m_baseURL
+ "frame_timing_inner.html?100px:100px";
2925 registerMockedURLLoad(toKURL(url
), "frame_timing_inner.html");
2926 url
= m_baseURL
+ "frame_timing_inner.html?200px:200px";
2927 registerMockedURLLoad(toKURL(url
), "frame_timing_inner.html");
2928 url
= m_baseURL
+ "frame_timing_inner.html?300px:300px";
2929 registerMockedURLLoad(toKURL(url
), "frame_timing_inner.html");
2930 url
= m_baseURL
+ "frame_timing_b.html";
2931 registerMockedURLLoad(toKURL(url
), "frame_timing_b.html");
2932 url
= m_baseURL
+ "frame_timing_3.html";
2933 registerMockedURLLoad(toKURL(url
), "frame_timing_3.html");
2935 WebView
* webView
= m_webViewHelper
.initialize(true);
2936 loadFrame(webView
->mainFrame(), url
);
2938 webView
->resize(WebSize(800, 600));
2941 WebViewImpl
* webViewImpl
= toWebViewImpl(webView
);
2943 Frame
* frame
= webViewImpl
->page()->mainFrame();
2944 int64_t id
= frame
->frameID();
2946 EXPECT_EQ(3u, frame
->tree().childCount());
2948 const WebLayer
* graphicsLayer1
=
2949 toLocalFrame(webViewImpl
->page()->mainFrame())->document()
2950 ->layoutView()->enclosingLayer()
2951 ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries()
2952 ->graphicsLayerBacking()->platformLayer();
2953 WebVector
<std::pair
<int64_t, WebRect
>> frameTimingRequests1
=
2954 graphicsLayer1
->frameTimingRequests();
2956 EXPECT_EQ(3u, frameTimingRequests1
.size());
2957 EXPECT_EQ(id
+ 0, frameTimingRequests1
[0].first
);
2958 EXPECT_EQ(WebRect(0, 0, 800, 600), frameTimingRequests1
[0].second
);
2959 EXPECT_EQ(WebRect(2, 2, 100, 100), frameTimingRequests1
[1].second
);
2960 EXPECT_EQ(WebRect(410, 2, 200, 200), frameTimingRequests1
[2].second
);
2962 const WebLayer
* graphicsLayer2
= nullptr;
2963 for (Frame
* frame
= webViewImpl
->page()->mainFrame(); frame
;
2964 frame
= frame
->tree().traverseNext()) {
2965 graphicsLayer2
= toLocalFrame(frame
)->document()->layoutView()
2967 ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries()
2968 ->graphicsLayerBacking()->platformLayer();
2969 if (graphicsLayer2
!= graphicsLayer1
)
2972 WebVector
<std::pair
<int64_t, WebRect
>> frameTimingRequests2
=
2973 graphicsLayer2
->frameTimingRequests();
2974 EXPECT_EQ(2u, frameTimingRequests2
.size());
2975 EXPECT_EQ(WebRect(0, 0, 300, 300), frameTimingRequests2
[0].second
);
2976 EXPECT_EQ(WebRect(2, 2, 100, 100), frameTimingRequests2
[1].second
);
2978 const WebLayer
* graphicsLayer3
= nullptr;
2979 for (Frame
* frame
= webViewImpl
->page()->mainFrame(); frame
;
2980 frame
= frame
->tree().traverseNext()) {
2981 graphicsLayer3
= toLocalFrame(frame
)->document()->layoutView()
2983 ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries()
2984 ->graphicsLayerBacking()->platformLayer();
2985 if (graphicsLayer3
!= graphicsLayer1
&& graphicsLayer3
!= graphicsLayer2
)
2988 WebVector
<std::pair
<int64_t, WebRect
>> frameTimingRequests3
=
2989 graphicsLayer3
->frameTimingRequests();
2990 EXPECT_EQ(1u, frameTimingRequests3
.size());
2991 EXPECT_EQ(WebRect(2, 2, 100, 100), frameTimingRequests3
[0].second
);
2994 // Test 3 frames, all on the same layer (i.e. [1 2 3])
2995 // Fails on android, see crbug.com/488381.
2997 TEST_F(WebViewTest
, DISABLED_TestRecordFrameTimingEvents
)
2999 TEST_F(WebViewTest
, TestRecordFrameTimingEvents
)
3002 std::string url
= m_baseURL
+ "frame_timing_inner.html?100px:100px";
3003 registerMockedURLLoad(toKURL(url
), "frame_timing_inner.html");
3004 url
= m_baseURL
+ "frame_timing_inner.html?200px:200px";
3005 registerMockedURLLoad(toKURL(url
), "frame_timing_inner.html");
3006 url
= m_baseURL
+ "frame_timing_inner.html?300px:300px";
3007 registerMockedURLLoad(toKURL(url
), "frame_timing_inner.html");
3008 url
= m_baseURL
+ "frame_timing_1.html";
3009 registerMockedURLLoad(toKURL(url
), "frame_timing_1.html");
3011 WebView
* webView
= m_webViewHelper
.initialize(true);
3012 loadFrame(webView
->mainFrame(), url
);
3014 webView
->resize(WebSize(800, 600));
3017 WebViewImpl
* webViewImpl
= toWebViewImpl(webView
);
3019 Frame
* frame
= webViewImpl
->page()->mainFrame();
3020 int64_t id
= frame
->frameID();
3022 std::vector
<WebFrameTimingEvent
> compositePairs(3);
3023 compositePairs
[0] = WebFrameTimingEvent(1, 2.0);
3024 compositePairs
[1] = WebFrameTimingEvent(2, 3.0);
3025 compositePairs
[2] = WebFrameTimingEvent(3, 4.0);
3026 WebVector
<WebFrameTimingEvent
> compositeEvents(compositePairs
);
3027 webViewImpl
->recordFrameTimingEvent(WebView::CompositeEvent
, id
, compositeEvents
);
3028 PerformanceEntryVector composites
= DOMWindowPerformance::performance(*frame
->domWindow())->getEntriesByType("composite");
3029 PerformanceEntryVector renders
= DOMWindowPerformance::performance(*frame
->domWindow())->getEntriesByType("render");
3030 ASSERT_EQ(3ul, composites
.size());
3031 ASSERT_EQ(0ul, renders
.size());
3032 for (size_t i
= 0; i
< composites
.size(); ++i
) {
3033 double docTime
= frame
->domWindow()->document()->loader()->timing().monotonicTimeToZeroBasedDocumentTime(compositePairs
[i
].startTime
) * 1000.0;
3034 ASSERT_EQ(docTime
, composites
[i
]->startTime());
3037 // Skip ahead to subframe 2.
3038 frame
= frame
->tree().traverseNext();
3039 frame
= frame
->tree().traverseNext();
3042 std::vector
<WebFrameTimingEvent
> renderPairs(4);
3043 renderPairs
[0] = WebFrameTimingEvent(4, 5.0, 6.0);
3044 renderPairs
[1] =WebFrameTimingEvent(5, 6.0, 7.0);
3045 renderPairs
[2] =WebFrameTimingEvent(6, 7.0, 8.0);
3046 renderPairs
[3] =WebFrameTimingEvent(7, 8.0, 9.0);
3047 WebVector
<WebFrameTimingEvent
> renderEvents(renderPairs
);
3048 webViewImpl
->recordFrameTimingEvent(WebView::RenderEvent
, id
, renderEvents
);
3049 composites
= DOMWindowPerformance::performance(*frame
->domWindow())->getEntriesByType("composite");
3050 renders
= DOMWindowPerformance::performance(*frame
->domWindow())->getEntriesByType("render");
3051 ASSERT_EQ(0ul, composites
.size());
3052 ASSERT_EQ(4ul, renders
.size());
3053 for (size_t i
= 0; i
< renders
.size(); ++i
) {
3054 double docStartTime
= frame
->domWindow()->document()->loader()->timing().monotonicTimeToZeroBasedDocumentTime(renderPairs
[i
].startTime
) * 1000.0;
3055 ASSERT_DOUBLE_EQ(docStartTime
, renders
[i
]->startTime());
3056 double docFinishTime
= frame
->domWindow()->document()->loader()->timing().monotonicTimeToZeroBasedDocumentTime(renderPairs
[i
].finishTime
) * 1000.0;
3057 double docDuration
= docFinishTime
- docStartTime
;
3058 ASSERT_DOUBLE_EQ(docDuration
, renders
[i
]->duration());
3063 TEST_F(WebViewTest
, StopLoadingIfJavaScriptURLReturnsNoStringResult
)
3065 ViewCreatingWebViewClient client
;
3066 FrameTestHelpers::WebViewHelper mainWebView
;
3067 mainWebView
.initializeAndLoad("about:blank", true, 0, &client
);
3068 mainWebView
.webViewImpl()->page()->settings().setJavaScriptCanOpenWindowsAutomatically(true);
3070 WebFrame
* frame
= mainWebView
.webView()->mainFrame();
3071 v8::HandleScope
scope(v8::Isolate::GetCurrent());
3072 v8::Local
<v8::Value
> v8Value
= frame
->executeScriptAndReturnValue(WebScriptSource("var win = window.open('javascript:false'); win.document"));
3073 ASSERT_TRUE(v8Value
->IsObject());
3074 Document
* document
= V8Document::toImplWithTypeCheck(v8::Isolate::GetCurrent(), v8Value
);
3075 ASSERT_TRUE(document
);
3076 EXPECT_FALSE(document
->frame()->isLoading());
3079 } // namespace blink