summaryrefslogtreecommitdiff
path: root/data/extensions/uBlock0@raymondhill.net/web_accessible_resources/google-ima.js
diff options
context:
space:
mode:
Diffstat (limited to 'data/extensions/uBlock0@raymondhill.net/web_accessible_resources/google-ima.js')
-rw-r--r--data/extensions/uBlock0@raymondhill.net/web_accessible_resources/google-ima.js855
1 files changed, 855 insertions, 0 deletions
diff --git a/data/extensions/uBlock0@raymondhill.net/web_accessible_resources/google-ima.js b/data/extensions/uBlock0@raymondhill.net/web_accessible_resources/google-ima.js
new file mode 100644
index 0000000..4556516
--- /dev/null
+++ b/data/extensions/uBlock0@raymondhill.net/web_accessible_resources/google-ima.js
@@ -0,0 +1,855 @@
+/**
+ *
+ * Source below is based on Mozilla source code:
+ * https://searchfox.org/mozilla-central/rev/d317e93d9a59c9e4c06ada85fbff9f6a1ceaaad1/browser/extensions/webcompat/shims/google-ima.js
+ *
+ * Modifications to the original code below this comment:
+ * - Avoid JS syntax not supported by older browser versions
+ * - Add missing shim event
+ * - Modified to avoid jshint warnings as per uBO's config
+ * - Added `OmidVerificationVendor` to `ima`
+ * - 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
+ * - Corrected dispatch of LOAD event when preloading is enabled
+ * - Corrected dispatch of CONTENT_PAUSE/RESUME_REQUESTED events
+ *
+ * Related issue:
+ * - https://github.com/uBlockOrigin/uBlock-issues/issues/2158
+ *
+**/
+
+'use strict';
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Bug 1713690 - Shim Google Interactive Media Ads ima3.js
+ *
+ * Many sites use ima3.js for ad bidding and placement, often in conjunction
+ * with Google Publisher Tags, Prebid.js and/or other scripts. This shim
+ * provides a stubbed-out version of the API which helps work around related
+ * site breakage, such as black bxoes where videos ought to be placed.
+ */
+
+if (!window.google || !window.google.ima || !window.google.ima.VERSION) {
+ const VERSION = "3.517.2";
+
+ const CheckCanAutoplay = (function() {
+ // Sourced from: https://searchfox.org/mozilla-central/source/dom/media/gtest/negative_duration.mp4
+ const TEST_VIDEO = new Blob(
+ [
+ new Uint32Array([
+ 469762048,
+ 1887007846,
+ 1752392036,
+ 0,
+ 913273705,
+ 1717987696,
+ 828601953,
+ -1878917120,
+ 1987014509,
+ 1811939328,
+ 1684567661,
+ 0,
+ 0,
+ 0,
+ -402456576,
+ 0,
+ 256,
+ 1,
+ 0,
+ 0,
+ 256,
+ 0,
+ 0,
+ 0,
+ 256,
+ 0,
+ 0,
+ 0,
+ 64,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 33554432,
+ -201261056,
+ 1801548404,
+ 1744830464,
+ 1684564852,
+ 251658241,
+ 0,
+ 0,
+ 0,
+ 0,
+ 16777216,
+ 0,
+ -1,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 256,
+ 0,
+ 0,
+ 0,
+ 256,
+ 0,
+ 0,
+ 0,
+ 64,
+ 5,
+ 53250,
+ -2080309248,
+ 1634296941,
+ 738197504,
+ 1684563053,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ -2137614336,
+ -1,
+ -1,
+ 50261,
+ 754974720,
+ 1919706216,
+ 0,
+ 0,
+ 1701079414,
+ 0,
+ 0,
+ 0,
+ 1701079382,
+ 1851869295,
+ 1919249508,
+ 16777216,
+ 1852402979,
+ 102,
+ 1752004116,
+ 100,
+ 1,
+ 0,
+ 0,
+ 1852400676,
+ 102,
+ 1701995548,
+ 102,
+ 0,
+ 1,
+ 1819440396,
+ 32,
+ 1,
+ 1651799011,
+ 108,
+ 1937011607,
+ 100,
+ 0,
+ 1,
+ 1668702599,
+ 49,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 33555712,
+ 4718800,
+ 4718592,
+ 0,
+ 65536,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 16776984,
+ 1630601216,
+ 21193590,
+ -14745500,
+ 1729626337,
+ -1407254428,
+ 89161945,
+ 1049019,
+ 9453056,
+ -251611125,
+ 27269507,
+ -379058688,
+ -1329024392,
+ 268435456,
+ 1937011827,
+ 0,
+ 0,
+ 268435456,
+ 1668510835,
+ 0,
+ 0,
+ 335544320,
+ 2054386803,
+ 0,
+ 0,
+ 0,
+ 268435456,
+ 1868788851,
+ 0,
+ 0,
+ 671088640,
+ 2019915373,
+ 536870912,
+ 2019914356,
+ 0,
+ 16777216,
+ 16777216,
+ 0,
+ 0,
+ 0,
+ ]),
+ ],
+ { type: "video/mp4" }
+ );
+
+ let testVideo;
+
+ return function() {
+ if (!testVideo) {
+ testVideo = document.createElement("video");
+ testVideo.style =
+ "position:absolute; width:0; height:0; left:0; right:0; z-index:-1; border:0";
+ testVideo.setAttribute("muted", "muted");
+ testVideo.setAttribute("playsinline", "playsinline");
+ testVideo.src = URL.createObjectURL(TEST_VIDEO);
+ document.body.appendChild(testVideo);
+ }
+ return testVideo.play();
+ };
+ })();
+
+ const ima = {};
+
+ class AdDisplayContainer {
+ constructor(containerElement) {
+ const divElement = document.createElement("div");
+ divElement.style.setProperty("display", "none", "important");
+ divElement.style.setProperty("visibility", "collapse", "important");
+ containerElement.appendChild(divElement);
+ }
+ destroy() {}
+ initialize() {}
+ }
+
+ class ImaSdkSettings {
+ constructor() {
+ this.c = true;
+ this.f = {};
+ this.i = false;
+ this.l = "";
+ this.p = "";
+ this.r = 0;
+ this.t = "";
+ this.v = "";
+ }
+ getCompanionBackfill() {}
+ getDisableCustomPlaybackForIOS10Plus() {
+ return this.i;
+ }
+ getFeatureFlags() {
+ return this.f;
+ }
+ getLocale() {
+ return this.l;
+ }
+ getNumRedirects() {
+ return this.r;
+ }
+ getPlayerType() {
+ return this.t;
+ }
+ getPlayerVersion() {
+ return this.v;
+ }
+ getPpid() {
+ return this.p;
+ }
+ isCookiesEnabled() {
+ return this.c;
+ }
+ setAutoPlayAdBreaks() {}
+ setCompanionBackfill() {}
+ setCookiesEnabled(c) {
+ this.c = !!c;
+ }
+ setDisableCustomPlaybackForIOS10Plus(i) {
+ this.i = !!i;
+ }
+ setFeatureFlags(f) {
+ this.f = f;
+ }
+ setLocale(l) {
+ this.l = l;
+ }
+ setNumRedirects(r) {
+ this.r = r;
+ }
+ setPlayerType(t) {
+ this.t = t;
+ }
+ setPlayerVersion(v) {
+ this.v = v;
+ }
+ setPpid(p) {
+ this.p = p;
+ }
+ setSessionId(/*s*/) {}
+ setVpaidAllowed(/*a*/) {}
+ setVpaidMode(/*m*/) {}
+
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/2265#issuecomment-1637094149
+ getDisableFlashAds() {
+ }
+ setDisableFlashAds() {
+ }
+ }
+ ImaSdkSettings.CompanionBackfillMode = {
+ ALWAYS: "always",
+ ON_MASTER_AD: "on_master_ad",
+ };
+ ImaSdkSettings.VpaidMode = {
+ DISABLED: 0,
+ ENABLED: 1,
+ INSECURE: 2,
+ };
+
+ class EventHandler {
+ constructor() {
+ this.listeners = new Map();
+ }
+
+ _dispatch(e) {
+ let listeners = this.listeners.get(e.type);
+ listeners = listeners ? Array.from(listeners.values()) : [];
+ for (const listener of listeners) {
+ try {
+ listener(e);
+ } catch (r) {
+ console.error(r);
+ }
+ }
+ }
+
+ addEventListener(types, c, options, context) {
+ if (!Array.isArray(types)) {
+ types = [types];
+ }
+
+ for (const t of types) {
+ if (!this.listeners.has(t)) {
+ this.listeners.set(t, new Map());
+ }
+ this.listeners.get(t).set(c, c.bind(context || this));
+ }
+ }
+
+ removeEventListener(types, c) {
+ if (!Array.isArray(types)) {
+ types = [types];
+ }
+
+ for (const t of types) {
+ const typeSet = this.listeners.get(t);
+ if (typeSet) {
+ typeSet.delete(c);
+ }
+ }
+ }
+ }
+
+ class AdsLoader extends EventHandler {
+ constructor() {
+ super();
+ this.settings = new ImaSdkSettings();
+ }
+ contentComplete() {}
+ destroy() {}
+ getSettings() {
+ return this.settings;
+ }
+ getVersion() {
+ return VERSION;
+ }
+ requestAds(/*r, c*/) {
+ // If autoplay is disabled and the page is trying to autoplay a tracking
+ // ad, then IMA fails with an error, and the page is expected to request
+ // ads again later when the user clicks to play.
+ CheckCanAutoplay().then(
+ () => {
+ const { ADS_MANAGER_LOADED } = AdsManagerLoadedEvent.Type;
+ this._dispatch(new ima.AdsManagerLoadedEvent(ADS_MANAGER_LOADED));
+ },
+ () => {
+ const e = new ima.AdError(
+ "adPlayError",
+ 1205,
+ 1205,
+ "The browser prevented playback initiated without user interaction."
+ );
+ this._dispatch(new ima.AdErrorEvent(e));
+ }
+ );
+ }
+ }
+
+ class AdsManager extends EventHandler {
+ constructor() {
+ super();
+ this.volume = 1;
+ this._enablePreloading = false;
+ }
+ collapse() {}
+ configureAdsManager() {}
+ destroy() {}
+ discardAdBreak() {}
+ expand() {}
+ focus() {}
+ getAdSkippableState() {
+ return false;
+ }
+ getCuePoints() {
+ return [0];
+ }
+ getCurrentAd() {
+ return currentAd;
+ }
+ getCurrentAdCuePoints() {
+ return [];
+ }
+ getRemainingTime() {
+ return 0;
+ }
+ getVolume() {
+ return this.volume;
+ }
+ init(/*w, h, m, e*/) {
+ if (this._enablePreloading) {
+ this._dispatch(new ima.AdEvent(AdEvent.Type.LOADED));
+ }
+ }
+ isCustomClickTrackingUsed() {
+ return false;
+ }
+ isCustomPlaybackUsed() {
+ return false;
+ }
+ pause() {}
+ requestNextAdBreak() {}
+ resize(/*w, h, m*/) {}
+ resume() {}
+ setVolume(v) {
+ this.volume = v;
+ }
+ skip() {}
+ start() {
+ requestAnimationFrame(() => {
+ for (const type of [
+ AdEvent.Type.LOADED,
+ AdEvent.Type.STARTED,
+ AdEvent.Type.CONTENT_PAUSE_REQUESTED,
+ AdEvent.Type.AD_BUFFERING,
+ AdEvent.Type.FIRST_QUARTILE,
+ AdEvent.Type.MIDPOINT,
+ AdEvent.Type.THIRD_QUARTILE,
+ AdEvent.Type.COMPLETE,
+ AdEvent.Type.ALL_ADS_COMPLETED,
+ AdEvent.Type.CONTENT_RESUME_REQUESTED,
+ ]) {
+ try {
+ this._dispatch(new ima.AdEvent(type));
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ });
+ }
+ stop() {}
+ updateAdsRenderingSettings(/*s*/) {}
+ }
+
+ class AdsRenderingSettings {}
+
+ class AdsRequest {
+ setAdWillAutoPlay() {}
+ setAdWillPlayMuted() {}
+ setContinuousPlayback() {}
+ }
+
+ class AdPodInfo {
+ getAdPosition() {
+ return 1;
+ }
+ getIsBumper() {
+ return false;
+ }
+ getMaxDuration() {
+ return -1;
+ }
+ getPodIndex() {
+ return 1;
+ }
+ getTimeOffset() {
+ return 0;
+ }
+ getTotalAds() {
+ return 1;
+ }
+ }
+
+ class Ad {
+ constructor() {
+ this._pi = new AdPodInfo();
+ }
+ getAdId() {
+ return "";
+ }
+ getAdPodInfo() {
+ return this._pi;
+ }
+ getAdSystem() {
+ return "";
+ }
+ getAdvertiserName() {
+ return "";
+ }
+ getApiFramework() {
+ return null;
+ }
+ getCompanionAds() {
+ return [];
+ }
+ getContentType() {
+ return "";
+ }
+ getCreativeAdId() {
+ return "";
+ }
+ getCreativeId() {
+ return "";
+ }
+ getDealId() {
+ return "";
+ }
+ getDescription() {
+ return "";
+ }
+ getDuration() {
+ return 8.5;
+ }
+ getHeight() {
+ return 0;
+ }
+ getMediaUrl() {
+ return null;
+ }
+ getMinSuggestedDuration() {
+ return -2;
+ }
+ getSkipTimeOffset() {
+ return -1;
+ }
+ getSurveyUrl() {
+ return null;
+ }
+ getTitle() {
+ return "";
+ }
+ getTraffickingParameters() {
+ return {};
+ }
+ getTraffickingParametersString() {
+ return "";
+ }
+ getUiElements() {
+ return [""];
+ }
+ getUniversalAdIdRegistry() {
+ return "unknown";
+ }
+ getUniversalAdIds() {
+ return [new UniversalAdIdInfo()];
+ }
+ getUniversalAdIdValue() {
+ return "unknown";
+ }
+ getVastMediaBitrate() {
+ return 0;
+ }
+ getVastMediaHeight() {
+ return 0;
+ }
+ getVastMediaWidth() {
+ return 0;
+ }
+ getWidth() {
+ return 0;
+ }
+ getWrapperAdIds() {
+ return [""];
+ }
+ getWrapperAdSystems() {
+ return [""];
+ }
+ getWrapperCreativeIds() {
+ return [""];
+ }
+ isLinear() {
+ return true;
+ }
+ isSkippable() {
+ return true;
+ }
+ }
+
+ class CompanionAd {
+ getAdSlotId() {
+ return "";
+ }
+ getContent() {
+ return "";
+ }
+ getContentType() {
+ return "";
+ }
+ getHeight() {
+ return 1;
+ }
+ getWidth() {
+ return 1;
+ }
+ }
+
+ class AdError {
+ constructor(type, code, vast, message) {
+ this.errorCode = code;
+ this.message = message;
+ this.type = type;
+ this.vastErrorCode = vast;
+ }
+ getErrorCode() {
+ return this.errorCode;
+ }
+ getInnerError() {
+ return null;
+ }
+ getMessage() {
+ return this.message;
+ }
+ getType() {
+ return this.type;
+ }
+ getVastErrorCode() {
+ return this.vastErrorCode;
+ }
+ toString() {
+ return `AdError ${this.errorCode}: ${this.message}`;
+ }
+ }
+ AdError.ErrorCode = {};
+ AdError.Type = {};
+
+ const isEngadget = () => {
+ try {
+ for (const ctx of Object.values(window.vidible._getContexts())) {
+ const player = ctx.getPlayer();
+ if (!player) { continue;}
+ const div = player.div;
+ if (!div) { continue; }
+ if (div.innerHTML.includes("www.engadget.com")) {
+ return true;
+ }
+ }
+ } catch (_) {}
+ return false;
+ };
+
+ const currentAd = isEngadget() ? undefined : new Ad();
+
+ class AdEvent {
+ constructor(type) {
+ this.type = type;
+ }
+ getAd() {
+ return currentAd;
+ }
+ getAdData() {
+ return {};
+ }
+ }
+ AdEvent.Type = {
+ AD_BREAK_READY: "adBreakReady",
+ AD_BUFFERING: "adBuffering",
+ AD_CAN_PLAY: "adCanPlay",
+ AD_METADATA: "adMetadata",
+ AD_PROGRESS: "adProgress",
+ ALL_ADS_COMPLETED: "allAdsCompleted",
+ CLICK: "click",
+ COMPLETE: "complete",
+ CONTENT_PAUSE_REQUESTED: "contentPauseRequested",
+ CONTENT_RESUME_REQUESTED: "contentResumeRequested",
+ DURATION_CHANGE: "durationChange",
+ EXPANDED_CHANGED: "expandedChanged",
+ FIRST_QUARTILE: "firstQuartile",
+ IMPRESSION: "impression",
+ INTERACTION: "interaction",
+ LINEAR_CHANGE: "linearChange",
+ LINEAR_CHANGED: "linearChanged",
+ LOADED: "loaded",
+ LOG: "log",
+ MIDPOINT: "midpoint",
+ PAUSED: "pause",
+ RESUMED: "resume",
+ SKIPPABLE_STATE_CHANGED: "skippableStateChanged",
+ SKIPPED: "skip",
+ STARTED: "start",
+ THIRD_QUARTILE: "thirdQuartile",
+ USER_CLOSE: "userClose",
+ VIDEO_CLICKED: "videoClicked",
+ VIDEO_ICON_CLICKED: "videoIconClicked",
+ VIEWABLE_IMPRESSION: "viewable_impression",
+ VOLUME_CHANGED: "volumeChange",
+ VOLUME_MUTED: "mute",
+ };
+
+ class AdErrorEvent {
+ constructor(error) {
+ this.type = "adError";
+ this.error = error;
+ }
+ getError() {
+ return this.error;
+ }
+ getUserRequestContext() {
+ return {};
+ }
+ }
+ AdErrorEvent.Type = {
+ AD_ERROR: "adError",
+ };
+
+ const manager = new AdsManager();
+
+ class AdsManagerLoadedEvent {
+ constructor(type) {
+ this.type = type;
+ }
+ getAdsManager(c, settings) {
+ if (settings && settings.enablePreloading) {
+ manager._enablePreloading = true;
+ }
+ return manager;
+ }
+ getUserRequestContext() {
+ return {};
+ }
+ }
+ AdsManagerLoadedEvent.Type = {
+ ADS_MANAGER_LOADED: "adsManagerLoaded",
+ };
+
+ class CustomContentLoadedEvent {}
+ CustomContentLoadedEvent.Type = {
+ CUSTOM_CONTENT_LOADED: "deprecated-event",
+ };
+
+ class CompanionAdSelectionSettings {}
+ CompanionAdSelectionSettings.CreativeType = {
+ ALL: "All",
+ FLASH: "Flash",
+ IMAGE: "Image",
+ };
+ CompanionAdSelectionSettings.ResourceType = {
+ ALL: "All",
+ HTML: "Html",
+ IFRAME: "IFrame",
+ STATIC: "Static",
+ };
+ CompanionAdSelectionSettings.SizeCriteria = {
+ IGNORE: "IgnoreSize",
+ SELECT_EXACT_MATCH: "SelectExactMatch",
+ SELECT_NEAR_MATCH: "SelectNearMatch",
+ };
+
+ class AdCuePoints {
+ getCuePoints() {
+ return [];
+ }
+ }
+
+ class AdProgressData {}
+
+ class UniversalAdIdInfo {
+ getAdIdRegistry() {
+ return "";
+ }
+ getAdIdValue() {
+ return "";
+ }
+ }
+
+ Object.assign(ima, {
+ AdCuePoints,
+ AdDisplayContainer,
+ AdError,
+ AdErrorEvent,
+ AdEvent,
+ AdPodInfo,
+ AdProgressData,
+ AdsLoader,
+ AdsManager: manager,
+ AdsManagerLoadedEvent,
+ AdsRenderingSettings,
+ AdsRequest,
+ CompanionAd,
+ CompanionAdSelectionSettings,
+ CustomContentLoadedEvent,
+ gptProxyInstance: {},
+ ImaSdkSettings,
+ OmidAccessMode: {
+ DOMAIN: "domain",
+ FULL: "full",
+ LIMITED: "limited",
+ },
+ OmidVerificationVendor: {
+ 1: "OTHER",
+ 2: "GOOGLE",
+ GOOGLE: 2,
+ OTHER: 1
+ },
+ settings: new ImaSdkSettings(),
+ UiElements: {
+ AD_ATTRIBUTION: "adAttribution",
+ COUNTDOWN: "countdown",
+ },
+ UniversalAdIdInfo,
+ VERSION,
+ ViewMode: {
+ FULLSCREEN: "fullscreen",
+ NORMAL: "normal",
+ },
+ });
+
+ if (!window.google) {
+ window.google = {};
+ }
+
+ window.google.ima = ima;
+}