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.