[Chromium] Support scrolling and zooming to focused input elements
authorabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Jul 2012 00:27:19 +0000 (00:27 +0000)
committerabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Jul 2012 00:27:19 +0000 (00:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=91661

Reviewed by Darin Fisher.

This patch introduces saveScrollAndScaleState and
restoreScrollAndScaleState, which can be used to save and restore the
scroll and scale state of the WebView, respectively.  These functions
will be used by Chromium on Android to save the scale and scrolls state
before zoom into a text field so that we can "undo" the zoom if the
user didn't mean to zoom into the text field.

I wanted to write unit tests for these functions, but it wasn't clear
to me how to write the test because startPageScaleAnimation appears to
complete asynchronously.

* public/WebView.h:
(WebView):
* src/WebViewImpl.cpp:
(WebKit::WebViewImpl::WebViewImpl):
(WebKit::WebViewImpl::saveScrollAndScaleState):
(WebKit):
(WebKit::WebViewImpl::restoreScrollAndScaleState):
(WebKit::WebViewImpl::resetSavedScrollAndScaleState):
(WebKit::WebViewImpl::didCommitLoad):
* src/WebViewImpl.h:
(WebViewImpl):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@123554 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/public/WebView.h
Source/WebKit/chromium/src/WebViewImpl.cpp
Source/WebKit/chromium/src/WebViewImpl.h

index c65193c..16d3104 100644 (file)
@@ -1,3 +1,33 @@
+2012-07-24  Adam Barth  <abarth@webkit.org>
+
+        [Chromium] Support scrolling and zooming to focused input elements
+        https://bugs.webkit.org/show_bug.cgi?id=91661
+
+        Reviewed by Darin Fisher.
+
+        This patch introduces saveScrollAndScaleState and
+        restoreScrollAndScaleState, which can be used to save and restore the
+        scroll and scale state of the WebView, respectively.  These functions
+        will be used by Chromium on Android to save the scale and scrolls state
+        before zoom into a text field so that we can "undo" the zoom if the
+        user didn't mean to zoom into the text field.
+
+        I wanted to write unit tests for these functions, but it wasn't clear
+        to me how to write the test because startPageScaleAnimation appears to
+        complete asynchronously.
+
+        * public/WebView.h:
+        (WebView):
+        * src/WebViewImpl.cpp:
+        (WebKit::WebViewImpl::WebViewImpl):
+        (WebKit::WebViewImpl::saveScrollAndScaleState):
+        (WebKit):
+        (WebKit::WebViewImpl::restoreScrollAndScaleState):
+        (WebKit::WebViewImpl::resetSavedScrollAndScaleState):
+        (WebKit::WebViewImpl::didCommitLoad):
+        * src/WebViewImpl.h:
+        (WebViewImpl):
+
 2012-07-24  Dave Tu  <dtu@chromium.org>
 
         [chromium] Add time spent painting to GPU benchmarking renderingStats() API.
index 0085ba5..7e8da86 100644 (file)
@@ -254,6 +254,14 @@ public:
     virtual float minimumPageScaleFactor() const = 0;
     virtual float maximumPageScaleFactor() const = 0;
 
+    // Save the WebView's current scroll and scale state. Each call to this function
+    // overwrites the previously saved scroll and scale state.
+    virtual void saveScrollAndScaleState() = 0;
+
+    // Restore the previously saved scroll and scale state. After restroing the
+    // state, this function deletes any saved scroll and scale state.
+    virtual void restoreScrollAndScaleState() = 0;
+
     // Prevent the web page from setting a maximum scale via the viewport meta
     // tag. This is an accessibility feature that lets folks zoom in to web
     // pages even if the web page tries to block scaling.
index 3729dce..7c6da60 100644 (file)
@@ -197,6 +197,8 @@ static const float doubleTapZoomContentDefaultMargin = 5;
 static const float doubleTapZoomContentMinimumMargin = 2;
 static const double doubleTabZoomAnimationDurationInSeconds = 0.25;
 
+// Constants for zooming in on a focused text field.
+static const double scrollAndScaleAnimationDurationInSeconds = 0.2;
 
 namespace WebKit {
 
@@ -392,6 +394,7 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
     , m_maximumPageScaleFactor(maxPageScaleFactor)
     , m_ignoreViewportTagMaximumScale(false)
     , m_pageScaleFactorIsSet(false)
+    , m_savedPageScaleFactor(0)
     , m_contextMenuAllowed(false)
     , m_doingDragAndDrop(false)
     , m_ignoreInputEvents(false)
@@ -2730,6 +2733,33 @@ float WebViewImpl::maximumPageScaleFactor() const
     return m_maximumPageScaleFactor;
 }
 
+void WebViewImpl::saveScrollAndScaleState()
+{
+    m_savedPageScaleFactor = pageScaleFactor();
+    m_savedScrollOffset = mainFrame()->scrollOffset();
+}
+
+void WebViewImpl::restoreScrollAndScaleState()
+{
+    if (!m_savedPageScaleFactor)
+        return;
+
+#if ENABLE(GESTURE_EVENTS)
+    startPageScaleAnimation(IntPoint(m_savedScrollOffset), false, m_savedPageScaleFactor, scrollAndScaleAnimationDurationInSeconds);
+#else
+    setPageScaleFactor(m_savedPageScaleFactor, WebPoint());
+    mainFrame()->setScrollOffset(m_savedScrollOffset);
+#endif
+
+    resetSavedScrollAndScaleState();
+}
+
+void WebViewImpl::resetSavedScrollAndScaleState()
+{
+    m_savedPageScaleFactor = 0;
+    m_savedScrollOffset = IntSize();
+}
+
 WebSize WebViewImpl::fixedLayoutSize() const
 {
     if (!page())
@@ -3263,6 +3293,7 @@ void WebViewImpl::didCommitLoad(bool* isNewNavigation, bool isNavigationWithinPa
         m_pageScaleFactorIsSet = false;
 
     m_gestureAnimation.clear();
+    resetSavedScrollAndScaleState();
 }
 
 void WebViewImpl::layoutUpdated(WebFrameImpl* webframe)
index 1155969..01f5066 100644 (file)
@@ -220,6 +220,8 @@ public:
     virtual void setPageScaleFactorLimits(float minPageScale, float maxPageScale);
     virtual float minimumPageScaleFactor() const;
     virtual float maximumPageScaleFactor() const;
+    virtual void saveScrollAndScaleState();
+    virtual void restoreScrollAndScaleState();
     virtual void setIgnoreViewportTagMaximumScale(bool);
 
     virtual float deviceScaleFactor() const;
@@ -579,6 +581,8 @@ private:
     float clampPageScaleFactorToLimits(float scale);
     WebPoint clampOffsetAtScale(const WebPoint& offset, float scale);
 
+    void resetSavedScrollAndScaleState();
+
     friend class WebView;  // So WebView::Create can call our constructor
     friend class WTF::RefCounted<WebViewImpl>;
 
@@ -707,15 +711,18 @@ private:
 
     double m_maximumZoomLevel;
 
+    // State related to the page scale
     float m_pageDefinedMinimumPageScaleFactor;
     float m_pageDefinedMaximumPageScaleFactor;
     float m_minimumPageScaleFactor;
     float m_maximumPageScaleFactor;
-
     bool m_ignoreViewportTagMaximumScale;
-
     bool m_pageScaleFactorIsSet;
 
+    // Saved page scale state.
+    float m_savedPageScaleFactor; // 0 means that no page scale factor is saved.
+    WebCore::IntSize m_savedScrollOffset;
+
     bool m_contextMenuAllowed;
 
     bool m_doingDragAndDrop;