mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-23 05:41:20 -08:00
fix(iframe): [PKG-IFRAME-03] release failed setup and bind message peers
This commit is contained in:
1 parent
b8d03e7366
commit
b8cdafedd1
23 files changed
+7940
-32
No files matched your search
@@ -0,0 +1,28 @@
|
||||
import type { Packet, RequestHost } from './requests'
|
||||
import { cancelRequests } from './requests'
|
||||
|
||||
interface ConnectionHost extends RequestHost {
|
||||
url: string
|
||||
onMessage: (event: MessageEvent<Packet>) => void
|
||||
}
|
||||
|
||||
const connections = new WeakMap<ConnectionHost, () => void>()
|
||||
|
||||
export function connect(host: ConnectionHost): void {
|
||||
const owner = window
|
||||
const receiver = host.onMessage
|
||||
connections.set(host, () => owner.removeEventListener('message', receiver))
|
||||
owner.addEventListener('message', receiver)
|
||||
host.$iframe.src = host.url
|
||||
}
|
||||
|
||||
export function releaseConnection(host: ConnectionHost): void {
|
||||
const disconnect = connections.get(host)
|
||||
connections.delete(host)
|
||||
try {
|
||||
disconnect?.()
|
||||
}
|
||||
finally {
|
||||
cancelRequests(host)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { Callbacks, Packet } from './requests'
|
||||
import { cancelRequests, postRequest } from './requests'
|
||||
import { connect, releaseConnection } from './connection'
|
||||
import { acceptsMessage } from './protocol'
|
||||
import { postRequest } from './requests'
|
||||
|
||||
export default class ArtplayerToolIframe {
|
||||
declare url: string
|
||||
@@ -33,6 +35,9 @@ export default class ArtplayerToolIframe {
|
||||
throw new Error('The "ArtplayerToolIframe.onMessage" method can only be used in iframe')
|
||||
}
|
||||
|
||||
if (!acceptsMessage(event, window.parent))
|
||||
return
|
||||
|
||||
const { type, data, id } = event.data
|
||||
switch (type) {
|
||||
case 'commit':
|
||||
@@ -84,12 +89,23 @@ export default class ArtplayerToolIframe {
|
||||
this.destroyed = false
|
||||
this.messageCallback = () => null
|
||||
this.onMessage = this.onMessage.bind(this)
|
||||
window.addEventListener('message', this.onMessage)
|
||||
this.$iframe.src = this.url
|
||||
try {
|
||||
connect(this)
|
||||
}
|
||||
catch (error) {
|
||||
this.destroyed = true
|
||||
try {
|
||||
releaseConnection(this)
|
||||
}
|
||||
catch {
|
||||
// Preserve the original setup failure if cleanup also fails.
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
onMessage(event: MessageEvent<Packet>) {
|
||||
if (this.destroyed)
|
||||
if (this.destroyed || !acceptsMessage(event, this.$iframe.contentWindow))
|
||||
return
|
||||
|
||||
const { type, data, id } = event.data
|
||||
@@ -139,7 +155,6 @@ export default class ArtplayerToolIframe {
|
||||
|
||||
destroy() {
|
||||
this.destroyed = true
|
||||
window.removeEventListener('message', this.onMessage)
|
||||
cancelRequests(this)
|
||||
releaseConnection(this)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { Packet } from './requests'
|
||||
|
||||
export function acceptsMessage(event: MessageEvent<unknown>, peer: Window | null): event is MessageEvent<Packet> {
|
||||
if (event.source !== undefined && event.source !== null && event.source !== peer)
|
||||
return false
|
||||
const data = event.data
|
||||
return typeof data === 'object' && data !== null && 'type' in data && typeof data.type === 'string'
|
||||
}
|
||||
Reference in new issue
Block a user