Log Message
[iOS] Add `WKWebView` API to control CSS "small viewport" `sv*` and "large viewport" `lv*` units https://bugs.webkit.org/show_bug.cgi?id=237979 <rdar://problem/89434696>
Reviewed by Tim Horton. Source/WebCore: Tests: CSSViewportUnits.NegativeMinimumViewportInset CSSViewportUnits.NegativeMaximumViewportInset CSSViewportUnits.MinimumViewportInsetLargerThanMaximumViewportInset CSSViewportUnits.MinimumViewportInsetLargerThanFrame CSSViewportUnits.MaximumViewportInsetLargerThanFrame CSSViewportUnits.MinimumViewportInset CSSViewportUnits.MaximumViewportInset CSSViewportUnits.MinimumViewportInsetWithZoom CSSViewportUnits.MaximumViewportInsetWithZoom CSSViewportUnits.MinimumViewportInsetWithWritingMode CSSViewportUnits.MaximumViewportInsetWithWritingMode CSSViewportUnits.MinimumViewportInsetWithFrame CSSViewportUnits.MaximumViewportInsetWithFrame CSSViewportUnits.MinimumViewportInsetWithBounds CSSViewportUnits.MaximumViewportInsetWithBounds CSSViewportUnits.MinimumViewportInsetWithContentInset CSSViewportUnits.MaximumViewportInsetWithContentInset CSSViewportUnits.MinimumViewportInsetWithSafeAreaInsets CSSViewportUnits.MaximumViewportInsetWithSafeAreaInsets CSSViewportUnits.UnobscuredSizeOverridesIgnoreMaximumViewportInsetAPI * page/FrameView.h: * page/FrameView.cpp: (WebCore::FrameView::performSizeToContentAutoSize): (WebCore::FrameView::enableAutoSizeMode): (WebCore::FrameView::clearSizeOverrideForCSSDefaultViewportUnits): Added. (WebCore::FrameView::setSizeForCSSDefaultViewportUnits): Added. (WebCore::FrameView::overrideWidthForCSSDefaultViewportUnits): Added. (WebCore::FrameView::resetOverriddenWidthForCSSDefaultViewportUnits): Added. (WebCore::FrameView::overrideSizeForCSSDefaultViewportUnits): Added. (WebCore::FrameView::sizeForCSSDefaultViewportUnits const): Renamed from `sizeForCSSDefaultViewportUnits`. (WebCore::FrameView::copyCSSViewportUnits const): Added. Add all the various methods for getting/setting/overriding/clearing an override value for CSS "default viewport" `v*` units. This allows for `WKWebView` clients to preserve existing behavior (where CSS "default viewport" `v*` units match the size of the `WKWebView`) while adding supporting CSS "small viewport" `sv*` units and CSS "large viewport" `lv*` units. Source/WebKit: Recently the W3C CSS working group added [some new unit types to CSS](https://drafts.csswg.org/css-values-4/#viewport-variants) with the goal of helping web developers better deal with browsers that have dynamic UI elements that change apperance/size/etc. based on user actions (e.g. the URL bar collapsing/"squishing" and expanding/"unsquishing" depending on whether the user has most recently scrolled/swiped down the page). These new units come in three categories: - the "large viewport" units (`lvw`, `lvh`, etc.) each represent 1% of one dimension of the size of the visual area of the page when all browser UI elements are in their smallest state (e.g. when the URL bar is collapsed/"squished") - the "small viewport" units (`svw`, `svh`, etc.) each represent 1% of one dimension of the size of the visual area of the page when all browser UI elements are in their largest state (e.g. when the URL bar is expanded/"unsquished") - the "dynamic viewport" units (`dvw`, `dvh`, etc.) each represent 1% of one dimension of the size of the current visual area of the page, which depends on the current state of all browser UI elements This way, developer could use `100svh` to ensure that no matter what state the browser UI elements are in the entire element will always be visible on the screen, or use `100dvh` to respond to browser UI element changes by automatically resizing various elements to always fully take advantage of the available space. Nothing needs to be added to support "dynamic viewport" `dv*` units as there already exists other methods to adjust the visual area of the `WKWebView` without adjusting its `frame` (e.g. `-[WKWebView setBounds:]`, `-[UIScrollView setContentInset:]`, etc.). But for "small viewport" `sv*` units and "large viewport" `lv*` units, however, there is unfortunately no way to tell a `WKWebView` anything like "this is the smallest/largest that this `WKWebView` will ever be", so there's no way to know ahead of time what the size of the visual area would be when all browser UI elements are in their smallest/largest state. As such, this patch adds a new API to allow for `WKWebView` clients to tell WebKit this information ahead of time. Note that there already exists the concept of "default viewport" units (`vw`, `vh`, etc.) that each represent 1% of one dimension of the size of the visual area of the page when all browser UI elements are in their default state. The behavior of these units remain the same, and the value can be changed via the existing `-[WKWebView setFrame:]`. Tests: CSSViewportUnits.NegativeMinimumViewportInset CSSViewportUnits.NegativeMaximumViewportInset CSSViewportUnits.MinimumViewportInsetLargerThanMaximumViewportInset CSSViewportUnits.MinimumViewportInsetLargerThanFrame CSSViewportUnits.MaximumViewportInsetLargerThanFrame CSSViewportUnits.MinimumViewportInset CSSViewportUnits.MaximumViewportInset CSSViewportUnits.MinimumViewportInsetWithZoom CSSViewportUnits.MaximumViewportInsetWithZoom CSSViewportUnits.MinimumViewportInsetWithWritingMode CSSViewportUnits.MaximumViewportInsetWithWritingMode CSSViewportUnits.MinimumViewportInsetWithFrame CSSViewportUnits.MaximumViewportInsetWithFrame CSSViewportUnits.MinimumViewportInsetWithBounds CSSViewportUnits.MaximumViewportInsetWithBounds CSSViewportUnits.MinimumViewportInsetWithContentInset CSSViewportUnits.MaximumViewportInsetWithContentInset CSSViewportUnits.MinimumViewportInsetWithSafeAreaInsets CSSViewportUnits.MaximumViewportInsetWithSafeAreaInsets CSSViewportUnits.UnobscuredSizeOverridesIgnoreMaximumViewportInsetAPI * UIProcess/API/Cocoa/WKWebViewInternal.h: * UIProcess/API/Cocoa/WKWebView.h: * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _recalculateViewportSizesWithMinimumViewportInset:maximumViewportInset:throwOnInvalidInput:]): Added. (-[WKWebView setMinimumViewportInset:maximumViewportInset:]): Added. * UIProcess/API/ios/WKWebViewIOS.mm: (-[WKWebView _processWillSwapOrDidExit]): (-[WKWebView _frameOrBoundsChanged]): (-[WKWebView _didCompleteAnimatedResize]): (-[WKWebView _setMinimumUnobscuredSizeOverride:]): (-[WKWebView _setMaximumUnobscuredSizeOverride:]): (-[WKWebView _beginAnimatedResizeWithUpdates:]): (-[WKWebView _dispatchSetMinimumUnobscuredSize:]): Deleted. (-[WKWebView _dispatchSetMaximumUnobscuredSize:]): Deleted. Recalculate the size for CSS "small viewport" `sv*` units whenever the `frame` changes. Also move the deduplication logic that prevents the same value from being sent to the WebProcess more than once to the setter methods on `WebPageProxy` so that it can be used by more than just iOS-only codepaths. * UIProcess/WebPageProxy.h: * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::setDefaultUnobscuredSize): Added. (WebKit::WebPageProxy::setMinimumUnobscuredSize): Added. (WebKit::WebPageProxy::setMaximumUnobscuredSize): Added. (WebKit::WebPageProxy::creationParameters): * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::dynamicViewportSizeUpdate): (WebKit::WebPageProxy::setMinimumUnobscuredSize): Deleted. (WebKit::WebPageProxy::setMaximumUnobscuredSize): Deleted. * Shared/WebPageCreationParameters.h: * Shared/WebPageCreationParameters.cpp: (WebKit::WebPageCreationParameters::encode const): (WebKit::WebPageCreationParameters::decode): * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::WebPage): (WebKit::WebPage::setViewportSizeForCSSViewportUnits): (WebKit::WebPage::setDefaultUnobscuredSize): Added. (WebKit::WebPage::setMinimumUnobscuredSize): Added. (WebKit::WebPage::setMaximumUnobscuredSize): Added. (WebKit::WebPage::updateSizeForCSSDefaultViewportUnits): Added. (WebKit::WebPage::updateSizeForCSSSmallViewportUnits): Added. (WebKit::WebPage::updateSizeForCSSLargeViewportUnits): Added. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::viewportConfigurationChanged): (WebKit::WebPage::setMinimumUnobscuredSize): Deleted. (WebKit::WebPage::setMaximumUnobscuredSize): Deleted. (WebKit::WebPage::updateViewportSizeForCSSViewportUnits): Deleted. Add all the various methods for getting/setting/overriding/clearing an override value for CSS "default viewport" `v*` units. This allows for `WKWebView` clients to preserve existing behavior (where CSS "default viewport" `v*` units match the size of the `WKWebView`) while adding supporting CSS "small viewport" `sv*` units and CSS "large viewport" `lv*` units. Move iOS-only code to be for all platforms. * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: (WebKit::WebFrameLoaderClient::transitionToCommittedForNewPage): Propagate all viewport size overrides when a new `FrameView` is created. Tools: * TestWebKitAPI/Tests/WebKitCocoa/CSSViewportUnits.mm: (TEST.CSSViewportUnits.NegativeMinimumViewportInset): Added. (TEST.CSSViewportUnits.NegativeMaximumViewportInset): Added. (TEST.CSSViewportUnits.MinimumViewportInsetLargerThanMaximumViewportInset): Added. (TEST.CSSViewportUnits.MinimumViewportInsetLargerThanFrame): Added. (TEST.CSSViewportUnits.MaximumViewportInsetLargerThanFrame): Added. (TEST.CSSViewportUnits.MinimumViewportInset): Added. (TEST.CSSViewportUnits.MaximumViewportInset): Added. (TEST.CSSViewportUnits.MinimumViewportInsetWithZoom): Added. (TEST.CSSViewportUnits.MaximumViewportInsetWithZoom): Added. (TEST.CSSViewportUnits.MinimumViewportInsetWithWritingMode): Added. (TEST.CSSViewportUnits.MaximumViewportInsetWithWritingMode): Added. (TEST.CSSViewportUnits.MinimumViewportInsetWithFrame): Added. (TEST.CSSViewportUnits.MaximumViewportInsetWithFrame): Added. (TEST.CSSViewportUnits.MinimumViewportInsetWithBounds): Added. (TEST.CSSViewportUnits.MaximumViewportInsetWithBounds): Added. (TEST.CSSViewportUnits.MinimumViewportInsetWithContentInset): Added. (TEST.CSSViewportUnits.MaximumViewportInsetWithContentInset): Added. (TEST.CSSViewportUnits.MinimumViewportInsetWithSafeAreaInsets): Added. (TEST.CSSViewportUnits.MaximumViewportInsetWithSafeAreaInsets): Added. (TEST.CSSViewportUnits.UnobscuredSizeOverridesIgnoreMaximumViewportInsetAPI): Added.
Modified Paths
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/page/FrameView.cpp
- trunk/Source/WebCore/page/FrameView.h
- trunk/Source/WebKit/ChangeLog
- trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp
- trunk/Source/WebKit/Shared/WebPageCreationParameters.h
- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.h
- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h
- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm
- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
- trunk/Source/WebKit/UIProcess/WebPageProxy.h
- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp
- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h
- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
- trunk/Tools/ChangeLog
- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/CSSViewportUnits.mm
Diff
Modified: trunk/Source/WebCore/ChangeLog (291979 => 291980)
--- trunk/Source/WebCore/ChangeLog 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebCore/ChangeLog 2022-03-28 18:18:47 UTC (rev 291980)
@@ -1,3 +1,48 @@
+2022-03-28 Devin Rousso <drou...@apple.com>
+
+ [iOS] Add `WKWebView` API to control CSS "small viewport" `sv*` and "large viewport" `lv*` units
+ https://bugs.webkit.org/show_bug.cgi?id=237979
+ <rdar://problem/89434696>
+
+ Reviewed by Tim Horton.
+
+ Tests: CSSViewportUnits.NegativeMinimumViewportInset
+ CSSViewportUnits.NegativeMaximumViewportInset
+ CSSViewportUnits.MinimumViewportInsetLargerThanMaximumViewportInset
+ CSSViewportUnits.MinimumViewportInsetLargerThanFrame
+ CSSViewportUnits.MaximumViewportInsetLargerThanFrame
+ CSSViewportUnits.MinimumViewportInset
+ CSSViewportUnits.MaximumViewportInset
+ CSSViewportUnits.MinimumViewportInsetWithZoom
+ CSSViewportUnits.MaximumViewportInsetWithZoom
+ CSSViewportUnits.MinimumViewportInsetWithWritingMode
+ CSSViewportUnits.MaximumViewportInsetWithWritingMode
+ CSSViewportUnits.MinimumViewportInsetWithFrame
+ CSSViewportUnits.MaximumViewportInsetWithFrame
+ CSSViewportUnits.MinimumViewportInsetWithBounds
+ CSSViewportUnits.MaximumViewportInsetWithBounds
+ CSSViewportUnits.MinimumViewportInsetWithContentInset
+ CSSViewportUnits.MaximumViewportInsetWithContentInset
+ CSSViewportUnits.MinimumViewportInsetWithSafeAreaInsets
+ CSSViewportUnits.MaximumViewportInsetWithSafeAreaInsets
+ CSSViewportUnits.UnobscuredSizeOverridesIgnoreMaximumViewportInsetAPI
+
+ * page/FrameView.h:
+ * page/FrameView.cpp:
+ (WebCore::FrameView::performSizeToContentAutoSize):
+ (WebCore::FrameView::enableAutoSizeMode):
+ (WebCore::FrameView::clearSizeOverrideForCSSDefaultViewportUnits): Added.
+ (WebCore::FrameView::setSizeForCSSDefaultViewportUnits): Added.
+ (WebCore::FrameView::overrideWidthForCSSDefaultViewportUnits): Added.
+ (WebCore::FrameView::resetOverriddenWidthForCSSDefaultViewportUnits): Added.
+ (WebCore::FrameView::overrideSizeForCSSDefaultViewportUnits): Added.
+ (WebCore::FrameView::sizeForCSSDefaultViewportUnits const): Renamed from `sizeForCSSDefaultViewportUnits`.
+ (WebCore::FrameView::copyCSSViewportUnits const): Added.
+ Add all the various methods for getting/setting/overriding/clearing an override value for
+ CSS "default viewport" `v*` units. This allows for `WKWebView` clients to preserve existing
+ behavior (where CSS "default viewport" `v*` units match the size of the `WKWebView`) while
+ adding supporting CSS "small viewport" `sv*` units and CSS "large viewport" `lv*` units.
+
2022-03-28 Brady Eidson <beid...@apple.com>
Support ServiceWorkerClients.openWindow.
Modified: trunk/Source/WebCore/page/FrameView.cpp (291979 => 291980)
--- trunk/Source/WebCore/page/FrameView.cpp 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebCore/page/FrameView.cpp 2022-03-28 18:18:47 UTC (rev 291980)
@@ -3624,6 +3624,7 @@
document.updateLayout();
};
+ resetOverriddenWidthForCSSDefaultViewportUnits();
resetOverriddenWidthForCSSSmallViewportUnits();
resetOverriddenWidthForCSSLargeViewportUnits();
@@ -3686,6 +3687,7 @@
resize(newSize.width(), i ? newSize.height() : minAutoSize.height());
// Protect the content from evergrowing layout.
auto preferredViewportWidth = std::min(newSize.width(), m_autoSizeConstraint.width());
+ overrideWidthForCSSDefaultViewportUnits(preferredViewportWidth);
overrideWidthForCSSSmallViewportUnits(preferredViewportWidth);
overrideWidthForCSSLargeViewportUnits(preferredViewportWidth);
// Force the scrollbar state to avoid the scrollbar code adding them and causing them to be needed. For example,
@@ -4767,11 +4769,13 @@
setNeedsLayoutAfterViewConfigurationChange();
layoutContext().scheduleLayout();
if (m_shouldAutoSize) {
+ overrideWidthForCSSDefaultViewportUnits(m_autoSizeConstraint.width());
overrideWidthForCSSSmallViewportUnits(m_autoSizeConstraint.width());
overrideWidthForCSSLargeViewportUnits(m_autoSizeConstraint.width());
return;
}
+ clearSizeOverrideForCSSDefaultViewportUnits();
clearSizeOverrideForCSSSmallViewportUnits();
clearSizeOverrideForCSSLargeViewportUnits();
// Since autosize mode forces the scrollbar mode, change them to being auto.
@@ -5602,6 +5606,47 @@
}
}
+void FrameView::clearSizeOverrideForCSSDefaultViewportUnits()
+{
+ if (!m_defaultViewportSizeOverride)
+ return;
+
+ m_defaultViewportSizeOverride = std::nullopt;
+ if (auto* document = frame().document())
+ document->styleScope().didChangeStyleSheetEnvironment();
+}
+
+void FrameView::setSizeForCSSDefaultViewportUnits(FloatSize size)
+{
+ overrideSizeForCSSDefaultViewportUnits({ size.width(), size.height() });
+}
+
+void FrameView::overrideWidthForCSSDefaultViewportUnits(float width)
+{
+ overrideSizeForCSSDefaultViewportUnits({ width, m_defaultViewportSizeOverride ? m_defaultViewportSizeOverride->height : std::nullopt });
+}
+
+void FrameView::resetOverriddenWidthForCSSDefaultViewportUnits()
+{
+ overrideSizeForCSSDefaultViewportUnits({ { }, m_defaultViewportSizeOverride ? m_defaultViewportSizeOverride->height : std::nullopt });
+}
+
+void FrameView::overrideSizeForCSSDefaultViewportUnits(OverrideViewportSize size)
+{
+ if (m_defaultViewportSizeOverride == size)
+ return;
+
+ m_defaultViewportSizeOverride = size;
+
+ if (auto* document = frame().document())
+ document->styleScope().didChangeStyleSheetEnvironment();
+}
+
+FloatSize FrameView::sizeForCSSDefaultViewportUnits() const
+{
+ return calculateSizeForCSSViewportUnitsOverride(m_defaultViewportSizeOverride);
+}
+
void FrameView::clearSizeOverrideForCSSSmallViewportUnits()
{
if (!m_smallViewportSizeOverride)
@@ -5716,9 +5761,11 @@
return rectForFixedPositionLayout().size();
}
-FloatSize FrameView::sizeForCSSDefaultViewportUnits() const
+void FrameView::copyCSSViewportSizeOverrides(FrameView& view)
{
- return sizeForCSSLargeViewportUnits();
+ m_defaultViewportSizeOverride = view.m_defaultViewportSizeOverride;
+ m_smallViewportSizeOverride = view.m_smallViewportSizeOverride;
+ m_largeViewportSizeOverride = view.m_largeViewportSizeOverride;
}
bool FrameView::shouldPlaceVerticalScrollbarOnLeft() const
Modified: trunk/Source/WebCore/page/FrameView.h (291979 => 291980)
--- trunk/Source/WebCore/page/FrameView.h 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebCore/page/FrameView.h 2022-03-28 18:18:47 UTC (rev 291980)
@@ -228,6 +228,10 @@
WEBCORE_EXPORT void adjustViewSize();
+ WEBCORE_EXPORT void setSizeForCSSDefaultViewportUnits(FloatSize);
+ void clearSizeOverrideForCSSDefaultViewportUnits();
+ FloatSize sizeForCSSDefaultViewportUnits() const;
+
WEBCORE_EXPORT void setSizeForCSSSmallViewportUnits(FloatSize);
void clearSizeOverrideForCSSSmallViewportUnits();
FloatSize sizeForCSSSmallViewportUnits() const;
@@ -238,7 +242,7 @@
FloatSize sizeForCSSDynamicViewportUnits() const;
- FloatSize sizeForCSSDefaultViewportUnits() const;
+ WEBCORE_EXPORT void copyCSSViewportSizeOverrides(FrameView&);
IntRect windowClipRect() const final;
WEBCORE_EXPORT IntRect windowClipRectForFrameOwner(const HTMLFrameOwnerElement*, bool clipToLayerContents) const;
@@ -867,6 +871,10 @@
};
FloatSize calculateSizeForCSSViewportUnitsOverride(std::optional<OverrideViewportSize>) const;
+ void overrideSizeForCSSDefaultViewportUnits(OverrideViewportSize);
+ void overrideWidthForCSSDefaultViewportUnits(float);
+ void resetOverriddenWidthForCSSDefaultViewportUnits();
+
void overrideSizeForCSSSmallViewportUnits(OverrideViewportSize);
void overrideWidthForCSSSmallViewportUnits(float);
void resetOverriddenWidthForCSSSmallViewportUnits();
@@ -944,6 +952,7 @@
std::optional<IntSize> m_customSizeForResizeEvent;
#endif
+ std::optional<OverrideViewportSize> m_defaultViewportSizeOverride;
std::optional<OverrideViewportSize> m_smallViewportSizeOverride;
std::optional<OverrideViewportSize> m_largeViewportSizeOverride;
Modified: trunk/Source/WebKit/ChangeLog (291979 => 291980)
--- trunk/Source/WebKit/ChangeLog 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/ChangeLog 2022-03-28 18:18:47 UTC (rev 291980)
@@ -1,3 +1,129 @@
+2022-03-28 Devin Rousso <drou...@apple.com>
+
+ [iOS] Add `WKWebView` API to control CSS "small viewport" `sv*` and "large viewport" `lv*` units
+ https://bugs.webkit.org/show_bug.cgi?id=237979
+ <rdar://problem/89434696>
+
+ Reviewed by Tim Horton.
+
+ Recently the W3C CSS working group added [some new unit types to CSS](https://drafts.csswg.org/css-values-4/#viewport-variants)
+ with the goal of helping web developers better deal with browsers that have dynamic UI
+ elements that change apperance/size/etc. based on user actions (e.g. the URL bar
+ collapsing/"squishing" and expanding/"unsquishing" depending on whether the user has most
+ recently scrolled/swiped down the page).
+
+ These new units come in three categories:
+ - the "large viewport" units (`lvw`, `lvh`, etc.) each represent 1% of one dimension of the
+ size of the visual area of the page when all browser UI elements are in their smallest
+ state (e.g. when the URL bar is collapsed/"squished")
+ - the "small viewport" units (`svw`, `svh`, etc.) each represent 1% of one dimension of the
+ size of the visual area of the page when all browser UI elements are in their largest
+ state (e.g. when the URL bar is expanded/"unsquished")
+ - the "dynamic viewport" units (`dvw`, `dvh`, etc.) each represent 1% of one dimension of
+ the size of the current visual area of the page, which depends on the current state of all
+ browser UI elements
+
+ This way, developer could use `100svh` to ensure that no matter what state the browser UI
+ elements are in the entire element will always be visible on the screen, or use `100dvh` to
+ respond to browser UI element changes by automatically resizing various elements to always
+ fully take advantage of the available space.
+
+ Nothing needs to be added to support "dynamic viewport" `dv*` units as there already exists
+ other methods to adjust the visual area of the `WKWebView` without adjusting its `frame`
+ (e.g. `-[WKWebView setBounds:]`, `-[UIScrollView setContentInset:]`, etc.).
+
+ But for "small viewport" `sv*` units and "large viewport" `lv*` units, however, there is
+ unfortunately no way to tell a `WKWebView` anything like "this is the smallest/largest that
+ this `WKWebView` will ever be", so there's no way to know ahead of time what the size of the
+ visual area would be when all browser UI elements are in their smallest/largest state. As
+ such, this patch adds a new API to allow for `WKWebView` clients to tell WebKit this
+ information ahead of time.
+
+ Note that there already exists the concept of "default viewport" units (`vw`, `vh`, etc.)
+ that each represent 1% of one dimension of the size of the visual area of the page when all
+ browser UI elements are in their default state. The behavior of these units remain the same,
+ and the value can be changed via the existing `-[WKWebView setFrame:]`.
+
+ Tests: CSSViewportUnits.NegativeMinimumViewportInset
+ CSSViewportUnits.NegativeMaximumViewportInset
+ CSSViewportUnits.MinimumViewportInsetLargerThanMaximumViewportInset
+ CSSViewportUnits.MinimumViewportInsetLargerThanFrame
+ CSSViewportUnits.MaximumViewportInsetLargerThanFrame
+ CSSViewportUnits.MinimumViewportInset
+ CSSViewportUnits.MaximumViewportInset
+ CSSViewportUnits.MinimumViewportInsetWithZoom
+ CSSViewportUnits.MaximumViewportInsetWithZoom
+ CSSViewportUnits.MinimumViewportInsetWithWritingMode
+ CSSViewportUnits.MaximumViewportInsetWithWritingMode
+ CSSViewportUnits.MinimumViewportInsetWithFrame
+ CSSViewportUnits.MaximumViewportInsetWithFrame
+ CSSViewportUnits.MinimumViewportInsetWithBounds
+ CSSViewportUnits.MaximumViewportInsetWithBounds
+ CSSViewportUnits.MinimumViewportInsetWithContentInset
+ CSSViewportUnits.MaximumViewportInsetWithContentInset
+ CSSViewportUnits.MinimumViewportInsetWithSafeAreaInsets
+ CSSViewportUnits.MaximumViewportInsetWithSafeAreaInsets
+ CSSViewportUnits.UnobscuredSizeOverridesIgnoreMaximumViewportInsetAPI
+
+ * UIProcess/API/Cocoa/WKWebViewInternal.h:
+ * UIProcess/API/Cocoa/WKWebView.h:
+ * UIProcess/API/Cocoa/WKWebView.mm:
+ (-[WKWebView _recalculateViewportSizesWithMinimumViewportInset:maximumViewportInset:throwOnInvalidInput:]): Added.
+ (-[WKWebView setMinimumViewportInset:maximumViewportInset:]): Added.
+ * UIProcess/API/ios/WKWebViewIOS.mm:
+ (-[WKWebView _processWillSwapOrDidExit]):
+ (-[WKWebView _frameOrBoundsChanged]):
+ (-[WKWebView _didCompleteAnimatedResize]):
+ (-[WKWebView _setMinimumUnobscuredSizeOverride:]):
+ (-[WKWebView _setMaximumUnobscuredSizeOverride:]):
+ (-[WKWebView _beginAnimatedResizeWithUpdates:]):
+ (-[WKWebView _dispatchSetMinimumUnobscuredSize:]): Deleted.
+ (-[WKWebView _dispatchSetMaximumUnobscuredSize:]): Deleted.
+ Recalculate the size for CSS "small viewport" `sv*` units whenever the `frame` changes. Also
+ move the deduplication logic that prevents the same value from being sent to the WebProcess
+ more than once to the setter methods on `WebPageProxy` so that it can be used by more than
+ just iOS-only codepaths.
+
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::setDefaultUnobscuredSize): Added.
+ (WebKit::WebPageProxy::setMinimumUnobscuredSize): Added.
+ (WebKit::WebPageProxy::setMaximumUnobscuredSize): Added.
+ (WebKit::WebPageProxy::creationParameters):
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::dynamicViewportSizeUpdate):
+ (WebKit::WebPageProxy::setMinimumUnobscuredSize): Deleted.
+ (WebKit::WebPageProxy::setMaximumUnobscuredSize): Deleted.
+ * Shared/WebPageCreationParameters.h:
+ * Shared/WebPageCreationParameters.cpp:
+ (WebKit::WebPageCreationParameters::encode const):
+ (WebKit::WebPageCreationParameters::decode):
+ * WebProcess/WebPage/WebPage.messages.in:
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::WebPage):
+ (WebKit::WebPage::setViewportSizeForCSSViewportUnits):
+ (WebKit::WebPage::setDefaultUnobscuredSize): Added.
+ (WebKit::WebPage::setMinimumUnobscuredSize): Added.
+ (WebKit::WebPage::setMaximumUnobscuredSize): Added.
+ (WebKit::WebPage::updateSizeForCSSDefaultViewportUnits): Added.
+ (WebKit::WebPage::updateSizeForCSSSmallViewportUnits): Added.
+ (WebKit::WebPage::updateSizeForCSSLargeViewportUnits): Added.
+ * WebProcess/WebPage/ios/WebPageIOS.mm:
+ (WebKit::WebPage::viewportConfigurationChanged):
+ (WebKit::WebPage::setMinimumUnobscuredSize): Deleted.
+ (WebKit::WebPage::setMaximumUnobscuredSize): Deleted.
+ (WebKit::WebPage::updateViewportSizeForCSSViewportUnits): Deleted.
+ Add all the various methods for getting/setting/overriding/clearing an override value for
+ CSS "default viewport" `v*` units. This allows for `WKWebView` clients to preserve existing
+ behavior (where CSS "default viewport" `v*` units match the size of the `WKWebView`) while
+ adding supporting CSS "small viewport" `sv*` units and CSS "large viewport" `lv*` units.
+ Move iOS-only code to be for all platforms.
+
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+ (WebKit::WebFrameLoaderClient::transitionToCommittedForNewPage):
+ Propagate all viewport size overrides when a new `FrameView` is created.
+
2022-03-28 Brady Eidson <beid...@apple.com>
Support ServiceWorkerClients.openWindow.
Modified: trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp (291979 => 291980)
--- trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp 2022-03-28 18:18:47 UTC (rev 291980)
@@ -44,6 +44,9 @@
encoder << underlayColor;
encoder << useFixedLayout;
encoder << fixedLayoutSize;
+ encoder << defaultUnobscuredSize;
+ encoder << minimumUnobscuredSize;
+ encoder << maximumUnobscuredSize;
encoder << viewExposedRect;
encoder << alwaysShowsHorizontalScroller;
encoder << alwaysShowsVerticalScroller;
@@ -102,8 +105,6 @@
encoder << availableScreenSize;
encoder << overrideScreenSize;
encoder << textAutosizingWidth;
- encoder << minimumUnobscuredSize;
- encoder << maximumUnobscuredSize;
encoder << deviceOrientation;
encoder << keyboardIsAttached;
encoder << canShowWhileLocked;
@@ -225,6 +226,12 @@
return std::nullopt;
if (!decoder.decode(parameters.fixedLayoutSize))
return std::nullopt;
+ if (!decoder.decode(parameters.defaultUnobscuredSize))
+ return std::nullopt;
+ if (!decoder.decode(parameters.minimumUnobscuredSize))
+ return std::nullopt;
+ if (!decoder.decode(parameters.maximumUnobscuredSize))
+ return std::nullopt;
if (!decoder.decode(parameters.viewExposedRect))
return std::nullopt;
if (!decoder.decode(parameters.alwaysShowsHorizontalScroller))
@@ -366,10 +373,6 @@
return std::nullopt;
if (!decoder.decode(parameters.textAutosizingWidth))
return std::nullopt;
- if (!decoder.decode(parameters.minimumUnobscuredSize))
- return std::nullopt;
- if (!decoder.decode(parameters.maximumUnobscuredSize))
- return std::nullopt;
if (!decoder.decode(parameters.deviceOrientation))
return std::nullopt;
if (!decoder.decode(parameters.keyboardIsAttached))
Modified: trunk/Source/WebKit/Shared/WebPageCreationParameters.h (291979 => 291980)
--- trunk/Source/WebKit/Shared/WebPageCreationParameters.h 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/Shared/WebPageCreationParameters.h 2022-03-28 18:18:47 UTC (rev 291980)
@@ -84,6 +84,10 @@
bool useFixedLayout;
WebCore::IntSize fixedLayoutSize;
+ WebCore::FloatSize defaultUnobscuredSize;
+ WebCore::FloatSize minimumUnobscuredSize;
+ WebCore::FloatSize maximumUnobscuredSize;
+
std::optional<WebCore::FloatRect> viewExposedRect;
bool alwaysShowsHorizontalScroller;
@@ -162,8 +166,6 @@
WebCore::FloatSize availableScreenSize;
WebCore::FloatSize overrideScreenSize;
float textAutosizingWidth;
- WebCore::FloatSize minimumUnobscuredSize;
- WebCore::FloatSize maximumUnobscuredSize;
int32_t deviceOrientation { 0 };
bool keyboardIsAttached { false };
bool canShowWhileLocked { false };
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.h (291979 => 291980)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.h 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.h 2022-03-28 18:18:47 UTC (rev 291980)
@@ -621,6 +621,25 @@
*/
@property (nonatomic, readonly) WKFullscreenState fullscreenState WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+/*! @abstract Insets from the @link frame @/link that represent the smallest and largest possible size of the
+ visual area of the @link WKWebView @/link based on the state of the surrounding UI.
+ @discussion For apps with size-changing UI around the @link WKWebView @/link, specify minimumViewportInset and
+ maximumViewportInset to supply webpages with the appropriate value for CSS "large viewport" `lv*`
+ units and CSS "small viewport" `sv*` units respectively @link https://www.w3.org/TR/css-values-4/#viewport-variants @/link.
+ Set minimumViewportInset to the smallest inset a webpage may experience in your app's maximally
+ collapsed UI configuration. Set maximumViewportInset to the largest inset a webpage may experience
+ in your app's maximally expanded UI configuration. For apps where the maximally collapsed UI
+ configuration is such that the @link WKWebView @/link is not surrounded by anything, there is no need to specify
+ minimumViewportInset. For apps with fixed-sized UI surrounding the @link WKWebView @/link, there is no need to
+ specify either value. Both values must be either zero or positive, and maximumViewportInset must be
+ larger than minimumViewportInset.
+ */
+#if TARGET_OS_IPHONE
+@property (nonatomic, readonly) UIEdgeInsets minimumViewportInset WK_API_AVAILABLE(ios(WK_IOS_TBA));
+@property (nonatomic, readonly) UIEdgeInsets maximumViewportInset WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)setMinimumViewportInset:(UIEdgeInsets)minimumViewportInset maximumViewportInset:(UIEdgeInsets)maximumViewportInset WK_API_AVAILABLE(ios(WK_IOS_TBA));
+#endif
+
@end
#if !TARGET_OS_IPHONE
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (291979 => 291980)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2022-03-28 18:18:47 UTC (rev 291980)
@@ -1549,6 +1549,41 @@
});
}
+- (void)_recalculateViewportSizesWithMinimumViewportInset:(CocoaEdgeInsets)minimumViewportInset maximumViewportInset:(CocoaEdgeInsets)maximumViewportInset throwOnInvalidInput:(BOOL)throwOnInvalidInput
+{
+ auto frame = WebCore::FloatSize(self.frame.size);
+
+ auto minimumUnobscuredSize = frame - WebCore::FloatSize(maximumViewportInset.left + maximumViewportInset.right, maximumViewportInset.top + maximumViewportInset.bottom);
+ if (minimumUnobscuredSize.isEmpty()) {
+ if (throwOnInvalidInput) {
+ [NSException raise:NSInvalidArgumentException format:@"maximumViewportInset cannot be larger than frame"];
+ return;
+ }
+
+ RELEASE_LOG_ERROR(ViewportSizing, "maximumViewportInset cannot be larger than frame");
+ minimumUnobscuredSize = frame;
+ }
+
+ auto maximumUnobscuredSize = frame - WebCore::FloatSize(minimumViewportInset.left + minimumViewportInset.right, minimumViewportInset.top + minimumViewportInset.bottom);
+ if (maximumUnobscuredSize.isEmpty()) {
+ if (throwOnInvalidInput) {
+ [NSException raise:NSInvalidArgumentException format:@"minimumViewportInset cannot be larger than frame"];
+ return;
+ }
+
+ RELEASE_LOG_ERROR(ViewportSizing, "minimumViewportInset cannot be larger than frame");
+ maximumUnobscuredSize = frame;
+ }
+
+#if PLATFORM(IOS_FAMILY)
+ if (_viewLayoutSizeOverride || _minimumUnobscuredSizeOverride || _maximumUnobscuredSizeOverride)
+ return;
+#endif
+
+ _page->setMinimumUnobscuredSize(minimumUnobscuredSize);
+ _page->setMaximumUnobscuredSize(maximumUnobscuredSize);
+}
+
#if ENABLE(ATTACHMENT_ELEMENT)
- (void)_didInsertAttachment:(API::Attachment&)attachment withSource:(NSString *)source
@@ -1830,6 +1865,27 @@
#endif
}
+#if PLATFORM(IOS_FAMILY)
+
+- (void)setMinimumViewportInset:(CocoaEdgeInsets)minimumViewportInset maximumViewportInset:(CocoaEdgeInsets)maximumViewportInset
+{
+ if (minimumViewportInset.top < 0 || minimumViewportInset.left < 0 || minimumViewportInset.bottom < 0 || minimumViewportInset.right < 0)
+ [NSException raise:NSInvalidArgumentException format:@"minimumViewportInset cannot be negative"];
+
+ if (maximumViewportInset.top < 0 || maximumViewportInset.left < 0 || maximumViewportInset.bottom < 0 || maximumViewportInset.right < 0)
+ [NSException raise:NSInvalidArgumentException format:@"maximumViewportInset cannot be negative"];
+
+ if (minimumViewportInset.top + minimumViewportInset.bottom > maximumViewportInset.top + maximumViewportInset.bottom || minimumViewportInset.right + minimumViewportInset.left > maximumViewportInset.right + maximumViewportInset.left)
+ [NSException raise:NSInvalidArgumentException format:@"minimumViewportInset cannot be larger than maximumViewportInset"];
+
+ [self _recalculateViewportSizesWithMinimumViewportInset:minimumViewportInset maximumViewportInset:maximumViewportInset throwOnInvalidInput:YES];
+
+ _minimumViewportInset = minimumViewportInset;
+ _maximumViewportInset = maximumViewportInset;
+}
+
+#endif // PLATFORM(IOS_FAMILY)
+
@end
#pragma mark -
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h (291979 => 291980)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h 2022-03-28 18:18:47 UTC (rev 291980)
@@ -59,6 +59,14 @@
#define WK_WEB_VIEW_PROTOCOLS
#endif
+#if USE(APPKIT)
+using CocoaEdgeInsets = NSEdgeInsets;
+#endif
+
+#if PLATFORM(IOS_FAMILY)
+using CocoaEdgeInsets = UIEdgeInsets;
+#endif
+
typedef const struct OpaqueWKPage* WKPageRef;
namespace API {
@@ -132,6 +140,11 @@
_WKRenderingProgressEvents _observedRenderingProgressEvents;
BOOL _usePlatformFindUI;
+#if PLATFORM(IOS_FAMILY)
+ CocoaEdgeInsets _minimumViewportInset;
+ CocoaEdgeInsets _maximumViewportInset;
+#endif
+
#if PLATFORM(MAC)
std::unique_ptr<WebKit::WebViewImpl> _impl;
RetainPtr<WKTextFinderClient> _textFinderClient;
@@ -161,9 +174,7 @@
std::optional<CGSize> _viewLayoutSizeOverride;
std::optional<WebCore::FloatSize> _lastSentViewLayoutSize;
std::optional<CGSize> _minimumUnobscuredSizeOverride;
- std::optional<WebCore::FloatSize> _lastSentMinimumUnobscuredSize;
std::optional<CGSize> _maximumUnobscuredSizeOverride;
- std::optional<WebCore::FloatSize> _lastSentMaximumUnobscuredSize;
CGRect _inputViewBoundsInWindow;
CGFloat _viewportMetaTagWidth;
@@ -283,6 +294,8 @@
- (void)_internalDoAfterNextPresentationUpdate:(void (^)(void))updateBlock withoutWaitingForPainting:(BOOL)withoutWaitingForPainting withoutWaitingForAnimatedResize:(BOOL)withoutWaitingForAnimatedResize;
+- (void)_recalculateViewportSizesWithMinimumViewportInset:(CocoaEdgeInsets)minimumViewportInset maximumViewportInset:(CocoaEdgeInsets)maximumViewportInset throwOnInvalidInput:(BOOL)throwOnInvalidInput;
+
- (void)_showSafeBrowsingWarning:(const WebKit::SafeBrowsingWarning&)warning completionHandler:(CompletionHandler<void(std::variant<WebKit::ContinueUnsafeLoad, URL>&&)>&&)completionHandler;
- (void)_clearSafeBrowsingWarning;
- (void)_clearSafeBrowsingWarningIfForMainFrameNavigation;
Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm (291979 => 291980)
--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2022-03-28 18:18:47 UTC (rev 291980)
@@ -725,8 +725,6 @@
_didDeferUpdateVisibleContentRectsForUnstableScrollView = NO;
_currentlyAdjustingScrollViewInsetsForKeyboard = NO;
_lastSentViewLayoutSize = std::nullopt;
- _lastSentMinimumUnobscuredSize = std::nullopt;
- _lastSentMaximumUnobscuredSize = std::nullopt;
_lastSentDeviceOrientation = std::nullopt;
_frozenVisibleContentRect = std::nullopt;
@@ -1943,24 +1941,6 @@
_lastSentViewLayoutSize = viewLayoutSize;
}
-- (void)_dispatchSetMinimumUnobscuredSize:(WebCore::FloatSize)minimumUnobscuredSize
-{
- if (_lastSentMinimumUnobscuredSize && CGSizeEqualToSize(_lastSentMinimumUnobscuredSize.value(), minimumUnobscuredSize))
- return;
-
- _page->setMinimumUnobscuredSize(minimumUnobscuredSize);
- _lastSentMinimumUnobscuredSize = minimumUnobscuredSize;
-}
-
-- (void)_dispatchSetMaximumUnobscuredSize:(WebCore::FloatSize)maximumUnobscuredSize
-{
- if (_lastSentMaximumUnobscuredSize && CGSizeEqualToSize(_lastSentMaximumUnobscuredSize.value(), maximumUnobscuredSize))
- return;
-
- _page->setMaximumUnobscuredSize(maximumUnobscuredSize);
- _lastSentMaximumUnobscuredSize = maximumUnobscuredSize;
-}
-
- (void)_dispatchSetDeviceOrientation:(int32_t)deviceOrientation
{
if (_lastSentDeviceOrientation && _lastSentDeviceOrientation.value() == deviceOrientation)
@@ -1987,10 +1967,9 @@
if (_dynamicViewportUpdateMode == WebKit::DynamicViewportUpdateMode::NotResizing) {
if (!_viewLayoutSizeOverride)
[self _dispatchSetViewLayoutSize:[self activeViewLayoutSize:self.bounds]];
- if (!_minimumUnobscuredSizeOverride)
- [self _dispatchSetMinimumUnobscuredSize:WebCore::FloatSize(bounds.size)];
if (!_maximumUnobscuredSizeOverride)
- [self _dispatchSetMaximumUnobscuredSize:WebCore::FloatSize(bounds.size)];
+ _page->setDefaultUnobscuredSize(WebCore::FloatSize(bounds.size));
+ [self _recalculateViewportSizesWithMinimumViewportInset:_minimumViewportInset maximumViewportInset:_maximumViewportInset throwOnInvalidInput:NO];
BOOL sizeChanged = NO;
if (_page) {
@@ -2441,12 +2420,14 @@
if (!_lastSentViewLayoutSize || newViewLayoutSize != _lastSentViewLayoutSize.value())
[self _dispatchSetViewLayoutSize:newViewLayoutSize];
- if (!_lastSentMinimumUnobscuredSize || newMinimumUnobscuredSize != _lastSentMinimumUnobscuredSize.value())
- [self _dispatchSetMinimumUnobscuredSize:WebCore::FloatSize(newMinimumUnobscuredSize)];
+ if (_minimumUnobscuredSizeOverride)
+ _page->setMinimumUnobscuredSize(WebCore::FloatSize(newMinimumUnobscuredSize));
+ if (_maximumUnobscuredSizeOverride) {
+ _page->setDefaultUnobscuredSize(WebCore::FloatSize(newMaximumUnobscuredSize));
+ _page->setMaximumUnobscuredSize(WebCore::FloatSize(newMaximumUnobscuredSize));
+ }
+ [self _recalculateViewportSizesWithMinimumViewportInset:_minimumViewportInset maximumViewportInset:_maximumViewportInset throwOnInvalidInput:NO];
- if (!_lastSentMaximumUnobscuredSize || newMaximumUnobscuredSize != _lastSentMaximumUnobscuredSize.value())
- [self _dispatchSetMaximumUnobscuredSize:WebCore::FloatSize(newMaximumUnobscuredSize)];
-
if (!_lastSentDeviceOrientation || newOrientation != _lastSentDeviceOrientation.value())
[self _dispatchSetDeviceOrientation:newOrientation];
@@ -2832,7 +2813,7 @@
_minimumUnobscuredSizeOverride = size;
if (_dynamicViewportUpdateMode == WebKit::DynamicViewportUpdateMode::NotResizing)
- [self _dispatchSetMinimumUnobscuredSize:WebCore::FloatSize(size)];
+ _page->setMinimumUnobscuredSize(WebCore::FloatSize(size));
}
// Deprecated SPI
@@ -2847,8 +2828,10 @@
ASSERT(size.width <= self.bounds.size.width && size.height <= self.bounds.size.height);
_maximumUnobscuredSizeOverride = size;
- if (_dynamicViewportUpdateMode == WebKit::DynamicViewportUpdateMode::NotResizing)
- [self _dispatchSetMaximumUnobscuredSize:WebCore::FloatSize(size)];
+ if (_dynamicViewportUpdateMode == WebKit::DynamicViewportUpdateMode::NotResizing) {
+ _page->setDefaultUnobscuredSize(WebCore::FloatSize(size));
+ _page->setMaximumUnobscuredSize(WebCore::FloatSize(size));
+ }
}
- (UIEdgeInsets)_obscuredInsets
@@ -3190,9 +3173,11 @@
if (_viewLayoutSizeOverride)
[self _dispatchSetViewLayoutSize:newViewLayoutSize];
if (_minimumUnobscuredSizeOverride)
- [self _dispatchSetMinimumUnobscuredSize:WebCore::FloatSize(newMinimumUnobscuredSize)];
- if (_maximumUnobscuredSizeOverride)
- [self _dispatchSetMaximumUnobscuredSize:WebCore::FloatSize(newMaximumUnobscuredSize)];
+ _page->setMinimumUnobscuredSize(WebCore::FloatSize(newMinimumUnobscuredSize));
+ if (_maximumUnobscuredSizeOverride) {
+ _page->setDefaultUnobscuredSize(WebCore::FloatSize(newMaximumUnobscuredSize));
+ _page->setMaximumUnobscuredSize(WebCore::FloatSize(newMaximumUnobscuredSize));
+ }
if (_overridesInterfaceOrientation)
[self _dispatchSetDeviceOrientation:newOrientation];
@@ -3269,8 +3254,6 @@
WebCore::FloatBoxExtent unobscuredSafeAreaInsetsExtent(unobscuredSafeAreaInsets.top, unobscuredSafeAreaInsets.right, unobscuredSafeAreaInsets.bottom, unobscuredSafeAreaInsets.left);
_lastSentViewLayoutSize = newViewLayoutSize;
- _lastSentMinimumUnobscuredSize = newMinimumUnobscuredSize;
- _lastSentMaximumUnobscuredSize = newMaximumUnobscuredSize;
_lastSentDeviceOrientation = newOrientation;
_page->dynamicViewportSizeUpdate(newViewLayoutSize, newMinimumUnobscuredSize, newMaximumUnobscuredSize, visibleRectInContentCoordinates, unobscuredRectInContentCoordinates, futureUnobscuredRectInSelfCoordinates, unobscuredSafeAreaInsetsExtent, targetScale, newOrientation, newMinimumEffectiveDeviceWidth, ++_currentDynamicViewportSizeUpdateID);
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (291979 => 291980)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2022-03-28 18:18:47 UTC (rev 291980)
@@ -4079,6 +4079,45 @@
send(Messages::WebPage::SetFixedLayoutSize(size));
}
+void WebPageProxy::setDefaultUnobscuredSize(const FloatSize& size)
+{
+ if (size == m_defaultUnobscuredSize)
+ return;
+
+ m_defaultUnobscuredSize = size;
+
+ if (!hasRunningProcess())
+ return;
+
+ send(Messages::WebPage::SetDefaultUnobscuredSize(m_defaultUnobscuredSize));
+}
+
+void WebPageProxy::setMinimumUnobscuredSize(const FloatSize& size)
+{
+ if (size == m_minimumUnobscuredSize)
+ return;
+
+ m_minimumUnobscuredSize = size;
+
+ if (!hasRunningProcess())
+ return;
+
+ send(Messages::WebPage::SetMinimumUnobscuredSize(m_minimumUnobscuredSize));
+}
+
+void WebPageProxy::setMaximumUnobscuredSize(const FloatSize& size)
+{
+ if (size == m_maximumUnobscuredSize)
+ return;
+
+ m_maximumUnobscuredSize = size;
+
+ if (!hasRunningProcess())
+ return;
+
+ send(Messages::WebPage::SetMaximumUnobscuredSize(m_maximumUnobscuredSize));
+}
+
void WebPageProxy::setViewExposedRect(std::optional<WebCore::FloatRect> viewExposedRect)
{
if (m_viewExposedRect == viewExposedRect)
@@ -8289,6 +8328,9 @@
parameters.underlayColor = m_underlayColor;
parameters.useFixedLayout = m_useFixedLayout;
parameters.fixedLayoutSize = m_fixedLayoutSize;
+ parameters.defaultUnobscuredSize = m_defaultUnobscuredSize;
+ parameters.minimumUnobscuredSize = m_minimumUnobscuredSize;
+ parameters.maximumUnobscuredSize = m_maximumUnobscuredSize;
parameters.viewExposedRect = m_viewExposedRect;
parameters.alwaysShowsHorizontalScroller = m_alwaysShowsHorizontalScroller;
parameters.alwaysShowsVerticalScroller = m_alwaysShowsVerticalScroller;
@@ -8347,8 +8389,6 @@
parameters.overrideScreenSize = overrideScreenSize();
parameters.textAutosizingWidth = textAutosizingWidth();
parameters.mimeTypesWithCustomContentProviders = pageClient().mimeTypesWithCustomContentProviders();
- parameters.minimumUnobscuredSize = m_minimumUnobscuredSize;
- parameters.maximumUnobscuredSize = m_maximumUnobscuredSize;
parameters.deviceOrientation = m_deviceOrientation;
parameters.keyboardIsAttached = isInHardwareKeyboardMode();
parameters.canShowWhileLocked = m_configuration->canShowWhileLocked();
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (291979 => 291980)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2022-03-28 18:18:47 UTC (rev 291980)
@@ -851,10 +851,6 @@
void dynamicViewportSizeUpdate(const WebCore::FloatSize& viewLayoutSize, const WebCore::FloatSize& minimumUnobscuredSize, 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, double minimumEffectiveDeviceWidth, DynamicViewportSizeUpdateID);
void setViewportConfigurationViewLayoutSize(const WebCore::FloatSize&, double scaleFactor, double minimumEffectiveDeviceWidth);
- void setMinimumUnobscuredSize(const WebCore::FloatSize&);
- WebCore::FloatSize minimumUnobscuredSize() const { return m_minimumUnobscuredSize; }
- void setMaximumUnobscuredSize(const WebCore::FloatSize&);
- WebCore::FloatSize maximumUnobscuredSize() const { return m_maximumUnobscuredSize; }
void setDeviceOrientation(int32_t);
int32_t deviceOrientation() const { return m_deviceOrientation; }
void setOverrideViewportArguments(const std::optional<WebCore::ViewportArguments>&);
@@ -1122,6 +1118,13 @@
bool useFixedLayout() const { return m_useFixedLayout; };
const WebCore::IntSize& fixedLayoutSize() const { return m_fixedLayoutSize; };
+ void setDefaultUnobscuredSize(const WebCore::FloatSize&);
+ WebCore::FloatSize defaultUnobscuredSize() const { return m_defaultUnobscuredSize; }
+ void setMinimumUnobscuredSize(const WebCore::FloatSize&);
+ WebCore::FloatSize minimumUnobscuredSize() const { return m_minimumUnobscuredSize; }
+ void setMaximumUnobscuredSize(const WebCore::FloatSize&);
+ WebCore::FloatSize maximumUnobscuredSize() const { return m_maximumUnobscuredSize; }
+
void setViewExposedRect(std::optional<WebCore::FloatRect>);
std::optional<WebCore::FloatRect> viewExposedRect() const { return m_viewExposedRect; }
@@ -2846,6 +2849,10 @@
WebCore::IntSize m_fixedLayoutSize;
std::optional<WebCore::FloatRect> m_viewExposedRect;
+ WebCore::FloatSize m_defaultUnobscuredSize;
+ WebCore::FloatSize m_minimumUnobscuredSize;
+ WebCore::FloatSize m_maximumUnobscuredSize;
+
bool m_alwaysShowsHorizontalScroller { false };
bool m_alwaysShowsVerticalScroller { false };
@@ -3083,8 +3090,6 @@
#if PLATFORM(IOS_FAMILY)
Function<bool()> m_deviceOrientationUserPermissionHandlerForTesting;
bool m_waitingForPostLayoutEditorStateUpdateAfterFocusingElement { false };
- WebCore::FloatSize m_minimumUnobscuredSize;
- WebCore::FloatSize m_maximumUnobscuredSize;
bool m_lastObservedStateWasBackground { false };
HashSet<String> m_performActionOnElementAuthTokens;
#endif
Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (291979 => 291980)
--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2022-03-28 18:18:47 UTC (rev 291980)
@@ -273,6 +273,9 @@
hideValidationMessage();
m_viewportConfigurationViewLayoutSize = viewLayoutSize;
+ m_defaultUnobscuredSize = maximumUnobscuredSize;
+ m_minimumUnobscuredSize = minimumUnobscuredSize;
+ m_maximumUnobscuredSize = maximumUnobscuredSize;
m_process->send(Messages::WebPage::DynamicViewportSizeUpdate(viewLayoutSize,
minimumUnobscuredSize, maximumUnobscuredSize, targetExposedContentRect, targetUnobscuredRect,
targetUnobscuredRectInScrollViewCoordinates, unobscuredSafeAreaInsets,
@@ -301,22 +304,6 @@
m_process->send(Messages::WebPage::SetForceAlwaysUserScalable(userScalable), m_webPageID);
}
-void WebPageProxy::setMinimumUnobscuredSize(const WebCore::FloatSize& size)
-{
- m_minimumUnobscuredSize = size;
-
- if (hasRunningProcess())
- m_process->send(Messages::WebPage::SetMinimumUnobscuredSize(size), m_webPageID);
-}
-
-void WebPageProxy::setMaximumUnobscuredSize(const WebCore::FloatSize& size)
-{
- m_maximumUnobscuredSize = size;
-
- if (hasRunningProcess())
- m_process->send(Messages::WebPage::SetMaximumUnobscuredSize(size), m_webPageID);
-}
-
void WebPageProxy::setDeviceOrientation(int32_t deviceOrientation)
{
if (deviceOrientation != m_deviceOrientation) {
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (291979 => 291980)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2022-03-28 18:18:47 UTC (rev 291980)
@@ -1524,9 +1524,11 @@
bool shouldHideScrollbars = shouldDisableScrolling;
IntRect fixedVisibleContentRect;
+ auto oldView = m_frame->coreFrame()->view();
+
#if USE(COORDINATED_GRAPHICS)
- if (m_frame->coreFrame()->view())
- fixedVisibleContentRect = m_frame->coreFrame()->view()->fixedVisibleContentRect();
+ if (oldView)
+ fixedVisibleContentRect = oldView->fixedVisibleContentRect();
if (shouldUseFixedLayout)
shouldHideScrollbars = true;
#endif
@@ -1549,6 +1551,10 @@
horizontalScrollbarMode, horizontalLock, verticalScrollbarMode, verticalLock);
RefPtr<FrameView> view = m_frame->coreFrame()->view();
+
+ if (view && oldView)
+ view->copyCSSViewportSizeOverrides(*oldView);
+
if (int width = webPage->minimumSizeForAutoLayout().width()) {
int height = std::max(webPage->minimumSizeForAutoLayout().height(), 1);
view->enableFixedWidthAutoSizeMode(true, { width, height });
@@ -1567,7 +1573,7 @@
}
if (auto viewportSizeForViewportUnits = webPage->viewportSizeForCSSViewportUnits())
- view->setSizeForCSSLargeViewportUnits(*viewportSizeForViewportUnits);
+ view->setSizeForCSSDefaultViewportUnits(*viewportSizeForViewportUnits);
view->setProhibitsScrolling(shouldDisableScrolling);
view->setVisualUpdatesAllowedByClient(!webPage->shouldExtendIncrementalRenderingSuppression());
#if PLATFORM(COCOA)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (291979 => 291980)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2022-03-28 18:18:47 UTC (rev 291980)
@@ -744,6 +744,10 @@
setUseFixedLayout(parameters.useFixedLayout);
+ setDefaultUnobscuredSize(parameters.defaultUnobscuredSize);
+ setMinimumUnobscuredSize(parameters.minimumUnobscuredSize);
+ setMaximumUnobscuredSize(parameters.maximumUnobscuredSize);
+
setUnderlayColor(parameters.underlayColor);
setPaginationMode(parameters.paginationMode);
@@ -866,8 +870,6 @@
#if PLATFORM(IOS_FAMILY)
setViewportConfigurationViewLayoutSize(parameters.viewportConfigurationViewLayoutSize, parameters.viewportConfigurationLayoutSizeScaleFactor, parameters.viewportConfigurationMinimumEffectiveDeviceWidth);
- setMinimumUnobscuredSize(parameters.minimumUnobscuredSize);
- setMaximumUnobscuredSize(parameters.maximumUnobscuredSize);
#endif
#if USE(AUDIO_SESSION)
@@ -2369,6 +2371,81 @@
return view->fixedLayoutSize();
}
+void WebPage::setDefaultUnobscuredSize(const FloatSize& defaultUnobscuredSize)
+{
+ if (defaultUnobscuredSize == m_defaultUnobscuredSize)
+ return;
+
+ m_defaultUnobscuredSize = defaultUnobscuredSize;
+
+ updateSizeForCSSDefaultViewportUnits();
+}
+
+void WebPage::updateSizeForCSSDefaultViewportUnits()
+{
+ auto* mainFrameView = this->mainFrameView();
+ if (!mainFrameView)
+ return;
+
+ auto defaultUnobscuredSize = m_defaultUnobscuredSize;
+#if ENABLE(META_VIEWPORT)
+ if (defaultUnobscuredSize.isEmpty())
+ defaultUnobscuredSize = m_viewportConfiguration.viewLayoutSize();
+ defaultUnobscuredSize.scale(1 / m_viewportConfiguration.initialScaleIgnoringContentSize());
+#endif
+ mainFrameView->setSizeForCSSDefaultViewportUnits(defaultUnobscuredSize);
+}
+
+void WebPage::setMinimumUnobscuredSize(const FloatSize& minimumUnobscuredSize)
+{
+ if (minimumUnobscuredSize == m_minimumUnobscuredSize)
+ return;
+
+ m_minimumUnobscuredSize = minimumUnobscuredSize;
+
+ updateSizeForCSSSmallViewportUnits();
+}
+
+void WebPage::updateSizeForCSSSmallViewportUnits()
+{
+ auto* mainFrameView = this->mainFrameView();
+ if (!mainFrameView)
+ return;
+
+ auto minimumUnobscuredSize = m_minimumUnobscuredSize;
+#if ENABLE(META_VIEWPORT)
+ if (minimumUnobscuredSize.isEmpty())
+ minimumUnobscuredSize = m_viewportConfiguration.viewLayoutSize();
+ minimumUnobscuredSize.scale(1 / m_viewportConfiguration.initialScaleIgnoringContentSize());
+#endif
+ mainFrameView->setSizeForCSSSmallViewportUnits(minimumUnobscuredSize);
+}
+
+void WebPage::setMaximumUnobscuredSize(const FloatSize& maximumUnobscuredSize)
+{
+ if (maximumUnobscuredSize == m_maximumUnobscuredSize)
+ return;
+
+ m_maximumUnobscuredSize = maximumUnobscuredSize;
+
+ updateSizeForCSSLargeViewportUnits();
+}
+
+void WebPage::updateSizeForCSSLargeViewportUnits()
+{
+ auto* mainFrameView = this->mainFrameView();
+ if (!mainFrameView)
+ return;
+
+ auto maximumUnobscuredSize = m_maximumUnobscuredSize;
+#if ENABLE(META_VIEWPORT)
+ if (maximumUnobscuredSize.isEmpty())
+ maximumUnobscuredSize = m_viewportConfiguration.viewLayoutSize();
+ maximumUnobscuredSize.scale(1 / m_viewportConfiguration.initialScaleIgnoringContentSize());
+#endif
+ mainFrameView->setSizeForCSSLargeViewportUnits(maximumUnobscuredSize);
+}
+
void WebPage::disabledAdaptationsDidChange(const OptionSet<DisabledAdaptations>& disabledAdaptations)
{
#if PLATFORM(IOS_FAMILY)
@@ -6420,7 +6497,7 @@
m_viewportSizeForCSSViewportUnits = viewportSize;
if (m_viewportSizeForCSSViewportUnits)
- corePage()->mainFrame().view()->setSizeForCSSLargeViewportUnits(*m_viewportSizeForCSSViewportUnits);
+ corePage()->mainFrame().view()->setSizeForCSSDefaultViewportUnits(*m_viewportSizeForCSSViewportUnits);
}
bool WebPage::isSmartInsertDeleteEnabled()
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (291979 => 291980)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2022-03-28 18:18:47 UTC (rev 291980)
@@ -612,6 +612,10 @@
bool setFixedLayoutSize(const WebCore::IntSize&);
WebCore::IntSize fixedLayoutSize() const;
+ void setDefaultUnobscuredSize(const WebCore::FloatSize&);
+ void setMinimumUnobscuredSize(const WebCore::FloatSize&);
+ void setMaximumUnobscuredSize(const WebCore::FloatSize&);
+
void listenForLayoutMilestones(OptionSet<WebCore::LayoutMilestone>);
void setSuppressScrollbarAnimations(bool);
@@ -1101,8 +1105,6 @@
void updateVisibilityState(bool isInitialState = false);
#if PLATFORM(IOS_FAMILY)
- void setMinimumUnobscuredSize(const WebCore::FloatSize&);
- void setMaximumUnobscuredSize(const WebCore::FloatSize&);
void setDeviceOrientation(int32_t);
void dynamicViewportSizeUpdate(const WebCore::FloatSize& viewLayoutSize, const WebCore::FloatSize& minimumUnobscuredSize, 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, double minimumEffectiveDeviceWidth, DynamicViewportSizeUpdateID);
bool scaleWasSetByUIProcess() const { return m_scaleWasSetByUIProcess; }
@@ -1553,9 +1555,11 @@
bool didReceiveSyncWebPageMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&);
+ void updateSizeForCSSDefaultViewportUnits();
+ void updateSizeForCSSSmallViewportUnits();
+ void updateSizeForCSSLargeViewportUnits();
+
#if PLATFORM(IOS_FAMILY)
- void updateViewportSizeForCSSViewportUnits();
-
std::optional<FocusedElementInformation> focusedElementInformation();
void generateSyntheticEditingCommand(SyntheticEditingCommandType);
void handleSyntheticClick(WebCore::Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebKit::WebEvent::Modifier>, WebCore::PointerID = WebCore::mousePointerID);
@@ -2006,6 +2010,10 @@
bool m_useFixedLayout { false };
+ WebCore::FloatSize m_defaultUnobscuredSize;
+ WebCore::FloatSize m_minimumUnobscuredSize;
+ WebCore::FloatSize m_maximumUnobscuredSize;
+
WebCore::Color m_underlayColor;
#if ENABLE(UI_PROCESS_PDF_HUD)
@@ -2295,8 +2303,6 @@
std::optional<WebCore::SimpleRange> m_initialSelection;
WebCore::VisibleSelection m_storedSelectionForAccessibility { WebCore::VisibleSelection() };
- WebCore::FloatSize m_minimumUnobscuredSize;
- WebCore::FloatSize m_maximumUnobscuredSize;
int32_t m_deviceOrientation { 0 };
bool m_keyboardIsAttached { false };
bool m_canShowWhileLocked { false };
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (291979 => 291980)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2022-03-28 18:18:47 UTC (rev 291980)
@@ -49,8 +49,6 @@
MouseEvent(WebKit::WebMouseEvent event, std::optional<Vector<WebKit::SandboxExtension::Handle>> sandboxExtensions)
#if PLATFORM(IOS_FAMILY)
SetViewportConfigurationViewLayoutSize(WebCore::FloatSize size, double scaleFactor, double minimumEffectiveDeviceWidth)
- SetMinimumUnobscuredSize(WebCore::FloatSize size)
- SetMaximumUnobscuredSize(WebCore::FloatSize size)
SetDeviceOrientation(int32_t deviceOrientation)
SetOverrideViewportArguments(std::optional<WebCore::ViewportArguments> arguments)
DynamicViewportSizeUpdate(WebCore::FloatSize viewLayoutSize, WebCore::FloatSize minimumUnobscuredSize, WebCore::FloatSize maximumUnobscuredSize, WebCore::FloatRect targetExposedContentRect, WebCore::FloatRect targetUnobscuredRect, WebCore::FloatRect targetUnobscuredRectInScrollViewCoordinates, WebCore::RectEdges<float> targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, double minimumEffectiveDeviceWidth, uint64_t dynamicViewportSizeUpdateID)
@@ -300,6 +298,11 @@
SetUseFixedLayout(bool fixed)
SetFixedLayoutSize(WebCore::IntSize size)
+
+ SetDefaultUnobscuredSize(WebCore::FloatSize size)
+ SetMinimumUnobscuredSize(WebCore::FloatSize size)
+ SetMaximumUnobscuredSize(WebCore::FloatSize size)
+
ListenForLayoutMilestones(OptionSet<WebCore::LayoutMilestone> layoutMilestones)
SetSuppressScrollbarAnimations(bool suppressAnimations)
Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (291979 => 291980)
--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2022-03-28 18:18:47 UTC (rev 291980)
@@ -3570,18 +3570,6 @@
viewportConfigurationChanged(zoomToInitialScale);
}
-void WebPage::setMinimumUnobscuredSize(const FloatSize& minimumUnobscuredSize)
-{
- m_minimumUnobscuredSize = minimumUnobscuredSize;
- updateViewportSizeForCSSViewportUnits();
-}
-
-void WebPage::setMaximumUnobscuredSize(const FloatSize& maximumUnobscuredSize)
-{
- m_maximumUnobscuredSize = maximumUnobscuredSize;
- updateViewportSizeForCSSViewportUnits();
-}
-
void WebPage::setDeviceOrientation(int32_t deviceOrientation)
{
if (deviceOrientation == m_deviceOrientation)
@@ -3643,6 +3631,7 @@
if (setFixedLayoutSize(newLayoutSize))
resetTextAutosizing();
+ setDefaultUnobscuredSize(maximumUnobscuredSize);
setMinimumUnobscuredSize(minimumUnobscuredSize);
setMaximumUnobscuredSize(maximumUnobscuredSize);
m_page->setUnobscuredSafeAreaInsets(targetUnobscuredSafeAreaInsets);
@@ -3962,7 +3951,9 @@
m_page->setZoomedOutPageScaleFactor(m_viewportConfiguration.minimumScale());
- updateViewportSizeForCSSViewportUnits();
+ updateSizeForCSSDefaultViewportUnits();
+ updateSizeForCSSSmallViewportUnits();
+ updateSizeForCSSLargeViewportUnits();
FrameView& frameView = *mainFrameView();
IntPoint scrollPosition = frameView.scrollPosition();
@@ -3988,23 +3979,6 @@
}
}
-void WebPage::updateViewportSizeForCSSViewportUnits()
-{
- FloatSize smallestUnobscuredSize = m_minimumUnobscuredSize;
- if (smallestUnobscuredSize.isEmpty())
- smallestUnobscuredSize = m_viewportConfiguration.viewLayoutSize();
-
- FloatSize largestUnobscuredSize = m_maximumUnobscuredSize;
- if (largestUnobscuredSize.isEmpty())
- largestUnobscuredSize = m_viewportConfiguration.viewLayoutSize();
-
- FrameView& frameView = *mainFrameView();
- smallestUnobscuredSize.scale(1 / m_viewportConfiguration.initialScaleIgnoringContentSize());
- largestUnobscuredSize.scale(1 / m_viewportConfiguration.initialScaleIgnoringContentSize());
- frameView.setSizeForCSSSmallViewportUnits(smallestUnobscuredSize);
- frameView.setSizeForCSSLargeViewportUnits(largestUnobscuredSize);
-}
-
void WebPage::applicationWillResignActive()
{
[[NSNotificationCenter defaultCenter] postNotificationName:WebUIApplicationWillResignActiveNotification object:nil];
Modified: trunk/Tools/ChangeLog (291979 => 291980)
--- trunk/Tools/ChangeLog 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Tools/ChangeLog 2022-03-28 18:18:47 UTC (rev 291980)
@@ -1,3 +1,33 @@
+2022-03-28 Devin Rousso <drou...@apple.com>
+
+ [iOS] Add `WKWebView` API to control CSS "small viewport" `sv*` and "large viewport" `lv*` units
+ https://bugs.webkit.org/show_bug.cgi?id=237979
+ <rdar://problem/89434696>
+
+ Reviewed by Tim Horton.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/CSSViewportUnits.mm:
+ (TEST.CSSViewportUnits.NegativeMinimumViewportInset): Added.
+ (TEST.CSSViewportUnits.NegativeMaximumViewportInset): Added.
+ (TEST.CSSViewportUnits.MinimumViewportInsetLargerThanMaximumViewportInset): Added.
+ (TEST.CSSViewportUnits.MinimumViewportInsetLargerThanFrame): Added.
+ (TEST.CSSViewportUnits.MaximumViewportInsetLargerThanFrame): Added.
+ (TEST.CSSViewportUnits.MinimumViewportInset): Added.
+ (TEST.CSSViewportUnits.MaximumViewportInset): Added.
+ (TEST.CSSViewportUnits.MinimumViewportInsetWithZoom): Added.
+ (TEST.CSSViewportUnits.MaximumViewportInsetWithZoom): Added.
+ (TEST.CSSViewportUnits.MinimumViewportInsetWithWritingMode): Added.
+ (TEST.CSSViewportUnits.MaximumViewportInsetWithWritingMode): Added.
+ (TEST.CSSViewportUnits.MinimumViewportInsetWithFrame): Added.
+ (TEST.CSSViewportUnits.MaximumViewportInsetWithFrame): Added.
+ (TEST.CSSViewportUnits.MinimumViewportInsetWithBounds): Added.
+ (TEST.CSSViewportUnits.MaximumViewportInsetWithBounds): Added.
+ (TEST.CSSViewportUnits.MinimumViewportInsetWithContentInset): Added.
+ (TEST.CSSViewportUnits.MaximumViewportInsetWithContentInset): Added.
+ (TEST.CSSViewportUnits.MinimumViewportInsetWithSafeAreaInsets): Added.
+ (TEST.CSSViewportUnits.MaximumViewportInsetWithSafeAreaInsets): Added.
+ (TEST.CSSViewportUnits.UnobscuredSizeOverridesIgnoreMaximumViewportInsetAPI): Added.
+
2022-03-28 Brady Eidson <beid...@apple.com>
Support ServiceWorkerClients.openWindow.
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/CSSViewportUnits.mm (291979 => 291980)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/CSSViewportUnits.mm 2022-03-28 18:14:19 UTC (rev 291979)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/CSSViewportUnits.mm 2022-03-28 18:18:47 UTC (rev 291980)
@@ -169,8 +169,783 @@
}
}
+#if USE(APPKIT)
+#define CocoaEdgeInsetsMake NSEdgeInsetsMake
+#endif
+
#if PLATFORM(IOS_FAMILY)
+#define CocoaEdgeInsetsMake UIEdgeInsetsMake
+#endif
+#define CocoaEdgeInsetsZero CocoaEdgeInsetsMake(0, 0, 0, 0)
+
+#if PLATFORM(IOS_FAMILY)
+
+TEST(CSSViewportUnits, NegativeMinimumViewportInset)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+
+ bool didThrow = false;
+ @try {
+ [webView setMinimumViewportInset:CocoaEdgeInsetsMake(-11, 21, 31, 41) maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ } @catch (NSException *exception) {
+ didThrow = true;
+ }
+ EXPECT_TRUE(didThrow);
+}
+
+TEST(CSSViewportUnits, NegativeMaximumViewportInset)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+
+ bool didThrow = false;
+ @try {
+ [webView setMinimumViewportInset:CocoaEdgeInsetsZero maximumViewportInset:CocoaEdgeInsetsMake(-12, 22, 32, 42)];
+ } @catch (NSException *exception) {
+ didThrow = true;
+ }
+ EXPECT_TRUE(didThrow);
+}
+
+TEST(CSSViewportUnits, MinimumViewportInsetLargerThanMaximumViewportInset)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+
+ bool didThrow = false;
+ @try {
+ [webView setMinimumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42) maximumViewportInset:CocoaEdgeInsetsMake(11, 21, 31, 41)];
+ } @catch (NSException *exception) {
+ didThrow = true;
+ }
+ EXPECT_TRUE(didThrow);
+}
+
+TEST(CSSViewportUnits, MinimumViewportInsetThanLargerFrame)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+
+ bool didThrow = false;
+ @try {
+ [webView setMinimumViewportInset:CocoaEdgeInsetsMake(1100, 2100, 3100, 4100) maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ } @catch (NSException *exception) {
+ didThrow = true;
+ }
+ EXPECT_TRUE(didThrow);
+}
+
+TEST(CSSViewportUnits, MaximumViewportInsetThanLargerFrame)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+
+ bool didThrow = false;
+ @try {
+ [webView setMinimumViewportInset:CocoaEdgeInsetsMake(11, 21, 31, 41) maximumViewportInset:CocoaEdgeInsetsMake(1200, 2200, 3200, 4200)];
+ } @catch (NSException *exception) {
+ didThrow = true;
+ }
+ EXPECT_TRUE(didThrow);
+}
+
+TEST(CSSViewportUnits, MinimumViewportInset)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsMake(11, 21, 31, 41) maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, MaximumViewportInset)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsZero maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, MinimumViewportInsetWithZoom)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsMake(11, 21, 31, 41) maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+#if PLATFORM(IOS_FAMILY)
+ [webView scrollView].zoomScale = 2;
+#elif PLATFORM(MAC)
+ [webView setAllowsMagnification:YES];
+ [webView setMagnification:2];
+#endif
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, MaximumViewportInsetWithZoom)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsZero maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+#if PLATFORM(IOS_FAMILY)
+ [webView scrollView].zoomScale = 2;
+#elif PLATFORM(MAC)
+ [webView setAllowsMagnification:YES];
+ [webView setMagnification:2];
+#endif
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, MinimumViewportInsetWithWritingMode)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsMake(11, 21, 31, 41) maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ [webView objectByEvaluatingJavaScript:@"document.documentElement.style.writingMode = 'vertical-lr'"];
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, MaximumViewportInsetWithWritingMode)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsZero maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ [webView objectByEvaluatingJavaScript:@"document.documentElement.style.writingMode = 'vertical-lr'"];
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, MinimumViewportInsetWithFrame)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsMake(11, 21, 31, 41) maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ [webView setFrame:CGRectMake(0, 0, 220, 400)];
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(220, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(400, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(220, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(400, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(400, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(220, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(156, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(356, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(156, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(356, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(356, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(156, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(158, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(358, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(158, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(358, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(358, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(158, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, MaximumViewportInsetWithFrame)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsZero maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ [webView setFrame:CGRectMake(0, 0, 220, 400)];
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(220, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(400, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(220, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(400, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(400, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(220, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(156, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(356, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(156, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(356, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(356, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(156, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(220, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(400, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(220, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(400, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(400, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(220, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, MinimumViewportInsetWithBounds)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsMake(11, 21, 31, 41) maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ [webView setBounds:CGRectMake(50, 60, 320, 500)];
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, MaximumViewportInsetWithBounds)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsZero maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ [webView setBounds:CGRectMake(50, 60, 320, 500)];
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, MinimumViewportInsetWithContentInset)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsMake(11, 21, 31, 41) maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ [webView scrollView].contentInset = CocoaEdgeInsetsMake(50, 60, 70, 80);
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, MaximumViewportInsetWithContentInset)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsZero maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ [webView scrollView].contentInset = CocoaEdgeInsetsMake(50, 60, 70, 80);
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, MinimumViewportInsetWithSafeAreaInsets)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsMake(11, 21, 31, 41) maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ auto viewController = adoptNS([[UIViewController alloc] init]);
+ [viewController setAdditionalSafeAreaInsets:CocoaEdgeInsetsMake(50, 60, 70, 80)];
+ [viewController setView:webView.get()];
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(458, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(258, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, MaximumViewportInsetWithSafeAreaInsets)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsZero maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ auto viewController = adoptNS([[UIViewController alloc] init]);
+ [viewController setAdditionalSafeAreaInsets:CocoaEdgeInsetsMake(50, 60, 70, 80)];
+ [viewController setView:webView.get()];
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(456, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(256, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(500, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(320, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, UnobscuredSizeOverridesIgnoreMinimumViewportInset)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsMake(11, 21, 31, 41) maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ [webView _overrideLayoutParametersWithMinimumLayoutSize:CGSizeMake(10.5, 20.5)
+ maximumUnobscuredSizeOverride:CGSizeMake(30.5, 40.5)];
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(30.5, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(40.5, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(30.5, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(40.5, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(40.5, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(30.5, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(10.5, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(20.5, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(10.5, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(20.5, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(20.5, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(10.5, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(30.5, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(40.5, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(30.5, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(40.5, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(40.5, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(30.5, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
+TEST(CSSViewportUnits, UnobscuredSizeOverridesIgnoreMaximumViewportInset)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView setMinimumViewportInset:CocoaEdgeInsetsZero maximumViewportInset:CocoaEdgeInsetsMake(12, 22, 32, 42)];
+ [webView synchronouslyLoadTestPageNamed:@"CSSViewportUnits"];
+
+ [webView _overrideLayoutParametersWithMinimumLayoutSize:CGSizeMake(10.5, 20.5)
+ maximumUnobscuredSizeOverride:CGSizeMake(30.5, 40.5)];
+
+ [webView waitForNextPresentationUpdate];
+
+ EXPECT_FLOAT_EQ(30.5, viewportUnitLength(webView, @"vw"));
+ EXPECT_FLOAT_EQ(40.5, viewportUnitLength(webView, @"vh"));
+ EXPECT_FLOAT_EQ(30.5, viewportUnitLength(webView, @"vmin"));
+ EXPECT_FLOAT_EQ(40.5, viewportUnitLength(webView, @"vmax"));
+ EXPECT_FLOAT_EQ(40.5, viewportUnitLength(webView, @"vb"));
+ EXPECT_FLOAT_EQ(30.5, viewportUnitLength(webView, @"vi"));
+
+ EXPECT_FLOAT_EQ(10.5, viewportUnitLength(webView, @"svw"));
+ EXPECT_FLOAT_EQ(20.5, viewportUnitLength(webView, @"svh"));
+ EXPECT_FLOAT_EQ(10.5, viewportUnitLength(webView, @"svmin"));
+ EXPECT_FLOAT_EQ(20.5, viewportUnitLength(webView, @"svmax"));
+ EXPECT_FLOAT_EQ(20.5, viewportUnitLength(webView, @"svb"));
+ EXPECT_FLOAT_EQ(10.5, viewportUnitLength(webView, @"svi"));
+
+ EXPECT_FLOAT_EQ(30.5, viewportUnitLength(webView, @"lvw"));
+ EXPECT_FLOAT_EQ(40.5, viewportUnitLength(webView, @"lvh"));
+ EXPECT_FLOAT_EQ(30.5, viewportUnitLength(webView, @"lvmin"));
+ EXPECT_FLOAT_EQ(40.5, viewportUnitLength(webView, @"lvmax"));
+ EXPECT_FLOAT_EQ(40.5, viewportUnitLength(webView, @"lvb"));
+ EXPECT_FLOAT_EQ(30.5, viewportUnitLength(webView, @"lvi"));
+
+ {
+ double fixedWidth = widthOfElementWithID(webView, @"fixed");
+ double fixedHeight = heightOfElementWithID(webView, @"fixed");
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvw"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvh"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvmin"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvmax"));
+ EXPECT_FLOAT_EQ(fixedHeight, viewportUnitLength(webView, @"dvb"));
+ EXPECT_FLOAT_EQ(fixedWidth, viewportUnitLength(webView, @"dvi"));
+ }
+}
+
TEST(CSSViewportUnits, EmptyUnobscuredSizeOverrides)
{
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
_______________________________________________ webkit-changes mailing list webkit-changes@lists.webkit.org https://lists.webkit.org/mailman/listinfo/webkit-changes