@@ -29,15 +29,16 @@ function handleMessage(message: Message) {
29
29
30
30
let ID : string | null = null ;
31
31
if ( document . currentScript !== undefined && document . currentScript !== null ) {
32
- if ( "src" in document . currentScript && document . currentScript . src !== "" ) {
32
+ polyfillCurrentScript ( ) ;
33
+ if ( determineKnownTypeHasNoEmptyStringProp ( document . currentScript , "src" ) ) {
33
34
try {
34
35
ID = new URL ( document . currentScript . src ) . searchParams . get ( "id" ) ;
35
36
} catch ( _ ) {
36
37
// ID remains null.
37
38
}
38
39
}
39
40
if ( ID === null ) {
40
- // if `script.src` is masked, get id from attrs
41
+ // Fallback to get id from attrs
41
42
const ruffleId = document . currentScript . getAttribute ( "ruffle-id" ) ;
42
43
if ( ruffleId ) {
43
44
ID = ruffleId ;
@@ -57,6 +58,60 @@ function openInNewTab(swf: URL): void {
57
58
window . postMessage ( message , "*" ) ;
58
59
}
59
60
61
+ function polyfillCurrentScript ( ) : void {
62
+ const script = document . currentScript ! ;
63
+ try {
64
+ if ( determineKnownTypeHasNoEmptyStringProp ( script , "src" ) ) {
65
+ determineScriptIsMaskedSrcAndMakePolyfill ( script ) ;
66
+ }
67
+ } catch ( _ ) {
68
+ // Continue to run
69
+ }
70
+ }
71
+
72
+ function determineScriptIsMaskedSrcAndMakePolyfill (
73
+ script : HTMLScriptElement ,
74
+ ) : void {
75
+ const scriptUrlPolyfill = script . getAttribute ( "ruffle-src-polyfill" ) ;
76
+ if ( ! scriptUrlPolyfill ) {
77
+ return ;
78
+ }
79
+ const scriptUrl = script . src ;
80
+ const applyResetWebpackPublicPath = ( overridePublicPath : string ) : void => {
81
+ __webpack_public_path__ = overridePublicPath ;
82
+ // TODO: If there are other scripts that need to be dynamically created and executed, the current polyfill logic should also be applied.
83
+ } ;
84
+ // Reset webpack public path should be safe when it is using mask url
85
+ if ( "webkit-masked-url://hidden/" === scriptUrl ) {
86
+ const webpackCurrentPublicPath = __webpack_public_path__ ;
87
+ const scriptAutoPublicPath =
88
+ getWebpackPublicPathFromScriptSrc ( scriptUrl ) ;
89
+ if ( webpackCurrentPublicPath === scriptAutoPublicPath ) {
90
+ applyResetWebpackPublicPath (
91
+ getWebpackPublicPathFromScriptSrc ( scriptUrlPolyfill ) ,
92
+ ) ;
93
+ }
94
+ }
95
+ // TODO: Process other situations when mask url not webkit-masked-url://hidden/
96
+ }
97
+
98
+ // Exclude types that do not have this prop
99
+ function determineKnownTypeHasNoEmptyStringProp <
100
+ T extends object ,
101
+ TKey extends PropertyKey ,
102
+ > ( obj : T , prop : TKey ) : obj is T extends Record < TKey , string > ? T : never {
103
+ return prop in obj && ( obj as Record < PropertyKey , any > ) [ prop ] !== "" ;
104
+ }
105
+
106
+ // Copied from Webpack: https://github.com/webpack/webpack/blob/f1bdec5cc70236083e45b665831d5d79d6485db7/lib/runtime/AutoPublicPathRuntimeModule.js#L75
107
+ function getWebpackPublicPathFromScriptSrc ( scriptUrl : string ) : string {
108
+ return scriptUrl
109
+ . replace ( / ^ b l o b : / , "" )
110
+ . replace ( / # .* $ / , "" )
111
+ . replace ( / \? .* $ / , "" )
112
+ . replace ( / \/ [ ^ \/ ] + $ / , "/" ) ;
113
+ }
114
+
60
115
if ( ID ) {
61
116
window . addEventListener ( "message" , ( event ) => {
62
117
// We only accept messages from ourselves.
0 commit comments