Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/browser/extensions/webcompat/shims/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 12 kB image not shown  

Quelle  vidible.js   Sprache: JAVA

 
/* 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/. */


"use strict";

/**
 * Bug 1713710 - Shim Vidible video player
 *
 * Sites relying on Vidible's video player may experience broken videos if that
 * script is blocked. This shim allows users to opt into viewing those videos
 * regardless of any tracking consequences, by providing placeholders for each.
 */


if (!window.vidible?.version) {
  const PlayIconURL = "https://smartblock.firefox.etp/play.svg";

  const originalScript = (() => {
    const src = document.currentScript?.src;
    try {
      const { protocol, hostname, pathname, href } = new URL(src);
      if (
        (protocol === "http:" || protocol === "https:") &&
        pathname.endsWith("/vidible-min.js") &&
        (hostname.endsWith(".vidible.tv") ||
          hostname === "vdb-cdn-files.s3.amazonaws.com")
      ) {
        return href;
      }
    } catch (_) {}
    return "https://cdn-ssl.vidible.tv/prod/player/js/21.1.1/vidible-min.js";
  })();

  const getGUID = () => {
    const v = crypto.getRandomValues(new Uint8Array(20));
    return Array.from(v, c => c.toString(16)).join("");
  };

  const sendMessageToAddon = (function () {
    const shimId = "Vidible";
    const pendingMessages = new Map();
    const channel = new MessageChannel();
    channel.port1.onerror = console.error;
    channel.port1.onmessage = event => {
      const { messageId, response } = event.data;
      const resolve = pendingMessages.get(messageId);
      if (resolve) {
        pendingMessages.delete(messageId);
        resolve(response);
      }
    };
    function reconnect() {
      const detail = {
        pendingMessages: [...pendingMessages.values()],
        port: channel.port2,
        shimId,
      };
      window.dispatchEvent(new CustomEvent("ShimConnects", { detail }));
    }
    window.addEventListener("ShimHelperReady", reconnect);
    reconnect();
    return function (message) {
      const messageId = getGUID();
      return new Promise(resolve => {
        const payload = { message, messageId, shimId };
        pendingMessages.set(messageId, resolve);
        channel.port1.postMessage(payload);
      });
    };
  })();

  const Shimmer = (function () {
    // If a page might store references to an object before we replace it,
    // ensure that it only receives proxies to that object created by
    // `Shimmer.proxy(obj)`. Later when the unshimmed object is created,
    // call `Shimmer.unshim(proxy, unshimmed)`. This way the references
    // will automatically "become" the unshimmed object when appropriate.

    const shimmedObjects = new WeakMap();
    const unshimmedObjects = new Map();

    function proxy(shim) {
      if (shimmedObjects.has(shim)) {
        return shimmedObjects.get(shim);
      }

      const prox = new Proxy(shim, {
        get: (target, k) => {
          if (unshimmedObjects.has(prox)) {
            return unshimmedObjects.get(prox)[k];
          }
          return target[k];
        },
        apply: (target, thisArg, args) => {
          if (unshimmedObjects.has(prox)) {
            return unshimmedObjects.get(prox)(...args);
          }
          return target.apply(thisArg, args);
        },
        construct: (target, args) => {
          if (unshimmedObjects.has(prox)) {
            return new unshimmedObjects.get(prox)(...args);
          }
          return new target(...args);
        },
      });
      shimmedObjects.set(shim, prox);
      shimmedObjects.set(prox, prox);

      for (const key in shim) {
        const value = shim[key];
        if (typeof value === "function") {
          shim[key] = function () {
            const unshimmed = unshimmedObjects.get(prox);
            if (unshimmed) {
              return unshimmed[key].apply(unshimmed, arguments);
            }
            return value.apply(this, arguments);
          };
        } else if (typeof value !== "object" || value === null) {
          shim[key] = value;
        } else {
          shim[key] = Shimmer.proxy(value);
        }
      }

      return prox;
    }

    function unshim(shim, unshimmed) {
      unshimmedObjects.set(shim, unshimmed);

      for (const prop in shim) {
        if (prop in unshimmed) {
          const un = unshimmed[prop];
          if (typeof un === "object" && un !== null) {
            unshim(shim[prop], un);
          }
        } else {
          unshimmedObjects.set(shim[prop], undefined);
        }
      }
    }

    return { proxy, unshim };
  })();

  const extras = [];
  const playersByNode = new WeakMap();
  const playerData = new Map();

  const getJSONPVideoPlacements = () => {
    return document.querySelectorAll(
      `script[src*="delivery.vidible.tv/jsonp"]`
    );
  };

  const allowVidible = () => {
    if (allowVidible.promise) {
      return allowVidible.promise;
    }

    const shim = window.vidible;
    window.vidible = undefined;

    allowVidible.promise = sendMessageToAddon("optIn")
      .then(() => {
        return new Promise((resolve, reject) => {
          const script = document.createElement("script");
          script.src = originalScript;
          script.addEventListener("load", () => {
            Shimmer.unshim(shim, window.vidible);

            for (const args of extras) {
              window.visible.registerExtra(...args);
            }

            for (const jsonp of getJSONPVideoPlacements()) {
              const { src } = jsonp;
              const jscript = document.createElement("script");
              jscript.onload = resolve;
              jscript.src = src;
              jsonp.replaceWith(jscript);
            }

            for (const [playerShim, data] of playerData.entries()) {
              const { loadCalled, on, parent, placeholder, setup } = data;

              placeholder?.remove();

              const player = window.vidible.player(parent);
              Shimmer.unshim(playerShim, player);

              for (const [type, fns] of on.entries()) {
                for (const fn of fns) {
                  try {
                    player.on(type, fn);
                  } catch (e) {
                    console.error(e);
                  }
                }
              }

              if (setup) {
                player.setup(setup);
              }

              if (loadCalled) {
                player.load();
              }
            }

            resolve();
          });

          script.addEventListener("error", () => {
            script.remove();
            reject();
          });

          document.head.appendChild(script);
        });
      })
      .catch(() => {
        window.vidible = shim;
        delete allowVidible.promise;
      });

    return allowVidible.promise;
  };

  const createVideoPlaceholder = (service, callback) => {
    const placeholder = document.createElement("div");
    placeholder.style = `
      position: absolute;
      width: 100%;
      height: 100%;
      min-width: 160px;
      min-height: 100px;
      top: 0px;
      left: 0px;
      background: #000;
      color: #fff;
      text-align: center;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      background-image: url(${PlayIconURL});
      background-position: 50% 47.5%;
      background-repeat: no-repeat;
      background-size: 25% 25%;
      -moz-text-size-adjust: none;
      -moz-user-select: none;
      color: #fff;
      align-items: center;
      padding-top: 200px;
      font-size: 14pt;
    `;
    placeholder.textContent = `Click to allow blocked ${service} content`;
    placeholder.addEventListener("click", evt => {
      evt.isTrusted && callback();
    });
    return placeholder;
  };

  const Player = function (parent) {
    const existing = playersByNode.get(parent);
    if (existing) {
      return existing;
    }

    const player = Shimmer.proxy(this);
    playersByNode.set(parent, player);

    const placeholder = createVideoPlaceholder("Vidible", allowVidible);
    parent.parentNode.insertBefore(placeholder, parent);

    playerData.set(player, {
      on: new Map(),
      parent,
      placeholder,
    });
    return player;
  };

  const changeData = function (fn) {
    const data = playerData.get(this);
    if (data) {
      fn(data);
      playerData.set(this, data);
    }
  };

  Player.prototype = {
    addEventListener() {},
    destroy() {
      const { placeholder } = playerData.get(this);
      placeholder?.remove();
      playerData.delete(this);
    },
    dispatchEvent() {},
    getAdsPassedTime() {},
    getAllMacros() {},
    getCurrentTime() {},
    getDuration() {},
    getHeight() {},
    getPixelsLog() {},
    getPlayerContainer() {},
    getPlayerInfo() {},
    getPlayerStatus() {},
    getRequestsLog() {},
    getStripUrl() {},
    getVolume() {},
    getWidth() {},
    hidePlayReplayControls() {},
    isMuted() {},
    isPlaying() {},
    load() {
      changeData(data => (data.loadCalled = true));
    },
    mute() {},
    on(type, fn) {
      changeData(({ on }) => {
        if (!on.has(type)) {
          on.set(type, new Set());
        }
        on.get(type).add(fn);
      });
    },
    off(type, fn) {
      changeData(({ on }) => {
        on.get(type)?.delete(fn);
      });
    },
    overrideMacro() {},
    pause() {},
    play() {},
    playVideoByIndex() {},
    removeEventListener() {},
    seekTo() {},
    sendBirthDate() {},
    sendKey() {},
    setup(s) {
      changeData(data => (data.setup = s));
      return this;
    },
    setVideosToPlay() {},
    setVolume() {},
    showPlayReplayControls() {},
    toggleFullscreen() {},
    toggleMute() {},
    togglePlay() {},
    updateBid() {},
    version() {},
    volume() {},
  };

  const vidible = {
    ADVERT_CLOSED: "advertClosed",
    AD_END: "adend",
    AD_META: "admeta",
    AD_PAUSED: "adpaused",
    AD_PLAY: "adplay",
    AD_START: "adstart",
    AD_TIMEUPDATE: "adtimeupdate",
    AD_WAITING: "adwaiting",
    AGE_GATE_DISPLAYED: "agegatedisplayed",
    BID_UPDATED: "BidUpdated",
    CAROUSEL_CLICK: "CarouselClick",
    CONTEXT_ENDED: "contextended",
    CONTEXT_STARTED: "contextstarted",
    ENTER_FULLSCREEN: "playerenterfullscreen",
    EXIT_FULLSCREEN: "playerexitfullscreen",
    FALLBACK: "fallback",
    FLOAT_END_ACTION: "floatended",
    FLOAT_START_ACTION: "floatstarted",
    HIDE_PLAY_REPLAY_BUTTON: "hideplayreplaybutton",
    LIGHTBOX_ACTIVATED: "lightboxactivated",
    LIGHTBOX_DEACTIVATED: "lightboxdeactivated",
    MUTE: "Mute",
    PLAYER_CONTROLS_STATE_CHANGE: "playercontrolsstatechaned",
    PLAYER_DOCKED: "playerDocked",
    PLAYER_ERROR: "playererror",
    PLAYER_FLOATING: "playerFloating",
    PLAYER_READY: "playerready",
    PLAYER_RESIZE: "playerresize",
    PLAYLIST_END: "playlistend",
    SEEK_END: "SeekEnd",
    SEEK_START: "SeekStart",
    SHARE_SCREEN_CLOSED: "sharescreenclosed",
    SHARE_SCREEN_OPENED: "sharescreenopened",
    SHOW_PLAY_REPLAY_BUTTON: "showplayreplaybutton",
    SUBTITLES_DISABLED: "subtitlesdisabled",
    SUBTITLES_ENABLED: "subtitlesenabled",
    SUBTITLES_READY: "subtitlesready",
    UNMUTE: "Unmute",
    VIDEO_DATA_LOADED: "videodataloaded",
    VIDEO_END: "videoend",
    VIDEO_META: "videometadata",
    VIDEO_MODULE_CREATED: "videomodulecreated",
    VIDEO_PAUSE: "videopause",
    VIDEO_PLAY: "videoplay",
    VIDEO_SEEKEND: "videoseekend",
    VIDEO_SELECTED: "videoselected",
    VIDEO_START: "videostart",
    VIDEO_TIMEUPDATE: "videotimeupdate",
    VIDEO_VOLUME_CHANGED: "videovolumechanged",
    VOLUME: "Volume",
    _getContexts: () => [],
    "content.CLICK""content.click",
    "content.IMPRESSION""content.impression",
    "content.QUARTILE""content.quartile",
    "content.VIEW""content.view",
    createPlayer: parent => new Player(parent),
    createPlayerAsync: parent => new Player(parent),
    createVPAIDPlayer: parent => new Player(parent),
    destroyAll() {},
    extension() {},
    getContext() {},
    player: parent => new Player(parent),
    playerInceptionTime() {
      return { undefined: 1620149827713 };
    },
    registerExtra(a, b, c) {
      extras.push([a, b, c]);
    },
    version: () => "21.1.313",
  };

  window.vidible = Shimmer.proxy(vidible);

  for (const jsonp of getJSONPVideoPlacements()) {
    const player = new Player(jsonp);
    const { placeholder } = playerData.get(player);
    jsonp.parentNode.insertBefore(placeholder, jsonp);
  }
}

Messung V0.5
C=87 H=98 G=92

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.