mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-22 13:21:20 -08:00
feat: add Document Picture-in-Picture plugin for ArtPlayer
- Implemented the core functionality of the Document Picture-in-Picture plugin. - Created main plugin file `artplayer-plugin-document-pip.js` with support for opening and closing the PIP window. - Added legacy support in `artplayer-plugin-document-pip.legacy.js`. - Defined plugin options in `package.json` and included necessary metadata. - Developed the main logic in `src/index.js`, including style copying and event handling. - Created TypeScript definitions in `types/artplayer-plugin-document-pip.d.ts` for better type safety.
This commit is contained in:
1 parent
c23520a4a6
commit
7d4175efbc
73 files changed
+722
-230
No files matched your search
@@ -163,19 +163,17 @@
|
||||
})({"55Mmu":[function(require,module,exports,__globalThis) {
|
||||
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
|
||||
parcelHelpers.defineInteropFlag(exports);
|
||||
parcelHelpers.export(exports, "default", ()=>artplayerPluginPip);
|
||||
function artplayerPluginPip(userOptions = {}) {
|
||||
parcelHelpers.export(exports, "default", ()=>artplayerPluginDocumentPip);
|
||||
function artplayerPluginDocumentPip(userOptions = {}) {
|
||||
const options = {
|
||||
width: 480,
|
||||
height: 270,
|
||||
fallbackToVideoPiP: true,
|
||||
placeholder: `Playing in Document Picture-in-Picture`,
|
||||
...userOptions
|
||||
};
|
||||
return (art)=>{
|
||||
if (!('documentPictureInPicture' in window)) {
|
||||
art.notice.show = 'Document Picture-in-Picture is not supported';
|
||||
return;
|
||||
}
|
||||
const dpipOK = 'documentPictureInPicture' in window && typeof window.documentPictureInPicture?.requestWindow === 'function';
|
||||
const { proxy, icons, i18n, template: { $container }, constructor: { utils: { append, tooltip } } } = art;
|
||||
const state = {
|
||||
win: null,
|
||||
@@ -185,21 +183,44 @@ function artplayerPluginPip(userOptions = {}) {
|
||||
placeholder: null
|
||||
};
|
||||
function copyStylesTo(targetDoc) {
|
||||
const baseStyle = `
|
||||
html, body { margin:0; padding:0; width:100%; height:100%; background:#000; overflow:hidden; }
|
||||
#__art_dpip_root { position:absolute; inset:0; display:flex; }
|
||||
#__art_dpip_root > * { width:100% !important; height:100% !important; }
|
||||
`;
|
||||
const $style = document.querySelector('#artplayer-style');
|
||||
const clone = targetDoc.createElement('style');
|
||||
clone.textContent = baseStyle + $style.textContent;
|
||||
targetDoc.head.appendChild(clone);
|
||||
const meta = targetDoc.createElement('meta');
|
||||
meta.name = 'viewport';
|
||||
meta.content = 'width=device-width,initial-scale=1';
|
||||
targetDoc.head.appendChild(meta);
|
||||
const base = targetDoc.createElement('style');
|
||||
base.textContent = `
|
||||
html, body { margin:0; padding:0; width:100%; height:100%; background:#000; overflow:hidden; }
|
||||
#__art_dpip_root { position:absolute; inset:0; display:flex; }
|
||||
#__art_dpip_root > * { width:100% !important; height:100% !important; }
|
||||
`;
|
||||
targetDoc.head.appendChild(base);
|
||||
if (!targetDoc.querySelector('meta[name="viewport"]')) {
|
||||
const meta = targetDoc.createElement('meta');
|
||||
meta.name = 'viewport';
|
||||
meta.content = 'width=device-width,initial-scale=1';
|
||||
targetDoc.head.appendChild(meta);
|
||||
}
|
||||
try {
|
||||
document.querySelectorAll('link[rel="stylesheet"]').forEach((link)=>{
|
||||
const clone = targetDoc.createElement('link');
|
||||
clone.rel = 'stylesheet';
|
||||
clone.href = link.href;
|
||||
if (link.media) clone.media = link.media;
|
||||
if (link.crossOrigin) clone.crossOrigin = link.crossOrigin;
|
||||
if (link.referrerPolicy) clone.referrerPolicy = link.referrerPolicy;
|
||||
targetDoc.head.appendChild(clone);
|
||||
});
|
||||
} catch {}
|
||||
try {
|
||||
document.querySelectorAll('style').forEach((style)=>{
|
||||
const clone = targetDoc.createElement('style');
|
||||
clone.textContent = style.textContent;
|
||||
targetDoc.head.appendChild(clone);
|
||||
});
|
||||
} catch {}
|
||||
}
|
||||
async function open() {
|
||||
if (!dpipOK && options.fallbackToVideoPiP) {
|
||||
art.pip = true;
|
||||
console.warn('[artplayer-plugin-document-pip] Document Picture-in-Picture is not supported, falling back to Video Picture-in-Picture');
|
||||
return;
|
||||
}
|
||||
if (state.win) return;
|
||||
try {
|
||||
const pipWin = await window.documentPictureInPicture.requestWindow({
|
||||
@@ -223,17 +244,19 @@ function artplayerPluginPip(userOptions = {}) {
|
||||
root.appendChild(adopted);
|
||||
state.currentDoc = pipWin.document;
|
||||
const onResize = ()=>art.resize?.();
|
||||
const onPageHide = ()=>close();
|
||||
const onClose = ()=>close();
|
||||
pipWin.addEventListener('resize', onResize);
|
||||
pipWin.addEventListener('pagehide', onPageHide);
|
||||
pipWin.addEventListener('pagehide', onClose);
|
||||
pipWin.addEventListener('unload', onClose);
|
||||
state.cleanup = ()=>{
|
||||
pipWin.removeEventListener('resize', onResize);
|
||||
pipWin.removeEventListener('pagehide', onPageHide);
|
||||
pipWin.removeEventListener('pagehide', onClose);
|
||||
pipWin.removeEventListener('unload', onClose);
|
||||
};
|
||||
art.emit('document-pip', true);
|
||||
} catch (err) {
|
||||
art.notice.show = 'Document Picture-in-Picture open failed';
|
||||
console.warn('[artplayer-plugin-pip] open failed:', err);
|
||||
console.warn('[artplayer-plugin-document-pip] open failed:', err);
|
||||
}
|
||||
}
|
||||
function restoreToOriginalDocument() {
|
||||
@@ -246,6 +269,10 @@ function artplayerPluginPip(userOptions = {}) {
|
||||
state.currentDoc = backDoc;
|
||||
}
|
||||
function close() {
|
||||
if (!dpipOK && options.fallbackToVideoPiP) {
|
||||
art.pip = false;
|
||||
return;
|
||||
}
|
||||
if (!state.win) return;
|
||||
try {
|
||||
state.cleanup?.();
|
||||
@@ -255,7 +282,7 @@ function artplayerPluginPip(userOptions = {}) {
|
||||
art.emit('document-pip', false);
|
||||
} catch (err) {
|
||||
art.notice.show = 'Document Picture-in-Picture close failed';
|
||||
console.warn('[artplayer-plugin-pip] close failed:', err);
|
||||
console.warn('[artplayer-plugin-document-pip] close failed:', err);
|
||||
}
|
||||
}
|
||||
function toggle() {
|
||||
@@ -277,14 +304,14 @@ function artplayerPluginPip(userOptions = {}) {
|
||||
});
|
||||
art.on('destroy', close);
|
||||
return {
|
||||
name: 'artplayerPluginPip',
|
||||
name: 'artplayerPluginDocumentPip',
|
||||
open,
|
||||
close,
|
||||
toggle
|
||||
};
|
||||
};
|
||||
}
|
||||
if (typeof window !== 'undefined') window.artplayerPluginPip = artplayerPluginPip;
|
||||
if (typeof window !== 'undefined') window.artplayerPluginDocumentPip = artplayerPluginDocumentPip;
|
||||
|
||||
},{"@parcel/transformer-js/src/esmodule-helpers.js":"8oCsH"}],"8oCsH":[function(require,module,exports,__globalThis) {
|
||||
exports.interopDefault = function(a) {
|
||||
|
||||
Reference in new issue
Block a user