@@ -147,69 +147,44 @@ if (isOverlay) {
147147 // something from the original process
148148 require ( oldPreloadPath ) ;
149149} else {
150- ipcRenderer . on ( constants . ipcNodePreloadKickoff , ( _ , blockedScripts : string [ ] ) => {
151- ( async ( ) => {
152- try {
153- await init ( ) ;
154- logger . debug ( "Blocked scripts:" , blockedScripts ) ;
155-
156- const oldPreloadPath : string = ipcRenderer . sendSync ( constants . ipcGetOldPreloadPath ) ;
157- logger . debug ( "Old preload path:" , oldPreloadPath ) ;
158- if ( oldPreloadPath ) require ( oldPreloadPath ) ;
159-
160- // Do this to get global.DiscordNative assigned
161- // @ts -expect-error Lying to discord_desktop_core
162- process . emit ( "loaded" ) ;
163-
164- function replayScripts ( ) {
165- const ignoreScripts = [
166- // We never blocked this in the first place
167- "popout." ,
168- // We don't want this to load at all
169- "sentry."
170- ] ;
171-
172- const scripts = [ ...document . querySelectorAll ( "script" ) ] . filter ( ( script ) => {
173- if ( ! script . src ) return false ;
174-
175- try {
176- const url = new URL ( script . src ) ;
177- const hasUrl =
178- url . pathname . match ( / \/ a s s e t s \/ ( \d { 3 , 5 } | [ a - z A - Z - ] + ) \. / ) &&
179- ! url . searchParams . has ( "inj" ) &&
180- ( url . host . endsWith ( "discord.com" ) || url . host . endsWith ( "discordapp.com" ) ) ;
181- const shouldIgnore = ignoreScripts . some ( ( other ) => url . pathname . startsWith ( `/assets/${ other } ` ) ) ;
182- return hasUrl && ! shouldIgnore ;
183- } catch {
184- return false ;
185- }
186- } ) ;
187-
188- // bruh.
189- if ( moonlightNode . config . patchAll ) scripts . sort ( ( a , b ) => a . src . localeCompare ( b . src ) ) ;
190-
191- for ( const script of scripts ) {
192- const newScript = document . createElement ( "script" ) ;
193- for ( const attr of script . attributes ) {
194- if ( attr . name === "src" ) attr . value += "?inj" ;
195- newScript . setAttribute ( attr . name , attr . value ) ;
196- }
197-
198- if ( script . src . includes ( "/assets/web." ) ) ipcRenderer . sendSync ( constants . ipcNodePreloadKickoff ) ;
199-
200- script . remove ( ) ;
201- document . documentElement . appendChild ( newScript ) ;
202- }
203- }
204-
205- if ( document . readyState === "complete" ) {
206- replayScripts ( ) ;
207- } else {
208- window . addEventListener ( "load" , replayScripts ) ;
209- }
210- } catch ( e ) {
211- logger . error ( "Error restoring original scripts:" , e ) ;
150+ const doInit = async ( ) => {
151+ try {
152+ await init ( ) ;
153+
154+ const oldPreloadPath : string = ipcRenderer . sendSync ( constants . ipcGetOldPreloadPath ) ;
155+ logger ! . debug ( "Old preload path:" , oldPreloadPath ) ;
156+ if ( oldPreloadPath ) require ( oldPreloadPath ) ;
157+
158+ // Do this to get global.DiscordNative assigned
159+ // @ts -expect-error Lying to discord_desktop_core
160+ process . emit ( "loaded" ) ;
161+ } catch ( e ) {
162+ // biome-ignore lint/suspicious/noConsole: logger unlikely to be initialized
163+ console . error ( "[moonlight:node-preload] Error initializing:" , e ) ;
164+ }
165+ } ;
166+
167+ // violentmonkey's document-start injector logic
168+ const getOwnProp = ( obj : any , key : any , defVal ?: any ) => {
169+ try {
170+ if ( obj && Object . hasOwn ( obj , key ) ) {
171+ defVal = obj [ key ] ;
212172 }
213- } ) ( ) ;
173+ } catch {
174+ // noop
175+ }
176+ return defVal ;
177+ } ;
178+ const elemByTag = ( tag : string , i ?: number ) => getOwnProp ( document . getElementsByTagName ( tag ) , i || 0 ) ;
179+ const observer = new MutationObserver ( ( ) => {
180+ if ( elemByTag ( "*" ) ) {
181+ observer . disconnect ( ) ;
182+
183+ setTimeout ( ( ) => {
184+ window . stop ( ) ;
185+ doInit ( ) ;
186+ } , 0 ) ;
187+ }
214188 } ) ;
189+ observer . observe ( document , { childList : true , subtree : true } ) ;
215190}
0 commit comments