[iOS] Synchronize the WKContentView and UIScrollView updates with the tiles being...
authorbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Feb 2014 06:45:41 +0000 (06:45 +0000)
committerbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Feb 2014 06:45:41 +0000 (06:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=127886

Reviewed by Simon Fraser.

Source/WebCore:

The updates of the views on the UIProcess side was completely disconnected
from the tiles updates from the DrawingArea. There is a non-negligible time
between the size/scale update and the new tiles coming, which causes
visual glitches.

There are three main cases where the tiles and content would be out of sync
with the UIViews:
-When loading a new page with different content width of a different viewport.
-When a page changes its viewport.
-When the viewport-constrainted viewport size changes.

To fix the issue, WKView is modified to maintain the old state of WKContentView
and UIScrollView until the new tiles are available.

Geometry/scale update are split in two phases:
1) A source (the page or the user) changes parameters of the geometry. The WebProcess updates
   its layout accordingly.
   At this point, the UIViews are unchanged and are left with the old parameters.
2) Eventually, new tiles come and commitLayerTree() is called on the drawing area proxy.
   At that point, WKContentView and its UIScrollView are updated to match the committed
   size and scale for the page.

* WebCore.exp.in:
* WebCore.xcodeproj/project.pbxproj:
* page/ViewportConfiguration.cpp: Added.
(WebCore::constraintsAreAllRelative):
(WebCore::ViewportConfiguration::ViewportConfiguration):
(WebCore::ViewportConfiguration::setDefaultConfiguration):
(WebCore::ViewportConfiguration::setContentsSize):
(WebCore::ViewportConfiguration::setMinimumLayoutSize):
(WebCore::ViewportConfiguration::setViewportArguments):
(WebCore::ViewportConfiguration::layoutSize):
(WebCore::ViewportConfiguration::initialScale):
(WebCore::ViewportConfiguration::minimumScale):
(WebCore::ViewportConfiguration::maximumScale):
(WebCore::ViewportConfiguration::allowsUserScaling):
(WebCore::viewportArgumentValueIsValid):
(WebCore::applyViewportArgument):
(WebCore::ViewportConfiguration::updateConfiguration):
(WebCore::ViewportConfiguration::layoutWidth):
(WebCore::ViewportConfiguration::layoutHeight):
* page/ViewportConfiguration.h: Added.
(WebCore::ViewportConfigurationConfiguration::ViewportConfigurationConfiguration):
(WebCore::ViewportConfiguration::defaultConfiguration):
(WebCore::ViewportConfiguration::contentsSize):
(WebCore::ViewportConfiguration::minimumLayoutSize):
(WebCore::ViewportConfiguration::viewportArguments):

Source/WebKit2:

* Shared/mac/RemoteLayerTreeTransaction.h:
(WebKit::RemoteLayerTreeTransaction::mainFrameContentsSize):
(WebKit::RemoteLayerTreeTransaction::setMainFrameContentsSize):
(WebKit::RemoteLayerTreeTransaction::pageScaleFactor):
(WebKit::RemoteLayerTreeTransaction::setPageScaleFactor):
(WebKit::RemoteLayerTreeTransaction::minimumScaleFactor):
(WebKit::RemoteLayerTreeTransaction::setMinimumScaleFactor):
(WebKit::RemoteLayerTreeTransaction::maximumScaleFactor):
(WebKit::RemoteLayerTreeTransaction::setMaximumScaleFactor):
(WebKit::RemoteLayerTreeTransaction::allowsUserScaling):
(WebKit::RemoteLayerTreeTransaction::setAllowsUserScaling):
* Shared/mac/RemoteLayerTreeTransaction.mm:
(WebKit::RemoteLayerTreeTransaction::encode):
(WebKit::RemoteLayerTreeTransaction::decode):
* UIProcess/API/ios/PageClientImplIOS.h:
* UIProcess/API/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::didCommitLayerTree):
* UIProcess/API/ios/WKContentView.h:
* UIProcess/API/ios/WKContentView.mm:
(-[WKContentView setMinimumLayoutSize:]):
(-[WKContentView willStartUserTriggeredZoom]):
(-[WKContentView _didCommitLayerTree:WebKit::]):
* UIProcess/API/ios/WKContentViewInternal.h:
* UIProcess/API/ios/WKViewIOS.mm:
(-[WKView contentViewDidCommitLoadForMainFrame:]):
(-[WKView contentView:didCommitLayerTree:WebKit::]):
(-[WKView scrollViewWillBeginZooming:withView:]):
(-[WKView _commonInitializationWithContextRef:pageGroupRef:relatedToPage:]):
(-[WKView _frameOrBoundsChanged]):
(-[WKView minimumLayoutSizeOverride]):
(-[WKView setMinimumLayoutSizeOverride:]):
* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.cpp:
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::setVirtualViewportMinimumLayoutSize):
(WebKit::WebPageProxy::didCommitLayerTree):
(WebKit::WebPageProxy::willStartUserTriggeredZooming):
* UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm:
(WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree):
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::contentsSizeChanged):
(WebKit::WebChromeClient::dispatchViewportPropertiesDidChange):
* WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm:
(WebKit::WebChromeClient::didReceiveMobileDocType):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::WebPage):
(WebKit::WebPage::mainFrameDidLayout):
(WebKit::WebPage::didCommitLoad):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::viewportPropertiesDidChange):
(WebKit::WebPage::minimumPageScaleFactor):
(WebKit::WebPage::maximumPageScaleFactor):
(WebKit::WebPage::allowsUserScaling):
(WebKit::WebPage::setVirtualViewportMinimumLayoutSize):
(WebKit::WebPage::virtualViewportChanged):
(WebKit::WebPage::willStartUserTriggeredZooming):
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::flushLayers):

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

29 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/page/ViewportConfiguration.cpp [new file with mode: 0644]
Source/WebCore/page/ViewportConfiguration.h [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/ios/PageClientImplIOS.h
Source/WebKit2/UIProcess/API/ios/PageClientImplIOS.mm
Source/WebKit2/UIProcess/API/ios/WKContentView.h
Source/WebKit2/UIProcess/API/ios/WKContentView.mm
Source/WebKit2/UIProcess/API/ios/WKContentViewInternal.h
Source/WebKit2/UIProcess/API/ios/WKViewIOS.mm
Source/WebKit2/UIProcess/PageClient.h
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPageProxy.messages.in
Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm
Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm
Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp
Source/WebKit2/WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm
Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm

index e180bdcf5bb5d642ac9755b8991471f41fb18fc4..e81d95f3ffc0e0bada9c40e616714d1ea5dad03c 100644 (file)
@@ -1,3 +1,58 @@
+2014-02-05  Benjamin Poulain  <benjamin@webkit.org>
+
+        [iOS] Synchronize the WKContentView and UIScrollView updates with the tiles being commited
+        https://bugs.webkit.org/show_bug.cgi?id=127886
+
+        Reviewed by Simon Fraser.
+
+        The updates of the views on the UIProcess side was completely disconnected
+        from the tiles updates from the DrawingArea. There is a non-negligible time
+        between the size/scale update and the new tiles coming, which causes
+        visual glitches.
+
+        There are three main cases where the tiles and content would be out of sync
+        with the UIViews:
+        -When loading a new page with different content width of a different viewport.
+        -When a page changes its viewport.
+        -When the viewport-constrainted viewport size changes.
+
+        To fix the issue, WKView is modified to maintain the old state of WKContentView
+        and UIScrollView until the new tiles are available.
+
+        Geometry/scale update are split in two phases:
+        1) A source (the page or the user) changes parameters of the geometry. The WebProcess updates
+           its layout accordingly.
+           At this point, the UIViews are unchanged and are left with the old parameters.
+        2) Eventually, new tiles come and commitLayerTree() is called on the drawing area proxy.
+           At that point, WKContentView and its UIScrollView are updated to match the committed
+           size and scale for the page.
+
+        * WebCore.exp.in:
+        * WebCore.xcodeproj/project.pbxproj:
+        * page/ViewportConfiguration.cpp: Added.
+        (WebCore::constraintsAreAllRelative):
+        (WebCore::ViewportConfiguration::ViewportConfiguration):
+        (WebCore::ViewportConfiguration::setDefaultConfiguration):
+        (WebCore::ViewportConfiguration::setContentsSize):
+        (WebCore::ViewportConfiguration::setMinimumLayoutSize):
+        (WebCore::ViewportConfiguration::setViewportArguments):
+        (WebCore::ViewportConfiguration::layoutSize):
+        (WebCore::ViewportConfiguration::initialScale):
+        (WebCore::ViewportConfiguration::minimumScale):
+        (WebCore::ViewportConfiguration::maximumScale):
+        (WebCore::ViewportConfiguration::allowsUserScaling):
+        (WebCore::viewportArgumentValueIsValid):
+        (WebCore::applyViewportArgument):
+        (WebCore::ViewportConfiguration::updateConfiguration):
+        (WebCore::ViewportConfiguration::layoutWidth):
+        (WebCore::ViewportConfiguration::layoutHeight):
+        * page/ViewportConfiguration.h: Added.
+        (WebCore::ViewportConfigurationConfiguration::ViewportConfigurationConfiguration):
+        (WebCore::ViewportConfiguration::defaultConfiguration):
+        (WebCore::ViewportConfiguration::contentsSize):
+        (WebCore::ViewportConfiguration::minimumLayoutSize):
+        (WebCore::ViewportConfiguration::viewportArguments):
+
 2014-02-05  Benjamin Poulain  <benjamin@webkit.org>
 
         SelectorCodeGenerator::generateElementHasTagName should match the local name before the namespace
index bffa789243505e5745896e52d016effc646eb71a..8ad7a2bbbd8f30f7b0340fce768a09b5640bff25 100644 (file)
@@ -568,6 +568,8 @@ __ZN7WebCore15GraphicsLayerCA31platformCALayerAnimationStartedEd
 __ZN7WebCore15GraphicsLayerCA37flushCompositingStateForThisLayerOnlyEv
 __ZN7WebCore15GraphicsLayerCA40platformCALayerSetNeedsToRevalidateTilesEv
 __ZNK7WebCore15GraphicsLayerCA49platformCALayerContentsScaleMultiplierForNewTilesEPNS_15PlatformCALayerE
+__ZNK7WebCore21ViewportConfiguration10layoutSizeEv
+__ZNK7WebCore21ViewportConfiguration12initialScaleEv
 __ZN7WebCore15GraphicsLayerCA7setNameERKN3WTF6StringE
 __ZN7WebCore15GraphicsLayerCA7setSizeERKNS_9FloatSizeE
 __ZN7WebCore15GraphicsLayerCA8addChildEPNS_13GraphicsLayerE
@@ -575,6 +577,7 @@ __ZN7WebCore15GraphicsLayerCAC2EPNS_19GraphicsLayerClientE
 __ZN7WebCore15GraphicsLayerCAD2Ev
 __ZN7WebCore15GraphicsLayerCA19setCustomAppearanceENS_13GraphicsLayer16CustomAppearanceE
 __ZNK7WebCore15GraphicsLayerCA14primaryLayerIDEv
+__ZNK7WebCore21ViewportConfiguration12minimumScaleEv
 __ZN7WebCore15HitTestLocation12rectForPointERKNS_11LayoutPointEjjjj
 __ZN7WebCore15HitTestLocationC1ERKNS_10FloatPointE
 __ZN7WebCore15HitTestLocationD1Ev
@@ -845,6 +848,10 @@ __ZN7WebCore21SerializedScriptValueC1ERN3WTF6VectorIhLm0ENS1_15CrashOnOverflowEE
 __ZN7WebCore21SerializedScriptValueD1Ev
 __ZN7WebCore21URLByRemovingUserInfoEP5NSURL
 __ZN7WebCore21UserContentURLPattern5parseERKN3WTF6StringE
+__ZN7WebCore21ViewportConfiguration15setContentsSizeERKNS_7IntSizeE
+__ZN7WebCore21ViewportConfiguration20setMinimumLayoutSizeERKNS_7IntSizeE
+__ZN7WebCore21ViewportConfiguration20setViewportArgumentsERKNS_17ViewportArgumentsE
+__ZN7WebCore21ViewportConfiguration23setDefaultConfigurationERKNS0_10ParametersE
 __ZN7WebCore21WindowsLatin1EncodingEv
 __ZN7WebCore21createCFURLFromBufferEPKcmPK7__CFURL
 __ZN7WebCore21findEventWithKeyStateEPNS_5EventE
@@ -909,6 +916,7 @@ __ZN7WebCore24FrameDestructionObserverC2EPNS_5FrameE
 __ZN7WebCore24FrameDestructionObserverD2Ev
 __ZN7WebCore24ImmutableStylePropertiesD1Ev
 __ZN7WebCore24ReferenceFilterOperationC1ERKN3WTF6StringES4_NS_15FilterOperation13OperationTypeE
+__ZN7WebCore21ViewportConfigurationC1Ev
 __ZN7WebCore24createFragmentFromMarkupERNS_8DocumentERKN3WTF6StringES5_NS_19ParserContentPolicyE
 __ZN7WebCore24decodeURLEscapeSequencesERKN3WTF6StringE
 __ZN7WebCore24deleteCookiesForHostnameERKNS_21NetworkStorageSessionERKN3WTF6StringE
index f9a61d57b4def75071cecde46ed28e935bcbfa2d..653e22c1e511b9e9f4ed12ae1d3d0a65b62329fc 100644 (file)
                26C17A3F1491D2D400D12BA2 /* FileSystemIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26C17A3D1491D2D400D12BA2 /* FileSystemIOS.mm */; };
                26E98A10130A9FCA008EB7B2 /* TextCodecASCIIFastPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 26E98A0F130A9FCA008EB7B2 /* TextCodecASCIIFastPath.h */; };
                26F40D4A14904A6300CA67C4 /* EventLoopIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26F40D4914904A6300CA67C4 /* EventLoopIOS.mm */; };
+               26F9A83818A046AC00AEB88A /* ViewportConfiguration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F9A83618A046AC00AEB88A /* ViewportConfiguration.cpp */; };
+               26F9A83918A046AC00AEB88A /* ViewportConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 26F9A83718A046AC00AEB88A /* ViewportConfiguration.h */; settings = {ATTRIBUTES = (Private, ); }; };
                26FAE4CC1852E3A5004C8C46 /* ResourceHandleCFURLConnectionDelegate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26FAE4C81852E3A5004C8C46 /* ResourceHandleCFURLConnectionDelegate.cpp */; };
                26FAE4CD1852E3A5004C8C46 /* ResourceHandleCFURLConnectionDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 26FAE4C91852E3A5004C8C46 /* ResourceHandleCFURLConnectionDelegate.h */; };
                26FAE4CE1852E3A5004C8C46 /* SynchronousResourceHandleCFURLConnectionDelegate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26FAE4CA1852E3A5004C8C46 /* SynchronousResourceHandleCFURLConnectionDelegate.cpp */; };
                26C17A3D1491D2D400D12BA2 /* FileSystemIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = FileSystemIOS.mm; path = ios/FileSystemIOS.mm; sourceTree = "<group>"; };
                26E98A0F130A9FCA008EB7B2 /* TextCodecASCIIFastPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextCodecASCIIFastPath.h; sourceTree = "<group>"; };
                26F40D4914904A6300CA67C4 /* EventLoopIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = EventLoopIOS.mm; path = ios/EventLoopIOS.mm; sourceTree = "<group>"; };
+               26F9A83618A046AC00AEB88A /* ViewportConfiguration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ViewportConfiguration.cpp; sourceTree = "<group>"; };
+               26F9A83718A046AC00AEB88A /* ViewportConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewportConfiguration.h; sourceTree = "<group>"; };
                26FAE4C81852E3A5004C8C46 /* ResourceHandleCFURLConnectionDelegate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceHandleCFURLConnectionDelegate.cpp; sourceTree = "<group>"; };
                26FAE4C91852E3A5004C8C46 /* ResourceHandleCFURLConnectionDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceHandleCFURLConnectionDelegate.h; sourceTree = "<group>"; };
                26FAE4CA1852E3A5004C8C46 /* SynchronousResourceHandleCFURLConnectionDelegate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SynchronousResourceHandleCFURLConnectionDelegate.cpp; sourceTree = "<group>"; };
                                BC8BF1591058141800A40A07 /* UserStyleSheetTypes.h */,
                                F513A3E915FF4841001526DB /* ValidationMessageClient.h */,
                                8678D0BA1878E810003ABDE6 /* ViewState.h */,
+                               26F9A83618A046AC00AEB88A /* ViewportConfiguration.cpp */,
+                               26F9A83718A046AC00AEB88A /* ViewportConfiguration.h */,
                                1ABA80051897355500DCE9D6 /* VisitedLinkProvider.cpp */,
                                1ABA7FFF1897341200DCE9D6 /* VisitedLinkProvider.h */,
                                BE983D95052A2E0A00892D85 /* WebCoreKeyboardUIMode.h */,
                                B2FA3D790AB75A6F000E5AC4 /* JSSVGFEFloodElement.h in Headers */,
                                B2FA3D7B0AB75A6F000E5AC4 /* JSSVGFEFuncAElement.h in Headers */,
                                B2FA3D7D0AB75A6F000E5AC4 /* JSSVGFEFuncBElement.h in Headers */,
+                               26F9A83918A046AC00AEB88A /* ViewportConfiguration.h in Headers */,
                                B2FA3D7F0AB75A6F000E5AC4 /* JSSVGFEFuncGElement.h in Headers */,
                                B2FA3D810AB75A6F000E5AC4 /* JSSVGFEFuncRElement.h in Headers */,
                                B2FA3D830AB75A6F000E5AC4 /* JSSVGFEGaussianBlurElement.h in Headers */,
                                148AFDA60AF58360008CC700 /* ExceptionHandlers.mm in Sources */,
                                A024575116CEAA27000E5671 /* EXTDrawBuffers.cpp in Sources */,
                                6E67D2A61280E8A4008758F7 /* Extensions3DOpenGL.cpp in Sources */,
+                               26F9A83818A046AC00AEB88A /* ViewportConfiguration.cpp in Sources */,
                                44DAB5B115A623580097C1E4 /* Extensions3DOpenGLCommon.cpp in Sources */,
                                7728694E14F8882500F484DC /* EXTTextureFilterAnisotropic.cpp in Sources */,
                                97C740141603F7A10011FF2D /* FeatureObserver.cpp in Sources */,
diff --git a/Source/WebCore/page/ViewportConfiguration.cpp b/Source/WebCore/page/ViewportConfiguration.cpp
new file mode 100644 (file)
index 0000000..365904c
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2005-2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ViewportConfiguration.h"
+
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+#if !ASSERT_DISABLED
+static bool constraintsAreAllRelative(const ViewportConfiguration::Parameters& configuration)
+{
+    return !configuration.widthIsSet && !configuration.heightIsSet && !configuration.initialScaleIsSet;
+}
+#endif
+
+ViewportConfiguration::ViewportConfiguration()
+    : m_contentSize(1024, 768)
+    , m_minimumLayoutSize(m_contentSize)
+{
+    // Setup a reasonable default configuration to avoid computing infinite scale/sizes.
+    // Those are the original iPhone configuration.
+    m_defaultConfiguration.width = 980;
+    m_defaultConfiguration.widthIsSet = true;
+    m_defaultConfiguration.allowsUserScaling = true;
+    m_defaultConfiguration.minimumScale = 0.25;
+    m_defaultConfiguration.maximumScale = 5;
+    updateConfiguration();
+}
+
+void ViewportConfiguration::setDefaultConfiguration(const ViewportConfiguration::Parameters& defaultConfiguration)
+{
+    ASSERT(!constraintsAreAllRelative(m_configuration));
+    ASSERT(!m_defaultConfiguration.initialScaleIsSet || defaultConfiguration.initialScale > 0);
+    ASSERT(defaultConfiguration.minimumScale > 0);
+    ASSERT(defaultConfiguration.maximumScale >= defaultConfiguration.minimumScale);
+
+    m_defaultConfiguration = defaultConfiguration;
+    updateConfiguration();
+}
+
+void ViewportConfiguration::setContentsSize(const IntSize& contentSize)
+{
+    if (m_contentSize == contentSize)
+        return;
+
+    m_contentSize = contentSize;
+    updateConfiguration();
+}
+
+void ViewportConfiguration::setMinimumLayoutSize(const IntSize& minimumLayoutSize)
+{
+    if (m_minimumLayoutSize == minimumLayoutSize)
+        return;
+
+    m_minimumLayoutSize = minimumLayoutSize;
+    updateConfiguration();
+}
+
+void ViewportConfiguration::setViewportArguments(const ViewportArguments& viewportArguments)
+{
+    if (m_viewportArguments == viewportArguments)
+        return;
+
+    m_viewportArguments = viewportArguments;
+    updateConfiguration();
+}
+
+IntSize ViewportConfiguration::layoutSize() const
+{
+    return IntSize(layoutWidth(), layoutHeight());
+}
+
+double ViewportConfiguration::initialScale() const
+{
+    ASSERT(!constraintsAreAllRelative(m_configuration));
+
+    // If the document has specified its own initial scale, use it regardless.
+    // This is guaranteed to be sanity checked already, so no need for MIN/MAX.
+    if (m_configuration.initialScaleIsSet)
+        return m_configuration.initialScale;
+
+    // If not, it is up to us to determine the initial scale.
+    // We want a scale small enough to fit the document width-wise.
+    double width = m_contentSize.width() > 0 ? m_contentSize.width() : layoutWidth();
+    double initialScale = 0;
+    if (width > 0)
+        initialScale = m_minimumLayoutSize.width() / width;
+
+    // Prevent the intial scale from shrinking to a height smaller than our view's minimum height.
+    double height = m_contentSize.height() > 0 ? m_contentSize.height() : layoutHeight();
+    if (height > 0 && height * initialScale < m_minimumLayoutSize.height())
+        initialScale = m_minimumLayoutSize.height() / height;
+    return std::min(std::max(initialScale, m_configuration.minimumScale), m_configuration.maximumScale);
+}
+
+double ViewportConfiguration::minimumScale() const
+{
+    // If we scale to fit, then this is our minimum scale as well.
+    if (!m_configuration.initialScaleIsSet)
+        return initialScale();
+
+    // If not, we still need to sanity check our value.
+    double minimumScale = m_configuration.initialScale;
+
+    double contentWidth = m_contentSize.width();
+    if (contentWidth > 0 && contentWidth * minimumScale < m_minimumLayoutSize.width())
+        minimumScale = m_minimumLayoutSize.width() / contentWidth;
+
+    double contentHeight = m_contentSize.height();
+    if (contentHeight > 0 && contentHeight * minimumScale < m_minimumLayoutSize.height())
+        minimumScale = m_minimumLayoutSize.height() / contentHeight;
+
+    minimumScale = std::min(std::max(minimumScale, m_configuration.minimumScale), m_configuration.maximumScale);
+
+    return minimumScale;
+}
+
+static inline bool viewportArgumentValueIsValid(float value)
+{
+    return value > 0;
+}
+
+template<typename ValueType, typename ViewportArgumentsType>
+static inline void applyViewportArgument(ValueType& value, ViewportArgumentsType viewportArgumentValue, ValueType minimum, ValueType maximum)
+{
+    if (viewportArgumentValueIsValid(viewportArgumentValue))
+        value = std::min(maximum, std::max(minimum, static_cast<ValueType>(viewportArgumentValue)));
+}
+
+template<typename ValueType, typename ViewportArgumentsType>
+static inline void applyViewportArgument(ValueType& value, bool& valueIsSet, ViewportArgumentsType viewportArgumentValue, ValueType minimum, ValueType maximum)
+{
+    if (viewportArgumentValueIsValid(viewportArgumentValue)) {
+        value = std::min(maximum, std::max(minimum, static_cast<ValueType>(viewportArgumentValue)));
+        valueIsSet = true;
+    } else
+        valueIsSet = false;
+}
+
+void ViewportConfiguration::updateConfiguration()
+{
+    m_configuration = m_defaultConfiguration;
+
+    const double minimumViewportArgumentsScaleFactor = 0.1;
+    const double maximumViewportArgumentsScaleFactor = 10.0;
+
+    bool viewportArgumentsOverridesInitialScale;
+    bool viewportArgumentsOverridesWidth;
+    bool viewportArgumentsOverridesHeight;
+
+    applyViewportArgument(m_configuration.minimumScale, m_viewportArguments.minZoom, minimumViewportArgumentsScaleFactor, maximumViewportArgumentsScaleFactor);
+    applyViewportArgument(m_configuration.maximumScale, m_viewportArguments.maxZoom, m_configuration.minimumScale, maximumViewportArgumentsScaleFactor);
+    applyViewportArgument(m_configuration.initialScale, viewportArgumentsOverridesInitialScale, m_viewportArguments.zoom, m_configuration.minimumScale, m_configuration.maximumScale);
+
+    double minimumViewportArgumentsDimension = 10;
+    double maximumViewportArgumentsDimension = 10000;
+    applyViewportArgument(m_configuration.width, viewportArgumentsOverridesWidth, m_viewportArguments.width, minimumViewportArgumentsDimension, maximumViewportArgumentsDimension);
+    applyViewportArgument(m_configuration.height, viewportArgumentsOverridesHeight, m_viewportArguments.height, minimumViewportArgumentsDimension, maximumViewportArgumentsDimension);
+
+    if (viewportArgumentsOverridesInitialScale || viewportArgumentsOverridesWidth || viewportArgumentsOverridesHeight) {
+        m_configuration.initialScaleIsSet = viewportArgumentsOverridesInitialScale;
+        m_configuration.widthIsSet = viewportArgumentsOverridesWidth;
+        m_configuration.heightIsSet = viewportArgumentsOverridesHeight;
+    }
+
+    if (viewportArgumentValueIsValid(m_viewportArguments.userZoom))
+        m_configuration.allowsUserScaling = m_viewportArguments.userZoom != 0.;
+}
+
+int ViewportConfiguration::layoutWidth() const
+{
+    ASSERT(!constraintsAreAllRelative(m_configuration));
+
+    if (m_configuration.widthIsSet) {
+        // If we scale to fit, then accept the viewport width with sanity checking.
+        if (!m_configuration.initialScaleIsSet) {
+            double maximumScale = this->maximumScale();
+            double maximumContentWidthInViewportCoordinate = maximumScale * m_configuration.width;
+            if (maximumContentWidthInViewportCoordinate < m_minimumLayoutSize.width()) {
+                // The content zoomed to maxScale does not fit the the view. Return the minimum width
+                // satisfying the constraint maximumScale.
+                return std::round(m_minimumLayoutSize.width() / maximumScale);
+            }
+            return std::round(m_configuration.width);
+        }
+
+        // If not, make sure the viewport width and initial scale can co-exist.
+        double initialContentWidthInViewportCoordinate = m_configuration.width * m_configuration.initialScale;
+        if (initialContentWidthInViewportCoordinate < m_contentSize.width()) {
+            // The specified width does not fit in viewport. Return the minimum width that satisfy the initialScale constraint.
+            return std::round(m_minimumLayoutSize.width() / m_configuration.initialScale);
+        }
+        return std::round(m_configuration.width);
+    }
+
+    // If the page has a real scale, then just return the minimum size over the initial scale.
+    if (m_configuration.initialScaleIsSet && !m_configuration.heightIsSet)
+        return std::round(m_minimumLayoutSize.width() / m_configuration.initialScale);
+
+    if (m_minimumLayoutSize.height() > 0)
+        return std::round(m_minimumLayoutSize.width() * layoutHeight() / m_minimumLayoutSize.height());
+    return m_minimumLayoutSize.width();
+}
+
+int ViewportConfiguration::layoutHeight() const
+{
+    ASSERT(!constraintsAreAllRelative(m_configuration));
+
+    if (m_configuration.heightIsSet) {
+        // If we scale to fit, then accept the viewport height with sanity checking.
+        if (!m_configuration.initialScaleIsSet) {
+            double maximumScale = this->maximumScale();
+            double maximumContentHeightInViewportCoordinate = maximumScale * m_configuration.height;
+            if (maximumContentHeightInViewportCoordinate < m_minimumLayoutSize.height()) {
+                // The content zoomed to maxScale does not fit the the view. Return the minimum height that
+                // satisfy the constraint maximumScale.
+                return std::round(m_minimumLayoutSize.height() / maximumScale);
+            }
+            return std::round(m_configuration.height);
+        }
+
+        // If not, make sure the viewport width and initial scale can co-exist.
+        double initialContentHeightInViewportCoordinate = m_configuration.height * m_configuration.initialScale;
+        if (initialContentHeightInViewportCoordinate < m_minimumLayoutSize.height()) {
+            // The specified width does not fit in viewport. Return the minimum height that satisfy the initialScale constraint.
+            return std::round(m_minimumLayoutSize.height() / m_configuration.initialScale);
+        }
+        return std::round(m_configuration.height);
+    }
+
+    // If the page has a real scale, then just return the minimum size over the initial scale.
+    if (m_configuration.initialScaleIsSet && !m_configuration.widthIsSet)
+        return std::round(m_minimumLayoutSize.height() / m_configuration.initialScale);
+
+    if (m_minimumLayoutSize.width() > 0)
+        return std::round(m_minimumLayoutSize.height() * layoutWidth() / m_minimumLayoutSize.width());
+    return m_minimumLayoutSize.height();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/page/ViewportConfiguration.h b/Source/WebCore/page/ViewportConfiguration.h
new file mode 100644 (file)
index 0000000..6ba52ff
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2005-2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ViewportConfiguration_h
+#define ViewportConfiguration_h
+
+#include "IntSize.h"
+#include "ViewportArguments.h"
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class ViewportConfiguration {
+    WTF_MAKE_NONCOPYABLE(ViewportConfiguration); WTF_MAKE_FAST_ALLOCATED;
+public:
+    // FIXME: unify with ViewportArguments.
+    struct Parameters {
+        Parameters()
+            : width(0)
+            , height(0)
+            , initialScale(0)
+            , minimumScale(0)
+            , maximumScale(0)
+            , allowsUserScaling(false)
+            , widthIsSet(false)
+            , heightIsSet(false)
+            , initialScaleIsSet(false)
+        {
+        }
+
+        double width;
+        double height;
+        double initialScale;
+        double minimumScale;
+        double maximumScale;
+        bool allowsUserScaling;
+
+        bool widthIsSet;
+        bool heightIsSet;
+        bool initialScaleIsSet;
+    };
+
+    ViewportConfiguration();
+
+    const Parameters& defaultConfiguration() const { return m_defaultConfiguration; }
+    void setDefaultConfiguration(const Parameters&);
+
+    const IntSize& contentsSize() const { return m_contentSize; }
+    void setContentsSize(const IntSize&);
+
+    const IntSize& minimumLayoutSize() const { return m_minimumLayoutSize; }
+    void setMinimumLayoutSize(const IntSize&);
+
+    const ViewportArguments& viewportArguments() const { return m_viewportArguments; }
+    void setViewportArguments(const ViewportArguments&);
+
+    IntSize layoutSize() const;
+    double initialScale() const;
+    double minimumScale() const;
+    double maximumScale() const { return m_configuration.maximumScale; }
+    bool allowsUserScaling() const { return m_configuration.allowsUserScaling; }
+
+private:
+    void updateConfiguration();
+    int layoutWidth() const;
+    int layoutHeight() const;
+
+    Parameters m_configuration;
+    Parameters m_defaultConfiguration;
+    IntSize m_contentSize;
+    IntSize m_minimumLayoutSize;
+    ViewportArguments m_viewportArguments;
+};
+
+} // namespace WebCore
+
+#endif // ViewportConfiguration_h
index d5351c4c0152fcb26c128ecf91c2f4b42f37d4e2..9841525b5d409ae54dc7303b105ddde0a2ae3c84 100644 (file)
@@ -1,3 +1,73 @@
+2014-02-05  Benjamin Poulain  <benjamin@webkit.org>
+
+        [iOS] Synchronize the WKContentView and UIScrollView updates with the tiles being commited
+        https://bugs.webkit.org/show_bug.cgi?id=127886
+
+        Reviewed by Simon Fraser.
+
+        * Shared/mac/RemoteLayerTreeTransaction.h:
+        (WebKit::RemoteLayerTreeTransaction::mainFrameContentsSize):
+        (WebKit::RemoteLayerTreeTransaction::setMainFrameContentsSize):
+        (WebKit::RemoteLayerTreeTransaction::pageScaleFactor):
+        (WebKit::RemoteLayerTreeTransaction::setPageScaleFactor):
+        (WebKit::RemoteLayerTreeTransaction::minimumScaleFactor):
+        (WebKit::RemoteLayerTreeTransaction::setMinimumScaleFactor):
+        (WebKit::RemoteLayerTreeTransaction::maximumScaleFactor):
+        (WebKit::RemoteLayerTreeTransaction::setMaximumScaleFactor):
+        (WebKit::RemoteLayerTreeTransaction::allowsUserScaling):
+        (WebKit::RemoteLayerTreeTransaction::setAllowsUserScaling):
+        * Shared/mac/RemoteLayerTreeTransaction.mm:
+        (WebKit::RemoteLayerTreeTransaction::encode):
+        (WebKit::RemoteLayerTreeTransaction::decode):
+        * UIProcess/API/ios/PageClientImplIOS.h:
+        * UIProcess/API/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::didCommitLayerTree):
+        * UIProcess/API/ios/WKContentView.h:
+        * UIProcess/API/ios/WKContentView.mm:
+        (-[WKContentView setMinimumLayoutSize:]):
+        (-[WKContentView willStartUserTriggeredZoom]):
+        (-[WKContentView _didCommitLayerTree:WebKit::]):
+        * UIProcess/API/ios/WKContentViewInternal.h:
+        * UIProcess/API/ios/WKViewIOS.mm:
+        (-[WKView contentViewDidCommitLoadForMainFrame:]):
+        (-[WKView contentView:didCommitLayerTree:WebKit::]):
+        (-[WKView scrollViewWillBeginZooming:withView:]):
+        (-[WKView _commonInitializationWithContextRef:pageGroupRef:relatedToPage:]):
+        (-[WKView _frameOrBoundsChanged]):
+        (-[WKView minimumLayoutSizeOverride]):
+        (-[WKView setMinimumLayoutSizeOverride:]):
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.cpp:
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::setVirtualViewportMinimumLayoutSize):
+        (WebKit::WebPageProxy::didCommitLayerTree):
+        (WebKit::WebPageProxy::willStartUserTriggeredZooming):
+        * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm:
+        (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree):
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::contentsSizeChanged):
+        (WebKit::WebChromeClient::dispatchViewportPropertiesDidChange):
+        * WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm:
+        (WebKit::WebChromeClient::didReceiveMobileDocType):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::WebPage):
+        (WebKit::WebPage::mainFrameDidLayout):
+        (WebKit::WebPage::didCommitLoad):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::viewportPropertiesDidChange):
+        (WebKit::WebPage::minimumPageScaleFactor):
+        (WebKit::WebPage::maximumPageScaleFactor):
+        (WebKit::WebPage::allowsUserScaling):
+        (WebKit::WebPage::setVirtualViewportMinimumLayoutSize):
+        (WebKit::WebPage::virtualViewportChanged):
+        (WebKit::WebPage::willStartUserTriggeredZooming):
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
+        (WebKit::RemoteLayerTreeDrawingArea::flushLayers):
+
 2014-02-05  Benjamin Poulain  <bpoulain@apple.com>
 
         [WK2] Add the minimumLayoutSizeOverride SPI to WKWebView
index eb34a4fa2690d6f1188d2e8361dce2bac2ddf270..3200bf7c793c9a60e1f03c54935eef8f560f7200 100644 (file)
@@ -155,11 +155,31 @@ public:
     HashMap<WebCore::GraphicsLayer::PlatformLayerID, LayerProperties> changedLayers() const { return m_changedLayerProperties; }
     Vector<WebCore::GraphicsLayer::PlatformLayerID> destroyedLayers() const { return m_destroyedLayerIDs; }
 
+    WebCore::IntSize contentsSize() const { return m_contentsSize; }
+    void setContentsSize(const WebCore::IntSize& size) { m_contentsSize = size; };
+
+    double pageScaleFactor() const { return m_pageScaleFactor; }
+    void setPageScaleFactor(double pageScaleFactor) { m_pageScaleFactor = pageScaleFactor; }
+
+    double minimumScaleFactor() const { return m_minimumScaleFactor; }
+    void setMinimumScaleFactor(double scale) { m_minimumScaleFactor = scale; }
+
+    double maximumScaleFactor() const { return m_maximumScaleFactor; }
+    void setMaximumScaleFactor(double scale) { m_maximumScaleFactor = scale; }
+
+    bool allowsUserScaling() const { return m_allowsUserScaling; }
+    void setAllowsUserScaling(bool allowsUserScaling) { m_allowsUserScaling = allowsUserScaling; }
+
 private:
     WebCore::GraphicsLayer::PlatformLayerID m_rootLayerID;
     HashMap<WebCore::GraphicsLayer::PlatformLayerID, LayerProperties> m_changedLayerProperties;
     Vector<LayerCreationProperties> m_createdLayers;
     Vector<WebCore::GraphicsLayer::PlatformLayerID> m_destroyedLayerIDs;
+    WebCore::IntSize m_contentsSize;
+    double m_pageScaleFactor;
+    double m_minimumScaleFactor;
+    double m_maximumScaleFactor;
+    bool m_allowsUserScaling;
 };
 
 } // namespace WebKit
index 2769ab8f3aa0046cf1d9db4f47d75fd81c6ec932..23f35dc4128ee53fe5de6ca4588a683495d62598 100644 (file)
@@ -348,6 +348,11 @@ void RemoteLayerTreeTransaction::encode(IPC::ArgumentEncoder& encoder) const
     encoder << m_createdLayers;
     encoder << m_changedLayerProperties;
     encoder << m_destroyedLayerIDs;
+    encoder << m_contentsSize;
+    encoder << m_pageScaleFactor;
+    encoder << m_minimumScaleFactor;
+    encoder << m_maximumScaleFactor;
+    encoder << m_allowsUserScaling;
 }
 
 bool RemoteLayerTreeTransaction::decode(IPC::ArgumentDecoder& decoder, RemoteLayerTreeTransaction& result)
@@ -371,6 +376,21 @@ bool RemoteLayerTreeTransaction::decode(IPC::ArgumentDecoder& decoder, RemoteLay
             return false;
     }
 
+    if (!decoder.decode(result.m_contentsSize))
+        return false;
+
+    if (!decoder.decode(result.m_pageScaleFactor))
+        return false;
+
+    if (!decoder.decode(result.m_minimumScaleFactor))
+        return false;
+
+    if (!decoder.decode(result.m_maximumScaleFactor))
+        return false;
+
+    if (!decoder.decode(result.m_allowsUserScaling))
+        return false;
+
     return true;
 }
 
index bf41977e1c4261a8ee67fb8efd9242f55310495c..982d7449af45611a0bb81e0266e8393a341c687d 100644 (file)
 #import "WKWebViewConfiguration.h"
 #import "WebBackForwardList.h"
 #import "WebPageProxy.h"
+#import <WebKit2/RemoteLayerTreeTransaction.h>
 #import <wtf/RetainPtr.h>
 
 #if PLATFORM(IOS)
 #import "WKScrollView.h"
-
-static const float minWebViewScale = 0.25;
-static const float maxWebViewScale = 5;
-static _UIWebViewportConfiguration standardViewportConfiguration = { { UIWebViewportStandardViewportWidth, UIWebViewportGrowsAndShrinksToFitHeight }, UIWebViewportScaleForScalesToFit, minWebViewScale, maxWebViewScale, true
-};
-
 #endif
 
 #if PLATFORM(MAC) && !PLATFORM(IOS)
@@ -58,10 +53,10 @@ static _UIWebViewportConfiguration standardViewportConfiguration = { { UIWebView
 #if PLATFORM(IOS)
     RetainPtr<WKScrollView> _scrollView;
     RetainPtr<WKContentView> _contentView;
-    RetainPtr<_UIWebViewportHandler> _viewportHandler;
 
-    BOOL _userHasChangedPageScale;
+    BOOL _isWaitingForNewLayerTreeAfterDidCommitLoad;
     BOOL _hasStaticMinimumLayoutSize;
+    CGSize _minimumLayoutSizeOverride;
 #endif
 #if PLATFORM(MAC) && !PLATFORM(IOS)
     RetainPtr<WKView> _wkView;
@@ -99,9 +94,6 @@ static _UIWebViewportConfiguration standardViewportConfiguration = { { UIWebView
     [_contentView setFrame:bounds];
     [_scrollView addSubview:_contentView.get()];
 
-    _viewportHandler = adoptNS([[_UIWebViewportHandler alloc] init]);
-    [_viewportHandler setDelegate:self];
-
     [self _frameOrBoundsChanged];
 #endif
 
@@ -213,75 +205,25 @@ static _UIWebViewportConfiguration standardViewportConfiguration = { { UIWebView
 
 #pragma mark WKContentViewDelegate
 
-- (void)contentView:(WKContentView *)contentView contentsSizeDidChange:(CGSize)newSize
-{
-    CGFloat zoomScale = [_scrollView zoomScale];
-    CGSize contentsSizeInScrollViewCoordinates = CGSizeMake(newSize.width * zoomScale, newSize.height * zoomScale);
-    [_scrollView setContentSize:contentsSizeInScrollViewCoordinates];
-
-    [_viewportHandler update:^{
-         [_viewportHandler setDocumentBounds:{CGPointZero, newSize}];
-    }];
-}
-
 - (void)contentViewDidCommitLoadForMainFrame:(WKContentView *)contentView
 {
-    _userHasChangedPageScale = NO;
-
-    WKContentType contentType = [_contentView contentType];
-    [_viewportHandler update:^{
-        [_viewportHandler clearWebKitViewportConfigurationFlags];
-        _UIWebViewportConfiguration configuration = standardViewportConfiguration;
-
-        if (contentType == PlainText) {
-            CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width;
-            configuration.size.width = screenWidth;
-        } else if (contentType == WKContentType::Image)
-            configuration.minimumScale = 0.01;
-
-        [_viewportHandler resetViewportConfiguration:&configuration];
-    }];
+    _isWaitingForNewLayerTreeAfterDidCommitLoad = YES;
 }
 
-- (void)contentViewDidReceiveMobileDocType:(WKContentView *)contentView
+- (void)contentView:(WKContentView *)contentView didCommitLayerTree:(const WebKit::RemoteLayerTreeTransaction&)layerTreeTransaction
 {
-    [_viewportHandler update:^{
-        _UIWebViewportConfiguration configuration = standardViewportConfiguration;
-        configuration.minimumScale = 1;
-        configuration.size = CGSizeMake(320, UIWebViewportGrowsAndShrinksToFitHeight);
-        [_viewportHandler resetViewportConfiguration:&configuration];
-    }];
-}
+    [_scrollView setMinimumZoomScale:layerTreeTransaction.minimumScaleFactor()];
+    [_scrollView setMaximumZoomScale:layerTreeTransaction.maximumScaleFactor()];
+    [_scrollView setZoomEnabled:layerTreeTransaction.allowsUserScaling()];
+    if (![_scrollView isZooming] && ![_scrollView isZoomBouncing])
+        [_scrollView setZoomScale:layerTreeTransaction.pageScaleFactor()];
 
-- (void)contentView:(WKContentView *)contentView didChangeViewportArgumentsSize:(CGSize)newSize initialScale:(float)initialScale minimumScale:(float)minimumScale maximumScale:(float)maximumScale allowsUserScaling:(float)allowsUserScaling
-{
-    [_viewportHandler update:^{
-        [_viewportHandler applyWebKitViewportArgumentsSize:newSize initialScale:initialScale minimumScale:minimumScale maximumScale:maximumScale allowsUserScaling:allowsUserScaling];
-    }];
-}
-
-#pragma mark - _UIWebViewportHandlerDelegate
-
-- (void)viewportHandlerDidChangeScales:(_UIWebViewportHandler *)viewportHandler
-{
-    ASSERT(viewportHandler == _viewportHandler);
-    [_scrollView setMinimumZoomScale:viewportHandler.minimumScale];
-    [_scrollView setMaximumZoomScale:viewportHandler.maximumScale];
-    [_scrollView setZoomEnabled:viewportHandler.allowsUserScaling];
-
-    if (!_userHasChangedPageScale)
-        [self _setDocumentScale:viewportHandler.initialScale];
-    else {
-        CGFloat currentScale = [_scrollView zoomScale];
-        CGFloat validScale = std::max(std::min(currentScale, static_cast<CGFloat>(viewportHandler.maximumScale)), static_cast<CGFloat>(viewportHandler.minimumScale));
-        [self _setDocumentScale:validScale];
+    if (_isWaitingForNewLayerTreeAfterDidCommitLoad) {
+        UIEdgeInsets inset = [_scrollView contentInset];
+        [_scrollView setContentOffset:CGPointMake(-inset.left, -inset.top)];
+        _isWaitingForNewLayerTreeAfterDidCommitLoad = NO;
     }
-}
-
-- (void)viewportHandler:(_UIWebViewportHandler *)viewportHandler didChangeViewportSize:(CGSize)newSize
-{
-    ASSERT(viewportHandler == _viewportHandler);
-    [_contentView setViewportSize:newSize];
+    
 }
 
 #pragma mark - UIScrollViewDelegate
@@ -295,7 +237,7 @@ static _UIWebViewportConfiguration standardViewportConfiguration = { { UIWebView
 - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
 {
     if (scrollView.pinchGestureRecognizer.state == UIGestureRecognizerStateBegan)
-        _userHasChangedPageScale = YES;
+        [_contentView willStartUserTriggeredZoom];
     [_contentView willStartZoomOrScroll];
 }
 
@@ -343,11 +285,8 @@ static _UIWebViewportConfiguration standardViewportConfiguration = { { UIWebView
 {
     CGRect bounds = self.bounds;
 
-    if (!_hasStaticMinimumLayoutSize) {
-        [_viewportHandler update:^{
-            [_viewportHandler setAvailableViewSize:bounds.size];
-        }];
-    }
+    if (!_hasStaticMinimumLayoutSize)
+        [_contentView setMinimumLayoutSize:bounds.size];
     [_scrollView setFrame:bounds];
     [_contentView setMinimumSize:bounds.size];
 }
@@ -368,15 +307,14 @@ static _UIWebViewportConfiguration standardViewportConfiguration = { { UIWebView
 - (CGSize)_minimumLayoutSizeOverride
 {
     ASSERT(_hasStaticMinimumLayoutSize);
-    return [_viewportHandler availableViewSize];
+    return _minimumLayoutSizeOverride;
 }
 
 - (void)_setMinimumLayoutSizeOverride:(CGSize)minimumLayoutSizeOverride
 {
     _hasStaticMinimumLayoutSize = YES;
-    [_viewportHandler update:^{
-        [_viewportHandler setAvailableViewSize:minimumLayoutSizeOverride];
-    }];
+    _minimumLayoutSizeOverride = minimumLayoutSizeOverride;
+    [_contentView setMinimumLayoutSize:minimumLayoutSizeOverride];
 }
 
 #endif
index 9ea6706aca77bd36ae7a2f99189469913122b7af..089d72795559f9c88e6a9fa0a477ba4f400785d4 100644 (file)
 #if PLATFORM(IOS)
 #import "WKContentViewInternal.h"
 #import <UIKit/UIScrollView_Private.h>
-#import <UIKit/_UIWebViewportHandler.h>
 #endif
 
 #if PLATFORM(IOS)
-#define WK_WEB_VIEW_PROTOCOLS <UIScrollViewDelegate, WKContentViewDelegate, _UIWebViewportHandlerDelegate>
+#define WK_WEB_VIEW_PROTOCOLS <UIScrollViewDelegate, WKContentViewDelegate>
 #endif
 
 #if !defined(WK_WEB_VIEW_PROTOCOLS)
index 49f99fc6bed54e22421bcdcc0c46f05249aaa865..2255fdcd150a1f22991e1540b64806f8d17ee4bd 100644 (file)
@@ -62,7 +62,6 @@ private:
     virtual void toolTipChanged(const String&, const String&) override;
     virtual bool decidePolicyForGeolocationPermissionRequest(WebFrameProxy&, WebSecurityOrigin&, GeolocationPermissionRequestProxy&) override;
     virtual void didCommitLoadForMainFrame() override;
-    virtual void didChangeContentSize(const WebCore::IntSize&) override;
     virtual void setCursor(const WebCore::Cursor&) override;
     virtual void setCursorHiddenUntilMouseMoves(bool) override;
     virtual void didChangeViewportProperties(const WebCore::ViewportAttributes&) override;
@@ -101,11 +100,9 @@ private:
     virtual void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) override;
     virtual void clearCustomSwipeViews() override;
 
-    virtual void mainDocumentDidReceiveMobileDocType() override;
-
     virtual void didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color& color, const Vector<WebCore::FloatQuad>& highlightedQuads, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius) override;
 
-    void didChangeViewportArguments(const WebCore::ViewportArguments& viewportArguments) override;
+    virtual void didCommitLayerTree(const RemoteLayerTreeTransaction&) override;
 
     virtual void startAssistingNode(const WebCore::IntRect&, bool hasNextFocusable, bool hasPreviousFocusable) override;
     virtual void stopAssistingNode() override;
index 7775ef6aa9013354c5d279ea461861e2ca7355ae..8e1a2ff67bbd235616d9e08a6534df808075f5c6 100644 (file)
@@ -147,11 +147,6 @@ void PageClientImpl::didCommitLoadForMainFrame()
     [m_view _didCommitLoadForMainFrame];
 }
 
-void PageClientImpl::didChangeContentSize(const IntSize& contentsSize)
-{
-    [m_view _didChangeContentSize:contentsSize];
-}
-
 void PageClientImpl::setCursor(const Cursor&)
 {
     notImplemented();
@@ -344,19 +339,14 @@ void PageClientImpl::clearCustomSwipeViews()
     notImplemented();
 }
 
-void PageClientImpl::mainDocumentDidReceiveMobileDocType()
-{
-    [m_view _didReceiveMobileDocTypeForMainFrame];
-}
-
 void PageClientImpl::didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color& color, const Vector<WebCore::FloatQuad>& highlightedQuads, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius)
 {
     [m_view _didGetTapHighlightForRequest:requestID color:color quads:highlightedQuads topLeftRadius:topLeftRadius topRightRadius:topRightRadius bottomLeftRadius:bottomLeftRadius bottomRightRadius:bottomRightRadius];
 }
 
-void PageClientImpl::didChangeViewportArguments(const WebCore::ViewportArguments& viewportArguments)
+void PageClientImpl::didCommitLayerTree(const RemoteLayerTreeTransaction& layerTreeTransaction)
 {
-    [m_view _didChangeViewportArguments:viewportArguments];
+    [m_view _didCommitLayerTree:layerTreeTransaction];
 }
 
 void PageClientImpl::startAssistingNode(const WebCore::IntRect&, bool, bool)
index 1ce24d62a2ea41a67244a39f52708bc5c2f77088..cdc886eb8a75b3e8f294de54aa5714a8bf0f3a29 100644 (file)
@@ -39,13 +39,14 @@ typedef NS_ENUM(unsigned, WKContentType)
     Image
 };
 
+namespace WebKit {
+class RemoteLayerTreeTransaction;
+}
+
 @protocol WKContentViewDelegate <NSObject>
 @optional
-- (void)contentView:(WKContentView *)contentView contentsSizeDidChange:(CGSize)newSize;
 - (void)contentViewDidCommitLoadForMainFrame:(WKContentView *)contentView;
-- (void)contentViewDidReceiveMobileDocType:(WKContentView *)contentView;
-- (void)contentView:(WKContentView *)contentView didChangeViewportArgumentsSize:(CGSize)newSize initialScale:(float)initialScale minimumScale:(float)minimumScale maximumScale:(float)maximumScale allowsUserScaling:(float)allowsUserScaling;
-
+- (void)contentView:(WKContentView *)contentView didCommitLayerTree:(const WebKit::RemoteLayerTreeTransaction&)layerTreeTransaction;
 @end
 
 WK_API_CLASS
@@ -66,10 +67,12 @@ WK_API_CLASS
 
 - (void)setMinimumSize:(CGSize)size;
 - (void)setViewportSize:(CGSize)size;
+- (void)setMinimumLayoutSize:(CGSize)size;
 
 - (void)didFinishScrollTo:(CGPoint)contentOffset;
 - (void)didScrollTo:(CGPoint)contentOffset;
 - (void)didZoomToScale:(CGFloat)scale;
 - (void)willStartZoomOrScroll;
+- (void)willStartUserTriggeredZoom;
 
 @end
index 56c008cac7e06df1a40624bab9affa3ce0d4fc84..b679548ec1772de1fad82b47b50efbed7056c17c 100644 (file)
@@ -209,6 +209,11 @@ using namespace WebKit;
     [self _updateViewExposedRect];
 }
 
+- (void)setMinimumLayoutSize:(CGSize)size
+{
+    _page->setViewportConfigurationMinimumLayoutSize(IntSize(CGCeiling(size.width), CGCeiling(size.height)));
+}
+
 - (void)didFinishScrollTo:(CGPoint)contentOffset
 {
     _currentExposedRectPosition = contentOffset;
@@ -231,6 +236,11 @@ using namespace WebKit;
     [_interactionView _willStartScrollingOrZooming];
 }
 
+- (void)willStartUserTriggeredZoom
+{
+    _page->willStartUserTriggeredZooming();
+}
+
 - (void)didZoomToScale:(CGFloat)scale
 {
     _page->didFinishZooming(scale);
@@ -304,26 +314,16 @@ using namespace WebKit;
         [_delegate contentViewDidCommitLoadForMainFrame:self];
 }
 
-- (void)_didChangeContentSize:(CGSize)contentsSize
+- (void)_didCommitLayerTree:(const WebKit::RemoteLayerTreeTransaction&)layerTreeTransaction
 {
+    CGSize contentsSize = layerTreeTransaction.contentsSize();
+
     [self setBounds:{CGPointZero, contentsSize}];
     [_interactionView setFrame:CGRectMake(0, 0, contentsSize.width, contentsSize.height)];
     [_rootContentView setFrame:CGRectMake(0, 0, contentsSize.width, contentsSize.height)];
 
-    if ([_delegate respondsToSelector:@selector(contentView:contentsSizeDidChange:)])
-        [_delegate contentView:self contentsSizeDidChange:contentsSize];
-}
-
-- (void)_didReceiveMobileDocTypeForMainFrame
-{
-    if ([_delegate respondsToSelector:@selector(contentViewDidReceiveMobileDocType:)])
-        [_delegate contentViewDidReceiveMobileDocType:self];
-}
-
-- (void)_didChangeViewportArguments:(const WebCore::ViewportArguments&)arguments
-{
-    if ([_delegate respondsToSelector:@selector(contentView:didChangeViewportArgumentsSize:initialScale:minimumScale:maximumScale:allowsUserScaling:)])
-        [_delegate contentView:self didChangeViewportArgumentsSize:CGSizeMake(arguments.width, arguments.height) initialScale:arguments.zoom minimumScale:arguments.minZoom maximumScale:arguments.maxZoom allowsUserScaling:arguments.userZoom];
+    if ([_delegate respondsToSelector:@selector(contentView:didCommitLayerTree:)])
+        [_delegate contentView:self didCommitLayerTree:layerTreeTransaction];
 }
 
 - (void)_didGetTapHighlightForRequest:(uint64_t)requestID color:(const Color&)color quads:(const Vector<FloatQuad>&)highlightedQuads topLeftRadius:(const IntSize&)topLeftRadius topRightRadius:(const IntSize&)topRightRadius bottomLeftRadius:(const IntSize&)bottomLeftRadius bottomRightRadius:(const IntSize&)bottomRightRadius
index 2bf8a0dd6e715b7f60ab64aa44233aaf8390f306..04cbfd8aeed1745cd14cf520b0692ada79f46d2b 100644 (file)
@@ -38,6 +38,7 @@ namespace WebKit {
 class DrawingAreaProxy;
 class GeolocationPermissionRequestProxy;
 class LayerTreeContext;
+class RemoteLayerTreeTransaction;
 class WebFrameProxy;
 class WebPageProxy;
 class WebSecurityOrigin;
@@ -57,9 +58,7 @@ struct InteractionInformationAtPosition;
 - (void)_setAcceleratedCompositingRootLayer:(CALayer *)rootLayer;
 
 - (void)_didCommitLoadForMainFrame;
-- (void)_didChangeContentSize:(CGSize)contentsSize;
-- (void)_didReceiveMobileDocTypeForMainFrame;
-- (void)_didChangeViewportArguments:(const WebCore::ViewportArguments&)viewportArguments;
+- (void)_didCommitLayerTree:(const WebKit::RemoteLayerTreeTransaction&)layerTreeTransaction;
 
 - (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;
 
index 5535f2d47b640f6535dc3df96efb097bff427001..f75fa6ff64a1e205e1b1174b4e881bf04c536d3f 100644 (file)
 #import "WKScrollView.h"
 #import <UIKit/UIScreen.h>
 #import <UIKit/UIScrollView_Private.h>
-#import <UIKit/_UIWebViewportHandler.h>
+#import <WebKit2/RemoteLayerTreeTransaction.h>
 #import <wtf/RetainPtr.h>
 
-static const float minWebViewScale = 0.25;
-static const float maxWebViewScale = 5;
-static struct _UIWebViewportConfiguration standardViewportConfiguration = { { UIWebViewportStandardViewportWidth, UIWebViewportGrowsAndShrinksToFitHeight }, UIWebViewportScaleForScalesToFit, minWebViewScale, maxWebViewScale, true };
-
-@interface WKView () <UIScrollViewDelegate, WKContentViewDelegate, _UIWebViewportHandlerDelegate>
+@interface WKView () <UIScrollViewDelegate, WKContentViewDelegate>
 - (void)_setDocumentScale:(CGFloat)newScale;
 @end
 
@@ -47,9 +43,9 @@ static struct _UIWebViewportConfiguration standardViewportConfiguration = { { UI
     RetainPtr<WKScrollView> _scrollView;
     RetainPtr<WKContentView> _contentView;
 
-    BOOL _userHasChangedPageScale;
-    RetainPtr<_UIWebViewportHandler> _viewportHandler;
+    BOOL _isWaitingForNewLayerTreeAfterDidCommitLoad;
     BOOL _hasStaticMinimumLayoutSize;
+    CGSize _minimumLayoutSizeOverride;
 }
 
 - (id)initWithCoder:(NSCoder *)coder
@@ -103,82 +99,27 @@ static struct _UIWebViewportConfiguration standardViewportConfiguration = { { UI
 
 #pragma mark WKContentViewDelegate
 
-- (void)contentView:(WKContentView *)contentView contentsSizeDidChange:(CGSize)newSize
-{
-    CGFloat zoomScale = [_scrollView zoomScale];
-    CGSize contentsSizeInScrollViewCoordinates = CGSizeMake(newSize.width * zoomScale, newSize.height * zoomScale);
-    [_scrollView setContentSize:contentsSizeInScrollViewCoordinates];
-
-    [_viewportHandler update:^{
-         [_viewportHandler setDocumentBounds:{CGPointZero, newSize}];
-    }];
-}
-
 - (void)contentViewDidCommitLoadForMainFrame:(WKContentView *)contentView
 {
-    _userHasChangedPageScale = NO;
-
-    WKContentType contentType = [_contentView contentType];
-    [_viewportHandler update:^{
-        [_viewportHandler clearWebKitViewportConfigurationFlags];
-        struct _UIWebViewportConfiguration configuration = standardViewportConfiguration;
-
-        if (contentType == PlainText) {
-            CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width;
-            configuration.size.width = screenWidth;
-        } else if (contentType == WKContentType::Image)
-            configuration.minimumScale = 0.01;
-
-        [_viewportHandler resetViewportConfiguration:&configuration];
-    }];
-}
-
-- (void)contentViewDidReceiveMobileDocType:(WKContentView *)contentView
-{
-    [_viewportHandler update:^{
-        struct _UIWebViewportConfiguration configuration = standardViewportConfiguration;
-        configuration.minimumScale = 1;
-        configuration.size = CGSizeMake(320.0, UIWebViewportGrowsAndShrinksToFitHeight);
-        [_viewportHandler resetViewportConfiguration:&configuration];
-    }];
+    _isWaitingForNewLayerTreeAfterDidCommitLoad = YES;
 }
 
-- (void)contentView:(WKContentView *)contentView didChangeViewportArgumentsSize:(CGSize)newSize initialScale:(float)initialScale minimumScale:(float)minimumScale maximumScale:(float)maximumScale allowsUserScaling:(float)allowsUserScaling
-{
-    [_viewportHandler update:^{
-        [_viewportHandler applyWebKitViewportArgumentsSize:newSize
-                                              initialScale:initialScale
-                                              minimumScale:minimumScale
-                                              maximumScale:maximumScale
-                                         allowsUserScaling:allowsUserScaling];
-    }];
-}
-
-#pragma mark - _UIWebViewportHandlerDelegate
-
-- (void)viewportHandlerDidChangeScales:(_UIWebViewportHandler *)viewportHandler
+- (void)contentView:(WKContentView *)contentView didCommitLayerTree:(const WebKit::RemoteLayerTreeTransaction&)layerTreeTransaction
 {
-    ASSERT(viewportHandler == _viewportHandler);
-    [_scrollView setMinimumZoomScale:viewportHandler.minimumScale];
-    [_scrollView setMaximumZoomScale:viewportHandler.maximumScale];
-    [_scrollView setZoomEnabled:viewportHandler.allowsUserScaling];
-
-    if (!_userHasChangedPageScale)
-        [self _setDocumentScale:viewportHandler.initialScale];
-    else {
-        CGFloat currentScale = [_scrollView zoomScale];
-        CGFloat validScale = std::max(std::min(currentScale, static_cast<CGFloat>(viewportHandler.maximumScale)), static_cast<CGFloat>(viewportHandler.minimumScale));
-        [self _setDocumentScale:validScale];
+    [_scrollView setMinimumZoomScale:layerTreeTransaction.minimumScaleFactor()];
+    [_scrollView setMaximumZoomScale:layerTreeTransaction.maximumScaleFactor()];
+    [_scrollView setZoomEnabled:layerTreeTransaction.allowsUserScaling()];
+    if (![_scrollView isZooming] && ![_scrollView isZoomBouncing])
+        [_scrollView setZoomScale:layerTreeTransaction.pageScaleFactor()];
+
+    if (_isWaitingForNewLayerTreeAfterDidCommitLoad) {
+        UIEdgeInsets inset = [_scrollView contentInset];
+        [_scrollView setContentOffset:CGPointMake(-inset.left, -inset.top)];
+        _isWaitingForNewLayerTreeAfterDidCommitLoad = NO;
     }
-}
 
-- (void)viewportHandler:(_UIWebViewportHandler *)viewportHandler didChangeViewportSize:(CGSize)newSize
-{
-    ASSERT(viewportHandler == _viewportHandler);
-    [_contentView setViewportSize:newSize];
 }
 
-
 #pragma mark - UIScrollViewDelegate
 
 - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
@@ -190,7 +131,7 @@ static struct _UIWebViewportConfiguration standardViewportConfiguration = { { UI
 - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
 {
     if (scrollView.pinchGestureRecognizer.state == UIGestureRecognizerStateBegan)
-        _userHasChangedPageScale = YES;
+        [_contentView willStartUserTriggeredZoom];
     [_contentView willStartZoomOrScroll];
 }
 
@@ -255,20 +196,14 @@ static struct _UIWebViewportConfiguration standardViewportConfiguration = { { UI
     [_contentView setFrame:bounds];
     [_scrollView addSubview:_contentView.get()];
 
-    _viewportHandler = adoptNS([[_UIWebViewportHandler alloc] init]);
-    [_viewportHandler setDelegate:self];
-
     [self _frameOrBoundsChanged];
 }
 
 - (void)_frameOrBoundsChanged
 {
     CGRect bounds = [self bounds];
-    if (!_hasStaticMinimumLayoutSize) {
-        [_viewportHandler update:^{
-            [_viewportHandler setAvailableViewSize:bounds.size];
-        }];
-    }
+    if (!_hasStaticMinimumLayoutSize)
+        [_contentView setMinimumLayoutSize:bounds.size];
     [_scrollView setFrame:bounds];
     [_contentView setMinimumSize:bounds.size];
 }
@@ -310,15 +245,14 @@ static struct _UIWebViewportConfiguration standardViewportConfiguration = { { UI
 - (CGSize)minimumLayoutSizeOverride
 {
     ASSERT(_hasStaticMinimumLayoutSize);
-    return [_viewportHandler availableViewSize];
+    return _minimumLayoutSizeOverride;
 }
 
 - (void)setMinimumLayoutSizeOverride:(CGSize)minimumLayoutSizeOverride
 {
     _hasStaticMinimumLayoutSize = YES;
-    [_viewportHandler update:^{
-        [_viewportHandler setAvailableViewSize:minimumLayoutSizeOverride];
-    }];
+    _minimumLayoutSizeOverride = minimumLayoutSizeOverride;
+    [_contentView setMinimumLayoutSize:minimumLayoutSizeOverride];
 }
 
 @end
index 7884e2753d82bffe76e152c74e6d98474bb8f20f..ec72ac36b3ba54531991c02e88a9737b6520188e 100644 (file)
@@ -55,6 +55,7 @@ namespace WebKit {
 class DrawingAreaProxy;
 class FindIndicator;
 class NativeWebKeyboardEvent;
+class RemoteLayerTreeTransaction;
 class WebContextMenuProxy;
 class WebEditCommandProxy;
 class WebPopupMenuProxy;
@@ -149,7 +150,7 @@ public:
     virtual void handleDownloadRequest(DownloadProxy*) = 0;
 #endif // PLATFORM(EFL) || PLATFORM(GTK)
 
-#if PLATFORM(EFL) || PLATFORM(IOS)
+#if PLATFORM(EFL)
     virtual void didChangeContentSize(const WebCore::IntSize&) = 0;
 #endif
 
@@ -238,11 +239,9 @@ public:
 #endif // PLATFORM(MAC)
 
 #if PLATFORM(IOS)
-    virtual void mainDocumentDidReceiveMobileDocType() = 0;
-
     virtual void didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color&, const Vector<WebCore::FloatQuad>& highlightedQuads, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius) = 0;
 
-    virtual void didChangeViewportArguments(const WebCore::ViewportArguments&) = 0;
+    virtual void didCommitLayerTree(const RemoteLayerTreeTransaction&) = 0;
 
     virtual void startAssistingNode(const WebCore::IntRect&, bool hasNextFocusable, bool hasPreviousFocusable) = 0;
     virtual void stopAssistingNode() = 0;
index 845a28fbb263dae513ec94845a2b9455723b6bdc..a5ab87b19de315afffb1b6fefd280d39136db185 100644 (file)
@@ -2874,7 +2874,7 @@ void WebPageProxy::handleDownloadRequest(DownloadProxy* download)
 }
 #endif // PLATFORM(EFL) || PLATFORM(GTK)
 
-#if PLATFORM(EFL) || PLATFORM(IOS)
+#if PLATFORM(EFL)
 void WebPageProxy::didChangeContentSize(const IntSize& size)
 {
     m_pageClient.didChangeContentSize(size);
index b46c07cf12778fa358a6a3683b1158d4fc55b947..fcd7d59a8e738c812403cee0a2fb55d0a6535ff8 100644 (file)
@@ -139,6 +139,7 @@ class NativeWebKeyboardEvent;
 class NativeWebMouseEvent;
 class NativeWebWheelEvent;
 class PageClient;
+class RemoteLayerTreeTransaction;
 class RemoteScrollingCoordinatorProxy;
 class StringPairVector;
 class WebBackForwardList;
@@ -438,6 +439,8 @@ public:
     void executeEditCommand(const String& commandName);
     void validateCommand(const String& commandName, PassRefPtr<ValidateCommandCallback>);
 #if PLATFORM(IOS)
+    void setViewportConfigurationMinimumLayoutSize(const WebCore::IntSize&);
+    void didCommitLayerTree(const WebKit::RemoteLayerTreeTransaction&);
     void selectWithGesture(const WebCore::IntPoint, WebCore::TextGranularity, uint32_t gestureType, uint32_t gestureState, PassRefPtr<GestureCallback>);
     void updateSelectionWithTouches(const WebCore::IntPoint, uint32_t touches, bool baseIsStart, PassRefPtr<TouchesCallback>);
     void selectWithTwoTouches(const WebCore::IntPoint from, const WebCore::IntPoint to, uint32_t gestureType, uint32_t gestureState, PassRefPtr<GestureCallback>);
@@ -821,6 +824,7 @@ public:
     bool suppressVisibilityUpdates() { return m_suppressVisibilityUpdates; }
 
 #if PLATFORM(IOS)
+    void willStartUserTriggeredZooming();
     void didFinishScrolling(const WebCore::FloatPoint& contentOffset);
     void didFinishZooming(float newScale);
 
@@ -993,7 +997,7 @@ private:
 #if USE(COORDINATED_GRAPHICS)
     void didFindZoomableArea(const WebCore::IntPoint&, const WebCore::IntRect&);
 #endif
-#if PLATFORM(EFL) || PLATFORM(IOS)
+#if PLATFORM(EFL)
     void didChangeContentSize(const WebCore::IntSize&);
 #endif
 
@@ -1135,12 +1139,8 @@ private:
 #endif // PLATFORM(MAC) && !PLATFORM(IOS)
 
 #if PLATFORM(IOS)
-    void mainDocumentDidReceiveMobileDocType();
-
     void didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color& color, const Vector<WebCore::FloatQuad>& geometries, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius);
 
-    void didChangeViewportArguments(const WebCore::ViewportArguments& viewportArguments);
-
     void startAssistingNode(const WebCore::IntRect&, bool hasNextFocusable, bool hasPreviousFocusable);
     void stopAssistingNode();
     void notifyRevealedSelection();
index 710751e6ea18e41be45d572b67c047648194fcf8..165464e55aab4d7140d7732530ab86a278eeda1d 100644 (file)
@@ -90,7 +90,7 @@ messages -> WebPageProxy {
     DidFindZoomableArea(WebCore::IntPoint target, WebCore::IntRect area)
 #endif
 
-#if PLATFORM(EFL) || PLATFORM(IOS)
+#if PLATFORM(EFL)
     DidChangeContentSize(WebCore::IntSize newSize)
 #endif
 
@@ -306,10 +306,7 @@ messages -> WebPageProxy {
 #endif
 
 #if PLATFORM(IOS)
-    MainDocumentDidReceiveMobileDocType();
-
     DidGetTapHighlightGeometries(uint64_t requestID, WebCore::Color color, Vector<WebCore::FloatQuad> geometries, WebCore::IntSize topLeftRadius, WebCore::IntSize topRightRadius, WebCore::IntSize bottomLeftRadius, WebCore::IntSize bottomRightRadius)
-    DidChangeViewportArguments(WebCore::ViewportArguments viewportArguments)
 
     StartAssistingNode(WebCore::IntRect scrollRect, bool hasNextFocusable, bool hasPreviousFocusable)
     StopAssistingNode()
index 447c0f97df308961a4de4303e6bb3a04462e1c52..00638a4ad72ec28f7b6e8f813709d2e639eaf1a8 100644 (file)
@@ -229,6 +229,16 @@ void WebPageProxy::autocorrectionContextCallback(const String& beforeText, const
     callback->performCallbackWithReturnValue(beforeText, markedText, selectedText, afterText, location, length);
 }
 
+void WebPageProxy::setViewportConfigurationMinimumLayoutSize(const WebCore::IntSize& size)
+{
+    m_process->send(Messages::WebPage::SetViewportConfigurationMinimumLayoutSize(size), m_pageID);
+}
+
+void WebPageProxy::didCommitLayerTree(const WebKit::RemoteLayerTreeTransaction& layerTreeTransaction)
+{
+    m_pageClient.didCommitLayerTree(layerTreeTransaction);
+}
+
 void WebPageProxy::selectWithGesture(const WebCore::IntPoint point, WebCore::TextGranularity granularity, uint32_t gestureType, uint32_t gestureState, PassRefPtr<GestureCallback> callback)
 {
     if (!isValid()) {
@@ -417,6 +427,11 @@ bool WebPageProxy::acceptsFirstMouse(int, const WebKit::WebMouseEvent&)
     return false;
 }
 
+void WebPageProxy::willStartUserTriggeredZooming()
+{
+    process().send(Messages::WebPage::WillStartUserTriggeredZooming(), m_pageID);
+}
+
 void WebPageProxy::didFinishScrolling(const WebCore::FloatPoint& contentOffset)
 {
     process().send(Messages::WebPage::DidFinishScrolling(contentOffset), m_pageID);
@@ -441,21 +456,11 @@ void WebPageProxy::blurAssistedNode()
     process().send(Messages::WebPage::BlurAssistedNode(), m_pageID);
 }
 
-void WebPageProxy::mainDocumentDidReceiveMobileDocType()
-{
-    m_pageClient.mainDocumentDidReceiveMobileDocType();
-}
-
 void WebPageProxy::didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color& color, const Vector<WebCore::FloatQuad>& highlightedQuads, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius)
 {
     m_pageClient.didGetTapHighlightGeometries(requestID, color, highlightedQuads, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
 }
 
-void WebPageProxy::didChangeViewportArguments(const WebCore::ViewportArguments& viewportArguments)
-{
-    m_pageClient.didChangeViewportArguments(viewportArguments);
-}
-
 void WebPageProxy::startAssistingNode(const WebCore::IntRect& scrollRect, bool hasNextFocusable, bool hasPreviousFocusable)
 {
     m_pageClient.startAssistingNode(scrollRect, hasNextFocusable, hasPreviousFocusable);
index f16ecc44080aebd6759db396a84c0dc36470f4df..f37c8ee8021ab02bb89de5a2c3932cae5b40447e 100644 (file)
@@ -89,6 +89,9 @@ void RemoteLayerTreeDrawingAreaProxy::commitLayerTree(const RemoteLayerTreeTrans
 #if ENABLE(ASYNC_SCROLLING)
     m_webPageProxy->scrollingCoordinatorProxy()->updateScrollingTree(scrollingTreeTransaction);
 #endif
+#if PLATFORM(IOS)
+    m_webPageProxy->didCommitLayerTree(layerTreeTransaction);
+#endif
 }
 
 } // namespace WebKit
index 826484c8ea551e4331a73e8ee650e29c4a779529..43d9a4bd8257b4a6e537a41c35b73792f40f7e36 100644 (file)
@@ -501,9 +501,7 @@ void WebChromeClient::contentsSizeChanged(Frame* frame, const IntSize& size) con
 
     m_page->send(Messages::WebPageProxy::DidChangeContentSize(size));
 #endif
-#if PLATFORM(IOS)
-    m_page->send(Messages::WebPageProxy::DidChangeContentSize(size));
-#endif
+
 
     m_page->drawingArea()->mainFrameContentSizeChanged(size);
 
@@ -849,10 +847,9 @@ void WebChromeClient::exitFullScreenForElement(WebCore::Element* element)
 
 void WebChromeClient::dispatchViewportPropertiesDidChange(const ViewportArguments& viewportArguments) const
 {
-#if PLATFORM(IOS)
-    m_page->send(Messages::WebPageProxy::DidChangeViewportArguments(viewportArguments));
-#else
     UNUSED_PARAM(viewportArguments);
+#if PLATFORM(IOS)
+    m_page->viewportPropertiesDidChange(viewportArguments);
 #endif
 #if USE(TILED_BACKING_STORE)
     if (!m_page->useFixedLayout())
index 4fdca17cff0ffa52c8770832d925a9277a562171..f9117d8a6f203aebeb64908c728276b165e47d9c 100644 (file)
@@ -53,7 +53,7 @@ void WebChromeClient::elementDidBlur(const WebCore::Node* node)
 
 void WebChromeClient::didReceiveMobileDocType()
 {
-    m_page->send(Messages::WebPageProxy::MainDocumentDidReceiveMobileDocType());
+    // FIXME: update the ViewportConfiguration accordingly.
 }
 
 void WebChromeClient::setNeedsScrollNotifications(WebCore::Frame*, bool)
index 40f88535537a5a48db92063ee14e9ea1d2f94cb1..82635d1c48893957e198dd0850ef6e2c797b8c3d 100644 (file)
@@ -281,6 +281,7 @@ WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
 #endif
 #if PLATFORM(IOS)
     , m_shouldReturnWordAtSelection(false)
+    , m_userHasChangedPageScaleFactor(false)
 #endif
     , m_inspectorClient(0)
     , m_backgroundColor(Color::white)
@@ -3075,6 +3076,12 @@ void WebPage::mainFrameDidLayout()
 #if PLATFORM(MAC) && !PLATFORM(IOS)
     m_viewGestureGeometryCollector.mainFrameDidLayout();
 #endif
+#if PLATFORM(IOS)
+    if (FrameView* frameView = mainFrameView()) {
+        m_viewportConfiguration.setContentsSize(frameView->contentsSize());
+        viewportConfigurationChanged();
+    }
+#endif
 }
 
 void WebPage::addPluginView(PluginView* pluginView)
@@ -3977,6 +3984,22 @@ void WebPage::didCommitLoad(WebFrame* frame)
         if (page && page->pageScaleFactor() != 1)
             scalePage(1, IntPoint());
     }
+#if PLATFORM(IOS)
+    m_userHasChangedPageScaleFactor = false;
+
+    // FIXME: Setup a real configuration.
+    ViewportConfiguration::Parameters defaultConfiguration;
+    defaultConfiguration.width = 980;
+    defaultConfiguration.widthIsSet = true;
+    defaultConfiguration.allowsUserScaling = true;
+    defaultConfiguration.minimumScale = 0.25;
+    defaultConfiguration.maximumScale = 5;
+
+    m_viewportConfiguration.setDefaultConfiguration(defaultConfiguration);
+    m_viewportConfiguration.setViewportArguments(ViewportArguments());
+    m_viewportConfiguration.setContentsSize(m_viewportConfiguration.minimumLayoutSize());
+    viewportConfigurationChanged();
+#endif
 
 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
     resetPrimarySnapshottedPlugIn();
index f45a314669d89b6f346c46c61eff0eeb3cb5011e..c6fa990d71571a62e7fcb5d637d55a9922f9b601 100644 (file)
@@ -58,6 +58,7 @@
 #include <WebCore/TextChecking.h>
 #include <WebCore/UserActivity.h>
 #include <WebCore/ViewState.h>
+#include <WebCore/ViewportConfiguration.h>
 #include <WebCore/WebCoreKeyboardUIMode.h>
 #include <wtf/HashMap.h>
 #include <wtf/OwnPtr.h>
@@ -411,6 +412,12 @@ public:
 #endif
 
 #if PLATFORM(IOS)
+    void viewportPropertiesDidChange(const WebCore::ViewportArguments&);
+
+    double minimumPageScaleFactor() const;
+    double maximumPageScaleFactor() const;
+    bool allowsUserScaling() const;
+
     void handleTap(const WebCore::IntPoint&);
     void tapHighlightAtPosition(uint64_t requestID, const WebCore::FloatPoint&);
 
@@ -629,6 +636,9 @@ public:
     void updateVisibilityState(bool isInitialState = false);
 
 #if PLATFORM(IOS)
+    void setViewportConfigurationMinimumLayoutSize(const WebCore::IntSize&);
+    void viewportConfigurationChanged();
+    void willStartUserTriggeredZooming();
     void didFinishScrolling(const WebCore::FloatPoint& contentOffset);
     void didFinishZooming(float);
 #endif
@@ -1049,6 +1059,9 @@ private:
     RefPtr<WebCore::Range> m_currentWordRange;
     RefPtr<WebCore::Node> m_interactionNode;
     bool m_shouldReturnWordAtSelection;
+
+    WebCore::ViewportConfiguration m_viewportConfiguration;
+    bool m_userHasChangedPageScaleFactor;
 #endif
 
     WebInspectorClient* m_inspectorClient;
index f9d80309f58b6956ea9a3171b8307942f28f540e..b62fd41ec2808fb6f863528d1f63f2172087697f 100644 (file)
@@ -41,6 +41,8 @@ messages -> WebPage LegacyReceiver {
     MouseEventSyncForTesting(WebKit::WebMouseEvent event) -> (bool handled)
     WheelEventSyncForTesting(WebKit::WebWheelEvent event) -> (bool handled)
 #if PLATFORM(IOS)
+    SetViewportConfigurationMinimumLayoutSize(WebCore::IntSize size)
+
     HandleTap(WebCore::IntPoint point)
     TapHighlightAtPosition(uint64_t requestID, WebCore::FloatPoint point)
     BlurAssistedNode()
@@ -313,6 +315,7 @@ messages -> WebPage LegacyReceiver {
     SetVisibilityStatePrerender()
 
 #if PLATFORM(IOS)
+    WillStartUserTriggeredZooming();
     DidFinishScrolling(WebCore::FloatPoint contentOffset);
     DidFinishZooming(float scale);
 #endif
index 80ce7a026ff4b1f2063f5fd25f0a131249a8b162..9f471a33d106a887813072bdfbfd5259379183e7 100644 (file)
@@ -79,6 +79,27 @@ bool WebPage::executeKeypressCommandsInternal(const Vector<WebCore::KeypressComm
     return false;
 }
 
+void WebPage::viewportPropertiesDidChange(const ViewportArguments& viewportArguments)
+{
+    m_viewportConfiguration.setViewportArguments(viewportArguments);
+    viewportConfigurationChanged();
+}
+
+double WebPage::minimumPageScaleFactor() const
+{
+    return m_viewportConfiguration.minimumScale();
+}
+
+double WebPage::maximumPageScaleFactor() const
+{
+    return m_viewportConfiguration.maximumScale();
+}
+
+bool WebPage::allowsUserScaling() const
+{
+    return m_viewportConfiguration.allowsUserScaling();
+}
+
 bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* event, bool)
 {
     bool eventWasHandled = false;
@@ -960,6 +981,30 @@ void WebPage::elementDidBlur(WebCore::Node* node)
     }
 }
 
+void WebPage::setViewportConfigurationMinimumLayoutSize(const IntSize& size)
+{
+    m_viewportConfiguration.setMinimumLayoutSize(size);
+    viewportConfigurationChanged();
+}
+
+void WebPage::viewportConfigurationChanged()
+{
+    setFixedLayoutSize(m_viewportConfiguration.layoutSize());
+
+    double scale;
+    if (m_userHasChangedPageScaleFactor)
+        scale = std::max(std::min(pageScaleFactor(), m_viewportConfiguration.maximumScale()), m_viewportConfiguration.minimumScale());
+    else
+        scale = m_viewportConfiguration.initialScale();
+
+    m_page->setPageScaleFactor(scale, m_page->mainFrame().view()->scrollPosition());
+}
+
+void WebPage::willStartUserTriggeredZooming()
+{
+    m_userHasChangedPageScaleFactor = true;
+}
+
 void WebPage::didFinishScrolling(const WebCore::FloatPoint& contentOffset)
 {
     m_page->mainFrame().view()->setScrollOffset(WebCore::IntPoint(contentOffset));
index e1e0edab41d59f54d095f9ae7dd0ff0af02801bf..a1076cc70e45a8d91da144a3a4868a4190fd54a5 100644 (file)
@@ -321,6 +321,13 @@ void RemoteLayerTreeDrawingArea::flushLayers()
     // FIXME: minize these transactions if nothing changed.
     RemoteLayerTreeTransaction layerTransaction;
     m_remoteLayerTreeContext->buildTransaction(layerTransaction, *m_rootLayer);
+    layerTransaction.setContentsSize(m_webPage->corePage()->mainFrame().view()->contentsSize());
+    layerTransaction.setPageScaleFactor(m_webPage->corePage()->pageScaleFactor());
+#if PLATFORM(IOS)
+    layerTransaction.setMinimumScaleFactor(m_webPage->minimumPageScaleFactor());
+    layerTransaction.setMaximumScaleFactor(m_webPage->maximumPageScaleFactor());
+    layerTransaction.setAllowsUserScaling(m_webPage->allowsUserScaling());
+#endif
 
     RemoteScrollingCoordinatorTransaction scrollingTransaction;
 #if ENABLE(ASYNC_SCROLLING)