PageSourceSearch

https://www.letsroam.com/assets/js/common/mediabox/mediabox.js?cache_version=v12.2.6354ccd

js letsroam.com collected 2026-09-24 09:24:53 UTC 7,847 bytes, 265 lines download raw bytes

1/*! mediabox v1.1.3 | (c) 2018 Pedro Rogerio | https://github.com/pinceladasdaweb/mediabox */
2(function (root, factory) {
3  'use strict';
4  if (typeof define === 'function' && define.amd) {
5    define([], factory);
6  } else if (typeof exports === 'object') {
7    module.exports = factory();
8  } else {
9    root.MediaBox = factory();
10  }
11})(this, function () {
12  'use strict';
13
14  var MediaBox = function (element, params) {
15    var default_params = { autoplay: '1' },
16      params = params || 0;
17
18    if (!this || !(this instanceof MediaBox)) {
19      return new MediaBox(element, params);
20    }
21
22    if (!element) {
23      return false;
24    }
25
26    this.params = Object.assign(default_params, params);
27    this.selector =
28      element instanceof NodeList
29        ? element
30        : document.querySelectorAll(element);
31    this.root = document.querySelector('body');
32    this.run();
33  };
34
35  MediaBox.prototype = {
36    run: function () {
37      Array.prototype.forEach.call(
38        this.selector,
39        function (el) {
40          el.addEventListener(
41            'click',
42            function (e) {
43              console.log('mediabox video player');
44              e.preventDefault();
45
46              var link = this.parseUrl(el.getAttribute('data-video'));
47              this.render(link);
48              this.events();
49            }.bind(this),
50            false
51          );
52        }.bind(this)
53      );
54
55      this.root.addEventListener(
56        'keyup',
57        function (e) {
58          if ((e.keyCode || e.which) === 27) {
59            this.close(this.root.querySelector('.mediabox-wrap'));
60          }
61        }.bind(this),
62        false
63      );
64    },
65    template: function (s, d) {
66      var p;
67
68      for (p in d) {
69        if (d.hasOwnProperty(p)) {
70          s = s.replace(new RegExp('{' + p + '}', 'g'), d[p]);
71        }
72      }
73      return s;
74    },
75    parseUrl: function (url) {
76      var service = {},
77        matches;
78
79      if (
80        (matches = url.match(
81          /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#\&\?]*).*/
82        ))
83      ) {
84        service.provider = 'youtube';
85        service.id = matches[2];
86      } else if (
87        (matches = url.match(
88          /https?:\/\/(?:www\.)?vimeo.com\/(?:channels\/|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|)(\d+)(?:\/([0-9a-zA-Z]+))?(?:$|\/|\?)/
89        ))
90      ) {
91        service.provider = 'vimeo';
92        service.id = matches[3];
93        // An unlisted video is addressed as vimeo.com/<id>/<privacy hash>, and
94        // the hash has to travel to the player or it refuses to load.
95        service.hash = matches[4] || '';
96      } else {
97        service.provider = 'Unknown';
98        service.id = '';
99      }
100
101      return service;
102    },
103    // Reason: lightbox videos are narrated in English, so non-English visitors need
104    // captions turned on by default in their own language. Both providers support
105    // that through URL params, and an unavailable track is simply ignored by the
106    // player, so this is safe to always send on translated pages.
107    pageLanguage: function () {
108      var lang = '';
109
110      if (typeof document !== 'undefined' && document.documentElement) {
111        lang = document.documentElement.getAttribute('lang') || '';
112      }
113
114      // Normalize values like "pt-BR" or "pt_br" down to the base language code.
115      lang = lang.toLowerCase().replace('_', '-').split('-')[0];
116
117      return lang;
118    },
119    subtitleParams: function (service) {
120      var lang = this.pageLanguage();
121
122      if (!lang || lang === 'en') {
123        return {};
124      }
125
126      if (service.provider === 'youtube') {
127        return { cc_load_policy: '1', cc_lang_pref: lang, hl: lang };
128      }
129
130      if (service.provider === 'vimeo') {
131        return { texttrack: lang };
132      }
133
134      return {};
135    },
136    render: function (service) {
137      var embedLink, lightbox, urlParams, params, subtitles, key;
138
139      if (service.provider === 'youtube') {
140        embedLink = 'https://www.youtube.com/embed/' + service.id;
141      } else if (service.provider === 'vimeo') {
142        embedLink = 'https://player.vimeo.com/video/' + service.id;
143      } else {
144        throw new Error('Invalid video URL');
145      }
146
147      console.log('rendering video');
148      if (typeof fb_track_safe !== 'undefined') {
149        fb_track_safe('VideoView');
150      }
151
152      // Build a per-render copy so caption params never leak into later renders.
153      params = Object.assign({}, this.params);
154      if (service.provider === 'vimeo' && service.hash) {
155        params.h = service.hash;
156      }
157      subtitles = this.subtitleParams(service);
158      for (key in subtitles) {
159        if (subtitles.hasOwnProperty(key) && typeof params[key] === 'undefined') {
160          params[key] = subtitles[key];
161        }
162      }
163
164      urlParams = this.serialize(params);
165
166      lightbox = this.template(
167        '<div style="z-index: 9999999;" class="mediabox-wrap" role="dialog" aria-hidden="false"><div class="mediabox-content" role="document" tabindex="0"><span id="mediabox-esc" class="mediabox-close" aria-label="close" tabindex="1"></span><iframe src="{embed}{params}" frameborder="0" allowfullscreen></iframe></div></div>',
168        {
169          embed: embedLink,
170          params: urlParams,
171        }
172      );
173
174      this.lastFocusElement = document.activeElement;
175      this.root.insertAdjacentHTML('beforeend', lightbox);
176      document.body.classList.add('stop-scroll');
177
178      // Reason: the texttrack parameter above is applied inconsistently by the
179      // player, so enable the track explicitly through the API as well. This
180      // also records the video's tracks so later page loads can skip discovery.
181      if (service.provider === 'vimeo' && window.lrApplyVimeoSubtitles) {
182        var insertedIframe = this.root.querySelector('.mediabox-wrap iframe');
183        window.lrApplyVimeoSubtitles(insertedIframe, service.id);
184      }
185    },
186    events: function () {
187      var wrapper = document.querySelector('.mediabox-wrap');
188      var content = document.querySelector('.mediabox-content');
189
190      wrapper.addEventListener(
191        'click',
192        function (e) {
193          if (
194            (e.target &&
195              e.target.nodeName === 'SPAN' &&
196              e.target.className === 'mediabox-close') ||
197            (e.target.nodeName === 'DIV' &&
198              e.target.className === 'mediabox-wrap') ||
199            (e.target.className === 'mediabox-content' &&
200              e.target.nodeName !== 'IFRAME')
201          ) {
202            this.close(wrapper);
203          }
204        }.bind(this),
205        false
206      );
207
208      document.addEventListener(
209        'focus',
210        function (e) {
211          if (content && !content.contains(e.target)) {
212            e.stopPropagation();
213            content.focus();
214          }
215        },
216        true
217      );
218
219      content.addEventListener(
220        'keypress',
221        function (e) {
222          if (e.keyCode === 13) {
223            this.close(wrapper);
224          }
225        }.bind(this),
226        false
227      );
228    },
229    close: function (el) {
230      if (el === null) return true;
231      var timer = null;
232
233      if (timer) {
234        clearTimeout(timer);
235      }
236
237      el.classList.add('mediabox-hide');
238
239      timer = setTimeout(
240        function () {
241          var el = document.querySelector('.mediabox-wrap');
242          if (el !== null) {
243            document.body.classList.remove('stop-scroll');
244            this.root.removeChild(el);
245            this.lastFocusElement.focus();
246          }
247        }.bind(this),
248        500
249      );
250    },
251    serialize: function (obj) {
252      return (
253        '?' +
254        Object.keys(obj)
255          .reduce(function (a, k) {
256            a.push(k + '=' + encodeURIComponent(obj[k]));
257            return a;
258          }, [])
259          .join('&')
260      );
261    },
262  };
263
264  return MediaBox;
265});

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.