1/* 2 * DOM 3 */ 4(function(window, document){ 5 "use strict"; 6 7 var getByClass = function(context, cl){ 8 context = context || document; 9 if(context.getElementsByClassName) return context.getElementsByClassName(cl); 10 var node = context.getElementsByTagName('*') || context.all, 11 i = node.length, 12 e = []; 13 14 while(i--){ 15 var clNms = node[i].className.split(' '); 16 var j = clNms.length; 17 while(j--){ 18 if(clNms[j] == cl){ 19 e.push(node[i]); 20 break; 21 } 22 } 23 } 24 return e; 25 }, 26 getByAttr = function(context, attr){ 27 context = context || document; 28 var attrs = attr.split("="), 29 node = context.getElementsByTagName('*') || context.all, 30 i = node.length, 31 e = []; 32 33 while(i--){ 34 if(node[i].getAttribute(attrs[0]) == attrs[1]){ 35 e.push(node[i]); 36 } 37 } 38 return e; 39 }, 40 hasClass = function(el, cl){ 41 return new RegExp('(\\s|^)' + cl + '(\\s|$)').test(el.className); 42 }, 43 setEvent = function(el, e, cb){ 44 45 el.evnts = el.evnts || {}; 46 47 el.evnts[e[0]] = el.evnts[e[0]] || []; 48 49 var obj = []; 50 obj[0] = cb; 51 if(e[1]) obj[1] = e[1]; 52 53 el.evnts[e[0]].push(obj); 54 55 }, 56 bindEvent = function(el, event, cb){ 57 var events = event.split(' '); 58 59 for(var i = 0, l = events.length; i < l; i++){ 60 var e = events[i].split('.'); 61 62 if(el.addEventListener){ 63 el.addEventListener(e[0], cb, false); 64 } 65 else if(el.attachEvent){ 66 el.attachEvent('on' + e[0], cb); 67 } 68 69 setEvent(el, e, cb); 70 } 71 }, 72 unbindEvent = function(el, event){ 73 var events = event.split(' '); 74 el.evnts = el.evnts || []; 75 76 for(var i = 0, l = events.length; i < l; i++){ 77 var e = events[i].split('.'); 78 79 if(!el.evnts[e[0]]) continue; 80 81 var ii = el.evnts[e[0]].length; 82 while(ii--){ 83 84 if(e[1] && el.evnts[e[0]][ii][1] != e[1]) continue; 85 86 if(el.removeEventListener){ 87 el.removeEventListener(e[0], el.evnts[e[0]][ii][0], false); 88 } 89 else if(el.detachEvent){ 90 el.detachEvent('on' + e[0], el.evnts[e[0]][ii][0]); 91 } 92 93 el.evnts[e[0]].splice(ii, 1); 94 95 } 96 97 } 98 }, 99 toHTML = function(html){ 100 var a = document.createElement("div"); 101 102 a.innerHTML = html; 103 104 return a; 105 }, 106 getAbsoluteUrl = function(url){ 107 var el = document.createElement('div'); 108 el.innerHTML = '<a></a>'; 109 el.firstChild.href = url; 110 el.innerHTML = el.innerHTML; 111 return el.firstChild.href; 112 }, 113 triggerLoadCache = function(uri, status){ 114 for(var i = 0, item; item = DOM.load.cache[uri][i++]; ){ 115 if(status === 'success' && typeof item.cb === "function") item.cb(); 116 if(status === 'error' && typeof item.err === "function") item.err(); 117 } 118 DOM.load.cache[uri] = status; 119 }, 120 getXHR = function(){ 121 if(window.XDomainRequest){ 122 return new XDomainRequest(); 123 } 124 if(window.XMLHttpRequest){ 125 return new XMLHttpRequest(); 126 } 127 try{ 128 return new ActiveXObject('MSXML2.XMLHTTP.6.0'); 129 } 130 catch(e){ 131 try{ 132 return new ActiveXObject('MSXML2.XMLHTTP.3.0'); 133 } 134 catch(e){ 135 throw new Error("This browser does not support XMLHttpRequest."); 136 } 137 } 138 }; 139 140 var DOM = function(selector, context){ 141 return new DOM.lets.init(selector, context); 142 } 143 DOM.lets = DOM.prototype = { 144 constructor: DOM, 145 init: function(selector, context){ 146 context = context || document; 147 148 if(context instanceof DOM) context = context[0]; 149 150 if(!selector){ 151 return this; 152 } 153 else if(selector.nodeType || selector === window || selector === document){ 154 this[0] = selector; 155 this.length = 1; 156 } 157 else if(typeof selector === "string"){ 158 159 var s = selector.charAt(0), 160 el = []; 161 162 if(s == '#'){ 163 164 var id = document.getElementById(selector.substr(1)); 165 if(id) el[0] = id; 166 167 } 168 else{ 169 170 if(/\s/.test(selector)){ 171 172 var selectors = selector.split(/\s/); 173 174 var i = 0, 175 el = context; 176 177 while(i < selectors.length){ 178 el = DOM(selectors[i++], el); 179 } 180 181 } 182 else{ 183 184 if(s == '.'){ 185 el = getByClass(context, selector.substr(1).replace(/\./g, ' ')); 186 } 187 else if(s == '['){ 188 el = getByAttr(context, selector.substr(1, selector.length - 2)); 189 } 190 else{ 191 el = context.getElementsByTagName(selector); 192 } 193 194 } 195 196 } 197 198 if(!el[0] && context.querySelectorAll){ 199 200 try{ 201 el = context.querySelectorAll(selector); 202 } 203 catch(e){} 204 205 } 206 207 el = this.slice.call(el); 208 209 if(el[0]){ 210 this.length = el.length; 211 for(var i = 0, l = el.length; i < l; i++){ 212 this[i] = el[i]; 213 } 214 } 215 216 } 217 218 return (selector.constructor === DOM ? selector : this); 219 }, 220 length: 0, 221 slice: [].slice, 222 splice: [].splice 223 } 224 DOM.lets.init.prototype = DOM.lets; 225 226 DOM.lets.eq = function(index){ 227 return DOM(this[index]); 228 } 229 DOM.lets.find = function(selector){ 230 return DOM(selector, this[0]); 231 } 232 DOM.lets.parent = function(){ 233 return DOM(this[0].parentNode); 234 } 235 DOM.lets.on = function(type, cb){ 236 for(var i = 0, l = this.length; i < l; i++){ 237 bindEvent(this[i], type, cb); 238 } 239 240 return this; 241 } 242 DOM.lets.one = function(type, cb){ 243 var orgCb = cb; 244 /* 245 * TODO 246 * - add parsing type and adding random .namespace to func when doesnt include 247 */ 248 cb = function(event){ 249 DOM(this).off(type); 250 return orgCb.apply(this, arguments); 251 } 252 for(var i = 0, l = this.length; i < l; i++){ 253 bindEvent(this[i], type, cb); 254 } 255 256 return this; 257 } 258 DOM.lets.off = function(type){ 259 for(var i = 0, l = this.length; i < l; i++){ 260 unbindEvent(this[i], type); 261 } 262 263 return this; 264 } 265 DOM.lets.show = function(){ 266 for(var i = 0, l = this.length; i < l; i++){ 267 this[i].style.display = 'block'; 268 } 269 270 return this; 271 } 272 DOM.lets.hide = function(){ 273 for(var i = 0, l = this.length; i < l; i++){ 274 this[i].style.display = 'none'; 275 } 276 277 return this; 278 } 279 DOM.lets.focus = function(){ 280 return DOM(this[0].focus()); 281 } 282 DOM.lets.css = function(prop, value){ 283 if(typeof prop === "Object"){ 284 285 } 286 else if(prop && value){ 287 for(var i = 0, l = this.length; i < l; i++){ 288 this[i].style[prop] = value; 289 } 290 } 291 else if(prop && this.length == 1){ 292 return this[0].style[prop]; 293 } 294 295 return this; 296 } 297 DOM.lets.attr = function(attr, value){ 298 if(typeof attr === "Object"){ 299 // TODO 300 } 301 else if(attr && typeof value != "undefined"){ 302 for(var i = 0, l = this.length; i < l; i++){ 303 this[i].setAttribute(attr, value); 304 } 305 } 306 else if(typeof value == "undefined" && this[0]){ 307 return this[0].getAttribute(attr); 308 } 309 310 return this; 311 } 312 DOM.lets.removeAttr = function(attr){ 313 for(var i = 0, l = this.length; i < l; i++){ 314 this[i].removeAttribute(attr); 315 } 316 317 return this; 318 } 319 DOM.lets.val = function(val){ 320 if(val){ 321 for(var i = 0, l = this.length; i < l; i++){ 322 this[i].value = val; 323 } 324 } 325 else{ 326 return this[0].value; 327 } 328 329 return this; 330 } 331 DOM.lets.hasClass = function(cl){
332 return hasClass(this[0], cl); 333 } 334 DOM.lets.addClass = function(cl){ 335 var cl = cl.split(" "); 336 for(var i = 0, l = this.length; i < l; i++){ 337 for(var ii = 0, ll = cl.length; ii < ll; ii++){ 338 if(!hasClass(this[i], cl[ii])){ 339 this[i].className += (this[i].className ? ' ' : '') + cl[ii]; 340 } 341 } 342 } 343 344 return this; 345 } 346 DOM.lets.removeClass = function(cl){ 347 for(var i = 0, l = this.length; i < l; i++){ 348 if(cl){ 349 var splitCl = cl.split(" "); 350 for(var j = 0, k = splitCl.length; j < k; j++){ 351 352 if(hasClass(this[i], splitCl[j])){ 353 354 var curCl = this[i].className.split(" "); 355 var filter = []; 356 357 for(var ii = 0, ll = curCl.length; ii < ll; ii++){ 358 if(splitCl[j] != curCl[ii] && curCl[ii] != ""){ 359 filter.push(curCl[ii]); 360 } 361 } 362 363 this[i].className = filter.join(" "); 364 365 } 366 367 } 368 } 369 else{ 370 this[i].className = ""; 371 } 372 } 373 374 return this; 375 } 376 DOM.lets.toggleClass = function(cl, check){ 377 for(var i = 0, l = this.length; i < l; i++){ 378 if(typeof check !== "undefinded"){ 379 DOM(this[i])[(check ? "add" : "remove") + "Class"](cl); 380 } 381 else{ 382 383 if(DOM(this[i]).hasClass(cl)){ 384 DOM(this[i]).removeClass(cl); 385 } 386 else{ 387 DOM(this[i]).addClass(cl); 388 } 389 390 } 391 } 392 393 return this; 394 } 395 DOM.lets.wrap = function(html){ 396 var html = toHTML(html).firstChild; 397 398 for(var i = 0, l = this.length; i < l; i++){ 399 var el = this[i]; 400 401 if(el.nextSibling){ 402 el.parentNode.insertBefore(html, el.nextSibling); 403 } 404 else{ 405 el.parentNode.appendChild(html); 406 } 407 408 html.appendChild(el); 409 } 410 411 return this; 412 } 413 DOM.lets.append = function(html){ 414 for(var i = 0, l = this.length; i < l; i++){ 415 var html = toHTML(html); 416 while(html.children.length > 0){ 417 this[i].appendChild(html.children[0]); 418 } 419 } 420 421 return this; 422 } 423 DOM.lets.html = function(html){ 424 var html = toHTML(html).innerHTML; 425 426 for(var i = 0, l = this.length; i < l; i++){ 427 this[i].innerHTML = html; 428 } 429 430 return this; 431 } 432 DOM.lets.replaceWith = function(html){ 433 var html = toHTML(html).firstChild; 434 435 for(var i = 0, l = this.length; i < l; i++){ 436 var parent = this[i].parentNode; 437 438 parent.replaceChild(html, this[i]); 439 } 440 441 return this; 442 } 443 DOM.lets.remove = function(){ 444 for(var i = 0, l = this.length; i < l; i++){ 445 this[i].parentNode.removeChild(this[i]); 446 } 447 } 448 DOM.lets.scrollTop = function(val){ 449 var el = this[0], 450 win = el === window; 451 if(val === undefined){ 452 return win ? 453 ("pageYOffset" in el) ? 454 el["pageYOffset"] : 455 el.document.documentElement["scrollTop"] : 456 el["scrollTop"]; 457 } 458 459 if(win){ 460 el.scrollTo( 461 DOM(el).scrollLeft(), 462 val 463 ); 464 } 465 else{ 466 el["scrollTop"] = val; 467 } 468 } 469 DOM.lets.scrollLeft = function(val){ 470 var el = this[0], 471 win = el === window; 472 if(val === undefined){ 473 return win ? 474 ("pageXOffset" in el) ? 475 el["pageXOffset"] : 476 el.document.documentElement["scrollLeft"] : 477 el["scrollLeft"]; 478 } 479 480 if(win){ 481 el.scrollTo( 482 val, 483 DOM(el).scrollTop() 484 ); 485 } 486 else{ 487 el["scrollLeft"] = val; 488 } 489 } 490 491 DOM.extend = function(def, opt){ 492 var ext = {}; 493 var prop; 494 for(prop in def){ 495 if(Object.prototype.hasOwnProperty.call(def, prop)){ 496 ext[prop] = def[prop]; 497 } 498 } 499 for(prop in opt){ 500 if(Object.prototype.hasOwnProperty.call(opt, prop)){ 501 ext[prop] = opt[prop]; 502 } 503 } 504 return ext; 505 } 506 DOM.merge = function(first, second){ 507 var i = first.length, 508 j = 0; 509 510 if(typeof second.length === "number"){ 511 for(var l = second.length; j < l; j++){ 512 first[i++] = second[j]; 513 } 514 } 515 else{ 516 while(second[j] !== undefined){ 517 first[i++] = second[j++]; 518 } 519 } 520 521 first.length = i; 522 523 return first; 524 } 525 DOM.inArray = function(val, arr){ 526 for(var i = 0, l = arr.length; i < l; i++){ 527 if(arr[i] === val){ 528 return i; 529 } 530 } 531 return -1; 532 } 533 DOM.load = function(url, cb, err){ 534 var uri = getAbsoluteUrl(url); 535 536 if(typeof DOM.load.cache[uri] === "undefined"){ 537 var a, 538 b = document.getElementsByTagName('head')[0], 539 type=url.split('.').pop(); 540 541 if(type == 'css'){ 542 a = document.createElement('link'); 543 a.rel = 'stylesheet'; 544 a.type = 'text/css'; 545 } 546 else if(type == 'js'){ 547 a = document.createElement('script'); 548 a.type = 'text/javascript'; 549 } 550 551 DOM.load.cache[uri] = []; 552 DOM.load.cache[uri].push({ 553 cb: cb, 554 err: err, 555 }); 556 557 a.onload = function(){ 558 triggerLoadCache(uri, 'success'); 559 } 560 a.onreadystatechange = function(){ 561 if(this.readyState == 'complete' || this.readyState == 'loaded'){ 562 triggerLoadCache(uri, 'success'); 563 } 564 } 565 a.onerror = function(e){
566 triggerLoadCache(uri, 'error'); 567 } 568 569 a[type == 'css' ? "href" : "src"] = url; 570 571 b.appendChild(a); 572 573 } else { 574 if(typeof DOM.load.cache[uri] !== "string"){ 575 DOM.load.cache[uri].push({ 576 cb: cb, 577 err: err, 578 }); 579 } else { 580 if(DOM.load.cache[uri] === "success" && typeof cb === "function") cb(); 581 if(DOM.load.cache[uri] === "error" && typeof err === "function") err(); 582 } 583 } 584 585 } 586 DOM.load.cache = {}; 587 DOM.xhr = function(opts){ 588 var done = false, timer; 589 try{ 590 var xhr = getXHR(); 591 var async = typeof opts.async === "boolean" ? opts.async : true; 592 xhr.open(opts.method || "GET", opts.url, async); 593 xhr.onload = function(){ 594 clearTimeout(timer); 595 if(done) return; 596 done = true; 597 598 if(typeof opts.onload == "function") opts.onload(xhr.responseText, xhr); 599 if(typeof opts.oncomplete == "function") opts.oncomplete(xhr); 600 } 601 xhr.onreadystatechange = function(){ 602 if(this.readyState == 4 && !done) { 603 if(this.status == 200) { 604 xhr.onload.call(this); 605 } else { 606 xhr.onerror.call(this); 607 } 608 } 609 }; 610 xhr.onerror = function(err){ 611 clearTimeout(timer); 612 if(done) return; 613 done = true; 614 615 if(typeof opts.onerror == "function") opts.onerror(null, err || "error", this); 616 if(typeof opts.oncomplete == "function") opts.oncomplete(xhr); 617 }; 618 xhr.ontimeout = function(){ 619 xhr.onerror.call(this, "timeout"); 620 }; 621 xhr.onabort = function(){ 622 xhr.onerror.call(this, "abort"); 623 }; 624 if(async) xhr.timeout = opts.timeout || 10000; 625 xhr.withCredentials = opts.credentials || false; 626 if(opts.data) { 627 xhr.setRequestHeader("Content-Type", opts.contentType || "application/x-www-form-urlencoded; charset=UTF-8"); 628 } 629 xhr.send(opts.data || null); 630 631 timer = setTimeout(function(){ 632 xhr.ontimeout.call(xhr); 633 }, xhr.timeout); 634 } 635 catch(e){ 636 if(typeof opts.onerror == "function") opts.onerror(null, "trycatch"); 637 } 638 } 639 DOM.getJSON = function(url, cb, opts){ 640 DOM.xhr(DOM.extend({ 641 url: url, 642 onload: function(data, xhr){ 643 var status; 644 645 try{ 646 data = JSON.parse(data); 647 status = "success"; 648 } 649 catch(e){ 650 status = "invalid JSON"; 651 } 652 653 if(typeof cb == "function") cb(data, status, this); 654 }, 655 onerror: cb 656 }, opts || {})); 657 } 658 659 window.DOM = DOM; 660 661})(window, document); 662 663if (!Function.prototype.bind) { 664 Function.prototype.bind = function(oThis) { 665 if (typeof this !== 'function') { 666 // closest thing possible to the ECMAScript 5 667 // internal IsCallable function 668 throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); 669 } 670 671 var aArgs = Array.prototype.slice.call(arguments, 1), 672 fToBind = this, 673 fNOP = function() {}, 674 fBound = function() { 675 return fToBind.apply(this instanceof fNOP 676 ? this 677 : oThis, 678 aArgs.concat(Array.prototype.slice.call(arguments))); 679 }; 680 681 if (this.prototype) { 682 // Function.prototype doesn't have a prototype property 683 fNOP.prototype = this.prototype; 684 } 685 fBound.prototype = new fNOP(); 686 687 return fBound; 688 }; 689} 690 691if (!Array.prototype.map) { 692 Array.prototype.map = function(callback/*, thisArg*/) { 693 var T, A, k; 694 695 if (this == null) { 696 throw new TypeError('this is null or not defined'); 697 } 698 699 var O = Object(this); 700 var len = O.length >>> 0; 701 702 if (typeof callback !== 'function') { 703 throw new TypeError(callback + ' is not a function'); 704 } 705 706 if (arguments.length > 1) { 707 T = arguments[1]; 708 } 709 710 A = new Array(len); 711 k = 0; 712 713 while (k < len) { 714 var kValue, mappedValue; 715 716 if (k in O) { 717 kValue = O[k]; 718 mappedValue = callback.call(T, kValue, k, O); 719 A[k] = mappedValue; 720 } 721 k++; 722 } 723 724 return A; 725 }; 726} 727 728if (!Array.prototype.filter) { 729 Array.prototype.filter = function(fun /*, thisp*/) 730 { 731 var len = this.length; 732 if (typeof fun != "function") 733 throw new TypeError(); 734 735 var res = new Array(); 736 var thisp = arguments[1]; 737 for (var i = 0; i < len; i++) 738 { 739 if (i in this) 740 { 741 var val = this[i]; // in case fun mutates this 742 if (fun.call(thisp, val, i, this)) 743 res.push(val); 744 } 745 } 746 747 return res; 748 }; 749} 750 751// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel 752// MIT license
753!function(a,b,c){var f,d=0,e=["ms","moz","webkit","o"];for(f=0;f<e.length&&!a[b];++f)a[b]=a[e[f]+"RequestAnimationFrame"],a[c]=a[e[f]+"CancelAnimationFrame"]||a[e[f]+"CancelRequestAnimationFrame"];a[b]||(a[b]=function(b){var c=(new Date).getTime(),e=Math.max(0,16-(c-d)),f=a.setTimeout(function(){b(c+e)},e);return d=c+e,f}),a[c]||(a[c]=function(b){a.clearTimeout(b)})}(this,"requestAnimationFrame","cancelAnimationFrame"); 754 755// uuidv4 - RFC4122 UUIDs 756// MIT license 757!function(r){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=r();else if("function"==typeof define&&define.amd)define([],r);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.uuidv4=r()}}(function(){return function r(e,n,t){function o(f,u){if(!n[f]){if(!e[f]){var a="function"==typeof require&&require;if(!u&&a)return a(f,!0);if(i)return i(f,!0);var d=new Error("Cannot find module '"+f+"'");throw d.code="MODULE_NOT_FOUND",d}var p=n[f]={exports:{}};e[f][0].call(p.exports,function(r){var n=e[f][1][r];return o(n?n:r)},p,p.exports,r,e,n,t)}return n[f].exports}for(var i="function"==typeof require&&require,f=0;f<t.length;f++)o(t[f]);return o}({1:[function(r,e,n){function t(r,e){var n=e||0,t=o;return t[r[n++]]+t[r[n++]]+t[r[n++]]+t[r[n++]]+"-"+t[r[n++]]+t[r[n++]]+"-"+t[r[n++]]+t[r[n++]]+"-"+t[r[n++]]+t[r[n++]]+"-"+t[r[n++]]+t[r[n++]]+t[r[n++]]+t[r[n++]]+t[r[n++]]+t[r[n++]]}for(var o=[],i=0;i<256;++i)o[i]=(i+256).toString(16).substr(1);e.exports=t},{}],2:[function(r,e,n){var t="undefined"!=typeof crypto&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&msCrypto.getRandomValues.bind(msCrypto);if(t){var o=new Uint8Array(16);e.exports=function(){return t(o),o}}else{var i=new Array(16);e.exports=function(){for(var r,e=0;e<16;e++)0===(3&e)&&(r=4294967296*Math.random()),i[e]=r>>>((3&e)<<3)&255;return i}}},{}],3:[function(r,e,n){function t(r,e,n){var t=e&&n||0;"string"==typeof r&&(e="binary"===r?new Array(16):null,r=null),r=r||{};var f=r.random||(r.rng||o)();if(f[6]=15&f[6]|64,f[8]=63&f[8]|128,e)for(var u=0;u<16;++u)e[t+u]=f[u];return e||i(f)}var o=r("./lib/rng"),i=r("./lib/bytesToUuid");e.exports=t},{"./lib/bytesToUuid":1,"./lib/rng":2}]},{},[3])(3)}); 758 759// JavaScript MD5 760// MIT license 761!function(n){"use strict";function t(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function r(n,t){return n<<t|n>>>32-t}function e(n,e,o,u,c,f){return t(r(t(t(e,n),t(u,f)),c),o)}function o(n,t,r,o,u,c,f){return e(t&r|~t&o,n,t,u,c,f)}function u(n,t,r,o,u,c,f){return e(t&o|r&~o,n,t,u,c,f)}function c(n,t,r,o,u,c,f){return e(t^r^o,n,t,u,c,f)}function f(n,t,r,o,u,c,f){return e(r^(t|~o),n,t,u,c,f)}function i(n,r){n[r>>5]|=128<<r%32,n[14+(r+64>>>9<<4)]=r;var e,i,a,d,h,l=1732584193,g=-271733879,v=-1732584194,m=271733878;for(e=0;e<n.length;e+=16)i=l,a=g,d=v,h=m,g=f(g=f(g=f(g=f(g=c(g=c(g=c(g=c(g=u(g=u(g=u(g=u(g=o(g=o(g=o(g=o(g,v=o(v,m=o(m,l=o(l,g,v,m,n[e],7,-680876936),g,v,n[e+1],12,-389564586),l,g,n[e+2],17,606105819),m,l,n[e+3],22,-1044525330),v=o(v,m=o(m,l=o(l,g,v,m,n[e+4],7,-176418897),g,v,n[e+5],12,1200080426),l,g,n[e+6],17,-1473231341),m,l,n[e+7],22,-45705983),v=o(v,m=o(m,l=o(l,g,v,m,n[e+8],7,1770035416),g,v,n[e+9],12,-1958414417),l,g,n[e+10],17,-42063),m,l,n[e+11],22,-1990404162),v=o(v,m=o(m,l=o(l,g,v,m,n[e+12],7,1804603682),g,v,n[e+13],12,-40341101),l,g,n[e+14],17,-1502002290),m,l,n[e+15],22,1236535329),v=u(v,m=u(m,l=u(l,g,v,m,n[e+1],5,-165796510),g,v,n[e+6],9,-1069501632),l,g,n[e+11],14,643717713),m,l,n[e],20,-373897302),v=u(v,m=u(m,l=u(l,g,v,m,n[e+5],5,-701558691),g,v,n[e+10],9,38016083),l,g,n[e+15],14,-660478335),m,l,n[e+4],20,-405537848),v=u(v,m=u(m,l=u(l,g,v,m,n[e+9],5,568446438),g,v,n[e+14],9,-1019803690),l,g,n[e+3],14,-187363961),m,l,n[e+8],20,1163531501),v=u(v,m=u(m,l=u(l,g,v,m,n[e+13],5,-1444681467),g,v,n[e+2],9,-51403784),l,g,n[e+7],14,1735328473),m,l,n[e+12],20,-1926607734),v=c(v,m=c(m,l=c(l,g,v,m,n[e+5],4,-378558),g,v,n[e+8],11,-2022574463),l,g,n[e+11],16,1839030562),m,l,n[e+14],23,-35309556),v=c(v,m=c(m,l=c(l,g,v,m,n[e+1],4,-1530992060),g,v,n[e+4],11,1272893353),l,g,n[e+7],16,-155497632),m,l,n[e+10],23,-1094730640),v=c(v,m=c(m,l=c(l,g,v,m,n[e+13],4,681279174),g,v,n[e],11,-358537222),l,g,n[e+3],16,-722521979),m,l,n[e+6],23,76029189),v=c(v,m=c(m,l=c(l,g,v,m,n[e+9],4,-640364487),g,v,n[e+12],11,-421815835),l,g,n[e+15],16,530742520),m,l,n[e+2],23,-995338651),v=f(v,m=f(m,l=f(l,g,v,m,n[e],6,-198630844),g,v,n[e+7],10,1126891415),l,g,n[e+14],15,-1416354905),m,l,n[e+5],21,-57434055),v=f(v,m=f(m,l=f(l,g,v,m,n[e+12],6,1700485571),g,v,n[e+3],10,-1894986606),l,g,n[e+10],15,-1051523),m,l,n[e+1],21,-2054922799),v=f(v,m=f(m,l=f(l,g,v,m,n[e+8],6,1873313359),g,v,n[e+15],10,-30611744),l,g,n[e+6],15,-1560198380),m,l,n[e+13],21,1309151649),v=f(v,m=f(m,l=f(l,g,v,m,n[e+4],
7616,-145523070),g,v,n[e+11],10,-1120210379),l,g,n[e+2],15,718787259),m,l,n[e+9],21,-343485551),l=t(l,i),g=t(g,a),v=t(v,d),m=t(m,h);return[l,g,v,m]}function a(n){var t,r="",e=32*n.length;for(t=0;t<e;t+=8)r+=String.fromCharCode(n[t>>5]>>>t%32&255);return r}function d(n){var t,r=[];for(r[(n.length>>2)-1]=void 0,t=0;t<r.length;t+=1)r[t]=0;var e=8*n.length;for(t=0;t<e;t+=8)r[t>>5]|=(255&n.charCodeAt(t/8))<<t%32;return r}function h(n){return a(i(d(n),8*n.length))}function l(n,t){var r,e,o=d(n),u=[],c=[];for(u[15]=c[15]=void 0,o.length>16&&(o=i(o,8*n.length)),r=0;r<16;r+=1)u[r]=909522486^o[r],c[r]=1549556828^o[r];return e=i(u.concat(d(t)),512+8*t.length),a(i(c.concat(e),640))}function g(n){var t,r,e="";for(r=0;r<n.length;r+=1)t=n.charCodeAt(r),e+="0123456789abcdef".charAt(t>>>4&15)+"0123456789abcdef".charAt(15&t);return e}function v(n){return unescape(encodeURIComponent(n))}function m(n){return h(v(n))}function p(n){return g(m(n))}function s(n,t){return l(v(n),v(t))}function C(n,t){return g(s(n,t))}function A(n,t,r){return t?r?s(t,n):C(t,n):r?m(n):p(n)}"function"==typeof define&&define.amd?define(function(){return A}):"object"==typeof module&&module.exports?module.exports=A:n.md5=A}(this); 762 763/* 764 * videoPlayer 765 */ 766(function(api, $, window, document){ 767 "use strict"; 768 769 var defaults = { 770 enabled: true, /* if render videoPlayer */ 771 debug: false, /* 1: debug in console.log 2: debug on screen */ 772 selector: ".videoPlayer", /* default selector to render video */ 773 volume: 5, /* default volume value in 0-10 range */ 774 storage: { 775 enabled: true, /* if store values in localStorage */ 776 key: "videoPlayer_" /* localStorage key suffix */ 777 }, 778 proportion: "16:9", /* default 16:9 - accept String format like example: "4:3" */ 779 html: "", /* contains all html markup - setting later */ 780 ads: null, /* url to json file with ads */ 781 vast: null, /* url to vast file with ads */ 782 duration: null, /* fallback video duration for vast */ 783 gemius: { 784 debug: true, /* if debug gemius in console.log */ 785 stream: false, /* object for gemius stream */ 786 prism: false, /* object for gemius prism */ 787 player: false, /* object for gemius player */ 788 }, 789 recommended: [], /* array of recommended videos */ 790 recommendedCountdown: 10, /* seconds to next video */ 791 positionMemory: false, /* position memory (true/false) */ 792 positionMemoryLimit: 10, /* position memory array limit */ 793 diagnose: null, /* function to call when Diagnose button click */ 794 diagnoseButton: "Wyślij raport techniczny...", 795 errorMsg: "Przepraszamy, wystąpił problem z materiałem wideo.", 796 errorMsgTimeout: "Materiał nie mógł załadować się w określonym czasie. Sprawdź swoje połączenie internetowe.", 797 onInit: null, /* callback on init > function(videoPlayer, API){ videoPlayer - instance of object, API - functions to call } */ 798 onEnded: null, /* callback on ended > function(videoPlayer){ videoPlayer - instance of object } */ 799 onPlay: null, /* callback on play > function(videoPlayer){ videoPlayer - instance of object } */ 800 onPause: null, /* callback on pause > function(videoPlayer){ videoPlayer - instance of object } */ 801 onError: function(video){ /* callback on error > function(videoPlayer){ videoPlayer - instance of object } */ 802 var txt = video.mask.find('._'), 803 msg = txt[0].innerHTML, 804 geoISO = ["PL"], 805 msgGeo = "Przepraszamy, wideo nie jest dostępne na terenie Twojego kraju.", 806 errorGeo = null, 807 ip = null, 808 log = function(){ 809 if(!canPlayAny || errorGeo) { 810 var button; 811 if((button = video.mask.find('.' + config.classes.button.diagnose)).length) { 812 button.remove(); 813 video.skipDiagnose = true; 814 } 815 } 816 txt.html(msg); 817 video.errorGeo = errorGeo; 818 video.errorIp = ip; 819 }; 820 821 var srcs = video.videoEl.container.find(video.videoEl.media).find('source'), 822 canPlayAny = false, 823 msgCanPlay = "Twoja przeglądarka nie obsługuje odtwarzacza&
823nbsp;materiałów wideo."; 824 for(var i = 0, source; source = srcs[i++]; ) { 825 var src = source.getAttribute('src'), 826 type = source.getAttribute('type') || 'video/' + src.split('.').pop(), 827 canPlay = video.videoEl.media.canPlayType(type); 828 829 if(canPlay.replace(/no/, '') != "") { 830 canPlayAny = true; 831 } 832 } 833 834 if(!canPlayAny) { 835 msg = msgCanPlay; 836 return log(); 837 } 838 839 txt[0].innerHTML = ''; 840 841 DOM.xhr({ 842 url: video.videoEl.media.currentSrc, 843 method: 'HEAD', 844 oncomplete: function(xhr) { 845 if(xhr.status == 403) { 846 msg = msgGeo; 847 errorGeo = true; 848 } 849 850 log(); 851 } 852 }); 853 854 } 855 }, 856 config = { 857 classes: { 858 container: "videoPlayer", 859 videoEl: { 860 container: "videoPlayer__video", 861 media: "videoPlayer__video--media", 862 ads: "videoPlayer__video--ads" 863 }, 864 mask: "videoPlayer__mask", 865 adblock: { 866 container: "videoPlayer__adblock", 867 subclasses: { 868 "polsatsport.pl": "videoPlayer__adblock--lightblue", 869 "polsatnews.pl": "videoPlayer__adblock--orange", 870 "geekweek.pl": "videoPlayer__adblock--geekweek", 871 "poszkole.pl": "videoPlayer__adblock--poszkole", 872 default: "videoPlayer__adblock--lightblue", 873 }, 874 container_640px:"videoPlayer__adblock--640px", 875 container_480px:"videoPlayer__adblock--480px", 876 container_mob_320px:"videoPlayer__adblock--mob-320px", 877 container_mob: "videoPlayer__adblock--mob", 878 inner: "videoPlayer__adblock-inner", 879 inner2: "videoPlayer__adblock-inner2", 880 header: "videoPlayer__adblock-header", 881 info: "videoPlayer__adblock-info", 882 color: "videoPlayer__adblock-info-color", 883 button: "videoPlayer__adblock-button", 884 arrow: "videoPlayer__adblock-arrow", 885 info2: "videoPlayer__adblock-info--info2", 886 }, 887 adsUrl: "videoPlayer__adsUrl", 888 controls: "videoPlayer__controls", 889 state: { 890 firstPlay: "firstPlay", 891 playing: "playing", 892 stopped: "stopped", 893 ended: "ended", 894 muted: "muted", 895 fullscreen: "fullscreen", 896 loading: "loading", 897 loadingMetadata: "loading--metadata", 898 buffered: "buffered", 899 hideControls: "hideControls", 900 vast: "is--vast" 901 }, 902 button: { 903 container: "videoPlayer__buttons", 904 all: "videoPlayer__button", 905 play: "videoPlayer__button--play", 906 pause: "videoPlayer__button--pause", 907 mute: "videoPlayer__button--mute", 908 unmute: "videoPlayer__button--unmute", 909 iconPlay: "videoPlayer__button--iconPlay", 910 iconVolume: "videoPlayer__button--iconVolume", 911 iconSettings: "videoPlayer__button--iconSettings", 912 enterFullscreen: "videoPlayer__button--enterFullscreen", 913 exitFullscreen: "videoPlayer__button--exitFullscreen", 914 iconFullscreen: "videoPlayer__button--iconFullscreen", 915 restore: "videoPlayer__button--restore", 916 diagnose: "videoPlayer__button--diagnose", 917 }, 918 label: { 919 all: "videoPlayer__label", 920 span: "videoPlayer__label--span", 921 duration: "videoPlayer__label--duration", 922 total: "videoPlayer__label--total" 923 }, 924 progress: { 925 container: "videoPlayer__progress", 926 wrap: "videoPlayer__progressWrap", 927 all: "videoPlayer__progress--all", 928 seek: "videoPlayer__progress--seek", 929 buffer: "videoPlayer__progress--buffer", 930 bufferBg: "videoPlayer__progress--bufferBg", 931 played: "videoPlayer__progress--played", 932 volume: "videoPlayer__progress--volume", 933 ads: "videoPlayer__progress--ads" 934 }, 935 more: { 936 container: "videoPlayer__more", 937 volume: { 938 container: "videoPlayer__volume", 939 wrap: "videoPlayer__volumeWrap", 940 seek: "videoPlayer__volume--seek" 941 }, 942 settings: { 943 container: "videoPlayer__settings", 944 items: "videoPlayer__settings-items", 945 item: "videoPlayer__settings-item", 946 }, 947 fullscreen: { 948 container: "videoPlayer__fullscreen" 949 } 950 }, 951 recommended: { 952 container: "videoPlayer__recommended", 953 list: "videoPlayer__recommended-list", 954 item: "videoPlayer__recommended-item", 955 title: "videoPlayer__recommended-title", 956 img: "videoPlayer__recommended-img", 957 progress: "videoPlayer__recommended-progress", 958 svg: "videoPlayer__recommended-svg", 959 counter: "videoPlayer__recommended-counter", 960 seconds: "videoPlayer__recommended-seconds", 961 cancel: "videoPlayer__recommended-cancel" 962 }, 963 placeholder: "videoPlayer__placeholder", 964 vast: { 965 container: "videoPlayer__vast" 966 } 967 } 968 }; 969 970 defaults.html = (function(){ 971 return [ 972 '<div class="' + config.classes.mask + '"><span class="_"></span></div>', 973 '{recommended}', 974 '<div class="' + config.classes.controls + '">', 975 '<div class="' + config.classes.button.container + '">', 976 '<button class="' + config.classes.button.all + ' ' + config.classes.button.play + '"><span class="sr-only">Odtwórz</span></button>', 977 '<button class="' + config.classes.button.all + ' ' + config.classes.button.pause + '"><span class="sr-only">Wstrzymaj</span></button>', 978 '<div class="' + config.classes.button.all + ' ' + config.classes.button.iconPlay + '"><span class="_ _1"></span><span class="_ _2"></span><span class="_ _3"></span></div>', 979 '</div>', 980 '<div class="' + config.classes.progress.container + '">', 981 '<div class="' + config.classes.label.all + ' ' + config.classes.label.duration + '"><span class="sr-only">Aktualny czas</span><span class="' + config.classes.label.span + '">00:00</span></div>', 982 '<div class="' + config.classes.progress.wrap + '">', 983 '<label for="seek{id}" class="sr-only">Przewiń</label>', 984 '<input id="seek{id}" class="' + config.classes.progress.all + ' ' + config.classes.progress.seek + '" type="range" min="0" max="100" step="0.5" value="
9840">', 985 '<progress class="' + config.classes.progress.all + ' ' + config.classes.progress.played + '" max="100" value="0">', 986 '<div class="sr-only"><span>0</span>% odtworzone</div>', 987 '</progress>', 988 '<div class="' + config.classes.progress.all + ' ' + config.classes.progress.ads + '"></div>', 989 '<progress class="' + config.classes.progress.all + ' ' + config.classes.progress.buffer + '" max="100" value="0">', 990 '<div class="sr-only"><span>0</span>% załadowane</div>', 991 '</progress>', 992 '<div class="' + config.classes.progress.all + ' ' + config.classes.progress.bufferBg + '"></div>', 993 '</div>', 994 '<div class="' + config.classes.label.all + ' ' + config.classes.label.total + '"><span class="sr-only">Długość materiału</span><span class="' + config.classes.label.span + '">00:00</span></div>', 995 '</div>', 996 '<div class="' + config.classes.more.container + '">', 997 '<div class="' + config.classes.more.volume.container + '">', 998 '<input class="sr-only" id="mute{id}" type="checkbox">', 999 '<label for="mute{id}" class="' + config.classes.button.all + ' ' + config.classes.button.mute + '">', 1000 '<span class="sr-only">Wycisz</span>', 1001 '</label>', 1002 '<label for="mute{id}" class="' + config.classes.button.all + ' ' + config.classes.button.unmute + '">', 1003 '<span class="sr-only">Przywróć głośność</span>', 1004 '</label>', 1005 '<div class="' + config.classes.button.all + ' ' + config.classes.button.iconVolume + '"><span class="_ _1"></span><span class="_ _2"></span></div>', 1006 '<div class="' + config.classes.more.volume.wrap + '">', 1007 '<label for="volume{id}" class="sr-only">Głośność</label>', 1008 '<input id="volume{id}" class="' + config.classes.progress.all + ' ' + config.classes.more.volume.seek + '" type="range" min="0" max="10" step="0.5" value="' + defaults.volume + '">', 1009 '<progress class="' + config.classes.progress.all + ' ' + config.classes.progress.volume + '" max="100" value="0">', 1010 '<div class="sr-only"><span>0</span>% głośności</div>', 1011 '</progress>', 1012 '</div>', 1013 '</div>', 1014 '{settings}', 1015 '<div class="' + config.classes.more.fullscreen.container + '">', 1016 '<button class="' + config.classes.button.all + ' ' + config.classes.button.exitFullscreen + '"><span class="sr-only">Opuść tryb pełnoekranowy</span></button>', 1017 '<button class="' + config.classes.button.all + ' ' + config.classes.button.enterFullscreen + '"><span class="sr-only">Tryb pełnoekranowy</span></button>', 1018 '<div class="' + config.classes.button.all + ' ' + config.classes.button.iconFullscreen + '"></div>', 1019 '</div>', 1020 '</div>', 1021 '<a class="' + config.classes.adsUrl + '" target="_blank"></a>', 1022 '</div>' 1023 ].join("\n"); 1024 })(); 1025 1026 /* 1027 * Animate 1028 */ 1029 function Animate(options) { 1030 var self = this, 1031 defaults = { 1032 duration: 500, 1033 from: 0, 1034 to: 1, 1035 easing: Animate.easing.linear, 1036 onPlay: null, 1037 onPause: null, 1038 onUpdate: null, 1039 onStop: null 1040 }; 1041 1042 self.config = $.extend(defaults, options); 1043 self._pause = null; 1044 1045 self.play = function() { 1046 self._start = Date.now() - self._pause; 1047 _call('onPlay', self._step); 1048 _update(); 1049 } 1050 1051 self.pause = function() { 1052 cancelAnimationFrame(self._raf); 1053 self._pause = Date.now() - self._start; 1054 _call('onPause', self._step); 1055 } 1056 1057 self.stop = function() { 1058 cancelAnimationFrame(self._raf); 1059 _call('onStop'); 1060 self._start = self._step = self._current = self._pause = null; 1061 } 1062 1063 function _update() { 1064 self._current = Date.now() - self._start; 1065 if(self._current < self.config.duration){ 1066 self._raf = requestAnimationFrame(_update); 1067 self._step = self.config.easing(self._current, self.config.from, -self.config.from + self.config.to, self.config.duration); 1068 } 1069 else{ 1070 self._step = self.config.to; 1071 requestAnimationFrame(self.stop); 1072 } 1073 1074 _call('onUpdate', self._step); 1075 } 1076 1077 function _call(fn, step) { 1078 if(typeof self.config[fn] === "function") 1079 self.config[fn].call(null, self, step); 1080 } 1081 1082 return self; 1083 } 1084 1085 Animate.easing = { 1086 linear: function(t, b, c, d) { 1087 return c * t / d + b; 1088 }, 1089 easeOutCubic: function(t, b, c, d) { 1090 return c * (Math.pow(t / d - 1, 3) + 1) + b; 1091 }, 1092 easeInOutCubic: function(t, b, c, d) { 1093 if ((t /= d / 2) < 1) { 1094 return c / 2 * Math.pow(t, 3) + b; 1095 } 1096 return c / 2 * (Math.pow(t - 2, 3) + 2) + b; 1097 } 1098 } 1099 1100 Animate.calculate = function(from, to, step) { 1101 return from + (to - from) * step; 1102 } 1103 1104 var ua = navigator.userAgent.toLowerCase(); 1105 var an = navigator.appName.toLowerCase(); 1106 var isIEMobile = ua.indexOf("iemobile") > -1; 1107 var isAndroid = ua.indexOf("android") > -1 && !isIEMobile; 1108 var isOldAndroid = (isAndroid && parseFloat(ua.slice(ua.indexOf("android") + 8)) < 3); 1109 var isiPad = ua.indexOf("ipad") > -1; 1110 var isiPhone = ua.indexOf("iphone") > -1 && !isIEMobile; 1111 var iOS = isiPad || isiPhone; 1112 var iOSVersion = parseFloat((ua.match(/\b[0-9]+_[0-9]+(?:_[0-9]+)?\b/) || ['0'])[0].replace(/_/g, '.')); 1113 var isIE = ((an == "microsoft internet explorer") || ((an == "netscape") && (new RegExp("trident/.*rv:([0-9]{1,}[\.0-9]{0,})").exec(ua) != null))); 1114 var isOpera = !!window.opera; 1115 1116 function hash(str) { 1117 var hash = 0, i, chr, l = str.length; 1118 if(l === 0) return hash; 1119 for(i = 0; i < l; i++) { 1120 chr = str.charCodeAt(i); 1121 hash = ((hash << 5) - hash) + chr; 1122 hash |= 0; // Convert to 32bit integer 1123 } 1124 return hash; 1125 } 1126 1127 function _hit(url){ 1128 if(!url) return; 1129 new Image().src = url + '#' + Date.now(); 1130 } 1131 1132 function _getPercentage(current, max){ 1133 if(current === 0 || max === 0 || isNaN(current) || isNaN(max)){ 1134 return 0; 1135 } 1136 return ((current / max) * 100).toFixed(2); 1137 } 1138 1139 function _isFullscreen(){ 1140 return (document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement); 1141 } 1142 function _requestFullscreen(element){ 1143 1144 if(element.requestFullscreen){ 1145 element.requestFullscreen(); 1146 } 1147 else if(element.msRequestFullscreen){ 1148 element.msRequestFullscreen(); 1149 } 1150 else if(element.mozRequestFullScreen){ 1151 element.mozRequestFullScreen(); 1152 } 1153 else if(element.webkitRequestFullscreen){ 1154 element.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); 1155 } 1156 1157 } 1158 function _cancelFullscreen(){ 1159 1160 if(document.exitFullscreen){ 1161 document.exitFullscreen(); 1162 } 1163 else if(document.msExitFullscreen){ 1164 document.msExitFullscreen(); 1165 } 1166 else if(document.mozCancelFullScreen){ 1167 document.mozCancelFullScreen(); 1168 } 1169 else if(document.webkitExitFullscreen){ 1170 document.webkitExitFullscreen(); 1171 } 1172 1173 } 1174 1175 function _canPlay(type){ 1176 var v = document.createElement('video'); 1177 return v.canPlayType('video/' + type).replace(/no/, '') != "" ? true : false; 1178 } 1179 1180 function VideoPlayer(container){ 1181 1182 var video = this; 1183 var cfg = $.extend({}, config); 1184 1185 video.container = container; 1186 1187 video.logs = []; 1188 var debugEl = false; 1189 function _log(text, state){ 1190 if(cfg.debug){ 1191 1192 if(cfg.debug == 2){
1193 if(!debugEl){ 1194 $(video.container).append('<div class="videoPlayer__debug"><div class="videoPlayer__debug--wrap"><div class="videoPlayer__debug--cont"></div></div></div>'); 1195 debugEl = $(video.container).find('.videoPlayer__debug--cont'); 1196 } 1197 1198 var log = _logStringify(text); 1199 1200 debugEl.append('<p class="log' + (state ? (' log--' + state) : '') + '">' + log.join(', ') + '</p>'); 1201 debugEl.parent()[0].scrollTop = 1000000000; 1202 } 1203 else console[(state ? state : "log")](text); 1204 1205 } 1206 1207 var log = {}; 1208 log[state || "log"] = _logStringify(text); 1209 video.logs.push(log); 1210 } 1211 function _logStringify(text) { 1212 var log = [text]; 1213 if(typeof text === "object"){ 1214 log = []; 1215 for(var i in text) { 1216 if( 1217 typeof text[i] !== "object" 1218 ) { 1219 log.push(text[i]); 1220 } 1221 } 1222 } 1223 return log; 1224 } 1225 1226 function _prismDur(dur){ 1227 var i = (dur / 60); 1228 if(i < 5){ return '0-5'; } 1229 else if(i < 10){ return '5-10'; } 1230 else if(i < 15){ return '10-15'; } 1231 else{ return '15'; } 1232 } 1233 1234 var cfgStats = cfg.stats || cfg.gemius; 1235 1236 var _stats = { 1237 stream: function(action, time){ 1238 1239 if(window["gemiusStream"] && typeof cfgStats.stream == "object" && !video.isError){ 1240 1241 if(!cfgStats.stream.id || !cfgStats.stream.materialId){ 1242 _log("ERROR: Bad stream configuration (missing id or materialId)", 'error'); 1243 return; 1244 } 1245 1246 if(action == 'newStream'){ 1247 video.isNewStream = true; 1248 1249 cfgStats.stream.materialId = cfgStats.stream.materialId.replace(new RegExp(/[|*\n\t\r;=\/#]/g), " "); 1250 1251 _log("Stream: " + action, 'info'); 1252 1253 window["gemiusStream"].newStream(video.uniq, cfgStats.stream.materialId, Math.ceil(video.videoEl.media.duration), cfgStats.stream.customPackage || [], cfgStats.stream.additionalPackage || [], cfgStats.stream.id, cfgStats.stream.hit, cfgStats.stream.treeId); 1254 1255 if(video.streamEventBuffer && video.streamEventBuffer.length){ 1256 for(var i = 0, l = video.streamEventBuffer.length; i < l; i++){ 1257 _stats.stream(video.streamEventBuffer[i][0], video.streamEventBuffer[i][1]); 1258 } 1259 video.streamEventBuffer = []; 1260 } 1261 } 1262 else if(!video.isNewStream){ 1263 if(!video.streamEventBuffer) video.streamEventBuffer = []; 1264 video.streamEventBuffer.push([action, video.videoEl.media.currentTime]); 1265 1266 _log("Stream: " + action + " --buffered"); 1267 } 1268 else{ 1269 _log("Stream: " + action, 'info'); 1270 1271 window["gemiusStream"].event(video.uniq, cfgStats.stream.materialId, Math.ceil(time || video.videoEl.media.currentTime), action); 1272 } 1273 1274 } 1275 1276 }, 1277 prism: function(action, totalAd, currentAd){ 1278 1279 if(window["gemius_event"] && typeof cfgStats.prism == "object" && !video.isError){ 1280 1281 if(!cfgStats.prism.id || !cfgStats.prism.title){ 1282 _log("ERROR: Bad prism configuration (missing id or title)", 'error'); 1283 return; 1284 } 1285 if(action.indexOf("AdBlock") !== -1 ){ 1286 (function(cb){ 1287 if(isNaN(video.videoEl.media.duration)){ 1288 video.videoEl.media.addEventListener('durationchange', cb) 1289 }else { 1290 cb(); 1291 } 1292 })(function(){ 1293 cfgStats.prism.duration = _prismDur(video.videoEl.media.duration); 1294 var ladb = video.supported.storage 1295 ? (window.localStorage.getItem(cfg.storage.key+'ladb')==1) 1296 ? 'Tak' 1297 : (window.localStorage.getItem(cfg.storage.key+'ladb')==0) 1298 ? 'Nie' 1299 : '' 1300 : ''; 1301 window["gemius_event"]('_action_', cfgStats.prism.id, 'g=' + action, 'GoalName=Odtwarzanie/' + action, 'm=' + cfgStats.prism.title, 'l=' + cfgStats.prism.duration, 'ladb='+ladb, 'adf=true'); 1302 video.supported.storage && window.localStorage.setItem(cfg.storage.key+'ladb', action.indexOf('Tak')!==-1?1:0); 1303 }); 1304 _log("Prism: " + action); 1305 } 1306 else if(action == 'Nowy_Materiał'){ 1307 video.isNowyMaterial = true; 1308 1309 cfgStats.prism.title = cfgStats.prism.title.replace(new RegExp(/[ =&\+]/g), "_"); 1310 cfgStats.prism.duration = _prismDur(video.videoEl.media.duration); 1311
1312 _log("Prism: " + action, 'info'); 1313 1314 window["gemius_event"]('_action_', cfgStats.prism.id, 'g=' + action, 'GoalName=Odtwarzanie/' + action, 'm=' + cfgStats.prism.title, 'l=' + cfgStats.prism.duration); 1315 1316 if(video.prismEventBuffer && video.prismEventBuffer.length){ 1317 for(var i = 0, l = video.prismEventBuffer.length; i < l; i++){ 1318 _stats.prism(video.prismEventBuffer[i][0], video.prismEventBuffer[i][1], video.prismEventBuffer[i][2]); 1319 } 1320 video.prismEventBuffer = []; 1321 } 1322 } 1323 else if(!video.isNowyMaterial){ 1324 if(!video.prismEventBuffer) video.prismEventBuffer = []; 1325 video.prismEventBuffer.push([action, video.totalAdInBlock, video.currentAdInBlock]); 1326 1327 _log("Prism: " + action + " --buffered"); 1328 } 1329 else{ 1330 1331 _log("Prism: " + action + (video.isAds || totalAd ? (" :: ad [" + (currentAd || video.currentAdInBlock) + "/" + (totalAd || video.totalAdInBlock) + "]") : ""), 'info'); 1332 1333 if(!video.isAds && !totalAd) window["gemius_event"]('_action_', cfgStats.prism.id, 'g=' + action, 'GoalName=Odtwarzanie/' + action, 'm=' + cfgStats.prism.title, 'l=' + cfgStats.prism.duration); 1334 else window["gemius_event"]('_action_', cfgStats.prism.id, 'g=' + action, 'GoalName=Odtwarzanie/' + action, 'm=' + cfgStats.prism.title, 'l=' + cfgStats.prism.duration, 'an=' + (totalAd || video.totalAdInBlock), 'ap=' + (currentAd || video.currentAdInBlock)); 1335 1336 } 1337 1338 } 1339 }, 1340 player: function(action, ad, offset){ 1341 1342 if(window["GemiusPlayer"] && typeof cfgStats.player == "object" && !video.isError){ 1343 1344 if(!cfgStats.player.accountID || !cfgStats.player.programID){ 1345 _log("ERROR: Bad gplayer configuration (missing accountID or programID)", 'error'); 1346 return; 1347 } 1348 1349 if(action == 'newProgram'){ 1350 video.GPlayerInstance = new GemiusPlayer(video.uniq, cfgStats.player.accountID, {}); 1351 video.GPlayerInstance.setVideoObject(video.videoEl.media); 1352 cfgStats.player.additionalParameters.programDuration = video.videoEl.media.duration; 1353 cfgStats.player.additionalParameters.programName = cfgStats.player.additionalParameters.programName.replace(new RegExp(/[\n\t\r{}[\]()"'~`!@#$%^&*?;,:\/|=]/g), "").substr(0, 200); 1354 video.GPlayerInstance.newProgram(cfgStats.player.programID, cfgStats.player.additionalParameters); 1355 1356 _log("GPlayer: " + action, 'info'); 1357 1358 if(video.gPlayerEventBuffer && video.gPlayerEventBuffer.length){ 1359 for(var i = 0, l = video.gPlayerEventBuffer.length; i < l; i++){ 1360 _stats.player(video.gPlayerEventBuffer[i][0], video.gPlayerEventBuffer[i][1], video.gPlayerEventBuffer[i][2]); 1361 } 1362 video.gPlayerEventBuffer = []; 1363 } 1364 } 1365 else if(!video.GPlayerInstance){ 1366 if(!video.gPlayerEventBuffer) video.gPlayerEventBuffer = []; 1367 video.gPlayerEventBuffer.push([action, video.isAds && {id: video.adsID, duration: video.videoEl.ads.duration}, video.videoEl.media.currentTime]); 1368 1369 _log("GPlayer: " + action + " --buffered"); 1370 } 1371 else{ 1372 1373 var logEvent = ""; 1374 1375 if(action == "newAd"){ 1376 video.GPlayerInstance.newAd(ad && ad.id || video.adsID, { 1377 adDuration: ad && ad.duration || video.videoEl.ads.duration, 1378 BRN: cfgStats.player.additionalParameters.BRN || '' 1379 }); 1380 } 1381 else if(ad || video.isAds){ 1382 logEvent = "adEvent."; 1383 video.GPlayerInstance.adEvent(cfgStats.player.programID, ad && ad.id || video.adsID, offset || video.videoEl.media.currentTime, action); 1384 } 1385 else{ 1386 logEvent = "programEvent."; 1387 var additional = {}; 1388 if(action == "play"){ 1389 additional = { 1390 autoPlay: !video.gpPlay && video.init.autoplay, 1391 partID: 1 1392 }; 1393 video.gpPlay = true; 1394 } 1395 video.GPlayerInstance.programEvent(cfgStats.player.programID, offset || video.videoEl.media.currentTime, action, additional); 1396 } 1397 1398 _log("GPlayer: " + logEvent + action, 'info'); 1399 1400 } 1401 1402 } 1403 1404 }, 1405 redevents: function(action) { 1406 1407 if(typeof cfgStats.redevents == "object") { 1408 1409 var actions = this.redevents.actions || (this.redevents.actions = {
1410 'try': 't', // first play 1411 'begin preRoll': 'bp', 1412 'begin': 'b', 1413 'cycle': 'c', // interval event 1414 'change quality': 'cq', // `qt` parameter 1415 'begin midRoll': 'bm', 1416 'end midRoll': 'em', 1417 'seek': 'sk', 1418 'pause': 'p', 1419 'stop': 's', 1420 'end': 'e', 1421 'begin postRoll': 'br', 1422 'end postRoll': 'er', 1423 'error_adv': 'ea', 1424 'error_vod': 'ev' 1425 }); 1426 1427 var time = _getRedEventsTime(), 1428 sc = Math.floor(((video.videoEl.media.currentTime || 0) / (video.redeventsVl || video.videoEl.media.duration || cfg.duration || 0)) * 100), 1429 uid, pl, cid, ct, vl; 1430 1431 var defaults = this.redevents.defaults || ( 1432 uid = uuidv4(), 1433 pl = 'WWW', 1434 cid = cfgStats.redevents.hash, 1435 ct = 1 + '', 1436 video.redeventsVl = vl = Math.round(video.videoEl.media.duration || cfg.duration), 1437 this.redevents.defaults = { 1438 pr: cfgStats.redevents.portal, 1439 uid: uid, 1440 ct: ct, 1441 cid: cid, 1442 sh: 0, 1443 dc: 'PC', 1444 pl: pl, 1445 cl: api.version + '', 1446 ss: 2, 1447 ua: 'www_' + cfgStats.redevents.portal + '_html5', 1448 sid: md5(uid + pl + time + cid + ct), 1449 vl: vl 1450 } 1451 ); 1452 1453 if(!video.redeventsTry) { 1454 video.redeventsTry = true; 1455 video.redeventsDuration = new RedeventsDuration(); 1456 1457 _stats.redevents('try'); 1458 } 1459 1460 var params = $.extend(defaults, { 1461 et: actions[action], 1462 sc: sc, 1463 dr: video.redeventsDrStore || Math.floor(video.redeventsDuration.get() / 1000), 1464 tm: time, 1465 qt: video.quality || '480p' 1466 }); 1467 1468 if(action === 'try') { 1469 params.sc = params.dr = video.redeventsDrStore = null; 1470 } else if(action === 'begin') { 1471 video.redeventsDuration.play(); 1472 1473 $(window).on('beforeunload.redevents', function(){ 1474 _stats.redevents('stop'); 1475 }); 1476 $(video.videoEl.media).on('play.rd playing.rd pause.rd waiting.rd', function(e) { 1477 var playing = (e.type.indexOf('play') === 0); 1478 video.redeventsDuration[playing ? 'play' : 'pause'](); 1479 }); 1480 } else if(action === 'end') { 1481 video.redeventsDrStore = params.dr; 1482 video.redeventsDuration.reset(); 1483 $(window).off('beforeunload.redevents'); 1484 $(video.videoEl.media).off('play.rd playing.rd pause.rd waiting.rd'); 1485 } 1486 1487 $.xhr({ 1488 url: cfgStats.redevents.hit, 1489 method: 'POST', 1490 async: action !== 'stop', 1491 data: 'json=' + encodeURIComponent(JSON.stringify(params)) 1492 }); 1493 1494 _log("RedEvents: " + action, 'info'); 1495 1496 } 1497 } 1498 } 1499 1500 function RedeventsDuration() { 1501 this.duration = 0; 1502 this.cycleTime = 0; 1503 this.play = function() { 1504 if(!this.going) { 1505 this.going = true; 1506 this.last = Date.now(); 1507 1508 this.cycle(); 1509 } 1510 }; 1511 this.pause = function() { 1512 if(this.going) { 1513 this.going = false; 1514 this.duration = this.get(); 1515 this.cycleTime = (this.lastCycle ? Date.now() - this.lastCycle : 0); 1516 this.last = null; 1517 1518 clearTimeout(video.redeventsInterval); 1519 } 1520 }; 1521 this.reset = function() { 1522 clearTimeout(video.redeventsInterval); 1523 this.duration = 0; 1524 this.going = this.last = null; 1525 }; 1526 this.get = function() { 1527 return this.duration + (this.last ? Date.now() - this.last : 0); 1528 }; 1529 this.cycle = function() { 1530 var self = this; 1531 this.lastCycle = Date.now(); 1532 clearTimeout(video.redeventsInterval); 1533 video.redeventsInterval = setTimeout(function() { 1534 _stats.redevents('cycle'); 1535 1536 self.cycleTime = 0; 1537 self.cycle(); 1538 }, cfgStats.redevents.interval * 1000 - this.cycleTime); 1539 }; 1540 1541 return this; 1542 } 1543 1544 function _padLeft(x, n) { 1545 x = x.toString(); 1546 n = typeof n !== 'undefined' ? n : 2; 1547 while(x.length < n) { 1548 x = '0' + x; 1549 } 1550 return x; 1551 } 1552 function _getRedEventsTime() { 1553 var date = new Date(), 1554 time = ''; 1555 1556 time += date.getFullYear() + '-'; 1557 time += _padLeft(date.getMonth() + 1) + '-'; 1558 time += _padLeft(date.getDate()) + ' '; 1559 time += _padLeft(date.getHours()) + ':'; 1560 time += _padLeft(date.getMinutes()) + ':'; 1561 time += _padLeft(date.getSeconds()) + '.'; 1562 time += _padLeft(date.getMilliseconds(), 3) + '000'; 1563 time += date.getTimezoneOffset() < 0 1564 ? '+' + _padLeft(Math.round(date.getTimezoneOffset() / -60)) 1565 : '-' + _padLeft(Math.round(date.getTimezoneOffset() / 60)) 1566 1567 return time; 1568 } 1569 1570 /* return Object from video.container context */ 1571 function _getElements(selector){ 1572 return $(video.container).find(selector); 1573 } 1574 1575 function _instance(){ 1576 return video; 1577 } 1578 1579 var firstClick = false, 1580 preventLogOnAndroid = false; 1581 1582 function _play(){ 1583
1584 if(!video.loadedmetadata) return; 1585 1586 for(var i = 0, vp; vp = videoPlayer.els[i++]; ) { 1587 var instance; 1588 if(!vp.isPaused() && video !== (instance = vp.instance())) { 1589 var w = $(window), scroll = w.off('scroll.pauseactive').one('scroll.pauseactive', function(){ 1590 if(Date.now() - time < 1000) w.scrollTop(scroll); 1591 }).scrollTop(), time = Date.now(); 1592 1593 vp.pause(); 1594 1595 if(window.videoPlayer.persistent && window.videoPlayer.persistent.active === instance) { 1596 window.videoPlayer.persistent.active.container.removeClass('is--persistent'); 1597 window.videoPlayer.persistent.active = null; 1598 } 1599 1600 break; 1601 } 1602 } 1603 1604 /* on Android cannot play without user interaction */ 1605 if(!firstClick && isAndroid) { 1606 if((video.ads && video.ads["0"]) || (video.vast && video.vast.cuePoints.indexOf(0) > -1)) { 1607 firstClick = true; 1608 preventLogOnAndroid = true; 1609 video.videoEl.media.play(); 1610 video.videoEl.media.pause(); 1611 1612 /* skip to next frame */ 1613 setTimeout(function(){ 1614 preventLogOnAndroid = false; 1615 }); 1616 } 1617 } 1618 1619 if(video.vastActive) { 1620 video.vast.resume(); 1621 return; 1622 } 1623 1624 video.media.play(); 1625 1626 if(!video.isAds && !video.isEnded){ 1627 _stats.prism("Start"); 1628 } 1629 1630 if(!video.isPreAdsFirstPlay){ 1631 _stats.player("play"); 1632 } 1633 1634 if(typeof cfg.onPlay == "function"){ 1635 cfg.onPlay(video); 1636 } 1637 1638 setTimeout(function(){ video.buttons.pause.focus(); }, 100); 1639 _log(["Play", true]); 1640 } 1641 1642 function _pause(){ 1643 if(video.vastActive) { 1644 video.vast.pause(); 1645 return; 1646 } 1647 1648 video.media.pause(); 1649 1650 if(!video.isAds){ 1651 _stats.prism("Pauza"); 1652 _stats.redevents("pause"); 1653 } 1654 1655 _stats.player("pause"); 1656 1657 if(typeof cfg.onPause == "function"){ 1658 cfg.onPause(video); 1659 } 1660 1661 setTimeout(function(){ video.buttons.play.focus(); }, 100); 1662 _log(["Play", false]); 1663 } 1664 1665 function _toggle(){ 1666 if(video.isAds){ 1667 return _onClickAds(); 1668 } 1669 video.media.paused ? _play() : _pause(); 1670 } 1671 1672 function _hideControls(){ 1673 1674 function hideControlsFn(event){ 1675 1676 $(video.container).removeClass(cfg.classes.state.hideControls); 1677 clearTimeout(video.timerFullscreen); 1678 video.timerFullscreen = setTimeout(function(){ 1679 1680 $(video.container).addClass(cfg.classes.state.hideControls); 1681 1682 _log(["Fullscreen :: _hideControls", true]); 1683 1684 }, 4000); 1685 1686 } 1687 1688 $(video.container).on('mousemove.' + cfg.classes.state.hideControls, hideControlsFn); 1689 $(video.container).on('touchstart.' + cfg.classes.state.hideControls, hideControlsFn); 1690 1691 hideControlsFn(); 1692 1693 } 1694 function _showControls(){ 1695 1696 clearTimeout(video.timerFullscreen); 1697 $(video.container).off('mousemove.' + cfg.classes.state.hideControls); 1698 $(video.container).off('touchstart.' + cfg.classes.state.hideControls); 1699 $(video.container).removeClass(cfg.classes.state.hideControls); 1700 1701 _log(["Fullscreen :: _showControls", true]); 1702 1703 } 1704 1705 function _enterFullscreen(){ 1706 _requestFullscreen(video.container[0]); 1707 setTimeout(function(){ video.buttons[!video.media.paused ? "pause" : "play"].focus(); }, 100); 1708 1709 _hideControls(); 1710 1711 _log(["Fullscreen", true]); 1712 } 1713 1714 function _exitFullscreen(){ 1715 _cancelFullscreen(); 1716 setTimeout(function(){ video.buttons[!video.media.paused ? "pause" : "play"].focus(); }, 100); 1717 1718 _showControls(); 1719 1720 _log(["Fullscreen", false]); 1721 } 1722 1723 function _toggleFullscreen(){ 1724 _isFullscreen() === video.container[0] ? _exitFullscreen() : _enterFullscreen(); 1725 } 1726 1727 function _seek(input){ 1728 1729 if(video.isAds == true){ 1730 _log(["Seek", false, "ads"]); 1731 return false; 1732 } 1733 1734 var targetTime = 0; 1735 1736 if(typeof input === "string" && input.slice(-1) == "%"){ 1737 targetTime = video.media.duration * parseFloat(input) / 100; 1738 } 1739 else if(typeof input === "number"){ 1740 targetTime = input; 1741 } 1742 else if(typeof input === "object" && (input.type === "change" || input.type === "input")){ 1743 targetTime = ((input.target.value / input.target.max) * video.media.duration); 1744 } 1745 1746 if(targetTime < 0){ 1747 targetTime = 0; 1748 } 1749 else if(targetTime > video.media.duration){ 1750 targetTime = video.media.duration; 1751 } 1752 1753 try{ 1754 video.media.currentTime = targetTime.toFixed(1); 1755 _log(["Seek", video.media.currentTime]); 1756 } 1757 catch(e){} 1758 1759 if(video.seekingStart){ 1760 _stats.stream("seekingStarted"); 1761 _stats.player("seek"); 1762 _stats.prism("Przewijanie"); 1763 } 1764 1765 if(typeof input === "object" && (input.type === "input" || input.type === "change" && isIE)){
1766 if(!video.isInput){ 1767 video.isInput = true; 1768 _stats.stream("seekingStarted"); 1769 _stats.player("seek"); 1770 _stats.prism("Przewijanie"); 1771 } 1772 } 1773 if(typeof input === "object" && input.type === "change"){ 1774 video.isInput = false; 1775 if(!video.videoEl.media.paused){ 1776 _stats.stream("playing"); 1777 _stats.player("play"); 1778 _stats.redevents("seek"); 1779 } 1780 } 1781 1782 } 1783 function _progSeek(value) { 1784 _seek(value); 1785 1786 _stats.stream("seekingStarted"); 1787 _stats.player("seek"); 1788 _stats.prism("Przewijanie"); 1789 1790 if(!video.videoEl.media.paused){ 1791 _stats.stream("playing"); 1792 _stats.player("play"); 1793 _stats.redevents("seek"); 1794 } 1795 } 1796 1797 function _setVolume(volume){ 1798 1799 if(typeof volume === "undefined"){ 1800 if(cfg.storage.enabled && video.supported.storage){ 1801 volume = window.localStorage[cfg.storage.key + 'volume'] || cfg.volume; 1802 } 1803 else{ 1804 volume = cfg.volume; 1805 } 1806 } 1807 else if(typeof volume === "string" && volume.slice(-1) == "%"){ 1808 volume = 10 * parseFloat(volume) / 100; 1809 } 1810 1811 if(volume > 10){ 1812 volume = 10; 1813 } 1814 1815 video.volume.seek[0].value = volume; 1816 var value = _getPercentage(volume, 10); 1817 1818 if(video.supported.range){ 1819 video.progress.volume[0].value = value; 1820 } 1821 else{ 1822 video.progress.volume[0].style.width = value + "%"; 1823 } 1824 video.progress.volumeSpan[0].innerHTML = value; 1825 1826 video.media.volume = parseFloat(volume / 10); 1827 1828 _toggleMute(video.media.volume === 0); 1829 1830 if(video.vast) { 1831 video.vast.setVolumeState(); 1832 } 1833 1834 if(cfg.storage.enabled && video.supported.storage){ 1835 window.localStorage[cfg.storage.key + 'volume'] = volume; 1836 } 1837 1838 _log(["Volume", volume]); 1839 1840 } 1841 1842 function _toggleMute(muted){ 1843 1844 if(typeof muted === "undefined"){ 1845 muted = !video.media.muted; 1846 } 1847 1848 if(video.supported.range){ 1849 video.volume.checkbox[0].checked = muted; 1850 } 1851 1852 video.media.muted = muted; 1853 1854 if(video.vast) { 1855 video.vast.setVolumeState(); 1856 } 1857 1858 _checkMute(); 1859 1860 _log(["Muted", muted]); 1861 1862 } 1863 1864 function _checkPlaying(){ 1865 $(video.container).toggleClass(cfg.classes.state.firstPlay, video.firstPlay); 1866 $(video.container).toggleClass(cfg.classes.state.playing, video.vast && video.isAds ? !video.vast.isPaused() : !video.media.paused); 1867 $(video.container).toggleClass(cfg.classes.state.stopped, video.vast && video.isAds ? video.vast.isPaused() : video.media.paused); 1868 $(video.container).toggleClass(cfg.classes.state.ended, video.isEnded); 1869 } 1870 1871 function _checkMute(){ 1872 $(video.container).toggleClass(cfg.classes.state.muted, (video.media.volume === 0 || video.media.muted)); 1873 } 1874 1875 function _checkFullscreen(){ 1876 var fullscreenElement = _isFullscreen(); 1877 for(var i = 0, el; el = videoPlayer.els[i++]; ){ 1878 var container = el.instance().container; 1879 container.toggleClass(cfg.classes.state.fullscreen, fullscreenElement === container[0]); 1880 } 1881 } 1882 1883 function _checkLoading(event){ 1884 1885 var loading = (event.type === "waiting" && !isIEMobile && video.firstPlay); 1886 1887 _log(["Loading", loading]); 1888 1889 /* setTimeout to prevent setting class too fast */ 1890 clearTimeout(video.loadingTimer); 1891 video.loadingTimer = setTimeout(function(){ 1892 1893 if(!video.isInput){ 1894 if(loading){ 1895 _stats.stream("buffering"); 1896 _stats.player("buffer"); 1897 } 1898 if(video.loading == true && !loading && !video.videoEl.media.paused){ 1899 _stats.stream("playing"); 1900 _stats.player("play"); 1901 } 1902 } 1903 1904 video.loading = loading; 1905 $(video.container).toggleClass(cfg.classes.state.loading, loading); 1906 1907 }, (loading ? 250 : 0)); 1908 1909 /* 1910 * try reload every 10 sec in half a minute 1911 * if that fails, show error msg 1912 */ 1913 clearTimeout(video.loadingTimerReload); 1914 if(video.loadedmetadata && loading) { 1915 video.loadingTimerReload = setTimeout(function() { 1916 video.loadingTimerReloadCounter = video.loadingTimerReloadCounter || 0; 1917 if(video.loadingTimerReloadCounter < 3) { 1918 var media = video.videoEl.media, 1919 playing = !media.paused, 1920 current = media.currentTime; 1921 1922 if(playing) media.pause(); 1923 $(media).off('error.buffer').on('error.buffer', _networkState); 1924 media.load(); 1925 media.currentTime = current; 1926 if(playing) media.play(); 1927 1928 video.loadingTimerReloadCounter++; 1929 } else if(video.videoEl.media.currentTime > 1) { 1930 _showError('timeout'); 1931 } 1932 }, 20000); 1933 } 1934 1935 } 1936 1937 function _getBuffered(buffered, current){ 1938 for(var i = 0, l = buffered.length; i < l; i++){ 1939 if(buffered.start(i) <= current && buffered.end(i) > current) return buffered.end(i); 1940 } 1941 return buffered.end(buffered.length - 1); 1942 } 1943 1944 /* update progress, base on event from listener */ 1945 function _updateProgress(event){ 1946 1947 if(video.vast && video.isAds) return; 1948 1949 var progress = video.progress.played[0], 1950 text = video.progress.playedSpan[0], 1951 value = 0, 1952 ads = video.isAds || false, 1953 current = ads != true ? video.media.currentTime : video.time.ads.currentTime, 1954 duration = ads != true ? video.media.duration : video.time.ads.duration; 1955 1956 if(event){ 1957 switch(event.type){ 1958 case "timeupdate": 1959 case "seeking": 1960 value = _getPercentage(current, duration); 1961 if(event.type == "timeupdate"){ 1962 video.progress.seek[0].value = value; 1963 } 1964
1965 if(!video.prismStart && current != 0){ 1966 video.prismStart = true; 1967 _stats.prism("Start_Materiału_Głównego"); 1968 } 1969 if(!video.prism90 && value >= 90){ 1970 video.prism90 = true; 1971 _stats.prism("90_Procent"); 1972 } 1973 1974 break; 1975 1976 case "change": 1977 case "input": 1978 value = event.target.value; 1979 break; 1980 1981 case "playing": 1982 if(!video.redeventsBegin) { 1983 video.redeventsBegin = true; 1984 _stats.redevents('begin'); 1985 } 1986 case "progress": 1987 progress = video.progress.buffer[0]; 1988 text = video.progress.bufferSpan[0]; 1989 value = (function(){ 1990 var buffered = video.media.buffered; 1991 if(buffered.length){ 1992 return _getPercentage(_getBuffered(buffered, current), video.media.duration); 1993 } 1994 return 0; 1995 })(); 1996 1997 $(video.container).toggleClass(cfg.classes.state.buffered, (value >= 100)); 1998 1999 break; 2000 } 2001 } 2002 2003 if(video.supported.range){ 2004 progress.value = value; 2005 } 2006 else{ 2007 progress.style.width = value + "%"; 2008 } 2009 text.innerHTML = value; 2010 } 2011 2012 /* return time in (0*)00:00 format */ 2013 function _updateTimeDisplay(time){ 2014 time = time || ""; 2015 2016 var ads = video.isAds || false, 2017 getTime = (time || ads != true ? 2018 (time === "dur" ? video.videoEl.media.duration : video.videoEl.media.currentTime) : 2019 (video.time.ads.duration - (video.time.ads.currentTime = video.time.ads.duration - (video.time.ads.currentDuration - video.videoEl.ads.currentTime))) 2020 ); 2021 2022 if(ads){ 2023 time = "ads"; 2024 getTime = Math.max(0, getTime); 2025 } 2026 2027 video.time[time + "secs"] = ~~ (.5 + (getTime % 60)); 2028 video.time[time + "mins"] = ~~ (getTime / 60); 2029 2030 if(video.time[time + "secs"] == 60){ 2031 video.time[time + "secs"] = 0; 2032 video.time[time + "mins"] += 1; 2033 } 2034 2035 video.time[time + "secs"] = (video.time[time + "secs"] < 10 ? "0" : "") + video.time[time + "secs"]; 2036 video.time[time + "mins"] = (video.time[time + "mins"] < 10 ? "0" : "") + video.time[time + "mins"]; 2037 2038 return video.time[time + "mins"] + ":" + video.time[time + "secs"]; 2039 2040 } 2041 2042 function _timeUpdate(event){ 2043 if(video.isAds) return; 2044 video.labels.durationSpan[0].innerHTML = _updateTimeDisplay(); 2045 _updateProgress(event); 2046 } 2047 2048 function _durationUpdate(){ 2049 video.labels.totalSpan[0].innerHTML = _updateTimeDisplay("dur"); 2050 } 2051 2052 var checkingAdsOnTimeUpdate = false; 2053 function _checkAdsOnTimeUpdate(e){ 2054 if(video.adsOnTimeupdate.length && !isNaN(e.target.duration)){ 2055 var offset = video.adsOnTimeupdate[0].offset > 1 ? video.adsOnTimeupdate[0].offset : video.adsOnTimeupdate[0].offset * e.target.duration; 2056 if(e.target.currentTime >= offset){ 2057 checkingAdsOnTimeUpdate = true; 2058 2059 _hit(video.adsOnTimeupdate[0].url); 2060 _log(["_hit :: onTimeupdate", video.adsOnTimeupdate[0].url]); 2061 2062 video.adsOnTimeupdate.shift(); 2063 return _checkAdsOnTimeUpdate(e); 2064 } 2065 } 2066 checkingAdsOnTimeUpdate = false; 2067 } 2068 2069 function _adsTimeUpdate(e){ 2070 video.mask.attr('data-time', _updateTimeDisplay()); 2071 if(!checkingAdsOnTimeUpdate) _checkAdsOnTimeUpdate(e); 2072 } 2073 2074 function _vastUpdateTimeDisplay(time) { 2075 var getTime = Math.max(0, time || 0); 2076 2077 time = "ads"; 2078 video.time[time + "secs"] = ~~ (.5 + (getTime % 60)); 2079 video.time[time + "mins"] = ~~ (getTime / 60); 2080 2081 if(video.time[time + "secs"] == 60){ 2082 video.time[time + "secs"] = 0; 2083 video.time[time + "mins"] += 1; 2084 } 2085 2086 video.time[time + "secs"] = (video.time[time + "secs"] < 10 ? "0" : "") + video.time[time + "secs"]; 2087 video.time[time + "mins"] = (video.time[time + "mins"] < 10 ? "0" : "") + video.time[time + "mins"]; 2088 2089 return video.time[time + "mins"] + ":" + video.time[time + "secs"]; 2090 } 2091 function _vastTimeUpdate(time) { 2092 video.mask.attr('data-time', _vastUpdateTimeDisplay(time)); 2093 } 2094 2095 function _drag(elem, event){ 2096 var e = event || window.event; 2097 2098 var box = elem.getBoundingClientRect(); 2099 2100 var point = { 2101 x: (e.clientX - box.left), 2102 y: (e.clientY - box.top) 2103 } 2104 2105 return Math.max(0, Math.min(100, _getPercentage(point.x, box.width))); 2106 } 2107 2108 function _showError(type){ 2109 _log(["showError", type], "error"); 2110 2111 video.isError = true; 2112
2113 $(video.container).addClass('noControls error'); 2114 $(video.container).removeClass(cfg.classes.state.loading + " " + cfg.classes.state.loadingMetadata); 2115 $(video.media).off("waiting canplay seeked"); 2116 $(video.videoEl.media).off("loadedmetadata.dur"); 2117 $(video.videoEl.media).off("loadedmetadata waiting canplay seeked buffering"); 2118 $(video.mask).off("click"); 2119 $(video.mask).off("dblclick"); 2120 $(video.container).off('touchstart.mobilesafari'); 2121 2122 _pause(); 2123 2124 try { 2125 $(video.adsUrl).remove(); 2126 video.videoEl.ads.pause(); 2127 $(video.videoEl.ads).remove(); 2128 _toggleAds(false); 2129 } catch(e){} 2130 2131 $(video.mask).find('._').html(type === 'timeout' && cfg.errorMsgTimeout || cfg.errorMsg); 2132 2133 if(typeof cfg.diagnose === "function" && type !== 'timeout') { 2134 if(cfg.diagnoseButton) { 2135 var btn = video.mask 2136 .append('<button class="' + cfg.classes.button.all + ' ' + cfg.classes.button.diagnose + '">' + cfg.diagnoseButton + '</button>') 2137 .find('.' + cfg.classes.button.diagnose); 2138 2139 btn.on('click', function(event) { 2140 event.preventDefault(); 2141 btn.addClass('is--loading'); 2142 cfg.diagnose.call(this, video); 2143 }); 2144 } else { 2145 cfg.diagnose.call(null, video); 2146 } 2147 } 2148 2149 if(typeof cfg.onError === "function") { 2150 cfg.onError(video); 2151 } 2152 } 2153 2154 /* checks if video can play > if not then show error log */ 2155 function _networkState(event){ 2156 if(video.videoEl.media.networkState == 0 || (video.videoEl.media.networkState == 3 && (event || isiPad || isAndroid)) || event === "error"){ 2157 _log(["networkState", video.videoEl.media.networkState, (typeof event == "object" ? event.target.src : null)], "error"); 2158 _showError('error'); 2159 } 2160 } 2161 2162 /* 2163 * in Chrome can't seek when source is served by redcdn 2164 * so we fetch the source url 2165 */ 2166 function _fetchURL(callback){ 2167 2168 setTimeout(function(){ 2169 2170 callback = callback || function(){}; 2171 2172 if(window.fetch && video.videoEl.media.currentSrc){ 2173 var url = video.videoEl.media.currentSrc; 2174 window.fetch(url, { 2175 method: 'head' 2176 }).then(function(response){ 2177 2178 video.videoEl.media.src = response.url; 2179 _log(["_fetchURL"]); 2180 callback(); 2181 2182 }).catch(function(e){ 2183 2184 _log(["_fetchURL :: error", url, e], "error"); 2185 callback(); 2186 2187 }); 2188 2189 } 2190 else{ 2191 _log(["_fetchURL :: unsupported"]); 2192 callback(); 2193 } 2194 2195 }); 2196 2197 } 2198 2199 function _setupMedia(callback){ 2200 2201 if(!video.media){ 2202 return false; 2203 } 2204 2205 $(video.container).addClass(cfg.classes.state.stopped + " " + cfg.classes.state.loading + " " + cfg.classes.state.loadingMetadata); 2206 2207 if(!video.supported.range){ 2208 $(video.container).addClass('noRangeSupported'); 2209 }
2210 if(!video.supported.volume){ 2211 $(video.container).addClass('noVolumeSupported'); 2212 } 2213 if(!video.supported.fullscreen){ 2214 $(video.container).addClass('noFullscreenSupported'); 2215 } 2216 if(!video.supported.animation){ 2217 $(video.container).addClass('noAnimationSupported'); 2218 } 2219 if(!video.init.controls){ 2220 $(video.container).addClass('noControls'); 2221 } 2222 2223 _fetchURL(callback); 2224 2225 } 2226 2227 function _setupHTML(){ 2228 2229 var i, attrs, html = cfg.html, toRemove = []; 2230 2231 html = html.replace(/\{id\}/g, video.uniq); 2232 html = html.replace(/\{recommended\}/g, _recommended(cfg.recommended)); 2233 html = html.replace(/\{settings\}/g, _settings()); 2234 2235 $(video.container) 2236 .wrap('<div />')[0] 2237 .insertAdjacentHTML("afterend", html); 2238 2239 /* remove and set all atributes from video to video.parent() */ 2240 attrs = $(video.container)[0].attributes; 2241 2242 for(i = 0; i < attrs.length; i++){ 2243 if($.inArray(attrs[i].name, ['poster', 'src', 'playsinline', 'muted', 'autoplay', 'data-autoplay', 'controls', 'preload']) !== -1) continue; 2244 else if(attrs[i].name == 'class'){ 2245 $(video.container).parent().addClass(attrs[i].value); 2246 $(video.container).removeClass(); 2247 } 2248 else{ 2249 $(video.container).parent().attr(attrs[i].name, attrs[i].value); 2250 toRemove.push(attrs[i].name); 2251 } 2252 } 2253 2254 for(i = 0; i < toRemove.length; i++){ 2255 $(video.container).removeAttr(toRemove[i]); 2256 } 2257 2258 /* 2259 * set video.container to video.parent() 2260 * set tabindex = -1 for video DOM, we dont want to Tab reach this element 2261 */ 2262 video.container = $(video.container).attr('tabindex', '-1').addClass(cfg.classes.videoEl.media).parent().addClass(cfg.classes.container + " " + cfg.classes.state.stopped); 2263 2264 var proportionStyle = _proportionStyle(); 2265 2266 if(cfg.persistent) { 2267 var placeholder = document.createElement('div'); 2268 placeholder.className = cfg.classes.placeholder; 2269 2270 video.persistent = {}; 2271 video.persistent.placeholder = $(video.container[0].parentNode.insertBefore(placeholder, video.container[0].nextSibling)); 2272 2273 var restore = document.createElement('button'); 2274 restore.className = cfg.classes.button.all + ' ' + cfg.classes.button.restore; 2275 video.persistent.restore = $(video.container[0].appendChild(restore)); 2276 } 2277 2278 $(video.media).wrap('<div class="' + cfg.classes.videoEl.container + '"' + (proportionStyle ? ' style="padding-top:' + proportionStyle + '"' : '') + ' />'); 2279 2280 /* for iOS */ 2281 if(isiPad || isiPhone){ 2282 var webm = $(video.media).find('[type="video/webm"]'); 2283 2284 if(webm[0]){ 2285 video.media.insertAdjacentHTML('afterbegin', _outerHTML(webm[0])); 2286 webm.remove(); 2287 } 2288 2289 $(video.media).replaceWith(_outerHTML(video.media)); 2290 } 2291 2292 video.media = _getElements("." + cfg.classes.videoEl.media)[0]; 2293 2294 _log(["_setupHTML", video.container]); 2295 2296 } 2297 2298 function _outerHTML(el) { 2299 if('outerHTML' in el) { 2300 return el.outerHTML; 2301 } 2302 2303 var node, tmp; 2304 tmp = document.createElement('div'); 2305 node = el.cloneNode(true); 2306 tmp.appendChild(node); 2307 return tmp.innerHTML; 2308 } 2309 2310 function _proportionStyle() { 2311 var proportion = ''; 2312 if(cfg.proportion != "16:9" && (proportion = cfg.proportion.split(":")).length == 2){ 2313 proportion = (proportion[1] / proportion[0] * 100).toFixed(2) + '%'; 2314 } 2315 2316 return proportion; 2317 } 2318 2319 function _settings() { 2320 var html = '', 2321 container = $(video.container), 2322 qualities = container.find('source'), 2323 defaultSrc; 2324 2325 if(isIEMobile || isiPhone || (isiPad && iOSVersion < 10) || isOldAndroid) { 2326 return html; 2327 } 2328 2329 for(var i = 0, q; q = qualities[i++]; ) { 2330 var quality = q.getAttribute('data-quality'), 2331 contentType = q.getAttribute('type'); 2332 2333 if(!quality || contentType != 'video/mp4') continue; 2334 2335 video.qualities = video.qualities || []; 2336 2337 var src = q.getAttribute('src'); 2338 2339 video.qualities.push({ 2340 label: quality, 2341 src: src, 2342 isDefault: false 2343 }); 2344 2345 if(!defaultSrc) { 2346 defaultSrc = src; 2347 } 2348 } 2349 2350 if(video.qualities && video.qualities.length > 1) { 2351 video.isSettings = true; 2352 2353 video.qualities.sort(function(a, b) { 2354 return parseInt(a.label) < parseInt(b.label); 2355 }); 2356 2357 if(_is4G()) { 2358 var i = Math.max(0, video.qualities.length - 2); 2359 defaultSrc = video.qualities[i].src; 2360 } 2361 2362 video.qualities.unshift({ 2363 label: 'auto', 2364 src: defaultSrc, 2365 isDefault: true 2366 }); 2367 2368 html += '<div class="' + config.classes.more.settings.container + '">'; 2369 html += ' <div class="' + config.classes.more.settings.items + '">'; 2370 for(var i = 0, q; q = video.qualities[i++]; ) { 2371 html += ' <button class="' + config.classes.more.settings.item + (q.isDefault ? ' is--active' : '') + '">' + q.label + '</button>'; 2372 } 2373 html += ' </div>'; 2374 html += ' <div class="' + config.classes.button.all + ' ' + config.classes.button.iconSettings + '"><span class="_"></span></div>'; 2375 html += '</div>'; 2376 2377 container.addClass('is--settings'); 2378 } 2379 2380 return html; 2381 } 2382 2383 function _recommended(recommended){ 2384 var html = ''; 2385 2386 if(recommended.length){ 2387 video.isRecommended = true; 2388 2389 html = '<div class="' + cfg.classes.recommended.container + ' ' + cfg.classes.recommended.container + '--' + recommended.length + '">'; 2390 html += ' <div class="' + cfg.classes.recommended.item + ' ' + cfg.classes.recommended.item + '--main">'; 2391 html += ' <a href="' + recommended[0].url + '" class="' + cfg.classes.recommended.title + '">' + recommended[0].title + '</a>'; 2392 html += ' <img src="' + recommended[0].img + '" alt="" class="' + cfg.classes.recommended.img + '">'; 2393 html += ' <a href="' + recommended[0].url + '" class="' + cfg.classes.recommended.progress + '">' 2394 html += ' <svg class="' + cfg.classes.recommended.svg + '" version="1.1" viewBox="0 0 100 100" preserveAspectRatio="xMinYMin meet">'; 2395 html += ' <circle cx="50" cy="50" r="47" stroke-width="6" stroke-dasharray="296" stroke-dashoffset="0" class="' + cfg.classes.recommended.svg + '-circle" />'; 2396 html += ' <polygon points="35,25 72,50 35,75" class="' + cfg.classes.recommended.svg + '-play" />'; 2397 html += ' </svg>'; 2398 html += ' </a>'; 2399 html += ' <span class="' + cfg.classes.recommended.counter + '">Następne wideo rozpocznie się za <span class="' + cfg.classes.recommended.seconds + '">-</span>
2399 sekund. <span class="' + cfg.classes.recommended.cancel + '">Anuluj</span></span>'; 2400 html += ' </div>'; 2401 html += ' <div class="' + cfg.classes.recommended.list + '">'; 2402 for(var i = 1, l = recommended.length; i < l; i++){ 2403 html += ' <a href="' + recommended[i].url + '" class="' + cfg.classes.recommended.item + '">'; 2404 html += ' <span class="' + cfg.classes.recommended.title + '">' + recommended[i].title + '</span>'; 2405 html += ' <img src="' + recommended[i].img + '" alt="" class="' + cfg.classes.recommended.img + '">'; 2406 html += ' </a>'; 2407 } 2408 html += ' </div>'; 2409 html += '</div>'; 2410 } 2411 2412 return html; 2413 } 2414 function _recommendedScroll(){ 2415 requestAnimationFrame(function(){ 2416 var wHeight = window.innerHeight; 2417 2418 for(var i = 0, el; el = videoPlayer.els[i++]; ){ 2419 var el = el.instance(); 2420 2421 if(!el.recommended.showing || el.recommended.isCancel) continue; 2422 2423 var rect = el.recommended.svg[0].getBoundingClientRect(), 2424 oTop = rect.top, 2425 oHeight = rect.height, 2426 pos = oTop + oHeight / 2; 2427
2428 if(el.recommended.scrollState !== (el.recommended.scrollState = pos > 0 && pos < wHeight)){ 2429 if(window.videoPlayer.isBlur) continue; 2430 2431 if(el.recommended.scrollState){ 2432 el.recommended.animate.play(); 2433 } 2434 else{ 2435 el.recommended.animate.pause(); 2436 } 2437 } 2438 } 2439 }); 2440 } 2441 function _recommendedFocusChange(el){ 2442 if(!el.recommended.showing || el.recommended.isCancel) return; 2443 2444 if(window.videoPlayer.isBlur){ 2445 el.recommended.animate.pause(); 2446 } 2447 else if(el.recommended.scrollState){ 2448 el.recommended.animate.play(); 2449 } 2450 } 2451 function _prepareRecomended(){ 2452 var secs = isiPhone || isIEMobile ? 0 : cfg.recommendedCountdown, 2453 second, stroke; 2454 2455 video.recommended.scrollState = null; 2456 video.recommended.showing = true; 2457 video.recommended.isCancel = !secs; 2458 2459 if(!video.recommended.isCancel){ 2460 video.recommended.container.removeClass(cfg.classes.recommended.container + '--cancel'); 2461 video.recommended.container.addClass(cfg.classes.recommended.container + '--pause'); 2462 video.recommended.svg.attr('stroke-dashoffset', (stroke = parseInt(video.recommended.svg.attr('stroke-dasharray')))); 2463 video.recommended.seconds.html(secs); 2464 2465 video.recommended.animate = new Animate({ 2466 duration: secs * 1000, 2467 onPlay: function(){ 2468 video.recommended.isPause = false; 2469 video.recommended.container.removeClass(cfg.classes.recommended.container + '--pause'); 2470 }, 2471 onUpdate: function(anim, step){ 2472 if(video.recommended.isPause) 2473 return; 2474 2475 if(!video.recommended.showing){ 2476 video.recommended.animate.pause(); 2477 return; 2478 } 2479 2480 if(second != (second = Math.round(Animate.calculate(secs, 0, step)))){ 2481 video.recommended.seconds.html(second); 2482 } 2483 2484 video.recommended.svg.attr('stroke-dashoffset', Animate.calculate(stroke, 0, step)); 2485 }, 2486 onPause: function(){ 2487 video.recommended.container.addClass(cfg.classes.recommended.container + '--pause'); 2488 video.recommended.isPause = true; 2489 video.recommended.animate.stop(); 2490 }, 2491 onStop: function(){ 2492 if(!video.recommended.isCancel && !video.recommended.isPause){ 2493 var url = video.recommended.container.find('.' + cfg.classes.recommended.title).attr('href'); 2494 window.location.assign(url); 2495 } 2496 } 2497 }); 2498 2499 _recommendedScroll(); 2500 } 2501 else{ 2502 video.recommended.container.addClass(cfg.classes.recommended.container + '--off'); 2503 } 2504 } 2505 function _persistentClick() { 2506 window.videoPlayer.persistent.active = null; 2507 video.persistent.prevent = true; 2508 video.container.removeClass('is--persistent'); 2509 } 2510 function _persistentScroll() { 2511 requestAnimationFrame(function(){ 2512 var wHeight = window.innerHeight; 2513 2514 for(var i = 0, api; api = videoPlayer.els[i++]; ){ 2515 var instance = api.instance(); 2516 2517 if(!instance.persistent || instance.persistent.prevent || window.videoPlayer.persistent.active !== instance && api.isPaused()) continue; 2518 2519 window.videoPlayer.persistent.active = window.videoPlayer.persistent.active || instance; 2520 2521 var rect = window.videoPlayer.persistent.state ? 2522 instance.persistent.placeholder[0].getBoundingClientRect() : 2523 instance.container[0].getBoundingClientRect(); 2524 2525 var top = rect.top > wHeight, 2526 bottom = rect.bottom < 0, 2527 width = rect.width, 2528 height = rect.height; 2529 2530 if(window.videoPlayer.persistent.state !== (window.videoPlayer.persistent.state = top || bottom)) { 2531 if(!window.videoPlayer.persistent.state) { 2532 instance.container.removeClass('is--persistent'); 2533 2534 if(api.isPaused()) { 2535 window.videoPlayer.persistent.active = null; 2536 } 2537 } else { 2538 instance.persistent.placeholder[0].style.width = width + 'px'; 2539 instance.persistent.placeholder[0].style.height = height + 'px'; 2540 instance.container.addClass('is--persistent'); 2541 } 2542 } 2543 2544 return; 2545 } 2546 }); 2547 } 2548 function _getStorage(key, def) { 2549 try { 2550 return JSON.parse(window.localStorage[cfg.storage.key + key]) || def; 2551 } catch(e) {} 2552 2553 return def; 2554 } 2555 function _positionMemorySet() { 2556 2557 if(video.positionMemory) {
2558 var list = _getStorage('positionMemory', []); 2559 2560 for(var i = 0, item; item = list[i]; i++) { 2561 if(item[0] == video.uniq) { 2562 $(video.videoEl.media).one('play.positionMemorySet', function(){ 2563 _progSeek(item[1]); 2564 }); 2565 break; 2566 } 2567 } 2568 } 2569 } 2570 function _positionMemory() { 2571 var list = _getStorage('positionMemory', []), 2572 map = {}; 2573 2574 for(var i = 0, item; item = list[i]; i++) { 2575 map[item[0]] = i; 2576 } 2577 2578 var toRemove = []; 2579 for(var i = 0, api; api = window.videoPlayer.els[i++]; ) { 2580 var instance = api.instance(); 2581 2582 if(instance.positionMemory) { 2583 if(instance.videoEl.media.currentTime && !instance.isEnded) { 2584 var item = [instance.uniq, Math.round(instance.videoEl.media.currentTime)]; 2585 if(instance.uniq in map) { 2586 list[map[instance.uniq]] = item; 2587 } else { 2588 list.unshift(item); 2589 } 2590 } 2591 else if(instance.isEnded) { 2592 toRemove.push(instance.uniq); 2593 } 2594 } 2595 } 2596 2597 for(var i = list.length, item; item = list[--i]; ) { 2598 for(var j = toRemove.length, remove; remove = toRemove[--j]; ) { 2599 if(item[0] == remove) { 2600 list.splice(i, 1); 2601 toRemove.splice(j, 1); 2602 } 2603 } 2604 } 2605 2606 if(list.length > cfg.positionMemoryLimit) { 2607 list.length = cfg.positionMemoryLimit; 2608 } 2609 2610 window.localStorage[cfg.storage.key + 'positionMemory'] = JSON.stringify(list); 2611 } 2612 2613 function _setupElements(){ 2614 2615 video.videoEl = {}; 2616 video.videoEl.container = _getElements("." + cfg.classes.videoEl.container); 2617 video.videoEl.media = _getElements("." + cfg.classes.videoEl.media)[0]; 2618 2619 video.mask = _getElements("." + cfg.classes.mask); 2620 video.adsUrl = _getElements("." + cfg.classes.adsUrl); 2621 2622 video.controls = _getElements("." + cfg.classes.controls); 2623 2624 video.buttons = {}; 2625 video.buttons.all = _getElements("." + cfg.classes.button.all); 2626 video.buttons.play = _getElements("." + cfg.classes.button.play); 2627 video.buttons.pause = _getElements("." + cfg.classes.button.pause); 2628 video.buttons.mute = _getElements("." + cfg.classes.button.mute); 2629 video.buttons.unmute = _getElements("." + cfg.classes.button.unmute); 2630 video.buttons.enterFullscreen = _getElements("." + cfg.classes.button.enterFullscreen); 2631 video.buttons.exitFullscreen = _getElements("." + cfg.classes.button.exitFullscreen); 2632 2633 video.labels = {}; 2634 video.labels.all = _getElements("." + cfg.classes.label.all); 2635 video.labels.span = _getElements("." + cfg.classes.label.span); 2636 video.labels.duration = _getElements("." + cfg.classes.label.duration); 2637 video.labels.total = _getElements("." + cfg.classes.label.total); 2638 video.labels.durationSpan = _getElements("." + cfg.classes.label.duration + " ." + cfg.classes.label.span); 2639 video.labels.totalSpan = _getElements("." + cfg.classes.label.total + " ." + cfg.classes.label.span); 2640 2641 video.progress = {}; 2642 video.progress.container = _getElements("." + cfg.classes.progress.container); 2643 video.progress.all = _getElements("." + cfg.classes.progress.all); 2644 video.progress.ads = _getElements("." + cfg.classes.progress.ads); 2645 video.progress.seek = _getElements("." + cfg.classes.progress.seek); 2646 video.progress.buffer = _getElements("." + cfg.classes.progress.buffer); 2647 video.progress.bufferSpan = _getElements("." + cfg.classes.progress.buffer + " span"); 2648 video.progress.played = _getElements("." + cfg.classes.progress.played); 2649 video.progress.playedSpan = _getElements("." + cfg.classes.progress.played + " span"); 2650 video.progress.volume = _getElements("." + cfg.classes.progress.volume); 2651 video.progress.volumeSpan = _getElements("." + cfg.classes.progress.volume + " span"); 2652 2653 video.volume = {}; 2654 video.volume.container = _getElements("." + cfg.classes.more.volume.container); 2655 video.volume.wrap = _getElements("." + cfg.classes.more.volume.wrap); 2656 video.volume.checkbox = _getElements("." + cfg.classes.more.volume.container + " [type=checkbox]"); 2657 video.volume.seek = _getElements("." + cfg.classes.more.volume.seek); 2658 2659 video.settings = {}; 2660 video.settings.container = _getElements("." + cfg.classes.more.settings.container); 2661 video.settings.item = _getElements("." + cfg.classes.more.settings.item); 2662 2663 video.fullscreen = {}; 2664 video.fullscreen.container = _getElements("." + cfg.classes.more.fullscreen.container); 2665 2666 video.recommended = {}; 2667 video.recommended.container = _getElements("." + cfg.classes.recommended.container); 2668 video.recommended.svg = _getElements("." + cfg.classes.recommended.svg + "-circle"); 2669 video.recommended.seconds = _getElements("." + cfg.classes.recommended.seconds); 2670 video.recommended.cancel = _getElements("." + cfg.classes.recommended.cancel); 2671 2672 _log(["_setupElements", video]); 2673 2674 } 2675 2676 function checkIfCanAutoplay(cb) { 2677 if(video.checkIfCanAutoplay) { 2678 cb(video.checkIfCanAutoplay); 2679 return; 2680 } 2681 2682 var promise = video.videoEl.media.play(); 2683 2684 if(promise) { 2685 promise.then(function() { 2686 video.videoEl.media.pause();
2687 cb((video.checkIfCanAutoplay = { 2688 autoplayAllowed: true, 2689 autoplayRequiresMuted: false 2690 })); 2691 }).catch(function() { 2692 var _vol = video.videoEl.media.volume; 2693 _setVolume(0); 2694 2695 video.videoEl.media.play().then(function() { 2696 video.videoEl.media.pause(); 2697 cb((video.checkIfCanAutoplay = { 2698 autoplayAllowed: true, 2699 autoplayRequiresMuted: true 2700 })); 2701 }).catch(function() { 2702 _setVolume(_vol); 2703 2704 cb((video.checkIfCanAutoplay = { 2705 autoplayAllowed: false, 2706 autoplayRequiresMuted: false 2707 })); 2708 }); 2709 }); 2710 } else { 2711 var playing = !video.videoEl.media.paused; 2712 video.videoEl.media.pause(); 2713 2714 cb((video.checkIfCanAutoplay = { 2715 autoplayAllowed: playing, 2716 autoplayRequiresMuted: false 2717 })); 2718 } 2719 } 2720 2721 function _onLoadedMetadata(){ 2722 _durationUpdate(); 2723 2724 _stats.stream("newStream"); 2725 _stats.prism("Nowy_Materiał"); 2726 _stats.player("newProgram"); 2727 2728 2729 if(video.init.autoplay) { 2730 checkIfCanAutoplay(function(opts) { 2731 if(opts.autoplayAllowed) { 2732 _play(); 2733 } 2734 }); 2735 } 2736 } 2737 2738 function _loadedMetadata(event){ 2739 2740 var dur = video.videoEl.media.duration, 2741 durArr = [0, 1, 100, 6000]; 2742 2743 if((!event && isNaN(dur)) || video.loadedmetadata){ 2744 // video.videoEl.media.load(); 2745 return; 2746 } 2747 2748 _log(['loadedmetadata', !!event, dur]); 2749 2750 if(isAndroid || isiPhone || isiPad || dur){ 2751 2752 clearTimeout(video.timerMetadata); 2753 video.loadedmetadata = true; 2754 2755 if($.inArray(dur, durArr) !== -1 || isNaN(dur)){ 2756 2757 $(video.videoEl.media).on("durationchange.dur", function(e){ 2758 2759 if($.inArray(e.target.duration, durArr) === -1 && !isNaN(e.target.duration)){ 2760 _onLoadedMetadata(); 2761 $(video.videoEl.media).off("durationchange.dur"); 2762 } 2763 2764 }); 2765 2766 } 2767 else{ 2768 _onLoadedMetadata(); 2769 } 2770 2771 2772 $(video.container).off('touchstart.mobilesafari'); 2773 $(video.videoEl.media).off("loadedmetadata.dur"); 2774 2775 $(video.container).removeClass(cfg.classes.state.loading + " " + cfg.classes.state.loadingMetadata); 2776 2777 } 2778 else{ 2779 setTimeout(function() { 2780 dur = video.videoEl.media.duration; 2781 if(($.inArray(dur, durArr) !== -1 || isNaN(dur)) && video.videoEl.media.networkState !== 2) { 2782 _showError('timeout'); 2783 } 2784 }, 60000); 2785 } 2786 2787 } 2788 2789 function _is4G() { 2790 var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection; 2791 var type = (connection && connection.effectiveType || "").replace(/.*(\d)g/, function(a, b) { 2792 return b; 2793 }); 2794 2795 return type > 3; 2796 } 2797 2798 function _changeSource(src, label) { 2799 var time = video.videoEl.media.currentTime, 2800 paused = video.videoEl.media.paused; 2801 2802 video.container.addClass('loading loading--quality'); 2803 video.videoEl.media.src = src; 2804 video.videoEl.media.load(); 2805 video.videoEl.media.currentTime = time; 2806 $(video.videoEl.media).one('loadeddata', function() { 2807 video.container.removeClass('loading loading--quality'); 2808 2809 if(!paused) { 2810 video.videoEl.media.play(); 2811 } 2812 2813 video.quality = label === 'auto' ? '480p' : label; 2814 2815 if(video.redeventsBegin) 2816 _stats.redevents("change quality"); 2817 2818 }); 2819 } 2820 2821 function _listeners(){ 2822 2823 $(video.mask).on("click", _toggle); 2824 $(video.buttons.play).on("click", _play); 2825 $(video.buttons.pause).on("click", _pause); 2826 2827 if(video.supported.fullscreen){ 2828 $(video.mask).on("dblclick", _toggleFullscreen); 2829 $(video.buttons.enterFullscreen).on("click", _enterFullscreen); 2830 $(video.buttons.exitFullscreen).on("click", _exitFullscreen); 2831 } 2832 2833 $(video.volume.seek).on("change input", function(){ 2834 _setVolume(this.value); 2835 }); 2836 2837 $(video.progress.seek).on("change input", _seek); 2838 2839 if(!video.supported.range){ 2840 2841 video.progress.seek.replaceWith('<div class="' + cfg.classes.progress.all + ' ' + cfg.classes.progress.seek + ' ' + cfg.classes.progress.all + '--fallback"></div>'); 2842 video.progress.seek = _getElements("." + cfg.classes.progress.seek); 2843 2844 video.volume.seek.replaceWith('<div class="' + cfg.classes.progress.all + ' ' + cfg.classes.more.volume.seek + ' ' + cfg.classes.progress.all + '--fallback"></div>'); 2845 video.volume.seek = _getElements("." + cfg.classes.more.volume.seek); 2846 2847 2848 var startDrag = false; 2849 _getElements("." + cfg.classes.progress.all + "--fallback").on("mousedown.range", function(e){
2850 var elem = this, 2851 elemIsProgress = $(this).hasClass(cfg.classes.progress.seek), 2852 value = _drag(elem, e) + "%"; 2853 2854 startDrag = true; 2855 video.isInput = true; 2856 2857 if(elemIsProgress){ 2858 video.seekingStart = true; 2859 _seek(value); 2860 video.seekingStart = false; 2861 } 2862 else{ 2863 _setVolume(value); 2864 } 2865 2866 $(document).on("mousemove.range", function(e){ 2867 if(!startDrag) return; 2868 2869 value = _drag(elem, e) + "%"; 2870 2871 if(elemIsProgress){ 2872 _seek(value); 2873 } 2874 else{ 2875 _setVolume(value); 2876 } 2877 }); 2878 2879 $(document).one("mouseup.range", function(){ 2880 2881 if(elemIsProgress && !video.videoEl.media.paused){ 2882 _stats.stream("playing"); 2883 _stats.player("play"); 2884 } 2885 2886 startDrag = false; 2887 video.isInput = false; 2888 $(document).off("mousemove.range"); 2889 2890 }); 2891 }); 2892 2893 } 2894 2895 $(video.volume.checkbox).on("change", function(){ 2896 _toggleMute(this.checked); 2897 }); 2898 2899 if(video.isSettings) { 2900 video.settings.item.on('click', function(event) { 2901 event.preventDefault(); 2902 2903 var t = $(this), 2904 index = Array.prototype.slice.call(this.parentElement.children).indexOf(this); 2905 2906 if(t.hasClass('is--active')) 2907 return; 2908 2909 t.parent().find('.is--active').removeClass('is--active'); 2910 t.addClass('is--active'); 2911 2912 var q = video.qualities[index]; 2913 2914 _changeSource(q.src, q.label); 2915 2916 try{ 2917 if(q.label == 'auto') { 2918 window.localStorage.removeItem(cfg.storage.key + 'quality'); 2919 } else { 2920 window.localStorage[cfg.storage.key + 'quality'] = JSON.stringify(q.label); 2921 } 2922 } catch(e) {} 2923 }); 2924 2925 var storageQuality = _getStorage('quality', false); 2926 if(storageQuality) { 2927 for(var i = 0, q; q = video.qualities[i]; i++) { 2928 if(q.label == storageQuality) { 2929 video.settings.item[i].click(); 2930 break; 2931 } 2932 } 2933 } else if(_is4G()) { 2934 var i = Math.max(1, video.qualities.length - 2); 2935 _changeSource(video.qualities[i].src, video.qualities[i].label); 2936 } 2937 2938 } 2939 2940 if(cfg.persistent) { 2941 video.persistent.restore.on('click.persistent', _persistentClick); 2942 2943 if(!window.videoPlayer.persistent) { 2944 window.videoPlayer.persistent = {}; 2945 $(window).on('scroll.persistent', _persistentScroll); 2946 } 2947 } 2948 2949 if(cfg.positionMemory && cfg.storage.enabled && video.supported.storage) { 2950 video.positionMemory = true; 2951 2952 if(!window.videoPlayer.positionMemory) { 2953 window.videoPlayer.positionMemory = {}; 2954 2955 window.onbeforeunload = _positionMemory; 2956 } 2957 } 2958 2959 video.recommended.cancel.on("click", function(){ 2960 video.recommended.container.addClass(cfg.classes.recommended.container + '--cancel'); 2961 video.recommended.isCancel = true; 2962 video.recommended.animate.pause(); 2963 }); 2964 2965 $(video.media).on("volumechange", _checkMute); 2966 2967 $(video.media).on("play pause", _checkPlaying); 2968 $(video.videoEl.media).on("ended", function(){ 2969 if(video.isEnded) return; 2970 2971 /* fix for IE */ 2972 if(isIE) video.media.pause(); 2973 2974 function _logEnd() { 2975 _stats.stream("complete"); 2976 _stats.prism("Koniec_Materiału"); 2977 _stats.player("complete"); 2978 _stats.redevents("end"); 2979 2980 _log('end'); 2981 } 2982 2983 function _ended() { 2984 video.isEnded = true; 2985 _checkPlaying(); 2986 2987 if(video.isRecommended) { 2988 _prepareRecomended(); 2989 } 2990 2991 if(typeof cfg.onEnded == "function") { 2992 cfg.onEnded(video);
2993 } 2994 2995 $(video.progress.seek).one("change.afterend input.afterend", function() { 2996 $(video.container).removeClass(cfg.classes.state.ended); 2997 if(video.isRecommended) { 2998 video.recommended.showing = false; 2999 if(video.recommended.animate) video.recommended.animate.pause(); 3000 } 3001 }); 3002 3003 _log('ended'); 3004 } 3005 3006 if(video.vast && video.isAds) { 3007 return; 3008 } 3009 3010 _logEnd(); 3011 3012 if(video.vast) { 3013 video.vast.contentComplete(_ended); 3014 } else { 3015 _ended(); 3016 } 3017 3018 }); 3019 $(video.videoEl.media).on("play pause", function(e){ 3020 if(e.target.ended || preventLogOnAndroid) return; 3021 3022 if(e.type == "play" && video.isEnded){ 3023 3024 _stats.stream("newStream"); 3025 _stats.prism("Nowy_Materiał"); 3026 _stats.prism("Start"); 3027 _stats.redevents("try"); 3028 _stats.redevents("begin"); 3029 3030 video.isEnded = 3031 video.prismStart = 3032 video.prism90 = 3033 video.recommended.showing = false; 3034 3035 _checkPlaying(); 3036 } 3037 3038 var state = e.type == "play" ? "playing" : "paused"; 3039 _stats.stream(state); 3040 }); 3041 3042 $(video.videoEl.media).on("waiting canplay seeked buffering", _checkLoading); 3043 3044 if(!video.fullscreenListener) { 3045 $(document).on('webkitfullscreenchange mozfullscreenchange MSFullscreenChange fullscreenchange', _checkFullscreen); 3046 video.fullscreenListener = true; 3047 } 3048 3049 video.videoEl.media.addEventListener("error", _networkState, true); 3050 //if(isAndroid || isiPad) _networkState(); 3051 3052 $(video.media).on("progress", _updateProgress); 3053 3054 $(video.media).on("playing", _updateProgress); 3055 3056 video.timerMetadata = setTimeout(function(){ 3057 if(isAndroid || isiPhone || isiPad) _loadedMetadata(true); 3058 }, 3000); 3059 3060 $(video.videoEl.media).on("loadedmetadata.dur", _loadedMetadata); 3061 _loadedMetadata(); 3062 3063 if(!isAndroid){ 3064 3065 video.videoEl.media.load(); 3066 3067 if(isiPad || isiPhone){ 3068 3069 $(video.container).removeClass(cfg.classes.state.loadingMetadata); 3070 $(video.container).on('touchstart.mobilesafari', function(){ 3071 video.videoEl.media.load(); 3072 }); 3073 3074 } 3075 } 3076 3077 $(video.videoEl.media).on("timeupdate seeking", _timeUpdate); 3078 3079 if(!window.videoPlayer.focusChange){ 3080 window.videoPlayer.focusChange = true; 3081 $(window).on('focus.videoPlayer blur.videoPlayer', _focusChange); 3082 } 3083 3084 if(video.isRecommended && !window.videoPlayer.recommendedScroll){ 3085 window.videoPlayer.recommendedScroll = true; 3086 $(window).on('scroll.videoPlayer', _recommendedScroll); 3087 } 3088 } 3089 3090 function _toggleAds(ads){ 3091 $(video.container).toggleClass('ads', ads); 3092 video.isAds = ads; 3093 if(ads) video.mask.attr('data-time', '--:--'); 3094 } 3095 3096 function _isAds(){ 3097 return video.isAds; 3098 } 3099 3100 function _onClickAds(){ 3101 3102 if(!video.loadedmetadata || $(video.adsUrl).attr('href') == "") return; 3103 if(video.vast && video.vast.isPaused()) { 3104 _play(); 3105 } else if(!video.videoEl.ads.paused){ 3106 3107 _hit(video.adsOnClicked); 3108 3109 try{ 3110 $(video.adsUrl)[0].click(); 3111 } 3112 catch(e){ 3113 window.open($(video.adsUrl)[0].href, '_blank'); 3114 } 3115 3116 _log(["_hit :: onClicked", video.adsOnClicked]); 3117 3118 } 3119 else{ 3120 _play(); 3121 } 3122 3123 } 3124 3125 function _onEndedPREAds(e, row){ 3126 3127 /*if(!row){ 3128 _hit(video.adsOnEmitted); 3129 _log(["_hit :: onEmitted", video.adsOnEmitted]); 3130 }*/ 3131 3132 if(e) _stats.player("complete"); 3133 3134 video.time.ads.currentDuration -= row && row["duration"] || video.videoEl.ads.duration; 3135 3136 var row; 3137 if(row = video.ads["0"]["items"].shift()){ 3138 3139 video.currentAdInBlock++; 3140 3141 _stats.prism("PreRoll"); 3142 3143 video.videoEl.ads.src = _getSource(row.src); 3144 video.videoEl.ads.load(); 3145 video.adsUrl[0].href = row.url; 3146 video.adsID = row.id; 3147 video.adsOnClicked = row.events.on_clicked; 3148 video.adsOnEmitted = row.events.on_emitted; 3149 video.adsOnTimeupdate = row.events.on_timeupdate; 3150 3151 _stats.player("newAd"); 3152 //$(video.videoEl.ads).one('playing', function(){ 3153 // _gemius.player("play"); 3154 //}); 3155 3156 _hit(video.adsOnEmitted); 3157 _log(["_hit :: onEmitted", video.adsOnEmitted]); 3158 3159 } 3160 else{ 3161 3162 _stats.prism("PreRoll_KoniecBloku"); 3163 3164 /* unbind */ 3165 $(video.videoEl.ads).off("ended.ads"); 3166 $(video.videoEl.ads).off("error.ads"); 3167 3168 video.media = video.videoEl.media; 3169 3170 _toggleAds(false); 3171 3172 _setVolume(); 3173 3174 _checkBeforeBegin(); 3175 3176 video.currentAdInBlock = 0; 3177 video.totalAdInBlock = 0; 3178 3179 /* fix for iOS Mobile - the next ad has start time from previous one */ 3180 if(isiPad || isiPhone){ 3181 video.videoEl.ads.currentTime = 0.1; 3182 $(video.container).removeClass(cfg.classes.state.ended); 3183 } 3184 3185 if(video.ads["offsets"].length){ 3186 3187 _setupAdsMID(); 3188 3189 } 3190 else{ 3191 $(video.adsUrl).remove(); 3192 $(video.videoEl.ads).remove(); 3193 } 3194 3195 } 3196 3197 if(e || video.init.autoplay) _play(); 3198 3199 } 3200 3201 function _listenersAds(){ 3202 3203 $(video.videoEl.ads).one("playing", function(){ 3204 _toggleAds(true); 3205 3206 _stats.prism("PreRoll_StartBloku"); 3207 _stats.prism("PreRoll"); 3208 _stats.redevents("begin preRoll"); 3209 3210 _focusChange(); 3211 }); 3212 3213 $(video.videoEl.ads).on("play pause", _checkPlaying); 3214 3215 video.media = video.videoEl.ads; 3216 3217 $(video.videoEl.ads).on("ended.ads", _onEndedPREAds); 3218 $(video.videoEl.ads).on("timeupdate.ads", _adsTimeUpdate); 3219 3220 } 3221 3222 function _onEndedMIDAds(evntId, list, row){ 3223 3224 /*if(!row){ 3225 _hit(video.adsOnEmitted); 3226 _log(["_hit :: onEmitted", video.adsOnEmitted]); 3227 }*/ 3228 3229 video.time.ads.currentDuration -= row && row["duration"] || video.videoEl.ads.duration; 3230 3231 if(list["items"].length){ 3232 3233 video.currentAdInBlock++; 3234 3235 _stats.prism("MidRoll"); 3236 3237 var row = list["items"].shift(); 3238 3239 video.videoEl.ads.src = _getSource(row.src); 3240 video.videoEl.ads.load(); 3241 video.adsUrl[0].href = row.url; 3242 video.adsID = row.id; 3243 video.adsOnClicked = row.events.on_clicked; 3244 video.adsOnEmitted = row.events.on_emitted; 3245 video.adsOnTimeupdate = row.events.on_timeupdate; 3246 3247 _stats.player("newAd"); 3248 //$(video.videoEl.ads).one('playing', function(){ 3249 // _gemius.player("play"); 3250 //}); 3251 3252 _hit(video.adsOnEmitted); 3253 _log(["_hit :: onEmitted", video.adsOnEmitted]); 3254 3255 $(video.videoEl.ads).one("error.ads", function(){ 3256 _onEndedMIDAds(evntId, list, row); 3257 }); 3258 3259 } 3260 else{ 3261 3262 _stats.prism("MidRoll_KoniecBloku"); 3263 _stats.redevents("end midRoll"); 3264 3265 /* unbind */ 3266 $(video.videoEl.ads).off("error.ads"); 3267 $(video.videoEl.ads).off("ended.id" + evntId); 3268 3269 video.media = video.videoEl.media; 3270 3271 _toggleAds(false); 3272 3273 _setVolume(); 3274 3275 video.currentAdInBlock = 0; 3276 video.totalAdInBlock = 0; 3277 3278 /* fix for iOS Mobile - the next ad has start time from previous one */ 3279 if(isiPad || isiPhone) video.videoEl.ads.currentTime = 0.1; 3280 3281 $('#ads' + video.uniq + '_' + evntId).remove(); 3282 3283 var offset; 3284 if(offset = video.ads["offsets"].shift()){ 3285 3286 _setAdsListener(offset); 3287 3288 } 3289 else{ 3290 $(video.adsUrl).remove(); 3291 $(video.videoEl.ads).remove(); 3292 } 3293 3294 } 3295 3296 _play(); 3297 3298 } 3299 3300 function _setAdsListener(offset){ 3301 3302 var evntId = parseInt(offset * 100), 3303 time = offset * video.media.duration, 3304 counter = 0; 3305 3306 $(video.media).on("timeupdate.id" + evntId, function(e){
3307 if(e.target.currentTime >= time){ 3308 3309 $(video.media).off("timeupdate.id" + evntId); 3310 3311 var pause = video.media.paused; 3312 3313 video.media.pause(); 3314 _stats.player("break"); 3315 3316 var mid = video.ads["mid"], 3317 list = video.ads[offset]; 3318 3319 _toggleAds(true); 3320 3321 video.time.ads = { 3322 currentTime: 0, 3323 currentDuration: list["total"], 3324 duration: list["total"] 3325 }; 3326 3327 video.currentAdInBlock = 1; 3328 video.totalAdInBlock = list["items"].length; 3329 3330 var row = list["items"].shift(); 3331 3332 video.videoEl.ads.src = _getSource(row.src); 3333 video.videoEl.ads.load(); 3334 video.adsUrl[0].href = row.url; 3335 video.adsID = row.id; 3336 video.adsOnClicked = row.events.on_clicked; 3337 video.adsOnEmitted = row.events.on_emitted; 3338 video.adsOnTimeupdate = row.events.on_timeupdate; 3339 3340 _hit(video.adsOnEmitted); 3341 _log(["_hit :: onEmitted", video.adsOnEmitted]); 3342 3343 video.media = video.videoEl.ads; 3344 3345 _setVolume(); 3346 3347 if(!pause){ 3348 video.videoEl.ads.play(); 3349 3350 _focusChange(); 3351 } 3352 3353 /* skip to next frame */ 3354 setTimeout(function(){ 3355 _stats.prism("MidRoll_StartBloku"); 3356 _stats.prism("MidRoll"); 3357 _stats.player("newAd"); 3358 _stats.redevents("begin midRoll"); 3359 3360 $(video.videoEl.ads).one('playing', function(){ 3361 _stats.player("play"); 3362 }); 3363 }); 3364 3365 $(video.videoEl.ads).one("error.ads", function(){ 3366 _onEndedMIDAds(evntId, list, row); 3367 }); 3368 3369 $(video.videoEl.ads).on("ended.id" + evntId, function(e){ 3370 3371 _stats.player("complete"); 3372 _onEndedMIDAds(evntId, list); 3373 3374 }); 3375 3376 } 3377 3378 }); 3379 3380 } 3381 3382 function _getSource(source){ 3383 return source[(_canPlay('mp4') ? (video.container[0].clientWidth <= 360 ? "mobile" : "mp4") : "webm")]; 3384 } 3385 3386 function _isPaused(){ 3387 if(video.vast && video.isAds) { 3388 return video.vast.isPaused(); 3389 } 3390 return video.media.paused; 3391 } 3392 3393 function _shouldPlay(val){ 3394 if(typeof val !== "undefined") return video.shouldPlay = val; 3395 return video.shouldPlay; 3396 } 3397 3398 function _focusChange(e){ 3399 setTimeout(function(){ 3400 var blur = !document.hasFocus(); 3401 window.videoPlayer.isBlur = blur; 3402 3403 for(var i = 0, el; el = videoPlayer.els[i++]; ){ 3404 var instance = el.instance(); 3405 3406 if(el.isAds()){ 3407 if(blur) el.shouldPlay(instance.vast ? !instance.vast.isPaused() : !el.isPaused()); 3408 if(el.shouldPlay() || video.vastIsIMAClicked) blur ? el.pause() : (el.play(), video.vastIsIMAClicked = null); 3409 } 3410 3411 if(instance.isRecommended){ 3412 _recommendedFocusChange(instance); 3413 } 3414 } 3415 }); 3416 } 3417 3418 function _setupAds(){ 3419 3420 $(video.videoEl.container).append('<video class="' + cfg.classes.videoEl.ads + '" tabindex="-1" />'); 3421 video.videoEl.ads = _getElements("." + cfg.classes.videoEl.ads)[0]; 3422 3423 $(video.videoEl.ads).on("play.prism pause.prism", function(e){ 3424 if(e.target.ended || e.target.currentTime == 0) return; 3425 var state = e.type == "play" ? "Start" : "Pauza"; 3426 _stats.prism(state); 3427 }); 3428 3429 if(video.ads["0"]){ 3430 3431 _setupAdsPRE(); 3432 3433 } 3434 else if(video.ads["offsets"].length){ 3435 3436 _setupAdsMID(); 3437 3438 } 3439 3440 _log(["ADS", video.ads]); 3441 3442 } 3443 3444 function _setupAdsPRE(){ 3445 3446 var row, 3447 pre = video.ads["0"]; 3448 3449 video.time.ads = { 3450 currentTime: 0, 3451 currentDuration: pre["total"], 3452 duration: pre["total"] 3453 }; 3454 3455 video.currentAdInBlock = 1; 3456 video.totalAdInBlock = pre["items"].length; 3457 3458 _listenersAds(); 3459 3460 if(row = pre["items"].shift()){ 3461 3462 $(video.videoEl.ads).on("error.ads", function(){ 3463 _onEndedPREAds(false, row); 3464 }); 3465 3466 _setVolume(); 3467 3468 video.videoEl.ads.src = _getSource(row.src); 3469 video.videoEl.ads.load(); 3470 video.adsUrl[0].href = row.url; 3471 video.adsID = row.id; 3472 video.adsOnClicked = row.events.on_clicked; 3473 video.adsOnEmitted = row.events.on_emitted; 3474 video.adsOnTimeupdate = row.events.on_timeupdate; 3475 3476 video.isPreAdsFirstPlay = true; 3477 3478 $(video.videoEl.ads).one("play.firstPlayAdsEmitted", function(){ 3479 _toggleAds(true); 3480 _stats.player("newAd"); 3481 _stats.player("play"); 3482 3483 video.isPreAdsFirstPlay = false; 3484 3485 _hit(video.adsOnEmitted); 3486 _log(["_hit :: onEmitted", video.adsOnEmitted]); 3487 }); 3488 3489 } 3490 3491 } 3492 3493 function _setCuePoints(points) { 3494 var adsHtml = ""; 3495 3496 for(var i = 0, l = points.length; i < l; i++){ 3497 var left = (points[i] * 100); 3498 adsHtml += '<i style="left:' + left + '%" id="ads' + video.uniq + '_' + parseInt(left) + '"></i>'; 3499 } 3500 3501 $(video.progress.ads).html(adsHtml); 3502 } 3503 function _clearCuePoints(offset) { 3504 video.tmpCuePoints = video.tmpCuePoints || video.vast && video.vast.cuePoints.filter(function(point) { 3505 return point > 0; 3506 }) || []; 3507
3508 if(!video.tmpCuePoints.length) return; 3509 3510 video.tmpCuePoints = video.tmpCuePoints.filter(function(point) { 3511 if(!offset || point == offset) { 3512 var left = (point / video.videoEl.media.duration) * 100; 3513 $('#ads' + video.uniq + '_' + parseInt(left)).remove(); 3514 } else { 3515 return point; 3516 } 3517 }); 3518 } 3519 3520 function _setupAdsMID(){ 3521 3522 /* skip mid_roll ads - on iPad main video is freezing after ad's end */ 3523 if(isiPad){ 3524 video.firstPlay = true; 3525 return; 3526 } 3527 3528 var mid = video.ads["offsets"]; 3529 _setCuePoints(mid); 3530 3531 video.firstPlay = true; 3532 3533 $(video.videoEl.ads).on("play pause", _checkPlaying); 3534 $(video.videoEl.ads).on("timeupdate.ads", _adsTimeUpdate); 3535 3536 var dur = video.videoEl.media.duration, 3537 durArr = [0, 1, 100, 6000]; 3538 3539 if($.inArray(dur, durArr) !== -1 || isNaN(dur)){ 3540 3541 $(video.videoEl.media).on("durationchange.durAds", function(e){ 3542 3543 if($.inArray(e.target.duration, durArr) === -1 && !isNaN(e.target.duration)){ 3544 3545 _setAdsListener(mid.shift()); 3546 3547 $(video.videoEl.media).off("durationchange.durAds"); 3548 } 3549 3550 }); 3551 3552 } 3553 else{ 3554 _setAdsListener(mid.shift()); 3555 } 3556 3557 } 3558 3559 function _checkAfterAds(){ 3560 3561 if(video.init.muted/* || video.init.autoplay && isAndroid*/) { 3562 video.media.muted = false; 3563 _toggleMute(true); 3564 } 3565 3566 _positionMemorySet(); 3567 3568 } 3569 function _checkBeforeBegin(){ 3570 3571 video.firstPlay = true; 3572 3573 } 3574 function _setupListeners(){ 3575 /* setup listeners */ 3576 _listeners(); 3577 3578 _checkAfterAds(); 3579 _checkBeforeBegin(); 3580 } 3581 3582 /** 3583 * private init of videoPlayer 3584 * returns API for later use 3585 * API is stored in emitter DOM Object 3586 * @return {Object} 3587 * - media: video DOM element 3588 * - play: play video 3589 * - pause: pause video 3590 * - toggle: toggle play/pause video 3591 * - seek: seek { Number (seconds) || String (percent: "35%") } 3592 * - volume: volume { Number (0-10) || String (percent: "35%") } 3593 * - toggleMute: toggle mute 3594 * - toggleFullscreen: toggle fullscreen 3595 */ 3596 function _init(){ 3597 3598 video.media = $(video.container)[0]; 3599 3600 /* store init values */ 3601 video.init = {}; 3602 /* strange behavior on Chrome - muted returns false even if attr is defined */ 3603 video.init.muted = video.media.muted || video.media.getAttribute('muted') != null; 3604 video.init.controls = video.media.controls; 3605 video.init.autoplay = video.media.autoplay || ($(video.media).attr('data-autoplay') == "true"); 3606 3607 /* store time values */ 3608 video.time = {}; 3609 3610 video.supported = api.supported(); 3611 3612 if(!video.supported.video){ 3613 return false; 3614 } 3615 3616 /* get uniq || random value for labels */ 3617 var tmpmedia; 3618 video.uniq = (tmpmedia = $(video.media)).attr('data-id') || video.media.id || hash(tmpmedia.find('source').attr('src')) || -Math.floor(Math.random() * 10000); 3619 3620 /* 3621 * sets controls and autoplay to false, and preload to only metadata 3622 * autoplay will be set again later > ado Object 3623 */ 3624 video.media.controls = video.media.autoplay = false; 3625 video.media.preload = 'metadata'; 3626 3627 3628 /* setup all HTML markup */ 3629 _setupHTML(); 3630 3631 /* setup elements for interial use */ 3632 _setupElements(); 3633 3634 /* setup volume from localStorage */ 3635 _setVolume(); 3636 3637 /* setup classes */ 3638 _setupMedia(function(){ 3639 3640 if(isOldAndroid) { 3641 //cfg.vast = iOSVersion >= 10 ? cfg.vast || false; 3642 cfg.ads = false; 3643 } 3644 if(isIEMobile) { 3645 cfg.ads = cfg.vast = false; 3646 } 3647 3648 if(cfg.vast) { 3649 3650 new Vast(function(vast) { 3651 3652 video.vast = vast; 3653 3654 _setCuePoints(vast.cuePoints.filter(function(point) { 3655 return point > 0; 3656 }).map(function(point) { 3657 return point / video.videoEl.media.duration; 3658 })); 3659 3660 video.vastActive = true || vast.cuePoints.filter(function(point) { 3661 return point === 0; 3662 }).length > 0; 3663 3664 _setVolume(); 3665 3666 /* setup listeners */ 3667 _listeners(); 3668 3669 video.firstPlay = true; 3670 3671 _checkAfterAds(); 3672 3673 if(!vast.cuePoints.length) { 3674 _checkBeforeBegin(); 3675 } 3676 3677 _stats.prism("AdBlock/Nie"); 3678 3679 }, !config.adblockInfoFile ? _setupListeners : function(){ 3680 var domain = window.location.href, 3681 domain = domain.replace(/(http:\/\/|https:\/\/)|(www\.)/g, "").split("/")[0], 3682 subclass = config.classes.adblock.subclasses[domain] || config.classes.adblock.subclasses.default; 3683 3684 video.videoEl.container[0].insertAdjacentHTML('afterend', [ 3685 '<div class="'+config.classes.adblock.container+ (subclass?' '+subclass:'')+'">', 3686 '<div class="'+config.classes.adblock.inner+'">', 3687 '<div class="'+config.classes.adblock.inner2+'">', 3688 '<p class="'+config.classes.adblock.header+'">Wyłącz oprogramowanie do blokowania reklam, aby obejrzeć ten materiał</p>', 3689 '<p class="'+config.classes.adblock.info+'">Dzięki reklamom wszystkie nasze materiały możesz oglądać za darmo. <a href="'+config.adblockInfoFile+'" class="'+config.classes.adblock.color+'">Sprawdź jak wyłączyć blokowanie reklam</a></p>', 3690 '<a href="javascript:window.location.reload(true)" class="'+config.classes.adblock.button+'">
3690Spróbuj ponownie<span class="'+config.classes.adblock.arrow+'"></span></a>', 3691 '<p class="'+config.classes.adblock.info, config.classes.adblock.info2+'">Nie używasz oprogramowania do blokowania reklam, lecz nadal nie możesz odtworzyć materiału? Sprawdź połączenie z Internetem i spróbuj ponownie</p>', 3692 '</div>', 3693 '</div>', 3694 '</div>' 3695 ].join("\n") 3696 ); 3697 3698 var adblock = {}; 3699 adblock.container = _getElements("." + cfg.classes.adblock.container); 3700 adblock.container_640px = cfg.classes.adblock.container_640px; 3701 adblock.container_480px = cfg.classes.adblock.container_480px; 3702 adblock.container_mob_320px = cfg.classes.adblock.container_mob_320px; 3703 adblock.container_mob = cfg.classes.adblock.container_mob; 3704 3705 function _resizeAdblock(){ 3706 var adblockContainer = $(adblock.container); 3707 var adblockContainerWidth = $(adblock.container)[0].offsetWidth; 3708 adblockContainer.removeClass(adblock.container_640px) 3709 .removeClass(adblock.container_480px) 3710 .removeClass(adblock.container_mob_320px) 3711 .removeClass(adblock.container_mob); 3712 3713 if(adblockContainerWidth>=640) adblockContainer.addClass(adblock.container_640px); 3714 else if(adblockContainerWidth>=480) adblockContainer.addClass(adblock.container_480px); 3715 else if(adblockContainerWidth>=325) adblockContainer.addClass(adblock.container_mob_320px); 3716 else adblockContainer.addClass(adblock.container_mob); 3717 } 3718 3719 _resizeAdblock(); 3720 3721 function debounce(func, wait, immediate) { 3722 var timeout; 3723 return function() { 3724 var context = this, args = arguments; 3725 var later = function() { 3726 timeout = null; 3727 if (!immediate) func.apply(context, args); 3728 }; 3729 var callNow = immediate && !timeout; 3730 clearTimeout(timeout); 3731 timeout = setTimeout(later, wait); 3732 if (callNow) func.apply(context, args); 3733 }; 3734 }; 3735 3736 $(window).on("resize", debounce(_resizeAdblock, 250)); 3737 3738 _stats.prism("AdBlock/Tak"); 3739 }); 3740 3741 } else if(cfg.ads) { 3742 3743 $.getJSON(cfg.ads, function(data, status, xhr){ 3744 3745 if(status == "success"){ 3746 3747 var ads = { "offsets" : [] }, key; 3748 3749 for(var i in data){ 3750 3751 key = data[i]["offset"]; 3752 3753 if(!ads[key]){ 3754 3755 ads[key] = { "items" : [] , "total" : 0 }; 3756 3757 } 3758 3759 ads[key]["items"].push({ 3760 "id": i, 3761 "duration" : data[i]["dur"], 3762 "offset" : data[i]["offset"], 3763 "url" : data[i]["url"], 3764 "events" : { 3765 "on_emitted" : data[i]["on_emitted"], 3766 "on_clicked" : data[i]["on_clicked"], 3767 "on_timeupdate" : data[i]["on_timeupdate"] || [] 3768 }, 3769 "src" : { 3770 "webm" : data[i]["srcreq"] && data[i]["srcreq"][0]["url"] || "", 3771 "mp4" : data[i]["srcreq"] && data[i]["srcreq"][1]["url"] || "", 3772 "mobile" : data[i]["srcreq"] && data[i]["srcreq"][2]["url"] || "" 3773 } 3774 });
3775 ads[key]["total"] += parseInt(data[i]["dur"]); 3776 3777 if(key != 0 && $.inArray(key, ads["offsets"]) === -1) ads["offsets"].push(key); 3778 3779 } 3780 3781 video.ads = ads; 3782 3783 /* setup listeners */ 3784 _listeners(); 3785 3786 /* setup listeners */ 3787 if(!video.isError) _setupAds(); 3788 3789 _checkAfterAds(); 3790 3791 if(!ads[0] && !ads["offsets"].length){ 3792 _checkBeforeBegin(); 3793 } 3794 3795 } else { 3796 _setupListeners(); 3797 } 3798 3799 }, {credentials: true}); 3800 3801 } else { 3802 3803 /* 3804 * setup listeners 3805 * skip frame - iPad 3806 */ 3807 setTimeout(_setupListeners); 3808 3809 } 3810 3811 /* callback onInit */ 3812 if(typeof cfg.onInit === "function"){ 3813 setTimeout(function(){ 3814 cfg.onInit(video, returnApi); 3815 }, 200); 3816 } 3817 3818 _log(["_init", video]); 3819 3820 }); 3821 3822 return true; 3823 3824 } 3825 3826 function Vast(success, error) { 3827 3828 var self = this, 3829 ended = false, 3830 autostart = null, 3831 firstPlay = false, 3832 isInit = false, 3833 videoContentEl = video.videoEl.media, 3834 duration = videoContentEl.duration || cfg.duration, 3835 adContainerEl, 3836 adContainer, 3837 adLoader, 3838 adRequest, 3839 adManager, 3840 AD, 3841 ADisPaused, 3842 interval, 3843 errorTimeout, 3844 _ = { 3845 leftAdsDuration: 0, 3846 name: null, 3847 size: 0, 3848 offset: 0 3849 }; 3850 3851 function initUI() { 3852 adContainerEl = document.createElement('div'); 3853 adContainerEl.className = cfg.classes.vast.container; 3854 video.videoEl.container[0].appendChild(adContainerEl); 3855 3856 video.container.addClass(cfg.classes.state.vast); 3857 } 3858 3859 function destroyUI() { 3860 video.videoEl.container[0].removeChild(adContainerEl); 3861 video.container.removeClass(cfg.classes.state.vast); 3862 _clearCuePoints(); 3863 } 3864 3865 function destroy() { 3866 adManager && adManager.destroy(); 3867 adContainer && adContainer.destroy(); 3868 destroyUI(); 3869 } 3870 3871 function initIMA(vast) { 3872 autostart = video.init.autoplay; 3873 ended = false; 3874 3875 // clean up 3876 adContainer && destroy(); 3877 3878 initUI(); 3879 3880 google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED); 3881 google.ima.settings.setLocale('pl'); 3882 3883 adContainer = new google.ima.AdDisplayContainer(adContainerEl, videoContentEl); 3884 3885 adLoader = new google.ima.AdsLoader(adContainer); 3886 3887 adRequest = new google.ima.AdsRequest(); 3888 adRequest.adsResponse = vast; 3889 3890 adLoader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, function(e) { 3891 _log(['VAST :: adLoader: ' + e.getError()], 'error'); 3892 destroy(); 3893 error(e); 3894 }, false); 3895 3896 adLoader.addEventListener(google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, function(event) { 3897 success(initManager(event)); 3898 }, false); 3899 3900 function request(opts) { 3901 if(opts) { 3902 adRequest.setAdWillAutoPlay(opts.autoplayAllowed); 3903 adRequest.setAdWillPlayMuted(opts.autoplayRequiresMuted); 3904 } 3905 3906 adLoader.requestAds(adRequest); 3907 } 3908 3909 if(autostart) { 3910 checkIfCanAutoplay(request); 3911 } else { 3912 request(); 3913 } 3914 } 3915 3916 function initManager(event) { 3917 var adsRenderingSettings = new google.ima.AdsRenderingSettings(); 3918 adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; 3919 3920 adManager = event.getAdsManager(videoContentEl, adsRenderingSettings); 3921 3922 setListeners(adManager); 3923 setVolumeState(true); 3924 3925 self.cuePoints = adManager.getCuePoints(); 3926 3927 return self; 3928 } 3929 3930 function startRemainingTime() { 3931 interval = setInterval(function() { 3932 if(AD) { 3933 var remaining = adManager.getRemainingTime(), 3934 timeLeft = _.leftAdsDuration + remaining; 3935 3936 _vastTimeUpdate(timeLeft); 3937 } 3938 }, 300); 3939 } 3940 3941 function stopRemainingTime() { 3942 clearInterval(interval); 3943 } 3944 3945 function setVolumeState(init) { 3946 if(!init && autostart && !firstPlay) { 3947 return; 3948 } 3949 3950 adManager && adManager.setVolume( 3951 video.videoEl.media.muted 3952 ? 0 3953 : video.videoEl.media.volume 3954 ); 3955 } 3956 3957 function setListeners(manager) { 3958 3959 if(isiPhone) { 3960 video.videoEl.media.addEventListener('webkitendfullscreen', function() { 3961 var fs = document.fullScreenElement || document.webkitIsFullScreen == true || document.mozFullScreen || document.msFullscreenElement; 3962 if(!fs) { 3963 video.container.off('touchstart.iosFs').on('touchstart.iosFs', function() { 3964 video.videoEl.media.webkitEnterFullscreen(); 3965 });
3966 } 3967 }, false); 3968 } 3969 3970 manager.addEventListener(google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, function(event) { 3971 video.vastActive = false; 3972 _toggleAds(false); 3973 3974 if(_.name) { 3975 _stats.prism(_.name + "Roll_KoniecBloku", _.size, _.current - 1); 3976 if(_.name !== "Pre") _stats.redevents("end " + _.name.toLowerCase() + "Roll"); 3977 } 3978 3979 if(!video.videoEl.media.ended) { 3980 _play(); 3981 _checkPlaying(); 3982 } 3983 3984 stopRemainingTime(); 3985 }); 3986 3987 manager.addEventListener(google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, function(event) { 3988 AD = event.getAd(); 3989 var pod = AD.getAdPodInfo(), 3990 offset = pod.getTimeOffset(), 3991 adType = function() { 3992 switch(offset) { 3993 case -1: 3994 return "Post"; 3995 case 0: 3996 return "Pre"; 3997 default: 3998 return "Mid" 3999 } 4000 }(); 4001 4002 _.id = AD.getAdId(); 4003 _.leftAdsDuration = pod.getMaxDuration(); 4004 _.duration = AD.getDuration(); 4005 _.name = adType; 4006 _.size = pod.getTotalAds(); 4007 _.offset = offset === -1 ? duration : offset; 4008 _.current = 1; 4009 4010 if(offset > 0) { 4011 videoContentEl.pause(); 4012 _clearCuePoints(_.offset); 4013 _stats.player("break"); 4014 } 4015 4016 _toggleAds(true); 4017 _checkPlaying(); 4018 video.vastActive = true; 4019 4020 _stats.prism(_.name + "Roll_StartBloku", _.size, _.current); 4021 _stats.redevents("begin " + _.name.toLowerCase() + "Roll"); 4022 }); 4023 4024 manager.addEventListener(google.ima.AdEvent.Type.CLICK, function(event) { 4025 video.vastIsIMAClicked = true; 4026 }); 4027 4028 manager.addEventListener(google.ima.AdEvent.Type.STARTED, function(event) { 4029 4030 firstPlay = true; 4031 ADisPaused = false; 4032 AD = event.getAd(); 4033 var pod = AD.getAdPodInfo(), 4034 offset = pod.getTimeOffset(); 4035 4036 _.id = AD.getAdId(); 4037 _.duration = AD.getDuration(); 4038 _.leftAdsDuration = _.leftAdsDuration - _.duration; 4039 4040 setVolumeState(); 4041 startRemainingTime(); 4042 _focusChange(); 4043 4044 _stats.prism(_.name + "Roll", _.size, _.current++); 4045 _stats.player("newAd", {id: _.id, duration: _.duration}, _.offset); 4046 _stats.player("play", {id: _.id, duration: _.duration}, _.offset); 4047 4048 if(isiPhone && video.videoEl.media.poster) { 4049 video.videoEl.media.removeAttribute('poster'); 4050 } 4051 }); 4052 4053 manager.addEventListener(google.ima.AdEvent.Type.PAUSED, function(e) { 4054 4055 ADisPaused = true; 4056 _checkPlaying(); 4057 4058 _stats.prism("Pauza", _.size, _.current - 1); 4059 _stats.player("pause", {id: _.id, duration: _.duration}, _.offset); 4060 }); 4061 4062 manager.addEventListener(google.ima.AdEvent.Type.COMPLETE, function(e) { 4063 stopRemainingTime(); 4064 4065 _stats.player("complete", {id: _.id, duration: _.duration}, _.offset); 4066 }); 4067 4068 manager.addEventListener(google.ima.AdEvent.Type.RESUMED, function(e) { 4069 ADisPaused = false; 4070 _checkPlaying(); 4071 4072 _stats.prism("Start", _.size, _.current - 1); 4073 _stats.player("play", {id: _.id, duration: _.duration}, _.offset); 4074 }); 4075 4076 // manager.addEventListener(google.ima.AdEvent.Type.VOLUME_CHANGED, function(t) { 4077 // currentTime: _.offset, 4078 // volume: manager.getVolume() 4079 // }); 4080 4081 manager.addEventListener(google.ima.AdEvent.Type.ALL_ADS_COMPLETED, function(e) { 4082 ended = true; 4083 _clearCuePoints(); 4084 }); 4085 4086 manager.addEventListener(google.ima.AdEvent.Type.CLICK, function() { 4087 manager.pause(); 4088 }); 4089 4090 manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, function(e) { 4091 _log(['VAST :: adManager: ' + e.getError()], 'error'); 4092 destroy(); 4093 _toggleAds(false); 4094 video.vastActive = false; 4095 video.vast = null; 4096 _pause(); 4097 _checkPlaying(); 4098 }); 4099 } 4100 4101 function loadIMAScript(success, error) { 4102 function onSuccess() { 4103 loadVAST(success, error); 4104 } 4105 function onError(e) { 4106 ended = true; 4107 error && error(); 4108 } 4109 DOM.load('//imasdk.googleapis.com/js/sdkloader/ima3.js', onSuccess, onError); 4110 } 4111 4112 function loadVAST(success, error) { 4113 DOM.xhr({ 4114 url: cfg.vast, 4115 credentials: true, 4116 onload: function(_, xhr) { 4117 function _init() { 4118 clearTimeout(errorTimeout); 4119 success(createVMAP(xhr.responseXML, xhr.responseText)); 4120 } 4121 4122 duration = videoContentEl.duration || cfg.duration; 4123 4124 if(duration) { 4125 _init(); 4126 } else { 4127 $(videoContentEl).one('loadedmetadata.vast', _init); 4128 errorTimeout = setTimeout(function() { 4129 $(videoContentEl).off('loadedmetadata.vast'); 4130 _init(); 4131 _log('VAST :: loadVast > timeout', 'error'); 4132 }, 5000); 4133 } 4134 }, 4135 onerror: error 4136 }) 4137 } 4138 4139 function createVMAP(xml, text) { 4140 if(xml && xml.firstChild.tagName !== 'VAST') { 4141 return text; 4142 } 4143 4144 var vast = $(xml).find('VAST'), 4145 ads = vast.find('Ad'); 4146 4147 function _wraper(ads) { 4148 return '<vmap:VMAP xmlns:vmap="http://www.iab.net/videosuite/vmap" version="1.0">' + ads + '</vmap:VMAP>'; 4149 } 4150 function _adbreak(ads) { 4151 return ads.map(function(ad) { 4152 return [ 4153 '<vmap:AdBreak timeOffset="' + ad.offset + '" breakType="linear">', 4154 ' <vmap:AdSource allowMultipleAds="true" followRedirects="true">', 4155 ' <vmap:VASTAdData>', 4156 ' <VAST version="3.0">' + ad.data + '</VAST>', 4157 ' </vmap:VASTAdData>', 4158 ' </vmap:AdSource>', 4159 '</vmap:AdBreak>' 4160 ].join("\n"); 4161 }).join("\n"); 4162 } 4163 4164 function _pad(x) { 4165 return (x < 10 ? "0" : "") + x; 4166 } 4167 function _getOffset(ad) { 4168 var offset = (ad.attributes.offset || {value: '0%'}).value; 4169 switch(offset) { 4170 case '0%': 4171 return 'start'; 4172 case '100%': 4173 return 'end'; 4174 default: 4175 var floatOffset = duration * (parseInt(offset) / 100); 4176 4177 if(!duration) { 4178 return 'skip'; 4179 } 4180 4181 var s = floatOffset % 60, 4182 m = Math.floor(floatOffset / 60),
4183 h = Math.floor(floatOffset / 3600); 4184 4185 return _pad(h) + ':' + _pad(m) + ':' + _pad(s.toFixed(3)); 4186 } 4187 } 4188 function _offset(ad) { 4189 switch((ad.attributes.block || {}).value) { 4190 case '0': 4191 return 'start'; 4192 case '1': 4193 return 'end'; 4194 default: 4195 return _getOffset(ad); 4196 } 4197 } 4198 function _findAdBreakByOffset(breaks, offset) { 4199 for(var i = 0, block; block = breaks[i]; i++) { 4200 if(block.offset === offset) return i; 4201 } 4202 4203 return -1; 4204 } 4205 function _ads(ads) { 4206 var breaks = []; 4207 4208 if('XMLSerializer' in window) { 4209 var XMLS = new XMLSerializer(); 4210 4211 for(var i = 0, ad; ad = ads[i++]; ) { 4212 var offset = _offset(ad); 4213 4214 if(offset == 'skip') continue; 4215 4216 var _id = _findAdBreakByOffset(breaks, offset), 4217 id = _id !== -1 ? _id : breaks.length, 4218 html = XMLS.serializeToString(ad); 4219 4220 if(breaks[id]) { 4221 breaks[id].data += html; 4222 } else { 4223 breaks.push({ 4224 offset: offset, 4225 data: html 4226 });
4227 } 4228 } 4229 } 4230 4231 return breaks; 4232 } 4233 4234 return _wraper(_adbreak(_ads(ads))); 4235 } 4236 4237 function init() { 4238 loadIMAScript(initIMA, error); 4239 } 4240 4241 init(); 4242 4243 this.pause = function() { 4244 adManager && adManager.pause(); 4245 } 4246 4247 this.resume = function() { 4248 if(adManager) { 4249 if(ADisPaused) { 4250 adManager.resume(); 4251 } else if (!isInit) { 4252 videoContentEl.load(); 4253 adContainer.initialize(); 4254 4255 try { 4256 adManager.init('100%', '100%', google.ima.ViewMode.NORMAL); 4257 adManager.start(); 4258 isInit = true; 4259 } catch(e) { 4260 videoContentEl.play(); 4261 } 4262 } 4263 } 4264 } 4265 4266 this.setVolumeState = setVolumeState; 4267 4268 this.isPaused = function() { 4269 return ADisPaused; 4270 } 4271 4272 this.contentComplete = function(callback) { 4273 if(ended) { 4274 callback(); 4275 } else if(adManager) { 4276 var cb = function cbt() { 4277 ended = true; 4278 adManager.removeEventListener(google.ima.AdEvent.Type.ALL_ADS_COMPLETED, cbt); 4279 callback(); 4280 }; 4281 adLoader.contentComplete(); 4282 adManager.addEventListener(google.ima.AdEvent.Type.ALL_ADS_COMPLETED, cb); 4283 } else { 4284 callback(); 4285 } 4286 } 4287 } 4288 4289 if(!_init()){ 4290 return false; 4291 } 4292 4293 var returnApi = { 4294 media: video.media, 4295 isAds: _isAds, 4296 isPaused: _isPaused, 4297 shouldPlay: _shouldPlay, 4298 instance: _instance, 4299 play: _play, 4300 pause: _pause, 4301 toggle: _toggle, 4302 seek: _progSeek, 4303 volume: _setVolume, 4304 toggleMute: _toggleMute, 4305 toggleFullscreen: _toggleFullscreen 4306 }; 4307 4308 return returnApi; 4309 4310 } 4311 4312 4313 /** 4314 * Check if supported 4315 * @return {Object} 4316 * - range: input[type=range] 4317 * - video: video.canPlayType 4318 * - fullscreen: requestFullscreen 4319 * - storage: localStorage 4320 */ 4321 api.supported = function(){ 4322 4323 var range = (function(){ 4324 var i = document.createElement("input"); 4325 i.setAttribute("type", "range"); 4326 return i.type !== "text"; 4327 })(), 4328 progress = (document.createElement('progress').max !== undefined), 4329 video = !!document.createElement("video").canPlayType, 4330 volume = (function(){ 4331 /* test for iOS which cannot set volume */ 4332 var a = document.createElement('audio'); 4333 a.volume = .5; 4334 return (a.volume == .5); 4335 })(), 4336 fullscreen = (document.fullscreenEnabled || 4337 document.webkitFullscreenEnabled || 4338 document.msFullscreenEnabled || 4339 document.mozFullScreenEnabled) && (function(){ 4340 var d = document.createElement("div"); 4341 return ("requestFullscreen" in d 4342 || "msRequestFullscreen" in d 4343 || "mozRequestFullScreen" in d 4344 || "webkitRequestFullScreen" in d); 4345 })(), 4346 storage = (function(){ 4347 try{ 4348 if("localStorage" in window && window.localStorage != null){ 4349 window.localStorage.setItem('localStorage', 1); 4350 window.localStorage.removeItem('localStorage'); 4351 return true; 4352 } 4353 else return false; 4354 } 4355 catch(e){return false;} 4356 })(), 4357 animation = (function(){ 4358 var animation = false, 4359 animationstring = 'animation', 4360 keyframeprefix = '', 4361 domPrefixes = 'Webkit Moz O ms Khtml'.split(' '), 4362 pfx = '', 4363 elm = document.createElement('div'); 4364 4365 if( elm.style.animationName !== undefined ) { animation = true; } 4366 4367 if( animation === false ) { 4368 for( var i = 0; i < domPrefixes.length; i++ ) { 4369 if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) { 4370 pfx = domPrefixes[ i ]; 4371 animationstring = pfx + 'Animation'; 4372 keyframeprefix = '-' + pfx.toLowerCase() + '-'; 4373 animation = true; 4374 break; 4375 } 4376 } 4377 } 4378 4379 return animation; 4380 })(); 4381 4382 return { 4383 video: video, 4384 range: (range && progress && !isOpera), 4385 volume: volume, 4386 fullscreen: fullscreen, 4387 storage: storage, 4388 animation: animation 4389 }; 4390 4391 } 4392 4393 /** 4394 * Init videoPlayer 4395 * @param {Object} options 4396 * @return {Object} videoPlayer 4397 */ 4398 api.init = function(options){ 4399 4400 config = $.extend(config, $.extend(defaults, $.extend(options, api.config))); 4401 4402 if(!config.enabled){ 4403 return false; 4404 } 4405 4406 var elements = $(config.selector), 4407 videos = []; 4408 4409 for(var i = 0, l = elements.length; i < l; i++){ 4410 4411 var el = elements[i]; 4412 4413 if(typeof el.videoPlayer === "undefined"){ 4414 /* 4415 * if vp == true 4416 * means videoPlayer successfully init, 4417 * means video has parentNode 4418 * so return API to this parentNode 4419 * else 4420 * return false to el 4421 */ 4422 4423 var vp = new VideoPlayer(el); 4424 el = vp ? vp.media.parentNode.parentNode : el; 4425 el.videoPlayer = vp; 4426 api.els.push(vp); 4427 } 4428 4429 videos.push(el.videoPlayer); 4430 4431 } 4432 4433 return videos; 4434 4435 } 4436 4437 api.version = 2.4; 4438 4439 /* array of videoPlayers on current page */ 4440 api.els = api.els || []; 4441 4442 4443 var returnEl = []; 4444 for(var i = 0, l = (api.buffer || []).length; i < l; i++){ 4445 returnEl.push(api.init(api.buffer[i])); 4446 } 4447 4448 delete api.buffer; 4449 4450 return returnEl; 4451 4452}(this.videoPlayer = this.videoPlayer || {}, DOM, window, document));
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.