├── .prettierrc.yml ├── .npmrc ├── .prettierignore ├── .gitignore ├── .travis.yml ├── changelog.md ├── src ├── metadata.ts └── index.ts ├── tsconfig.json ├── .editorconfig ├── LICENSE ├── package.json ├── tslint.json ├── test └── index.html ├── webpack.config.js ├── README.md └── dist └── release ├── fullscreen.js └── fullscreen.js.map /.prettierrc.yml: -------------------------------------------------------------------------------- 1 | singleQuote: false 2 | trailingComma: all 3 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # git tag prefix 2 | tag-version-prefix="" 3 | 4 | # disable package-lock.json 5 | package-lock=false 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | demo/**/* 2 | dist/**/* 3 | coverage/**/* 4 | node_modules/**/* 5 | 6 | # ignore root configration files 7 | *.json 8 | *.yml 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | .idea 3 | .vscode 4 | 5 | dist/* 6 | !dist/release 7 | 8 | deploy 9 | coverage 10 | node_modules 11 | 12 | npm-debug.log* 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | language: node_js 3 | node_js: 4 | - lts/* 5 | 6 | before_script: 7 | - npm i 8 | 9 | script: 10 | - npm run tslint 11 | 12 | deploy: 13 | provider: npm 14 | email: "$NPM_EMAIL" 15 | api_key: "$NPM_TOKEN" 16 | on: 17 | tags: true 18 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | > `(*)` meaning `breaking change` 4 | 5 | ### 3.0.0 6 | 7 | - Upgrade project 8 | - Remove `fs.toggleFullscreen()` method (\*) 9 | - Change behaviour of `fs.addListener/fs.removeListener` methods (\*) 10 | - Support returned promise of `fs.requestFullscreen/fs.exitFullscreen` 11 | -------------------------------------------------------------------------------- /src/metadata.ts: -------------------------------------------------------------------------------- 1 | interface ProjectMetadata { 2 | readonly name: string; 3 | readonly version: string; 4 | readonly revision: string; 5 | readonly production: boolean; 6 | readonly lastCompiled: string; 7 | } 8 | 9 | // @ts-ignore (from webpack.DefinePlugin) 10 | export const metadata: ProjectMetadata = Object.freeze(__X_METADATA__); 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "strict": true, 5 | "sourceMap": true, 6 | "skipLibCheck": true, 7 | "importHelpers": true, 8 | "esModuleInterop": true, 9 | "resolveJsonModule": true, 10 | "downlevelIteration": true, 11 | "suppressImplicitAnyIndexErrors": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "experimentalDecorators": false, 14 | "emitDecoratorMetadata": false, 15 | "jsx": "react", 16 | "outDir": "./dist/out-tsc", 17 | "target": "es5", 18 | "moduleResolution": "node", 19 | "lib": [ 20 | "dom", 21 | "scripthost", 22 | "esnext" 23 | ] 24 | }, 25 | "include": [ 26 | "**/*" 27 | ], 28 | "exclude": [ 29 | "node_modules" 30 | ] 31 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Option for setting a maximum length for each line 7 | # Supported By A Limited Number of Editors 8 | # https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#supported-by-a-limited-number-of-editors 9 | [*] 10 | max_line_length = 120 11 | 12 | # Unix-style newlines with a newline ending every file 13 | [*] 14 | end_of_line = lf 15 | 16 | # Matches multiple files with brace expansion notation 17 | # Set default charset 18 | [*] 19 | charset = utf-8 20 | 21 | # 4 space indentation 22 | [*] 23 | indent_style = space 24 | indent_size = 4 25 | 26 | # Matches the exact files 27 | [*.{json,yml}] 28 | indent_style = space 29 | indent_size = 2 30 | 31 | # Configration files 32 | [.*] 33 | indent_style = space 34 | indent_size = 2 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 L&H 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@semibold/fullscreen", 3 | "version": "3.1.0", 4 | "description": "JavaScript Fullscreen API. Support different frames(documents)", 5 | "browser": "dist/release/fullscreen.js", 6 | "types": "src/index.ts", 7 | "scripts": { 8 | "build": "webpack --mode=production --devtool=source-map", 9 | "start": "webpack -w --mode=development --devtool=cheap-module-eval-source-map", 10 | "tslint": "tslint -c tslint.json -p tsconfig.json", 11 | "version": "npm run build && git add -A dist" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/Semibold/Fullscreen.git" 16 | }, 17 | "keywords": [ 18 | "browser", 19 | "fullscreen" 20 | ], 21 | "author": "Aqours", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/Semibold/Fullscreen/issues" 25 | }, 26 | "homepage": "https://github.com/Semibold/Fullscreen#readme", 27 | "engines": { 28 | "node": ">=8.9.0" 29 | }, 30 | "husky": { 31 | "hooks": { 32 | "pre-commit": "pretty-quick --staged" 33 | } 34 | }, 35 | "publishConfig": { 36 | "access": "public" 37 | }, 38 | "devDependencies": { 39 | "@types/node": "8.9.5", 40 | "event-hooks-webpack-plugin": "2.1.1", 41 | "git-rev-sync": "1.12.0", 42 | "husky": "1.3.1", 43 | "prettier": "1.15.3", 44 | "pretty-quick": "1.8.0", 45 | "rimraf": "2.6.2", 46 | "shell-env": "2.1.0", 47 | "ts-loader": "5.3.2", 48 | "tslint": "5.12.0", 49 | "typescript": "3.2.2", 50 | "uglifyjs-webpack-plugin": "2.1.1", 51 | "webpack": "4.28.2", 52 | "webpack-bundle-analyzer": "3.3.2", 53 | "webpack-cli": "3.1.2" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "linterOptions": { 3 | "exclude": [ 4 | "demo/**", 5 | "dist/**", 6 | "coverage/**", 7 | "node_modules/**" 8 | ] 9 | }, 10 | "rules": { 11 | "member-ordering": { 12 | "options": [ 13 | { 14 | "order": [ 15 | "static-field", 16 | "instance-field", 17 | "constructor", 18 | "static-method", 19 | "instance-method" 20 | ] 21 | } 22 | ] 23 | }, 24 | "no-inferrable-types": [ 25 | true, 26 | "ignore-params", 27 | "ignore-properties" 28 | ], 29 | "no-internal-module": true, 30 | "no-namespace": [ 31 | true, 32 | "allow-declarations" 33 | ], 34 | "typedef": true, 35 | "unified-signatures": true, 36 | "ban-comma-operator": true, 37 | "label-position": true, 38 | "no-arg": true, 39 | "no-console": { 40 | "severity": "warning" 41 | }, 42 | "no-construct": true, 43 | "no-debugger": true, 44 | "no-duplicate-super": true, 45 | "no-duplicate-switch-case": true, 46 | "no-eval": true, 47 | "no-for-in-array": true, 48 | "no-misused-new": true, 49 | "no-sparse-arrays": true, 50 | "no-string-throw": true, 51 | "no-switch-case-fall-through": true, 52 | "no-this-assignment": [ 53 | true, 54 | { 55 | "allowed-names": [ 56 | "^that$" 57 | ], 58 | "allow-destructuring": true 59 | } 60 | ], 61 | "no-unsafe-finally": true, 62 | "no-var-keyword": true, 63 | "radix": true, 64 | "triple-equals": [ 65 | true, 66 | "allow-null-check" 67 | ], 68 | "use-isnan": true, 69 | "deprecation": { 70 | "severity": "warning" 71 | }, 72 | "no-require-imports": true, 73 | "callable-types": true, 74 | "class-name": true, 75 | "interface-over-type-literal": true, 76 | "new-parens": true, 77 | "no-boolean-literal-compare": true, 78 | "variable-name": [ 79 | true, 80 | "ban-keywords", 81 | "allow-snake-case", 82 | "check-format" 83 | ] 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | test 7 | 40 | 41 | 42 |
43 | 46 | 50 |
51 | 52 | 53 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const rimraf = require("rimraf"); 3 | const webpack = require("webpack"); 4 | const shell = require("shell-env"); 5 | const git = require("git-rev-sync"); 6 | const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); 7 | const EventHooksPlugin = require("event-hooks-webpack-plugin"); 8 | const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); 9 | 10 | const manifest = require("./package.json"); 11 | 12 | const shellEnv = Object(shell.sync()); 13 | const webpackPath = path.resolve(__dirname, "dist/webpack"); 14 | const releasePath = path.resolve(__dirname, "dist/release"); 15 | 16 | /** 17 | * @readonly 18 | * @desc Webpack/Custom Command Line Interface 19 | */ 20 | class CustomDefaultConfig { 21 | static get argv() { 22 | return { 23 | mode: "production", 24 | devtool: false, 25 | }; 26 | } 27 | 28 | static get env() { 29 | return { 30 | // Custom envionment variables 31 | }; 32 | } 33 | 34 | constructor(envProxy, argvProxy) { 35 | this.envProxy = envProxy; 36 | this.argvProxy = argvProxy; 37 | this.lastCompiled = new Date().toISOString(); 38 | } 39 | 40 | get production() { 41 | return this.argvProxy.mode === "production"; 42 | } 43 | 44 | get outputPath() { 45 | return this.production ? releasePath : webpackPath; 46 | } 47 | } 48 | 49 | /** 50 | * @desc Webpack Config 51 | */ 52 | module.exports = function(_env = {}, _argv = {}) { 53 | const env = new Proxy(CustomDefaultConfig.env, { 54 | get(target, key, receiver) { 55 | if (_env[key] != null) return _env[key]; 56 | return Reflect.get(target, key, receiver); 57 | }, 58 | }); 59 | const argv = new Proxy(CustomDefaultConfig.argv, { 60 | get(target, key, receiver) { 61 | if (_argv[key] != null) return _argv[key]; 62 | return Reflect.get(target, key, receiver); 63 | }, 64 | }); 65 | const config = new CustomDefaultConfig(env, argv); 66 | const preamble = `/*! @preserve ${manifest.name}: ${manifest.version}-${git.short()} (${config.lastCompiled}) */`; 67 | 68 | console.log(`webpack mode: ${argv.mode}, git revision: ${git.short()}, current branch: ${git.branch()}`); 69 | 70 | return { 71 | mode: argv.mode, 72 | entry: { 73 | fullscreen: "./src/index.ts", 74 | }, 75 | devtool: argv.devtool, 76 | module: { 77 | rules: [ 78 | { 79 | test: /\.tsx?$/, 80 | use: [ 81 | { 82 | loader: "ts-loader", 83 | options: { 84 | compilerOptions: { 85 | module: "esnext", 86 | }, 87 | }, 88 | }, 89 | ], 90 | }, 91 | ], 92 | }, 93 | output: { 94 | path: config.outputPath, 95 | filename: "[name].js", 96 | libraryTarget: "umd", 97 | }, 98 | resolve: { 99 | extensions: [".tsx", ".ts", ".jsx", ".js"], 100 | }, 101 | plugins: [ 102 | new webpack.ProgressPlugin(shellEnv["CI"] ? new Function() : null), 103 | new webpack.DefinePlugin({ 104 | __X_METADATA__: JSON.stringify({ 105 | name: manifest.name, 106 | version: manifest.version, 107 | revision: git.short(), 108 | production: config.production, 109 | lastCompiled: config.lastCompiled, 110 | }), 111 | }), 112 | new EventHooksPlugin({ 113 | environment: function() { 114 | if (config.production) { 115 | rimraf.sync(releasePath); 116 | } else { 117 | rimraf.sync(webpackPath); 118 | } 119 | }, 120 | }), 121 | new BundleAnalyzerPlugin({ 122 | analyzerMode: config.production ? "static" : "disabled", 123 | openAnalyzer: false, 124 | }), 125 | ], 126 | optimization: { 127 | minimizer: [ 128 | new UglifyJsPlugin({ 129 | sourceMap: Boolean(argv.devtool), 130 | extractComments: false, 131 | uglifyOptions: { 132 | compress: { 133 | drop_console: false, 134 | drop_debugger: true, 135 | }, 136 | output: { 137 | /** 138 | * @desc escape Unicode characters in strings and regexps 139 | * (affects directives with non-ascii characters becoming invalid) 140 | */ 141 | ascii_only: false, 142 | 143 | /** 144 | * A real coup for debugging! 145 | */ 146 | max_line_len: 4096, 147 | preamble: preamble, 148 | }, 149 | }, 150 | }), 151 | ], 152 | }, 153 | node: false, 154 | }; 155 | }; 156 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fullscreen 2 | 3 | > [Changelog](changelog.md) 4 | 5 | > Modern JavaScript Fullscreen API. Just for browser. 6 | 7 | ## Install 8 | 9 | > Source code is written by TypeScript. 10 | 11 | `$ npm i @semibold/fullscreen` 12 | 13 | ## Usage 14 | 15 | ```js 16 | // Global 17 | // 18 | 19 | // NodeJS Module 20 | const { Fullscreen } = require("@semibold/fullscreen"); 21 | 22 | // ES-next Module 23 | import { Fullscreen } from "@semibold/fullscreen"; 24 | ``` 25 | 26 | ## Support 27 | 28 | More Information: [Can I Use Fullscreen?](http://caniuse.com/#search=fullscreen) 29 | 30 | ## Instance & API 31 | 32 | ```js 33 | /** 34 | * @param {Element} target - target element 35 | */ 36 | const fs = new Fullscreen(target); 37 | 38 | /** 39 | * @typedef {Object} Metadata 40 | * @property {string} name 41 | * @property {string} version 42 | * @property {string} revision 43 | * @property {boolean} production 44 | * @property {string} lastCompiled 45 | * @return {Metadata} 46 | */ 47 | Fullscreen.metadata; 48 | 49 | /** 50 | * @return {Element} - get current target element 51 | */ 52 | fs.currentElement; 53 | 54 | /** 55 | * @return {FullscreenAPIMapping | null} 56 | */ 57 | fs.fullscreenMapping; 58 | 59 | /** 60 | * @desc The `fullscreenEnabled` attribute tells you whether or not the document is 61 | * currently in a state that would allow fullscreen mode to be requested. 62 | * 63 | * @return {boolean} 64 | */ 65 | fs.fullscreenEnabled; 66 | 67 | /** 68 | * @desc The `fullscreenElement` attribute tells you the element that's currently being 69 | * displayed fullscreen. If this is non-null, the document is in fullscreen mode. 70 | * If this is null, the document is not in fullscreen mode. 71 | * 72 | * @return {Element | null} 73 | */ 74 | fs.fullscreenElement; 75 | 76 | /** 77 | * @desc Return BrowsingContextPromise 78 | * 79 | * @return {PromiseConstructor | null} 80 | */ 81 | fs.getBrowsingContextPromise(); 82 | 83 | /** 84 | * @desc The `fs.requestFullscreen()` method issues an asynchronous request to make 85 | * the target be displayed full-screen. 86 | * @desc It will always return promise if BrowsingContextPromise is available. 87 | * 88 | * @param {Object} [options] 89 | * @param {"auto" | "show" | "hide"} [options.navigationUI] 90 | * 91 | * @return {Promise | void} 92 | */ 93 | fs.requestFullscreen(options); 94 | 95 | /** 96 | * @desc The `fs.exitFullscreen()` is a method that takes the target out of 97 | * full-screen mode. 98 | * @desc It will always return promise if BrowsingContextPromise is available. 99 | * 100 | * @param {boolean} [isBrowsingContext] 101 | * @desc `fs.exitFullscreen()` does nothing if `document.fullscreenElement !== target`. 102 | * @desc `fs.exitFullscreen(true)` equal to `docuemnt.exitFullscreen()`. 103 | * 104 | * @return {Promise | void} 105 | */ 106 | fs.exitFullscreen(isBrowsingContext); 107 | 108 | /** 109 | * @desc Needn't to add prefix to the `type` 110 | * @desc The `fullscreenchange` event is fired when the document is switched to/out-of 111 | * fullscreen mode. 112 | * @desc The fullscreenerror event is fired when the document cannot switch to fullscreen 113 | * mode. 114 | * 115 | * @param {FullscreenEventType} type - "fullscreenchange" | "fullscreenerror" 116 | * @param {EventListenerOrEventListenerObject} listener 117 | * @param {boolean | AddEventListenerOptions} [options] 118 | * 119 | * @deprecated Use returned promise if BrowsingContextPromise is available. 120 | */ 121 | fs.addListener(type, listener, options); 122 | 123 | /** 124 | * @desc Needn't to add prefix to the `type` 125 | * @desc Similar to `fs.addEventListener(type, listener, options)` 126 | * 127 | * @param {FullscreenEventType} type - "fullscreenchange" | "fullscreenerror" 128 | * @param {EventListenerOrEventListenerObject} listener 129 | * @param {boolean | EventListenerOptions} [options] 130 | * 131 | * @deprecated Use returned promise if BrowsingContextPromise is available. 132 | */ 133 | fs.removeListener(type, listener, options); 134 | ``` 135 | 136 | ## Example 137 | 138 | ```js 139 | const fs = new Fullscreen(document.body); 140 | 141 | function onFullscreenChange(e) { 142 | console.log("fullscreenchange event triggered"); 143 | } 144 | 145 | if (fs.fullscreenEnabled) { 146 | console.log(fs.currentElement === document.body); // log: true 147 | 148 | fs.addListener("fullscreenchange", onFullscreenChange); 149 | fs.requestFullscreen(); // triggered by gesture 150 | 151 | if (fs.getBrowsingContextPromise()) { 152 | fs.exitFullscreen() 153 | .then(() => { 154 | console.log("Everything is ok."); 155 | }) 156 | .catch(err => { 157 | if (err) { 158 | console.warn(err); 159 | } else { 160 | alert("Cannot exit fullscreen mode."); 161 | } 162 | }); 163 | } 164 | } 165 | ``` 166 | 167 | ## Non-public API 168 | 169 | ```js 170 | /** 171 | * @desc Be Careful: these methods only support a handful of the latest browsers. 172 | * 173 | * @desc Equal to `Element.onfullscreenchange` and `Element.onfullscreenerror` 174 | * @desc Equal to `Element.addEventListener` and `Element.removeEventListener` 175 | * 176 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenchange 177 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenerror 178 | */ 179 | fs.onfullscreenchange; 180 | fs.onfullscreenerror; 181 | fs.addEventListener(type, listener, options); 182 | fs.removeEventListener(type, listener, options); 183 | ``` 184 | 185 | ## FAQ 186 | 187 | - Should I use deprecated method(`fs.addListener/fs.removeListener`)? 188 | - You should use these method if BrowsingContextPromise is unavailable . 189 | - Why remove `fs.toggleFullscreen` method? 190 | - Because this method isn't reliable if browser support options of `fs.requestFullscreen(options)`. 191 | - Can I use non-public methods(`fs.addEventListener/fs.removeEventListener/...`)? 192 | - It depends on you. These methods only support a handful of the latest browsers. 193 | 194 | ## Reference 195 | 196 | - [MDN - Fullscreen API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API) 197 | - [WhatWG - Fullscreen API](https://fullscreen.spec.whatwg.org/) 198 | -------------------------------------------------------------------------------- /dist/release/fullscreen.js: -------------------------------------------------------------------------------- 1 | /*! @preserve @semibold/fullscreen: 3.1.0-2219a1b (2018-12-28T09:59:30.931Z) */ 2 | !function(e,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define([],n);else{var r=n();for(var t in r)("object"==typeof exports?exports:e)[t]=r[t]}}(window,function(){return function(r){var t={};function l(e){if(t[e])return t[e].exports;var n=t[e]={i:e,l:!1,exports:{}};return r[e].call(n.exports,n,n.exports,l),n.l=!0,n.exports}return l.m=r,l.c=t,l.d=function(e,n,r){l.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(n,e){if(1&e&&(n=l(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var r=Object.create(null);if(l.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var t in n)l.d(r,t,function(e){return n[e]}.bind(null,t));return r},l.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(n,"a",n),n},l.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},l.p="",l(l.s=0)}([function(e,n,r){"use strict";r.r(n);var t=Object.freeze({name:"@semibold/fullscreen",version:"3.1.0",revision:"2219a1b",production:!0,lastCompiled:"2018-12-28T09:59:30.931Z"});r.d(n,"Fullscreen",function(){return l});var l=function(){function e(e){this.cfs=null,this.fss=[{fullscreenEnabled:"fullscreenEnabled",fullscreenElement:"fullscreenElement",onfullscreenchange:"onfullscreenchange",onfullscreenerror:"onfullscreenerror",requestFullscreen:"requestFullscreen",exitFullscreen:"exitFullscreen",fullscreenchange:"fullscreenchange",fullscreenerror:"fullscreenerror"},{fullscreenEnabled:"webkitFullscreenEnabled",fullscreenElement:"webkitFullscreenElement",onfullscreenchange:"onwebkitfullscreenchange",onfullscreenerror:"onwebkitfullscreenerror",requestFullscreen:"webkitRequestFullscreen",exitFullscreen:"webkitExitFullscreen",fullscreenchange:"webkitfullscreenchange",fullscreenerror:"webkitfullscreenerror"},{fullscreenEnabled:"mozFullScreenEnabled",fullscreenElement:"mozFullScreenElement",onfullscreenchange:"onmozfullscreenchange",onfullscreenerror:"onmozfullscreenerror",requestFullscreen:"mozRequestFullScreen",exitFullscreen:"mozCancelFullScreen",fullscreenchange:"mozfullscreenchange",fullscreenerror:"mozfullscreenerror"},{fullscreenEnabled:"msFullscreenEnabled",fullscreenElement:"msFullscreenElement",onfullscreenchange:"onmsfullscreenchange",onfullscreenerror:"onmsfullscreenerror",requestFullscreen:"msRequestFullscreen",exitFullscreen:"msExitFullscreen",fullscreenchange:"MSFullscreenChange",fullscreenerror:"MSFullscreenError"}],this.ele=e,this.doc=this.ele.ownerDocument||document,this.win=this.doc.defaultView||window;for(var n=0;nthis.fss[i]; 79 | break; 80 | } 81 | } 82 | } 83 | 84 | static get metadata() { 85 | return metadata; 86 | } 87 | 88 | get currentElement(): Element { 89 | return this.ele; 90 | } 91 | 92 | get fullscreenMapping(): FullscreenAPIMapping | null { 93 | return this.cfs; 94 | } 95 | 96 | get fullscreenEnabled(): boolean { 97 | if (this.cfs) { 98 | return Boolean(this.doc[this.cfs.fullscreenEnabled]); 99 | } else { 100 | return false; 101 | } 102 | } 103 | 104 | get fullscreenElement(): Element | null { 105 | if (this.cfs) { 106 | return this.doc[this.cfs.fullscreenElement] || null; 107 | } else { 108 | return null; 109 | } 110 | } 111 | 112 | getBrowsingContextPromise(): PromiseConstructor | null { 113 | const maybePromise = this.win["Promise"]; 114 | if ( 115 | typeof maybePromise === "function" && 116 | typeof maybePromise.resolve === "function" && 117 | typeof maybePromise.reject === "function" 118 | ) { 119 | return maybePromise; 120 | } else { 121 | return null; 122 | } 123 | } 124 | 125 | requestFullscreen(options?: FullscreenOptions): Promise | void { 126 | if (this.cfs) { 127 | // tslint:disable-next-line 128 | const Promise = this.getBrowsingContextPromise(); 129 | if (Promise) { 130 | const p1: Promise = new Promise((resolve, reject) => { 131 | const onchange = (e: Event) => { 132 | if (this.fullscreenElement === this.currentElement) { 133 | this.removeEventListener("fullscreenchange", onchange, true); 134 | this.removeEventListener("fullscreenerror", onerror, true); 135 | this.removeListener("fullscreenchange", onchange); 136 | this.removeListener("fullscreenerror", onerror); 137 | resolve(); 138 | } 139 | }; 140 | const onerror = (e: Event) => { 141 | if (this.fullscreenElement !== this.currentElement) { 142 | this.removeEventListener("fullscreenchange", onchange, true); 143 | this.removeEventListener("fullscreenerror", onerror, true); 144 | this.removeListener("fullscreenchange", onchange); 145 | this.removeListener("fullscreenerror", onerror); 146 | reject(/* new Error(message)? */); 147 | } 148 | }; 149 | this.addEventListener("fullscreenchange", onchange, true); 150 | this.addEventListener("fullscreenerror", onerror, true); 151 | this.addListener("fullscreenchange", onchange); 152 | this.addListener("fullscreenerror", onerror); 153 | }); 154 | const p2 = this.ele[this.cfs.requestFullscreen](options); 155 | if (p2 && typeof p2.then === "function" && typeof p2.catch === "function") { 156 | return p2; 157 | } else { 158 | return p1; 159 | } 160 | } else { 161 | return this.ele[this.cfs.requestFullscreen](options); 162 | } 163 | } 164 | } 165 | 166 | exitFullscreen(isBrowsingContext?: boolean): Promise | void { 167 | if (this.cfs) { 168 | // tslint:disable-next-line 169 | const Promise = this.getBrowsingContextPromise(); 170 | if (Promise) { 171 | if (isBrowsingContext || this.fullscreenElement === this.ele) { 172 | const p1: Promise = new Promise((resolve, reject) => { 173 | const onchange = (e: Event) => { 174 | if (isBrowsingContext || this.fullscreenElement !== this.currentElement) { 175 | this.removeEventListener("fullscreenchange", onchange, true); 176 | this.removeEventListener("fullscreenerror", onerror, true); 177 | this.removeListener("fullscreenchange", onchange); 178 | this.removeListener("fullscreenerror", onerror); 179 | resolve(); 180 | } 181 | }; 182 | const onerror = (e: Event) => { 183 | if (isBrowsingContext || this.fullscreenElement === this.currentElement) { 184 | this.removeEventListener("fullscreenchange", onchange, true); 185 | this.removeEventListener("fullscreenerror", onerror, true); 186 | this.removeListener("fullscreenchange", onchange); 187 | this.removeListener("fullscreenerror", onerror); 188 | reject(/* new Error(message)? */); 189 | } 190 | }; 191 | this.addEventListener("fullscreenchange", onchange, true); 192 | this.addEventListener("fullscreenerror", onerror, true); 193 | this.addListener("fullscreenchange", onchange); 194 | this.addListener("fullscreenerror", onerror); 195 | }); 196 | const p2 = this.doc[this.cfs.exitFullscreen](); 197 | if (p2 && typeof p2.then === "function" && typeof p2.catch === "function") { 198 | return p2; 199 | } else { 200 | return p1; 201 | } 202 | } else { 203 | return Promise.reject( 204 | new this.win["TypeError"]( 205 | "The document containing the element isn't fully active; that is, it's not the current active document.", 206 | ), 207 | ); 208 | } 209 | } else { 210 | if (isBrowsingContext || this.fullscreenElement === this.ele) { 211 | return this.doc[this.cfs.exitFullscreen](); 212 | } 213 | } 214 | } 215 | } 216 | 217 | /** 218 | * @desc Modern APIs 219 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenchange#Browser_compatibility 220 | */ 221 | get onfullscreenchange() { 222 | if (this.cfs) { 223 | return this.ele[this.cfs.onfullscreenchange]; 224 | } else { 225 | return null; 226 | } 227 | } 228 | 229 | /** 230 | * @desc Modern APIs 231 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenchange#Browser_compatibility 232 | */ 233 | set onfullscreenchange(callback: ((this: Element, ev: Event) => any) | null) { 234 | if (this.cfs) { 235 | this.ele[this.cfs.onfullscreenchange] = callback; 236 | } 237 | } 238 | 239 | /** 240 | * @desc Modern APIs 241 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenerror#Browser_compatibility 242 | */ 243 | get onfullscreenerror() { 244 | if (this.cfs) { 245 | return this.ele[this.cfs.onfullscreenerror]; 246 | } else { 247 | return null; 248 | } 249 | } 250 | 251 | /** 252 | * @desc Modern APIs 253 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenerror#Browser_compatibility 254 | */ 255 | set onfullscreenerror(callback: ((this: Element, ev: Event) => any) | null) { 256 | if (this.cfs) { 257 | this.ele[this.cfs.onfullscreenerror] = callback; 258 | } 259 | } 260 | 261 | /** 262 | * @desc Modern APIs 263 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenchange#Browser_compatibility 264 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenerror#Browser_compatibility 265 | */ 266 | addEventListener( 267 | type: FullscreenEventType, 268 | listener: EventListenerOrEventListenerObject, 269 | options?: boolean | AddEventListenerOptions, 270 | ) { 271 | if (this.cfs) { 272 | if (type === "fullscreenchange" || type === "fullscreenerror") { 273 | this.ele.addEventListener(this.cfs[type], listener, options); 274 | } 275 | } 276 | } 277 | 278 | /** 279 | * @desc Modern APIs 280 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenchange#Browser_compatibility 281 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenerror#Browser_compatibility 282 | */ 283 | removeEventListener( 284 | type: FullscreenEventType, 285 | listener: EventListenerOrEventListenerObject, 286 | options?: boolean | EventListenerOptions, 287 | ) { 288 | if (this.cfs) { 289 | if (type === "fullscreenchange" || type === "fullscreenerror") { 290 | this.ele.removeEventListener(this.cfs[type], listener, options); 291 | } 292 | } 293 | } 294 | 295 | /** 296 | * @deprecated Use returned promise if BrowsingContextPromise is available. 297 | */ 298 | addListener( 299 | type: FullscreenEventType, 300 | listener: EventListenerOrEventListenerObject, 301 | options?: boolean | AddEventListenerOptions, 302 | ) { 303 | if (this.cfs) { 304 | if (type === "fullscreenchange" || type === "fullscreenerror") { 305 | this.doc.addEventListener(this.cfs[type], listener, options); 306 | } 307 | } 308 | } 309 | 310 | /** 311 | * @deprecated Use returned promise if BrowsingContextPromise is available. 312 | */ 313 | removeListener( 314 | type: FullscreenEventType, 315 | listener: EventListenerOrEventListenerObject, 316 | options?: boolean | EventListenerOptions, 317 | ) { 318 | if (this.cfs) { 319 | if (type === "fullscreenchange" || type === "fullscreenerror") { 320 | this.doc.removeEventListener(this.cfs[type], listener, options); 321 | } 322 | } 323 | } 324 | } 325 | -------------------------------------------------------------------------------- /dist/release/fullscreen.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap","webpack:///./src/metadata.ts","webpack:///./src/index.ts"],"names":["root","factory","exports","module","define","amd","a","i","window","installedModules","__webpack_require__","moduleId","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","metadata","freeze","version","revision","production","lastCompiled","__webpack_exports__","src_Fullscreen","Fullscreen","ele","this","cfs","fss","fullscreenEnabled","fullscreenElement","onfullscreenchange","onfullscreenerror","requestFullscreen","exitFullscreen","fullscreenchange","fullscreenerror","doc","ownerDocument","document","win","defaultView","length","Boolean","getBrowsingContextPromise","maybePromise","resolve","reject","options","_this","Promise_1","p1","onchange","e","currentElement","removeEventListener","onerror","removeListener","addEventListener","addListener","p2","then","catch","isBrowsingContext","Promise_2","callback","type","listener"],"mappings":"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","file":"fullscreen.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse {\n\t\tvar a = factory();\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","interface ProjectMetadata {\n readonly name: string;\n readonly version: string;\n readonly revision: string;\n readonly production: boolean;\n readonly lastCompiled: string;\n}\n\n// @ts-ignore (from webpack.DefinePlugin)\nexport const metadata: ProjectMetadata = Object.freeze(__X_METADATA__);\n","import { metadata } from \"./metadata\";\n\nexport interface FullscreenOptions {\n navigationUI: \"auto\" | \"show\" | \"hide\";\n}\n\nexport interface FullscreenAPIMapping {\n fullscreenEnabled: \"fullscreenEnabled\" | \"webkitFullscreenEnabled\" | \"mozFullScreenEnabled\" | \"msFullscreenEnabled\";\n fullscreenElement: \"fullscreenElement\" | \"webkitFullscreenElement\" | \"mozFullScreenElement\" | \"msFullscreenElement\";\n onfullscreenchange:\n | \"onfullscreenchange\"\n | \"onwebkitfullscreenchange\"\n | \"onmozfullscreenchange\"\n | \"onmsfullscreenchange\";\n onfullscreenerror: \"onfullscreenerror\" | \"onwebkitfullscreenerror\" | \"onmozfullscreenerror\" | \"onmsfullscreenerror\";\n requestFullscreen: \"requestFullscreen\" | \"webkitRequestFullscreen\" | \"mozRequestFullScreen\" | \"msRequestFullscreen\";\n exitFullscreen: \"exitFullscreen\" | \"webkitExitFullscreen\" | \"mozCancelFullScreen\" | \"msExitFullscreen\";\n fullscreenchange: \"fullscreenchange\" | \"webkitfullscreenchange\" | \"mozfullscreenchange\" | \"MSFullscreenChange\";\n fullscreenerror: \"fullscreenerror\" | \"webkitfullscreenerror\" | \"mozfullscreenerror\" | \"MSFullscreenError\";\n}\n\nexport type FullscreenEventType = \"fullscreenchange\" | \"fullscreenerror\";\n\nexport class Fullscreen {\n private readonly ele: Element;\n private readonly doc: Document;\n private readonly win: Window;\n private readonly cfs: FullscreenAPIMapping | null = null;\n private readonly fss = [\n {\n fullscreenEnabled: \"fullscreenEnabled\",\n fullscreenElement: \"fullscreenElement\",\n onfullscreenchange: \"onfullscreenchange\",\n onfullscreenerror: \"onfullscreenerror\",\n requestFullscreen: \"requestFullscreen\",\n exitFullscreen: \"exitFullscreen\",\n fullscreenchange: \"fullscreenchange\",\n fullscreenerror: \"fullscreenerror\",\n },\n {\n fullscreenEnabled: \"webkitFullscreenEnabled\",\n fullscreenElement: \"webkitFullscreenElement\",\n onfullscreenchange: \"onwebkitfullscreenchange\",\n onfullscreenerror: \"onwebkitfullscreenerror\",\n requestFullscreen: \"webkitRequestFullscreen\",\n exitFullscreen: \"webkitExitFullscreen\",\n fullscreenchange: \"webkitfullscreenchange\",\n fullscreenerror: \"webkitfullscreenerror\",\n },\n {\n fullscreenEnabled: \"mozFullScreenEnabled\",\n fullscreenElement: \"mozFullScreenElement\",\n onfullscreenchange: \"onmozfullscreenchange\",\n onfullscreenerror: \"onmozfullscreenerror\",\n requestFullscreen: \"mozRequestFullScreen\",\n exitFullscreen: \"mozCancelFullScreen\",\n fullscreenchange: \"mozfullscreenchange\",\n fullscreenerror: \"mozfullscreenerror\",\n },\n {\n fullscreenEnabled: \"msFullscreenEnabled\",\n fullscreenElement: \"msFullscreenElement\",\n onfullscreenchange: \"onmsfullscreenchange\",\n onfullscreenerror: \"onmsfullscreenerror\",\n requestFullscreen: \"msRequestFullscreen\",\n exitFullscreen: \"msExitFullscreen\",\n fullscreenchange: \"MSFullscreenChange\",\n fullscreenerror: \"MSFullscreenError\",\n },\n ];\n\n constructor(ele: Element) {\n this.ele = ele;\n this.doc = this.ele.ownerDocument || document;\n this.win = this.doc.defaultView || window;\n for (let i = 0; i < this.fss.length; i++) {\n if (this.fss[i].fullscreenEnabled in this.doc) {\n this.cfs = this.fss[i];\n break;\n }\n }\n }\n\n static get metadata() {\n return metadata;\n }\n\n get currentElement(): Element {\n return this.ele;\n }\n\n get fullscreenMapping(): FullscreenAPIMapping | null {\n return this.cfs;\n }\n\n get fullscreenEnabled(): boolean {\n if (this.cfs) {\n return Boolean(this.doc[this.cfs.fullscreenEnabled]);\n } else {\n return false;\n }\n }\n\n get fullscreenElement(): Element | null {\n if (this.cfs) {\n return this.doc[this.cfs.fullscreenElement] || null;\n } else {\n return null;\n }\n }\n\n getBrowsingContextPromise(): PromiseConstructor | null {\n const maybePromise = this.win[\"Promise\"];\n if (\n typeof maybePromise === \"function\" &&\n typeof maybePromise.resolve === \"function\" &&\n typeof maybePromise.reject === \"function\"\n ) {\n return maybePromise;\n } else {\n return null;\n }\n }\n\n requestFullscreen(options?: FullscreenOptions): Promise | void {\n if (this.cfs) {\n // tslint:disable-next-line\n const Promise = this.getBrowsingContextPromise();\n if (Promise) {\n const p1: Promise = new Promise((resolve, reject) => {\n const onchange = (e: Event) => {\n if (this.fullscreenElement === this.currentElement) {\n this.removeEventListener(\"fullscreenchange\", onchange, true);\n this.removeEventListener(\"fullscreenerror\", onerror, true);\n this.removeListener(\"fullscreenchange\", onchange);\n this.removeListener(\"fullscreenerror\", onerror);\n resolve();\n }\n };\n const onerror = (e: Event) => {\n if (this.fullscreenElement !== this.currentElement) {\n this.removeEventListener(\"fullscreenchange\", onchange, true);\n this.removeEventListener(\"fullscreenerror\", onerror, true);\n this.removeListener(\"fullscreenchange\", onchange);\n this.removeListener(\"fullscreenerror\", onerror);\n reject(/* new Error(message)? */);\n }\n };\n this.addEventListener(\"fullscreenchange\", onchange, true);\n this.addEventListener(\"fullscreenerror\", onerror, true);\n this.addListener(\"fullscreenchange\", onchange);\n this.addListener(\"fullscreenerror\", onerror);\n });\n const p2 = this.ele[this.cfs.requestFullscreen](options);\n if (p2 && typeof p2.then === \"function\" && typeof p2.catch === \"function\") {\n return p2;\n } else {\n return p1;\n }\n } else {\n return this.ele[this.cfs.requestFullscreen](options);\n }\n }\n }\n\n exitFullscreen(isBrowsingContext?: boolean): Promise | void {\n if (this.cfs) {\n // tslint:disable-next-line\n const Promise = this.getBrowsingContextPromise();\n if (Promise) {\n if (isBrowsingContext || this.fullscreenElement === this.ele) {\n const p1: Promise = new Promise((resolve, reject) => {\n const onchange = (e: Event) => {\n if (isBrowsingContext || this.fullscreenElement !== this.currentElement) {\n this.removeEventListener(\"fullscreenchange\", onchange, true);\n this.removeEventListener(\"fullscreenerror\", onerror, true);\n this.removeListener(\"fullscreenchange\", onchange);\n this.removeListener(\"fullscreenerror\", onerror);\n resolve();\n }\n };\n const onerror = (e: Event) => {\n if (isBrowsingContext || this.fullscreenElement === this.currentElement) {\n this.removeEventListener(\"fullscreenchange\", onchange, true);\n this.removeEventListener(\"fullscreenerror\", onerror, true);\n this.removeListener(\"fullscreenchange\", onchange);\n this.removeListener(\"fullscreenerror\", onerror);\n reject(/* new Error(message)? */);\n }\n };\n this.addEventListener(\"fullscreenchange\", onchange, true);\n this.addEventListener(\"fullscreenerror\", onerror, true);\n this.addListener(\"fullscreenchange\", onchange);\n this.addListener(\"fullscreenerror\", onerror);\n });\n const p2 = this.doc[this.cfs.exitFullscreen]();\n if (p2 && typeof p2.then === \"function\" && typeof p2.catch === \"function\") {\n return p2;\n } else {\n return p1;\n }\n } else {\n return Promise.reject(\n new this.win[\"TypeError\"](\n \"The document containing the element isn't fully active; that is, it's not the current active document.\",\n ),\n );\n }\n } else {\n if (isBrowsingContext || this.fullscreenElement === this.ele) {\n return this.doc[this.cfs.exitFullscreen]();\n }\n }\n }\n }\n\n /**\n * @desc Modern APIs\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenchange#Browser_compatibility\n */\n get onfullscreenchange() {\n if (this.cfs) {\n return this.ele[this.cfs.onfullscreenchange];\n } else {\n return null;\n }\n }\n\n /**\n * @desc Modern APIs\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenchange#Browser_compatibility\n */\n set onfullscreenchange(callback: ((this: Element, ev: Event) => any) | null) {\n if (this.cfs) {\n this.ele[this.cfs.onfullscreenchange] = callback;\n }\n }\n\n /**\n * @desc Modern APIs\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenerror#Browser_compatibility\n */\n get onfullscreenerror() {\n if (this.cfs) {\n return this.ele[this.cfs.onfullscreenerror];\n } else {\n return null;\n }\n }\n\n /**\n * @desc Modern APIs\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenerror#Browser_compatibility\n */\n set onfullscreenerror(callback: ((this: Element, ev: Event) => any) | null) {\n if (this.cfs) {\n this.ele[this.cfs.onfullscreenerror] = callback;\n }\n }\n\n /**\n * @desc Modern APIs\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenchange#Browser_compatibility\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenerror#Browser_compatibility\n */\n addEventListener(\n type: FullscreenEventType,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) {\n if (this.cfs) {\n if (type === \"fullscreenchange\" || type === \"fullscreenerror\") {\n this.ele.addEventListener(this.cfs[type], listener, options);\n }\n }\n }\n\n /**\n * @desc Modern APIs\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenchange#Browser_compatibility\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/onfullscreenerror#Browser_compatibility\n */\n removeEventListener(\n type: FullscreenEventType,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) {\n if (this.cfs) {\n if (type === \"fullscreenchange\" || type === \"fullscreenerror\") {\n this.ele.removeEventListener(this.cfs[type], listener, options);\n }\n }\n }\n\n /**\n * @deprecated Use returned promise if BrowsingContextPromise is available.\n */\n addListener(\n type: FullscreenEventType,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) {\n if (this.cfs) {\n if (type === \"fullscreenchange\" || type === \"fullscreenerror\") {\n this.doc.addEventListener(this.cfs[type], listener, options);\n }\n }\n }\n\n /**\n * @deprecated Use returned promise if BrowsingContextPromise is available.\n */\n removeListener(\n type: FullscreenEventType,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) {\n if (this.cfs) {\n if (type === \"fullscreenchange\" || type === \"fullscreenerror\") {\n this.doc.removeEventListener(this.cfs[type], listener, options);\n }\n }\n }\n}\n"],"sourceRoot":""} --------------------------------------------------------------------------------