-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[iOS] Element Fullscreen does not respect viewport-fit
https://bugs.webkit.org/show_bug.cgi?id=264012 rdar://117304719 Reviewed by Wenson Hsieh and Tim Horton. Tests: fast/viewport/ios/full-screen-safe-area-insets.html fullscreen/full-screen-document-background-color.html When configuring the WKWebView during the enter fullscreen operation, various settings of the view must be returned to their default state for the "automatic" avoid-safe-areas behavior to kick in. For some calls made by clients, there is no way to reset those behaviors to default, and the existing implementation merely overrode those settings with other non-default values. The end result was that all fullscreen content was behaving as if `viewport-fit=cover` was specified, which allowed some content to slip into the safe areas. Additionally, when embedded content is taken fullscreen, the viewport settings of that embedded iframe are not respected, and the embedded content uses the viewport settings of whatever page embedded it. Also, the fullscreen element's background is not used in the overflow areas when iframe content is in fullscreen. * Source/WebCore/dom/Document.cpp: (WebCore::Document::updateViewportArguments): * Source/WebCore/dom/FullscreenManager.cpp: (WebCore::FullscreenManager::dispatchFullscreenChangeOrErrorEvent): (WebCore::FullscreenManager::deepestFullscreenDocument const): * Source/WebCore/dom/FullscreenManager.h: * Source/WebCore/page/LocalFrameView.cpp: (WebCore::LocalFrameView::documentBackgroundColor const): * Source/WebCore/page/Page.cpp: (WebCore::viewportDocumentForFrame): (WebCore::Page::viewportArguments const): * Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h: * Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm: (-[WKWebView _resetScrollViewInsetAdjustmentBehavior]): (-[WKWebView _haveSetUnobscuredSafeAreaInsets]): (-[WKWebView _resetUnobscuredSafeAreaInsets]): (-[WKWebView _hasOverriddenLayoutParameters]): (-[WKWebView _viewLayoutSizeOverride]): (-[WKWebView _minimumUnobscuredSizeOverride]): (-[WKWebView _maximumUnobscuredSizeOverride]): (-[WKWebView _resetObscuredInsets]): (-[WKWebView _clearOverrideLayoutParameters]): * Source/WebKit/UIProcess/ios/WKContentView.mm: (-[WKContentView setFrame:]): * Source/WebKit/UIProcess/ios/WKScrollView.h: * Source/WebKit/UIProcess/ios/WKScrollView.mm: (-[WKScrollView _contentInsetWasExternallyOverridden]): (-[WKScrollView _resetContentInset]): (-[WKScrollView _resetContentInsetAdjustmentBehavior]): * Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm: (-[WKFullScreenViewController viewDidLayoutSubviews]): (-[WKFullScreenViewController viewWillTransitionToSize:withTransitionCoordinator:]): * Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm: (WebKit::WKWebViewState::applyTo): (WebKit::WKWebViewState::store): (-[WKFullScreenWindowController enterFullScreen:]): (-[WKFullScreenWindowController beganEnterFullScreenWithInitialFrame:finalFrame:]): Canonical link: https://commits.webkit.org/270199@main
- Loading branch information
Showing
21 changed files
with
523 additions
and
50 deletions.
There are no files selected for viewing
47 changes: 47 additions & 0 deletions
47
LayoutTests/fast/viewport/ios/full-screen-safe-area-insets-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
|
||
Set main frame viewport-fit=contain and test iframes | ||
RUN(metaViewport.content = "width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no, viewport-fit=contain") | ||
RUN(setSafeAreaInsets(100, 50)) | ||
EXPECTED (visibleRect.left == '-100') OK | ||
EXPECTED (visibleRect.top == '-50') OK | ||
|
||
Test that fullscreen within an iframe with viewport-fit-cover has viewport-fit-cover behavior: | ||
RUN(frame.src = "resources/viewport-fit-cover.html") | ||
EVENT(load) | ||
RUN(enterFullscreen()) | ||
EXPECTED (visibleRect.left == '0') OK | ||
EXPECTED (visibleRect.top == '0') OK | ||
RUN(exitFullscreen()) | ||
|
||
Test that fullscreen within an iframe with viewport-fit-contain has viewport-fit-contain behavior: | ||
RUN(frame.src = "resources/viewport-fit-contain.html") | ||
EVENT(load) | ||
RUN(enterFullscreen()) | ||
EXPECTED (visibleRect.left == '-100') OK | ||
EXPECTED (visibleRect.top == '-50') OK | ||
RUN(exitFullscreen()) | ||
|
||
Set main frame viewport-fit=cover and re-test iframes | ||
RUN(metaViewport.content = "width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no, viewport-fit=cover") | ||
EXPECTED (visibleRect.left == '0') OK | ||
EXPECTED (visibleRect.top == '0') OK | ||
|
||
RUN(frame.src = "resources/viewport-fit-cover.html") | ||
EVENT(load) | ||
Test that fullscreen within an iframe with viewport-fit-cover has viewport-fit-cover behavior: | ||
RUN(enterFullscreen()) | ||
EXPECTED (visibleRect.left == '0') OK | ||
EXPECTED (visibleRect.top == '0') OK | ||
RUN(exitFullscreen()) | ||
|
||
Test that fullscreen within an iframe with viewport-fit-contain has viewport-fit-contain behavior: | ||
RUN(frame.src = "resources/viewport-fit-contain.html") | ||
EVENT(load) | ||
RUN(enterFullscreen()) | ||
EXPECTED (visibleRect.left == '-100') OK | ||
EXPECTED (visibleRect.top == '-50') OK | ||
RUN(exitFullscreen()) | ||
|
||
RUN(setSafeAreaInsets(0, 0)) | ||
END OF TEST | ||
|
130 changes: 130 additions & 0 deletions
130
LayoutTests/fast/viewport/ios/full-screen-safe-area-insets.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<title>full-screen-safe-area-insets</title> | ||
<script src="../../../fullscreen/full-screen-test.js"></script> | ||
<script src="resources/viewport-test-utils.js"></script> | ||
<script> | ||
function setSafeAreaInsets(left, top) { | ||
const script = `(function() { | ||
uiController.setSafeAreaInsets(${top}, 0, 0, ${left}); | ||
uiController.doAfterVisibleContentRectUpdate(() => { | ||
uiController.uiScriptComplete(); | ||
}) | ||
})();`; | ||
return new Promise(resolve => { | ||
testRunner.runUIScript(script, () => { | ||
resolve(); | ||
}); | ||
}); | ||
} | ||
|
||
function getVisibleRect() { | ||
const script = `(function() { | ||
return JSON.stringify(uiController.contentVisibleRect); | ||
})();` | ||
return new Promise(resolve => { | ||
testRunner.runUIScript(script, value => { | ||
var result = JSON.parse(value); | ||
resolve(result); | ||
}) | ||
}); | ||
} | ||
|
||
async function enterFullscreen() { | ||
return new Promise(resolve => { | ||
internals.withUserGesture(() => { | ||
frame.contentDocument.documentElement.requestFullscreen().then(resolve, resolve); | ||
}); | ||
}); | ||
} | ||
|
||
async function exitFullscreen() { | ||
return new Promise(resolve => { | ||
internals.withUserGesture(() => { | ||
frame.contentDocument.exitFullscreen().then(resolve, resolve); | ||
}); | ||
}); | ||
} | ||
|
||
async function testExpectedVisibleRect(left, top) { | ||
window.scrollTo(0, 0); | ||
// await sleepFor(100); | ||
window.visibleRect = await getVisibleRect(); | ||
testExpected('visibleRect.left', left) | ||
testExpected('visibleRect.top', top) | ||
} | ||
|
||
async function runTest() { | ||
consoleDiv = document.getElementById('console'); | ||
consoleWrite('Set main frame viewport-fit=contain and test iframes') | ||
window.metaViewport = document.querySelector('meta[name="viewport"]'); | ||
run('metaViewport.content = "width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no, viewport-fit=contain"') | ||
await run('setSafeAreaInsets(100, 50)'); | ||
await testExpectedVisibleRect(-100, -50); | ||
|
||
consoleWrite('') | ||
|
||
consoleWrite('Test that fullscreen within an iframe with viewport-fit-cover has viewport-fit-cover behavior:') | ||
run('frame.src = "resources/viewport-fit-cover.html"'); | ||
await waitFor(frame, 'load'); | ||
|
||
await run('enterFullscreen()'); | ||
|
||
await testExpectedVisibleRect(0, 0); | ||
|
||
await run('exitFullscreen()'); | ||
consoleWrite('') | ||
|
||
consoleWrite('Test that fullscreen within an iframe with viewport-fit-contain has viewport-fit-contain behavior:') | ||
run('frame.src = "resources/viewport-fit-contain.html"'); | ||
await waitFor(frame, 'load'); | ||
await run('enterFullscreen()'); | ||
await testExpectedVisibleRect(-100, -50); | ||
await run('exitFullscreen()'); | ||
consoleWrite('') | ||
|
||
consoleWrite('Set main frame viewport-fit=cover and re-test iframes') | ||
run('metaViewport.content = "width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"') | ||
await testExpectedVisibleRect(0, 0); | ||
consoleWrite('') | ||
|
||
run('frame.src = "resources/viewport-fit-cover.html"'); | ||
await waitFor(frame, 'load'); | ||
|
||
consoleWrite('Test that fullscreen within an iframe with viewport-fit-cover has viewport-fit-cover behavior:') | ||
await run('enterFullscreen()'); | ||
await testExpectedVisibleRect(0, 0); | ||
await run('exitFullscreen()'); | ||
consoleWrite('') | ||
|
||
consoleWrite('Test that fullscreen within an iframe with viewport-fit-contain has viewport-fit-contain behavior:') | ||
run('frame.src = "resources/viewport-fit-contain.html"'); | ||
await waitFor(frame, 'load'); | ||
await run('enterFullscreen()'); | ||
await testExpectedVisibleRect(-100, -50); | ||
await run('exitFullscreen()'); | ||
consoleWrite('') | ||
|
||
await run('setSafeAreaInsets(0, 0)'); | ||
} | ||
|
||
window.addEventListener('load', event => { | ||
if (!window.internals) { | ||
consoleWrite('This test requires internals; please run in WKTR/DRT.'); | ||
return; | ||
} | ||
runTest().finally(endTest); | ||
}) | ||
</script> | ||
<style> | ||
#console { height: 200px; overflow: scroll; } | ||
</style> | ||
</head> | ||
<body> | ||
<iframe id=frame width=100 height=50></iframe> | ||
<div id=console></div> | ||
</body> | ||
</html> |
15 changes: 15 additions & 0 deletions
15
LayoutTests/fast/viewport/ios/resources/viewport-fit-contain.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta name="viewport" content="width=device-width, initial-scale=1,viewport-fit=contain"> | ||
</head> | ||
<script> | ||
window.addEventListener('load', event => { | ||
document.body.onclick = function() { | ||
document.body.webkitRequestFullScreen(); | ||
}; | ||
}); | ||
</script> | ||
<body> | ||
</body> | ||
</html> |
15 changes: 15 additions & 0 deletions
15
LayoutTests/fast/viewport/ios/resources/viewport-fit-cover.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta name="viewport" content="width=device-width, initial-scale=1,viewport-fit=cover"> | ||
</head> | ||
<script> | ||
window.addEventListener('load', event => { | ||
document.body.onclick = function() { | ||
document.body.webkitRequestFullScreen(); | ||
}; | ||
}); | ||
</script> | ||
<body> | ||
</body> | ||
</html> |
8 changes: 8 additions & 0 deletions
8
LayoutTests/fullscreen/full-screen-document-background-color-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
|
||
EXPECTED (internals.documentBackgroundColor() == 'rgb(255, 255, 255)') OK | ||
RUN(enterFullscreen()) | ||
EXPECTED (internals.documentBackgroundColor() == 'rgb(0, 128, 0)') OK | ||
RUN(exitFullscreen()) | ||
EXPECTED (internals.documentBackgroundColor() == 'rgb(255, 255, 255)') OK | ||
END OF TEST | ||
|
40 changes: 40 additions & 0 deletions
40
LayoutTests/fullscreen/full-screen-document-background-color.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<title>full-screen-document-background-color</title> | ||
<style>html { background-color: white; }</style> | ||
<script src="full-screen-test.js"></script> | ||
<script> | ||
async function enterFullscreen() { | ||
return new Promise(resolve => { | ||
internals.withUserGesture(() => { | ||
frame.contentDocument.body.requestFullscreen().then(resolve, resolve); | ||
}); | ||
}); | ||
} | ||
|
||
async function exitFullscreen() { | ||
return new Promise(resolve => { | ||
internals.withUserGesture(() => { | ||
frame.contentDocument.exitFullscreen().then(resolve, resolve); | ||
}); | ||
}); | ||
} | ||
|
||
async function runTest() { | ||
testExpected('internals.documentBackgroundColor()', 'rgb(255, 255, 255)'); | ||
await run('enterFullscreen()'); | ||
testExpected('internals.documentBackgroundColor()', 'rgb(0, 128, 0)'); | ||
await run('exitFullscreen()'); | ||
testExpected('internals.documentBackgroundColor()', 'rgb(255, 255, 255)'); | ||
} | ||
window.addEventListener('load', event => { | ||
runTest().finally(endTest); | ||
}) | ||
</script> | ||
</head> | ||
<body> | ||
<iframe id=frame width=100 height=50 src="resources/green.html"></iframe> | ||
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.