Title: [136129] trunk/Source/WebKit2
Revision
136129
Author
allan.jen...@digia.com
Date
2012-11-29 07:00:49 -0800 (Thu, 29 Nov 2012)

Log Message

Possible to resize out of bounds
https://bugs.webkit.org/show_bug.cgi?id=103521

Reviewed by Jocelyn Turcotte.

Enforce the viewportBounds after resize, and ensure a user fitted page remains
fit on viewport resize, but not on content growth.

* UIProcess/API/qt/tests/qmltests/WebView/tst_resize.qml: Added.
* UIProcess/PageViewportController.cpp:
(WebKit::PageViewportController::didChangeContentsSize):
(WebKit::PageViewportController::didChangeViewportAttributes):
(WebKit::PageViewportController::updateMinimumScaleToFit):
* UIProcess/PageViewportController.h:
(PageViewportController):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (136128 => 136129)


--- trunk/Source/WebKit2/ChangeLog	2012-11-29 14:57:38 UTC (rev 136128)
+++ trunk/Source/WebKit2/ChangeLog	2012-11-29 15:00:49 UTC (rev 136129)
@@ -1,3 +1,21 @@
+2012-11-29  Allan Sandfeld Jensen  <allan.jen...@digia.com>
+
+        Possible to resize out of bounds 
+        https://bugs.webkit.org/show_bug.cgi?id=103521
+
+        Reviewed by Jocelyn Turcotte.
+
+        Enforce the viewportBounds after resize, and ensure a user fitted page remains
+        fit on viewport resize, but not on content growth.
+
+        * UIProcess/API/qt/tests/qmltests/WebView/tst_resize.qml: Added.
+        * UIProcess/PageViewportController.cpp:
+        (WebKit::PageViewportController::didChangeContentsSize):
+        (WebKit::PageViewportController::didChangeViewportAttributes):
+        (WebKit::PageViewportController::updateMinimumScaleToFit):
+        * UIProcess/PageViewportController.h:
+        (PageViewportController):
+
 2012-11-29  Michael BrĂ¼ning  <michael.brun...@digia.com>
 
         [Qt][WK2] Commit the preedit string in the input method when focus is about to be moved.

Added: trunk/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_resize.qml (0 => 136129)


--- trunk/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_resize.qml	                        (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_resize.qml	2012-11-29 15:00:49 UTC (rev 136129)
@@ -0,0 +1,175 @@
+import QtQuick 2.0
+import QtTest 1.0
+import QtWebKit 3.0
+import QtWebKit.experimental 1.0
+import Test 1.0
+import "../common"
+
+Item {
+    TestWebView {
+        id: webView
+        width: 320
+        height: 480
+
+        property variant result
+
+        property variant content: "data:text/html," +
+            "<head>" +
+            "    <meta name='viewport' content='width=device-width'>" +
+            "</head>" +
+            "<body>" +
+            "    <div id='target' style='width: 240px; height: 360px;'>" +
+            "    </div>" +
+            "</body>"
+
+        signal resultReceived
+    }
+
+    SignalSpy {
+        id: resultSpy
+        target: webView
+        signalName: "resultReceived"
+    }
+
+    SignalSpy {
+        id: scaleSpy
+        target: webView.experimental.test
+        signalName: "contentsScaleCommitted"
+    }
+
+    SignalSpy {
+        id: sizeSpy
+        target: webView.experimental.test
+        signalName: "contentsSizeChanged"
+    }
+
+    TestCase {
+        name: "Resize"
+        when: windowShown
+
+        property variant test: webView.experimental.test
+
+        function init() {
+            resultSpy.clear()
+            scaleSpy.clear()
+            viewportSpy.clear()
+        }
+
+        function run(signalSpy, script) {
+            signalSpy.clear();
+            var result;
+            webView.experimental.evaluateJavaScript(
+                script,
+                function(value) { webView.resultReceived(); result = value });
+            signalSpy.wait();
+            return result;
+        }
+
+        function contentsSize() {
+            return test.contentsSize.width + "x" + test.contentsSize.height;
+        }
+
+        function elementRect(id) {
+            return JSON.parse(run(resultSpy, "JSON.stringify(document.getElementById('" + id + "').getBoundingClientRect());"))
+        }
+
+        function doubleTapAtPoint(x, y) {
+            scaleSpy.clear()
+            test.touchDoubleTap(webView, x, y)
+            scaleSpy.wait()
+        }
+
+        function resize(w, h) {
+            sizeSpy.clear()
+            webView.width = w
+            sizeSpy.wait()
+            webView.height = h
+            sizeSpy.wait()
+        }
+
+        function test_basic() {
+            webView.url = ""
+            verify(webView.waitForViewportReady())
+
+            compare(contentsSize(), "320x480")
+            compare(test.contentsScale, 1.0)
+
+            resize(480, 720)
+            compare(contentsSize(), "480x720")
+            compare(test.contentsScale, 1.0)
+
+            resize(320, 480)
+            compare(contentsSize(), "320x480")
+            compare(test.contentsScale, 1.0)
+
+        }
+
+        function test_resizeAfterNeutralZoom() {
+            webView.url = ""
+            verify(webView.waitForViewportReady())
+
+            compare(contentsSize(), "320x480")
+            compare(test.contentsScale, 1.0)
+
+            var target = elementRect("target");
+            var targetScale = webView.width / (target.width + 2 * 10) // inflated by 10px
+
+            // Zoom in and out.
+            doubleTapAtPoint(100, 50)
+
+            compare(test.contentsScale, targetScale)
+
+            doubleTapAtPoint(100, 50)
+
+            compare(test.contentsScale, 1.0)
+
+            // Now check resizing still works as expected.
+            resize(480, 720)
+            compare(contentsSize(), "480x720")
+            compare(test.contentsScale, 1.0)
+
+            resize(320, 480)
+            compare(contentsSize(), "320x480")
+            compare(test.contentsScale, 1.0)
+        }
+
+        function test_resizeZoomedIn() {
+            // Note that if we change the behavior of resize on zoomed-in content, for instance
+            // to preserve the visible width (like rotate), this test will need to be updated.
+            webView.url = ""
+            verify(webView.waitForViewportReady())
+
+            compare(contentsSize(), "320x480")
+            compare(test.contentsScale, 1.0)
+
+            var target = elementRect("target");
+            var targetScale = webView.width / (target.width + 2 * 10) // inflated by 10px
+
+            // Double tap to zoom in.
+            doubleTapAtPoint(100, 50)
+
+            compare(test.contentsScale, targetScale)
+
+            // Resize just a small bit, not changing scale.
+            resize(288, 432)
+            compare(contentsSize(), "288x432")
+            compare(test.contentsScale, targetScale)
+
+            // And double tap to reset zoom.
+            target = elementRect("target");
+            targetScale = webView.width / (target.width + 2 * 10)
+            doubleTapAtPoint(100, 50)
+            compare(test.contentsScale, targetScale)
+
+            // Double tap again to zoom out.
+            doubleTapAtPoint(100, 50)
+            compare(contentsSize(), "288x432")
+            compare(test.contentsScale, 1.0)
+
+            // And reset
+            resize(320, 480)
+            compare(contentsSize(), "320x480")
+            compare(test.contentsScale, 1.0)
+        }
+    }
+}

Modified: trunk/Source/WebKit2/UIProcess/PageViewportController.cpp (136128 => 136129)


--- trunk/Source/WebKit2/UIProcess/PageViewportController.cpp	2012-11-29 14:57:38 UTC (rev 136128)
+++ trunk/Source/WebKit2/UIProcess/PageViewportController.cpp	2012-11-29 15:00:49 UTC (rev 136129)
@@ -111,7 +111,7 @@
 {
     m_contentsSize = newSize;
 
-    bool minimumScaleUpdated = updateMinimumScaleToFit();
+    bool minimumScaleUpdated = updateMinimumScaleToFit(false);
 
     if (m_initiallyFitToViewport) {
         // Restrict scale factors to m_minimumScaleToFit.
@@ -232,7 +232,7 @@
     if (!m_initiallyFitToViewport)
         WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(m_rawAttributes);
 
-    if (updateMinimumScaleToFit())
+    if (updateMinimumScaleToFit(true))
         m_client->didChangeViewportAttributes();
 
     syncVisibleContents();
@@ -277,11 +277,13 @@
     syncVisibleContents();
 }
 
-bool PageViewportController::updateMinimumScaleToFit()
+bool PageViewportController::updateMinimumScaleToFit(bool userInitiatedUpdate)
 {
     if (m_viewportSize.isEmpty() || m_contentsSize.isEmpty())
         return false;
 
+    bool currentlyScaledToFit = fuzzyCompare(m_effectiveScale, toViewportScale(m_minimumScaleToFit), 0.001);
+
     float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(m_rawAttributes, WebCore::roundedIntSize(m_viewportSize), WebCore::roundedIntSize(m_contentsSize), devicePixelRatio());
 
     if (minimumScale <= 0)
@@ -290,8 +292,16 @@
     if (!fuzzyCompare(minimumScale, m_minimumScaleToFit, 0.001)) {
         m_minimumScaleToFit = minimumScale;
 
-        if (!m_hadUserInteraction && !hasSuspendedContent())
-            applyScaleAfterRenderingContents(toViewportScale(minimumScale));
+        if (!hasSuspendedContent()) {
+            if (!m_hadUserInteraction || (userInitiatedUpdate && currentlyScaledToFit))
+                applyScaleAfterRenderingContents(toViewportScale(m_minimumScaleToFit));
+            else {
+                // Ensure the effective scale stays within bounds.
+                float boundedScale = innerBoundedViewportScale(m_effectiveScale);
+                if (!fuzzyCompare(boundedScale, m_effectiveScale, 0.001))
+                    applyScaleAfterRenderingContents(boundedScale);
+            }
+        }
 
         return true;
     }

Modified: trunk/Source/WebKit2/UIProcess/PageViewportController.h (136128 => 136129)


--- trunk/Source/WebKit2/UIProcess/PageViewportController.h	2012-11-29 14:57:38 UTC (rev 136128)
+++ trunk/Source/WebKit2/UIProcess/PageViewportController.h	2012-11-29 15:00:49 UTC (rev 136129)
@@ -84,7 +84,7 @@
     void syncVisibleContents(const WebCore::FloatPoint &trajectoryVector = WebCore::FloatPoint::zero());
     void applyScaleAfterRenderingContents(float scale);
     void applyPositionAfterRenderingContents(const WebCore::FloatPoint& pos);
-    bool updateMinimumScaleToFit();
+    bool updateMinimumScaleToFit(bool userInitiatedUpdate);
     WebCore::FloatSize viewportSizeInContentsCoordinates() const;
 
     WebPageProxy* const m_webPageProxy;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to