mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-22 05:11:20 -08:00
test(vtt-thumbnail): [PKG-VTT-THUMB-01] freeze published runtime contracts
This commit is contained in:
1 parent
8c57d56f17
commit
d4ede650e8
15 files changed
+1003
-7
No files matched your search
@@ -0,0 +1,123 @@
|
||||
import vm from 'node:vm'
|
||||
import { transform } from 'esbuild'
|
||||
import { readMember } from '../../refactor/scripts/releases.mjs'
|
||||
import { verifyVttThumbnailContract } from '../../refactor/scripts/vtt-thumbnail-contract.mjs'
|
||||
|
||||
export async function vttThumbnailHistorical() {
|
||||
const { baseline, archives, sources } = await verifyVttThumbnailContract()
|
||||
const name = 'artplayer-plugin-vtt-thumbnail'
|
||||
const implementations = []
|
||||
for (const release of [baseline.release, ...baseline.previous]) {
|
||||
if (release.version === '1.0.0')
|
||||
continue
|
||||
for (const field of ['main', 'legacy']) {
|
||||
implementations.push({ name: `published-${release.version}-${field}`, version: release.version, profile: release.version === '1.0.1' ? 'old-control' : release.version === '1.0.2' ? 'no-class' : 'current', code: readMember(archives.get(release.version), `package/${release.manifest[field].replace(/^\.\//, '')}`).toString() })
|
||||
}
|
||||
}
|
||||
for (const version of ['1.0.0', 'workspace']) {
|
||||
const source = file => version === 'workspace' ? sources.get(`packages/${name}/src/${file}`) : readMember(archives.get(version), `package/src/${file}`).toString()
|
||||
const code = `${source('getVttArray.js').replace('export default ', '')}\n${source('index.js').replace(/^import getVttArray from ['"].\/getVttArray['"];?\s*$/m, '')}`
|
||||
implementations.push({ name: version === 'workspace' ? 'frozen-workspace-source' : 'published-1.0.0-source-only', version, profile: version === '1.0.0' ? 'mouse-source-only' : 'current', code: (await transform(code, { format: 'cjs', target: 'es2020' })).code })
|
||||
}
|
||||
for (const suffix of ['js', 'legacy.js'])
|
||||
implementations.push({ name: `frozen-workspace-${suffix}`, version: 'workspace', profile: 'current', code: sources.get(`packages/${name}/dist/${name}.${suffix}`) })
|
||||
return implementations
|
||||
}
|
||||
|
||||
export const vttText = 'WEBVTT\n\n00:00:00.900 --> 00:00:05.900\nsheet.jpg#xywh=10,20,80,45\n\n00:00:05.100 --> 00:00:10.999\nsecond.jpg#xywh=90,65,80,45\n'
|
||||
|
||||
// Only the 1.0.1–1.0.3 compiled artifacts require compact cue arrows.
|
||||
export function acceptedVttText(implementation, text = vttText) {
|
||||
return /^published-1\.0\.[123]-(?:main|legacy)$/.test(implementation.name)
|
||||
? text.replaceAll(' --> ', '-->')
|
||||
: text
|
||||
}
|
||||
|
||||
export function vttThumbnailEnvironment(implementation, { script = false, mobile = false, text = vttText, deferred = false } = {}) {
|
||||
const requests = []
|
||||
const controls = []
|
||||
const listeners = new Map()
|
||||
const proxies = new Map()
|
||||
const timers = new Map()
|
||||
const classes = new Set()
|
||||
const styles = {}
|
||||
let nextTimer = 0
|
||||
let resolveFetch
|
||||
let rejectFetch
|
||||
const response = source => ({ ok: true, status: 200, text: async () => source })
|
||||
const pending = deferred
|
||||
? new Promise((resolve, reject) => {
|
||||
resolveFetch = resolve
|
||||
rejectFetch = reject
|
||||
})
|
||||
: null
|
||||
const progress = { clientWidth: 200, getBoundingClientRect: () => ({ left: 20 }) }
|
||||
const control = { styles }
|
||||
const art = {
|
||||
constructor: { utils: {
|
||||
isMobile: mobile,
|
||||
clamp: (value, min, max) => Math.min(max, Math.max(min, value)),
|
||||
setStyle(element, key, value) { element.styles[key] = value },
|
||||
addClass(element, name) { classes.add(name) },
|
||||
} },
|
||||
duration: 10,
|
||||
template: { $progress: progress },
|
||||
events: { proxy(element, name, callback) {
|
||||
if (!proxies.has(name))
|
||||
proxies.set(name, [])
|
||||
proxies.get(name).push(callback)
|
||||
} },
|
||||
controls: { add(option) {
|
||||
controls.push(option)
|
||||
option.mounted(control)
|
||||
} },
|
||||
on(name, callback) {
|
||||
if (!listeners.has(name))
|
||||
listeners.set(name, [])
|
||||
listeners.get(name).push(callback)
|
||||
return this
|
||||
},
|
||||
off(name, callback) { listeners.set(name, (listeners.get(name) || []).filter(item => item !== callback)) },
|
||||
}
|
||||
const box = {
|
||||
window: {},
|
||||
fetch(...args) {
|
||||
requests.push(args)
|
||||
return pending || Promise.resolve(response(text))
|
||||
},
|
||||
setTimeout(callback, delay) {
|
||||
const id = nextTimer++
|
||||
timers.set(id, { callback, delay })
|
||||
return id
|
||||
},
|
||||
clearTimeout(id) { timers.delete(id) },
|
||||
}
|
||||
const module = { exports: {} }
|
||||
if (!script)
|
||||
Object.assign(box, { module, exports: module.exports })
|
||||
vm.runInNewContext(implementation.code, box)
|
||||
const exported = script ? box.artplayerPluginVttThumbnail || box.window.artplayerPluginVttThumbnail : module.exports
|
||||
const factory = typeof exported === 'function' ? exported : exported.default
|
||||
return {
|
||||
factory,
|
||||
exported,
|
||||
art,
|
||||
box,
|
||||
styles,
|
||||
classes,
|
||||
controls,
|
||||
listeners,
|
||||
proxies,
|
||||
timers,
|
||||
requests,
|
||||
progress,
|
||||
resolve(source = text) { resolveFetch(response(source)) },
|
||||
reject(error) { rejectFetch(error) },
|
||||
async emit(name, ...args) { return Promise.all((listeners.get(name) || []).map(callback => callback(...args))) },
|
||||
async hover(percentage, type = 'hover', event = {}) {
|
||||
return Promise.all(implementation.profile === 'mouse-source-only'
|
||||
? (proxies.get('mousemove') || []).map(callback => callback({ pageX: 20 + progress.clientWidth * percentage }))
|
||||
: (listeners.get('setBar') || []).map(callback => callback(type, percentage, event)))
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user