UNPKG

fullscreenx

Version:

Fullscreen made simple. Zero-dependency, promise-based fullscreen library for modern browsers

8 lines (7 loc) 3.79 kB
/*! * FullscreenX v1.0.0 - Fullscreen made simple. * (c) 2025 Mahyar SBT * MIT License * https://github.com/mahyarsbt/fullscreenx */ !function(e,t){"use strict";"function"==typeof define&&define.amd?define([],t):"object"==typeof module&&module.exports?module.exports=t():e.FullscreenX=t()}("undefined"!=typeof self?self:this,function(){"use strict";const e=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],t=(()=>{if("undefined"==typeof document)return null;for(const n of e){const e=n[1];if(e in document)return{request:n[0],exit:n[1],element:n[2],enabled:n[3],change:n[4],error:n[5]}}return null})(),n={change:[],enter:[],exit:[],error:[]};let r=null,l=null;const u=3e3,s=(e,t,n)=>{const r=e=>{t.removeEventListener(t,r),n(e)};e.addEventListener(t,r)},c=e=>{if(!e)return document.documentElement;if("string"==typeof e){const t=document.querySelector(e);if(!t)throw new Error(`FullscreenX: Element not found for selector "${e}"`);return t}if(e instanceof Element)return e;throw new Error("FullscreenX: Invalid element or selector")},o=(e,t)=>{const r=n[e];for(let e=0;e<r.length;e++)r[e](t)},i=e=>{const n=document[t.element];o("change",e),!r&&n?o("enter",e):r&&!n&&o("exit",e),r=n},a=e=>{o("error",e)};t&&(document.addEventListener(t.change,i,!1),document.addEventListener(t.error,a,!1));const f={request(e,n){if(!t)return Promise.reject(new Error("FullscreenX: Fullscreen API not supported"));if(l)return Promise.reject(new Error("FullscreenX: Request already pending"));const r=c(e);return l=new Promise((e,c)=>{let o,i=!1;const a=()=>{o&&clearTimeout(o),i=!0,l=null},f=()=>{!i&&document[t.element]===r&&(a(),e())},m=e=>{i||(a(),c(new Error("FullscreenX: Request failed")))};s(document,t.change,f),s(document,t.error,m),o=setTimeout(()=>{i||(document.removeEventListener(t.change,f),document.removeEventListener(t.error,m),a(),c(new Error("FullscreenX: Request timeout")))},u);const d=r[t.request](n);d&&"function"==typeof d.then&&d.catch(e=>{i||(a(),c(e))})})},exit(){return t?document[t.element]?l?Promise.reject(new Error("FullscreenX: Request already pending")):l=new Promise((e,n)=>{let r,c=!1;const o=()=>{r&&clearTimeout(r),c=!0,l=null},i=()=>{!c&&!document[t.element]&&(o(),e())},a=()=>{c||(o(),n(new Error("FullscreenX: Exit failed")))};s(document,t.change,i),s(document,t.error,a),r=setTimeout(()=>{c||(document.removeEventListener(t.change,i),document.removeEventListener(t.error,a),o(),n(new Error("FullscreenX: Exit timeout")))},u);const f=document[t.exit]();f&&"function"==typeof f.then&&f.catch(e=>{c||(o(),n(e))})}):Promise.resolve():Promise.reject(new Error("FullscreenX: Fullscreen API not supported"))},toggle(e,t){return this.isFullscreen()?this.exit():this.request(e,t)},isEnabled(){return!(!t||!document[t.enabled])},isFullscreen(){return!(!t||!document[t.element])},element(){return t?document[t.element]||null:null},on(e,t){n[e]&&"function"==typeof t&&-1===n[e].indexOf(t)&&n[e].push(t)},off(e,t){if(n[e]){const r=n[e].indexOf(t);r>-1&&n[e].splice(r,1)}},onchange(e){this.on("change",e)},onerror(e){this.on("error",e)},raw:t||{request:null,exit:null,element:null,enabled:null,change:null,error:null}};return f});