fix: allow iframe-initiated HTML fullscreen to exit while in macOS fullscreen (#20962)
* fix: explicitly resize the contents when exiting html fullscreen while in OS fullscreen * test: ensure HTML fullscreen toggles while in OS fullscreen
This commit is contained in:
parent
fcee7212ce
commit
15dffb3dde
4 changed files with 119 additions and 0 deletions
|
@ -355,6 +355,13 @@ void CommonWebContentsDelegate::ExitFullscreenModeForTab(
|
||||||
return;
|
return;
|
||||||
SetHtmlApiFullscreen(false);
|
SetHtmlApiFullscreen(false);
|
||||||
owner_window_->NotifyWindowLeaveHtmlFullScreen();
|
owner_window_->NotifyWindowLeaveHtmlFullScreen();
|
||||||
|
|
||||||
|
if (native_fullscreen_) {
|
||||||
|
// Explicitly trigger a view resize, as the size is not actually changing if
|
||||||
|
// the browser is fullscreened, too. Chrome does this indirectly from
|
||||||
|
// `chrome/browser/ui/exclusive_access/fullscreen_controller.cc`.
|
||||||
|
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommonWebContentsDelegate::IsFullscreenForTabOrPending(
|
bool CommonWebContentsDelegate::IsFullscreenForTabOrPending(
|
||||||
|
|
|
@ -1066,3 +1066,81 @@ describe('font fallback', () => {
|
||||||
if (process.platform === 'win32') { expect(fonts[0].familyName).to.be.oneOf(['Meiryo', 'Yu Gothic']) } else if (process.platform === 'darwin') { expect(fonts[0].familyName).to.equal('Hiragino Kaku Gothic ProN') }
|
if (process.platform === 'win32') { expect(fonts[0].familyName).to.be.oneOf(['Meiryo', 'Yu Gothic']) } else if (process.platform === 'darwin') { expect(fonts[0].familyName).to.equal('Hiragino Kaku Gothic ProN') }
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('iframe using HTML fullscreen API while window is OS-fullscreened', () => {
|
||||||
|
const fullscreenChildHtml = promisify(fs.readFile)(
|
||||||
|
path.join(fixturesPath, 'pages', 'fullscreen-oopif.html')
|
||||||
|
)
|
||||||
|
let w: BrowserWindow, server: http.Server
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
server = http.createServer(async (_req, res) => {
|
||||||
|
res.writeHead(200, { 'Content-Type': 'text/html' })
|
||||||
|
res.write(await fullscreenChildHtml)
|
||||||
|
res.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
server.listen(8989, '127.0.0.1')
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
w = new BrowserWindow({
|
||||||
|
show: true,
|
||||||
|
fullscreen: true,
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
nodeIntegrationInSubFrames: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await closeAllWindows()
|
||||||
|
;(w as any) = null
|
||||||
|
server.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can fullscreen from out-of-process iframes (OOPIFs)', done => {
|
||||||
|
ipcMain.once('fullscreenChange', async () => {
|
||||||
|
const fullscreenWidth = await w.webContents.executeJavaScript(
|
||||||
|
"document.querySelector('iframe').offsetWidth"
|
||||||
|
)
|
||||||
|
expect(fullscreenWidth > 0).to.be.true()
|
||||||
|
|
||||||
|
await w.webContents.executeJavaScript(
|
||||||
|
"document.querySelector('iframe').contentWindow.postMessage('exitFullscreen', '*')"
|
||||||
|
)
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 500))
|
||||||
|
|
||||||
|
const width = await w.webContents.executeJavaScript(
|
||||||
|
"document.querySelector('iframe').offsetWidth"
|
||||||
|
)
|
||||||
|
expect(width).to.equal(0)
|
||||||
|
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
|
||||||
|
const html =
|
||||||
|
'<iframe style="width: 0" frameborder=0 src="http://localhost:8989" allowfullscreen></iframe>'
|
||||||
|
w.loadURL(`data:text/html,${html}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can fullscreen from in-process iframes', done => {
|
||||||
|
ipcMain.once('fullscreenChange', async () => {
|
||||||
|
const fullscreenWidth = await w.webContents.executeJavaScript(
|
||||||
|
"document.querySelector('iframe').offsetWidth"
|
||||||
|
)
|
||||||
|
expect(fullscreenWidth > 0).to.true()
|
||||||
|
|
||||||
|
await w.webContents.executeJavaScript('document.exitFullscreen()')
|
||||||
|
const width = await w.webContents.executeJavaScript(
|
||||||
|
"document.querySelector('iframe').offsetWidth"
|
||||||
|
)
|
||||||
|
expect(width).to.equal(0)
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
|
||||||
|
w.loadFile(path.join(fixturesPath, 'pages', 'fullscreen-ipif.html'))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
15
spec/fixtures/pages/fullscreen-ipif.html
vendored
Normal file
15
spec/fixtures/pages/fullscreen-ipif.html
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<body>
|
||||||
|
<iframe style="width: 0" frameborder=0 src="fullscreen.html" allowfullscreen></iframe>
|
||||||
|
<script>
|
||||||
|
const { webFrame, ipcRenderer } = require('electron')
|
||||||
|
const iframe = document.querySelector('iframe')
|
||||||
|
|
||||||
|
document.addEventListener('fullscreenchange', () => {
|
||||||
|
ipcRenderer.send('fullscreenChange')
|
||||||
|
})
|
||||||
|
|
||||||
|
iframe.addEventListener('load', () => {
|
||||||
|
webFrame.executeJavaScript("document.querySelector('iframe').contentDocument.querySelector('video').requestFullscreen()", true)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</body>
|
19
spec/fixtures/pages/fullscreen-oopif.html
vendored
Normal file
19
spec/fixtures/pages/fullscreen-oopif.html
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<script>
|
||||||
|
const { webFrame, ipcRenderer } = require('electron')
|
||||||
|
|
||||||
|
document.addEventListener('fullscreenchange', () => {
|
||||||
|
ipcRenderer.send('fullscreenChange', webFrame.routingId)
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('message', ({ data }) => {
|
||||||
|
if (data === 'exitFullscreen') {
|
||||||
|
document.exitFullscreen()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
window.focus()
|
||||||
|
webFrame.executeJavaScript('document.querySelector("video").requestFullscreen()', true)
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<video></video>
|
Loading…
Add table
Reference in a new issue