sindresorhus / screenfull

Simple wrapper for cross-browser usage of the JavaScript Fullscreen API
https://sindresorhus.com/screenfull
MIT License
7.08k stars 698 forks source link

Possibility of using css selector display-mode: fullscreen for more accurate `isFullscreen` #214

Open MCArth opened 2 years ago

MCArth commented 2 years ago

Hi, I recently stumbled upon the relatively new display-mode: fullscreen css selector and it seems to work very nicely, accurately describing the fullscreen state even when the fullscreen isn't initiated by the current document's scripts (which doesn't work at the moment) - e.g. user presses f11 or document is iframed and externally fullscreened.

Example:

let matchedFullscreenMedia = window.matchMedia('(display-mode: fullscreen)').matches
window.matchMedia('(display-mode: fullscreen)').addEventListener('change', ({ matches }) => {
  matchedFullscreenMedia = matches
});

I've tested in chrome and it works when the user presses f11 or the document is iframed+externally fullscreened and it seems to be well supported (https://caniuse.com/?search=display-mode)

I'm wondering if there are any pitfalls in using this?

av01d commented 1 year ago

I think this is a great way of detecting fullscreen state. A small change in the code (function isFullscreen) adapts this nicely:

Object.defineProperties(screenfull, {
   isFullscreen: {
      get: () => {
         return window.matchMedia('(display-mode: fullscreen)').matches;
      }
   },
   ...
});

You should also modify on('change') (and onchange):

on(event, callback) {
   if ('change' == event) {
      window.matchMedia('(display-mode: fullscreen)').addEventListener('change', callback, false);
   }
   else {
      const eventName = eventNameMap[event];
      if (eventName) {
         document.addEventListener(eventName, callback, false);
      }
   }
},

and off('change'):

off(event, callback) {
   if ('change' == event) {
      window.matchMedia('(display-mode: fullscreen)').removeEventListener('change', callback, false);
   }
   else {
      const eventName = eventNameMap[event];
      if (eventName) {
         document.removeEventListener(eventName, callback, false);
      }
   }
},