mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-09 03:46:16 -08:00
70 lines
2.9 KiB
JavaScript
70 lines
2.9 KiB
JavaScript
import fs from 'node:fs'
|
|
import process from 'node:process'
|
|
import vm from 'node:vm'
|
|
import { verifyIframeContract } from '../../refactor/scripts/iframe-contract.mjs'
|
|
import { readMember } from '../../refactor/scripts/releases.mjs'
|
|
import { compilePackage } from './load.js'
|
|
|
|
export async function iframeCandidate() {
|
|
if (process.env.ARTPLAYER_IFRAME_BASELINE === '1')
|
|
return (await iframeHistorical()).find(item => item.name === 'workspace.js')
|
|
return { name: process.env.ARTPLAYER_IFRAME_ARTIFACT ? 'candidate-artifact' : 'candidate-source', global: 'ArtplayerToolIframe', namespace: false, code: process.env.ARTPLAYER_IFRAME_ARTIFACT ? fs.readFileSync(process.env.ARTPLAYER_IFRAME_ARTIFACT, 'utf8') : await compilePackage('artplayer-tool-iframe', 'umd') }
|
|
}
|
|
|
|
export async function iframeHistorical() {
|
|
const { baseline, archive, sources } = await verifyIframeContract()
|
|
return [
|
|
...Object.keys(baseline.release.files).filter(file => file.startsWith('package/dist/')).map(file => ({ name: `published-${file.split('/').at(-1)}`, code: readMember(archive, file).toString(), global: file.includes('helper') ? 'ArtplayerHelperIframe' : 'ArtplayerPluginIframe', namespace: true })),
|
|
...['.js', '.legacy.js'].map(suffix => ({ name: `workspace${suffix}`, code: sources.get(`packages/artplayer-tool-iframe/dist/artplayer-tool-iframe${suffix}`), global: 'ArtplayerToolIframe', namespace: false })),
|
|
]
|
|
}
|
|
|
|
export function iframeEnvironment(implementation, child = false) {
|
|
const handlers = new Map()
|
|
const timers = new Map()
|
|
const sent = []
|
|
const order = []
|
|
let now = 1234
|
|
let nextTimer = 0
|
|
class Frame {
|
|
contentWindow = { postMessage: (packet, origin) => sent.push({ packet, origin }) }
|
|
get src() { return this.url }
|
|
set src(value) {
|
|
this.url = value
|
|
order.push('src')
|
|
}
|
|
}
|
|
const module = { exports: {} }
|
|
const box = {
|
|
module,
|
|
exports: module.exports,
|
|
HTMLIFrameElement: Frame,
|
|
Date: class extends Date { static now() { return now } },
|
|
setTimeout(callback, delay) {
|
|
const id = ++nextTimer
|
|
timers.set(id, { callback, delay })
|
|
return id
|
|
},
|
|
clearTimeout(id) { timers.delete(id) },
|
|
addEventListener(name, callback) {
|
|
const set = handlers.get(name) || new Set()
|
|
set.add(callback)
|
|
handlers.set(name, set)
|
|
order.push(`listen:${name}`)
|
|
},
|
|
removeEventListener(name, callback) { handlers.get(name)?.delete(callback) },
|
|
}
|
|
box.window = box
|
|
box.self = box
|
|
box.top = child ? {} : box
|
|
box.parent = { postMessage: (packet, origin) => sent.push({ packet, origin }) }
|
|
vm.runInNewContext(implementation.code, box)
|
|
const exported = module.exports
|
|
const Factory = exported.default || exported
|
|
return { box, Factory, exported, Frame, handlers, timers, sent, order, now(value) {
|
|
now = value
|
|
}, dispatch(data, source, origin = 'https://unrelated.invalid') {
|
|
for (const callback of handlers.get('message') || []) callback({ data, source, origin })
|
|
} }
|
|
}
|