In Chrome extension content scripts it is fine to do:
const myTarget = new EventTarget()
myTarget.addEventListener('test', () => console.log('test1'))
myTarget.dispatchEvent(new Event('test'))
but this does not work in Firefox, because in Firefox this !== window
. Instead Firefox has this === globalThis
where for some reason some standard Web API's like EventTarget in globalThis['EventTarget']
do not work, while window['EventTarget']
does work.
As a result this would mean to be able to use various standard Web APIs like EventTarget I'd need to call them via Window as window['EventTarget']
even though it works fine in Chrome as is. Alternatively deleting the EventTarget with delete globalThis['EventTarget']
makes it fallback to window['EvenTarget']
as well. I don't think either solutions are acceptable.
How can I deal with this in a sane way?
Example:
const { log } = console
log(EventTarget === EventTarget)
log(EventTarget === window['EventTarget'])
log(EventTarget === globalThis['EventTarget'])
log(EventTarget === self['EventTarget'])
const test1 = new EventTarget()
const test2 = new window['EventTarget']()
const test3 = new globalThis['EventTarget']()
test1.addEventListener('test', () => log('test1'))
test2.addEventListener('test', () => log('test2'))
test3.addEventListener('test', () => log('test3'))
test1.dispatchEvent(new Event('test'))
test2.dispatchEvent(new Event('test'))
test3.dispatchEvent(new Event('test'))
will log in Firefox add-on content script:
true
false
true
false
test2
and in Chrome extension content script:
true
true
true
true
test1
test2
test3
Firefox version: 128 (Latest)
Firefox manifest version: v2
Chrome manifest version: v3
Conclusion is, as @woxxom mentioned, that it's yet another decade old bug in Firefox that never got fixed. Instead of reinventing standard Web API's for this by coding it ourselves, it suffices to:
globalThis['EventTarget'] = window['EventTarget']
or
delete globalThis['EventTarget']
for Firefox only, as unsightly as it is.