mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
fix: allow iframe-initiated HTML fullscreen to exit while in macOS fullscreen (7-1-x) (#21021)
* 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:
@@ -344,6 +344,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(
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import * as chai from 'chai'
|
||||
import * as chaiAsPromised from 'chai-as-promised'
|
||||
import { BrowserWindow, WebContents, session, ipcMain } from 'electron'
|
||||
import { emittedOnce } from './events-helpers';
|
||||
import { closeAllWindows } from './window-helpers';
|
||||
import * as https from 'https';
|
||||
import * as http from 'http';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import { EventEmitter } from 'events';
|
||||
import { emittedOnce } from './events-helpers'
|
||||
import { closeAllWindows } from './window-helpers'
|
||||
import * as https from 'https'
|
||||
import * as http from 'http'
|
||||
import * as path from 'path'
|
||||
import * as fs from 'fs'
|
||||
import { EventEmitter } from 'events'
|
||||
import { promisify } from 'util'
|
||||
|
||||
const { expect } = chai
|
||||
|
||||
@@ -242,3 +243,81 @@ describe('web security', () => {
|
||||
await p
|
||||
})
|
||||
})
|
||||
|
||||
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>
|
||||
Reference in New Issue
Block a user