artplayer-plugin-iframe(#407)

* update artplayer-plugin-iframe
This commit is contained in:
Harvey Zack authored and GitHub committed 2022-10-21 10:36:50 +08:00
1 parent 08f284a64b
commit fed80dcca4
79 files changed
+1213 -571

No files matched your search

@@ -0,0 +1,196 @@
---
title: Iframe Plugin
sidebar_position: 3
---
## Demo
👉 [View Demo](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-iframe/index.js&example=iframe)
## Install
### Install from `npm`:
```bash
$ npm install artplayer-plugin-iframe
```
### Install from `yarn`:
```bash
$ yarn add artplayer-plugin-iframe
```
### Install from `script`:
```html
<!-- local -->
<script src="path/to/artplayer-plugin-iframe.js"></script>
<!-- jsdelivr -->
<script src="https://cdn.jsdelivr.net/npm/artplayer-plugin-iframe/dist/artplayer-plugin-iframe.js"></script>
<!-- unpkg -->
<script src="https://unpkg.com/artplayer-plugin-iframe/dist/artplayer-plugin-iframe.js"></script>
```
Then you can access the plugin function through `window.artplayerPluginIframe`
## Use
### index.html
```html showLineNumbers title="index.html"
<!DOCTYPE html>
<html>
<head>
<title>ArtPlayer</title>
<meta charset="UTF-8" />
</head>
<body>
<iframe id="iframe"></iframe>
<script src="path/to/artplayer-plugin-iframe.js"></script>
<script>
const iframe = new ArtplayerPluginIframe({
// iframe element
iframe: document.querySelector('#iframe'),
// iframe url
url: 'path/to/iframe.html',
});
// Push message to iframe
iframe.commit(() => {
var art = new Artplayer({
container: '.artplayer-app',
url: 'path/to/video.mp4',
});
});
</script>
</body>
</html>
```
### iframe.html
```html showLineNumbers title="iframe.html"
<!DOCTYPE html>
<html>
<head>
<title>ArtPlayer</title>
<meta charset="UTF-8" />
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div class="artplayer-app" style="width: 100%; height: 100%;"></div>
<script src="path/to/artplayer.js"></script>
<script src="path/to/artplayer-plugin-iframe.js"></script>
<script>
// Inject the script, receive messages from the instance
ArtplayerPluginIframe.inject();
</script>
</body>
</html>
```
## Instance Api
### commit
- Type: `Function`
Push message to iframe, the function will run inside the iframe
```js
iframe.commit(() => {
var art = new Artplayer({
container: '.artplayer-app',
url: 'path/to/video.mp4',
});
});
iframe.commit(() => {
art.seek = 5;
});
// Get the value from the iframe
(async function () {
// Use return keyword
var currentTime = await iframe.commit(() => {
return art.currentTime;
});
// Or use resolve method
var currentTime2 = await iframe.commit((resolve) => {
setTimeout(() => {
resolve(art.currentTime);
}, 1000);
});
})();
```
### message
- Type: `Function`
Receive message from the iframe
```js
iframe.message((event) => {
console.log(event);
});
```
### destroy
- Type: `Function`
Destroy the instance, cannot communicate with the iframe after destroy
```js
iframe.destroy();
```
## Iframe Api
:::danger Tip
The `Iframe Api` can only be used in `iframe`.
:::
### inject
- Type: `Function`
Inject the script, then can receive messages from the instance
```js
ArtplayerPluginIframe.inject();
```
### postMessage
- Type: `Function`
Push message to instance
```js
iframe.message((event) => {
console.log(event);
});
iframe.commit(() => {
ArtplayerPluginIframe.postMessage({
type: 'currentTime',
data: art.currentTime,
});
});
```
@@ -0,0 +1,196 @@
---
title: Iframe 插件
sidebar_position: 3
---
## 演示
👉 [View Demo](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-iframe/index.js&example=iframe)
## 安装
### 通过 `npm` 安装:
```bash
$ npm install artplayer-plugin-iframe
```
### 通过 `yarn` 安装:
```bash
$ yarn add artplayer-plugin-iframe
```
### 通过 `script` 安装:
```html
<!-- 本地 -->
<script src="path/to/artplayer-plugin-iframe.js"></script>
<!-- jsdelivr -->
<script src="https://cdn.jsdelivr.net/npm/artplayer-plugin-iframe/dist/artplayer-plugin-iframe.js"></script>
<!-- unpkg -->
<script src="https://unpkg.com/artplayer-plugin-iframe/dist/artplayer-plugin-iframe.js"></script>
```
然后你可以通过 `window.artplayerPluginIframe` 访问到插件函数
## 使用
### index.html
```html showLineNumbers title="index.html"
<!DOCTYPE html>
<html>
<head>
<title>ArtPlayer</title>
<meta charset="UTF-8" />
</head>
<body>
<iframe id="iframe"></iframe>
<script src="path/to/artplayer-plugin-iframe.js"></script>
<script>
const iframe = new ArtplayerPluginIframe({
// iframe 元素
iframe: document.querySelector('#iframe'),
// iframe 地址
url: 'path/to/iframe.html',
});
// 向 iframe 发送消息
iframe.commit(() => {
var art = new Artplayer({
container: '.artplayer-app',
url: 'path/to/video.mp4',
});
});
</script>
</body>
</html>
```
### iframe.html
```html showLineNumbers title="iframe.html"
<!DOCTYPE html>
<html>
<head>
<title>ArtPlayer</title>
<meta charset="UTF-8" />
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div class="artplayer-app" style="width: 100%; height: 100%;"></div>
<script src="path/to/artplayer.js"></script>
<script src="path/to/artplayer-plugin-iframe.js"></script>
<script>
// 注入脚本,接收来自实例的消息
ArtplayerPluginIframe.inject();
</script>
</body>
</html>
```
## 实例接口
### commit
- 类型: `Function`
将消息推送到 iframe,该函数将在 iframe 内部运行
```js
iframe.commit(() => {
var art = new Artplayer({
container: '.artplayer-app',
url: 'path/to/video.mp4',
});
});
iframe.commit(() => {
art.seek = 5;
});
// 获取来自 iframe 的值
(async function () {
// 使用 return 关键词
var currentTime = await iframe.commit(() => {
return art.currentTime;
});
// 或者使用 resolve 方法
var currentTime2 = await iframe.commit((resolve) => {
setTimeout(() => {
resolve(art.currentTime);
}, 1000);
});
})();
```
### message
- 类型: `Function`
接收来自 iframe 的消息
```js
iframe.message((event) => {
console.log(event);
});
```
### destroy
- 类型: `Function`
销毁实例,销毁后无法与 iframe 通信
```js
iframe.destroy();
```
## Iframe 接口
:::danger Tip
`Iframe 接口` 只能运行在 `iframe` 里
:::
### inject
- 类型: `Function`
注入脚本,接收来自实例的消息
```js
ArtplayerPluginIframe.inject();
```
### postMessage
- 类型: `Function`
将消息推送到实例
```js
iframe.message((event) => {
console.log(event);
});
iframe.commit(() => {
ArtplayerPluginIframe.postMessage({
type: 'currentTime',
data: art.currentTime,
});
});
```
@@ -0,0 +1,10 @@
node_modules
.DS_Store
yarn.lock
package-lock.json
test
coverage
.nyc_output
.parcel-cache
.cache
docs
+1
View File
@@ -0,0 +1 @@
package-lock=false
@@ -0,0 +1,15 @@
# artplayer-plugin-iframe
Iframe plugin for ArtPlayer
## Demo
[https://artplayer.org](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-iframe/index.js&example=iframe)
## Usage
[https://artplayer.org/document/en/Plugins/iframe](https://artplayer.org/document/en/Plugins/iframe)
## License
MIT © Harvey Zack
@@ -0,0 +1,7 @@
/*!
* artplayer-helper-iframe.js v1.0.0
* Github: https://github.com/zhw2590582/ArtPlayer
* (c) 2017-2022 Harvey Zack
* Released under the MIT License.
*/
!function(e,t,s,n,i){var r="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{},o="function"==typeof r.parcelRequire4dc0&&r.parcelRequire4dc0,a=o.cache||{},c="undefined"!=typeof module&&"function"==typeof module.require&&module.require.bind(module);function d(t,s){if(!a[t]){if(!e[t]){var n="function"==typeof r.parcelRequire4dc0&&r.parcelRequire4dc0;if(!s&&n)return n(t,!0);if(o)return o(t,!0);if(c&&"string"==typeof t)return c(t);var i=new Error("Cannot find module '"+t+"'");throw i.code="MODULE_NOT_FOUND",i}l.resolve=function(s){var n=e[t][1][s];return null!=n?n:s},l.cache={};var u=a[t]=new d.Module(t);e[t][0].call(u.exports,l,u,u.exports,this)}return a[t].exports;function l(e){var t=l.resolve(e);return!1===t?{}:d(t)}}d.isParcelRequire=!0,d.Module=function(e){this.id=e,this.bundle=d,this.exports={}},d.modules=e,d.cache=a,d.parent=o,d.register=function(t,s){e[t]=[function(e,t){t.exports=s},{}]},Object.defineProperty(d,"root",{get:function(){return r.parcelRequire4dc0}}),r.parcelRequire4dc0=d;for(var u=0;u<t.length;u++)d(t[u]);var l=d(s);"object"==typeof exports&&"undefined"!=typeof module?module.exports=l:"function"==typeof define&&define.amd&&define((function(){return l}))}({kXBUH:[function(e,t,s){e("@parcel/transformer-js/src/esmodule-helpers.js").defineInteropFlag(s);class n{static postMessage({type:e,data:t,id:s=0}){window.parent.postMessage({type:e,data:t,id:s},"*")}static async onMessage(e){const{type:t,data:s,id:i}=e.data;switch(t){case"commit":try{if(s.match(/\bresolve\((.*?)\)/)){const e=`return new Promise(function(resolve){\n${s}\n})`,t=await new Function(e)();n.postMessage({type:"response",data:t,id:i})}else{const e=new Function(s)();n.postMessage({type:"response",data:e,id:i})}}catch(e){n.postMessage({type:"error",data:e.message,id:i})}break;case"destroy":n.isDestroy||n.destroy()}}static inject(){n.isInject=!0,n.isDestroy=!1,n.postMessage({type:"inject"}),window.addEventListener("message",n.onMessage)}static destroy(){n.isInject=!1,n.isDestroy=!0,n.postMessage({type:"destroy"}),window.removeEventListener("message",n.onMessage)}constructor({iframe:e,url:t}){this.url=t,this.$iframe=e,this.promises={},this.isInject=!1,this.isDestroy=!1,this.messageCallback=()=>null,this.onMessage=this.onMessage.bind(this),window.addEventListener("message",this.onMessage),this.$iframe.src=this.url}onMessage(e){const{type:t,data:s,id:n}=e.data;switch(t){case"inject":this.isInject=!0;break;case"destroy":this.isInject=!1,this.isDestroy||this.destroy()}this.promises[n]&&("error"===t?this.promises[n].reject(new Error(s)):this.promises[n].resove(s),delete this.promises[n]),this.messageCallback&&this.messageCallback({type:t,data:s})}postMessage({type:e,data:t}){return new Promise(((s,n)=>{(function i(){if(this.isInject){const i=Date.now();this.promises[i]={resove:s,reject:n},this.$iframe.contentWindow.postMessage({type:e,data:t,id:i},"*")}else this.isDestroy||setTimeout(i.bind(this),200)}).call(this)}))}commit(e){const t=e.toString(),s=t.substring(t.indexOf("{")+1,t.lastIndexOf("}"));return this.postMessage({type:"commit",data:s})}message(e){this.messageCallback=e}destroy(){this.isDestroy=!0,window.removeEventListener("message",this.onMessage)}}s.default=n,"undefined"!=typeof window&&(window.ArtplayerHelperIframe=n)},{"@parcel/transformer-js/src/esmodule-helpers.js":"9pCYc"}],"9pCYc":[function(e,t,s){s.interopDefault=function(e){return e&&e.__esModule?e:{default:e}},s.defineInteropFlag=function(e){Object.defineProperty(e,"__esModule",{value:!0})},s.exportAll=function(e,t){return Object.keys(e).forEach((function(s){"default"===s||"__esModule"===s||t.hasOwnProperty(s)||Object.defineProperty(t,s,{enumerable:!0,get:function(){return e[s]}})})),t},s.export=function(e,t,s){Object.defineProperty(e,t,{enumerable:!0,get:s})}},{}]},["kXBUH"],"kXBUH");
@@ -0,0 +1,7 @@
/*!
* artplayer-helper-iframe.js v1.0.0
* Github: https://github.com/zhw2590582/ArtPlayer
* (c) 2017-2022 Harvey Zack
* Released under the MIT License.
*/
!function(e,t,r,n,o){var i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{},a="function"==typeof i.parcelRequire4dc0&&i.parcelRequire4dc0,s=a.cache||{},c="undefined"!=typeof module&&"function"==typeof module.require&&module.require.bind(module);function u(t,r){if(!s[t]){if(!e[t]){var n="function"==typeof i.parcelRequire4dc0&&i.parcelRequire4dc0;if(!r&&n)return n(t,!0);if(a)return a(t,!0);if(c&&"string"==typeof t)return c(t);var o=new Error("Cannot find module '"+t+"'");throw o.code="MODULE_NOT_FOUND",o}f.resolve=function(r){var n=e[t][1][r];return null!=n?n:r},f.cache={};var l=s[t]=new u.Module(t);e[t][0].call(l.exports,f,l,l.exports,this)}return s[t].exports;function f(e){var t=f.resolve(e);return!1===t?{}:u(t)}}u.isParcelRequire=!0,u.Module=function(e){this.id=e,this.bundle=u,this.exports={}},u.modules=e,u.cache=s,u.parent=a,u.register=function(t,r){e[t]=[function(e,t){t.exports=r},{}]},Object.defineProperty(u,"root",{get:function(){return i.parcelRequire4dc0}}),i.parcelRequire4dc0=u;for(var l=0;l<t.length;l++)u(t[l]);var f=u(r);"object"==typeof exports&&"undefined"!=typeof module?module.exports=f:"function"==typeof define&&define.amd&&define((function(){return f}))}({"03Ksz":[function(e,t,r){var n=e("@parcel/transformer-js/src/esmodule-helpers.js");n.defineInteropFlag(r),n.export(r,"default",(function(){return h}));var o=e("@swc/helpers/src/_async_to_generator.mjs"),i=n.interopDefault(o),a=e("@swc/helpers/src/_class_call_check.mjs"),s=n.interopDefault(a),c=e("@swc/helpers/src/_create_class.mjs"),u=n.interopDefault(c),l=e("regenerator-runtime"),f=n.interopDefault(l),h=function(){"use strict";function e(t){var r=t.iframe,n=t.url;(0,s.default)(this,e),this.url=n,this.$iframe=r,this.promises={},this.isInject=!1,this.isDestroy=!1,this.messageCallback=function(){return null},this.onMessage=this.onMessage.bind(this),window.addEventListener("message",this.onMessage),this.$iframe.src=this.url}return(0,u.default)(e,[{key:"onMessage",value:function(e){var t=e.data,r=t.type,n=t.data,o=t.id;switch(r){case"inject":this.isInject=!0;break;case"destroy":this.isInject=!1,this.isDestroy||this.destroy()}this.promises[o]&&("error"===r?this.promises[o].reject(new Error(n)):this.promises[o].resove(n),delete this.promises[o]),this.messageCallback&&this.messageCallback({type:r,data:n})}},{key:"postMessage",value:function(e){var t=e.type,r=e.data,n=this;return new Promise((function(e,o){(function n(){if(this.isInject){var i=Date.now();this.promises[i]={resove:e,reject:o},this.$iframe.contentWindow.postMessage({type:t,data:r,id:i},"*")}else this.isDestroy||setTimeout(n.bind(this),200)}).call(n)}))}},{key:"commit",value:function(e){var t=e.toString(),r=t.substring(t.indexOf("{")+1,t.lastIndexOf("}"));return this.postMessage({type:"commit",data:r})}},{key:"message",value:function(e){this.messageCallback=e}},{key:"destroy",value:function(){this.isDestroy=!0,window.removeEventListener("message",this.onMessage)}}],[{key:"postMessage",value:function(e){var t=e.type,r=e.data,n=e.id,o=void 0===n?0:n;window.parent.postMessage({type:t,data:r,id:o},"*")}},{key:"onMessage",value:function(t){return(0,i.default)(f.default.mark((function r(){var n,o,i,a,s,c,u;return f.default.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:n=t.data,o=n.type,i=n.data,a=n.id,r.t0=o,r.next="commit"===r.t0?4:"destroy"===r.t0?20:22;break;case 4:if(r.prev=4,!i.match(/\bresolve\((.*?)\)/)){r.next=13;break}return s="return new Promise(function(resolve){\n".concat(i,"\n})"),r.next=9,new Function(s)();case 9:c=r.sent,e.postMessage({type:"response",data:c,id:a}),r.next=14;break;case 13:u=new Function(i)(),e.postMessage({type:"response",data:u,id:a});case 14:r.next=19;break;case 16:r.prev=16,r.t1=r.catch(4),e.postMessage({type:"error",data:r.t1.message,id:a});case 19:return r.abrupt("break",23);case 20:return e.isDestroy||e.destroy(),r.abrupt("break",23);case 22:return r.abrupt("break",23);case 23:case"end":return r.stop()}}),r,null,[[4,16]])})))()}},{key:"inject",value:function(){e.isInject=!0,e.isDestroy=!1,e.postMessage({type:"inject"}),window.addEventListener("message",e.onMessage)}},{key:"destroy",value:function(){e.isInject=!1,e.isDestroy=!0,e.postMessage({type:"destroy"}),window.removeEventListener("message",e.onMessage)}}]),e}();"undefined"!=typeof window&&(window.ArtplayerHelperIframe=h)},{"@swc/helpers/src/_async_to_generator.mjs":"eiCdg","@swc/helpers/src/_class_call_check.mjs":"fs9hQ","@swc/helpers/src/_create_class.mjs":"eAORo","regenerator-runtime":"kuNhv","@parcel/transformer-js/src/esmodule-helpers.js":"47PTV"}],eiCdg:[function(e,t,r){function n(e,t,r,n,o,i,a){try{var s=e[i](a),c=s.value}catch(e){return void r(e)}s.done?t(c):Promise.resolve(c).then(n,o)}e("@parcel/transformer-js/src/esmodule-helpers.js").defineInteropFlag(r),r.default=function(e){return function(){var t=this,r=arguments;return new Promise((function(o,i){var a=e.apply(t,r);function s(e){n(a,o,Line truncated
@@ -0,0 +1,24 @@
{
"license": "MIT",
"version": "1.0.0",
"name": "artplayer-plugin-iframe",
"types": "types/artplayer-plugin-iframe.d.ts",
"description": "Iframe plugin for ArtPlayer",
"main": "dist/artplayer-plugin-iframe.js",
"legacy": "dist/artplayer-plugin-iframe.legacy.js",
"author": "Harvey Zack <laozhaochaguan@gmail.com>",
"browserslist": "> 0.5%, last 2 versions, not dead",
"homepage": "https://artplayer.org",
"repository": {
"type": "git",
"url": "git+https://github.com/zhw2590582/ArtPlayer.git"
},
"bugs": {
"url": "https://github.com/zhw2590582/ArtPlayer/issues"
},
"keywords": [
"html5",
"video",
"player"
]
}
@@ -0,0 +1,150 @@
export default class ArtplayerPluginIframe {
static get iframe() {
return window.top !== window;
}
static postMessage({ type, data, id = 0 }) {
if (!ArtplayerPluginIframe.iframe) {
throw new Error('The postMessage method can only be used in iframe');
}
window.parent.postMessage(
{
type: type,
data: data,
id: id,
},
'*',
);
}
static async onMessage(event) {
if (!ArtplayerPluginIframe.iframe) {
throw new Error('The onMessage method can only be used in iframe');
}
const { type, data, id } = event.data;
switch (type) {
case 'commit':
try {
if (data.match(/\bresolve\((.*?)\)/)) {
const string = `return new Promise(function(resolve){\n${data}\n})`;
const result = await new Function(string)();
ArtplayerPluginIframe.postMessage({ type: 'response', data: result, id });
} else {
const result = new Function(data)();
ArtplayerPluginIframe.postMessage({ type: 'response', data: result, id });
}
} catch (error) {
ArtplayerPluginIframe.postMessage({ type: 'error', data: error.message, id });
}
break;
default:
break;
}
}
static inject() {
if (!ArtplayerPluginIframe.iframe) {
throw new Error('The inject method can only be used in iframe');
}
ArtplayerPluginIframe.postMessage({ type: 'inject' });
window.addEventListener('message', ArtplayerPluginIframe.onMessage);
}
constructor({ iframe, url }) {
if (iframe instanceof HTMLIFrameElement === false) {
throw new Error('option.iframe needs to be a HTMLIFrameElement');
}
if (typeof url !== 'string') {
throw new Error('option.url needs to be a string');
}
this.url = url;
this.$iframe = iframe;
this.promises = {};
this.injected = false;
this.destroyed = false;
this.messageCallback = () => null;
this.onMessage = this.onMessage.bind(this);
window.addEventListener('message', this.onMessage);
this.$iframe.src = this.url;
}
onMessage(event) {
const { type, data, id } = event.data;
switch (type) {
case 'inject':
this.injected = true;
break;
default:
break;
}
if (this.promises[id]) {
if (type === 'error') {
this.promises[id].reject(new Error(data));
} else {
this.promises[id].resove(data);
}
delete this.promises[id];
}
if (this.messageCallback) {
this.messageCallback({ type, data });
}
}
postMessage({ type, data }) {
return new Promise((resove, reject) => {
(function loop() {
if (this.destroyed) {
reject(new Error('the instance has been destroyed'));
} else {
if (this.injected) {
const id = Date.now();
this.promises[id] = { resove, reject };
this.$iframe.contentWindow.postMessage(
{
type: type,
data: data,
id: id,
},
'*',
);
} else {
setTimeout(loop.bind(this), 200);
}
}
}.call(this));
});
}
commit(callback) {
if (typeof callback !== 'function') {
throw new Error('commit.callback needs to be a function');
}
const callbackString = callback.toString();
const bodyString = callbackString.substring(callbackString.indexOf('{') + 1, callbackString.lastIndexOf('}'));
return this.postMessage({ type: 'commit', data: bodyString });
}
message(callback) {
if (typeof callback !== 'function') {
throw new Error('message.callback needs to be a function');
}
this.messageCallback = callback;
}
destroy() {
this.destroyed = true;
window.removeEventListener('message', this.onMessage);
}
}
if (typeof window !== 'undefined') {
window['ArtplayerPluginIframe'] = ArtplayerPluginIframe;
}
@@ -0,0 +1,6 @@
import ArtplayerPluginIframe from '..';
const iframe = new ArtplayerPluginIframe({
iframe: document.getElementById('iframe') as HTMLIFrameElement,
url: 'iframe.html',
});
@@ -0,0 +1,30 @@
export = ArtplayerPluginIframe;
export as namespace ArtplayerPluginIframe;
type Message = {
type: string;
data: any;
id?: number;
};
declare class ArtplayerPluginIframe {
constructor(option: { iframe: HTMLIFrameElement; url: string });
static iframe: boolean;
static postMessage(message: Message): void;
static onMessage(event: MessageEvent & { data: Message }): void;
static inject(): void;
readonly promises: Record<number, { resove: Function; reject: Function }>;
readonly injected: boolean;
readonly destroyed: boolean;
readonly $iframe: HTMLIFrameElement;
readonly url: string;
readonly messageCallback: (...args: any[]) => any;
onMessage(event: MessageEvent & { data: Message }): void;
postMessage(message: Message): Promise<any>;
commit<T extends (...args: any[]) => any>(callback: T): Promise<ReturnType<T>>;
message(callback: (...args: any[]) => any): void;
destroy(): void;
}