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
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
https://bugs.webkit.org/show_bug.cgi?id=128167
__ZN7WebCore15GraphicsLayerCA37flushCompositingStateForThisLayerOnlyEv
__ZN7WebCore15GraphicsLayerCA40platformCALayerSetNeedsToRevalidateTilesEv
__ZNK7WebCore15GraphicsLayerCA49platformCALayerContentsScaleMultiplierForNewTilesEPNS_15PlatformCALayerE
+__ZNK7WebCore21ViewportConfiguration10layoutSizeEv
+__ZNK7WebCore21ViewportConfiguration12initialScaleEv
__ZN7WebCore15GraphicsLayerCA7setNameERKN3WTF6StringE
__ZN7WebCore15GraphicsLayerCA7setSizeERKNS_9FloatSizeE
__ZN7WebCore15GraphicsLayerCA8addChildEPNS_13GraphicsLayerE
__ZN7WebCore15GraphicsLayerCAD2Ev
__ZN7WebCore15GraphicsLayerCA19setCustomAppearanceENS_13GraphicsLayer16CustomAppearanceE
__ZNK7WebCore15GraphicsLayerCA14primaryLayerIDEv
+__ZNK7WebCore21ViewportConfiguration12minimumScaleEv
__ZN7WebCore15HitTestLocation12rectForPointERKNS_11LayoutPointEjjjj
__ZN7WebCore15HitTestLocationC1ERKNS_10FloatPointE
__ZN7WebCore15HitTestLocationD1Ev
__ZN7WebCore21SerializedScriptValueD1Ev
__ZN7WebCore21URLByRemovingUserInfoEP5NSURL
__ZN7WebCore21UserContentURLPattern5parseERKN3WTF6StringE
+__ZN7WebCore21ViewportConfiguration15setContentsSizeERKNS_7IntSizeE
+__ZN7WebCore21ViewportConfiguration20setMinimumLayoutSizeERKNS_7IntSizeE
+__ZN7WebCore21ViewportConfiguration20setViewportArgumentsERKNS_17ViewportArgumentsE
+__ZN7WebCore21ViewportConfiguration23setDefaultConfigurationERKNS0_10ParametersE
__ZN7WebCore21WindowsLatin1EncodingEv
__ZN7WebCore21createCFURLFromBufferEPKcmPK7__CFURL
__ZN7WebCore21findEventWithKeyStateEPNS_5EventE
__ZN7WebCore24FrameDestructionObserverD2Ev
__ZN7WebCore24ImmutableStylePropertiesD1Ev
__ZN7WebCore24ReferenceFilterOperationC1ERKN3WTF6StringES4_NS_15FilterOperation13OperationTypeE
+__ZN7WebCore21ViewportConfigurationC1Ev
__ZN7WebCore24createFragmentFromMarkupERNS_8DocumentERKN3WTF6StringES5_NS_19ParserContentPolicyE
__ZN7WebCore24decodeURLEscapeSequencesERKN3WTF6StringE
__ZN7WebCore24deleteCookiesForHostnameERKNS_21NetworkStorageSessionERKN3WTF6StringE
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 */,
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+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
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
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)
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;
}
#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)
#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;
[_contentView setFrame:bounds];
[_scrollView addSubview:_contentView.get()];
- _viewportHandler = adoptNS([[_UIWebViewportHandler alloc] init]);
- [_viewportHandler setDelegate:self];
-
[self _frameOrBoundsChanged];
#endif
#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
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
if (scrollView.pinchGestureRecognizer.state == UIGestureRecognizerStateBegan)
- _userHasChangedPageScale = YES;
+ [_contentView willStartUserTriggeredZoom];
[_contentView willStartZoomOrScroll];
}
{
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];
}
- (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
#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)
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;
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;
[m_view _didCommitLoadForMainFrame];
}
-void PageClientImpl::didChangeContentSize(const IntSize& contentsSize)
-{
- [m_view _didChangeContentSize:contentsSize];
-}
-
void PageClientImpl::setCursor(const Cursor&)
{
notImplemented();
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)
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
- (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
[self _updateViewExposedRect];
}
+- (void)setMinimumLayoutSize:(CGSize)size
+{
+ _page->setViewportConfigurationMinimumLayoutSize(IntSize(CGCeiling(size.width), CGCeiling(size.height)));
+}
+
- (void)didFinishScrollTo:(CGPoint)contentOffset
{
_currentExposedRectPosition = contentOffset;
[_interactionView _willStartScrollingOrZooming];
}
+- (void)willStartUserTriggeredZoom
+{
+ _page->willStartUserTriggeredZooming();
+}
+
- (void)didZoomToScale:(CGFloat)scale
{
_page->didFinishZooming(scale);
[_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
class DrawingAreaProxy;
class GeolocationPermissionRequestProxy;
class LayerTreeContext;
+class RemoteLayerTreeTransaction;
class WebFrameProxy;
class WebPageProxy;
class WebSecurityOrigin;
- (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;
#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
RetainPtr<WKScrollView> _scrollView;
RetainPtr<WKContentView> _contentView;
- BOOL _userHasChangedPageScale;
- RetainPtr<_UIWebViewportHandler> _viewportHandler;
+ BOOL _isWaitingForNewLayerTreeAfterDidCommitLoad;
BOOL _hasStaticMinimumLayoutSize;
+ CGSize _minimumLayoutSizeOverride;
}
- (id)initWithCoder:(NSCoder *)coder
#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
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
if (scrollView.pinchGestureRecognizer.state == UIGestureRecognizerStateBegan)
- _userHasChangedPageScale = YES;
+ [_contentView willStartUserTriggeredZoom];
[_contentView willStartZoomOrScroll];
}
[_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];
}
- (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
class DrawingAreaProxy;
class FindIndicator;
class NativeWebKeyboardEvent;
+class RemoteLayerTreeTransaction;
class WebContextMenuProxy;
class WebEditCommandProxy;
class WebPopupMenuProxy;
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
#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;
}
#endif // PLATFORM(EFL) || PLATFORM(GTK)
-#if PLATFORM(EFL) || PLATFORM(IOS)
+#if PLATFORM(EFL)
void WebPageProxy::didChangeContentSize(const IntSize& size)
{
m_pageClient.didChangeContentSize(size);
class NativeWebMouseEvent;
class NativeWebWheelEvent;
class PageClient;
+class RemoteLayerTreeTransaction;
class RemoteScrollingCoordinatorProxy;
class StringPairVector;
class WebBackForwardList;
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>);
bool suppressVisibilityUpdates() { return m_suppressVisibilityUpdates; }
#if PLATFORM(IOS)
+ void willStartUserTriggeredZooming();
void didFinishScrolling(const WebCore::FloatPoint& contentOffset);
void didFinishZooming(float newScale);
#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
#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();
DidFindZoomableArea(WebCore::IntPoint target, WebCore::IntRect area)
#endif
-#if PLATFORM(EFL) || PLATFORM(IOS)
+#if PLATFORM(EFL)
DidChangeContentSize(WebCore::IntSize newSize)
#endif
#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()
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()) {
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);
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);
#if ENABLE(ASYNC_SCROLLING)
m_webPageProxy->scrollingCoordinatorProxy()->updateScrollingTree(scrollingTreeTransaction);
#endif
+#if PLATFORM(IOS)
+ m_webPageProxy->didCommitLayerTree(layerTreeTransaction);
+#endif
}
} // namespace WebKit
m_page->send(Messages::WebPageProxy::DidChangeContentSize(size));
#endif
-#if PLATFORM(IOS)
- m_page->send(Messages::WebPageProxy::DidChangeContentSize(size));
-#endif
+
m_page->drawingArea()->mainFrameContentSizeChanged(size);
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())
void WebChromeClient::didReceiveMobileDocType()
{
- m_page->send(Messages::WebPageProxy::MainDocumentDidReceiveMobileDocType());
+ // FIXME: update the ViewportConfiguration accordingly.
}
void WebChromeClient::setNeedsScrollNotifications(WebCore::Frame*, bool)
#endif
#if PLATFORM(IOS)
, m_shouldReturnWordAtSelection(false)
+ , m_userHasChangedPageScaleFactor(false)
#endif
, m_inspectorClient(0)
, m_backgroundColor(Color::white)
#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)
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();
#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>
#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&);
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
RefPtr<WebCore::Range> m_currentWordRange;
RefPtr<WebCore::Node> m_interactionNode;
bool m_shouldReturnWordAtSelection;
+
+ WebCore::ViewportConfiguration m_viewportConfiguration;
+ bool m_userHasChangedPageScaleFactor;
#endif
WebInspectorClient* m_inspectorClient;
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()
SetVisibilityStatePrerender()
#if PLATFORM(IOS)
+ WillStartUserTriggeredZooming();
DidFinishScrolling(WebCore::FloatPoint contentOffset);
DidFinishZooming(float scale);
#endif
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;
}
}
+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));
// 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)