Further improve google-ima shim script (#3900)

I worked through some of the websites listed in the google-ima shim
script issue[1], to see what was going wrong. It turned out the
addEventListener method supports an optional context Object, which is
bound to the listener if provided. Some websites make use of that,
and then break when `this` is not bound correctly when events are
dispatched.

See also https://github.com/duckduckgo/tracker-surrogates/pull/24

1 - https://github.com/uBlockOrigin/uBlock-issues/issues/2265
This commit is contained in:
Dave Vandyke 2023-10-25 17:00:21 +01:00 committed by GitHub
parent c2217a170e
commit 0fa30a73c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -9,6 +9,10 @@
* - Modified to avoid jshint warnings as per uBO's config * - Modified to avoid jshint warnings as per uBO's config
* - Added `OmidVerificationVendor` to `ima` * - Added `OmidVerificationVendor` to `ima`
* - Have `AdError.getInnerError()` return `null` * - Have `AdError.getInnerError()` return `null`
* - Have `AdDisplayContainer` constructor add DIV element to container
* - Added missing event dispatcher functionality
* - Corrected return type of `Ad.getUniversalAdIds()`
* - Corrected typo in `UniversalAdIdInfo.getAdIdValue()` method name
* *
* Related issue: * Related issue:
* - https://github.com/uBlockOrigin/uBlock-issues/issues/2158 * - https://github.com/uBlockOrigin/uBlock-issues/issues/2158
@ -331,8 +335,9 @@ if (!window.google || !window.google.ima || !window.google.ima.VERSION) {
} }
_dispatch(e) { _dispatch(e) {
const listeners = this.listeners.get(e.type) || []; let listeners = this.listeners.get(e.type);
for (const listener of Array.from(listeners)) { listeners = listeners ? Array.from(listeners.values()) : [];
for (const listener of listeners) {
try { try {
listener(e); listener(e);
} catch (r) { } catch (r) {
@ -341,16 +346,16 @@ if (!window.google || !window.google.ima || !window.google.ima.VERSION) {
} }
} }
addEventListener(types, c) { addEventListener(types, c, options, context) {
if (!Array.isArray(types)) { if (!Array.isArray(types)) {
types = [types]; types = [types];
} }
for (const t of types) { for (const t of types) {
if (!this.listeners.has(t)) { if (!this.listeners.has(t)) {
this.listeners.set(t, new Set()); this.listeners.set(t, new Map());
} }
this.listeners.get(t).add(c); this.listeners.get(t).set(c, c.bind(context || this));
} }
} }