Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Update index.js #226

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
295 changes: 156 additions & 139 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,160 +1,177 @@
/* eslint-disable promise/prefer-await-to-then */

// Mapping for different Fullscreen API variations across browsers
const methodMap = [
[
'requestFullscreen',
'exitFullscreen',
'fullscreenElement',
'fullscreenEnabled',
'fullscreenchange',
'fullscreenerror',
],
// New WebKit
[
'webkitRequestFullscreen',
'webkitExitFullscreen',
'webkitFullscreenElement',
'webkitFullscreenEnabled',
'webkitfullscreenchange',
'webkitfullscreenerror',

],
// Old WebKit
[
'webkitRequestFullScreen',
'webkitCancelFullScreen',
'webkitCurrentFullScreenElement',
'webkitCancelFullScreen',
'webkitfullscreenchange',
'webkitfullscreenerror',

],
[
'mozRequestFullScreen',
'mozCancelFullScreen',
'mozFullScreenElement',
'mozFullScreenEnabled',
'mozfullscreenchange',
'mozfullscreenerror',
],
[
'msRequestFullscreen',
'msExitFullscreen',
'msFullscreenElement',
'msFullscreenEnabled',
'MSFullscreenChange',
'MSFullscreenError',
],
// Standard

Check failure on line 5 in index.js

View workflow job for this annotation

GitHub Actions / Node.js 16

Expected indentation of 1 tab but found 2 spaces.
[

Check failure on line 6 in index.js

View workflow job for this annotation

GitHub Actions / Node.js 16

Expected indentation of 1 tab but found 2 spaces.
'requestFullscreen',

Check failure on line 7 in index.js

View workflow job for this annotation

GitHub Actions / Node.js 16

Expected indentation of 2 tabs but found 4 spaces.
'exitFullscreen',

Check failure on line 8 in index.js

View workflow job for this annotation

GitHub Actions / Node.js 16

Expected indentation of 2 tabs but found 4 spaces.
'fullscreenElement',

Check failure on line 9 in index.js

View workflow job for this annotation

GitHub Actions / Node.js 16

Expected indentation of 2 tabs but found 4 spaces.
'fullscreenEnabled',

Check failure on line 10 in index.js

View workflow job for this annotation

GitHub Actions / Node.js 16

Expected indentation of 2 tabs but found 4 spaces.
'fullscreenchange',

Check failure on line 11 in index.js

View workflow job for this annotation

GitHub Actions / Node.js 16

Expected indentation of 2 tabs but found 4 spaces.
'fullscreenerror',

Check failure on line 12 in index.js

View workflow job for this annotation

GitHub Actions / Node.js 16

Expected indentation of 2 tabs but found 4 spaces.
],

Check failure on line 13 in index.js

View workflow job for this annotation

GitHub Actions / Node.js 16

Expected indentation of 1 tab but found 2 spaces.
// New WebKit

Check failure on line 14 in index.js

View workflow job for this annotation

GitHub Actions / Node.js 16

Expected indentation of 1 tab but found 2 spaces.
[
'webkitRequestFullscreen',
'webkitExitFullscreen',
'webkitFullscreenElement',
'webkitFullscreenEnabled',
'webkitfullscreenchange',
'webkitfullscreenerror',
],
// Old WebKit
[
'webkitRequestFullScreen',
'webkitCancelFullScreen',
'webkitCurrentFullScreenElement',
'webkitCancelFullScreen',
'webkitfullscreenchange',
'webkitfullscreenerror',
],
// Mozilla
[
'mozRequestFullScreen',
'mozCancelFullScreen',
'mozFullScreenElement',
'mozFullScreenEnabled',
'mozfullscreenchange',
'mozfullscreenerror',
],
// Microsoft
[
'msRequestFullscreen',
'msExitFullscreen',
'msFullscreenElement',
'msFullscreenEnabled',
'MSFullscreenChange',
'MSFullscreenError',
],
];

// Native API detection and mapping
const nativeAPI = (() => {
if (typeof document === 'undefined') {
return false;
}

const unprefixedMethods = methodMap[0];
const returnValue = {};

for (const methodList of methodMap) {
const exitFullscreenMethod = methodList?.[1];
if (exitFullscreenMethod in document) {
for (const [index, method] of methodList.entries()) {
returnValue[unprefixedMethods[index]] = method;
}

return returnValue;
}
}

return false;
if (typeof document === 'undefined') {
return false;
}

const unprefixedMethods = methodMap[0];
const returnValue = {};

// Loop through methodMap to find the supported fullscreen API
for (const methodList of methodMap) {
const exitFullscreenMethod = methodList?.[1]; // exitFullscreen or equivalent
if (exitFullscreenMethod in document) {
methodList.forEach((method, index) => {
returnValue[unprefixedMethods[index]] = method;
});
return returnValue;
}
}

return false;
})();

// Event names for fullscreen changes and errors
const eventNameMap = {
change: nativeAPI.fullscreenchange,
error: nativeAPI.fullscreenerror,
change: nativeAPI.fullscreenchange,
error: nativeAPI.fullscreenerror,
};

// eslint-disable-next-line import/no-mutable-exports
// Screenfull API implementation
let screenfull = {
// eslint-disable-next-line default-param-last
request(element = document.documentElement, options) {
return new Promise((resolve, reject) => {
const onFullScreenEntered = () => {
screenfull.off('change', onFullScreenEntered);
resolve();
};

screenfull.on('change', onFullScreenEntered);

const returnPromise = element[nativeAPI.requestFullscreen](options);

if (returnPromise instanceof Promise) {
returnPromise.then(onFullScreenEntered).catch(reject);
}
});
},
exit() {
return new Promise((resolve, reject) => {
if (!screenfull.isFullscreen) {
resolve();
return;
}

const onFullScreenExit = () => {
screenfull.off('change', onFullScreenExit);
resolve();
};

screenfull.on('change', onFullScreenExit);

const returnPromise = document[nativeAPI.exitFullscreen]();

if (returnPromise instanceof Promise) {
returnPromise.then(onFullScreenExit).catch(reject);
}
});
},
toggle(element, options) {
return screenfull.isFullscreen ? screenfull.exit() : screenfull.request(element, options);
},
onchange(callback) {
screenfull.on('change', callback);
},
onerror(callback) {
screenfull.on('error', callback);
},
on(event, callback) {
const eventName = eventNameMap[event];
if (eventName) {
document.addEventListener(eventName, callback, false);
}
},
off(event, callback) {
const eventName = eventNameMap[event];
if (eventName) {
document.removeEventListener(eventName, callback, false);
}
},
raw: nativeAPI,
// Request fullscreen mode for the given element
request(element = document.documentElement, options) {
return new Promise((resolve, reject) => {
const onFullScreenEntered = () => {
screenfull.off('change', onFullScreenEntered);
resolve();
};

screenfull.on('change', onFullScreenEntered);

const returnPromise = element[nativeAPI.requestFullscreen](options);
if (returnPromise instanceof Promise) {
returnPromise.then(onFullScreenEntered).catch(reject);
}
});
},

// Exit fullscreen mode
exit() {
return new Promise((resolve, reject) => {
if (!screenfull.isFullscreen) {
resolve();
return;
}

const onFullScreenExit = () => {
screenfull.off('change', onFullScreenExit);
resolve();
};

screenfull.on('change', onFullScreenExit);

const returnPromise = document[nativeAPI.exitFullscreen]();
if (returnPromise instanceof Promise) {
returnPromise.then(onFullScreenExit).catch(reject);
}
});
},

// Toggle fullscreen mode
toggle(element, options) {
return screenfull.isFullscreen ? screenfull.exit() : screenfull.request(element, options);
},

// Listen for fullscreen change events
onchange(callback) {
screenfull.on('change', callback);
},

// Listen for fullscreen error events
onerror(callback) {
screenfull.on('error', callback);
},

// Add event listener for specified event (change or error)
on(event, callback) {
const eventName = eventNameMap[event];
if (eventName) {
document.addEventListener(eventName, callback, false);
}
},

// Remove event listener for specified event
off(event, callback) {
const eventName = eventNameMap[event];
if (eventName) {
document.removeEventListener(eventName, callback, false);
}
},

// Raw access to native fullscreen API
raw: nativeAPI,
};

// Define properties for screenfull (fullscreen status, current element, and API availability)
Object.defineProperties(screenfull, {
isFullscreen: {
get: () => Boolean(document[nativeAPI.fullscreenElement]),
},
element: {
enumerable: true,
get: () => document[nativeAPI.fullscreenElement] ?? undefined,
},
isEnabled: {
enumerable: true,
// Coerce to boolean in case of old WebKit.
get: () => Boolean(document[nativeAPI.fullscreenEnabled]),
},
isFullscreen: {
get: () => Boolean(document[nativeAPI.fullscreenElement]),
},
element: {
enumerable: true,
get: () => document[nativeAPI.fullscreenElement] ?? undefined,
},
isEnabled: {
enumerable: true,
get: () => Boolean(document[nativeAPI.fullscreenEnabled]),
},
});

// Fallback in case Fullscreen API is not supported
if (!nativeAPI) {
screenfull = {isEnabled: false};
screenfull = { isEnabled: false };
}

export default screenfull;
Loading