Diff
Modified: trunk/Source/WebCore/ChangeLog (229062 => 229063)
--- trunk/Source/WebCore/ChangeLog 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebCore/ChangeLog 2018-02-27 17:16:31 UTC (rev 229063)
@@ -1,5 +1,47 @@
2018-02-27 Wenson Hsieh <wenson_hs...@apple.com>
+ [Extra zoom mode] Implement additional SPI for adjusting viewport shrink-to-fit behavior
+ https://bugs.webkit.org/show_bug.cgi?id=183100
+ <rdar://problem/37840987>
+
+ Reviewed by Tim Horton.
+
+ Introduce new customization options to ViewportConfiguration. The first is m_forceHorizontalShrinkToFit, which
+ (when set to true) forces the viewport to scale using shrink-to-fit heuristics, regardless of whether
+ "shrink-to-fit=no" is specified via viewport parameters or if content width did not exceed minimum layout size.
+ The second is m_viewSize, which reflects the true size of the viewport. See WebKit ChangeLog for more details.
+
+ Tests: ViewportSizingTests.ForceShrinkToFitViewportOverridesViewportParameters
+ ViewportSizingTests.ShrinkToFitViewportWithMinimumAllowedLayoutWidth
+
+ * page/ViewportConfiguration.cpp:
+ (WebCore::ViewportConfiguration::ViewportConfiguration):
+ (WebCore::ViewportConfiguration::setMinimumLayoutSize):
+
+ Plumb the real size of the view alongside the minimum layout size when updating the minimum layout size.
+
+ (WebCore::ViewportConfiguration::setForceHorizontalShrinkToFit):
+ (WebCore::ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints const):
+
+ Bail early and return true if forceHorizontalShrinkToFit is set. This forces shrink-to-fit even in cases where
+ "shrink-to-fit" is set to "no", or content dimensions don't exceed layout dimensions.
+
+ (WebCore::ViewportConfiguration::initialScaleFromSize const):
+
+ Use view dimensions rather than minimum layout dimensions when computing the initial scale. Minimum layout size
+ is no longer always equal to the size of the view if the client has specified a minimum allowed layout width. As
+ such, when computing the initial scale, to ensure that the content (which was laid out using the minimum layout
+ size) fits within the real viewport, we need to divide real viewport dimensions by content dimensions.
+
+ (WebCore::ViewportConfiguration::minimumScale const):
+
+ Similarly, use view size instead of minimum layout size to compute minimum scale.
+
+ (WebCore::ViewportConfiguration::description const):
+ * page/ViewportConfiguration.h:
+
+2018-02-27 Wenson Hsieh <wenson_hs...@apple.com>
+
Unreviewed, fix the debug build after r228877.
In the case where CAN_DISALLOW_USER_INSTALLED_FONTS is enabled, this function doesn't return anything when
Modified: trunk/Source/WebCore/page/ViewportConfiguration.cpp (229062 => 229063)
--- trunk/Source/WebCore/page/ViewportConfiguration.cpp 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebCore/page/ViewportConfiguration.cpp 2018-02-27 17:16:31 UTC (rev 229063)
@@ -49,6 +49,7 @@
: m_minimumLayoutSize(1024, 768)
, m_canIgnoreScalingConstraints(false)
, m_forceAlwaysUserScalable(false)
+ , m_forceHorizontalShrinkToFit(false)
{
// Setup a reasonable default configuration to avoid computing infinite scale/sizes.
// Those are the original iPhone configuration.
@@ -82,12 +83,14 @@
return true;
}
-bool ViewportConfiguration::setMinimumLayoutSize(const FloatSize& minimumLayoutSize)
+bool ViewportConfiguration::setMinimumLayoutSize(const FloatSize& minimumLayoutSize, const FloatSize& viewSize)
{
- if (m_minimumLayoutSize == minimumLayoutSize)
+ if (m_minimumLayoutSize == minimumLayoutSize && m_viewSize == viewSize)
return false;
m_minimumLayoutSize = minimumLayoutSize;
+ m_viewSize = viewSize;
+
updateConfiguration();
return true;
}
@@ -103,6 +106,15 @@
return true;
}
+bool ViewportConfiguration::setForceHorizontalShrinkToFit(bool forceHorizontalShrinkToFit)
+{
+ if (m_forceHorizontalShrinkToFit == forceHorizontalShrinkToFit)
+ return false;
+
+ m_forceHorizontalShrinkToFit = forceHorizontalShrinkToFit;
+ return true;
+}
+
bool ViewportConfiguration::setCanIgnoreScalingConstraints(bool canIgnoreScalingConstraints)
{
if (canIgnoreScalingConstraints == m_canIgnoreScalingConstraints)
@@ -123,6 +135,9 @@
if (!m_canIgnoreScalingConstraints)
return false;
+ if (m_forceHorizontalShrinkToFit)
+ return true;
+
if (!m_configuration.allowsShrinkToFit)
return false;
@@ -167,14 +182,14 @@
// If not, it is up to us to determine the initial scale.
// We want a scale small enough to fit the document width-wise.
- const FloatSize& minimumLayoutSize = m_minimumLayoutSize;
double initialScale = 0;
if (width > 0 && !shouldIgnoreVerticalScalingConstraints())
- initialScale = minimumLayoutSize.width() / width;
+ initialScale = m_viewSize.width() / width;
// Prevent the initial scale from shrinking to a height smaller than our view's minimum height.
- if (height > 0 && height * initialScale < minimumLayoutSize.height() && !shouldIgnoreHorizontalScalingConstraints())
- initialScale = minimumLayoutSize.height() / height;
+ if (height > 0 && height * initialScale < m_viewSize.height() && !shouldIgnoreHorizontalScalingConstraints())
+ initialScale = m_viewSize.height() / height;
+
return std::min(std::max(initialScale, shouldIgnoreScalingConstraints ? m_defaultConfiguration.minimumScale : m_configuration.minimumScale), m_configuration.maximumScale);
}
@@ -200,14 +215,13 @@
if (m_forceAlwaysUserScalable)
minimumScale = std::min(minimumScale, forceAlwaysUserScalableMinimumScale);
- const FloatSize& minimumLayoutSize = m_minimumLayoutSize;
double contentWidth = m_contentSize.width();
- if (contentWidth > 0 && contentWidth * minimumScale < minimumLayoutSize.width() && !shouldIgnoreVerticalScalingConstraints())
- minimumScale = minimumLayoutSize.width() / contentWidth;
+ if (contentWidth > 0 && contentWidth * minimumScale < m_viewSize.width() && !shouldIgnoreVerticalScalingConstraints())
+ minimumScale = m_viewSize.width() / contentWidth;
double contentHeight = m_contentSize.height();
- if (contentHeight > 0 && contentHeight * minimumScale < minimumLayoutSize.height() && !shouldIgnoreHorizontalScalingConstraints())
- minimumScale = minimumLayoutSize.height() / contentHeight;
+ if (contentHeight > 0 && contentHeight * minimumScale < m_viewSize.height() && !shouldIgnoreHorizontalScalingConstraints())
+ minimumScale = m_viewSize.height() / contentHeight;
minimumScale = std::min(std::max(minimumScale, m_configuration.minimumScale), m_configuration.maximumScale);
@@ -490,6 +504,7 @@
ts.dumpProperty("ignoring horizontal scaling constraints", shouldIgnoreHorizontalScalingConstraints() ? "true" : "false");
ts.dumpProperty("ignoring vertical scaling constraints", shouldIgnoreVerticalScalingConstraints() ? "true" : "false");
ts.dumpProperty("avoids unsafe area", avoidsUnsafeArea() ? "true" : "false");
+ ts.dumpProperty("force horizontal shrink to fit", m_forceHorizontalShrinkToFit ? "true" : "false");
ts.endGroup();
Modified: trunk/Source/WebCore/page/ViewportConfiguration.h (229062 => 229063)
--- trunk/Source/WebCore/page/ViewportConfiguration.h 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebCore/page/ViewportConfiguration.h 2018-02-27 17:16:31 UTC (rev 229063)
@@ -75,11 +75,13 @@
WEBCORE_EXPORT bool setContentsSize(const IntSize&);
const FloatSize& minimumLayoutSize() const { return m_minimumLayoutSize; }
- WEBCORE_EXPORT bool setMinimumLayoutSize(const FloatSize&);
+ WEBCORE_EXPORT bool setMinimumLayoutSize(const FloatSize&, const FloatSize& viewSize);
const ViewportArguments& viewportArguments() const { return m_viewportArguments; }
WEBCORE_EXPORT bool setViewportArguments(const ViewportArguments&);
+ WEBCORE_EXPORT bool setForceHorizontalShrinkToFit(bool);
+
WEBCORE_EXPORT bool setCanIgnoreScalingConstraints(bool);
void setForceAlwaysUserScalable(bool forceAlwaysUserScalable) { m_forceAlwaysUserScalable = forceAlwaysUserScalable; }
@@ -120,10 +122,12 @@
Parameters m_defaultConfiguration;
IntSize m_contentSize;
FloatSize m_minimumLayoutSize;
+ FloatSize m_viewSize;
ViewportArguments m_viewportArguments;
bool m_canIgnoreScalingConstraints;
bool m_forceAlwaysUserScalable;
+ bool m_forceHorizontalShrinkToFit;
};
WTF::TextStream& operator<<(WTF::TextStream&, const ViewportConfiguration::Parameters&);
Modified: trunk/Source/WebKit/ChangeLog (229062 => 229063)
--- trunk/Source/WebKit/ChangeLog 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/ChangeLog 2018-02-27 17:16:31 UTC (rev 229063)
@@ -1,3 +1,105 @@
+2018-02-27 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [Extra zoom mode] Implement additional SPI for adjusting viewport shrink-to-fit behavior
+ https://bugs.webkit.org/show_bug.cgi?id=183100
+ <rdar://problem/37840987>
+
+ Reviewed by Tim Horton.
+
+ Add new SPI hooks to provide finer control over certain aspects of the shrink-to-fit viewport heuristic.
+ Currently, in certain cases of iPad multitasking, Safari allows shrinking content to fit by default. This means
+ that even when "width=device-width" is used, if the contents of the page are too wide to fit within the
+ viewport's width, we'll adjust the initial scale such that the viewport can fit all of the content.
+
+ However, in certain viewport dimensions, this heuristic is insufficient to ensure that pages are laid out and
+ displayed properly within the viewport. Namely, one could imagine that an element with a hard-coded width that
+ is larger than the real viewport width would cause all other elements with dimensions relative to the body to be
+ excessively shrunk down once shrink-to-fit is applied, so the page would still look broken even if the contents
+ of the page all fit within the viewport.
+
+ To mitigate this, we decouple the notions of minimum layout size from the size of the actual viewport (which we
+ simply refer to as "view size"). This allows us to introduce a mechanism where we lay out the page at a given
+ minimum layout size that is larger than the size of the view; later, when we determine the initial scale, we
+ then apply shrink-to-fit scaling using the view size rather than the minimum layout size. This grants us the
+ ability to lay out content as if our view were large, but still ensure that the contents of the page fit within
+ the actual view.
+
+ * Shared/VisibleContentRectUpdateInfo.cpp:
+ (WebKit::VisibleContentRectUpdateInfo::encode const):
+ (WebKit::VisibleContentRectUpdateInfo::decode):
+ (WebKit::operator<<):
+ * Shared/VisibleContentRectUpdateInfo.h:
+ (WebKit::VisibleContentRectUpdateInfo::VisibleContentRectUpdateInfo):
+ (WebKit::VisibleContentRectUpdateInfo::forceHorizontalShrinkToFit const):
+ (WebKit::operator==):
+
+ Plumb the forceHorizontalShrinkToFit flag through VisibleContentRectUpdateInfo.
+
+ * Shared/WebPageCreationParameters.cpp:
+ (WebKit::WebPageCreationParameters::encode const):
+ (WebKit::WebPageCreationParameters::decode):
+ * Shared/WebPageCreationParameters.h:
+
+ Plumb viewSize through IPC to WebPage.
+
+ * UIProcess/API/Cocoa/WKWebView.mm:
+ (-[WKWebView _initializeWithConfiguration:]):
+
+ Start off WKWebView flags at their initial values.
+
+ (-[WKWebView _minimumAllowedLayoutWidth]):
+ (-[WKWebView _setMinimumAllowedLayoutWidth:]):
+
+ This provides the minimum width at which the page will lay out, such that if the view width dips below this
+ value, we'll use this minimum allowed layout width instead. 0 by default.
+
+ (-[WKWebView activeMinimumLayoutSizes:]):
+
+ Refactor this from a static function to a helper method on WKWebView that computes both the minimum layout size
+ (which takes minimum allowed layout width into account) as well as the real view size. Refactor all call sites
+ to use this new method, and also propagate the view size down via IPC, alongside the minimum layout size.
+
+ (-[WKWebView _dispatchSetMinimumLayoutSize:viewSize:]):
+ (-[WKWebView _frameOrBoundsChanged]):
+ (-[WKWebView _setMinimumLayoutSizeOverride:]):
+ (-[WKWebView _setForceHorizontalViewportShrinkToFit:]):
+ (-[WKWebView _forceHorizontalViewportShrinkToFit]):
+
+ Setting this flag to YES forces us to always shrink-to-fit in the horizontal axis. NO by default.
+
+ (-[WKWebView _beginAnimatedResizeWithUpdates:]):
+ (-[WKWebView _endAnimatedResize]):
+ (activeMinimumLayoutSize): Deleted.
+
+ More refactoring to replace activeMinimumLayoutSize() with -activeMinimumLayoutSizes:.
+
+ (-[WKWebView _dispatchSetMinimumLayoutSize:]): Deleted.
+ * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::creationParameters):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/ios/WKContentView.mm:
+ (-[WKContentView didUpdateVisibleRect:unobscuredRect:unobscuredRectInScrollViewCoordinates:obscuredInsets:unobscuredSafeAreaInsets:inputViewBounds:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:enclosedInScrollableAncestorView:]):
+
+ Pass _forceHorizontalViewportShrinkToFit into the visible content rect update.
+
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::dynamicViewportSizeUpdate):
+ (WebKit::WebPageProxy::setViewportConfigurationMinimumLayoutSize):
+
+ Plumb viewSize alongside the existing minimumLayoutSize.
+
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::m_credentialsMessenger):
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+ * WebProcess/WebPage/ios/WebPageIOS.mm:
+ (WebKit::WebPage::setViewportConfigurationMinimumLayoutSize):
+ (WebKit::WebPage::dynamicViewportSizeUpdate):
+ (WebKit::WebPage::updateVisibleContentRects):
+
+ Set forceHorizontalShrinkToFit on the viewport configuration here.
+
2018-02-27 Tim Horton <timothy_hor...@apple.com>
Stop using deprecated CADisplay SPI
Modified: trunk/Source/WebKit/Shared/VisibleContentRectUpdateInfo.cpp (229062 => 229063)
--- trunk/Source/WebKit/Shared/VisibleContentRectUpdateInfo.cpp 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/Shared/VisibleContentRectUpdateInfo.cpp 2018-02-27 17:16:31 UTC (rev 229063)
@@ -53,6 +53,7 @@
encoder << m_isFirstUpdateForNewViewSize;
encoder << m_isChangingObscuredInsetsInteractively;
encoder << m_allowShrinkToFit;
+ encoder << m_forceHorizontalShrinkToFit;
encoder << m_enclosedInScrollableAncestorView;
}
@@ -92,6 +93,8 @@
return false;
if (!decoder.decode(result.m_allowShrinkToFit))
return false;
+ if (!decoder.decode(result.m_forceHorizontalShrinkToFit))
+ return false;
if (!decoder.decode(result.m_enclosedInScrollableAncestorView))
return false;
@@ -130,6 +133,8 @@
ts.dumpProperty("enclosedInScrollableAncestorView", info.enclosedInScrollableAncestorView());
ts.dumpProperty("timestamp", info.timestamp().secondsSinceEpoch().value());
+ ts.dumpProperty("allowShrinkToFit", info.allowShrinkToFit());
+ ts.dumpProperty("forceHorizontalShrinkToFit", info.forceHorizontalShrinkToFit());
if (info.horizontalVelocity())
ts.dumpProperty("horizontalVelocity", info.horizontalVelocity());
if (info.verticalVelocity())
Modified: trunk/Source/WebKit/Shared/VisibleContentRectUpdateInfo.h (229062 => 229063)
--- trunk/Source/WebKit/Shared/VisibleContentRectUpdateInfo.h 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/Shared/VisibleContentRectUpdateInfo.h 2018-02-27 17:16:31 UTC (rev 229063)
@@ -45,7 +45,7 @@
public:
VisibleContentRectUpdateInfo() = default;
- VisibleContentRectUpdateInfo(const WebCore::FloatRect& exposedContentRect, const WebCore::FloatRect& unobscuredContentRect, const WebCore::FloatRect& unobscuredRectInScrollViewCoordinates, const WebCore::FloatRect& unobscuredContentRectRespectingInputViewBounds, const WebCore::FloatRect& customFixedPositionRect, const WebCore::FloatBoxExtent& obscuredInsets, const WebCore::FloatBoxExtent& unobscuredSafeAreaInsets, double scale, bool inStableState, bool isFirstUpdateForNewViewSize, bool isChangingObscuredInsetsInteractively, bool allowShrinkToFit, bool enclosedInScrollableAncestorView, MonotonicTime timestamp, double horizontalVelocity, double verticalVelocity, double scaleChangeRate, uint64_t lastLayerTreeTransactionId)
+ VisibleContentRectUpdateInfo(const WebCore::FloatRect& exposedContentRect, const WebCore::FloatRect& unobscuredContentRect, const WebCore::FloatRect& unobscuredRectInScrollViewCoordinates, const WebCore::FloatRect& unobscuredContentRectRespectingInputViewBounds, const WebCore::FloatRect& customFixedPositionRect, const WebCore::FloatBoxExtent& obscuredInsets, const WebCore::FloatBoxExtent& unobscuredSafeAreaInsets, double scale, bool inStableState, bool isFirstUpdateForNewViewSize, bool isChangingObscuredInsetsInteractively, bool allowShrinkToFit, bool forceHorizontalShrinkToFit, bool enclosedInScrollableAncestorView, MonotonicTime timestamp, double horizontalVelocity, double verticalVelocity, double scaleChangeRate, uint64_t lastLayerTreeTransactionId)
: m_exposedContentRect(exposedContentRect)
, m_unobscuredContentRect(unobscuredContentRect)
, m_unobscuredContentRectRespectingInputViewBounds(unobscuredContentRectRespectingInputViewBounds)
@@ -63,6 +63,7 @@
, m_isFirstUpdateForNewViewSize(isFirstUpdateForNewViewSize)
, m_isChangingObscuredInsetsInteractively(isChangingObscuredInsetsInteractively)
, m_allowShrinkToFit(allowShrinkToFit)
+ , m_forceHorizontalShrinkToFit(forceHorizontalShrinkToFit)
, m_enclosedInScrollableAncestorView(enclosedInScrollableAncestorView)
{
}
@@ -80,6 +81,7 @@
bool isFirstUpdateForNewViewSize() const { return m_isFirstUpdateForNewViewSize; }
bool isChangingObscuredInsetsInteractively() const { return m_isChangingObscuredInsetsInteractively; }
bool allowShrinkToFit() const { return m_allowShrinkToFit; }
+ bool forceHorizontalShrinkToFit() const { return m_forceHorizontalShrinkToFit; }
bool enclosedInScrollableAncestorView() const { return m_enclosedInScrollableAncestorView; }
MonotonicTime timestamp() const { return m_timestamp; }
@@ -112,6 +114,7 @@
bool m_isFirstUpdateForNewViewSize { false };
bool m_isChangingObscuredInsetsInteractively { false };
bool m_allowShrinkToFit { false };
+ bool m_forceHorizontalShrinkToFit { false };
bool m_enclosedInScrollableAncestorView { false };
};
@@ -130,6 +133,7 @@
&& a.inStableState() == b.inStableState()
&& a.isFirstUpdateForNewViewSize() == b.isFirstUpdateForNewViewSize()
&& a.allowShrinkToFit() == b.allowShrinkToFit()
+ && a.forceHorizontalShrinkToFit() == b.forceHorizontalShrinkToFit()
&& a.enclosedInScrollableAncestorView() == b.enclosedInScrollableAncestorView();
}
Modified: trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp (229062 => 229063)
--- trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp 2018-02-27 17:16:31 UTC (rev 229063)
@@ -88,6 +88,7 @@
encoder << textAutosizingWidth;
encoder << ignoresViewportScaleLimits;
encoder << viewportConfigurationMinimumLayoutSize;
+ encoder << viewportConfigurationViewSize;
encoder << maximumUnobscuredSize;
#endif
#if PLATFORM(COCOA)
@@ -244,6 +245,8 @@
return std::nullopt;
if (!decoder.decode(parameters.viewportConfigurationMinimumLayoutSize))
return std::nullopt;
+ if (!decoder.decode(parameters.viewportConfigurationViewSize))
+ return std::nullopt;
if (!decoder.decode(parameters.maximumUnobscuredSize))
return std::nullopt;
#endif
Modified: trunk/Source/WebKit/Shared/WebPageCreationParameters.h (229062 => 229063)
--- trunk/Source/WebKit/Shared/WebPageCreationParameters.h 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/Shared/WebPageCreationParameters.h 2018-02-27 17:16:31 UTC (rev 229063)
@@ -145,6 +145,7 @@
float textAutosizingWidth;
bool ignoresViewportScaleLimits;
WebCore::FloatSize viewportConfigurationMinimumLayoutSize;
+ WebCore::FloatSize viewportConfigurationViewSize;
WebCore::FloatSize maximumUnobscuredSize;
#endif
#if PLATFORM(COCOA)
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (229062 => 229063)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2018-02-27 17:16:31 UTC (rev 229063)
@@ -189,6 +189,11 @@
ResizingWithDocumentHidden,
};
+struct ActiveViewportLayoutSizes {
+ WebCore::FloatSize minimumLayoutSize;
+ WebCore::FloatSize viewSize;
+};
+
#endif // PLATFORM(IOS)
#if PLATFORM(IOS)
@@ -302,6 +307,8 @@
std::optional<int32_t> _lastSentDeviceOrientation;
BOOL _allowsViewportShrinkToFit;
+ BOOL _forceHorizontalViewportShrinkToFit;
+ CGFloat _minimumAllowedLayoutWidth;
BOOL _hasCommittedLoadForMainFrame;
BOOL _needsResetViewStateAfterCommitLoadForMainFrame;
@@ -698,7 +705,16 @@
#if PLATFORM(IOS)
_dragInteractionPolicy = _WKDragInteractionPolicyDefault;
+#if ENABLE(EXTRA_ZOOM_MODE)
+ _minimumAllowedLayoutWidth = 320;
+ _allowsViewportShrinkToFit = YES;
+ _forceHorizontalViewportShrinkToFit = YES;
+#else
+ _minimumAllowedLayoutWidth = 0;
+ _allowsViewportShrinkToFit = NO;
+ _forceHorizontalViewportShrinkToFit = NO;
#endif
+#endif // PLATFORM(IOS)
}
- (void)_setUpSQLiteDatabaseTrackerClient
@@ -2481,25 +2497,45 @@
return UIEdgeInsetsAdd([_scrollView _contentScrollInset], self.safeAreaInsets, [_scrollView _edgesApplyingSafeAreaInsetsToContentInset]);
}
-static WebCore::FloatSize activeMinimumLayoutSize(WKWebView *webView, const CGRect& bounds)
+- (CGFloat)_minimumAllowedLayoutWidth
{
- if (webView->_overridesMinimumLayoutSize)
- return WebCore::FloatSize(webView->_minimumLayoutSizeOverride);
+ return _minimumAllowedLayoutWidth;
+}
+- (void)_setMinimumAllowedLayoutWidth:(CGFloat)minimumAllowedLayoutWidth
+{
+ if (_minimumAllowedLayoutWidth == minimumAllowedLayoutWidth)
+ return;
+
+ _minimumAllowedLayoutWidth = minimumAllowedLayoutWidth;
+
+ auto sizes = [self activeMinimumLayoutSizes:self.bounds];
+ [self _dispatchSetMinimumLayoutSize:sizes.minimumLayoutSize viewSize:sizes.viewSize];
+}
+
+- (ActiveViewportLayoutSizes)activeMinimumLayoutSizes:(const CGRect&)bounds
+{
+ if (_overridesMinimumLayoutSize)
+ return { WebCore::FloatSize(_minimumLayoutSizeOverride), WebCore::FloatSize(_minimumLayoutSizeOverride) };
+
+ ActiveViewportLayoutSizes sizes;
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
- return WebCore::FloatSize(UIEdgeInsetsInsetRect(CGRectMake(0, 0, bounds.size.width, bounds.size.height), webView._scrollViewSystemContentInset).size);
+ sizes.viewSize = WebCore::FloatSize(UIEdgeInsetsInsetRect(CGRectMake(0, 0, bounds.size.width, bounds.size.height), self._scrollViewSystemContentInset).size);
#else
- return WebCore::FloatSize(bounds.size);
+ sizes.viewSize = WebCore::FloatSize { bounds.size };
#endif
+
+ sizes.minimumLayoutSize = { std::max<float>(sizes.viewSize.width(), self._minimumAllowedLayoutWidth), sizes.viewSize.height() };
+ return sizes;
}
-- (void)_dispatchSetMinimumLayoutSize:(WebCore::FloatSize)minimumLayoutSize
+- (void)_dispatchSetMinimumLayoutSize:(WebCore::FloatSize)minimumLayoutSize viewSize:(WebCore::FloatSize)viewSize
{
if (_lastSentMinimumLayoutSize && CGSizeEqualToSize(_lastSentMinimumLayoutSize.value(), minimumLayoutSize))
return;
- LOG_WITH_STREAM(VisibleRects, stream << "-[WKWebView " << _page->pageID() << " _dispatchSetMinimumLayoutSize:] " << minimumLayoutSize << " contentZoomScale " << contentZoomScale(self));
- _page->setViewportConfigurationMinimumLayoutSize(minimumLayoutSize);
+ LOG_WITH_STREAM(VisibleRects, stream << "-[WKWebView " << _page->pageID() << " _dispatchSetMinimumLayoutSize:] " << minimumLayoutSize << " viewSize " << viewSize << " contentZoomScale " << contentZoomScale(self));
+ _page->setViewportConfigurationMinimumLayoutSize(minimumLayoutSize, viewSize);
_lastSentMinimumLayoutSize = minimumLayoutSize;
}
@@ -2527,8 +2563,10 @@
[_scrollView setFrame:bounds];
if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::NotResizing) {
- if (!_overridesMinimumLayoutSize)
- [self _dispatchSetMinimumLayoutSize:activeMinimumLayoutSize(self, self.bounds)];
+ if (!_overridesMinimumLayoutSize) {
+ auto sizes = [self activeMinimumLayoutSizes:self.bounds];
+ [self _dispatchSetMinimumLayoutSize:sizes.minimumLayoutSize viewSize:sizes.viewSize];
+ }
if (!_overridesMaximumUnobscuredSize)
[self _dispatchSetMaximumUnobscuredSize:WebCore::FloatSize(bounds.size)];
@@ -4902,7 +4940,7 @@
_minimumLayoutSizeOverride = minimumLayoutSizeOverride;
if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::NotResizing)
- [self _dispatchSetMinimumLayoutSize:WebCore::FloatSize(minimumLayoutSizeOverride)];
+ [self _dispatchSetMinimumLayoutSize:WebCore::FloatSize(minimumLayoutSizeOverride) viewSize:WebCore::FloatSize(minimumLayoutSizeOverride)];
}
@@ -5009,6 +5047,20 @@
[self _dispatchSetMaximumUnobscuredSize:WebCore::FloatSize(size)];
}
+- (void)_setForceHorizontalViewportShrinkToFit:(BOOL)forceHorizontalViewportShrinkToFit
+{
+ if (_forceHorizontalViewportShrinkToFit == forceHorizontalViewportShrinkToFit)
+ return;
+
+ _forceHorizontalViewportShrinkToFit = forceHorizontalViewportShrinkToFit;
+ [self _scheduleVisibleContentRectUpdate];
+}
+
+- (BOOL)_forceHorizontalViewportShrinkToFit
+{
+ return _forceHorizontalViewportShrinkToFit;
+}
+
- (void)_setAllowsViewportShrinkToFit:(BOOL)allowShrinkToFit
{
_allowsViewportShrinkToFit = allowShrinkToFit;
@@ -5050,8 +5102,8 @@
_dynamicViewportUpdateMode = DynamicViewportUpdateMode::ResizingWithAnimation;
- WebCore::FloatSize oldMinimumLayoutSize = activeMinimumLayoutSize(self, oldBounds);
- WebCore::FloatSize oldMaximumUnobscuredSize = activeMaximumUnobscuredSize(self, oldBounds);
+ auto oldSizes = [self activeMinimumLayoutSizes:self.bounds];
+ auto oldMaximumUnobscuredSize = activeMaximumUnobscuredSize(self, oldBounds);
int32_t oldOrientation = activeOrientation(self);
UIEdgeInsets oldObscuredInsets = _obscuredInsets;
@@ -5058,19 +5110,19 @@
updateBlock();
CGRect newBounds = self.bounds;
- WebCore::FloatSize newMinimumLayoutSize = activeMinimumLayoutSize(self, newBounds);
- WebCore::FloatSize newMaximumUnobscuredSize = activeMaximumUnobscuredSize(self, newBounds);
+ auto newSizes = [self activeMinimumLayoutSizes:newBounds];
+ auto newMaximumUnobscuredSize = activeMaximumUnobscuredSize(self, newBounds);
int32_t newOrientation = activeOrientation(self);
UIEdgeInsets newObscuredInsets = _obscuredInsets;
CGRect futureUnobscuredRectInSelfCoordinates = UIEdgeInsetsInsetRect(newBounds, _obscuredInsets);
CGRect contentViewBounds = [_contentView bounds];
- ASSERT_WITH_MESSAGE(!(_overridesMinimumLayoutSize && newMinimumLayoutSize.isEmpty()), "Clients controlling the layout size should maintain a valid layout size to minimize layouts.");
- if (CGRectIsEmpty(newBounds) || newMinimumLayoutSize.isEmpty() || CGRectIsEmpty(futureUnobscuredRectInSelfCoordinates) || CGRectIsEmpty(contentViewBounds)) {
+ ASSERT_WITH_MESSAGE(!(_overridesMinimumLayoutSize && newSizes.minimumLayoutSize.isEmpty()), "Clients controlling the layout size should maintain a valid layout size to minimize layouts.");
+ if (CGRectIsEmpty(newBounds) || newSizes.minimumLayoutSize.isEmpty() || CGRectIsEmpty(futureUnobscuredRectInSelfCoordinates) || CGRectIsEmpty(contentViewBounds)) {
_dynamicViewportUpdateMode = DynamicViewportUpdateMode::NotResizing;
[self _frameOrBoundsChanged];
if (_overridesMinimumLayoutSize)
- [self _dispatchSetMinimumLayoutSize:WebCore::FloatSize(newMinimumLayoutSize)];
+ [self _dispatchSetMinimumLayoutSize:newSizes.minimumLayoutSize viewSize:newSizes.viewSize];
if (_overridesMaximumUnobscuredSize)
[self _dispatchSetMaximumUnobscuredSize:WebCore::FloatSize(newMaximumUnobscuredSize)];
if (_overridesInterfaceOrientation)
@@ -5081,7 +5133,7 @@
}
if (CGRectEqualToRect(oldBounds, newBounds)
- && oldMinimumLayoutSize == newMinimumLayoutSize
+ && oldSizes.minimumLayoutSize == newSizes.minimumLayoutSize
&& oldMaximumUnobscuredSize == newMaximumUnobscuredSize
&& oldOrientation == newOrientation
&& UIEdgeInsetsEqualToEdgeInsets(oldObscuredInsets, newObscuredInsets)) {
@@ -5101,13 +5153,13 @@
[_resizeAnimationView addSubview:[_contentView unscaledView]];
CGSize contentSizeInContentViewCoordinates = contentViewBounds.size;
- [_scrollView setMinimumZoomScale:std::min(newMinimumLayoutSize.width() / contentSizeInContentViewCoordinates.width, [_scrollView minimumZoomScale])];
- [_scrollView setMaximumZoomScale:std::max(newMinimumLayoutSize.width() / contentSizeInContentViewCoordinates.width, [_scrollView maximumZoomScale])];
+ [_scrollView setMinimumZoomScale:std::min(newSizes.minimumLayoutSize.width() / contentSizeInContentViewCoordinates.width, [_scrollView minimumZoomScale])];
+ [_scrollView setMaximumZoomScale:std::max(newSizes.minimumLayoutSize.width() / contentSizeInContentViewCoordinates.width, [_scrollView maximumZoomScale])];
// Compute the new scale to keep the current content width in the scrollview.
CGFloat oldWebViewWidthInContentViewCoordinates = oldUnobscuredContentRect.width();
CGFloat visibleContentViewWidthInContentCoordinates = std::min(contentSizeInContentViewCoordinates.width, oldWebViewWidthInContentViewCoordinates);
- CGFloat targetScale = newMinimumLayoutSize.width() / visibleContentViewWidthInContentCoordinates;
+ CGFloat targetScale = newSizes.minimumLayoutSize.width() / visibleContentViewWidthInContentCoordinates;
CGFloat resizeAnimationViewAnimationScale = targetScale / contentZoomScale(self);
[_resizeAnimationView setTransform:CGAffineTransformMakeScale(resizeAnimationViewAnimationScale, resizeAnimationViewAnimationScale)];
@@ -5147,11 +5199,11 @@
UIEdgeInsets unobscuredSafeAreaInsets = [self _computedUnobscuredSafeAreaInset];
WebCore::FloatBoxExtent unobscuredSafeAreaInsetsExtent(unobscuredSafeAreaInsets.top, unobscuredSafeAreaInsets.right, unobscuredSafeAreaInsets.bottom, unobscuredSafeAreaInsets.left);
- _lastSentMinimumLayoutSize = newMinimumLayoutSize;
+ _lastSentMinimumLayoutSize = newSizes.minimumLayoutSize;
_lastSentMaximumUnobscuredSize = newMaximumUnobscuredSize;
_lastSentDeviceOrientation = newOrientation;
- _page->dynamicViewportSizeUpdate(newMinimumLayoutSize, newMaximumUnobscuredSize, visibleRectInContentCoordinates, unobscuredRectInContentCoordinates, futureUnobscuredRectInSelfCoordinates, unobscuredSafeAreaInsetsExtent, targetScale, newOrientation);
+ _page->dynamicViewportSizeUpdate(newSizes.minimumLayoutSize, newSizes.viewSize, newMaximumUnobscuredSize, visibleRectInContentCoordinates, unobscuredRectInContentCoordinates, futureUnobscuredRectInSelfCoordinates, unobscuredSafeAreaInsetsExtent, targetScale, newOrientation);
if (WebKit::DrawingAreaProxy* drawingArea = _page->drawingArea())
drawingArea->setSize(WebCore::IntSize(newBounds.size));
}
@@ -5216,12 +5268,12 @@
[self _scheduleVisibleContentRectUpdate];
CGRect newBounds = self.bounds;
- WebCore::FloatSize newMinimumLayoutSize = activeMinimumLayoutSize(self, newBounds);
- WebCore::FloatSize newMaximumUnobscuredSize = activeMaximumUnobscuredSize(self, newBounds);
+ auto newSizes = [self activeMinimumLayoutSizes:newBounds];
+ auto newMaximumUnobscuredSize = activeMaximumUnobscuredSize(self, newBounds);
int32_t newOrientation = activeOrientation(self);
- if (!_lastSentMinimumLayoutSize || newMinimumLayoutSize != _lastSentMinimumLayoutSize.value())
- [self _dispatchSetMinimumLayoutSize:WebCore::FloatSize(newMinimumLayoutSize)];
+ if (!_lastSentMinimumLayoutSize || newSizes.minimumLayoutSize != _lastSentMinimumLayoutSize.value())
+ [self _dispatchSetMinimumLayoutSize:newSizes.minimumLayoutSize viewSize:newSizes.viewSize];
if (!_lastSentMaximumUnobscuredSize || newMaximumUnobscuredSize != _lastSentMaximumUnobscuredSize.value())
[self _dispatchSetMaximumUnobscuredSize:WebCore::FloatSize(newMaximumUnobscuredSize)];
if (!_lastSentDeviceOrientation || newOrientation != _lastSentDeviceOrientation.value())
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h (229062 => 229063)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h 2018-02-27 17:16:31 UTC (rev 229063)
@@ -204,6 +204,8 @@
@property (nonatomic, setter=_setInterfaceOrientationOverride:) UIInterfaceOrientation _interfaceOrientationOverride;
@property (nonatomic, setter=_setAllowsViewportShrinkToFit:) BOOL _allowsViewportShrinkToFit;
+@property (nonatomic, setter=_setForceHorizontalViewportShrinkToFit:) BOOL _forceHorizontalViewportShrinkToFit WK_API_AVAILABLE(ios(WK_IOS_TBA));
+@property (nonatomic, setter=_setMinimumAllowedLayoutWidth:) CGFloat _minimumAllowedLayoutWidth WK_API_AVAILABLE(ios(WK_IOS_TBA));
// FIXME: Remove these three properties once we expose WKWebViewContentProvider as API.
@property (nonatomic, readonly, getter=_isDisplayingPDF) BOOL _displayingPDF;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (229062 => 229063)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-02-27 17:16:31 UTC (rev 229063)
@@ -5853,6 +5853,7 @@
parameters.mimeTypesWithCustomContentProviders = m_pageClient.mimeTypesWithCustomContentProviders();
parameters.ignoresViewportScaleLimits = m_forceAlwaysUserScalable;
parameters.viewportConfigurationMinimumLayoutSize = m_viewportConfigurationMinimumLayoutSize;
+ parameters.viewportConfigurationViewSize = m_viewportConfigurationViewSize;
parameters.maximumUnobscuredSize = m_maximumUnobscuredSize;
#endif
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (229062 => 229063)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-02-27 17:16:31 UTC (rev 229063)
@@ -532,10 +532,10 @@
void overflowScrollWillStartScroll();
void overflowScrollDidEndScroll();
- void dynamicViewportSizeUpdate(const WebCore::FloatSize& minimumLayoutSize, const WebCore::FloatSize& maximumUnobscuredSize, const WebCore::FloatRect& targetExposedContentRect, const WebCore::FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& unobscuredSafeAreaInsets, double targetScale, int32_t deviceOrientation);
+ void dynamicViewportSizeUpdate(const WebCore::FloatSize& minimumLayoutSize, const WebCore::FloatSize& viewSize, const WebCore::FloatSize& maximumUnobscuredSize, const WebCore::FloatRect& targetExposedContentRect, const WebCore::FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& unobscuredSafeAreaInsets, double targetScale, int32_t deviceOrientation);
void synchronizeDynamicViewportUpdate();
- void setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize&);
+ void setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize&, const WebCore::FloatSize& viewSize);
void setMaximumUnobscuredSize(const WebCore::FloatSize&);
void setDeviceOrientation(int32_t);
int32_t deviceOrientation() const { return m_deviceOrientation; }
@@ -2088,6 +2088,7 @@
std::unique_ptr<NodeAssistanceArguments> m_deferredNodeAssistanceArguments;
bool m_forceAlwaysUserScalable { false };
WebCore::FloatSize m_viewportConfigurationMinimumLayoutSize;
+ WebCore::FloatSize m_viewportConfigurationViewSize;
WebCore::FloatSize m_maximumUnobscuredSize;
#endif
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentView.mm (229062 => 229063)
--- trunk/Source/WebKit/UIProcess/ios/WKContentView.mm 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentView.mm 2018-02-27 17:16:31 UTC (rev 229063)
@@ -425,6 +425,7 @@
_sizeChangedSinceLastVisibleContentRectUpdate,
isChangingObscuredInsetsInteractively,
_webView._allowsViewportShrinkToFit,
+ _webView._forceHorizontalViewportShrinkToFit,
enclosedInScrollableAncestorView,
timestamp,
velocityData.horizontalVelocity,
Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (229062 => 229063)
--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2018-02-27 17:16:31 UTC (rev 229063)
@@ -304,7 +304,7 @@
m_pageClient.overflowScrollDidEndScroll();
}
-void WebPageProxy::dynamicViewportSizeUpdate(const FloatSize& minimumLayoutSize, const WebCore::FloatSize& maximumUnobscuredSize, const FloatRect& targetExposedContentRect, const FloatRect& targetUnobscuredRect, const FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& unobscuredSafeAreaInsets, double targetScale, int32_t deviceOrientation)
+void WebPageProxy::dynamicViewportSizeUpdate(const FloatSize& minimumLayoutSize, const FloatSize& viewSize, const WebCore::FloatSize& maximumUnobscuredSize, const FloatRect& targetExposedContentRect, const FloatRect& targetUnobscuredRect, const FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& unobscuredSafeAreaInsets, double targetScale, int32_t deviceOrientation)
{
if (!isValid())
return;
@@ -313,7 +313,7 @@
m_dynamicViewportSizeUpdateWaitingForTarget = true;
m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = true;
- m_process->send(Messages::WebPage::DynamicViewportSizeUpdate(minimumLayoutSize, maximumUnobscuredSize, targetExposedContentRect, targetUnobscuredRect, targetUnobscuredRectInScrollViewCoordinates, unobscuredSafeAreaInsets, targetScale, deviceOrientation, ++m_currentDynamicViewportSizeUpdateID), m_pageID);
+ m_process->send(Messages::WebPage::DynamicViewportSizeUpdate(minimumLayoutSize, viewSize, maximumUnobscuredSize, targetExposedContentRect, targetUnobscuredRect, targetUnobscuredRectInScrollViewCoordinates, unobscuredSafeAreaInsets, targetScale, deviceOrientation, ++m_currentDynamicViewportSizeUpdateID), m_pageID);
}
void WebPageProxy::synchronizeDynamicViewportUpdate()
@@ -353,12 +353,13 @@
m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = false;
}
-void WebPageProxy::setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize& size)
+void WebPageProxy::setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize& size, const WebCore::FloatSize& viewSize)
{
m_viewportConfigurationMinimumLayoutSize = size;
+ m_viewportConfigurationViewSize = viewSize;
if (isValid())
- m_process->send(Messages::WebPage::SetViewportConfigurationMinimumLayoutSize(size), m_pageID);
+ m_process->send(Messages::WebPage::SetViewportConfigurationMinimumLayoutSize(size, viewSize), m_pageID);
}
void WebPageProxy::setForceAlwaysUserScalable(bool userScalable)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (229062 => 229063)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2018-02-27 17:16:31 UTC (rev 229063)
@@ -604,7 +604,7 @@
#endif
#if PLATFORM(IOS)
- setViewportConfigurationMinimumLayoutSize(parameters.viewportConfigurationMinimumLayoutSize);
+ setViewportConfigurationMinimumLayoutSize(parameters.viewportConfigurationMinimumLayoutSize, parameters.viewportConfigurationViewSize);
setMaximumUnobscuredSize(parameters.maximumUnobscuredSize);
#endif
}
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (229062 => 229063)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-02-27 17:16:31 UTC (rev 229063)
@@ -867,10 +867,10 @@
void updateVisibilityState(bool isInitialState = false);
#if PLATFORM(IOS)
- void setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize&);
+ void setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize&, const WebCore::FloatSize& viewSize);
void setMaximumUnobscuredSize(const WebCore::FloatSize&);
void setDeviceOrientation(int32_t);
- void dynamicViewportSizeUpdate(const WebCore::FloatSize& minimumLayoutSize, const WebCore::FloatSize& maximumUnobscuredSize, const WebCore::FloatRect& targetExposedContentRect, const WebCore::FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID);
+ void dynamicViewportSizeUpdate(const WebCore::FloatSize& minimumLayoutSize, const WebCore::FloatSize& viewSize, const WebCore::FloatSize& maximumUnobscuredSize, const WebCore::FloatRect& targetExposedContentRect, const WebCore::FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID);
void synchronizeDynamicViewportUpdate(double& newTargetScale, WebCore::FloatPoint& newScrollPosition, uint64_t& nextValidLayerTreeTransactionID);
std::optional<float> scaleFromUIProcess(const VisibleContentRectUpdateInfo&) const;
void updateVisibleContentRects(const VisibleContentRectUpdateInfo&, MonotonicTime oldestTimestamp);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (229062 => 229063)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-02-27 17:16:31 UTC (rev 229063)
@@ -41,10 +41,10 @@
KeyEvent(WebKit::WebKeyboardEvent event)
MouseEvent(WebKit::WebMouseEvent event)
#if PLATFORM(IOS)
- SetViewportConfigurationMinimumLayoutSize(WebCore::FloatSize size)
+ SetViewportConfigurationMinimumLayoutSize(WebCore::FloatSize size, WebCore::FloatSize viewSize)
SetMaximumUnobscuredSize(WebCore::FloatSize size)
SetDeviceOrientation(int32_t deviceOrientation)
- DynamicViewportSizeUpdate(WebCore::FloatSize minimumLayoutSize, WebCore::FloatSize maximumUnobscuredSize, WebCore::FloatRect targetExposedContentRect, WebCore::FloatRect targetUnobscuredRect, WebCore::FloatRect targetUnobscuredRectInScrollViewCoordinates, WebCore::RectEdges<float> targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID)
+ DynamicViewportSizeUpdate(WebCore::FloatSize minimumLayoutSize, WebCore::FloatSize viewSize, WebCore::FloatSize maximumUnobscuredSize, WebCore::FloatRect targetExposedContentRect, WebCore::FloatRect targetUnobscuredRect, WebCore::FloatRect targetUnobscuredRectInScrollViewCoordinates, WebCore::RectEdges<float> targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID)
SynchronizeDynamicViewportUpdate() -> (double newTargetScale, WebCore::FloatPoint newScrollPosition, uint64_t nextValidLayerTreeTransactionID)
HandleTap(WebCore::IntPoint point, uint64_t lastLayerTreeTransactionId)
Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (229062 => 229063)
--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2018-02-27 17:16:31 UTC (rev 229063)
@@ -2851,10 +2851,10 @@
}
}
-void WebPage::setViewportConfigurationMinimumLayoutSize(const FloatSize& size)
+void WebPage::setViewportConfigurationMinimumLayoutSize(const FloatSize& size, const FloatSize& viewSize)
{
- LOG_WITH_STREAM(VisibleRects, stream << "WebPage " << m_pageID << " setViewportConfigurationMinimumLayoutSize " << size);
- if (m_viewportConfiguration.setMinimumLayoutSize(size))
+ LOG_WITH_STREAM(VisibleRects, stream << "WebPage " << m_pageID << " setViewportConfigurationMinimumLayoutSize " << size << " viewSize " << viewSize);
+ if (m_viewportConfiguration.setMinimumLayoutSize(size, viewSize))
viewportConfigurationChanged();
}
@@ -2889,12 +2889,12 @@
}
}
-void WebPage::dynamicViewportSizeUpdate(const FloatSize& minimumLayoutSize, const WebCore::FloatSize& maximumUnobscuredSize, const FloatRect& targetExposedContentRect, const FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& targetUnobscuredSafeAreaInsets, double targetScale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID)
+void WebPage::dynamicViewportSizeUpdate(const FloatSize& minimumLayoutSize, const FloatSize& viewSize, const WebCore::FloatSize& maximumUnobscuredSize, const FloatRect& targetExposedContentRect, const FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& targetUnobscuredSafeAreaInsets, double targetScale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID)
{
SetForScope<bool> dynamicSizeUpdateGuard(m_inDynamicSizeUpdate, true);
// FIXME: this does not handle the cases where the content would change the content size or scroll position from _javascript_.
// To handle those cases, we would need to redo this computation on every change until the next visible content rect update.
- LOG_WITH_STREAM(VisibleRects, stream << "\nWebPage::dynamicViewportSizeUpdate - minimumLayoutSize " << minimumLayoutSize << " targetUnobscuredRect " << targetUnobscuredRect << " targetExposedContentRect " << targetExposedContentRect << " targetScale " << targetScale);
+ LOG_WITH_STREAM(VisibleRects, stream << "\nWebPage::dynamicViewportSizeUpdate - minimumLayoutSize " << minimumLayoutSize << " viewSize " << viewSize << " targetUnobscuredRect " << targetUnobscuredRect << " targetExposedContentRect " << targetExposedContentRect << " targetScale " << targetScale);
FrameView& frameView = *m_page->mainFrame().view();
IntSize oldContentSize = frameView.contentsSize();
@@ -2927,7 +2927,7 @@
}
LOG_WITH_STREAM(VisibleRects, stream << "WebPage::dynamicViewportSizeUpdate setting minimum layout size to " << minimumLayoutSize);
- m_viewportConfiguration.setMinimumLayoutSize(minimumLayoutSize);
+ m_viewportConfiguration.setMinimumLayoutSize(minimumLayoutSize, viewSize);
IntSize newLayoutSize = m_viewportConfiguration.layoutSize();
if (setFixedLayoutSize(newLayoutSize))
@@ -3307,7 +3307,9 @@
if (scrollPosition != frameView.scrollPosition())
m_dynamicSizeUpdateHistory.clear();
- if (m_viewportConfiguration.setCanIgnoreScalingConstraints(m_ignoreViewportScalingConstraints && visibleContentRectUpdateInfo.allowShrinkToFit()))
+ bool didUpdateForceHorizontalShrinkToFit = m_viewportConfiguration.setForceHorizontalShrinkToFit(visibleContentRectUpdateInfo.forceHorizontalShrinkToFit());
+ bool didUpdateCanIgnoreViewportScalingConstraints = m_viewportConfiguration.setCanIgnoreScalingConstraints(m_ignoreViewportScalingConstraints && visibleContentRectUpdateInfo.allowShrinkToFit());
+ if (didUpdateForceHorizontalShrinkToFit || didUpdateCanIgnoreViewportScalingConstraints)
viewportConfigurationChanged();
frameView.setUnobscuredContentSize(visibleContentRectUpdateInfo.unobscuredContentRect().size());
Modified: trunk/Tools/ChangeLog (229062 => 229063)
--- trunk/Tools/ChangeLog 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Tools/ChangeLog 2018-02-27 17:16:31 UTC (rev 229063)
@@ -1,3 +1,20 @@
+2018-02-27 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [Extra zoom mode] Implement additional SPI for adjusting viewport shrink-to-fit behavior
+ https://bugs.webkit.org/show_bug.cgi?id=183100
+ <rdar://problem/37840987>
+
+ Reviewed by Tim Horton.
+
+ Add API tests that exercise -_setMinimumAllowedLayoutWidth: and -_setForceHorizontalViewportShrinkToFit:. See
+ WebKit ChangeLog for more detail.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/ios/ViewportSizingTests.mm: Added.
+ (TestWebKitAPI::while):
+ (viewportTestPageMarkup):
+ (TestWebKitAPI::TEST):
+
2018-02-27 Yusuke Suzuki <utatane....@gmail.com>
Unreviewed, skip FTL tests if FTL is disabled
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (229062 => 229063)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2018-02-27 16:43:22 UTC (rev 229062)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2018-02-27 17:16:31 UTC (rev 229063)
@@ -90,6 +90,7 @@
2E14A5291D3FE96B0010F35B /* autoplaying-video-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E14A5281D3FE8B80010F35B /* autoplaying-video-with-audio.html */; };
2E1B7B001D41ABA7007558B4 /* large-video-seek-after-ending.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1B7AFF1D41A95F007558B4 /* large-video-seek-after-ending.html */; };
2E1B7B021D41B1B9007558B4 /* large-video-hides-controls-after-seek-to-end.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1B7B011D41B1B3007558B4 /* large-video-hides-controls-after-seek-to-end.html */; };
+ 2E1B881F2040EE5300FFF6A9 /* ViewportSizingTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E1B881E2040EE5300FFF6A9 /* ViewportSizingTests.mm */; };
2E1DFDED1D42A51100714A00 /* large-videos-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDEC1D42A41C00714A00 /* large-videos-with-audio.html */; };
2E1DFDEF1D42A6F200714A00 /* large-videos-with-audio-autoplay.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDEE1D42A6EB00714A00 /* large-videos-with-audio-autoplay.html */; };
2E1DFDF11D42E1E400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */; };
@@ -1221,6 +1222,7 @@
2E14A5281D3FE8B80010F35B /* autoplaying-video-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "autoplaying-video-with-audio.html"; sourceTree = "<group>"; };
2E1B7AFF1D41A95F007558B4 /* large-video-seek-after-ending.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-seek-after-ending.html"; sourceTree = "<group>"; };
2E1B7B011D41B1B3007558B4 /* large-video-hides-controls-after-seek-to-end.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-hides-controls-after-seek-to-end.html"; sourceTree = "<group>"; };
+ 2E1B881E2040EE5300FFF6A9 /* ViewportSizingTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ViewportSizingTests.mm; sourceTree = "<group>"; };
2E1DFDEC1D42A41C00714A00 /* large-videos-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-videos-with-audio.html"; sourceTree = "<group>"; };
2E1DFDEE1D42A6EB00714A00 /* large-videos-with-audio-autoplay.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-videos-with-audio-autoplay.html"; sourceTree = "<group>"; };
2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-seek-to-beginning-and-play-after-ending.html"; sourceTree = "<group>"; };
@@ -2303,6 +2305,7 @@
F4D4F3B71E4E36E400BB2767 /* DataInteractionTests.mm */,
7560917719259C59009EF06E /* MemoryCacheAddImageToCacheIOS.mm */,
F46849BD1EEF58E400B937FE /* UIPasteboardTests.mm */,
+ 2E1B881E2040EE5300FFF6A9 /* ViewportSizingTests.mm */,
514958BD1F7427AC00E87BAD /* WKWebViewAutofillTests.mm */,
);
path = ios;
@@ -3666,6 +3669,7 @@
7C83E03A1D0A602700FEBCF3 /* UtilitiesCocoa.mm in Sources */,
7C83E0C61D0A654E00FEBCF3 /* VideoControlsManager.mm in Sources */,
115EB3431EE0BA03003C2C0A /* ViewportSizeForViewportUnits.mm in Sources */,
+ 2E1B881F2040EE5300FFF6A9 /* ViewportSizingTests.mm in Sources */,
6356FB221EC4E0BA0044BF18 /* VisibleContentRect.mm in Sources */,
83779C381F82FECE007CDA8A /* VisitedLinkStore.mm in Sources */,
0F139E771A423A5B00F590F5 /* WeakObjCPtr.mm in Sources */,
Added: trunk/Tools/TestWebKitAPI/Tests/ios/ViewportSizingTests.mm (0 => 229063)
--- trunk/Tools/TestWebKitAPI/Tests/ios/ViewportSizingTests.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/ios/ViewportSizingTests.mm 2018-02-27 17:16:31 UTC (rev 229063)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#import "config.h"
+
+#if WK_API_ENABLED && PLATFORM(IOS)
+
+#import "PlatformUtilities.h"
+#import "TestWKWebView.h"
+#import <WebKit/WKWebViewPrivate.h>
+
+using namespace TestWebKitAPI;
+
+@implementation TestWKWebView (ViewportTestingHelpers)
+
+- (BOOL)scaleIsApproximately:(CGFloat)expectedScale
+{
+ static const double maximumExpectedScaleDifference = 0.001;
+ return ABS(self.scrollView.zoomScale - expectedScale) < maximumExpectedScaleDifference;
+}
+
+- (void)expectScaleToBecome:(CGFloat)expectedScale
+{
+ while (![self scaleIsApproximately:expectedScale])
+ [self waitForNextPresentationUpdate];
+}
+
+@end
+
+static NSString *viewportTestPageMarkup(NSString *viewportMetaContent, int contentWidth, int contentHeight)
+{
+ return [NSString stringWithFormat:@"<meta name='viewport' content='%@'><body style='margin: 0'><div style='width: %dpx; height: %dpx; background-color: red'></div>", viewportMetaContent, contentWidth, contentHeight];
+}
+
+namespace TestWebKitAPI {
+
+TEST(ViewportSizingTests, ForceShrinkToFitViewportOverridesViewportParameters)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400)]);
+ [webView _setAllowsViewportShrinkToFit:YES];
+ [webView _setForceHorizontalViewportShrinkToFit:NO];
+ [webView synchronouslyLoadHTMLString:viewportTestPageMarkup(@"width=device-width, shrink-to-fit=no", 600, 100)];
+ [webView expectScaleToBecome:1];
+
+ [webView _setForceHorizontalViewportShrinkToFit:YES];
+ [webView expectScaleToBecome:0.667];
+
+ [webView _setForceHorizontalViewportShrinkToFit:NO];
+ [webView expectScaleToBecome:1];
+}
+
+TEST(ViewportSizingTests, ShrinkToFitViewportWithMinimumAllowedLayoutWidth)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)]);
+ [webView _setAllowsViewportShrinkToFit:YES];
+ [webView _setForceHorizontalViewportShrinkToFit:YES];
+ [webView _setMinimumAllowedLayoutWidth:0];
+ [webView synchronouslyLoadHTMLString:viewportTestPageMarkup(@"width=device-width, initial-scale=1", 400, 100)];
+ [webView expectScaleToBecome:0.5];
+ EXPECT_WK_STREQ("200", [webView stringByEvaluatingJavaScript:@"document.body.clientWidth"]);
+
+ [webView _setMinimumAllowedLayoutWidth:400];
+ [webView waitForNextPresentationUpdate];
+ EXPECT_WK_STREQ("400", [webView stringByEvaluatingJavaScript:@"document.body.clientWidth"]);
+ EXPECT_TRUE([webView scaleIsApproximately:0.5]);
+
+ [webView _setMinimumAllowedLayoutWidth:100];
+ [webView waitForNextPresentationUpdate];
+ EXPECT_WK_STREQ("200", [webView stringByEvaluatingJavaScript:@"document.body.clientWidth"]);
+ EXPECT_TRUE([webView scaleIsApproximately:0.5]);
+}
+
+} // namespace TestWebKitAPI
+
+#endif // WK_API_ENABLED && PLATFORM(IOS)