1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "core/frame/PinchViewport.h"
9 #include "core/frame/FrameHost.h"
10 #include "core/frame/LocalFrame.h"
11 #include "core/rendering/RenderView.h"
12 #include "core/rendering/compositing/CompositedLayerMapping.h"
13 #include "core/rendering/compositing/RenderLayerCompositor.h"
14 #include "public/platform/Platform.h"
15 #include "public/platform/WebLayerTreeView.h"
16 #include "public/platform/WebUnitTestSupport.h"
17 #include "public/web/WebScriptSource.h"
18 #include "public/web/WebSettings.h"
19 #include "public/web/WebViewClient.h"
20 #include "web/WebLocalFrameImpl.h"
21 #include "web/tests/FrameTestHelpers.h"
22 #include "web/tests/URLTestHelpers.h"
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
26 #define EXPECT_POINT_EQ(expected, actual) \
28 EXPECT_EQ((expected).x(), (actual).x()); \
29 EXPECT_EQ((expected).y(), (actual).y()); \
32 #define EXPECT_FLOAT_POINT_EQ(expected, actual) \
34 EXPECT_FLOAT_EQ((expected).x(), (actual).x()); \
35 EXPECT_FLOAT_EQ((expected).y(), (actual).y()); \
38 #define EXPECT_POINT_EQ(expected, actual) \
40 EXPECT_EQ((expected).x(), (actual).x()); \
41 EXPECT_EQ((expected).y(), (actual).y()); \
44 #define EXPECT_SIZE_EQ(expected, actual) \
46 EXPECT_EQ((expected).width(), (actual).width()); \
47 EXPECT_EQ((expected).height(), (actual).height()); \
50 #define EXPECT_FLOAT_SIZE_EQ(expected, actual) \
52 EXPECT_FLOAT_EQ((expected).width(), (actual).width()); \
53 EXPECT_FLOAT_EQ((expected).height(), (actual).height()); \
56 #define EXPECT_FLOAT_RECT_EQ(expected, actual) \
58 EXPECT_FLOAT_EQ((expected).x(), (actual).x()); \
59 EXPECT_FLOAT_EQ((expected).y(), (actual).y()); \
60 EXPECT_FLOAT_EQ((expected).width(), (actual).width()); \
61 EXPECT_FLOAT_EQ((expected).height(), (actual).height()); \
65 using namespace WebCore;
66 using namespace blink;
67 using blink::FrameTestHelpers::runPendingTasks;
71 class PinchViewportTest : public testing::Test {
74 : m_baseURL("http://www.test.com/")
78 void initializeWithDesktopSettings(void (*overrideSettingsFunc)(WebSettings*) = 0)
80 if (!overrideSettingsFunc)
81 overrideSettingsFunc = &configureSettings;
82 m_helper.initialize(true, 0, &m_mockWebViewClient, overrideSettingsFunc);
83 webViewImpl()->setPageScaleFactorLimits(1, 4);
86 void initializeWithAndroidSettings(void (*overrideSettingsFunc)(WebSettings*) = 0)
88 if (!overrideSettingsFunc)
89 overrideSettingsFunc = &configureAndroidSettings;
90 m_helper.initialize(true, 0, &m_mockWebViewClient, overrideSettingsFunc);
93 virtual ~PinchViewportTest()
95 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
98 void navigateTo(const std::string& url)
100 FrameTestHelpers::loadFrame(webViewImpl()->mainFrame(), url);
101 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
104 void forceFullCompositingUpdate()
106 webViewImpl()->layout();
109 void registerMockedHttpURLLoad(const std::string& fileName)
111 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(fileName.c_str()));
114 void executeScript(const WebString& code)
116 webViewImpl()->mainFrame()->executeScript(WebScriptSource(code));
120 WebLayer* getRootScrollLayer()
122 RenderLayerCompositor* compositor = frame()->contentRenderer()->compositor();
124 ASSERT(compositor->scrollLayer());
126 WebLayer* webScrollLayer = compositor->scrollLayer()->platformLayer();
127 return webScrollLayer;
130 WebViewImpl* webViewImpl() const { return m_helper.webViewImpl(); }
131 LocalFrame* frame() const { return m_helper.webViewImpl()->mainFrameImpl()->frame(); }
133 static void configureSettings(WebSettings* settings)
135 settings->setJavaScriptEnabled(true);
136 settings->setForceCompositingMode(true);
137 settings->setAcceleratedCompositingEnabled(true);
138 settings->setAcceleratedCompositingForFixedPositionEnabled(true);
139 settings->setAcceleratedCompositingForOverflowScrollEnabled(true);
140 settings->setCompositedScrollingForFramesEnabled(true);
141 settings->setPinchVirtualViewportEnabled(true);
144 static void configureAndroidSettings(WebSettings* settings)
146 configureSettings(settings);
147 settings->setViewportEnabled(true);
148 settings->setViewportMetaEnabled(true);
149 settings->setShrinksViewportContentToFit(true);
153 std::string m_baseURL;
154 FrameTestHelpers::TestWebViewClient m_mockWebViewClient;
157 FrameTestHelpers::WebViewHelper m_helper;
160 // Test that resizing the PinchViewport works as expected and that resizing the
161 // WebView resizes the PinchViewport.
162 TEST_F(PinchViewportTest, TestResize)
164 initializeWithDesktopSettings();
165 webViewImpl()->resize(IntSize(320, 240));
167 navigateTo("about:blank");
168 forceFullCompositingUpdate();
170 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
172 IntSize webViewSize = webViewImpl()->size();
174 // Make sure the pinch viewport was initialized.
175 EXPECT_SIZE_EQ(webViewSize, pinchViewport.size());
177 // Resizing the WebView should change the PinchViewport.
178 webViewSize = IntSize(640, 480);
179 webViewImpl()->resize(webViewSize);
180 EXPECT_SIZE_EQ(webViewSize, IntSize(webViewImpl()->size()));
181 EXPECT_SIZE_EQ(webViewSize, pinchViewport.size());
183 // Resizing the pinch viewport shouldn't affect the WebView.
184 IntSize newViewportSize = IntSize(320, 200);
185 pinchViewport.setSize(newViewportSize);
186 EXPECT_SIZE_EQ(webViewSize, IntSize(webViewImpl()->size()));
187 EXPECT_SIZE_EQ(newViewportSize, pinchViewport.size());
190 static void turnOffForceCompositingMode(WebSettings* settings)
192 PinchViewportTest::configureSettings(settings);
193 settings->setForceCompositingMode(false);
196 // Test that the container layer gets sized properly if the WebView is resized
197 // prior to the PinchViewport being attached to the layer tree.
198 TEST_F(PinchViewportTest, TestWebViewResizedBeforeAttachment)
200 initializeWithDesktopSettings(turnOffForceCompositingMode);
201 webViewImpl()->resize(IntSize(320, 240));
203 navigateTo("about:blank");
204 forceFullCompositingUpdate();
205 webViewImpl()->enterForceCompositingMode(true);
207 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
208 EXPECT_FLOAT_SIZE_EQ(FloatSize(320, 240), pinchViewport.rootGraphicsLayer()->size());
211 // Make sure that the visibleRect method acurately reflects the scale and scroll location
213 TEST_F(PinchViewportTest, TestVisibleRect)
215 initializeWithDesktopSettings();
216 webViewImpl()->resize(IntSize(320, 240));
218 navigateTo("about:blank");
219 forceFullCompositingUpdate();
221 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
223 // Initial visible rect should be the whole frame.
224 EXPECT_SIZE_EQ(IntSize(webViewImpl()->size()), pinchViewport.size());
226 // Viewport is whole frame.
227 IntSize size = IntSize(400, 200);
228 webViewImpl()->resize(size);
229 webViewImpl()->layout();
230 pinchViewport.setSize(size);
232 // Scale the viewport to 2X; size should not change.
233 FloatRect expectedRect(FloatPoint(0, 0), size);
234 expectedRect.scale(0.5);
235 pinchViewport.setScale(2);
236 EXPECT_EQ(2, pinchViewport.scale());
237 EXPECT_SIZE_EQ(size, pinchViewport.size());
238 EXPECT_FLOAT_RECT_EQ(expectedRect, pinchViewport.visibleRect());
240 // Move the viewport.
241 expectedRect.setLocation(FloatPoint(5, 7));
242 pinchViewport.setLocation(expectedRect.location());
243 EXPECT_FLOAT_RECT_EQ(expectedRect, pinchViewport.visibleRect());
245 expectedRect.setLocation(FloatPoint(200, 100));
246 pinchViewport.setLocation(expectedRect.location());
247 EXPECT_FLOAT_RECT_EQ(expectedRect, pinchViewport.visibleRect());
249 // Scale the viewport to 3X to introduce some non-int values.
250 FloatPoint oldLocation = expectedRect.location();
251 expectedRect = FloatRect(FloatPoint(), size);
252 expectedRect.scale(1 / 3.0f);
253 expectedRect.setLocation(oldLocation);
254 pinchViewport.setScale(3);
255 EXPECT_FLOAT_RECT_EQ(expectedRect, pinchViewport.visibleRect());
257 expectedRect.setLocation(FloatPoint(0.25f, 0.333f));
258 pinchViewport.setLocation(expectedRect.location());
259 EXPECT_FLOAT_RECT_EQ(expectedRect, pinchViewport.visibleRect());
262 // Test that the viewport's scroll offset is always appropriately bounded such that the
263 // pinch viewport always stays within the bounds of the main frame.
264 TEST_F(PinchViewportTest, TestOffsetClamping)
266 initializeWithDesktopSettings();
267 webViewImpl()->resize(IntSize(320, 240));
269 navigateTo("about:blank");
270 forceFullCompositingUpdate();
272 // Pinch viewport should be initialized to same size as frame so no scrolling possible.
273 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
274 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
276 pinchViewport.setLocation(FloatPoint(-1, -2));
277 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
279 pinchViewport.setLocation(FloatPoint(100, 200));
280 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
282 pinchViewport.setLocation(FloatPoint(-5, 10));
283 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
285 // Scale by 2x. The viewport's visible rect should now have a size of 160x120.
286 pinchViewport.setScale(2);
287 FloatPoint location(10, 50);
288 pinchViewport.setLocation(location);
289 EXPECT_FLOAT_POINT_EQ(location, pinchViewport.visibleRect().location());
291 pinchViewport.setLocation(FloatPoint(1000, 2000));
292 EXPECT_FLOAT_POINT_EQ(FloatPoint(160, 120), pinchViewport.visibleRect().location());
294 pinchViewport.setLocation(FloatPoint(-1000, -2000));
295 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
297 // Make sure offset gets clamped on scale out. Scale to 1.25 so the viewport is 256x192.
298 pinchViewport.setLocation(FloatPoint(160, 120));
299 pinchViewport.setScale(1.25);
300 EXPECT_FLOAT_POINT_EQ(FloatPoint(64, 48), pinchViewport.visibleRect().location());
302 // Scale out smaller than 1.
303 pinchViewport.setScale(0.25);
304 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
307 // Test that the viewport can be scrolled around only within the main frame in the presence
308 // of viewport resizes, as would be the case if the on screen keyboard came up.
309 TEST_F(PinchViewportTest, TestOffsetClampingWithResize)
311 initializeWithDesktopSettings();
312 webViewImpl()->resize(IntSize(320, 240));
314 navigateTo("about:blank");
315 forceFullCompositingUpdate();
317 // Pinch viewport should be initialized to same size as frame so no scrolling possible.
318 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
319 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
321 // Shrink the viewport vertically. The resize shouldn't affect the location, but it
322 // should allow vertical scrolling.
323 pinchViewport.setSize(IntSize(320, 200));
324 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
325 pinchViewport.setLocation(FloatPoint(10, 20));
326 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 20), pinchViewport.visibleRect().location());
327 pinchViewport.setLocation(FloatPoint(0, 100));
328 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 40), pinchViewport.visibleRect().location());
329 pinchViewport.setLocation(FloatPoint(0, 10));
330 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 10), pinchViewport.visibleRect().location());
331 pinchViewport.setLocation(FloatPoint(0, -100));
332 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
334 // Repeat the above but for horizontal dimension.
335 pinchViewport.setSize(IntSize(280, 240));
336 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
337 pinchViewport.setLocation(FloatPoint(10, 20));
338 EXPECT_FLOAT_POINT_EQ(FloatPoint(10, 0), pinchViewport.visibleRect().location());
339 pinchViewport.setLocation(FloatPoint(100, 0));
340 EXPECT_FLOAT_POINT_EQ(FloatPoint(40, 0), pinchViewport.visibleRect().location());
341 pinchViewport.setLocation(FloatPoint(10, 0));
342 EXPECT_FLOAT_POINT_EQ(FloatPoint(10, 0), pinchViewport.visibleRect().location());
343 pinchViewport.setLocation(FloatPoint(-100, 0));
344 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
346 // Now with both dimensions.
347 pinchViewport.setSize(IntSize(280, 200));
348 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
349 pinchViewport.setLocation(FloatPoint(10, 20));
350 EXPECT_FLOAT_POINT_EQ(FloatPoint(10, 20), pinchViewport.visibleRect().location());
351 pinchViewport.setLocation(FloatPoint(100, 100));
352 EXPECT_FLOAT_POINT_EQ(FloatPoint(40, 40), pinchViewport.visibleRect().location());
353 pinchViewport.setLocation(FloatPoint(10, 3));
354 EXPECT_FLOAT_POINT_EQ(FloatPoint(10, 3), pinchViewport.visibleRect().location());
355 pinchViewport.setLocation(FloatPoint(-10, -4));
356 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
359 // Test that the viewport is scrollable but bounded appropriately within the main frame
360 // when we apply both scaling and resizes.
361 TEST_F(PinchViewportTest, TestOffsetClampingWithResizeAndScale)
363 initializeWithDesktopSettings();
364 webViewImpl()->resize(IntSize(320, 240));
366 navigateTo("about:blank");
367 forceFullCompositingUpdate();
369 // Pinch viewport should be initialized to same size as WebView so no scrolling possible.
370 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
371 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), pinchViewport.visibleRect().location());
373 // Zoom in to 2X so we can scroll the viewport to 160x120.
374 pinchViewport.setScale(2);
375 pinchViewport.setLocation(FloatPoint(200, 200));
376 EXPECT_FLOAT_POINT_EQ(FloatPoint(160, 120), pinchViewport.visibleRect().location());
378 // Now resize the viewport to make it 10px smaller. Since we're zoomed in by 2X it should
379 // allow us to scroll by 5px more.
380 pinchViewport.setSize(IntSize(310, 230));
381 pinchViewport.setLocation(FloatPoint(200, 200));
382 EXPECT_FLOAT_POINT_EQ(FloatPoint(165, 125), pinchViewport.visibleRect().location());
384 // The viewport can be larger than the main frame (currently 320, 240) though typically
385 // the scale will be clamped to prevent it from actually being larger. Make sure size
386 // changes clamp the offset so the inner remains within the outer.
387 pinchViewport.setSize(IntSize(330, 250));
388 EXPECT_SIZE_EQ(IntSize(330, 250), pinchViewport.size());
389 EXPECT_FLOAT_POINT_EQ(FloatPoint(155, 115), pinchViewport.visibleRect().location());
390 pinchViewport.setLocation(FloatPoint(200, 200));
391 EXPECT_FLOAT_POINT_EQ(FloatPoint(155, 115), pinchViewport.visibleRect().location());
393 // Resize both the viewport and the frame to be larger.
394 webViewImpl()->resize(IntSize(640, 480));
395 webViewImpl()->layout();
396 EXPECT_SIZE_EQ(IntSize(webViewImpl()->size()), pinchViewport.size());
397 EXPECT_SIZE_EQ(IntSize(webViewImpl()->size()), frame()->view()->frameRect().size());
398 pinchViewport.setLocation(FloatPoint(1000, 1000));
399 EXPECT_FLOAT_POINT_EQ(FloatPoint(320, 240), pinchViewport.visibleRect().location());
401 // Make sure resizing the viewport doesn't change its offset if the resize doesn't make
402 // the viewport go out of bounds.
403 pinchViewport.setLocation(FloatPoint(200, 200));
404 pinchViewport.setSize(IntSize(880, 560));
405 EXPECT_FLOAT_POINT_EQ(FloatPoint(200, 200), pinchViewport.visibleRect().location());
407 // Resizing the viewport such that the viewport is out of bounds should move the
409 pinchViewport.setSize(IntSize(920, 640));
410 EXPECT_FLOAT_POINT_EQ(FloatPoint(180, 160), pinchViewport.visibleRect().location());
413 // The main FrameView's size should be set such that its the size of the pinch viewport
414 // at minimum scale. If there's no explicit minimum scale set, the FrameView should be
415 // set to the content width and height derived by the aspect ratio.
416 TEST_F(PinchViewportTest, TestFrameViewSizedToContent)
418 initializeWithAndroidSettings();
419 webViewImpl()->resize(IntSize(320, 240));
421 registerMockedHttpURLLoad("200-by-300-viewport.html");
422 navigateTo(m_baseURL + "200-by-300-viewport.html");
424 webViewImpl()->resize(IntSize(600, 800));
425 webViewImpl()->layout();
427 EXPECT_SIZE_EQ(IntSize(200, 266),
428 webViewImpl()->mainFrameImpl()->frameView()->frameRect().size());
431 // The main FrameView's size should be set such that its the size of the pinch viewport
432 // at minimum scale. On Desktop, the minimum scale is set at 1 so make sure the FrameView
433 // is sized to the viewport.
434 TEST_F(PinchViewportTest, TestFrameViewSizedToMinimumScale)
436 initializeWithDesktopSettings();
437 webViewImpl()->resize(IntSize(320, 240));
439 registerMockedHttpURLLoad("200-by-300.html");
440 navigateTo(m_baseURL + "200-by-300.html");
442 webViewImpl()->resize(IntSize(100, 160));
443 webViewImpl()->layout();
445 EXPECT_SIZE_EQ(IntSize(100, 160),
446 webViewImpl()->mainFrameImpl()->frameView()->frameRect().size());
449 // The main FrameView's size should be set such that its the size of the pinch viewport
450 // at minimum scale. Test that the FrameView is appropriately sized in the presence
451 // of a viewport <meta> tag.
452 TEST_F(PinchViewportTest, TestFrameViewSizedToViewportMetaMinimumScale)
454 initializeWithAndroidSettings();
455 webViewImpl()->resize(IntSize(320, 240));
457 registerMockedHttpURLLoad("200-by-300-min-scale-2.html");
458 navigateTo(m_baseURL + "200-by-300-min-scale-2.html");
460 webViewImpl()->resize(IntSize(100, 160));
461 webViewImpl()->layout();
463 EXPECT_SIZE_EQ(IntSize(50, 80),
464 webViewImpl()->mainFrameImpl()->frameView()->frameRect().size());
467 // Test that the pinch viewport still gets sized in AutoSize/AutoResize mode.
468 TEST_F(PinchViewportTest, TestPinchViewportGetsSizeInAutoSizeMode)
470 initializeWithDesktopSettings();
472 EXPECT_SIZE_EQ(IntSize(0, 0), IntSize(webViewImpl()->size()));
473 EXPECT_SIZE_EQ(IntSize(0, 0), frame()->page()->frameHost().pinchViewport().size());
475 webViewImpl()->enableAutoResizeMode(WebSize(10, 10), WebSize(1000, 1000));
477 registerMockedHttpURLLoad("200-by-300.html");
478 navigateTo(m_baseURL + "200-by-300.html");
480 EXPECT_SIZE_EQ(IntSize(200, 300), frame()->page()->frameHost().pinchViewport().size());
483 // Test that the text selection handle's position accounts for the pinch viewport.
484 TEST_F(PinchViewportTest, TestTextSelectionHandles)
486 initializeWithDesktopSettings();
487 webViewImpl()->resize(IntSize(500, 800));
489 registerMockedHttpURLLoad("pinch-viewport-input-field.html");
490 navigateTo(m_baseURL + "pinch-viewport-input-field.html");
492 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
493 webViewImpl()->setInitialFocus(false);
495 WebRect originalAnchor;
496 WebRect originalFocus;
497 webViewImpl()->selectionBounds(originalAnchor, originalFocus);
499 webViewImpl()->setPageScaleFactor(2);
500 pinchViewport.setLocation(FloatPoint(100, 400));
504 webViewImpl()->selectionBounds(anchor, focus);
506 IntPoint expected(IntRect(originalAnchor).location());
507 expected.moveBy(-flooredIntPoint(pinchViewport.visibleRect().location()));
508 expected.scale(pinchViewport.scale(), pinchViewport.scale());
510 EXPECT_POINT_EQ(expected, IntRect(anchor).location());
511 EXPECT_POINT_EQ(expected, IntRect(focus).location());
513 // FIXME(bokan) - http://crbug.com/364154 - Figure out how to test text selection
514 // as well rather than just carret.
517 // Test that the HistoryItem for the page stores the pinch viewport's offset and scale.
518 TEST_F(PinchViewportTest, TestSavedToHistoryItem)
520 initializeWithDesktopSettings();
521 webViewImpl()->resize(IntSize(200, 300));
522 webViewImpl()->layout();
524 registerMockedHttpURLLoad("200-by-300.html");
525 navigateTo(m_baseURL + "200-by-300.html");
527 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0),
528 webViewImpl()->page()->mainFrame()->loader().currentItem()->pinchViewportScrollPoint());
530 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
531 pinchViewport.setScale(2);
533 EXPECT_EQ(2, webViewImpl()->page()->mainFrame()->loader().currentItem()->pageScaleFactor());
535 pinchViewport.setLocation(FloatPoint(10, 20));
537 EXPECT_FLOAT_POINT_EQ(FloatPoint(10, 20),
538 webViewImpl()->page()->mainFrame()->loader().currentItem()->pinchViewportScrollPoint());
541 // Test restoring a HistoryItem properly restores the pinch viewport's state.
542 TEST_F(PinchViewportTest, TestRestoredFromHistoryItem)
544 initializeWithDesktopSettings();
545 webViewImpl()->resize(IntSize(200, 300));
547 registerMockedHttpURLLoad("200-by-300.html");
551 WebURL destinationURL(blink::URLTestHelpers::toKURL(m_baseURL + "200-by-300.html"));
552 item.setURLString(destinationURL.string());
553 item.setPinchViewportScrollOffset(WebFloatPoint(100, 120));
554 item.setPageScaleFactor(2);
556 webViewImpl()->mainFrame()->loadHistoryItem(item, WebHistoryDifferentDocumentLoad, WebURLRequest::UseProtocolCachePolicy);
557 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
559 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
560 EXPECT_EQ(2, pinchViewport.scale());
562 EXPECT_FLOAT_POINT_EQ(FloatPoint(100, 120), pinchViewport.visibleRect().location());
565 // Test restoring a HistoryItem without the pinch viewport offset falls back to distributing
566 // the scroll offset between the main frame and the pinch viewport.
567 TEST_F(PinchViewportTest, TestRestoredFromLegacyHistoryItem)
569 initializeWithDesktopSettings();
570 webViewImpl()->resize(IntSize(100, 150));
572 registerMockedHttpURLLoad("200-by-300-viewport.html");
576 WebURL destinationURL(blink::URLTestHelpers::toKURL(m_baseURL + "200-by-300-viewport.html"));
577 item.setURLString(destinationURL.string());
578 // (-1, -1) will be used if the HistoryItem is an older version prior to having
579 // pinch viewport scroll offset.
580 item.setPinchViewportScrollOffset(WebFloatPoint(-1, -1));
581 item.setScrollOffset(WebPoint(120, 180));
582 item.setPageScaleFactor(2);
584 webViewImpl()->mainFrame()->loadHistoryItem(item, WebHistoryDifferentDocumentLoad, WebURLRequest::UseProtocolCachePolicy);
585 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
587 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
588 EXPECT_EQ(2, pinchViewport.scale());
589 EXPECT_POINT_EQ(IntPoint(100, 150), frame()->view()->scrollPosition());
590 EXPECT_FLOAT_POINT_EQ(FloatPoint(20, 30), pinchViewport.visibleRect().location());
593 // Test that the scrollFocusedNodeIntoRect method works with the pinch viewport.
594 TEST_F(PinchViewportTest, TestScrollFocusedNodeIntoRect)
596 initializeWithDesktopSettings();
597 webViewImpl()->resize(IntSize(500, 300));
599 registerMockedHttpURLLoad("pinch-viewport-input-field.html");
600 navigateTo(m_baseURL + "pinch-viewport-input-field.html");
602 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
603 webViewImpl()->resizePinchViewport(IntSize(200, 100));
604 webViewImpl()->setInitialFocus(false);
605 webViewImpl()->scrollFocusedNodeIntoRect(IntRect(0, 0, 500, 200));
607 EXPECT_POINT_EQ(IntPoint(0, frame()->view()->maximumScrollPosition().y()),
608 frame()->view()->scrollPosition());
609 EXPECT_FLOAT_POINT_EQ(FloatPoint(150, 200), pinchViewport.visibleRect().location());
611 // Try it again but with the page zoomed in
612 frame()->view()->notifyScrollPositionChanged(IntPoint(0, 0));
613 webViewImpl()->resizePinchViewport(IntSize(500, 300));
614 pinchViewport.setLocation(FloatPoint(0, 0));
616 webViewImpl()->setPageScaleFactor(2);
617 webViewImpl()->scrollFocusedNodeIntoRect(IntRect(0, 0, 500, 200));
618 EXPECT_POINT_EQ(IntPoint(0, frame()->view()->maximumScrollPosition().y()),
619 frame()->view()->scrollPosition());
620 EXPECT_FLOAT_POINT_EQ(FloatPoint(125, 150), pinchViewport.visibleRect().location());
622 // Once more but make sure that we don't move the pinch viewport unless necessary.
623 registerMockedHttpURLLoad("pinch-viewport-input-field-long-and-wide.html");
624 navigateTo(m_baseURL + "pinch-viewport-input-field-long-and-wide.html");
625 webViewImpl()->setInitialFocus(false);
626 frame()->view()->notifyScrollPositionChanged(IntPoint(0, 0));
627 webViewImpl()->resizePinchViewport(IntSize(500, 300));
628 pinchViewport.setLocation(FloatPoint(30, 50));
630 webViewImpl()->setPageScaleFactor(2);
631 webViewImpl()->scrollFocusedNodeIntoRect(IntRect(0, 0, 500, 200));
632 EXPECT_POINT_EQ(IntPoint(200-30-75, 600-50-65), frame()->view()->scrollPosition());
633 EXPECT_FLOAT_POINT_EQ(FloatPoint(30, 50), pinchViewport.visibleRect().location());