PageSourceSearch

https://player.hashtagtreinamentos.com/api.v2.js

js hashtagtreinamentos.com collected 2026-09-25 14:11:44 UTC 6,078 bytes, 144 lines download raw bytes

1/*
2 * Hash Player -- api.v2.js, no mesmo contrato da api.v2.js do Panda.
3 *
4 * Os sites (tema-wordpress-hashtag, lps-hashtag, capacitaciones, fnat) fazem:
5 *
6 *     new PandaPlayer(idDoIframe, { onReady, onError })
7 *     player.onEvent(({ message, currentTime, isMutedIndicator }) => ...)   // "panda_timeupdate"
8 *     player.getCurrentTime(); player.getDuration(); player.play(); ...
9 *
10 * e e so isso que precisa continuar funcionando quando o host do iframe e o
11 * deste script trocarem (F3). O protocolo entre esta pagina e o iframe e o
12 * MESMO do Panda (medido em 19/09/2026 na api.v2.js deles): o iframe manda
13 * `{ message: "panda_allData", video, playerData: {...} }` e
14 * `{ message: "panda_timeupdate", video, currentTime, isMutedIndicator }`;
15 * o pai manda `{ type: "play" | "pause" | "togglePlay" | "currentTime" |
16 * "volume" | "speed" | "fullscreen.toggle", parameter }`. Assim a api.v2.js
17 * deles tambem toca o nosso embed, e a nossa toca o deles.
18 *
19 * Sem dependencia, sem build: e servido como esta em /api.v2.js.
20 */
21(function () {
22  "use strict";
23
24  function idDoVideo(iframe) {
25    try {
26      return new URL(iframe.src, location.href).searchParams.get("v") || "";
27    } catch (e) {
28      return "";
29    }
30  }
31
32  function PandaPlayer(elementId, opcoes) {
33    var self = this;
34    opcoes = opcoes || {};
35    this.element_id = elementId;
36    this.onReady = opcoes.onReady;
37    this.onError = opcoes.onError;
38    this.ready = false;
39    this.paused = true;
40    this.muted = false;
41    this.volume = 1;
42    this.currentTime = 0;
43    this.duration = 0;
44    this.speed = 1;
45    this.fullscreen = false;
46    this.captions = null;
47    this.callbacks = [];
48    this._filaEventos = [];
49    this._filaChamadas = [];
50
51    var iframe = document.getElementById(elementId);
52    if (!iframe || iframe.tagName !== "IFRAME") {
53      if (this.onError) this.onError({ message: "panda_error", error: "iframe nao encontrado: " + elementId });
54      return;
55    }
56    this.iframe = iframe;
57    this.video_external_id = idDoVideo(iframe);
58    try {
59      this.origin = new URL(iframe.src, location.href).origin;
60    } catch (e) {
61      this.origin = "*";
62    }
63
64    this._ouvir = function (ev) {
65      var d = ev.data;
66      if (!d || typeof d !== "object" || !d.message) return;
67      if (ev.source !== iframe.contentWindow) return;
68      if (d.video && self.video_external_id && d.video !== self.video_external_id) return;
69      if (d.message === "panda_error" && self.onError) self.onError(d);
70      if (d.message === "panda_allData" && d.playerData) {
71        var p = d.playerData;
72        self.paused = !!p.paused;
73        self.muted = !!p.muted;
74        self.volume = p.volume;
75        self.currentTime = p.currentTime;
76        self.duration = p.duration;
77        self.speed = p.speed;
78        self.fullscreen = !!p.fullscreen;
79        self.captions = p.captions;
80        if (!self.ready && p.duration > 0) {
81          self.ready = true;
82          if (self.onReady) self.onReady();
83          self._filaChamadas.forEach(function (f) { f(); });
84          self._filaChamadas = [];
85        }
86      }
87      if (d.message === "panda_timeupdate") self.currentTime = d.currentTime;
88      if (self.ready) {
89        if (self._filaEventos.length) {
90          self._filaEventos.forEach(function (e) { self.callbacks.forEach(function (cb) { cb(e); }); });
91          self._filaEventos = [];
92        }
93        self.callbacks.forEach(function (cb) { cb(d); });
94      } else {
95        self._filaEventos.push(d);
96      }
97    };
98    window.addEventListener("message", this._ouvir);
99    // Instanciado DEPOIS de o iframe carregar, os allData iniciais ja se
100    // foram e `ready` nunca viraria: pergunta o estado agora, fora da fila
101    // (que so anda depois do ready). Se o iframe ainda nao carregou, a
102    // pergunta se perde e o proprio loadedmetadata dele traz o allData.
103    try {
104      if (iframe.contentWindow) iframe.contentWindow.postMessage({ type: "allData" }, this.origin);
105    } catch (e) {}
106  }
107
108  PandaPlayer.prototype._mandar = function (msg) {
109    var self = this;
110    var envia = function () {
111      if (self.iframe && self.iframe.contentWindow) self.iframe.contentWindow.postMessage(msg, self.origin);
112    };
113    if (this.ready) envia();
114    else this._filaChamadas.push(envia);
115  };
116
117  PandaPlayer.prototype.onEvent = function (cb) {
118    if (typeof cb === "function") this.callbacks.push(cb);
119  };
120  PandaPlayer.prototype.play = function () { this._mandar({ type: "play" }); };
121  PandaPlayer.prototype.pause = function () { this._mandar({ type: "pause" }); };
122  PandaPlayer.prototype.togglePlay = function () { this._mandar({ type: "togglePlay" }); };
123  PandaPlayer.prototype.setCurrentTime = function (t) { this._mandar({ type: "currentTime", parameter: Number(t) || 0 }); };
124  PandaPlayer.prototype.getCurrentTime = function () { return this.currentTime; };
125  PandaPlayer.prototype.getDuration = function () { return this.duration; };
126  PandaPlayer.prototype.setVolume = function (v) { this._mandar({ type: "volume", parameter: Number(v) }); };
127  PandaPlayer.prototype.getVolume = function () { return this.volume; };
128  PandaPlayer.prototype.setSpeed = function (s) { this._mandar({ type: "speed", parameter: Number(s) || 1 }); };
129  PandaPlayer.prototype.getSpeed = function () { return this.speed; };
130  PandaPlayer.prototype.isPaused = function () { return this.paused; };
131  PandaPlayer.prototype.isMuted = function () { return this.muted; };
132  PandaPlayer.prototype.toggleFullscreen = function () { this._mandar({ type: "fullscreen.toggle" }); };
133  PandaPlayer.prototype.exitFullscreen = function () { this._mandar({ type: "fullscreen.exit" }); };
134  PandaPlayer.prototype.destroy = function () {
135    window.removeEventListener("message", this._ouvir);
136    this.callbacks = [];
137  };
138  // Existem na api do Panda; aqui sao no-op declarados, para nao quebrar quem chama.
139  PandaPlayer.prototype.loadButtonInTime = function () {};
140  PandaPlayer.prototype.loadWindowScreen = function () {};
141
142  window.PandaPlayer = PandaPlayer;
143  window.HashPlayer = PandaPlayer;
144})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.