fix: html fullscreen transitions stacking (#32905)
* fix: html fullscreen transitions stacking * spec: move webview test to spec-main
This commit is contained in:
		
					parent
					
						
							
								f44ecb7f03
							
						
					
				
			
			
				commit
				
					
						16db5a112e
					
				
			
		
					 12 changed files with 184 additions and 61 deletions
				
			
		| 
						 | 
				
			
			@ -3673,7 +3673,12 @@ void WebContents::EnumerateDirectory(
 | 
			
		|||
 | 
			
		||||
bool WebContents::IsFullscreenForTabOrPending(
 | 
			
		||||
    const content::WebContents* source) {
 | 
			
		||||
  return html_fullscreen_;
 | 
			
		||||
  bool transition_fs = owner_window()
 | 
			
		||||
                           ? owner_window()->fullscreen_transition_state() !=
 | 
			
		||||
                                 NativeWindow::FullScreenTransitionState::NONE
 | 
			
		||||
                           : false;
 | 
			
		||||
 | 
			
		||||
  return html_fullscreen_ || transition_fs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool WebContents::TakeFocus(content::WebContents* source, bool reverse) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3995,9 +4000,8 @@ void WebContents::SetHtmlApiFullscreen(bool enter_fullscreen) {
 | 
			
		|||
          ? !web_preferences->ShouldDisableHtmlFullscreenWindowResize()
 | 
			
		||||
          : true;
 | 
			
		||||
 | 
			
		||||
  if (html_fullscreenable) {
 | 
			
		||||
  if (html_fullscreenable)
 | 
			
		||||
    owner_window_->SetFullScreen(enter_fullscreen);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  UpdateHtmlApiFullscreen(enter_fullscreen);
 | 
			
		||||
  native_fullscreen_ = false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -718,6 +718,15 @@ std::string NativeWindow::GetAccessibleTitle() {
 | 
			
		|||
  return base::UTF16ToUTF8(accessible_title_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NativeWindow::HandlePendingFullscreenTransitions() {
 | 
			
		||||
  if (pending_transitions_.empty())
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  bool next_transition = pending_transitions_.front();
 | 
			
		||||
  pending_transitions_.pop();
 | 
			
		||||
  SetFullScreen(next_transition);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// static
 | 
			
		||||
int32_t NativeWindow::next_id_ = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@
 | 
			
		|||
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <queue>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -317,6 +318,17 @@ class NativeWindow : public base::SupportsUserData,
 | 
			
		|||
    observers_.RemoveObserver(obs);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  enum class FullScreenTransitionState { ENTERING, EXITING, NONE };
 | 
			
		||||
 | 
			
		||||
  // Handle fullscreen transitions.
 | 
			
		||||
  void HandlePendingFullscreenTransitions();
 | 
			
		||||
  void set_fullscreen_transition_state(FullScreenTransitionState state) {
 | 
			
		||||
    fullscreen_transition_state_ = state;
 | 
			
		||||
  }
 | 
			
		||||
  FullScreenTransitionState fullscreen_transition_state() const {
 | 
			
		||||
    return fullscreen_transition_state_;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  views::Widget* widget() const { return widget_.get(); }
 | 
			
		||||
  views::View* content_view() const { return content_view_; }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -375,6 +387,10 @@ class NativeWindow : public base::SupportsUserData,
 | 
			
		|||
  // The "titleBarStyle" option.
 | 
			
		||||
  TitleBarStyle title_bar_style_ = TitleBarStyle::kNormal;
 | 
			
		||||
 | 
			
		||||
  std::queue<bool> pending_transitions_;
 | 
			
		||||
  FullScreenTransitionState fullscreen_transition_state_ =
 | 
			
		||||
      FullScreenTransitionState::NONE;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  std::unique_ptr<views::Widget> widget_;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,6 @@
 | 
			
		|||
#import <Cocoa/Cocoa.h>
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <queue>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -172,11 +171,6 @@ class NativeWindowMac : public NativeWindow,
 | 
			
		|||
  void SetCollectionBehavior(bool on, NSUInteger flag);
 | 
			
		||||
  void SetWindowLevel(int level);
 | 
			
		||||
 | 
			
		||||
  enum class FullScreenTransitionState { ENTERING, EXITING, NONE };
 | 
			
		||||
 | 
			
		||||
  // Handle fullscreen transitions.
 | 
			
		||||
  void SetFullScreenTransitionState(FullScreenTransitionState state);
 | 
			
		||||
  void HandlePendingFullscreenTransitions();
 | 
			
		||||
  bool HandleDeferredClose();
 | 
			
		||||
  void SetHasDeferredWindowClose(bool defer_close) {
 | 
			
		||||
    has_deferred_window_close_ = defer_close;
 | 
			
		||||
| 
						 | 
				
			
			@ -247,13 +241,6 @@ class NativeWindowMac : public NativeWindow,
 | 
			
		|||
  bool zoom_to_page_width_ = false;
 | 
			
		||||
  absl::optional<gfx::Point> traffic_light_position_;
 | 
			
		||||
 | 
			
		||||
  std::queue<bool> pending_transitions_;
 | 
			
		||||
  FullScreenTransitionState fullscreen_transition_state() const {
 | 
			
		||||
    return fullscreen_transition_state_;
 | 
			
		||||
  }
 | 
			
		||||
  FullScreenTransitionState fullscreen_transition_state_ =
 | 
			
		||||
      FullScreenTransitionState::NONE;
 | 
			
		||||
 | 
			
		||||
  // Trying to close an NSWindow during a fullscreen transition will cause the
 | 
			
		||||
  // window to lock up. Use this to track if CloseWindow was called during a
 | 
			
		||||
  // fullscreen transition, to defer the -[NSWindow close] call until the
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -582,11 +582,6 @@ bool NativeWindowMac::IsVisible() {
 | 
			
		|||
  return [window_ isVisible] && !occluded && !IsMinimized();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NativeWindowMac::SetFullScreenTransitionState(
 | 
			
		||||
    FullScreenTransitionState state) {
 | 
			
		||||
  fullscreen_transition_state_ = state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool NativeWindowMac::IsEnabled() {
 | 
			
		||||
  return [window_ attachedSheet] == nil;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -670,15 +665,6 @@ bool NativeWindowMac::IsMinimized() {
 | 
			
		|||
  return [window_ isMiniaturized];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NativeWindowMac::HandlePendingFullscreenTransitions() {
 | 
			
		||||
  if (pending_transitions_.empty())
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  bool next_transition = pending_transitions_.front();
 | 
			
		||||
  pending_transitions_.pop();
 | 
			
		||||
  SetFullScreen(next_transition);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool NativeWindowMac::HandleDeferredClose() {
 | 
			
		||||
  if (has_deferred_window_close_) {
 | 
			
		||||
    SetHasDeferredWindowClose(false);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -237,7 +237,7 @@ using FullScreenTransitionState =
 | 
			
		|||
  // Store resizable mask so it can be restored after exiting fullscreen.
 | 
			
		||||
  is_resizable_ = shell_->HasStyleMask(NSWindowStyleMaskResizable);
 | 
			
		||||
 | 
			
		||||
  shell_->SetFullScreenTransitionState(FullScreenTransitionState::ENTERING);
 | 
			
		||||
  shell_->set_fullscreen_transition_state(FullScreenTransitionState::ENTERING);
 | 
			
		||||
 | 
			
		||||
  shell_->NotifyWindowWillEnterFullScreen();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -246,7 +246,7 @@ using FullScreenTransitionState =
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
- (void)windowDidEnterFullScreen:(NSNotification*)notification {
 | 
			
		||||
  shell_->SetFullScreenTransitionState(FullScreenTransitionState::NONE);
 | 
			
		||||
  shell_->set_fullscreen_transition_state(FullScreenTransitionState::NONE);
 | 
			
		||||
 | 
			
		||||
  shell_->NotifyWindowEnterFullScreen();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -257,13 +257,13 @@ using FullScreenTransitionState =
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
- (void)windowWillExitFullScreen:(NSNotification*)notification {
 | 
			
		||||
  shell_->SetFullScreenTransitionState(FullScreenTransitionState::EXITING);
 | 
			
		||||
  shell_->set_fullscreen_transition_state(FullScreenTransitionState::EXITING);
 | 
			
		||||
 | 
			
		||||
  shell_->NotifyWindowWillLeaveFullScreen();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)windowDidExitFullScreen:(NSNotification*)notification {
 | 
			
		||||
  shell_->SetFullScreenTransitionState(FullScreenTransitionState::NONE);
 | 
			
		||||
  shell_->set_fullscreen_transition_state(FullScreenTransitionState::NONE);
 | 
			
		||||
 | 
			
		||||
  shell_->SetResizable(is_resizable_);
 | 
			
		||||
  shell_->NotifyWindowLeaveFullScreen();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4731,19 +4731,80 @@ describe('BrowserWindow module', () => {
 | 
			
		|||
        expect(w.isFullScreen()).to.be.false('is fullscreen');
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('handles several HTML fullscreen transitions', async () => {
 | 
			
		||||
        const w = new BrowserWindow();
 | 
			
		||||
        await w.loadFile(path.join(fixtures, 'pages', 'a.html'));
 | 
			
		||||
 | 
			
		||||
        expect(w.isFullScreen()).to.be.false('is fullscreen');
 | 
			
		||||
 | 
			
		||||
        const enterFullScreen = emittedOnce(w, 'enter-full-screen');
 | 
			
		||||
        const leaveFullScreen = emittedOnce(w, 'leave-full-screen');
 | 
			
		||||
 | 
			
		||||
        await w.webContents.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
 | 
			
		||||
        await enterFullScreen;
 | 
			
		||||
        await w.webContents.executeJavaScript('document.exitFullscreen()', true);
 | 
			
		||||
        await leaveFullScreen;
 | 
			
		||||
 | 
			
		||||
        expect(w.isFullScreen()).to.be.false('is fullscreen');
 | 
			
		||||
 | 
			
		||||
        await delay();
 | 
			
		||||
 | 
			
		||||
        await w.webContents.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
 | 
			
		||||
        await enterFullScreen;
 | 
			
		||||
        await w.webContents.executeJavaScript('document.exitFullscreen()', true);
 | 
			
		||||
        await leaveFullScreen;
 | 
			
		||||
 | 
			
		||||
        expect(w.isFullScreen()).to.be.false('is fullscreen');
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('handles several transitions in close proximity', async () => {
 | 
			
		||||
        const w = new BrowserWindow();
 | 
			
		||||
 | 
			
		||||
        expect(w.isFullScreen()).to.be.false('is fullscreen');
 | 
			
		||||
 | 
			
		||||
        const enterFS = emittedNTimes(w, 'enter-full-screen', 2);
 | 
			
		||||
        const leaveFS = emittedNTimes(w, 'leave-full-screen', 2);
 | 
			
		||||
 | 
			
		||||
        w.setFullScreen(true);
 | 
			
		||||
        w.setFullScreen(false);
 | 
			
		||||
        w.setFullScreen(true);
 | 
			
		||||
        w.setFullScreen(false);
 | 
			
		||||
 | 
			
		||||
        const enterFullScreen = emittedNTimes(w, 'enter-full-screen', 2);
 | 
			
		||||
        await enterFullScreen;
 | 
			
		||||
        await Promise.all([enterFS, leaveFS]);
 | 
			
		||||
 | 
			
		||||
        expect(w.isFullScreen()).to.be.true('not fullscreen');
 | 
			
		||||
        expect(w.isFullScreen()).to.be.false('not fullscreen');
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('handles several chromium-initiated transitions in close proximity', async () => {
 | 
			
		||||
        const w = new BrowserWindow();
 | 
			
		||||
        await w.loadFile(path.join(fixtures, 'pages', 'a.html'));
 | 
			
		||||
 | 
			
		||||
        expect(w.isFullScreen()).to.be.false('is fullscreen');
 | 
			
		||||
 | 
			
		||||
        let enterCount = 0;
 | 
			
		||||
        let exitCount = 0;
 | 
			
		||||
 | 
			
		||||
        const done = new Promise<void>(resolve => {
 | 
			
		||||
          const checkDone = () => {
 | 
			
		||||
            if (enterCount === 2 && exitCount === 2) resolve();
 | 
			
		||||
          };
 | 
			
		||||
 | 
			
		||||
          w.webContents.on('enter-html-full-screen', () => {
 | 
			
		||||
            enterCount++;
 | 
			
		||||
            checkDone();
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          w.webContents.on('leave-html-full-screen', () => {
 | 
			
		||||
            exitCount++;
 | 
			
		||||
            checkDone();
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        await w.webContents.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
 | 
			
		||||
        await w.webContents.executeJavaScript('document.exitFullscreen()');
 | 
			
		||||
        await w.webContents.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
 | 
			
		||||
        await w.webContents.executeJavaScript('document.exitFullscreen()');
 | 
			
		||||
        await done;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('does not crash when exiting simpleFullScreen (properties)', async () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ import * as url from 'url';
 | 
			
		|||
import * as ChildProcess from 'child_process';
 | 
			
		||||
import { EventEmitter } from 'events';
 | 
			
		||||
import { promisify } from 'util';
 | 
			
		||||
import { ifit, ifdescribe, delay, defer } from './spec-helpers';
 | 
			
		||||
import { ifit, ifdescribe, defer, delay } from './spec-helpers';
 | 
			
		||||
import { AddressInfo } from 'net';
 | 
			
		||||
import { PipeTransport } from './pipe-transport';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1590,7 +1590,7 @@ describe('iframe using HTML fullscreen API while window is OS-fullscreened', ()
 | 
			
		|||
    server.close();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('can fullscreen from out-of-process iframes (OOPIFs)', async () => {
 | 
			
		||||
  ifit(process.platform !== 'darwin')('can fullscreen from out-of-process iframes (non-macOS)', async () => {
 | 
			
		||||
    const fullscreenChange = emittedOnce(ipcMain, 'fullscreenChange');
 | 
			
		||||
    const html =
 | 
			
		||||
      '<iframe style="width: 0" frameborder=0 src="http://localhost:8989" allowfullscreen></iframe>';
 | 
			
		||||
| 
						 | 
				
			
			@ -1614,8 +1614,37 @@ describe('iframe using HTML fullscreen API while window is OS-fullscreened', ()
 | 
			
		|||
    expect(width).to.equal(0);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  ifit(process.platform === 'darwin')('can fullscreen from out-of-process iframes (macOS)', async () => {
 | 
			
		||||
    await emittedOnce(w, 'enter-full-screen');
 | 
			
		||||
    const fullscreenChange = emittedOnce(ipcMain, 'fullscreenChange');
 | 
			
		||||
    const html =
 | 
			
		||||
      '<iframe style="width: 0" frameborder=0 src="http://localhost:8989" allowfullscreen></iframe>';
 | 
			
		||||
    w.loadURL(`data:text/html,${html}`);
 | 
			
		||||
    await fullscreenChange;
 | 
			
		||||
 | 
			
		||||
    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 emittedOnce(w.webContents, 'leave-html-full-screen');
 | 
			
		||||
 | 
			
		||||
    const width = await w.webContents.executeJavaScript(
 | 
			
		||||
      "document.querySelector('iframe').offsetWidth"
 | 
			
		||||
    );
 | 
			
		||||
    expect(width).to.equal(0);
 | 
			
		||||
 | 
			
		||||
    w.setFullScreen(false);
 | 
			
		||||
    await emittedOnce(w, 'leave-full-screen');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // TODO(jkleinsc) fix this flaky test on WOA
 | 
			
		||||
  ifit(process.platform !== 'win32' || process.arch !== 'arm64')('can fullscreen from in-process iframes', async () => {
 | 
			
		||||
    if (process.platform === 'darwin') await emittedOnce(w, 'enter-full-screen');
 | 
			
		||||
 | 
			
		||||
    const fullscreenChange = emittedOnce(ipcMain, 'fullscreenChange');
 | 
			
		||||
    w.loadFile(path.join(fixturesPath, 'pages', 'fullscreen-ipif.html'));
 | 
			
		||||
    await fullscreenChange;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
  <div id="div">
 | 
			
		||||
    WebView
 | 
			
		||||
  </div>
 | 
			
		||||
  <video></video>
 | 
			
		||||
  <script type="text/javascript" charset="utf-8">
 | 
			
		||||
    const {ipcRenderer} = require('electron')
 | 
			
		||||
    ipcRenderer.send('webview-ready')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -426,11 +426,16 @@ describe('<webview> tag', function () {
 | 
			
		|||
          contextIsolation: false
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      const attachPromise = emittedOnce(w.webContents, 'did-attach-webview');
 | 
			
		||||
      const loadPromise = emittedOnce(w.webContents, 'did-finish-load');
 | 
			
		||||
      const readyPromise = emittedOnce(ipcMain, 'webview-ready');
 | 
			
		||||
 | 
			
		||||
      w.loadFile(path.join(__dirname, 'fixtures', 'webview', 'fullscreen', 'main.html'));
 | 
			
		||||
 | 
			
		||||
      const [, webview] = await attachPromise;
 | 
			
		||||
      await readyPromise;
 | 
			
		||||
      await Promise.all([readyPromise, loadPromise]);
 | 
			
		||||
 | 
			
		||||
      return [w, webview];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -442,17 +447,38 @@ describe('<webview> tag', function () {
 | 
			
		|||
      closeAllWindows();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should make parent frame element fullscreen too', async () => {
 | 
			
		||||
    ifit(process.platform !== 'darwin')('should make parent frame element fullscreen too (non-macOS)', async () => {
 | 
			
		||||
      const [w, webview] = await loadWebViewWindow();
 | 
			
		||||
      expect(await w.webContents.executeJavaScript('isIframeFullscreen()')).to.be.false();
 | 
			
		||||
 | 
			
		||||
      const parentFullscreen = emittedOnce(ipcMain, 'fullscreenchange');
 | 
			
		||||
      await webview.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
 | 
			
		||||
      await parentFullscreen;
 | 
			
		||||
 | 
			
		||||
      expect(await w.webContents.executeJavaScript('isIframeFullscreen()')).to.be.true();
 | 
			
		||||
 | 
			
		||||
      const close = emittedOnce(w, 'closed');
 | 
			
		||||
      w.close();
 | 
			
		||||
      await emittedOnce(w, 'closed');
 | 
			
		||||
      await close;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    ifit(process.platform === 'darwin')('should make parent frame element fullscreen too (macOS)', async () => {
 | 
			
		||||
      const [w, webview] = await loadWebViewWindow();
 | 
			
		||||
      expect(await w.webContents.executeJavaScript('isIframeFullscreen()')).to.be.false();
 | 
			
		||||
 | 
			
		||||
      const parentFullscreen = emittedOnce(ipcMain, 'fullscreenchange');
 | 
			
		||||
      const enterHTMLFS = emittedOnce(w.webContents, 'enter-html-full-screen');
 | 
			
		||||
      const leaveHTMLFS = emittedOnce(w.webContents, 'leave-html-full-screen');
 | 
			
		||||
 | 
			
		||||
      await webview.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
 | 
			
		||||
      expect(await w.webContents.executeJavaScript('isIframeFullscreen()')).to.be.true();
 | 
			
		||||
 | 
			
		||||
      await webview.executeJavaScript('document.exitFullscreen()');
 | 
			
		||||
      await Promise.all([enterHTMLFS, leaveHTMLFS, parentFullscreen]);
 | 
			
		||||
 | 
			
		||||
      const close = emittedOnce(w, 'closed');
 | 
			
		||||
      w.close();
 | 
			
		||||
      await close;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // FIXME(zcbenz): Fullscreen events do not work on Linux.
 | 
			
		||||
| 
						 | 
				
			
			@ -468,8 +494,9 @@ describe('<webview> tag', function () {
 | 
			
		|||
      await delay(0);
 | 
			
		||||
      expect(w.isFullScreen()).to.be.false();
 | 
			
		||||
 | 
			
		||||
      const close = emittedOnce(w, 'closed');
 | 
			
		||||
      w.close();
 | 
			
		||||
      await emittedOnce(w, 'closed');
 | 
			
		||||
      await close;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Sending ESC via sendInputEvent only works on Windows.
 | 
			
		||||
| 
						 | 
				
			
			@ -485,8 +512,9 @@ describe('<webview> tag', function () {
 | 
			
		|||
      await delay(0);
 | 
			
		||||
      expect(w.isFullScreen()).to.be.false();
 | 
			
		||||
 | 
			
		||||
      const close = emittedOnce(w, 'closed');
 | 
			
		||||
      w.close();
 | 
			
		||||
      await emittedOnce(w, 'closed');
 | 
			
		||||
      await close;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('pressing ESC should emit the leave-html-full-screen event', async () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -513,11 +541,27 @@ describe('<webview> tag', function () {
 | 
			
		|||
      const leaveFSWindow = emittedOnce(w, 'leave-html-full-screen');
 | 
			
		||||
      const leaveFSWebview = emittedOnce(webContents, 'leave-html-full-screen');
 | 
			
		||||
      webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Escape' });
 | 
			
		||||
      await leaveFSWindow;
 | 
			
		||||
      await leaveFSWebview;
 | 
			
		||||
      await leaveFSWindow;
 | 
			
		||||
 | 
			
		||||
      const close = emittedOnce(w, 'closed');
 | 
			
		||||
      w.close();
 | 
			
		||||
      await emittedOnce(w, 'closed');
 | 
			
		||||
      await close;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should support user gesture', async () => {
 | 
			
		||||
      const [w, webview] = await loadWebViewWindow();
 | 
			
		||||
 | 
			
		||||
      const waitForEnterHtmlFullScreen = emittedOnce(webview, 'enter-html-full-screen');
 | 
			
		||||
 | 
			
		||||
      const jsScript = "document.querySelector('video').webkitRequestFullscreen()";
 | 
			
		||||
      webview.executeJavaScript(jsScript, true);
 | 
			
		||||
 | 
			
		||||
      await waitForEnterHtmlFullScreen;
 | 
			
		||||
 | 
			
		||||
      const close = emittedOnce(w, 'closed');
 | 
			
		||||
      w.close();
 | 
			
		||||
      await close;
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								spec/fixtures/pages/fullscreen.html
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								spec/fixtures/pages/fullscreen.html
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
<video></video>
 | 
			
		||||
<video></video>
 | 
			
		||||
| 
						 | 
				
			
			@ -910,20 +910,6 @@ describe('<webview> tag', function () {
 | 
			
		|||
  });
 | 
			
		||||
 | 
			
		||||
  describe('executeJavaScript', () => {
 | 
			
		||||
    it('should support user gesture', async () => {
 | 
			
		||||
      await loadWebView(webview, {
 | 
			
		||||
        src: `file://${fixtures}/pages/fullscreen.html`
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // Event handler has to be added before js execution.
 | 
			
		||||
      const waitForEnterHtmlFullScreen = waitForEvent(webview, 'enter-html-full-screen');
 | 
			
		||||
 | 
			
		||||
      const jsScript = "document.querySelector('video').webkitRequestFullscreen()";
 | 
			
		||||
      webview.executeJavaScript(jsScript, true);
 | 
			
		||||
 | 
			
		||||
      return waitForEnterHtmlFullScreen;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('can return the result of the executed script', async () => {
 | 
			
		||||
      await loadWebView(webview, {
 | 
			
		||||
        src: 'about:blank'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue