fix: allow iframe-initiated HTML fullscreen to exit while in macOS fullscreen ()

* 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:
loc 2019-11-05 16:34:45 -05:00 committed by Samuel Attard
parent fcee7212ce
commit 15dffb3dde
4 changed files with 119 additions and 0 deletions

View file

@ -355,6 +355,13 @@ void CommonWebContentsDelegate::ExitFullscreenModeForTab(
return;
SetHtmlApiFullscreen(false);
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(

View file

@ -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') }
})
})
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'))
})
})

View 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>

View 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>