Implement viewport-width-based fast-click heuristic
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Oct 2015 23:34:54 +0000 (23:34 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Oct 2015 23:34:54 +0000 (23:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=150604
<rdar://problem/23267308>

Reviewed by Simon Fraser.

Source/WebKit2:

Implement a new fast-click heuristic that applies to viewports with width = device-width. The basic rules are
as follows: when a page has viewport width = device-width and is at initial zoom scale, we disable double-tapping
in favor of fast-clicking. However, if the viewport scale is not the initial scale, we allow double tapping. For
fast-clicking to remain useful after the user pinch-zooms, we change our double-tap to zoom out behavior to zoom
to the initial scale rather than the minimum scale. For unscalable viewports, we default to fast-clicking behavior,
and for all other viewports not at device-width, we double-tap to zoom and scroll as normal.

This patch removes some logic previously used for our scroll- and zoom-based fast-clicking heuristic, and adds
information about the viewport width and initial scale to RemoteLayerTreeTransactions. This information is then
used by the UI process to determine whether double tapping should be disabled or enabled.

The fast-click heuristic can be turned off through user default preferences, and a tap highlight for debugging
fast-clicking can also be enabled through a user default preference. A red highlight indicates that a single-
tap was slow, whereas a green highlight indicates a fast single-tap.

* Shared/mac/RemoteLayerTreeTransaction.h:
(WebKit::RemoteLayerTreeTransaction::initialScaleFactor):
(WebKit::RemoteLayerTreeTransaction::setInitialScaleFactor):
(WebKit::RemoteLayerTreeTransaction::viewportMetaTagWidth):
(WebKit::RemoteLayerTreeTransaction::setViewportMetaTagWidth):
* Shared/mac/RemoteLayerTreeTransaction.mm:
(WebKit::RemoteLayerTreeTransaction::encode):
(WebKit::RemoteLayerTreeTransaction::decode):
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView initWithFrame:configuration:]):
(-[WKWebView _processDidExit]):
(-[WKWebView _didCommitLayerTree:]):
(-[WKWebView _zoomToInitialScaleWithOrigin:animated:]):
(-[WKWebView _allowsDoubleTapGestures]):
(-[WKWebView _setViewportMetaTagWidth:]): Deleted.
(-[WKWebView _contentZoomScale]): Deleted.
(-[WKWebView _viewportMetaTagWidth]): Deleted.
(-[WKWebView _viewportIsUserScalable]): Deleted.
* UIProcess/API/Cocoa/WKWebViewInternal.h:
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::disableDoubleTapGesturesDuringTapIfNecessary):
(WebKit::PageClientImpl::didChangeViewportMetaTagWidth): Deleted.
(WebKit::PageClientImpl::disableDoubleTapGesturesUntilTapIsFinishedIfNecessary): Deleted.
* UIProcess/ios/SmartMagnificationController.h:
* UIProcess/ios/SmartMagnificationController.mm:
(WebKit::SmartMagnificationController::didCollectGeometryForSmartMagnificationGesture):
* UIProcess/ios/WKContentView.h:
* UIProcess/ios/WKContentView.mm:
(-[WKContentView _zoomToInitialScaleWithOrigin:]):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView setupInteraction]):
(-[WKContentView _showTapHighlight]):
(-[WKContentView _didGetTapHighlightForRequest:color:quads:topLeftRadius:topRightRadius:bottomLeftRadius:bottomRightRadius:]):
(-[WKContentView _mayDisableDoubleTapGesturesDuringSingleTap]):
(-[WKContentView _disableDoubleTapGesturesDuringTapIfNecessary:]):
(-[WKContentView _finishInteraction]):
(-[WKContentView _endPotentialTapAndEnableDoubleTapGesturesIfNecessary]):
(-[WKContentView _tapHighlightColorForFastClick:]):
(-[WKContentView _setDoubleTapGesturesEnabled:]):
(-[WKContentView _fastClickZoomThreshold]): Deleted.
(-[WKContentView _allowDoubleTapToZoomForCurrentZoomScale:andTargetZoomScale:]): Deleted.
(-[WKContentView _disableDoubleTapGesturesUntilTapIsFinishedIfNecessary:allowsDoubleTapZoom:targetRect:isReplaced:minimumScale:maximumScale:]): Deleted.
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::disableDoubleTapGesturesDuringTapIfNecessary):
(WebKit::WebPageProxy::viewportMetaTagWidthDidChange): Deleted.
(WebKit::WebPageProxy::disableDoubleTapGesturesUntilTapIsFinishedIfNecessary): Deleted.
* WebProcess/WebPage/ViewGestureGeometryCollector.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::willCommitLayerTree):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::potentialTapAtPosition):
(WebKit::WebPage::viewportPropertiesDidChange): Deleted.

LayoutTests:

Implement a new fast-click heuristic that applies to viewports with width = device-width. Adds
new tests to check various fast-clicking behaviors. These three tests check (for pages with width=
device-width) that:

- Double-tapping to zoom still works when the scale is not the initial scale.
- If the page is at initial scale, we fire fast-clicks instead of zooming.
- When zooming out from element scale, we end up at initial scale instead of minimum scale.

* fast/events/ios/viewport-device-width-allows-double-tap-zoom-out-expected.txt: Added.
* fast/events/ios/viewport-device-width-allows-double-tap-zoom-out.html: Added.
* fast/events/ios/viewport-device-width-at-initial-scale-fast-clicks-expected.txt: Added.
* fast/events/ios/viewport-device-width-at-initial-scale-fast-clicks.html: Added.
* fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: Added.
* fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: Added.

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

28 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/events/ios/viewport-device-width-allows-double-tap-zoom-out-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/ios/viewport-device-width-allows-double-tap-zoom-out.html [new file with mode: 0644]
LayoutTests/fast/events/ios/viewport-device-width-at-initial-scale-fast-clicks-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/ios/viewport-device-width-at-initial-scale-fast-clicks.html [new file with mode: 0644]
LayoutTests/fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/ios/viewport-zooms-from-element-to-initial-scale.html [new file with mode: 0644]
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.h
Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm
Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit2/UIProcess/PageClient.h
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPageProxy.messages.in
Source/WebKit2/UIProcess/ios/PageClientImplIOS.h
Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm
Source/WebKit2/UIProcess/ios/SmartMagnificationController.h
Source/WebKit2/UIProcess/ios/SmartMagnificationController.mm
Source/WebKit2/UIProcess/ios/WKContentView.h
Source/WebKit2/UIProcess/ios/WKContentView.mm
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm
Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.h
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm

index abab69faef542a8f1cefb2e1f0938dc7a5c6a45a..fec97b373991cb08df22c3f0bd2c05b788820173 100644 (file)
@@ -1,3 +1,26 @@
+2015-10-27  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Implement viewport-width-based fast-click heuristic
+        https://bugs.webkit.org/show_bug.cgi?id=150604
+        <rdar://problem/23267308>
+
+        Reviewed by Simon Fraser.
+
+        Implement a new fast-click heuristic that applies to viewports with width = device-width. Adds
+        new tests to check various fast-clicking behaviors. These three tests check (for pages with width=
+        device-width) that:
+
+        - Double-tapping to zoom still works when the scale is not the initial scale.
+        - If the page is at initial scale, we fire fast-clicks instead of zooming.
+        - When zooming out from element scale, we end up at initial scale instead of minimum scale.
+
+        * fast/events/ios/viewport-device-width-allows-double-tap-zoom-out-expected.txt: Added.
+        * fast/events/ios/viewport-device-width-allows-double-tap-zoom-out.html: Added.
+        * fast/events/ios/viewport-device-width-at-initial-scale-fast-clicks-expected.txt: Added.
+        * fast/events/ios/viewport-device-width-at-initial-scale-fast-clicks.html: Added.
+        * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: Added.
+        * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: Added.
+
 2015-10-27  Ryan Haddad  <ryanhaddad@apple.com>
 
         Cleaning up formatting on recent additions win TestExpectations file
diff --git a/LayoutTests/fast/events/ios/viewport-device-width-allows-double-tap-zoom-out-expected.txt b/LayoutTests/fast/events/ios/viewport-device-width-allows-double-tap-zoom-out-expected.txt
new file mode 100644 (file)
index 0000000..b447114
--- /dev/null
@@ -0,0 +1,2 @@
+The viewport zoomed to scale: 1.6
+
diff --git a/LayoutTests/fast/events/ios/viewport-device-width-allows-double-tap-zoom-out.html b/LayoutTests/fast/events/ios/viewport-device-width-allows-double-tap-zoom-out.html
new file mode 100644 (file)
index 0000000..0a0e29f
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+
+<html>
+<meta name="viewport" content="initial-scale=1.0, width=device-width">
+<head>
+    <script id="ui-script" type="text/plain">
+        (function() {
+            uiController.didEndZoomingCallback = function() {
+                uiController.uiScriptComplete(uiController.zoomScale);
+            };
+            uiController.doubleTapAtPoint(15, 15, function() {});
+        })();
+    </script>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        function getUIScript()
+        {
+            return document.getElementById("ui-script").text;
+        }
+
+        function runTest()
+        {
+            if (!window.eventSender || !testRunner.runUIScript)
+                return;
+
+            eventSender.scalePageBy(3, 3);
+            testRunner.runUIScript(getUIScript(), function(result) {
+                document.getElementById("target").innerText = "The viewport zoomed to scale: " + result;
+                testRunner.notifyDone();
+            });
+        }
+
+        function handleClick()
+        {
+            document.getElementById("target").innerText = "FAIL: Click fired when we should only be zooming.";
+            testRunner.notifyDone();
+        }
+    </script>
+    <style>
+        body {
+            margin: 0;
+        }
+        #target {
+            height: 100px;
+            width: 100px;
+            background-color: silver;
+        }
+    </style>
+</head>
+<body onload="runTest()">
+<div id="target"></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/ios/viewport-device-width-at-initial-scale-fast-clicks-expected.txt b/LayoutTests/fast/events/ios/viewport-device-width-at-initial-scale-fast-clicks-expected.txt
new file mode 100644 (file)
index 0000000..512374b
--- /dev/null
@@ -0,0 +1,12 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+Repeatedly tapping on the button should fire click events.
+
+This test is best run in WebKitTestRunner. If you are running this test manually, verify that tapping the button causes a "Click!" message to appear below, and that click occurred without the regular 350ms delay for double tapping.
+
+Click!
+Click!
+Click!
+
diff --git a/LayoutTests/fast/events/ios/viewport-device-width-at-initial-scale-fast-clicks.html b/LayoutTests/fast/events/ios/viewport-device-width-at-initial-scale-fast-clicks.html
new file mode 100644 (file)
index 0000000..ff37391
--- /dev/null
@@ -0,0 +1,62 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+
+<html>
+<meta name="viewport" content="initial-scale=1.0, width=device-width">
+
+<head>
+    <script src="../../../resources/js-test-pre.js"></script>
+    <script id="ui-script" type="text/plain">
+        (function() {
+            uiController.didEndZoomingCallback = function() {
+                uiController.uiScriptComplete("FAIL: Zoomed to scale " + uiController.zoomScale + " when we should only be firing fast clicks.");
+            };
+
+            function fireSuccessiveSingleTaps() {
+                uiController.singleTapAtPoint(200, 200, fireSuccessiveSingleTaps);
+            }
+            fireSuccessiveSingleTaps();
+        })();
+    </script>
+
+    <script>
+    var clickCount = 0;
+    if (window.testRunner)
+        testRunner.waitUntilDone();
+
+    function getUIScript() {
+        return document.getElementById("ui-script").text;
+    }
+
+    function runTest() {
+        if (testRunner.runUIScript)
+            testRunner.runUIScript(getUIScript(), function(result) { });
+    }
+    function handleClicked() {
+        clickCount++;
+        document.body.appendChild(document.createTextNode("Click!"));
+        document.body.appendChild(document.createElement("br"));
+        if (clickCount == 3)
+            testRunner.notifyDone();
+    }
+    </script>
+
+    <style>
+    body {
+        margin: 0;
+    }
+
+    #target {
+        width: 400px;
+        height: 400px;
+    }
+    </style>
+</head>
+
+<body onload="runTest()">
+    <button id="target" onclick="handleClicked()"></button>
+    <p>Repeatedly tapping on the button should fire click events.</p>
+    <p>This test is best run in WebKitTestRunner. If you are running this test manually, verify that tapping the button causes a "Click!" message to appear below, and that click occurred without the regular 350ms delay for double tapping.</p>
+    <script src="../../../resources/js-test-post.js"></script>
+</body>
+
+</html>
diff --git a/LayoutTests/fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt b/LayoutTests/fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt
new file mode 100644 (file)
index 0000000..c979464
--- /dev/null
@@ -0,0 +1 @@
+The viewport zoomed to scale: 5
diff --git a/LayoutTests/fast/events/ios/viewport-zooms-from-element-to-initial-scale.html b/LayoutTests/fast/events/ios/viewport-zooms-from-element-to-initial-scale.html
new file mode 100644 (file)
index 0000000..6769122
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+
+<html>
+<meta name="viewport" content="initial-scale=5, width=device-width">
+<head>
+    <script id="ui-script" type="text/plain">
+        (function() {
+            uiController.didEndZoomingCallback = function() {
+                uiController.uiScriptComplete(uiController.zoomScale);
+            };
+            uiController.doubleTapAtPoint(15, 15, function() {});
+        })();
+    </script>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        function getUIScript()
+        {
+            return document.getElementById("ui-script").text;
+        }
+
+        function runTest()
+        {
+            if (!window.eventSender || !testRunner.runUIScript)
+                return;
+
+            eventSender.scalePageBy(1.6, 1.6);
+            testRunner.runUIScript(getUIScript(), function(result) {
+                document.getElementById("target").innerText = "The viewport zoomed to scale: " + Number(result);
+                testRunner.notifyDone();
+            });
+        }
+
+        function handleClick()
+        {
+            document.getElementById("target").innerText = "FAIL: Click fired when we should only be zooming.";
+            testRunner.notifyDone();
+        }
+    </script>
+    <style>
+        body {
+            margin: 0;
+        }
+        #target {
+            height: 100px;
+            width: 100px;
+            background-color: silver;
+        }
+    </style>
+</head>
+<body onload="runTest()">
+<div id="target"></div>
+</body>
+</html>
index cba601ddff873bbf38cd397536994293085406e1..af44f2d90dbc340baae687f48e5473d7ddded2de 100644 (file)
@@ -1,3 +1,85 @@
+2015-10-27  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Implement viewport-width-based fast-click heuristic
+        https://bugs.webkit.org/show_bug.cgi?id=150604
+        <rdar://problem/23267308>
+
+        Reviewed by Simon Fraser.
+
+        Implement a new fast-click heuristic that applies to viewports with width = device-width. The basic rules are
+        as follows: when a page has viewport width = device-width and is at initial zoom scale, we disable double-tapping
+        in favor of fast-clicking. However, if the viewport scale is not the initial scale, we allow double tapping. For
+        fast-clicking to remain useful after the user pinch-zooms, we change our double-tap to zoom out behavior to zoom
+        to the initial scale rather than the minimum scale. For unscalable viewports, we default to fast-clicking behavior,
+        and for all other viewports not at device-width, we double-tap to zoom and scroll as normal.
+
+        This patch removes some logic previously used for our scroll- and zoom-based fast-clicking heuristic, and adds
+        information about the viewport width and initial scale to RemoteLayerTreeTransactions. This information is then
+        used by the UI process to determine whether double tapping should be disabled or enabled.
+
+        The fast-click heuristic can be turned off through user default preferences, and a tap highlight for debugging
+        fast-clicking can also be enabled through a user default preference. A red highlight indicates that a single-
+        tap was slow, whereas a green highlight indicates a fast single-tap.
+
+        * Shared/mac/RemoteLayerTreeTransaction.h:
+        (WebKit::RemoteLayerTreeTransaction::initialScaleFactor):
+        (WebKit::RemoteLayerTreeTransaction::setInitialScaleFactor):
+        (WebKit::RemoteLayerTreeTransaction::viewportMetaTagWidth):
+        (WebKit::RemoteLayerTreeTransaction::setViewportMetaTagWidth):
+        * Shared/mac/RemoteLayerTreeTransaction.mm:
+        (WebKit::RemoteLayerTreeTransaction::encode):
+        (WebKit::RemoteLayerTreeTransaction::decode):
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView initWithFrame:configuration:]):
+        (-[WKWebView _processDidExit]):
+        (-[WKWebView _didCommitLayerTree:]):
+        (-[WKWebView _zoomToInitialScaleWithOrigin:animated:]):
+        (-[WKWebView _allowsDoubleTapGestures]):
+        (-[WKWebView _setViewportMetaTagWidth:]): Deleted.
+        (-[WKWebView _contentZoomScale]): Deleted.
+        (-[WKWebView _viewportMetaTagWidth]): Deleted.
+        (-[WKWebView _viewportIsUserScalable]): Deleted.
+        * UIProcess/API/Cocoa/WKWebViewInternal.h:
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/ios/PageClientImplIOS.h:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::disableDoubleTapGesturesDuringTapIfNecessary):
+        (WebKit::PageClientImpl::didChangeViewportMetaTagWidth): Deleted.
+        (WebKit::PageClientImpl::disableDoubleTapGesturesUntilTapIsFinishedIfNecessary): Deleted.
+        * UIProcess/ios/SmartMagnificationController.h:
+        * UIProcess/ios/SmartMagnificationController.mm:
+        (WebKit::SmartMagnificationController::didCollectGeometryForSmartMagnificationGesture):
+        * UIProcess/ios/WKContentView.h:
+        * UIProcess/ios/WKContentView.mm:
+        (-[WKContentView _zoomToInitialScaleWithOrigin:]):
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView setupInteraction]):
+        (-[WKContentView _showTapHighlight]):
+        (-[WKContentView _didGetTapHighlightForRequest:color:quads:topLeftRadius:topRightRadius:bottomLeftRadius:bottomRightRadius:]):
+        (-[WKContentView _mayDisableDoubleTapGesturesDuringSingleTap]):
+        (-[WKContentView _disableDoubleTapGesturesDuringTapIfNecessary:]):
+        (-[WKContentView _finishInteraction]):
+        (-[WKContentView _endPotentialTapAndEnableDoubleTapGesturesIfNecessary]):
+        (-[WKContentView _tapHighlightColorForFastClick:]):
+        (-[WKContentView _setDoubleTapGesturesEnabled:]):
+        (-[WKContentView _fastClickZoomThreshold]): Deleted.
+        (-[WKContentView _allowDoubleTapToZoomForCurrentZoomScale:andTargetZoomScale:]): Deleted.
+        (-[WKContentView _disableDoubleTapGesturesUntilTapIsFinishedIfNecessary:allowsDoubleTapZoom:targetRect:isReplaced:minimumScale:maximumScale:]): Deleted.
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::disableDoubleTapGesturesDuringTapIfNecessary):
+        (WebKit::WebPageProxy::viewportMetaTagWidthDidChange): Deleted.
+        (WebKit::WebPageProxy::disableDoubleTapGesturesUntilTapIsFinishedIfNecessary): Deleted.
+        * WebProcess/WebPage/ViewGestureGeometryCollector.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::willCommitLayerTree):
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::potentialTapAtPosition):
+        (WebKit::WebPage::viewportPropertiesDidChange): Deleted.
+
 2015-10-27  Tim Horton  <timothy_horton@apple.com>
 
         WKView being inside WKWebView leads to weird API issues
index 8a00a3c68b2cb2a62d989c419e1aec221704d1c1..068d22e967ef672e33a56941759b49d9beb7e708 100644 (file)
@@ -224,6 +224,12 @@ public:
     double maximumScaleFactor() const { return m_maximumScaleFactor; }
     void setMaximumScaleFactor(double scale) { m_maximumScaleFactor = scale; }
 
+    double initialScaleFactor() const { return m_initialScaleFactor; }
+    void setInitialScaleFactor(double scale) { m_initialScaleFactor = scale; }
+
+    double viewportMetaTagWidth() const { return m_viewportMetaTagWidth; }
+    void setViewportMetaTagWidth(double width) { m_viewportMetaTagWidth = width; }
+
     bool allowsUserScaling() const { return m_allowsUserScaling; }
     void setAllowsUserScaling(bool allowsUserScaling) { m_allowsUserScaling = allowsUserScaling; }
 
@@ -258,6 +264,8 @@ private:
     double m_pageScaleFactor { 1 };
     double m_minimumScaleFactor { 1 };
     double m_maximumScaleFactor { 1 };
+    double m_initialScaleFactor { 1 };
+    double m_viewportMetaTagWidth { -1 };
     uint64_t m_renderTreeSize { 0 };
     uint64_t m_transactionID { 0 };
     WebCore::LayoutMilestones m_newlyReachedLayoutMilestones { 0 };
index 7e7c932c2f0ed11e889c157ba74b492934541b02..d6a9e280554a6784b4f241393c92cc6e9d85972a 100644 (file)
@@ -517,6 +517,8 @@ void RemoteLayerTreeTransaction::encode(IPC::ArgumentEncoder& encoder) const
     encoder << m_pageScaleFactor;
     encoder << m_minimumScaleFactor;
     encoder << m_maximumScaleFactor;
+    encoder << m_initialScaleFactor;
+    encoder << m_viewportMetaTagWidth;
 
     encoder << m_renderTreeSize;
     encoder << m_transactionID;
@@ -597,6 +599,12 @@ bool RemoteLayerTreeTransaction::decode(IPC::ArgumentDecoder& decoder, RemoteLay
     if (!decoder.decode(result.m_maximumScaleFactor))
         return false;
 
+    if (!decoder.decode(result.m_initialScaleFactor))
+        return false;
+
+    if (!decoder.decode(result.m_viewportMetaTagWidth))
+        return false;
+
     if (!decoder.decode(result.m_renderTreeSize))
         return false;
 
index 5931ef32eed7feb8daa092d534b571dc50b3bad7..8852cc42cde6cd1d5564a3d1dcdad7bf7aa58f67 100644 (file)
@@ -174,6 +174,9 @@ WKWebView* fromWebPageProxy(WebKit::WebPageProxy& page)
     CGSize _maximumUnobscuredSizeOverride;
     CGRect _inputViewBounds;
     CGFloat _viewportMetaTagWidth;
+    CGFloat _initialScaleFactor;
+    BOOL _fastClickingIsDisabled;
+
     BOOL _allowsLinkPreview;
 
     UIEdgeInsets _obscuredInsets;
@@ -353,7 +356,9 @@ static bool shouldAllowPictureInPictureMediaPlayback()
     [_scrollView addSubview:[_contentView unscaledView]];
     [self _updateScrollViewBackground];
 
-    _viewportMetaTagWidth = -1;
+    _viewportMetaTagWidth = WebCore::ViewportArguments::ValueAuto;
+    _initialScaleFactor = 1;
+    _fastClickingIsDisabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitFastClickingDisabled"];
 
     [self _frameOrBoundsChanged];
 
@@ -814,11 +819,6 @@ static CGSize roundScrollViewContentSize(const WebKit::WebPageProxy& page, CGSiz
     _page->didLayoutForCustomContentProvider();
 }
 
-- (void)_setViewportMetaTagWidth:(float)newWidth
-{
-    _viewportMetaTagWidth = newWidth;
-}
-
 - (void)_willInvokeUIScrollViewDelegateCallback
 {
     _delayUpdateVisibleContentRects = YES;
@@ -931,7 +931,8 @@ static WebCore::Color scrollViewBackgroundColor(WKWebView *webView)
     [_scrollView setContentOffset:[self _adjustedContentOffset:CGPointZero]];
     [_scrollView setZoomScale:1];
 
-    _viewportMetaTagWidth = -1;
+    _viewportMetaTagWidth = WebCore::ViewportArguments::ValueAuto;
+    _initialScaleFactor = 1;
     _hasCommittedLoadForMainFrame = NO;
     _needsResetViewStateAfterCommitLoadForMainFrame = NO;
     _dynamicViewportUpdateMode = DynamicViewportUpdateMode::NotResizing;
@@ -1013,7 +1014,10 @@ static inline bool areEssentiallyEqualAsFloat(float a, float b)
     if (!layerTreeTransaction.scaleWasSetByUIProcess() && ![_scrollView isZooming] && ![_scrollView isZoomBouncing] && ![_scrollView _isAnimatingZoom])
         [_scrollView setZoomScale:layerTreeTransaction.pageScaleFactor()];
 
-    [_contentView _setDoubleTapGesturesEnabled:self._viewportIsUserScalable];
+    _viewportMetaTagWidth = layerTreeTransaction.viewportMetaTagWidth();
+    _initialScaleFactor = layerTreeTransaction.initialScaleFactor();
+    if (![_contentView _mayDisableDoubleTapGesturesDuringSingleTap])
+        [_contentView _setDoubleTapGesturesEnabled:self._allowsDoubleTapGestures];
 
     [self _updateScrollViewBackground];
 
@@ -1292,6 +1296,12 @@ static WebCore::FloatPoint constrainContentOffset(WebCore::FloatPoint contentOff
     [self _zoomToPoint:origin atScale:[_scrollView minimumZoomScale] animated:animated];
 }
 
+- (void)_zoomToInitialScaleWithOrigin:(WebCore::FloatPoint)origin animated:(BOOL)animated
+{
+    ASSERT(_initialScaleFactor > 0);
+    [self _zoomToPoint:origin atScale:_initialScaleFactor animated:animated];
+}
+
 // focusedElementRect and selectionRect are both in document coordinates.
 - (void)_zoomToFocusRect:(WebCore::FloatRect)focusedElementRectInDocumentCoordinates selectionRect:(WebCore::FloatRect)selectionRectInDocumentCoordinates fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll
 {
@@ -1411,11 +1421,6 @@ static WebCore::FloatPoint constrainContentOffset(WebCore::FloatPoint contentOff
                         force:YES];
 }
 
-- (CGFloat)_contentZoomScale
-{
-    return contentZoomScale(self);
-}
-
 - (CGFloat)_targetContentZoomScaleForRect:(const WebCore::FloatRect&)targetRect currentScale:(double)currentScale fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale
 {
     WebCore::FloatSize unobscuredContentSize([self _contentRectForUserInteraction].size);
@@ -3096,14 +3101,20 @@ static inline WebKit::FindOptions toFindOptions(_WKFindOptions wkFindOptions)
     return [(WKPDFView *)_customContentView.get() suggestedFilename];
 }
 
-- (CGFloat)_viewportMetaTagWidth
+- (BOOL)_allowsDoubleTapGestures
 {
-    return _viewportMetaTagWidth;
-}
+    if (_fastClickingIsDisabled)
+        return YES;
 
-- (BOOL)_viewportIsUserScalable
-{
-    return [_scrollView isZoomEnabled] && [_scrollView minimumZoomScale] < [_scrollView maximumZoomScale];
+    // If the page is not user scalable, we don't allow double tap gestures.
+    if (![_scrollView isZoomEnabled] || [_scrollView minimumZoomScale] >= [_scrollView maximumZoomScale])
+        return NO;
+
+    // For scalable viewports, only disable double tap gestures if the viewport width is device width.
+    if (_viewportMetaTagWidth != WebCore::ViewportArguments::ValueDeviceWidth)
+        return YES;
+
+    return !areEssentiallyEqualAsFloat(contentZoomScale(self), _initialScaleFactor);
 }
 
 - (_WKWebViewPrintFormatter *)_webViewPrintFormatter
index a936a6f18a1fa4109ac684bc0a8fcff214e429ff..47b9de33aa14977816b8225928bc6c2015bd7e96 100644 (file)
@@ -87,10 +87,10 @@ struct PrintInfo;
 - (void)_zoomToFocusRect:(WebCore::FloatRect)focusedElementRect selectionRect:(WebCore::FloatRect)selectionRectInDocumentCoordinates fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll;
 - (BOOL)_zoomToRect:(WebCore::FloatRect)targetRect withOrigin:(WebCore::FloatPoint)origin fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale minimumScrollDistance:(float)minimumScrollDistance;
 - (void)_zoomOutWithOrigin:(WebCore::FloatPoint)origin animated:(BOOL)animated;
+- (void)_zoomToInitialScaleWithOrigin:(WebCore::FloatPoint)origin animated:(BOOL)animated;
 
 - (void)_setHasCustomContentView:(BOOL)hasCustomContentView loadedMIMEType:(const WTF::String&)mimeType;
 - (void)_didFinishLoadingDataForCustomContentProviderWithSuggestedFilename:(const WTF::String&)suggestedFilename data:(NSData *)data;
-- (void)_setViewportMetaTagWidth:(float)newWidth;
 
 - (void)_willInvokeUIScrollViewDelegateCallback;
 - (void)_didInvokeUIScrollViewDelegateCallback;
@@ -109,9 +109,7 @@ struct PrintInfo;
 - (void)_navigationGestureDidBegin;
 - (void)_navigationGestureDidEnd;
 
-- (CGFloat)_contentZoomScale;
-- (CGFloat)_targetContentZoomScaleForRect:(const WebCore::FloatRect&)targetRect currentScale:(double)currentScale fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale;
-
+@property (nonatomic, readonly) BOOL _allowsDoubleTapGestures;
 @property (nonatomic, readonly) UIEdgeInsets _computedContentInset;
 #else
 @property (nonatomic, setter=_setIgnoresNonWheelEvents:) BOOL _ignoresNonWheelEvents;
index b7cbf3135d93ad161478d4bfcb68a871d658409f..7bd8baa98ae3a8624e42a4461892c1e017108e14 100644 (file)
@@ -134,10 +134,6 @@ typedef NS_ENUM(NSInteger, _WKImmediateActionType) {
 // FIXME: This can be removed once WKNavigation's response property is implemented.
 @property (nonatomic, readonly) NSString *_suggestedFilenameForDisplayedPDF;
 
-// The viewport meta tag width is negative if the value is not defined.
-@property (nonatomic, readonly) CGFloat _viewportMetaTagWidth;
-@property (nonatomic, readonly) BOOL _viewportIsUserScalable;
-
 @property (nonatomic, readonly) _WKWebViewPrintFormatter *_webViewPrintFormatter;
 
 - (void)_beginInteractiveObscuredInsetsChange;
index 8f39e1ec57e6408677f8a0fd798f37efa1e981d0..3e92adea99eaa7eca7c24fdc63c6e5016131614c 100644 (file)
@@ -294,8 +294,7 @@ public:
     virtual void didUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold) = 0;
     virtual void showPlaybackTargetPicker(bool hasVideo, const WebCore::IntRect& elementRect) = 0;
     virtual void zoomToRect(WebCore::FloatRect, double minimumScale, double maximumScale) = 0;
-    virtual void didChangeViewportMetaTagWidth(float) = 0;
-    virtual void disableDoubleTapGesturesUntilTapIsFinishedIfNecessary(uint64_t requestID, bool allowsDoubleTapZoom, const WebCore::FloatRect& targetRect, bool isReplacedElement, double minimumScale, double maximumScale) = 0;
+    virtual void disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID) = 0;
     virtual double minimumZoomScale() const = 0;
     virtual WebCore::FloatRect documentRect() const = 0;
     virtual void overflowScrollViewWillStartPanGesture() = 0;
index 6baa32d281c77f927a1f43b62120ce37fb71c4b2..43477ae069feee70df6bd67c23c702b5c741b809 100644 (file)
@@ -510,8 +510,7 @@ public:
     void zoomToRect(WebCore::FloatRect, double minimumScale, double maximumScale);
     void commitPotentialTapFailed();
     void didNotHandleTapAsClick(const WebCore::IntPoint&);
-    void viewportMetaTagWidthDidChange(float width);
-    void disableDoubleTapGesturesUntilTapIsFinishedIfNecessary(uint64_t requestID, bool allowsDoubleTapZoom, const WebCore::FloatRect& targetRect, bool isReplacedElement, double minimumScale, double maximumScale);
+    void disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID);
     void didFinishDrawingPagesToPDF(const IPC::DataReference&);
     void contentSizeCategoryDidChange(const String& contentSizeCategory);
     void getLookupContextAtPoint(const WebCore::IntPoint&, std::function<void(const String&, CallbackBase::Error)>);
index e2b2c7d11ebae1bc5db5af9b21b9adb7d67cd23b..360619d2d072e1d69e388d91ab5bd90d60fd93e3 100644 (file)
@@ -183,8 +183,7 @@ messages -> WebPageProxy {
     ZoomToRect(WebCore::FloatRect rect, double minimumScale, double maximumScale)
     CommitPotentialTapFailed()
     DidNotHandleTapAsClick(WebCore::IntPoint point)
-    ViewportMetaTagWidthDidChange(float width)
-    DisableDoubleTapGesturesUntilTapIsFinishedIfNecessary(uint64_t requestID, bool allowsDoubleTapZoom, WebCore::FloatRect targetRect, bool isReplacedElement, double minimumScale, double maximumScale)
+    DisableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID)
     DidFinishDrawingPagesToPDF(IPC::DataReference pdfData)
 #endif
 #if PLATFORM(GTK)
index 6ec47b6452110e4cbeca5f6f3ec34ddf773046ef..b8dbae678f99c162ed094e1a4ca2a9b7cf14b56c 100644 (file)
@@ -134,8 +134,7 @@ private:
     virtual void showPlaybackTargetPicker(bool hasVideo, const WebCore::IntRect& elementRect) override;
 
     virtual bool handleRunOpenPanel(WebPageProxy*, WebFrameProxy*, WebOpenPanelParameters*, WebOpenPanelResultListenerProxy*) override;
-    virtual void didChangeViewportMetaTagWidth(float) override;
-    virtual void disableDoubleTapGesturesUntilTapIsFinishedIfNecessary(uint64_t requestID, bool allowsDoubleTapZoom, const WebCore::FloatRect& targetRect, bool isReplacedElement, double minimumScale, double maximumScale) override;
+    virtual void disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID) override;
     virtual double minimumZoomScale() const override;
     virtual WebCore::FloatRect documentRect() const override;
 
index 55ec2aecaeaf59c1a1c33c974c9456a3a8cf988a..63728f031ccdbf1011bcc926e70ebd9693bd427e 100644 (file)
@@ -254,17 +254,12 @@ void PageClientImpl::didChangeContentSize(const WebCore::IntSize&)
     notImplemented();
 }
 
-void PageClientImpl::didChangeViewportMetaTagWidth(float newWidth)
+void PageClientImpl::disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID)
 {
-    [m_webView _setViewportMetaTagWidth:newWidth];
-}
-
-void PageClientImpl::disableDoubleTapGesturesUntilTapIsFinishedIfNecessary(uint64_t requestID, bool allowsDoubleTapZoom, const WebCore::FloatRect& targetRect, bool isReplacedElement, double minimumScale, double maximumScale)
-{
-    if (!m_webView._viewportIsUserScalable)
+    if (!m_webView._allowsDoubleTapGestures)
         return;
 
-    [m_contentView _disableDoubleTapGesturesUntilTapIsFinishedIfNecessary:requestID allowsDoubleTapZoom:allowsDoubleTapZoom targetRect:targetRect isReplaced:isReplacedElement minimumScale:minimumScale maximumScale:maximumScale];
+    [m_contentView _disableDoubleTapGesturesDuringTapIfNecessary:requestID];
 }
 
 double PageClientImpl::minimumZoomScale() const
index b765a0a33e738fb5d3901e3982a9d834f4bb4a1e..fc48cad9f6b692c506118578f316688e3804402e 100644 (file)
@@ -48,7 +48,6 @@ public:
 
     void handleSmartMagnificationGesture(WebCore::FloatPoint origin);
     void handleResetMagnificationGesture(WebCore::FloatPoint origin);
-    void adjustSmartMagnificationTargetRectAndZoomScales(bool addMagnificationPadding, WebCore::FloatRect& targetRect, double& minimumScale, double& maximumScale);
 
 private:
     // IPC::MessageReceiver.
@@ -56,6 +55,7 @@ private:
 
     void didCollectGeometryForSmartMagnificationGesture(WebCore::FloatPoint origin, WebCore::FloatRect renderRect, WebCore::FloatRect visibleContentBounds, bool isReplacedElement, double viewportMinimumScale, double viewportMaximumScale);
     void magnify(WebCore::FloatPoint origin, WebCore::FloatRect targetRect, WebCore::FloatRect visibleContentRect, double viewportMinimumScale, double viewportMaximumScale);
+    void adjustSmartMagnificationTargetRectAndZoomScales(bool addMagnificationPadding, WebCore::FloatRect& targetRect, double& minimumScale, double& maximumScale);
 
     WebPageProxy& m_webPageProxy;
     WKContentView *m_contentView;
index 410b823957fb839100d6a8982986bbc6e73399de..06d7506e4c779f9bebe4525022d48665eb08efdc 100644 (file)
@@ -93,7 +93,7 @@ void SmartMagnificationController::didCollectGeometryForSmartMagnificationGestur
 {
     if (targetRect.isEmpty()) {
         // FIXME: If we don't zoom, send the tap along to text selection (see <rdar://problem/6810344>).
-        [m_contentView _zoomOutWithOrigin:origin];
+        [m_contentView _zoomToInitialScaleWithOrigin:origin];
         return;
     }
     double minimumScale = viewportMinimumScale;
@@ -119,7 +119,7 @@ void SmartMagnificationController::didCollectGeometryForSmartMagnificationGestur
         return;
 
     // FIXME: If we still don't zoom, send the tap along to text selection (see <rdar://problem/6810344>).
-    [m_contentView _zoomOutWithOrigin:origin];
+    [m_contentView _zoomToInitialScaleWithOrigin:origin];
 }
 
 void SmartMagnificationController::magnify(FloatPoint origin, FloatRect targetRect, FloatRect visibleContentRect, double viewportMinimumScale, double viewportMaximumScale)
index b720da9623e567a3d098d8be53bc694556ab450c..037086b0f2e6a34a69bd58840c0ce1e4051c5616 100644 (file)
@@ -92,5 +92,6 @@ class WebProcessPool;
 - (void)_zoomToFocusRect:(CGRect)rectToFocus selectionRect:(CGRect)selectionRect fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll;
 - (BOOL)_zoomToRect:(CGRect)targetRect withOrigin:(CGPoint)origin fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale minimumScrollDistance:(CGFloat)minimumScrollDistance;
 - (void)_zoomOutWithOrigin:(CGPoint)origin;
+- (void)_zoomToInitialScaleWithOrigin:(CGPoint)origin;
 
 @end
index 587886a0911a6c6b380e30ced1b5fd3e27ee6285..bd34d456455b01478102ce6f8a31816a7c3720ab 100644 (file)
@@ -540,6 +540,11 @@ private:
     return [_webView _zoomOutWithOrigin:origin animated:YES];
 }
 
+- (void)_zoomToInitialScaleWithOrigin:(CGPoint)origin
+{
+    return [_webView _zoomToInitialScaleWithOrigin:origin animated:YES];
+}
+
 - (void)_applicationWillResignActive:(NSNotification*)notification
 {
     _page->applicationWillResignActive();
index cea2826726415e639ae64c5c65d28dc3c727bdc1..c65f0daae4caa5412379fd970fe519be367c550d 100644 (file)
@@ -159,6 +159,7 @@ struct WKAutoCorrectionData {
     BOOL _inspectorNodeSearchEnabled;
     BOOL _didAccessoryTabInitiateFocus;
     BOOL _isExpectingFastSingleTapCommit;
+    BOOL _showDebugTapHighlightsForFastClicking;
 }
 
 @end
@@ -183,7 +184,8 @@ struct WKAutoCorrectionData {
 - (void)_commitPotentialTapFailed;
 - (void)_didGetTapHighlightForRequest:(uint64_t)requestID color:(const WebCore::Color&)color quads:(const Vector<WebCore::FloatQuad>&)highlightedQuads topLeftRadius:(const WebCore::IntSize&)topLeftRadius topRightRadius:(const WebCore::IntSize&)topRightRadius bottomLeftRadius:(const WebCore::IntSize&)bottomLeftRadius bottomRightRadius:(const WebCore::IntSize&)bottomRightRadius;
 
-- (void)_disableDoubleTapGesturesUntilTapIsFinishedIfNecessary:(uint64_t)requestID allowsDoubleTapZoom:(bool)allowsDoubleTapZoom targetRect:(WebCore::FloatRect)targetRect isReplaced:(BOOL)isReplacedElement minimumScale:(double)minimumScale maximumScale:(double)maximumScale;
+- (BOOL)_mayDisableDoubleTapGesturesDuringSingleTap;
+- (void)_disableDoubleTapGesturesDuringTapIfNecessary:(uint64_t)requestID;
 - (void)_startAssistingNode:(const WebKit::AssistedNodeInformation&)information userIsInteracting:(BOOL)userIsInteracting blurPreviousNode:(BOOL)blurPreviousNode userObject:(NSObject <NSSecureCoding> *)userObject;
 - (void)_stopAssistingNode;
 - (void)_selectionChanged;
index 617d717e6225c39311edf80c0c0d2a65ce346698..0ff69d7f14abe9ddf7cb02192532ea2ec9e0ebca 100644 (file)
@@ -476,6 +476,7 @@ static UIWebSelectionMode toUIWebSelectionMode(WKSelectionGranularity granularit
     [_actionSheetAssistant setDelegate:self];
     _smartMagnificationController = std::make_unique<SmartMagnificationController>(self);
     _isExpectingFastSingleTapCommit = NO;
+    _showDebugTapHighlightsForFastClicking = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitShowFastClickDebugTapHighlights"];
 }
 
 - (void)cleanupInteraction
@@ -840,7 +841,7 @@ static NSValue *nsSizeForTapHighlightBorderRadius(WebCore::IntSize borderRadius,
 
 - (void)_showTapHighlight
 {
-    if (!highlightedQuadsAreSmallerThanRect(_tapHighlightInformation.quads, _page->unobscuredContentRect()))
+    if (!highlightedQuadsAreSmallerThanRect(_tapHighlightInformation.quads, _page->unobscuredContentRect()) && !_showDebugTapHighlightsForFastClicking)
         return;
 
     if (!_highlightView) {
@@ -860,12 +861,15 @@ static NSValue *nsSizeForTapHighlightBorderRadius(WebCore::IntSize borderRadius,
 
     _isTapHighlightIDValid = NO;
 
-    _tapHighlightInformation.color = color;
     _tapHighlightInformation.quads = highlightedQuads;
     _tapHighlightInformation.topLeftRadius = topLeftRadius;
     _tapHighlightInformation.topRightRadius = topRightRadius;
     _tapHighlightInformation.bottomLeftRadius = bottomLeftRadius;
     _tapHighlightInformation.bottomRightRadius = bottomRightRadius;
+    if (_showDebugTapHighlightsForFastClicking)
+        _tapHighlightInformation.color = [self _tapHighlightColorForFastClick:![_doubleTapGestureRecognizer isEnabled]];
+    else
+        _tapHighlightInformation.color = color;
 
     if (_potentialTapInProgress) {
         _hasTapHighlightForPotentialTap = YES;
@@ -880,41 +884,16 @@ static NSValue *nsSizeForTapHighlightBorderRadius(WebCore::IntSize borderRadius,
     }
 }
 
-- (CGFloat)_fastClickZoomThreshold
-{
-    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
-    if (![defaults boolForKey:@"WebKitFastClickingEnabled"])
-        return 0;
-
-    return [defaults floatForKey:@"WebKitFastClickZoomThreshold"];
-}
-
-- (BOOL)_allowDoubleTapToZoomForCurrentZoomScale:(CGFloat)currentZoomScale andTargetZoomScale:(CGFloat)targetZoomScale
+- (BOOL)_mayDisableDoubleTapGesturesDuringSingleTap
 {
-    CGFloat zoomThreshold = [self _fastClickZoomThreshold];
-    if (!zoomThreshold)
-        return YES;
-
-    CGFloat minimumZoomRatioForDoubleTapToZoomIn = 1 + zoomThreshold;
-    CGFloat maximumZoomRatioForDoubleTapToZoomOut = 1 / minimumZoomRatioForDoubleTapToZoomIn;
-    CGFloat zoomRatio = targetZoomScale / currentZoomScale;
-    return zoomRatio < maximumZoomRatioForDoubleTapToZoomOut || zoomRatio > minimumZoomRatioForDoubleTapToZoomIn;
+    return _potentialTapInProgress;
 }
 
-- (void)_disableDoubleTapGesturesUntilTapIsFinishedIfNecessary:(uint64_t)requestID allowsDoubleTapZoom:(bool)allowsDoubleTapZoom targetRect:(WebCore::FloatRect)targetRect isReplaced:(BOOL)isReplacedElement minimumScale:(double)minimumScale maximumScale:(double)maximumScale
+- (void)_disableDoubleTapGesturesDuringTapIfNecessary:(uint64_t)requestID
 {
     if (!_potentialTapInProgress || _latestTapID != requestID)
         return;
 
-    if (allowsDoubleTapZoom) {
-        // Though the element allows us to zoom in on double tap, we avoid this behavior in favor of fast clicking if the difference in scale is insignificant.
-        _smartMagnificationController->adjustSmartMagnificationTargetRectAndZoomScales(!isReplacedElement, targetRect, minimumScale, maximumScale);
-        CGFloat currentZoomScale = [_webView _contentZoomScale];
-        CGFloat targetZoomScale = [_webView _targetContentZoomScaleForRect:targetRect currentScale:currentZoomScale fitEntireRect:isReplacedElement minimumScale:minimumScale maximumScale:maximumScale];
-        if ([self _allowDoubleTapToZoomForCurrentZoomScale:currentZoomScale andTargetZoomScale:targetZoomScale])
-            return;
-    }
-
     [self _setDoubleTapGesturesEnabled:NO];
 }
 
@@ -1153,7 +1132,8 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
 - (void)_finishInteraction
 {
     _isTapHighlightIDValid = NO;
-    [UIView animateWithDuration:0.1
+    CGFloat tapHighlightFadeDuration = _showDebugTapHighlightsForFastClicking ? 0.25 : 0.1;
+    [UIView animateWithDuration:tapHighlightFadeDuration
                      animations:^{
                          [_highlightView layer].opacity = 0;
                      }
@@ -1259,7 +1239,7 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
 
 - (void)_endPotentialTapAndEnableDoubleTapGesturesIfNecessary
 {
-    if (_webView._viewportIsUserScalable)
+    if (_webView._allowsDoubleTapGestures)
         [self _setDoubleTapGesturesEnabled:YES];
 
     _potentialTapInProgress = NO;
@@ -2414,6 +2394,12 @@ static void selectionChangedWithTouch(WKContentView *view, const WebCore::IntPoi
     });
 }
 
+- (WebCore::Color)_tapHighlightColorForFastClick:(BOOL)forFastClick
+{
+    ASSERT(_showDebugTapHighlightsForFastClicking);
+    return forFastClick ? WebCore::Color(0, 225, 0, 127) : WebCore::Color(225, 0, 0, 127);
+}
+
 - (void)_setDoubleTapGesturesEnabled:(BOOL)enabled
 {
     if (enabled && ![_doubleTapGestureRecognizer isEnabled]) {
@@ -2423,6 +2409,10 @@ static void selectionChangedWithTouch(WKContentView *view, const WebCore::IntPoi
         [_doubleTapGestureRecognizer setDelegate:nil];
         [self _createAndConfigureDoubleTapGestureRecognizer];
     }
+
+    if (_showDebugTapHighlightsForFastClicking && !enabled)
+        _tapHighlightInformation.color = [self _tapHighlightColorForFastClick:YES];
+
     [_doubleTapGestureRecognizer setEnabled:enabled];
 }
 
index 7d307cfe2495da503233fa249cb3f9e2b6d27f84..21d3c8792144384aec5e2dcdf6763dc021e4d48b 100644 (file)
@@ -932,14 +932,9 @@ void WebPageProxy::didNotHandleTapAsClick(const WebCore::IntPoint& point)
     m_uiClient->didNotHandleTapAsClick(point);
 }
 
-void WebPageProxy::viewportMetaTagWidthDidChange(float width)
+void WebPageProxy::disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID)
 {
-    m_pageClient.didChangeViewportMetaTagWidth(width);
-}
-
-void WebPageProxy::disableDoubleTapGesturesUntilTapIsFinishedIfNecessary(uint64_t requestID, bool allowsDoubleTapZoom, const WebCore::FloatRect& targetRect, bool isReplacedElement, double minimumScale, double maximumScale)
-{
-    m_pageClient.disableDoubleTapGesturesUntilTapIsFinishedIfNecessary(requestID, allowsDoubleTapZoom, targetRect, isReplacedElement, minimumScale, maximumScale);
+    m_pageClient.disableDoubleTapGesturesDuringTapIfNecessary(requestID);
 }
 
 void WebPageProxy::didFinishDrawingPagesToPDF(const IPC::DataReference& pdfData)
index 98d9c97b2c4d133ce19186c916eef40c7ebdbf23..05fa674a5fdf69175bb568ce07155c3749a889c8 100644 (file)
@@ -45,7 +45,6 @@ public:
     ~ViewGestureGeometryCollector();
 
     void mainFrameDidLayout();
-    void computeZoomInformationForNode(WebCore::Node&, WebCore::FloatPoint& origin, WebCore::FloatRect& renderRect, bool& isReplaced, double& viewportMinimumScale, double& viewportMaximumScale);
 
 private:
     // IPC::MessageReceiver.
@@ -62,6 +61,7 @@ private:
 #endif
 
     void dispatchDidCollectGeometryForSmartMagnificationGesture(WebCore::FloatPoint origin, WebCore::FloatRect targetRect, WebCore::FloatRect visibleContentRect, bool isReplacedElement, double viewportMinimumScale, double viewportMaximumScale);
+    void computeZoomInformationForNode(WebCore::Node&, WebCore::FloatPoint& origin, WebCore::FloatRect& renderRect, bool& isReplaced, double& viewportMinimumScale, double& viewportMaximumScale);
 
     WebPage& m_webPage;
 
index ce9fc82fef1f177a8a6b6d24575daeb27e072f17..9baa8bcd38e4a70efe4887e706bcabfef166d539 100644 (file)
@@ -2943,6 +2943,8 @@ void WebPage::willCommitLayerTree(RemoteLayerTreeTransaction& layerTransaction)
     layerTransaction.setScaleWasSetByUIProcess(scaleWasSetByUIProcess());
     layerTransaction.setMinimumScaleFactor(m_viewportConfiguration.minimumScale());
     layerTransaction.setMaximumScaleFactor(m_viewportConfiguration.maximumScale());
+    layerTransaction.setInitialScaleFactor(m_viewportConfiguration.initialScale());
+    layerTransaction.setViewportMetaTagWidth(m_viewportConfiguration.viewportArguments().width);
     layerTransaction.setAllowsUserScaling(allowsUserScaling());
 #endif
 #if PLATFORM(MAC)
index ea427445e35c6fe48c15b167f983d590988fb651..5c98b62a72f9a077b7585c874cd60d607bc62030 100644 (file)
@@ -233,13 +233,8 @@ void WebPage::viewportPropertiesDidChange(const ViewportArguments& viewportArgum
     if (m_viewportConfiguration.viewportArguments() == viewportArguments)
         return;
 
-    float oldWidth = m_viewportConfiguration.viewportArguments().width;
-
     m_viewportConfiguration.setViewportArguments(viewportArguments);
     viewportConfigurationChanged();
-
-    if (oldWidth != viewportArguments.width)
-        send(Messages::WebPageProxy::ViewportMetaTagWidthDidChange(viewportArguments.width));
 }
 
 void WebPage::didReceiveMobileDocType(bool isMobileDoctype)
@@ -664,22 +659,10 @@ void WebPage::potentialTapAtPosition(uint64_t requestID, const WebCore::FloatPoi
 {
     m_potentialTapNode = m_page->mainFrame().nodeRespondingToClickEvents(position, m_potentialTapLocation);
     sendTapHighlightForNodeIfNecessary(requestID, m_potentialTapNode.get());
-    if (m_potentialTapNode) {
 #if ENABLE(TOUCH_EVENTS)
-        if (!m_potentialTapNode->allowsDoubleTapGesture()) {
-            send(Messages::WebPageProxy::DisableDoubleTapGesturesUntilTapIsFinishedIfNecessary(requestID, false, FloatRect(), false, 0, 0));
-            return;
-        }
+    if (m_potentialTapNode && !m_potentialTapNode->allowsDoubleTapGesture())
+        send(Messages::WebPageProxy::DisableDoubleTapGesturesDuringTapIfNecessary(requestID));
 #endif
-        FloatPoint origin = position;
-        FloatRect renderRect;
-        bool isReplaced;
-        double viewportMinimumScale;
-        double viewportMaximumScale;
-
-        m_viewGestureGeometryCollector.computeZoomInformationForNode(*m_potentialTapNode.get(), origin, renderRect, isReplaced, viewportMinimumScale, viewportMaximumScale);
-        send(Messages::WebPageProxy::DisableDoubleTapGesturesUntilTapIsFinishedIfNecessary(requestID, true, renderRect, isReplaced, viewportMinimumScale, viewportMaximumScale));
-    }
 }
 
 void WebPage::commitPotentialTap(uint64_t lastLayerTreeTransactionId)