Skip to content

Commit

Permalink
[iOS] Entering fullscreen from iframe without explicit viewport resul…
Browse files Browse the repository at this point in the history
…ts in badly cropped video

https://bugs.webkit.org/show_bug.cgi?id=270909
rdar://123725878

Reviewed by Abrar Rahman Protyasha.

In 270199@main, support was added for using the viewport settings from the outermost fullscreen
document, rather than the top document. This allowed an <iframe> whose contents specified a
viewport-fit=cover behavior to work within a hosting document without that viewport setting.
However, for an <iframe> whose contents did not specify a viewport at all, it would receive
the default desktop viewport, which is 980px wide. This, combined with the iOS fullscreen
behavior of blocking zoom, meant that the fullscreen viewport would be much, much larger than
the physical viewport.

When entering or exiting fullscreen mode, notify the WebPage, and reset the default viewport
such that in fullscreen the web page will receive the "native" viewport rather than the "desktop"
one by default. This requires storing the results of didReceiveMobileDocType(), so that it
can be re-used after page load.

* Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.cpp:
(WebKit::WebFullScreenManager::willEnterFullScreen):
(WebKit::WebFullScreenManager::didExitFullScreen):
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::isInFullscreenChanged):
* Source/WebKit/WebProcess/WebPage/WebPage.h:
* Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::didReceiveMobileDocType):
(WebKit::WebPage::resetViewportDefaultConfiguration):

Canonical link: https://commits.webkit.org/276138@main
  • Loading branch information
jernoble committed Mar 15, 2024
1 parent 416a9cc commit 66ba699
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ EVENT(load)
RUN(enterFullscreen())
EXPECTED (visibleRect.left == '-100') OK
EXPECTED (visibleRect.top == '-50') OK
Test that fullscreen within an iframe without an explicit viewport setting has native viewport behavior:
RUN(frame.src = "resources/no-viewport.html")
EVENT(load)
RUN(enterFullscreen())
EXPECTED (visibleRect.left == '-100') OK
EXPECTED (visibleRect.top == '-50') OK
EXPECTED (visibleRect.width < '980') OK
RUN(exitFullscreen())

RUN(setSafeAreaInsets(0, 0))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@
await waitFor(frame, 'load');
await run('enterFullscreen()');
await testExpectedVisibleRect(-100, -50);

consoleWrite('Test that fullscreen within an iframe without an explicit viewport setting has native viewport behavior:')
run('frame.src = "resources/no-viewport.html"');
await waitFor(frame, 'load');
await run('enterFullscreen()');
await testExpectedVisibleRect(-100, -50);
testExpected('visibleRect.width', 980, '<');
await run('exitFullscreen()');
consoleWrite('')

Expand All @@ -127,4 +134,4 @@
<iframe id=frame width=100 height=50></iframe>
<div id=console></div>
</body>
</html>
</html>
12 changes: 12 additions & 0 deletions LayoutTests/fast/viewport/ios/resources/no-viewport.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<script>
window.addEventListener('load', event => {
document.body.onclick = function() {
document.body.webkitRequestFullScreen();
};
});
</script>
<body>
</body>
</html>
4 changes: 4 additions & 0 deletions Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ void WebFullScreenManager::willEnterFullScreen(WebCore::HTMLMediaElementEnums::V
return;
}

m_page->isInFullscreenChanged(WebPage::IsInFullscreenMode::Yes);

#if !PLATFORM(IOS_FAMILY)
m_page->hidePageBanners();
#endif
Expand Down Expand Up @@ -430,6 +432,8 @@ static Vector<Ref<Element>> collectFullscreenElementsFromElement(Element* elemen

void WebFullScreenManager::didExitFullScreen()
{
m_page->isInFullscreenChanged(WebPage::IsInFullscreenMode::No);

if (!m_element)
return;

Expand Down
12 changes: 12 additions & 0 deletions Source/WebKit/WebProcess/WebPage/WebPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5143,6 +5143,18 @@ WebFullScreenManager* WebPage::fullScreenManager()
m_fullScreenManager = WebFullScreenManager::create(*this);
return m_fullScreenManager.get();
}

void WebPage::isInFullscreenChanged(IsInFullscreenMode isInFullscreenMode)
{
if (m_isInFullscreenMode == isInFullscreenMode)
return;
m_isInFullscreenMode = isInFullscreenMode;

#if ENABLE(META_VIEWPORT)
resetViewportDefaultConfiguration(m_mainFrame.ptr(), m_isMobileDoctype);
#endif
}

#endif

void WebPage::addConsoleMessage(FrameIdentifier frameID, MessageSource messageSource, MessageLevel messageLevel, const String& message, std::optional<WebCore::ResourceLoaderIdentifier> requestID)
Expand Down
6 changes: 6 additions & 0 deletions Source/WebKit/WebProcess/WebPage/WebPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,9 @@ class WebPage : public API::ObjectImpl<API::Object::Type::BundlePage>, public IP

#if ENABLE(FULLSCREEN_API)
WebFullScreenManager* fullScreenManager();

enum class IsInFullscreenMode : bool { No, Yes };
void isInFullscreenChanged(IsInFullscreenMode);
#endif

void addConsoleMessage(WebCore::FrameIdentifier, MessageSource, MessageLevel, const String&, std::optional<WebCore::ResourceLoaderIdentifier> = std::nullopt);
Expand Down Expand Up @@ -2371,6 +2374,7 @@ class WebPage : public API::ObjectImpl<API::Object::Type::BundlePage>, public IP

#if ENABLE(FULLSCREEN_API)
RefPtr<WebFullScreenManager> m_fullScreenManager;
IsInFullscreenMode m_isInFullscreenMode { IsInFullscreenMode::No };
#endif

RefPtr<WebPopupMenu> m_activePopupMenu;
Expand Down Expand Up @@ -2573,6 +2577,8 @@ class WebPage : public API::ObjectImpl<API::Object::Type::BundlePage>, public IP
std::optional<std::pair<TransactionID, double>> m_lastLayerTreeTransactionIdAndPageScaleBeforeScalingPage;
bool m_sendAutocorrectionContextAfterFocusingElement { false };
std::unique_ptr<WebCore::IgnoreSelectionChangeForScope> m_ignoreSelectionChangeScopeForDictation;

bool m_isMobileDoctype { false };
#endif // PLATFORM(IOS_FAMILY)

WebCore::Timer m_layerVolatilityTimer;
Expand Down
5 changes: 5 additions & 0 deletions Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@ static void convertContentToRootView(const LocalFrameView& view, Vector<Selectio

void WebPage::didReceiveMobileDocType(bool isMobileDoctype)
{
m_isMobileDoctype = isMobileDoctype;
resetViewportDefaultConfiguration(m_mainFrame.ptr(), isMobileDoctype);
}

Expand Down Expand Up @@ -4101,6 +4102,10 @@ static void handleAnimationActions(Element& element, uint32_t action)
}

auto parametersForStandardFrame = [&] {
#if ENABLE(FULLSCREEN_API)
if (m_isInFullscreenMode == IsInFullscreenMode::Yes)
return m_viewportConfiguration.nativeWebpageParameters();
#endif
if (shouldIgnoreMetaViewport())
return m_viewportConfiguration.nativeWebpageParameters();
return ViewportConfiguration::webpageParameters();
Expand Down

0 comments on commit 66ba699

Please sign in to comment.