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;