vendor: 4,340 bytes, lines 1-66
1/** 2 * @license 3 * Video.js 5.19.2 <http://videojs.com/> 4 * Copyright Brightcove, Inc. <https://www.brightcove.com/> 5 * Available under Apache License Version 2.0 6 * <https://github.com/videojs/video.js/blob/master/LICENSE> 7 * 8 * Includes vtt.js <https://github.com/mozilla/vtt.js> 9 * Available under Apache License Version 2.0 10 * <https://github.com/mozilla/vtt.js/blob/master/LICENSE> 11 */ 12 13(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.videojs = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ 14'use strict'; 15 16exports.__esModule = true; 17 18var _button = _dereq_(2); 19 20var _button2 = _interopRequireDefault(_button); 21 22var _component = _dereq_(5); 23 24var _component2 = _interopRequireDefault(_component); 25 26function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 27 28function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 29 30function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 31 32function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 33 * @file big-play-button.js 34 */ 35 36 37/** 38 * The initial play button that shows before the video has played. The hiding of the 39 * `BigPlayButton` get done via CSS and `Player` states. 40 * 41 * @extends Button 42 */ 43var BigPlayButton = function (_Button) { 44 _inherits(BigPlayButton, _Button); 45 46 function BigPlayButton() { 47 _classCallCheck(this, BigPlayButton); 48 49 return _possibleConstructorReturn(this, _Button.apply(this, arguments)); 50 } 51 52 /** 53 * Builds the default DOM `className`. 54 * 55 * @return {string} 56 * The DOM `className` for this object. Always returns 'vjs-big-play-button'. 57 */ 58 BigPlayButton.prototype.buildCSSClass = function buildCSSClass() { 59 return 'vjs-big-play-button'; 60 }; 61 62 /** 63 * This gets called when a `BigPlayButton` "clicked". See {@link ClickableComponent} 64 * for more detailed information on what a click can be. 65 * 66 * @param {EventTarget~Event} event
67 * The `keydown`, `tap`, or `click` event that caused this function to be 68 * called. 69 * 70 * @listens tap 71 * @listens click 72 */ 73 74 75 BigPlayButton.prototype.handleClick = function handleClick(event) { 76 this.player_.play(); 77 78 var cb = this.player_.getChild('controlBar'); 79 var playToggle = cb && cb.getChild('playToggle'); 80 81 if (!playToggle) { 82 this.player_.focus(); 83 return; 84 } 85 86 this.setTimeout(function () { 87 playToggle.focus(); 88 }, 1); 89 }; 90 91 return BigPlayButton; 92}(_button2['default']); 93 94/** 95 * The text that should display over the `BigPlayButton`s controls. Added to for localization. 96 * 97 * @type {string} 98 * @private 99 */ 100 101 102BigPlayButton.prototype.controlText_ = 'Play Video'; 103 104_component2['default'].registerComponent('BigPlayButton', BigPlayButton); 105exports['default'] = BigPlayButton; 106 107},{"2":2,"5":5}],2:[function(_dereq_,module,exports){ 108'use strict'; 109 110exports.__esModule = true; 111 112var _clickableComponent = _dereq_(3); 113 114var _clickableComponent2 = _interopRequireDefault(_clickableComponent); 115 116var _component = _dereq_(5); 117 118var _component2 = _interopRequireDefault(_component); 119 120var _log = _dereq_(86); 121 122var _log2 = _interopRequireDefault(_log); 123 124var _obj = _dereq_(88); 125 126function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 127 128function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 129 130function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 131 132function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 133 * @file button.js 134 */ 135 136 137/** 138 * Base class for all buttons. 139 * 140 * @extends ClickableComponent 141 */ 142var Button = function (_ClickableComponent) { 143 _inherits(Button, _ClickableComponent); 144 145 function Button() { 146 _classCallCheck(this, Button); 147 148 return _possibleConstructorReturn(this, _ClickableComponent.apply(this, arguments)); 149 } 150 151 /** 152 * Create the `Button`s DOM element. 153 * 154 * @param {string} [tag=button] 155 * Element's node type. e.g. 'button' 156 * 157 * @param {Object} [props={}] 158 * An object of properties that should be set on the element. 159 * 160 * @param {Object} [attributes={}] 161 * An object of attributes that should be set on the element. 162 * 163 * @return {Element} 164 * The element that gets created. 165 */ 166 Button.prototype.createEl = function createEl() { 167 var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'button'; 168 var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 169 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 170 171 props = (0, _obj.assign)({ 172 className: this.buildCSSClass() 173 }, props); 174 175 if (tag !== 'button') { 176 _log2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.'); 177 178 // Add properties for clickable element which is not a native HTML button 179 props = (0, _obj.assign)({ 180 tabIndex: 0 181 }, props); 182 183 // Add ARIA attributes for clickable element which is not a native HTML button 184 attributes = (0, _obj.assign)({ 185 role: 'button' 186 }, attributes); 187 } 188 189 // Add attributes for button element 190 attributes = (0, _obj.assign)({ 191 192 // Necessary since the default button type is "submit" 193 'type': 'button', 194 195 // let the screen reader user know that the text of the button may change 196 'aria-live': 'polite' 197 }, attributes); 198 199 var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes); 200 201 this.createControlTextEl(el); 202 203 return el; 204 }; 205 206 /** 207 * Add a child `Component` inside of this `Button`. 208 * 209 * @param {string|Component} child 210 * The name or instance of a child to add. 211 * 212 * @param {Object} [options={}] 213 * The key/value store of options that will get passed to children of 214 * the child. 215 * 216 * @return {Component} 217 * The `Component` that gets added as a child. When using a string the 218 * `Component` will get created by this process. 219 * 220 * @deprecated since version 5 221 */ 222 223 224 Button.prototype.addChild = function addChild(child) { 225 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 226 227 var className = this.constructor.name; 228 229 _log2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.'); 230 231 // Avoid the error message generated by ClickableComponent's addChild method 232 return _component2['default'].prototype.addChild.call(this, child, options); 233 }; 234 235 /** 236 * Enable the `Button` element so that it can be activated or clicked. Use this with 237 * {@link Button#disable}. 238 */ 239 240 241 Button.prototype.enable = function enable() { 242 _ClickableComponent.prototype.enable.call(this); 243 this.el_.removeAttribute('disabled'); 244 }; 245 246 /** 247 * Enable the `Button` element so that it cannot be activated or clicked. Use this with 248 * {@link Button#enable}. 249 */ 250 251 252 Button.prototype.disable = function disable() { 253 _ClickableComponent.prototype.disable.call(this); 254 this.el_.setAttribute('disabled', 'disabled'); 255 }; 256 257 /** 258 * This gets called when a `Button` has focus and `keydown` is triggered via a key 259 * press. 260 * 261 * @param {EventTarget~Event} event 262 * The event that caused this function to get called. 263 * 264 * @listens keydown 265 */ 266 267 268 Button.prototype.handleKeyPress = function handleKeyPress(event) { 269 270 // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button. 271 if (event.which === 32 || event.which === 13) { 272 return; 273 } 274 275 // Pass keypress handling up for unsupported keys 276 _ClickableComponent.prototype.handleKeyPress.call(this, event); 277 }; 278 279 return Button; 280}(_clickableComponent2['default']); 281 282_component2['default'].registerComponent('Button', Button); 283exports['default'] = Button; 284 285},{"3":3,"5":5,"86":86,"88":88}],3:[function(_dereq_,module,exports){ 286'use strict'; 287 288exports.__esModule = true; 289 290var _component = _dereq_(5); 291 292var _component2 = _interopRequireDefault(_component); 293 294var _dom = _dereq_(81); 295 296var Dom = _interopRequireWildcard(_dom); 297 298var _events = _dereq_(82); 299 300var Events = _interopRequireWildcard(_events); 301 302var _fn = _dereq_(83); 303 304var Fn = _interopRequireWildcard(_fn); 305 306var _log = _dereq_(86); 307 308var _log2 = _interopRequireDefault(_log); 309 310var _document = _dereq_(94); 311 312var _document2 = _interopRequireDefault(_document); 313 314var _obj = _dereq_(88); 315 316function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 317 318function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 319 320function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 321 322function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 323 324function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
324onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 325 * @file button.js 326 */ 327 328 329/** 330 * Clickable Component which is clickable or keyboard actionable, 331 * but is not a native HTML button. 332 * 333 * @extends Component 334 */ 335var ClickableComponent = function (_Component) { 336 _inherits(ClickableComponent, _Component); 337 338 /** 339 * Creates an instance of this class. 340 * 341 * @param {Player} player 342 * The `Player` that this class should be attached to. 343 * 344 * @param {Object} [options] 345 * The key/value store of player options. 346 */ 347 function ClickableComponent(player, options) { 348 _classCallCheck(this, ClickableComponent); 349 350 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 351 352 _this.emitTapEvents(); 353 354 _this.enable(); 355 return _this; 356 } 357 358 /** 359 * Create the `Component`s DOM element. 360 * 361 * @param {string} [tag=div] 362 * The element's node type. 363 * 364 * @param {Object} [props={}] 365 * An object of properties that should be set on the element. 366 * 367 * @param {Object} [attributes={}] 368 * An object of attributes that should be set on the element. 369 * 370 * @return {Element} 371 * The element that gets created. 372 */ 373 374 375 ClickableComponent.prototype.createEl = function createEl() { 376 var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div'; 377 var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 378 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 379 380 props = (0, _obj.assign)({ 381 className: this.buildCSSClass(), 382 tabIndex: 0 383 }, props); 384 385 if (tag === 'button') { 386 _log2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.'); 387 } 388 389 // Add ARIA attributes for clickable element which is not a native HTML button 390 attributes = (0, _obj.assign)({ 391 'role': 'button', 392 393 // let the screen reader user know that the text of the element may change 394 'aria-live': 'polite' 395 }, attributes); 396 397 this.tabIndex_ = props.tabIndex; 398 399 var el = _Component.prototype.createEl.call(this, tag, props, attributes); 400 401 this.createControlTextEl(el); 402 403 return el; 404 }; 405 406 /** 407 * Create a control text element on this `Component` 408 * 409 * @param {Element} [el] 410 * Parent element for the control text. 411 * 412 * @return {Element} 413 * The control text element that gets created. 414 */ 415 416 417 ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) { 418 this.controlTextEl_ = Dom.createEl('span', { 419 className: 'vjs-control-text' 420 }); 421 422 if (el) { 423 el.appendChild(this.controlTextEl_); 424 } 425 426 this.controlText(this.controlText_, el); 427 428 return this.controlTextEl_; 429 }; 430 431 /** 432 * Get or set the localize text to use for the controls on the `Component`. 433 * 434 * @param {string} [text] 435 * Control text for element. 436 * 437 * @param {Element} [el=this.el()] 438 * Element to set the title on. 439 * 440 * @return {string|ClickableComponent} 441 * - The control text when getting 442 * - Returns itself when setting; method can be chained. 443 */ 444 445 446 ClickableComponent.prototype.controlText = function controlText(text) { 447 var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.el(); 448 449 if (!text) { 450 return this.controlText_ || 'Need Text'; 451 } 452 453 var localizedText = this.localize(text); 454 455 this.controlText_ = text; 456 this.controlTextEl_.innerHTML = localizedText; 457 458 if (!this.nonIconControl) { 459 // Set title attribute if only an icon is shown 460 el.setAttribute('title', localizedText); 461 } 462 463 return this; 464 }; 465 466 /** 467 * Builds the default DOM `className`. 468 * 469 * @return {string} 470 * The DOM `className` for this object. 471 */ 472 473 474 ClickableComponent.prototype.buildCSSClass = function buildCSSClass() { 475 return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this); 476 }; 477 478 /** 479 * Enable this `Component`s element. 480 * 481 * @return {ClickableComponent} 482 * Returns itself; method can be chained. 483 */ 484 485 486 ClickableComponent.prototype.enable = function enable() { 487 this.removeClass('vjs-disabled'); 488 this.el_.setAttribute('aria-disabled', 'false'); 489 if (typeof this.tabIndex_ !== 'undefined') { 490 this.el_.setAttribute('tabIndex', this.tabIndex_); 491 } 492 this.on('tap', this.handleClick); 493 this.on('click', this.handleClick); 494 this.on('focus', this.handleFocus); 495 this.on('blur', this.handleBlur); 496 return this; 497 }; 498 499 /** 500 * Disable this `Component`s element. 501 * 502 * @return {ClickableComponent} 503 * Returns itself; method can be chained. 504 */ 505 506 507 ClickableComponent.prototype.disable = function disable() { 508 this.addClass('vjs-disabled'); 509 this.el_.setAttribute('aria-disabled', 'true'); 510 if (typeof this.tabIndex_ !== 'undefined') { 511 this.el_.removeAttribute('tabIndex'); 512 } 513 this.off('tap', this.handleClick); 514 this.off('click', this.handleClick); 515 this.off('focus', this.handleFocus); 516 this.off('blur', this.handleBlur); 517 return this; 518 }; 519 520 /** 521 * This gets called when a `ClickableComponent` gets: 522 * - Clicked (via the `click` event, listening starts in the constructor) 523 * - Tapped (via the `tap` event, listening starts in the constructor) 524 * - The following things happen in order: 525 * 1. {@link ClickableComponent#handleFocus} is called via a `focus` event on the 526 * `ClickableComponent`. 527 * 2. {@link ClickableComponent#handleFocus} adds a listener for `keydown` on using 528 * {@link ClickableComponent#handleKeyPress}. 529 * 3. `ClickableComponent` has not had a `blur` event (`blur` means that focus was lost). The user presses 530 * the space or enter key. 531 * 4. {@link ClickableComponent#handleKeyPress} calls this function with the `keydown` 532 * event as a parameter. 533 * 534 * @param {EventTarget~Event} event
535 * The `keydown`, `tap`, or `click` event that caused this function to be 536 * called. 537 * 538 * @listens tap 539 * @listens click 540 * @abstract 541 */ 542 543 544 ClickableComponent.prototype.handleClick = function handleClick(event) {}; 545 546 /** 547 * This gets called when a `ClickableComponent` gains focus via a `focus` event. 548 * Turns on listening for `keydown` events. When they happen it 549 * calls `this.handleKeyPress`. 550 * 551 * @param {EventTarget~Event} event 552 * The `focus` event that caused this function to be called. 553 * 554 * @listens focus 555 */ 556 557 558 ClickableComponent.prototype.handleFocus = function handleFocus(event) { 559 Events.on(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); 560 }; 561 562 /** 563 * Called when this ClickableComponent has focus and a key gets pressed down. By 564 * default it will call `this.handleClick` when the key is space or enter. 565 * 566 * @param {EventTarget~Event} event 567 * The `keydown` event that caused this function to be called. 568 * 569 * @listens keydown 570 */ 571 572 573 ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) { 574 575 // Support Space (32) or Enter (13) key operation to fire a click event 576 if (event.which === 32 || event.which === 13) { 577 event.preventDefault(); 578 this.handleClick(event); 579 } else if (_Component.prototype.handleKeyPress) { 580 581 // Pass keypress handling up for unsupported keys 582 _Component.prototype.handleKeyPress.call(this, event); 583 } 584 }; 585 586 /** 587 * Called when a `ClickableComponent` loses focus. Turns off the listener for 588 * `keydown` events. Which Stops `this.handleKeyPress` from getting called. 589 * 590 * @param {EventTarget~Event} event 591 * The `blur` event that caused this function to be called. 592 * 593 * @listens blur 594 */ 595 596 597 ClickableComponent.prototype.handleBlur = function handleBlur(event) { 598 Events.off(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); 599 }; 600 601 return ClickableComponent; 602}(_component2['default']); 603 604_component2['default'].registerComponent('ClickableComponent', ClickableComponent); 605exports['default'] = ClickableComponent; 606 607},{"5":5,"81":81,"82":82,"83":83,"86":86,"88":88,"94":94}],4:[function(_dereq_,module,exports){ 608'use strict'; 609 610exports.__esModule = true; 611 612var _button = _dereq_(2); 613 614var _button2 = _interopRequireDefault(_button); 615 616var _component = _dereq_(5); 617 618var _component2 = _interopRequireDefault(_component); 619 620function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 621 622function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 623 624function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 625 626function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 627 * @file close-button.js 628 */ 629 630 631/** 632 * The `CloseButton` is a `{@link Button}` that fires a `close` event when 633 * it gets clicked. 634 * 635 * @extends Button 636 */ 637var CloseButton = function (_Button) { 638 _inherits(CloseButton, _Button); 639 640 /** 641 * Creates an instance of the this class. 642 * 643 * @param {Player} player 644 * The `Player` that this class should be attached to. 645 * 646 * @param {Object} [options] 647 * The key/value store of player options. 648 */ 649 function CloseButton(player, options) { 650 _classCallCheck(this, CloseButton); 651 652 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options)); 653 654 _this.controlText(options && options.controlText || _this.localize('Close')); 655 return _this; 656 } 657 658 /** 659 * Builds the default DOM `className`. 660 * 661 * @return {string} 662 * The DOM `className` for this object. 663 */ 664 665 666 CloseButton.prototype.buildCSSClass = function buildCSSClass() { 667 return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this); 668 }; 669 670 /** 671 * This gets called when a `CloseButton` gets clicked. See 672 * {@link ClickableComponent#handleClick} for more information on when this will be 673 * triggered 674 * 675 * @param {EventTarget~Event} event
676 * The `keydown`, `tap`, or `click` event that caused this function to be 677 * called. 678 * 679 * @listens tap 680 * @listens click 681 * @fires CloseButton#close 682 */ 683 684 685 CloseButton.prototype.handleClick = function handleClick(event) { 686 687 /** 688 * Triggered when the a `CloseButton` is clicked. 689 * 690 * @event CloseButton#close 691 * @type {EventTarget~Event} 692 * 693 * @property {boolean} [bubbles=false] 694 * set to false so that the close event does not 695 * bubble up to parents if there is no listener 696 */ 697 this.trigger({ type: 'close', bubbles: false }); 698 }; 699 700 return CloseButton; 701}(_button2['default']); 702 703_component2['default'].registerComponent('CloseButton', CloseButton); 704exports['default'] = CloseButton; 705 706},{"2":2,"5":5}],5:[function(_dereq_,module,exports){ 707'use strict'; 708 709exports.__esModule = true; 710 711var _window = _dereq_(95); 712 713var _window2 = _interopRequireDefault(_window); 714 715var _dom = _dereq_(81); 716 717var Dom = _interopRequireWildcard(_dom); 718 719var _fn = _dereq_(83); 720 721var Fn = _interopRequireWildcard(_fn); 722 723var _guid = _dereq_(85); 724 725var Guid = _interopRequireWildcard(_guid); 726 727var _events = _dereq_(82); 728 729var Events = _interopRequireWildcard(_events); 730 731var _log = _dereq_(86); 732 733var _log2 = _interopRequireDefault(_log); 734 735var _toTitleCase = _dereq_(91); 736 737var _toTitleCase2 = _interopRequireDefault(_toTitleCase); 738 739var _mergeOptions = _dereq_(87); 740 741var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 742 743function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 744 745function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 746 747function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** 748 * Player Component - Base class for all UI objects 749 * 750 * @file component.js 751 */ 752 753 754/** 755 * Base class for all UI Components. 756 * Components are UI objects which represent both a javascript object and an element 757 * in the DOM. They can be children of other components, and can have 758 * children themselves. 759 * 760 * Components can also use methods from {@link EventTarget} 761 */ 762var Component = function () { 763 764 /** 765 * A callback that is called when a component is ready. Does not have any 766 * paramters and any callback value will be ignored. 767 * 768 * @callback Component~ReadyCallback 769 * @this Component 770 */ 771 772 /** 773 * Creates an instance of this class. 774 * 775 * @param {Player} player 776 * The `Player` that this class should be attached to. 777 * 778 * @param {Object} [options] 779 * The key/value store of player options. 780 # 781 * @param {Object[]} [options.children] 782 * An array of children objects to intialize this component with. Children objects have 783 * a name property that will be used if more than one component of the same type needs to be 784 * added. 785 * 786 * @param {Component~ReadyCallback} [ready] 787 * Function that gets called when the `Component` is ready. 788 */ 789 function Component(player, options, ready) { 790 _classCallCheck(this, Component); 791 792 // The component might be the player itself and we can't pass `this` to super 793 if (!player && this.play) { 794 this.player_ = player = this; // eslint-disable-line 795 } else { 796 this.player_ = player; 797 } 798 799 // Make a copy of prototype.options_ to protect against overriding defaults 800 this.options_ = (0, _mergeOptions2['default'])({}, this.options_); 801 802 // Updated options with supplied options 803 options = this.options_ = (0, _mergeOptions2['default'])(this.options_, options); 804 805 // Get ID from options or options element if one is supplied 806 this.id_ = options.id || options.el && options.el.id; 807 808 // If there was no ID from the options, generate one 809 if (!this.id_) { 810 // Don't require the player ID function in the case of mock players 811 var id = player && player.id && player.id() || 'no_player'; 812 813 this.id_ = id + '_component_' + Guid.newGUID(); 814 } 815 816 this.name_ = options.name || null; 817 818 // Create element if one wasn't provided in options 819 if (options.el) { 820 this.el_ = options.el; 821 } else if (options.createEl !== false) { 822 this.el_ = this.createEl(); 823 } 824 825 this.children_ = []; 826 this.childIndex_ = {}; 827 this.childNameIndex_ = {}; 828 829 // Add any child components in options 830 if (options.initChildren !== false) { 831 this.initChildren(); 832 } 833 834 this.ready(ready); 835 // Don't want to trigger ready here or it will before init is actually 836 // finished for all children that run this constructor 837 838 if (options.reportTouchActivity !== false) { 839 this.enableTouchActivity(); 840 } 841 } 842 843 /** 844 * Dispose of the `Component` and all child components. 845 * 846 * @fires Component#dispose 847 */ 848 849 850 Component.prototype.dispose = function dispose() { 851 852 /** 853 * Triggered when a `Component` is disposed. 854 * 855 * @event Component#dispose 856 * @type {EventTarget~Event} 857 * 858 * @property {boolean} [bubbles=false] 859 * set to false so that the close event does not 860 * bubble up 861 */ 862 this.trigger({ type: 'dispose', bubbles: false }); 863 864 // Dispose all children. 865 if (this.children_) { 866 for (var i = this.children_.length - 1; i >= 0; i--) { 867 if (this.children_[i].dispose) { 868 this.children_[i].dispose(); 869 } 870 } 871 } 872 873 // Delete child references 874 this.children_ = null; 875 this.childIndex_ = null; 876 this.childNameIndex_ = null; 877 878 // Remove all event listeners. 879 this.off(); 880 881 // Remove element from DOM 882 if (this.el_.parentNode) { 883 this.el_.parentNode.removeChild(this.el_); 884 } 885 886 Dom.removeElData(this.el_); 887 this.el_ = null; 888 }; 889 890 /** 891 * Return the {@link Player}
891 that the `Component` has attached to. 892 * 893 * @return {Player} 894 * The player that this `Component` has attached to. 895 */ 896 897 898 Component.prototype.player = function player() { 899 return this.player_; 900 }; 901 902 /** 903 * Deep merge of options objects with new options. 904 * > Note: When both `obj` and `options` contain properties whose values are objects. 905 * The two properties get merged using {@link module:mergeOptions} 906 * 907 * @param {Object} obj 908 * The object that contains new options. 909 * 910 * @return {Object} 911 * A new object of `this.options_` and `obj` merged together. 912 * 913 * @deprecated since version 5 914 */ 915 916 917 Component.prototype.options = function options(obj) { 918 _log2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0'); 919 920 if (!obj) { 921 return this.options_; 922 } 923 924 this.options_ = (0, _mergeOptions2['default'])(this.options_, obj); 925 return this.options_; 926 }; 927 928 /** 929 * Get the `Component`s DOM element 930 * 931 * @return {Element} 932 * The DOM element for this `Component`. 933 */ 934 935 936 Component.prototype.el = function el() { 937 return this.el_; 938 }; 939 940 /** 941 * Create the `Component`s DOM element. 942 * 943 * @param {string} [tagName] 944 * Element's DOM node type. e.g. 'div' 945 * 946 * @param {Object} [properties] 947 * An object of properties that should be set. 948 * 949 * @param {Object} [attributes] 950 * An object of attributes that should be set. 951 * 952 * @return {Element} 953 * The element that gets created. 954 */ 955 956 957 Component.prototype.createEl = function createEl(tagName, properties, attributes) { 958 return Dom.createEl(tagName, properties, attributes); 959 }; 960 961 /** 962 * Localize a string given the string in english. 963 * 964 * @param {string} string 965 * The string to localize. 966 * 967 * @return {string} 968 * The localized string or if no localization exists the english string. 969 */ 970 971 972 Component.prototype.localize = function localize(string) { 973 var code = this.player_.language && this.player_.language(); 974 var languages = this.player_.languages && this.player_.languages(); 975 976 if (!code || !languages) { 977 return string; 978 } 979 980 var language = languages[code]; 981 982 if (language && language[string]) { 983 return language[string]; 984 } 985 986 var primaryCode = code.split('-')[0]; 987 var primaryLang = languages[primaryCode]; 988 989 if (primaryLang && primaryLang[string]) { 990 return primaryLang[string]; 991 } 992 993 return string; 994 }; 995 996 /** 997 * Return the `Component`s DOM element. This is where children get inserted. 998 * This will usually be the the same as the element returned in {@link Component#el}. 999 * 1000 * @return {Element} 1001 * The content element for this `Component`. 1002 */ 1003 1004 1005 Component.prototype.contentEl = function contentEl() { 1006 return this.contentEl_ || this.el_; 1007 }; 1008 1009 /** 1010 * Get this `Component`s ID 1011 * 1012 * @return {string} 1013 * The id of this `Component` 1014 */ 1015 1016 1017 Component.prototype.id = function id() { 1018 return this.id_; 1019 }; 1020 1021 /** 1022 * Get the `Component`s name. The name gets used to reference the `Component` 1023 * and is set during registration. 1024 * 1025 * @return {string} 1026 * The name of this `Component`. 1027 */ 1028 1029 1030 Component.prototype.name = function name() { 1031 return this.name_; 1032 }; 1033 1034 /** 1035 * Get an array of all child components 1036 * 1037 * @return {Array} 1038 * The children 1039 */ 1040 1041 1042 Component.prototype.children = function children() { 1043 return this.children_; 1044 }; 1045 1046 /** 1047 * Returns the child `Component` with the given `id`. 1048 * 1049 * @param {string} id 1050 * The id of the child `Component` to get. 1051 * 1052 * @return {Component|undefined} 1053 * The child `Component` with the given `id` or undefined. 1054 */ 1055 1056 1057 Component.prototype.getChildById = function getChildById(id) { 1058 return this.childIndex_[id]; 1059 }; 1060 1061 /** 1062 * Returns the child `Component` with the given `name`. 1063 * 1064 * @param {string} name 1065 * The name of the child `Component` to get. 1066 * 1067 * @return {Component|undefined} 1068 * The child `Component` with the given `name` or undefined. 1069 */ 1070 1071 1072 Component.prototype.getChild = function getChild(name) { 1073 if (!name) { 1074 return; 1075 } 1076 1077 name = (0, _toTitleCase2['default'])(name); 1078 1079 return this.childNameIndex_[name]; 1080 }; 1081 1082 /** 1083 * Add a child `Component` inside the current `Component`. 1084 * 1085 * 1086 * @param {string|Component} child 1087 * The name or instance of a child to add. 1088 * 1089 * @param {Object} [options={}] 1090 * The key/value store of options that will get passed to children of 1091 * the child. 1092 * 1093 * @param {number} [index=this.children_.length] 1094 * The index to attempt to add a child into. 1095 * 1096 * @return {Component} 1097 * The `Component` that gets added as a child. When using a string the 1098 * `Component` will get created by this process. 1099 */ 1100 1101 1102 Component.prototype.addChild = function addChild(child) { 1103 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 1104 var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.children_.length; 1105 1106 var component = void 0; 1107 var componentName = void 0; 1108 1109 // If child is a string, create component with options 1110 if (typeof child === 'string') { 1111 componentName = (0, _toTitleCase2['default'])(child); 1112 1113 // Options can also be specified as a boolean, 1114 // so convert to an empty object if false. 1115 if (!options) { 1116 options = {}; 1117 } 1118 1119 // Same as above, but true is deprecated so show a warning. 1120 if (options === true) { 1121 _log2['default'].warn('Initializing a child component with `true` is deprecated.' + 'Children should be defined in an array when possible, ' + 'but if necessary use an object instead of `true`.'); 1122 options = {}; 1123 } 1124 1125 var componentClassName = options.componentClass || componentName; 1126 1127 // Set name through options 1128 options.name = componentName; 1129 1130 // Create a new object & element for this controls set 1131 // If there's no .player_, this is a player 1132 var ComponentClass = Component.getComponent(componentClassName); 1133 1134 if (!ComponentClass) { 1135 throw new Error('Component ' + componentClassName + ' does not exist'); 1136 } 1137 1138 // data stored directly on the videojs object may be 1139 // misidentified as a component to retain 1140 // backwards-compatibility with 4.x. check to make sure the 1141 // component class can be instantiated. 1142 if (typeof ComponentClass !== 'function') { 1143 return null; 1144 } 1145 1146 component = new ComponentClass(this.player_ || this, options); 1147 1148 // child is a component instance 1149 } else { 1150 component = child; 1151 } 1152 1153 this.children_.splice(index, 0, component); 1154 1155 if (typeof component.id === 'function') { 1156 this.childIndex_[component.id()] = component; 1157 } 1158 1159 // If a name wasn't used to create the component, check if we can use the 1160 // name function of the component 1161 componentName = componentName || component.name && (0, _toTitleCase2['default'])(component.name()); 1162 1163 if (componentName) { 1164 this.childNameIndex_[componentName] = component; 1165 } 1166 1167 // Add the UI object's element to the container div (box) 1168 // Having an element is not required 1169 if (typeof component.el === 'function' && component.el()) { 1170 var childNodes = this.contentEl().children;
vendor: 4,344 bytes, lines 1171-1315
1171 var refNode = childNodes[index] || null; 1172 1173 this.contentEl().insertBefore(component.el(), refNode); 1174 } 1175 1176 // Return so it can stored on parent object if desired. 1177 return component; 1178 }; 1179 1180 /** 1181 * Remove a child `Component` from this `Component`s list of children. Also removes 1182 * the child `Component`s element from this `Component`s element. 1183 * 1184 * @param {Component} component 1185 * The child `Component` to remove. 1186 */ 1187 1188 1189 Component.prototype.removeChild = function removeChild(component) { 1190 if (typeof component === 'string') { 1191 component = this.getChild(component); 1192 } 1193 1194 if (!component || !this.children_) { 1195 return; 1196 } 1197 1198 var childFound = false; 1199 1200 for (var i = this.children_.length - 1; i >= 0; i--) { 1201 if (this.children_[i] === component) { 1202 childFound = true; 1203 this.children_.splice(i, 1); 1204 break; 1205 } 1206 } 1207 1208 if (!childFound) { 1209 return; 1210 } 1211 1212 this.childIndex_[component.id()] = null; 1213 this.childNameIndex_[component.name()] = null; 1214 1215 var compEl = component.el(); 1216 1217 if (compEl && compEl.parentNode === this.contentEl()) { 1218 this.contentEl().removeChild(component.el()); 1219 } 1220 }; 1221 1222 /** 1223 * Add and initialize default child `Component`s based upon options. 1224 */ 1225 1226 1227 Component.prototype.initChildren = function initChildren() { 1228 var _this = this; 1229 1230 var children = this.options_.children; 1231 1232 if (children) { 1233 // `this` is `parent` 1234 var parentOptions = this.options_; 1235 1236 var handleAdd = function handleAdd(child) { 1237 var name = child.name; 1238 var opts = child.opts; 1239 1240 // Allow options for children to be set at the parent options 1241 // e.g. videojs(id, { controlBar: false }); 1242 // instead of videojs(id, { children: { controlBar: false }); 1243 if (parentOptions[name] !== undefined) { 1244 opts = parentOptions[name]; 1245 } 1246 1247 // Allow for disabling default components 1248 // e.g. options['children']['posterImage'] = false 1249 if (opts === false) { 1250 return; 1251 } 1252 1253 // Allow options to be passed as a simple boolean if no configuration 1254 // is necessary. 1255 if (opts === true) { 1256 opts = {}; 1257 } 1258 1259 // We also want to pass the original player options 1260 // to each component as well so they don't need to 1261 // reach back into the player for options later. 1262 opts.playerOptions = _this.options_.playerOptions; 1263 1264 // Create and add the child component. 1265 // Add a direct reference to the child by name on the parent instance. 1266 // If two of the same component are used, different names should be supplied 1267 // for each 1268 var newChild = _this.addChild(name, opts); 1269 1270 if (newChild) { 1271 _this[name] = newChild; 1272 } 1273 }; 1274 1275 // Allow for an array of children details to passed in the options 1276 var workingChildren = void 0; 1277 var Tech = Component.getComponent('Tech'); 1278 1279 if (Array.isArray(children)) { 1280 workingChildren = children; 1281 } else { 1282 workingChildren = Object.keys(children); 1283 } 1284 1285 workingChildren 1286 // children that are in this.options_ but also in workingChildren would 1287 // give us extra children we do not want. So, we want to filter them out. 1288 .concat(Object.keys(this.options_).filter(function (child) { 1289 return !workingChildren.some(function (wchild) { 1290 if (typeof wchild === 'string') { 1291 return child === wchild; 1292 } 1293 return child === wchild.name; 1294 }); 1295 })).map(function (child) { 1296 var name = void 0; 1297 var opts = void 0; 1298 1299 if (typeof child === 'string') { 1300 name = child; 1301 opts = children[name] || _this.options_[name] || {}; 1302 } else { 1303 name = child.name; 1304 opts = child; 1305 } 1306 1307 return { name: name, opts: opts }; 1308 }).filter(function (child) { 1309 // we have to make sure that child.name isn't in the techOrder since 1310 // techs are registerd as Components but can't aren't compatible 1311 // See https://github.com/videojs/video.js/issues/2772 1312 var c = Component.getComponent(child.opts.componentClass || (0, _toTitleCase2['default'])(child.name)); 1313 1314 return c && !Tech.isTech(c); 1315 }
1315).forEach(handleAdd); 1316 } 1317 }; 1318 1319 /** 1320 * Builds the default DOM class name. Should be overriden by sub-components. 1321 * 1322 * @return {string} 1323 * The DOM class name for this object. 1324 * 1325 * @abstract 1326 */ 1327 1328 1329 Component.prototype.buildCSSClass = function buildCSSClass() { 1330 // Child classes can include a function that does: 1331 // return 'CLASS NAME' + this._super(); 1332 return ''; 1333 }; 1334 1335 /** 1336 * Add an `event listener` to this `Component`s element. 1337 * 1338 * The benefit of using this over the following: 1339 * - `VjsEvents.on(otherElement, 'eventName', myFunc)` 1340 * - `otherComponent.on('eventName', myFunc)` 1341 * 1342 * 1. Is that the listeners will get cleaned up when either component gets disposed. 1343 * 1. It will also bind `myComponent` as the context of `myFunc`. 1344 * > NOTE: If you remove the element from the DOM that has used `on` you need to 1345 * clean up references using: `myComponent.trigger(el, 'dispose')` 1346 * This will also allow the browser to garbage collect it. In special 1347 * cases such as with `window` and `document`, which are both permanent, 1348 * this is not necessary. 1349 * 1350 * @param {string|Component|string[]} [first] 1351 * The event name, and array of event names, or another `Component`. 1352 * 1353 * @param {EventTarget~EventListener|string|string[]} [second] 1354 * The listener function, an event name, or an Array of events names. 1355 * 1356 * @param {EventTarget~EventListener} [third] 1357 * The event handler if `first` is a `Component` and `second` is an event name 1358 * or an Array of event names. 1359 * 1360 * @return {Component} 1361 * Returns itself; method can be chained. 1362 * 1363 * @listens Component#dispose 1364 */ 1365 1366 1367 Component.prototype.on = function on(first, second, third) { 1368 var _this2 = this; 1369 1370 if (typeof first === 'string' || Array.isArray(first)) { 1371 Events.on(this.el_, first, Fn.bind(this, second)); 1372 1373 // Targeting another component or element 1374 } else { 1375 var target = first; 1376 var type = second; 1377 var fn = Fn.bind(this, third); 1378 1379 // When this component is disposed, remove the listener from the other component 1380 var removeOnDispose = function removeOnDispose() { 1381 return _this2.off(target, type, fn); 1382 }; 1383 1384 // Use the same function ID so we can remove it later it using the ID 1385 // of the original listener 1386 removeOnDispose.guid = fn.guid; 1387 this.on('dispose', removeOnDispose); 1388 1389 // If the other component is disposed first we need to clean the reference 1390 // to the other component in this component's removeOnDispose listener 1391 // Otherwise we create a memory leak. 1392 var cleanRemover = function cleanRemover() { 1393 return _this2.off('dispose', removeOnDispose); 1394 }; 1395 1396 // Add the same function ID so we can easily remove it later 1397 cleanRemover.guid = fn.guid; 1398 1399 // Check if this is a DOM node 1400 if (first.nodeName) { 1401 // Add the listener to the other element 1402 Events.on(target, type, fn); 1403 Events.on(target, 'dispose', cleanRemover); 1404 1405 // Should be a component 1406 // Not using `instanceof Component` because it makes mock players difficult 1407 } else if (typeof first.on === 'function') { 1408 // Add the listener to the other component 1409 target.on(type, fn); 1410 target.on('dispose', cleanRemover); 1411 } 1412 } 1413 1414 return this; 1415 }; 1416 1417 /** 1418 * Remove an event listener from this `Component`s element. If the second argument is 1419 * exluded all listeners for the type passed in as the first argument will be removed. 1420 * 1421 * @param {string|Component|string[]} [first] 1422 * The event name, and array of event names, or another `Component`. 1423 * 1424 * @param {EventTarget~EventListener|string|string[]} [second] 1425 * The listener function, an event name, or an Array of events names. 1426 * 1427 * @param {EventTarget~EventListener} [third] 1428 * The event handler if `first` is a `Component` and `second` is an event name 1429 * or an Array of event names. 1430 * 1431 * @return {Component} 1432 * Returns itself; method can be chained. 1433 */ 1434 1435 1436 Component.prototype.off = function off(first, second, third) { 1437 if (!first || typeof first === 'string' || Array.isArray(first)) { 1438 Events.off(this.el_, first, second); 1439 } else { 1440 var target = first; 1441 var type = second; 1442 // Ensure there's at least a guid, even if the function hasn't been used 1443 var fn = Fn.bind(this, third); 1444 1445 // Remove the dispose listener on this component, 1446 // which was given the same guid as the event listener 1447 this.off('dispose', fn); 1448 1449 if (first.nodeName) { 1450 // Remove the listener 1451 Events.off(target, type, fn); 1452 // Remove the listener for cleaning the dispose listener 1453 Events.off(target, 'dispose', fn); 1454 } else {
1455 target.off(type, fn); 1456 target.off('dispose', fn); 1457 } 1458 } 1459 1460 return this; 1461 }; 1462 1463 /** 1464 * Add an event listener that gets triggered only once and then gets removed. 1465 * 1466 * @param {string|Component|string[]} [first] 1467 * The event name, and array of event names, or another `Component`. 1468 * 1469 * @param {EventTarget~EventListener|string|string[]} [second] 1470 * The listener function, an event name, or an Array of events names. 1471 * 1472 * @param {EventTarget~EventListener} [third] 1473 * The event handler if `first` is a `Component` and `second` is an event name 1474 * or an Array of event names. 1475 * 1476 * @return {Component} 1477 * Returns itself; method can be chained. 1478 */ 1479 1480 1481 Component.prototype.one = function one(first, second, third) { 1482 var _this3 = this, 1483 _arguments = arguments; 1484 1485 if (typeof first === 'string' || Array.isArray(first)) { 1486 Events.one(this.el_, first, Fn.bind(this, second)); 1487 } else { 1488 var target = first; 1489 var type = second; 1490 var fn = Fn.bind(this, third); 1491 1492 var newFunc = function newFunc() { 1493 _this3.off(target, type, newFunc); 1494 fn.apply(null, _arguments); 1495 }; 1496 1497 // Keep the same function ID so we can remove it later 1498 newFunc.guid = fn.guid; 1499 1500 this.on(target, type, newFunc); 1501 } 1502 1503 return this; 1504 }; 1505 1506 /** 1507 * Trigger an event on an element. 1508 * 1509 * @param {EventTarget~Event|Object|string} event 1510 * The event name, and Event, or an event-like object with a type attribute 1511 * set to the event name. 1512 * 1513 * @param {Object} [hash] 1514 * Data hash to pass along with the event 1515 * 1516 * @return {Component} 1517 * Returns itself; method can be chained. 1518 */ 1519 1520 1521 Component.prototype.trigger = function trigger(event, hash) { 1522 Events.trigger(this.el_, event, hash); 1523 return this; 1524 }; 1525 1526 /** 1527 * Bind a listener to the component's ready state. If the ready event has already 1528 * happened it will trigger the function immediately. 1529 * 1530 * @param {Component~ReadyCallback} fn 1531 * A function to call when ready is triggered. 1532 * 1533 * @param {boolean} [sync=false] 1534 * Execute the listener synchronously if `Component` is ready. 1535 * 1536 * @return {Component} 1537 * Returns itself; method can be chained. 1538 */ 1539 1540 1541 Component.prototype.ready = function ready(fn) { 1542 var sync = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 1543 1544 if (fn) { 1545 if (this.isReady_) { 1546 if (sync) { 1547 fn.call(this); 1548 } else { 1549 // Call the function asynchronously by default for consistency 1550 this.setTimeout(fn, 1); 1551 } 1552 } else { 1553 this.readyQueue_ = this.readyQueue_ || []; 1554 this.readyQueue_.push(fn); 1555 } 1556 } 1557 return this; 1558 }; 1559 1560 /** 1561 * Trigger all the ready listeners for this `Component`. 1562 * 1563 * @fires Component#ready 1564 */ 1565 1566 1567 Component.prototype.triggerReady = function triggerReady() { 1568 this.isReady_ = true; 1569 1570 // Ensure ready is triggerd asynchronously 1571 this.setTimeout(function () { 1572 var readyQueue = this.readyQueue_; 1573 1574 // Reset Ready Queue 1575 this.readyQueue_ = []; 1576 1577 if (readyQueue && readyQueue.length > 0) { 1578 readyQueue.forEach(function (fn) { 1579 fn.call(this); 1580 }, this); 1581 } 1582 1583 // Allow for using event listeners also 1584 /** 1585 * Triggered when a `Component` is ready. 1586 * 1587 * @event Component#ready 1588 * @type {EventTarget~Event} 1589 */ 1590 this.trigger('ready'); 1591 }, 1); 1592 }; 1593 1594 /** 1595 * Find a single DOM element matching a `selector`. This can be within the `Component`s 1596 * `contentEl()` or another custom context. 1597 * 1598 * @param {string} selector 1599 * A valid CSS selector, which will be passed to `querySelector`. 1600 * 1601 * @param {Element|string} [context=this.contentEl()] 1602 * A DOM element within which to query. Can also be a selector string in 1603 * which case the first matching element will get used as context. If 1604 * missing `this.contentEl()` gets used. If `this.contentEl()` returns 1605 * nothing it falls back to `document`. 1606 * 1607 * @return {Element|null} 1608 * the dom element that was found, or null 1609 * 1610 * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) 1611 */ 1612 1613 1614 Component.prototype.$ = function $(selector, context) { 1615 return Dom.$(selector, context || this.contentEl()); 1616 }; 1617 1618 /** 1619 * Finds all DOM element matching a `selector`. This can be within the `Component`s 1620 * `contentEl()` or another custom context. 1621 * 1622 * @param {string} selector 1623 * A valid CSS selector, which will be passed to `querySelectorAll`. 1624 * 1625 * @param {Element|string} [context=this.contentEl()] 1626 * A DOM element within which to query. Can also be a selector string in 1627 * which case the first matching element will get used as context. If 1628 * missing `this.contentEl()` gets used. If `this.contentEl()` returns 1629 * nothing it falls back to `document`. 1630 * 1631 * @return {NodeList} 1632 * a list of dom elements that were found 1633 * 1634 * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) 1635 */ 1636 1637 1638 Component.prototype.$$ = function $$(selector, context) { 1639 return Dom.$$(selector, context || this.contentEl()); 1640 }; 1641 1642 /** 1643 * Check if a component's element has a CSS class name. 1644 * 1645 * @param {string} classToCheck 1646 * CSS class name to check. 1647 * 1648 * @return {boolean}
1649 * - True if the `Component` has the class. 1650 * - False if the `Component` does not have the class` 1651 */ 1652 1653 1654 Component.prototype.hasClass = function hasClass(classToCheck) { 1655 return Dom.hasElClass(this.el_, classToCheck); 1656 }; 1657 1658 /** 1659 * Add a CSS class name to the `Component`s element. 1660 * 1661 * @param {string} classToAdd 1662 * CSS class name to add 1663 * 1664 * @return {Component} 1665 * Returns itself; method can be chained. 1666 */ 1667 1668 1669 Component.prototype.addClass = function addClass(classToAdd) { 1670 Dom.addElClass(this.el_, classToAdd); 1671 return this; 1672 }; 1673 1674 /** 1675 * Remove a CSS class name from the `Component`s element. 1676 * 1677 * @param {string} classToRemove 1678 * CSS class name to remove 1679 * 1680 * @return {Component} 1681 * Returns itself; method can be chained. 1682 */ 1683 1684 1685 Component.prototype.removeClass = function removeClass(classToRemove) { 1686 Dom.removeElClass(this.el_, classToRemove); 1687 return this; 1688 }; 1689 1690 /** 1691 * Add or remove a CSS class name from the component's element. 1692 * - `classToToggle` gets added when {@link Component#hasClass} would return false. 1693 * - `classToToggle` gets removed when {@link Component#hasClass} would return true. 1694 * 1695 * @param {string} classToToggle 1696 * The class to add or remove based on (@link Component#hasClass} 1697 * 1698 * @param {boolean|Dom~predicate} [predicate] 1699 * An {@link Dom~predicate} function or a boolean 1700 * 1701 * @return {Component} 1702 * Returns itself; method can be chained. 1703 */ 1704 1705 1706 Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) { 1707 Dom.toggleElClass(this.el_, classToToggle, predicate); 1708 return this; 1709 }; 1710 1711 /** 1712 * Show the `Component`s element if it is hidden by removing the 1713 * 'vjs-hidden' class name from it. 1714 * 1715 * @return {Component} 1716 * Returns itself; method can be chained. 1717 */ 1718 1719 1720 Component.prototype.show = function show() { 1721 this.removeClass('vjs-hidden'); 1722 return this; 1723 }; 1724 1725 /** 1726 * Hide the `Component`s element if it is currently showing by adding the 1727 * 'vjs-hidden` class name to it. 1728 * 1729 * @return {Component} 1730 * Returns itself; method can be chained. 1731 */ 1732 1733 1734 Component.prototype.hide = function hide() { 1735 this.addClass('vjs-hidden'); 1736 return this; 1737 }; 1738 1739 /** 1740 * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing' 1741 * class name to it. Used during fadeIn/fadeOut. 1742 * 1743 * @return {Component} 1744 * Returns itself; method can be chained. 1745 * 1746 * @private 1747 */ 1748 1749 1750 Component.prototype.lockShowing = function lockShowing() { 1751 this.addClass('vjs-lock-showing'); 1752 return this; 1753 }; 1754 1755 /** 1756 * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing' 1757 * class name from it. Used during fadeIn/fadeOut. 1758 * 1759 * @return {Component} 1760 * Returns itself; method can be chained. 1761 * 1762 * @private 1763 */ 1764 1765 1766 Component.prototype.unlockShowing = function unlockShowing() { 1767 this.removeClass('vjs-lock-showing'); 1768 return this; 1769 }; 1770 1771 /** 1772 * Get the value of an attribute on the `Component`s element. 1773 * 1774 * @param {string} attribute 1775 * Name of the attribute to get the value from. 1776 * 1777 * @return {string|null} 1778 * - The value of the attribute that was asked for. 1779 * - Can be an empty string on some browsers if the attribute does not exist 1780 * or has no value 1781 * - Most browsers will return null if the attibute does not exist or has 1782 * no value. 1783 * 1784 * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute} 1785 */ 1786 1787 1788 Component.prototype.getAttribute = function getAttribute(attribute) { 1789 return Dom.getAttribute(this.el_, attribute); 1790 }; 1791 1792 /** 1793 * Set the value of an attribute on the `Component`'s element 1794 * 1795 * @param {string} attribute 1796 * Name of the attribute to set. 1797 * 1798 * @param {string} value 1799 * Value to set the attribute to. 1800 * 1801 * @return {Component} 1802 * Returns itself; method can be chained. 1803 * 1804 * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute} 1805 */ 1806 1807 1808 Component.prototype.setAttribute = function setAttribute(attribute, value) { 1809 Dom.setAttribute(this.el_, attribute, value); 1810 return this; 1811 }; 1812 1813 /** 1814 * Remove an attribute from the `Component`s element. 1815 * 1816 * @param {string} attribute 1817 * Name of the attribute to remove. 1818 * 1819 * @return {Component} 1820 * Returns itself; method can be chained. 1821 * 1822 * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute} 1823 */ 1824 1825 1826 Component.prototype.removeAttribute = function removeAttribute(attribute) { 1827 Dom.removeAttribute(this.el_, attribute); 1828 return this; 1829 }; 1830 1831 /** 1832 * Get or set the width of the component based upon the CSS styles. 1833 * See {@link Component#dimension} for more detailed information. 1834 * 1835 * @param {number|string} [num] 1836 * The width that you want to set postfixed with '%', 'px' or nothing. 1837 * 1838 * @param {boolean} [skipListeners] 1839 * Skip the resize event trigger 1840 * 1841 * @return {Component|number|string} 1842 * - The width when getting, zero if there is no width. Can be a string 1843 * postpixed with '%' or 'px'. 1844 * - Returns itself when setting; method can be chained. 1845 */ 1846 1847 1848 Component.prototype.width = function width(num, skipListeners) { 1849 return this.dimension('width', num, skipListeners); 1850 }; 1851 1852 /** 1853 * Get or set the height of the component based upon the CSS styles. 1854 * See {@link Component#dimension} for more detailed information. 1855 * 1856 * @param {number|string} [num] 1857 * The height that you want to set postfixed with '%', 'px' or nothing. 1858 * 1859 * @param {boolean} [skipListeners] 1860 * Skip the resize event trigger 1861 * 1862 * @return {Component|number|string} 1863 * - The width when getting, zero if there is no width. Can be a string 1864 * postpixed with '%' or 'px'. 1865 * - Returns itself when setting; method can be chained. 1866 */ 1867 1868 1869 Component.prototype.height = function height(num, skipListeners) { 1870 return this.dimension('height', num, skipListeners); 1871 }; 1872 1873 /** 1874 * Set both the width and height of the `Component` element at the same time. 1875 * 1876 * @param {number|string} width 1877 * Width to set the `Component`s element to. 1878 * 1879 * @param {number|string} height 1880 * Height to set the `Component`s element to. 1881 * 1882 * @return {Component} 1883 * Returns itself; method can be chained. 1884 */ 1885 1886 1887 Component.prototype.dimensions = function dimensions(width, height) { 1888 // Skip resize listeners on width for optimization 1889 return this.width(width, true).height(height); 1890 }; 1891 1892 /** 1893 * Get or set width or height of the `Component` element. This is the shared code 1894 * for the {@link Component#width} and {@link Component#height}. 1895 * 1896 * Things to know: 1897 * - If the width or height in an number this will return the number postfixed with 'px'. 1898 * - If the width/height is a percent this will return the percent postfixed with '%' 1899 * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function 1900 * defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`. 1901 * See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-u
1901sing-width/} 1902 * for more information 1903 * - If you want the computed style of the component, use {@link Component#currentWidth} 1904 * and {@link {Component#currentHeight} 1905 * 1906 * @fires Component#resize 1907 * 1908 * @param {string} widthOrHeight 1909 8 'width' or 'height' 1910 * 1911 * @param {number|string} [num] 1912 8 New dimension 1913 * 1914 * @param {boolean} [skipListeners] 1915 * Skip resize event trigger 1916 * 1917 * @return {Component} 1918 * - the dimension when getting or 0 if unset 1919 * - Returns itself when setting; method can be chained. 1920 */ 1921 1922 1923 Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) { 1924 if (num !== undefined) { 1925 // Set to zero if null or literally NaN (NaN !== NaN) 1926 if (num === null || num !== num) { 1927 num = 0; 1928 } 1929 1930 // Check if using css width/height (% or px) and adjust 1931 if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) { 1932 this.el_.style[widthOrHeight] = num; 1933 } else if (num === 'auto') { 1934 this.el_.style[widthOrHeight] = ''; 1935 } else { 1936 this.el_.style[widthOrHeight] = num + 'px'; 1937 } 1938 1939 // skipListeners allows us to avoid triggering the resize event when setting both width and height 1940 if (!skipListeners) { 1941 /** 1942 * Triggered when a component is resized. 1943 * 1944 * @event Component#resize 1945 * @type {EventTarget~Event} 1946 */ 1947 this.trigger('resize'); 1948 } 1949 1950 // Return component 1951 return this; 1952 } 1953 1954 // Not setting a value, so getting it 1955 // Make sure element exists 1956 if (!this.el_) { 1957 return 0; 1958 } 1959 1960 // Get dimension value from style 1961 var val = this.el_.style[widthOrHeight]; 1962 var pxIndex = val.indexOf('px'); 1963 1964 if (pxIndex !== -1) { 1965 // Return the pixel value with no 'px' 1966 return parseInt(val.slice(0, pxIndex), 10); 1967 } 1968 1969 // No px so using % or no style was set, so falling back to offsetWidth/height 1970 // If component has display:none, offset will return 0 1971 // TODO: handle display:none and no dimension style using px 1972 return parseInt(this.el_['offset' + (0, _toTitleCase2['default'])(widthOrHeight)], 10); 1973 }; 1974 1975 /** 1976 * Get the width or the height of the `Component` elements computed style. Uses 1977 * `window.getComputedStyle`. 1978 * 1979 * @param {string} widthOrHeight 1980 * A string containing 'width' or 'height'. Whichever one you want to get. 1981 * 1982 * @return {number} 1983 * The dimension that gets asked for or 0 if nothing was set 1984 * for that dimension. 1985 */ 1986 1987 1988 Component.prototype.currentDimension = function currentDimension(widthOrHeight) { 1989 var computedWidthOrHeight = 0; 1990 1991 if (widthOrHeight !== 'width' && widthOrHeight !== 'height') { 1992 throw new Error('currentDimension only accepts width or height value'); 1993 } 1994 1995 if (typeof _window2['default'].getComputedStyle === 'function') { 1996 var computedStyle = _window2['default'].getComputedStyle(this.el_); 1997 1998 computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight]; 1999 } 2000 2001 // remove 'px' from variable and parse as integer 2002 computedWidthOrHeight = parseFloat(computedWidthOrHeight); 2003 2004 // if the computed value is still 0, it's possible that the browser is lying 2005 // and we want to check the offset values. 2006 // This code also runs on IE8 and wherever getComputedStyle doesn't exist. 2007 if (computedWidthOrHeight === 0) { 2008 var rule = 'offset' + (0, _toTitleCase2['default'])(widthOrHeight); 2009 2010 computedWidthOrHeight = this.el_[rule]; 2011 } 2012 2013 return computedWidthOrHeight; 2014 }; 2015 2016 /** 2017 * An object that contains width and height values of the `Component`s 2018 * computed style. Uses `window.getComputedStyle`. 2019 * 2020 * @typedef {Object} Component~DimensionObject 2021 * 2022 * @property {number} width 2023 * The width of the `Component`s computed style. 2024 * 2025 * @property {number} height 2026 * The height of the `Component`s computed style. 2027 */ 2028 2029 /** 2030 * Get an object that contains width and height values of the `Component`s 2031 * computed style. 2032 * 2033 * @return {Component~DimensionObject} 2034 * The dimensions of the components element 2035 */ 2036 2037 2038 Component.prototype.currentDimensions = function currentDimensions() { 2039 return { 2040 width: this.currentDimension('width'), 2041 height: this.currentDimension('height') 2042 }; 2043 }; 2044 2045 /** 2046 * Get the width of the `Component`s computed style. Uses `window.getComputedStyle`. 2047 * 2048 * @return {number} width 2049 * The width of the `Component`s computed style. 2050 */ 2051 2052 2053 Component.prototype.currentWidth = function currentWidth() { 2054 return this.currentDimension('width'); 2055 }; 2056 2057 /** 2058 * Get the height of the `Component`s computed style. Uses `window.getComputedStyle`. 2059 * 2060 * @return {number} height 2061 * The height of the `Component`s computed style. 2062 */ 2063 2064 2065 Component.prototype.currentHeight = function currentHeight() { 2066 return this.currentDimension('height'); 2067 }; 2068 2069 /** 2070 * Set the focus to this component 2071 */ 2072 2073
vendor: 9,394 bytes, lines 2074-2334
2074 Component.prototype.focus = function focus() { 2075 this.el_.focus(); 2076 }; 2077 2078 /** 2079 * Remove the focus from this component 2080 */ 2081 2082 2083 Component.prototype.blur = function blur() { 2084 this.el_.blur(); 2085 }; 2086 2087 /** 2088 * Emit a 'tap' events when touch event support gets detected. This gets used to 2089 * support toggling the controls through a tap on the video. They get enabled 2090 * because every sub-component would have extra overhead otherwise. 2091 * 2092 * @private 2093 * @fires Component#tap 2094 * @listens Component#touchstart 2095 * @listens Component#touchmove 2096 * @listens Component#touchleave 2097 * @listens Component#touchcancel 2098 * @listens Component#touchend 2099 */ 2100 2101 2102 Component.prototype.emitTapEvents = function emitTapEvents() { 2103 // Track the start time so we can determine how long the touch lasted 2104 var touchStart = 0; 2105 var firstTouch = null; 2106 2107 // Maximum movement allowed during a touch event to still be considered a tap 2108 // Other popular libs use anywhere from 2 (hammer.js) to 15, 2109 // so 10 seems like a nice, round number. 2110 var tapMovementThreshold = 10; 2111 2112 // The maximum length a touch can be while still being considered a tap 2113 var touchTimeThreshold = 200; 2114 2115 var couldBeTap = void 0; 2116 2117 this.on('touchstart', function (event) { 2118 // If more than one finger, don't consider treating this as a click 2119 if (event.touches.length === 1) { 2120 // Copy pageX/pageY from the object 2121 firstTouch = { 2122 pageX: event.touches[0].pageX, 2123 pageY: event.touches[0].pageY 2124 }; 2125 // Record start time so we can detect a tap vs. "touch and hold" 2126 touchStart = new Date().getTime(); 2127 // Reset couldBeTap tracking 2128 couldBeTap = true; 2129 } 2130 }); 2131 2132 this.on('touchmove', function (event) { 2133 // If more than one finger, don't consider treating this as a click 2134 if (event.touches.length > 1) { 2135 couldBeTap = false; 2136 } else if (firstTouch) { 2137 // Some devices will throw touchmoves for all but the slightest of taps. 2138 // So, if we moved only a small distance, this could still be a tap 2139 var xdiff = event.touches[0].pageX - firstTouch.pageX; 2140 var ydiff = event.touches[0].pageY - firstTouch.pageY; 2141 var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff); 2142 2143 if (touchDistance > tapMovementThreshold) { 2144 couldBeTap = false; 2145 } 2146 } 2147 }); 2148 2149 var noTap = function noTap() { 2150 couldBeTap = false; 2151 }; 2152 2153 // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s 2154 this.on('touchleave', noTap); 2155 this.on('touchcancel', noTap); 2156 2157 // When the touch ends, measure how long it took and trigger the appropriate 2158 // event 2159 this.on('touchend', function (event) { 2160 firstTouch = null; 2161 // Proceed only if the touchmove/leave/cancel event didn't happen 2162 if (couldBeTap === true) { 2163 // Measure how long the touch lasted 2164 var touchTime = new Date().getTime() - touchStart; 2165 2166 // Make sure the touch was less than the threshold to be considered a tap 2167 if (touchTime < touchTimeThreshold) { 2168 // Don't let browser turn this into a click 2169 event.preventDefault(); 2170 /** 2171 * Triggered when a `Component` is tapped. 2172 * 2173 * @event Component#tap 2174 * @type {EventTarget~Event} 2175 */ 2176 this.trigger('tap'); 2177 // It may be good to copy the touchend event object and change the 2178 // type to tap, if the other event properties aren't exact after 2179 // Events.fixEvent runs (e.g. event.target) 2180 } 2181 } 2182 }); 2183 }; 2184 2185 /** 2186 * This function reports user activity whenever touch events happen. This can get 2187 * turned off by any sub-components that wants touch events to act another way. 2188 * 2189 * Report user touch activity when touch events occur. User activity gets used to 2190 * determine when controls should show/hide. It is simple when it comes to mouse 2191 * events, because any mouse event should show the controls. So we capture mouse 2192 * events that bubble up to the player and report activity when that happens. 2193 * With touch events it isn't as easy as `touchstart` and `touchend` toggle player 2194 * controls. So touch events can't help us at the player level either. 2195 * 2196 * User activity gets checked asynchronously. So what could happen is a tap event 2197 * on the video turns the controls off. Then the `touchend` event bubbles up to 2198 * the player. Which, if it reported user activity, would turn the controls right 2199 * back on. We also don't want to completely block touch events from bubbling up. 2200 * Furthermore a `touchmove` event and anything other than a tap, should not turn 2201 * controls back on. 2202 * 2203 * @listens Component#touchstart 2204 * @listens Component#touchmove 2205 * @listens Component#touchend 2206 * @listens Component#touchcancel 2207 */ 2208 2209 2210 Component.prototype.enableTouchActivity = function enableTouchActivity() { 2211 // Don't continue if the root player doesn't support reporting user activity 2212 if (!this.player() || !this.player().reportUserActivity) { 2213 return; 2214 } 2215 2216 // listener for reporting that the user is active 2217 var report = Fn.bind(this.player(), this.player().reportUserActivity); 2218 2219 var touchHolding = void 0; 2220 2221 this.on('touchstart', function () { 2222 report(); 2223 // For as long as the they are touching the device or have their mouse down, 2224 // we consider them active even if they're not moving their finger or mouse. 2225 // So we want to continue to update that they are active 2226 this.clearInterval(touchHolding); 2227 // report at the same interval as activityCheck 2228 touchHolding = this.setInterval(report, 250); 2229 }); 2230 2231 var touchEnd = function touchEnd(event) { 2232 report(); 2233 // stop the interval that maintains activity if the touch is holding 2234 this.clearInterval(touchHolding); 2235 }; 2236 2237 this.on('touchmove', report); 2238 this.on('touchend', touchEnd); 2239 this.on('touchcancel', touchEnd); 2240 }; 2241 2242 /** 2243 * A callback that has no parameters and is bound into `Component`s context. 2244 * 2245 * @callback Component~GenericCallback 2246 * @this Component 2247 */ 2248 2249 /** 2250 * Creates a function that runs after an `x` millisecond timeout. This function is a 2251 * wrapper around `window.setTimeout`. There are a few reasons to use this one 2252 * instead though: 2253 * 1. It gets cleared via {@link Component#clearTimeout} when 2254 * {@link Component#dispose} gets called. 2255 * 2. The function callback will gets turned into a {@link Component~GenericCallback} 2256 * 2257 * > Note: You can use `window.clearTimeout` on the id returned by this function. This 2258 * will cause its dispose listener not to get cleaned up! Please use 2259 * {@link Component#clearTimeout} or {@link Component#dispose}. 2260 * 2261 * @param {Component~GenericCallback} fn 2262 * The function that will be run after `timeout`. 2263 * 2264 * @param {number} timeout 2265 * Timeout in milliseconds to delay before executing the specified function. 2266 * 2267 * @return {number} 2268 * Returns a timeout ID that gets used to identify the timeout. It can also 2269 * get used in {@link Component#clearTimeout} to clear the timeout that 2270 * was set. 2271 * 2272 * @listens Component#dispose 2273 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout} 2274 */ 2275 2276 2277 Component.prototype.setTimeout = function setTimeout(fn, timeout) { 2278 fn = Fn.bind(this, fn); 2279 2280 var timeoutId = _window2['default'].setTimeout(fn, timeout); 2281 var disposeFn = function disposeFn() { 2282 this.clearTimeout(timeoutId); 2283 }; 2284 2285 disposeFn.guid = 'vjs-timeout-' + timeoutId; 2286 2287 this.on('dispose', disposeFn); 2288 2289 return timeoutId; 2290 }; 2291 2292 /** 2293 * Clears a timeout that gets created via `window.setTimeout` or 2294 * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout} 2295 * use this function instead of `window.clearTimout`. If you don't your dispose 2296 * listener will not get cleaned up until {@link Component#dispose}! 2297 * 2298 * @param {number} timeoutId 2299 * The id of the timeout to clear. The return value of 2300 * {@link Component#setTimeout} or `window.setTimeout`. 2301 * 2302 * @return {number} 2303 * Returns the timeout id that was cleared. 2304 * 2305 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout} 2306 */ 2307 2308 2309 Component.prototype.clearTimeout = function clearTimeout(timeoutId) { 2310 _window2['default'].clearTimeout(timeoutId); 2311 2312 var disposeFn = function disposeFn() {}; 2313 2314 disposeFn.guid = 'vjs-timeout-' + timeoutId; 2315 2316 this.off('dispose', disposeFn); 2317 2318 return timeoutId; 2319 }; 2320 2321 /** 2322 * Creates a function that gets run every `x` milliseconds. This function is a wrapper 2323 * around `window.setInterval`. There are a few reasons to use this one instead though. 2324 * 1. It gets cleared via {@link Component#clearInterval} when 2325 * {@link Component#dispose} gets called. 2326 * 2. The function callback will be a {@link Component~GenericCallback} 2327 * 2328 * @param {Component~GenericCallback} fn 2329 * The function to run every `x` seconds. 2330 * 2331 * @param {number} interval 2332 * Execute the specified function every `x` milliseconds. 2333 * 2334 * @return {number}
2335 * Returns an id that can be used to identify the interval. It can also be be used in 2336 * {@link Component#clearInterval} to clear the interval. 2337 * 2338 * @listens Component#dispose 2339 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval} 2340 */ 2341 2342 2343 Component.prototype.setInterval = function setInterval(fn, interval) { 2344 fn = Fn.bind(this, fn); 2345 2346 var intervalId = _window2['default'].setInterval(fn, interval); 2347 2348 var disposeFn = function disposeFn() { 2349 this.clearInterval(intervalId); 2350 }; 2351 2352 disposeFn.guid = 'vjs-interval-' + intervalId; 2353 2354 this.on('dispose', disposeFn); 2355 2356 return intervalId; 2357 }; 2358 2359 /** 2360 * Clears an interval that gets created via `window.setInterval` or 2361 * {@link Component#setInterval}. If you set an inteval via {@link Component#setInterval} 2362 * use this function instead of `window.clearInterval`. If you don't your dispose 2363 * listener will not get cleaned up until {@link Component#dispose}! 2364 * 2365 * @param {number} intervalId 2366 * The id of the interval to clear. The return value of 2367 * {@link Component#setInterval} or `window.setInterval`. 2368 * 2369 * @return {number} 2370 * Returns the interval id that was cleared. 2371 * 2372 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval} 2373 */ 2374 2375 2376 Component.prototype.clearInterval = function clearInterval(intervalId) { 2377 _window2['default'].clearInterval(intervalId); 2378 2379 var disposeFn = function disposeFn() {}; 2380 2381 disposeFn.guid = 'vjs-interval-' + intervalId; 2382 2383 this.off('dispose', disposeFn); 2384 2385 return intervalId; 2386 }; 2387 2388 /** 2389 * Register a `Component` with `videojs` given the name and the component. 2390 * 2391 * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s 2392 * should be registered using {@link Tech.registerTech} or 2393 * {@link videojs:videojs.registerTech}. 2394 * 2395 * > NOTE: This function can also be seen on videojs as 2396 * {@link videojs:videojs.registerComponent}. 2397 * 2398 * @param {string} name 2399 * The name of the `Component` to register. 2400 * 2401 * @param {Component} comp 2402 * The `Component` class to register. 2403 * 2404 * @return {Component} 2405 * The `Component` that was registered. 2406 */ 2407 2408 2409 Component.registerComponent = function registerComponent(name, comp) { 2410 if (!name) { 2411 return; 2412 } 2413 2414 name = (0, _toTitleCase2['default'])(name); 2415 2416 if (!Component.components_) { 2417 Component.components_ = {}; 2418 } 2419 2420 if (name === 'Player' && Component.components_[name]) { 2421 var Player = Component.components_[name]; 2422 2423 // If we have players that were disposed, then their name will still be 2424 // in Players.players. So, we must loop through and verify that the value 2425 // for each item is not null. This allows registration of the Player component 2426 // after all players have been disposed or before any were created. 2427 if (Player.players && Object.keys(Player.players).length > 0 && Object.keys(Player.players).map(function (playerName) { 2428 return Player.players[playerName]; 2429 }).every(Boolean)) { 2430 throw new Error('Can not register Player component after player has been created'); 2431 } 2432 } 2433 2434 Component.components_[name] = comp; 2435 2436 return comp; 2437 }; 2438 2439 /** 2440 * Get a `Component` based on the name it was registered with. 2441 * 2442 * @param {string} name 2443 * The Name of the component to get. 2444 * 2445 * @return {Component} 2446 * The `Component` that got registered under the given name. 2447 * 2448 * @deprecated In `videojs` 6 this will not return `Component`s that were not 2449 * registered using {@link Component.registerComponent}. Currently we 2450 * check the global `videojs` object for a `Component` name and 2451 * return that if it exists. 2452 */ 2453 2454 2455 Component.getComponent = function getComponent(name) { 2456 if (!name) { 2457 return; 2458 } 2459 2460 name = (0, _toTitleCase2['default'])(name); 2461 2462 if (Component.components_ && Component.components_[name]) { 2463 return Component.components_[name]; 2464 } 2465 2466 if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) { 2467 _log2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)'); 2468 2469 return _window2['default'].videojs[name]; 2470 } 2471 }; 2472 2473 /** 2474 * Sets up the constructor using the supplied init method or uses the init of the 2475 * parent object. 2476 * 2477 * @param {Object} [props={}] 2478 * An object of properties. 2479 * 2480 * @return {Object} 2481 * the extended object. 2482 * 2483 * @deprecated since version 5 2484 */ 2485 2486 2487 Component.extend = function extend(props) { 2488 props = props || {}; 2489 2490 _log2['default'].warn('Component.extend({}) has been deprecated, ' + ' use videojs.extend(Component, {}) instead'); 2491 2492 // Set up the constructor using the supplied init method 2493 // or using the init of the parent object 2494 // Make sure to check the unobfuscated version for external libs 2495 var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {}; 2496 // In Resig's simple class inheritance (previously used) the constructor 2497 // is a function that calls `this.init.apply(arguments)` 2498 // However that would prevent us from using `ParentObject.call(this);` 2499 // in a Child constructor because the `this` in `this.init` 2500 // would still refer to the Child and cause an infinite loop. 2501 // We would instead have to do
2502 // `ParentObject.prototype.init.apply(this, arguments);` 2503 // Bleh. We're not creating a _super() function, so it's good to keep 2504 // the parent constructor reference simple. 2505 var subObj = function subObj() { 2506 init.apply(this, arguments); 2507 }; 2508 2509 // Inherit from this object's prototype 2510 subObj.prototype = Object.create(this.prototype); 2511 // Reset the constructor property for subObj otherwise 2512 // instances of subObj would have the constructor of the parent Object 2513 subObj.prototype.constructor = subObj; 2514 2515 // Make the class extendable 2516 subObj.extend = Component.extend; 2517 2518 // Extend subObj's prototype with functions and other properties from props 2519 for (var name in props) { 2520 if (props.hasOwnProperty(name)) { 2521 subObj.prototype[name] = props[name]; 2522 } 2523 } 2524 2525 return subObj; 2526 }; 2527 2528 return Component; 2529}(); 2530 2531Component.registerComponent('Component', Component); 2532exports['default'] = Component; 2533 2534},{"81":81,"82":82,"83":83,"85":85,"86":86,"87":87,"91":91,"95":95}],6:[function(_dereq_,module,exports){ 2535'use strict'; 2536 2537exports.__esModule = true; 2538 2539var _trackButton = _dereq_(36); 2540 2541var _trackButton2 = _interopRequireDefault(_trackButton); 2542 2543var _component = _dereq_(5); 2544 2545var _component2 = _interopRequireDefault(_component); 2546 2547var _audioTrackMenuItem = _dereq_(7); 2548 2549var _audioTrackMenuItem2 = _interopRequireDefault(_audioTrackMenuItem); 2550 2551function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2552 2553function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 2554 2555function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 2556 2557function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 2558 * @file audio-track-button.js 2559 */ 2560 2561 2562/** 2563 * The base class for buttons that toggle specific {@link AudioTrack} types. 2564 * 2565 * @extends TrackButton 2566 */ 2567var AudioTrackButton = function (_TrackButton) { 2568 _inherits(AudioTrackButton, _TrackButton); 2569 2570 /** 2571 * Creates an instance of this class. 2572 * 2573 * @param {Player} player 2574 * The `Player` that this class should be attached to. 2575 * 2576 * @param {Object} [options={}] 2577 * The key/value store of player options. 2578 */ 2579 function AudioTrackButton(player) { 2580 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 2581 2582 _classCallCheck(this, AudioTrackButton); 2583 2584 options.tracks = player.audioTracks && player.audioTracks(); 2585 2586 var _this = _possibleConstructorReturn(this, _TrackButton.call(this, player, options)); 2587 2588 _this.el_.setAttribute('aria-label', 'Audio Menu'); 2589 return _this; 2590 } 2591 2592 /** 2593 * Builds the default DOM `className`. 2594 * 2595 * @return {string} 2596 * The DOM `className` for this object. 2597 */ 2598 2599 2600 AudioTrackButton.prototype.buildCSSClass = function buildCSSClass() { 2601 return 'vjs-audio-button ' + _TrackButton.prototype.buildCSSClass.call(this); 2602 }; 2603 2604 /** 2605 * Create a menu item for each audio track 2606 * 2607 * @param {AudioTrackMenuItem[]} [items=[]] 2608 * An array of existing menu items to use. 2609 * 2610 * @return {AudioTrackMenuItem[]} 2611 * An array of menu items 2612 */ 2613 2614 2615 AudioTrackButton.prototype.createItems = function createItems() { 2616 var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 2617 2618 // if there's only one audio track, there no point in showing it 2619 this.hideThreshold_ = 1; 2620 2621 var tracks = this.player_.audioTracks && this.player_.audioTracks(); 2622 2623 if (!tracks) { 2624 return items; 2625 } 2626 2627 for (var i = 0; i < tracks.length; i++) { 2628 var track = tracks[i]; 2629 2630 items.push(new _audioTrackMenuItem2['default'](this.player_, { 2631 track: track, 2632 // MenuItem is selectable 2633 selectable: true 2634 })); 2635 } 2636 2637 return items; 2638 }; 2639 2640 return AudioTrackButton; 2641}(_trackButton2['default']); 2642 2643/** 2644 * The text that should display over the `AudioTrackButton`s controls. Added for localization. 2645 * 2646 * @type {string} 2647 * @private 2648 */ 2649 2650 2651AudioTrackButton.prototype.controlText_ = 'Audio Track'; 2652_component2['default'].registerComponent('AudioTrackButton', AudioTrackButton); 2653exports['default'] = AudioTrackButton; 2654 2655},{"36":36,"5":5,"7":7}],7:[function(_dereq_,module,exports){ 2656'use strict'; 2657 2658exports.__esModule = true; 2659 2660var _menuItem = _dereq_(48); 2661 2662var _menuItem2 = _interopRequireDefault(_menuItem); 2663 2664var _component = _dereq_(5); 2665 2666var _component2 = _interopRequireDefault(_component); 2667 2668var _fn = _dereq_(83); 2669 2670var Fn = _interopRequireWildcard(_fn); 2671 2672function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 2673 2674function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2675 2676function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 2677 2678function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 2679 2680function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
2680onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 2681 * @file audio-track-menu-item.js 2682 */ 2683 2684 2685/** 2686 * An {@link AudioTrack} {@link MenuItem} 2687 * 2688 * @extends MenuItem 2689 */ 2690var AudioTrackMenuItem = function (_MenuItem) { 2691 _inherits(AudioTrackMenuItem, _MenuItem); 2692 2693 /** 2694 * Creates an instance of this class. 2695 * 2696 * @param {Player} player 2697 * The `Player` that this class should be attached to. 2698 * 2699 * @param {Object} [options] 2700 * The key/value store of player options. 2701 */ 2702 function AudioTrackMenuItem(player, options) { 2703 _classCallCheck(this, AudioTrackMenuItem); 2704 2705 var track = options.track; 2706 var tracks = player.audioTracks(); 2707 2708 // Modify options for parent MenuItem class's init. 2709 options.label = track.label || track.language || 'Unknown'; 2710 options.selected = track.enabled; 2711 2712 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options)); 2713 2714 _this.track = track; 2715 2716 if (tracks) { 2717 var changeHandler = Fn.bind(_this, _this.handleTracksChange); 2718 2719 tracks.addEventListener('change', changeHandler); 2720 _this.on('dispose', function () { 2721 tracks.removeEventListener('change', changeHandler); 2722 }); 2723 } 2724 return _this; 2725 } 2726 2727 /** 2728 * This gets called when an `AudioTrackMenuItem is "clicked". See {@link ClickableComponent} 2729 * for more detailed information on what a click can be. 2730 * 2731 * @param {EventTarget~Event} [event] 2732 * The `keydown`, `tap`, or `click` event that caused this function to be 2733 * called. 2734 * 2735 * @listens tap 2736 * @listens click 2737 */ 2738 2739 2740 AudioTrackMenuItem.prototype.handleClick = function handleClick(event) { 2741 var tracks = this.player_.audioTracks(); 2742 2743 _MenuItem.prototype.handleClick.call(this, event); 2744 2745 if (!tracks) { 2746 return; 2747 } 2748 2749 for (var i = 0; i < tracks.length; i++) { 2750 var track = tracks[i]; 2751 2752 track.enabled = track === this.track; 2753 } 2754 }; 2755 2756 /** 2757 * Handle any {@link AudioTrack} change. 2758 * 2759 * @param {EventTarget~Event} [event] 2760 * The {@link AudioTrackList#change} event that caused this to run. 2761 * 2762 * @listens AudioTrackList#change 2763 */ 2764 2765 2766 AudioTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { 2767 this.selected(this.track.enabled); 2768 }; 2769 2770 return AudioTrackMenuItem; 2771}(_menuItem2['default']); 2772 2773_component2['default'].registerComponent('AudioTrackMenuItem', AudioTrackMenuItem); 2774exports['default'] = AudioTrackMenuItem; 2775 2776},{"48":48,"5":5,"83":83}],8:[function(_dereq_,module,exports){ 2777'use strict'; 2778 2779exports.__esModule = true; 2780 2781var _component = _dereq_(5); 2782 2783var _component2 = _interopRequireDefault(_component); 2784 2785_dereq_(12); 2786 2787_dereq_(32); 2788 2789_dereq_(33); 2790 2791_dereq_(35); 2792 2793_dereq_(34); 2794 2795_dereq_(10); 2796 2797_dereq_(18); 2798 2799_dereq_(9); 2800 2801_dereq_(38); 2802 2803_dereq_(40); 2804 2805_dereq_(11); 2806 2807_dereq_(25); 2808 2809_dereq_(27); 2810 2811_dereq_(29); 2812 2813_dereq_(24); 2814 2815_dereq_(6); 2816 2817_dereq_(13); 2818 2819_dereq_(21); 2820 2821function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2822 2823function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 2824 2825function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 2826 2827function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
2827onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 2828 * @file control-bar.js 2829 */ 2830 2831 2832// Required children 2833 2834 2835/** 2836 * Container of main controls. 2837 * 2838 * @extends Component 2839 */ 2840var ControlBar = function (_Component) { 2841 _inherits(ControlBar, _Component); 2842 2843 function ControlBar() { 2844 _classCallCheck(this, ControlBar); 2845 2846 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 2847 } 2848 2849 /** 2850 * Create the `Component`'s DOM element 2851 * 2852 * @return {Element} 2853 * The element that was created. 2854 */ 2855 ControlBar.prototype.createEl = function createEl() { 2856 return _Component.prototype.createEl.call(this, 'div', { 2857 className: 'vjs-control-bar', 2858 dir: 'ltr' 2859 }, { 2860 // The control bar is a group, so it can contain menuitems 2861 role: 'group' 2862 }); 2863 }; 2864 2865 return ControlBar; 2866}(_component2['default']); 2867 2868/** 2869 * Default options for `ControlBar` 2870 * 2871 * @type {Object} 2872 * @private 2873 */ 2874 2875 2876ControlBar.prototype.options_ = { 2877 children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subtitlesButton', 'captionsButton', 'audioTrackButton', 'fullscreenToggle'] 2878}; 2879 2880_component2['default'].registerComponent('ControlBar', ControlBar); 2881exports['default'] = ControlBar; 2882 2883},{"10":10,"11":11,"12":12,"13":13,"18":18,"21":21,"24":24,"25":25,"27":27,"29":29,"32":32,"33":33,"34":34,"35":35,"38":38,"40":40,"5":5,"6":6,"9":9}],9:[function(_dereq_,module,exports){ 2884'use strict'; 2885 2886exports.__esModule = true; 2887 2888var _button = _dereq_(2); 2889 2890var _button2 = _interopRequireDefault(_button); 2891 2892var _component = _dereq_(5); 2893 2894var _component2 = _interopRequireDefault(_component); 2895 2896function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2897 2898function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 2899 2900function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 2901 2902function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 2903 * @file fullscreen-toggle.js 2904 */ 2905 2906 2907/** 2908 * Toggle fullscreen video 2909 * 2910 * @extends Button 2911 */ 2912var FullscreenToggle = function (_Button) { 2913 _inherits(FullscreenToggle, _Button); 2914 2915 /** 2916 * Creates an instance of this class. 2917 * 2918 * @param {Player} player 2919 * The `Player` that this class should be attached to. 2920 * 2921 * @param {Object} [options] 2922 * The key/value store of player options. 2923 */ 2924 function FullscreenToggle(player, options) { 2925 _classCallCheck(this, FullscreenToggle); 2926 2927 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options)); 2928 2929 _this.on(player, 'fullscreenchange', _this.handleFullscreenChange); 2930 return _this; 2931 } 2932 2933 /** 2934 * Builds the default DOM `className`. 2935 * 2936 * @return {string} 2937 * The DOM `className` for this object. 2938 */ 2939 2940 2941 FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() { 2942 return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this); 2943 }; 2944 2945 /** 2946 * Handles fullscreenchange on the player and change control text accordingly. 2947 * 2948 * @param {EventTarget~Event} [event] 2949 * The {@link Player#fullscreenchange} event that caused this function to be 2950 * called. 2951 * 2952 * @listens Player#fullscreenchange 2953 */ 2954 2955 2956 FullscreenToggle.prototype.handleFullscreenChange = function handleFullscreenChange(event) { 2957 if (this.player_.isFullscreen()) { 2958 this.controlText('Non-Fullscreen'); 2959 } else { 2960 this.controlText('Fullscreen'); 2961 } 2962 }; 2963 2964 /** 2965 * This gets called when an `FullscreenToggle` is "clicked". See 2966 * {@link ClickableComponent} for more detailed information on what a click can be. 2967 * 2968 * @param {EventTarget~Event} [event]
2969 * The `keydown`, `tap`, or `click` event that caused this function to be 2970 * called. 2971 * 2972 * @listens tap 2973 * @listens click 2974 */ 2975 2976 2977 FullscreenToggle.prototype.handleClick = function handleClick(event) { 2978 if (!this.player_.isFullscreen()) { 2979 this.player_.requestFullscreen(); 2980 } else { 2981 this.player_.exitFullscreen(); 2982 } 2983 }; 2984 2985 return FullscreenToggle; 2986}(_button2['default']); 2987 2988/** 2989 * The text that should display over the `FullscreenToggle`s controls. Added for localization. 2990 * 2991 * @type {string} 2992 * @private 2993 */ 2994 2995 2996FullscreenToggle.prototype.controlText_ = 'Fullscreen'; 2997 2998_component2['default'].registerComponent('FullscreenToggle', FullscreenToggle); 2999exports['default'] = FullscreenToggle; 3000 3001},{"2":2,"5":5}],10:[function(_dereq_,module,exports){ 3002'use strict'; 3003 3004exports.__esModule = true; 3005 3006var _component = _dereq_(5); 3007 3008var _component2 = _interopRequireDefault(_component); 3009 3010var _dom = _dereq_(81); 3011 3012var Dom = _interopRequireWildcard(_dom); 3013 3014function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 3015 3016function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3017 3018function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 3019 3020function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 3021 3022function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 3023 * @file live-display.js 3024 */ 3025 3026 3027// TODO - Future make it click to snap to live 3028 3029/** 3030 * Displays the live indicator when duration is Infinity. 3031 * 3032 * @extends Component 3033 */ 3034var LiveDisplay = function (_Component) { 3035 _inherits(LiveDisplay, _Component); 3036 3037 /** 3038 * Creates an instance of this class. 3039 * 3040 * @param {Player} player 3041 * The `Player` that this class should be attached to. 3042 * 3043 * @param {Object} [options] 3044 * The key/value store of player options. 3045 */ 3046 function LiveDisplay(player, options) { 3047 _classCallCheck(this, LiveDisplay); 3048 3049 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 3050 3051 _this.updateShowing(); 3052 _this.on(_this.player(), 'durationchange', _this.updateShowing); 3053 return _this; 3054 } 3055 3056 /** 3057 * Create the `Component`'s DOM element 3058 * 3059 * @return {Element} 3060 * The element that was created. 3061 */ 3062 3063 3064 LiveDisplay.prototype.createEl = function createEl() { 3065 var el = _Component.prototype.createEl.call(this, 'div', { 3066 className: 'vjs-live-control vjs-control' 3067 }); 3068 3069 this.contentEl_ = Dom.createEl('div', { 3070 className: 'vjs-live-display', 3071 innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE') 3072 }, {
3073 'aria-live': 'off' 3074 }); 3075 3076 el.appendChild(this.contentEl_); 3077 return el; 3078 }; 3079 3080 /** 3081 * Check the duration to see if the LiveDisplay should be showing or not. Then show/hide 3082 * it accordingly 3083 * 3084 * @param {EventTarget~Event} [event] 3085 * The {@link Player#durationchange} event that caused this function to run. 3086 * 3087 * @listens Player#durationchange 3088 */ 3089 3090 3091 LiveDisplay.prototype.updateShowing = function updateShowing(event) { 3092 if (this.player().duration() === Infinity) { 3093 this.show(); 3094 } else { 3095 this.hide(); 3096 } 3097 }; 3098 3099 return LiveDisplay; 3100}(_component2['default']); 3101 3102_component2['default'].registerComponent('LiveDisplay', LiveDisplay); 3103exports['default'] = LiveDisplay; 3104 3105},{"5":5,"81":81}],11:[function(_dereq_,module,exports){ 3106'use strict'; 3107 3108exports.__esModule = true; 3109 3110var _button = _dereq_(2); 3111 3112var _button2 = _interopRequireDefault(_button); 3113 3114var _component = _dereq_(5); 3115 3116var _component2 = _interopRequireDefault(_component); 3117 3118var _dom = _dereq_(81); 3119 3120var Dom = _interopRequireWildcard(_dom); 3121 3122function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 3123 3124function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3125 3126function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 3127 3128function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 3129 3130function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 3131 * @file mute-toggle.js 3132 */ 3133 3134 3135/** 3136 * A button component for muting the audio. 3137 * 3138 * @extends Button 3139 */ 3140var MuteToggle = function (_Button) { 3141 _inherits(MuteToggle, _Button); 3142 3143 /** 3144 * Creates an instance of this class. 3145 * 3146 * @param {Player} player 3147 * The `Player` that this class should be attached to. 3148 * 3149 * @param {Object} [options] 3150 * The key/value store of player options. 3151 */ 3152 function MuteToggle(player, options) { 3153 _classCallCheck(this, MuteToggle); 3154 3155 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options)); 3156 3157 _this.on(player, 'volumechange', _this.update); 3158 3159 // hide mute toggle if the current tech doesn't support volume control 3160 if (player.tech_ && player.tech_.featuresVolumeControl === false) { 3161 _this.addClass('vjs-hidden'); 3162 } 3163 3164 _this.on(player, 'loadstart', function () { 3165 // We need to update the button to account for a default muted state. 3166 this.update(); 3167 3168 if (player.tech_.featuresVolumeControl === false) { 3169 this.addClass('vjs-hidden'); 3170 } else { 3171 this.removeClass('vjs-hidden'); 3172 } 3173 }); 3174 return _this; 3175 } 3176 3177 /** 3178 * Builds the default DOM `className`. 3179 * 3180 * @return {string} 3181 * The DOM `className` for this object. 3182 */ 3183 3184 3185 MuteToggle.prototype.buildCSSClass = function buildCSSClass() { 3186 return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this); 3187 }; 3188 3189 /** 3190 * This gets called when an `MuteToggle` is "clicked". See 3191 * {@link ClickableComponent} for more detailed information on what a click can be. 3192 * 3193 * @param {EventTarget~Event} [event]
3194 * The `keydown`, `tap`, or `click` event that caused this function to be 3195 * called. 3196 * 3197 * @listens tap 3198 * @listens click 3199 */ 3200 3201 3202 MuteToggle.prototype.handleClick = function handleClick(event) { 3203 this.player_.muted(this.player_.muted() ? false : true); 3204 }; 3205 3206 /** 3207 * Update the state of volume. 3208 * 3209 * @param {EventTarget~Event} [event] 3210 * The {@link Player#loadstart} event if this function was called through an 3211 * event. 3212 * 3213 * @listens Player#loadstart 3214 */ 3215 3216 3217 MuteToggle.prototype.update = function update(event) { 3218 var vol = this.player_.volume(); 3219 var level = 3; 3220 3221 if (vol === 0 || this.player_.muted()) { 3222 level = 0; 3223 } else if (vol < 0.33) { 3224 level = 1; 3225 } else if (vol < 0.67) { 3226 level = 2; 3227 } 3228 3229 // Don't rewrite the button text if the actual text doesn't change. 3230 // This causes unnecessary and confusing information for screen reader users. 3231 // This check is needed because this function gets called every time the volume level is changed. 3232 var toMute = this.player_.muted() ? 'Unmute' : 'Mute'; 3233 3234 if (this.controlText() !== toMute) { 3235 this.controlText(toMute); 3236 } 3237 3238 // TODO improve muted icon classes 3239 for (var i = 0; i < 4; i++) { 3240 Dom.removeElClass(this.el_, 'vjs-vol-' + i); 3241 } 3242 Dom.addElClass(this.el_, 'vjs-vol-' + level); 3243 }; 3244 3245 return MuteToggle; 3246}(_button2['default']); 3247 3248/** 3249 * The text that should display over the `MuteToggle`s controls. Added for localization. 3250 * 3251 * @type {string} 3252 * @private 3253 */ 3254 3255 3256MuteToggle.prototype.controlText_ = 'Mute'; 3257 3258_component2['default'].registerComponent('MuteToggle', MuteToggle); 3259exports['default'] = MuteToggle; 3260 3261},{"2":2,"5":5,"81":81}],12:[function(_dereq_,module,exports){ 3262'use strict'; 3263 3264exports.__esModule = true; 3265 3266var _button = _dereq_(2); 3267 3268var _button2 = _interopRequireDefault(_button); 3269 3270var _component = _dereq_(5); 3271 3272var _component2 = _interopRequireDefault(_component); 3273 3274function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3275 3276function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 3277 3278function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 3279 3280function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 3281 * @file play-toggle.js 3282 */ 3283 3284 3285/** 3286 * Button to toggle between play and pause. 3287 * 3288 * @extends Button 3289 */ 3290var PlayToggle = function (_Button) { 3291 _inherits(PlayToggle, _Button); 3292 3293 /** 3294 * Creates an instance of this class. 3295 * 3296 * @param {Player} player 3297 * The `Player` that this class should be attached to. 3298 * 3299 * @param {Object} [options] 3300 * The key/value store of player options. 3301 */ 3302 function PlayToggle(player, options) { 3303 _classCallCheck(this, PlayToggle); 3304 3305 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options)); 3306 3307 _this.on(player, 'play', _this.handlePlay); 3308 _this.on(player, 'pause', _this.handlePause); 3309 return _this; 3310 } 3311 3312 /** 3313 * Builds the default DOM `className`. 3314 * 3315 * @return {string} 3316 * The DOM `className` for this object. 3317 */ 3318 3319 3320 PlayToggle.prototype.buildCSSClass = function buildCSSClass() { 3321 return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this); 3322 }; 3323 3324 /** 3325 * This gets called when an `PlayToggle` is "clicked". See 3326 * {@link ClickableComponent} for more detailed information on what a click can be. 3327 * 3328 * @param {EventTarget~Event} [event]
3329 * The `keydown`, `tap`, or `click` event that caused this function to be 3330 * called. 3331 * 3332 * @listens tap 3333 * @listens click 3334 */ 3335 3336 3337 PlayToggle.prototype.handleClick = function handleClick(event) { 3338 if (this.player_.paused()) { 3339 this.player_.play(); 3340 } else { 3341 this.player_.pause(); 3342 } 3343 }; 3344 3345 /** 3346 * Add the vjs-playing class to the element so it can change appearance. 3347 * 3348 * @param {EventTarget~Event} [event] 3349 * The event that caused this function to run. 3350 * 3351 * @listens Player#play 3352 */ 3353 3354 3355 PlayToggle.prototype.handlePlay = function handlePlay(event) { 3356 this.removeClass('vjs-paused'); 3357 this.addClass('vjs-playing'); 3358 // change the button text to "Pause" 3359 this.controlText('Pause'); 3360 }; 3361 3362 /** 3363 * Add the vjs-paused class to the element so it can change appearance. 3364 * 3365 * @param {EventTarget~Event} [event] 3366 * The event that caused this function to run. 3367 * 3368 * @listens Player#pause 3369 */ 3370 3371 3372 PlayToggle.prototype.handlePause = function handlePause(event) { 3373 this.removeClass('vjs-playing'); 3374 this.addClass('vjs-paused'); 3375 // change the button text to "Play" 3376 this.controlText('Play'); 3377 }; 3378 3379 return PlayToggle; 3380}(_button2['default']); 3381 3382/** 3383 * The text that should display over the `PlayToggle`s controls. Added for localization. 3384 * 3385 * @type {string} 3386 * @private 3387 */ 3388 3389 3390PlayToggle.prototype.controlText_ = 'Play'; 3391 3392_component2['default'].registerComponent('PlayToggle', PlayToggle); 3393exports['default'] = PlayToggle; 3394 3395},{"2":2,"5":5}],13:[function(_dereq_,module,exports){ 3396'use strict'; 3397 3398exports.__esModule = true; 3399 3400var _menuButton = _dereq_(47); 3401 3402var _menuButton2 = _interopRequireDefault(_menuButton); 3403 3404var _menu = _dereq_(49); 3405 3406var _menu2 = _interopRequireDefault(_menu); 3407 3408var _playbackRateMenuItem = _dereq_(14); 3409 3410var _playbackRateMenuItem2 = _interopRequireDefault(_playbackRateMenuItem); 3411 3412var _component = _dereq_(5); 3413 3414var _component2 = _interopRequireDefault(_component); 3415 3416var _dom = _dereq_(81); 3417 3418var Dom = _interopRequireWildcard(_dom); 3419 3420function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 3421 3422function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3423 3424function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 3425 3426function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 3427 3428function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 3429 * @file playback-rate-menu-button.js 3430 */ 3431 3432 3433/** 3434 * The component for controlling the playback rate. 3435 * 3436 * @extends MenuButton 3437 */ 3438var PlaybackRateMenuButton = function (_MenuButton) { 3439 _inherits(PlaybackRateMenuButton, _MenuButton); 3440 3441 /** 3442 * Creates an instance of this class. 3443 * 3444 * @param {Player} player 3445 * The `Player` that this class should be attached to. 3446 * 3447 * @param {Object} [options] 3448 * The key/value store of player options. 3449 */ 3450 function PlaybackRateMenuButton(player, options) { 3451 _classCallCheck(this, PlaybackRateMenuButton); 3452 3453 var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options)); 3454 3455 _this.updateVisibility(); 3456 _this.updateLabel(); 3457 3458 _this.on(player, 'loadstart', _this.updateVisibility); 3459 _this.on(player, 'ratechange', _this.updateLabel); 3460 return _this; 3461 } 3462 3463 /** 3464 * Create the `Component`'s DOM element 3465 * 3466 * @return {Element} 3467 * The element that was created. 3468 */ 3469 3470 3471 PlaybackRateMenuButton.prototype.createEl = function createEl() { 3472 var el = _MenuButton.prototype.createEl.call(this); 3473 3474 this.labelEl_ = Dom.createEl('div', { 3475 className: 'vjs-playback-rate-value', 3476 innerHTML: 1.0 3477 }); 3478 3479 el.appendChild(this.labelEl_); 3480 3481 return el; 3482 }; 3483 3484 /** 3485 * Builds the default DOM `className`. 3486 * 3487 * @return {string} 3488 * The DOM `className` for this object. 3489 */ 3490 3491 3492 PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() { 3493 return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this); 3494 }; 3495 3496 /** 3497 * Create the playback rate menu 3498 * 3499 * @return {Menu} 3500 * Menu object populated with {@link PlaybackRateMenuItem}s 3501 */ 3502 3503 3504 PlaybackRateMenuButton.prototype.createMenu = function createMenu() { 3505 var menu = new _menu2['default'](this.player()); 3506 var rates = this.playbackRates(); 3507 3508 if (rates) { 3509 for (var i = rates.length - 1; i >= 0; i--) { 3510 menu.addChild(new _playbackRateMenuItem2['default'](this.player(), { rate: rates[i] + 'x' })); 3511 } 3512 } 3513 3514 return menu; 3515 }; 3516 3517 /** 3518 * Updates ARIA accessibility attributes 3519 */ 3520 3521 3522 PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() { 3523 // Current playback rate 3524 this.el().setAttribute('aria-valuenow', this.player().playbackRate()); 3525 }; 3526 3527 /** 3528 * This gets called when an `PlaybackRateMenuButton` is "clicked". See 3529 * {@link ClickableComponent} for more detailed information on what a click can be. 3530 * 3531 * @param {EventTarget~Event} [event]
3532 * The `keydown`, `tap`, or `click` event that caused this function to be 3533 * called. 3534 * 3535 * @listens tap 3536 * @listens click 3537 */ 3538 3539 3540 PlaybackRateMenuButton.prototype.handleClick = function handleClick(event) { 3541 // select next rate option 3542 var currentRate = this.player().playbackRate(); 3543 var rates = this.playbackRates(); 3544 3545 // this will select first one if the last one currently selected 3546 var newRate = rates[0]; 3547 3548 for (var i = 0; i < rates.length; i++) { 3549 if (rates[i] > currentRate) { 3550 newRate = rates[i]; 3551 break; 3552 } 3553 } 3554 this.player().playbackRate(newRate); 3555 }; 3556 3557 /** 3558 * Get possible playback rates 3559 * 3560 * @return {Array} 3561 * All possible playback rates 3562 */ 3563 3564 3565 PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() { 3566 return this.options_.playbackRates || this.options_.playerOptions && this.options_.playerOptions.playbackRates; 3567 }; 3568 3569 /** 3570 * Get whether playback rates is supported by the tech 3571 * and an array of playback rates exists 3572 * 3573 * @return {boolean} 3574 * Whether changing playback rate is supported 3575 */ 3576 3577 3578 PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() { 3579 return this.player().tech_ && this.player().tech_.featuresPlaybackRate && this.playbackRates() && this.playbackRates().length > 0; 3580 }; 3581 3582 /** 3583 * Hide playback rate controls when they're no playback rate options to select 3584 * 3585 * @param {EventTarget~Event} [event] 3586 * The event that caused this function to run. 3587 * 3588 * @listens Player#loadstart 3589 */ 3590 3591 3592 PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility(event) { 3593 if (this.playbackRateSupported()) { 3594 this.removeClass('vjs-hidden'); 3595 } else { 3596 this.addClass('vjs-hidden'); 3597 } 3598 }; 3599 3600 /** 3601 * Update button label when rate changed 3602 * 3603 * @param {EventTarget~Event} [event] 3604 * The event that caused this function to run. 3605 * 3606 * @listens Player#ratechange 3607 */ 3608 3609 3610 PlaybackRateMenuButton.prototype.updateLabel = function updateLabel(event) { 3611 if (this.playbackRateSupported()) { 3612 this.labelEl_.innerHTML = this.player().playbackRate() + 'x'; 3613 } 3614 }; 3615 3616 return PlaybackRateMenuButton; 3617}(_menuButton2['default']); 3618 3619/** 3620 * The text that should display over the `FullscreenToggle`s controls. Added for localization. 3621 * 3622 * @type {string} 3623 * @private 3624 */ 3625 3626 3627PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate'; 3628 3629_component2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton); 3630exports['default'] = PlaybackRateMenuButton; 3631 3632},{"14":14,"47":47,"49":49,"5":5,"81":81}],14:[function(_dereq_,module,exports){ 3633'use strict'; 3634 3635exports.__esModule = true; 3636 3637var _menuItem = _dereq_(48); 3638 3639var _menuItem2 = _interopRequireDefault(_menuItem); 3640 3641var _component = _dereq_(5); 3642 3643var _component2 = _interopRequireDefault(_component); 3644 3645function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3646 3647function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 3648 3649function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 3650 3651function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 3652 * @file playback-rate-menu-item.js 3653 */ 3654 3655 3656/** 3657 * The specific menu item type for selecting a playback rate. 3658 * 3659 * @extends MenuItem 3660 */ 3661var PlaybackRateMenuItem = function (_MenuItem) { 3662 _inherits(PlaybackRateMenuItem, _MenuItem); 3663 3664 /** 3665 * Creates an instance of this class. 3666 * 3667 * @param {Player} player 3668 * The `Player` that this class should be attached to. 3669 * 3670 * @param {Object} [options] 3671 * The key/value store of player options. 3672 */ 3673 function PlaybackRateMenuItem(player, options) { 3674 _classCallCheck(this, PlaybackRateMenuItem); 3675 3676 var label = options.rate; 3677 var rate = parseFloat(label, 10); 3678 3679 // Modify options for parent MenuItem class's init. 3680 options.label = label; 3681 options.selected = rate === 1; 3682 options.selectable = true; 3683 3684 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options)); 3685 3686 _this.label = label; 3687 _this.rate = rate; 3688 3689 _this.on(player, 'ratechange', _this.update); 3690 return _this; 3691 } 3692 3693 /** 3694 * This gets called when an `PlaybackRateMenuItem` is "clicked". See 3695 * {@link ClickableComponent} for more detailed information on what a click can be. 3696 * 3697 * @param {EventTarget~Event} [event]
3698 * The `keydown`, `tap`, or `click` event that caused this function to be 3699 * called. 3700 * 3701 * @listens tap 3702 * @listens click 3703 */ 3704 3705 3706 PlaybackRateMenuItem.prototype.handleClick = function handleClick(event) { 3707 _MenuItem.prototype.handleClick.call(this); 3708 this.player().playbackRate(this.rate); 3709 }; 3710 3711 /** 3712 * Update the PlaybackRateMenuItem when the playbackrate changes. 3713 * 3714 * @param {EventTarget~Event} [event] 3715 * The `ratechange` event that caused this function to run. 3716 * 3717 * @listens Player#ratechange 3718 */ 3719 3720 3721 PlaybackRateMenuItem.prototype.update = function update(event) { 3722 this.selected(this.player().playbackRate() === this.rate); 3723 }; 3724 3725 return PlaybackRateMenuItem; 3726}(_menuItem2['default']); 3727 3728/** 3729 * The text that should display over the `PlaybackRateMenuItem`s controls. Added for localization. 3730 * 3731 * @type {string} 3732 * @private 3733 */ 3734 3735 3736PlaybackRateMenuItem.prototype.contentElType = 'button'; 3737 3738_component2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem); 3739exports['default'] = PlaybackRateMenuItem; 3740 3741},{"48":48,"5":5}],15:[function(_dereq_,module,exports){ 3742'use strict'; 3743 3744exports.__esModule = true; 3745 3746var _component = _dereq_(5); 3747 3748var _component2 = _interopRequireDefault(_component); 3749 3750var _dom = _dereq_(81); 3751 3752var Dom = _interopRequireWildcard(_dom); 3753 3754function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 3755 3756function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3757 3758function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 3759 3760function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 3761 3762function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 3763 * @file load-progress-bar.js 3764 */ 3765 3766 3767/** 3768 * Shows loading progress 3769 * 3770 * @extends Component 3771 */ 3772var LoadProgressBar = function (_Component) { 3773 _inherits(LoadProgressBar, _Component); 3774 3775 /** 3776 * Creates an instance of this class. 3777 * 3778 * @param {Player} player 3779 * The `Player` that this class should be attached to. 3780 * 3781 * @param {Object} [options] 3782 * The key/value store of player options. 3783 */ 3784 function LoadProgressBar(player, options) { 3785 _classCallCheck(this, LoadProgressBar); 3786 3787 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 3788 3789 _this.partEls_ = []; 3790 _this.on(player, 'progress', _this.update); 3791 return _this; 3792 } 3793 3794 /** 3795 * Create the `Component`'s DOM element 3796 * 3797 * @return {Element} 3798 * The element that was created. 3799 */ 3800 3801 3802 LoadProgressBar.prototype.createEl = function createEl() { 3803 return _Component.prototype.createEl.call(this, 'div', { 3804 className: 'vjs-load-progress', 3805 innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>' 3806 }); 3807 }; 3808 3809 /** 3810 * Update progress bar 3811 * 3812 * @param {EventTarget~Event} [event] 3813 * The `progress` event that caused this function to run. 3814 * 3815 * @listens Player#progress 3816 */ 3817 3818 3819 LoadProgressBar.prototype.update = function update(event) { 3820 var buffered = this.player_.buffered(); 3821 var duration = this.player_.duration(); 3822 var bufferedEnd = this.player_.bufferedEnd(); 3823 var children = this.partEls_; 3824 3825 // get the percent width of a time compared to the total end 3826 var percentify = function percentify(time, end) { 3827 // no NaN 3828 var percent = time / end || 0; 3829 3830 return (percent >= 1 ? 1 : percent) * 100 + '%'; 3831 }; 3832 3833 // update the width of the progress bar 3834 this.el_.style.width = percentify(bufferedEnd, duration); 3835 3836 // add child elements to represent the individual buffered time ranges 3837 for (var i = 0; i < buffered.length; i++) { 3838 var start = buffered.start(i); 3839 var end = buffered.end(i); 3840 var part = children[i]; 3841 3842 if (!part) { 3843 part = this.el_.appendChild(Dom.createEl()); 3844 children[i] = part;
3845 } 3846 3847 // set the percent based on the width of the progress bar (bufferedEnd) 3848 part.style.left = percentify(start, bufferedEnd); 3849 part.style.width = percentify(end - start, bufferedEnd); 3850 } 3851 3852 // remove unused buffered range elements 3853 for (var _i = children.length; _i > buffered.length; _i--) { 3854 this.el_.removeChild(children[_i - 1]); 3855 } 3856 children.length = buffered.length; 3857 }; 3858 3859 return LoadProgressBar; 3860}(_component2['default']); 3861 3862_component2['default'].registerComponent('LoadProgressBar', LoadProgressBar); 3863exports['default'] = LoadProgressBar; 3864 3865},{"5":5,"81":81}],16:[function(_dereq_,module,exports){ 3866'use strict'; 3867 3868exports.__esModule = true; 3869 3870var _component = _dereq_(5); 3871 3872var _component2 = _interopRequireDefault(_component); 3873 3874var _dom = _dereq_(81); 3875 3876var Dom = _interopRequireWildcard(_dom); 3877 3878var _fn = _dereq_(83); 3879 3880var Fn = _interopRequireWildcard(_fn); 3881 3882var _formatTime = _dereq_(84); 3883 3884var _formatTime2 = _interopRequireDefault(_formatTime); 3885 3886var _computedStyle = _dereq_(80); 3887 3888var _computedStyle2 = _interopRequireDefault(_computedStyle); 3889 3890function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 3891 3892function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3893 3894function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 3895 3896function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 3897 3898function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 3899 * @file mouse-time-display.js 3900 */ 3901 3902 3903/** 3904 * The Mouse Time Display component shows the time you will seek to 3905 * when hovering over the progress bar 3906 * 3907 * @extends Component 3908 */ 3909var MouseTimeDisplay = function (_Component) { 3910 _inherits(MouseTimeDisplay, _Component); 3911 3912 /** 3913 * Creates an instance of this class. 3914 * 3915 * @param {Player} player 3916 * The `Player` that this class should be attached to. 3917 * 3918 * @param {Object} [options] 3919 * The key/value store of player options. 3920 */ 3921 function MouseTimeDisplay(player, options) { 3922 _classCallCheck(this, MouseTimeDisplay); 3923 3924 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 3925 3926 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) { 3927 _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside; 3928 } 3929 3930 if (_this.keepTooltipsInside) { 3931 _this.tooltip = Dom.createEl('div', { className: 'vjs-time-tooltip' }); 3932 _this.el().appendChild(_this.tooltip); 3933 _this.addClass('vjs-keep-tooltips-inside'); 3934 } 3935 3936 _this.update(0, 0); 3937 3938 player.on('ready', function () { 3939 _this.on(player.controlBar.progressControl.el(), 'mousemove', Fn.throttle(Fn.bind(_this, _this.handleMouseMove), 25)); 3940 }); 3941 return _this; 3942 } 3943 3944 /** 3945 * Create the `Component`'s DOM element 3946 * 3947 * @return {Element} 3948 * The element that was created. 3949 */ 3950 3951 3952 MouseTimeDisplay.prototype.createEl = function createEl() { 3953 return _Component.prototype.createEl.call(this, 'div', { 3954 className: 'vjs-mouse-display' 3955 }); 3956 }; 3957 3958 /** 3959 * Handle the mouse move event on the `MouseTimeDisplay`. 3960 * 3961 * @param {EventTarget~Event} event 3962 * The `mousemove` event that caused this to event to run. 3963 * 3964 * @listen mousemove 3965 */ 3966 3967 3968 MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) { 3969 var duration = this.player_.duration(); 3970 var newTime = this.calculateDistance(event) * duration; 3971 var position = event.pageX - Dom.findElPosition(this.el().parentNode).left; 3972 3973 this.update(newTime, position); 3974 }; 3975 3976 /** 3977 * Update the time and posistion of the `MouseTimeDisplay`. 3978 * 3979 * @param {number} newTime 3980 * Time to change the `MouseTimeDisplay` to. 3981 * 3982 * @param {nubmer} position 3983 * Postion from the left of the in pixels. 3984 */ 3985 3986 3987 MouseTimeDisplay.prototype.update = function update(newTime, position) { 3988 var time = (0, _formatTime2['default'])(newTime, this.player_.duration()); 3989 3990 this.el().style.left = position + 'px'; 3991 this.el().setAttribute('data-current-time', time); 3992 3993 if (this.keepTooltipsInside) { 3994 var clampedPosition = this.clampPosition_(position); 3995 var difference = position - clampedPosition + 1; 3996 var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width')); 3997 var tooltipWidthHalf = tooltipWidth / 2; 3998 3999 this.tooltip.innerHTML = time; 4000 this.tooltip.style.right = '-' + (tooltipWidthHalf - difference) + 'px'; 4001 } 4002 }; 4003 4004 /** 4005 * Get the mouse pointers x coordinate in pixels. 4006 * 4007 * @param {EventTarget~Event} [event] 4008 * The `mousemove` event that was passed to this function by 4009 * {@link MouseTimeDisplay#handleMouseMove} 4010 * 4011 * @return {number} 4012 * THe x position in pixels of the mouse pointer. 4013 */ 4014 4015 4016 MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) { 4017 return Dom.getPointerPosition(this.el().parentNode, event).x; 4018 }; 4019 4020 /** 4021 * This takes in a horizontal position for the bar and returns a clamped position. 4022 * Clamped position means that it will keep the position greater than half the width 4023 * of the tooltip and smaller than the player width minus half the width o the tooltip. 4024 * It will only clamp the position if `keepTooltipsInside` option is set. 4025 * 4026 * @param {number} position 4027 * The position the bar wants to be 4028 * 4029 * @return {number} 4030 * The (potentially) new clamped position. 4031 * 4032 * @private 4033 */ 4034 4035 4036 MouseTimeDisplay.prototype.clampPosition_ = function clampPosition_(position) { 4037 if (!this.keepTooltipsInside) { 4038 return position; 4039 } 4040 4041 var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width')); 4042 var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width')); 4043 var tooltipWidthHalf = tooltipWidth / 2; 4044 var actualPosition = position; 4045 4046 if (position < tooltipWidthHalf) { 4047 actualPosition = Math.ceil(tooltipWidthHalf); 4048 } else if (position > playerWidth - tooltipWidthHalf) { 4049 actualPosition = Math.floor(playerWidth - tooltipWidthHalf); 4050 } 4051 4052 return actualPosition; 4053 }; 4054 4055 return MouseTimeDisplay; 4056}(_component2['default']); 4057 4058_component2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay); 4059exports['default'] = MouseTimeDisplay; 4060 4061},{"5":5,"80":80,"81":81,"83":83,"84":84}],17:[function(_dereq_,module,exports){ 4062'use strict'; 4063 4064exports.__esModule = true; 4065 4066var _component = _dereq_(5); 4067 4068var _component2 = _interopRequireDefault(_component); 4069 4070var _fn = _dereq_(83); 4071 4072var Fn = _interopRequireWildcard(_fn); 4073 4074var _formatTime = _dereq_(84); 4075 4076var _formatTime2 = _interopRequireDefault(_formatTime); 4077 4078function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 4079 4080function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4081 4082function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4083 4084function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 4085 4086function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
4086onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4087 * @file play-progress-bar.js 4088 */ 4089 4090 4091/** 4092 * Shows play progress 4093 * 4094 * @extends Component 4095 */ 4096var PlayProgressBar = function (_Component) { 4097 _inherits(PlayProgressBar, _Component); 4098 4099 /** 4100 * Creates an instance of this class. 4101 * 4102 * @param {Player} player 4103 * The `Player` that this class should be attached to. 4104 * 4105 * @param {Object} [options] 4106 * The key/value store of player options. 4107 */ 4108 function PlayProgressBar(player, options) { 4109 _classCallCheck(this, PlayProgressBar); 4110 4111 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 4112 4113 _this.updateDataAttr(); 4114 _this.on(player, 'timeupdate', _this.updateDataAttr); 4115 player.ready(Fn.bind(_this, _this.updateDataAttr)); 4116 4117 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) { 4118 _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside; 4119 } 4120 4121 if (_this.keepTooltipsInside) { 4122 _this.addClass('vjs-keep-tooltips-inside'); 4123 } 4124 return _this; 4125 } 4126 4127 /** 4128 * Create the `Component`'s DOM element 4129 * 4130 * @return {Element} 4131 * The element that was created. 4132 */ 4133 4134 4135 PlayProgressBar.prototype.createEl = function createEl() { 4136 return _Component.prototype.createEl.call(this, 'div', { 4137 className: 'vjs-play-progress vjs-slider-bar', 4138 innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>' 4139 }); 4140 }; 4141 4142 /** 4143 * Update the data-current-time attribute on the `PlayProgressBar`. 4144 * 4145 * @param {EventTarget~Event} [event] 4146 * The `timeupdate` event that caused this to run. 4147 * 4148 * @listens Player#timeupdate 4149 */ 4150 4151 4152 PlayProgressBar.prototype.updateDataAttr = function updateDataAttr(event) { 4153 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 4154 4155 this.el_.setAttribute('data-current-time', (0, _formatTime2['default'])(time, this.player_.duration())); 4156 }; 4157 4158 return PlayProgressBar; 4159}(_component2['default']); 4160 4161_component2['default'].registerComponent('PlayProgressBar', PlayProgressBar); 4162exports['default'] = PlayProgressBar; 4163 4164},{"5":5,"83":83,"84":84}],18:[function(_dereq_,module,exports){ 4165'use strict'; 4166 4167exports.__esModule = true; 4168 4169var _component = _dereq_(5); 4170 4171var _component2 = _interopRequireDefault(_component); 4172 4173_dereq_(19); 4174 4175_dereq_(16); 4176 4177function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4178 4179function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4180 4181function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 4182 4183function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
4183onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4184 * @file progress-control.js 4185 */ 4186 4187 4188/** 4189 * The Progress Control component contains the seek bar, load progress, 4190 * and play progress. 4191 * 4192 * @extends Component 4193 */ 4194var ProgressControl = function (_Component) { 4195 _inherits(ProgressControl, _Component); 4196 4197 function ProgressControl() { 4198 _classCallCheck(this, ProgressControl); 4199 4200 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 4201 } 4202 4203 /** 4204 * Create the `Component`'s DOM element 4205 * 4206 * @return {Element} 4207 * The element that was created. 4208 */ 4209 ProgressControl.prototype.createEl = function createEl() { 4210 return _Component.prototype.createEl.call(this, 'div', { 4211 className: 'vjs-progress-control vjs-control' 4212 }); 4213 }; 4214 4215 return ProgressControl; 4216}(_component2['default']); 4217 4218/** 4219 * Default options for `ProgressControl` 4220 * 4221 * @type {Object} 4222 * @private 4223 */ 4224 4225 4226ProgressControl.prototype.options_ = { 4227 children: ['seekBar'] 4228}; 4229 4230_component2['default'].registerComponent('ProgressControl', ProgressControl); 4231exports['default'] = ProgressControl; 4232 4233},{"16":16,"19":19,"5":5}],19:[function(_dereq_,module,exports){ 4234'use strict'; 4235 4236exports.__esModule = true; 4237 4238var _slider = _dereq_(57); 4239 4240var _slider2 = _interopRequireDefault(_slider); 4241 4242var _component = _dereq_(5); 4243 4244var _component2 = _interopRequireDefault(_component); 4245 4246var _fn = _dereq_(83); 4247 4248var Fn = _interopRequireWildcard(_fn); 4249 4250var _formatTime = _dereq_(84); 4251 4252var _formatTime2 = _interopRequireDefault(_formatTime); 4253 4254var _computedStyle = _dereq_(80); 4255 4256var _computedStyle2 = _interopRequireDefault(_computedStyle); 4257 4258_dereq_(15); 4259 4260_dereq_(17); 4261 4262_dereq_(20); 4263 4264function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 4265 4266function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4267 4268function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4269 4270function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 4271 4272function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4273 * @file seek-bar.js 4274 */ 4275 4276 4277/** 4278 * Seek Bar and holder for the progress bars 4279 * 4280 * @extends Slider 4281 */
4282var SeekBar = function (_Slider) { 4283 _inherits(SeekBar, _Slider); 4284 4285 /** 4286 * Creates an instance of this class. 4287 * 4288 * @param {Player} player 4289 * The `Player` that this class should be attached to. 4290 * 4291 * @param {Object} [options] 4292 * The key/value store of player options. 4293 */ 4294 function SeekBar(player, options) { 4295 _classCallCheck(this, SeekBar); 4296 4297 var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options)); 4298 4299 _this.on(player, 'timeupdate', _this.updateProgress); 4300 _this.on(player, 'ended', _this.updateProgress); 4301 player.ready(Fn.bind(_this, _this.updateProgress)); 4302 4303 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) { 4304 _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside; 4305 } 4306 4307 if (_this.keepTooltipsInside) { 4308 _this.tooltipProgressBar = _this.addChild('TooltipProgressBar'); 4309 } 4310 return _this; 4311 } 4312 4313 /** 4314 * Create the `Component`'s DOM element 4315 * 4316 * @return {Element} 4317 * The element that was created. 4318 */ 4319 4320 4321 SeekBar.prototype.createEl = function createEl() { 4322 return _Slider.prototype.createEl.call(this, 'div', { 4323 className: 'vjs-progress-holder' 4324 }, { 4325 'aria-label': 'progress bar' 4326 }); 4327 }; 4328 4329 /** 4330 * Update the seek bars tooltip and width. 4331 * 4332 * @param {EventTarget~Event} [event] 4333 * The `timeupdate` or `ended` event that caused this to run. 4334 * 4335 * @listens Player#timeupdate 4336 * @listens Player#ended 4337 */ 4338 4339 4340 SeekBar.prototype.updateProgress = function updateProgress(event) { 4341 this.updateAriaAttributes(this.el_); 4342 4343 if (this.keepTooltipsInside) { 4344 this.updateAriaAttributes(this.tooltipProgressBar.el_); 4345 this.tooltipProgressBar.el_.style.width = this.bar.el_.style.width; 4346 4347 var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width')); 4348 var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltipProgressBar.tooltip, 'width')); 4349 var tooltipStyle = this.tooltipProgressBar.el().style; 4350 4351 tooltipStyle.maxWidth = Math.floor(playerWidth - tooltipWidth / 2) + 'px'; 4352 tooltipStyle.minWidth = Math.ceil(tooltipWidth / 2) + 'px'; 4353 tooltipStyle.right = '-' + tooltipWidth / 2 + 'px'; 4354 } 4355 }; 4356 4357 /** 4358 * Update ARIA accessibility attributes 4359 * 4360 * @param {Element} el 4361 * The element to update with aria accessibility attributes. 4362 */ 4363 4364 4365 SeekBar.prototype.updateAriaAttributes = function updateAriaAttributes(el) { 4366 // Allows for smooth scrubbing, when player can't keep up. 4367 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 4368 4369 // machine readable value of progress bar (percentage complete) 4370 el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2)); 4371 // human readable value of progress bar (time complete) 4372 el.setAttribute('aria-valuetext', (0, _formatTime2['default'])(time, this.player_.duration())); 4373 }; 4374 4375 /** 4376 * Get percentage of video played 4377 * 4378 * @return {number} 4379 * The percentage played 4380 */ 4381 4382 4383 SeekBar.prototype.getPercent = function getPercent() { 4384 var percent = this.player_.currentTime() / this.player_.duration(); 4385 4386 return percent >= 1 ? 1 : percent; 4387 }; 4388 4389 /** 4390 * Handle mouse down on seek bar 4391 * 4392 * @param {EventTarget~Event} event 4393 * The `mousedown` event that caused this to run. 4394 * 4395 * @listens mousedown 4396 */ 4397 4398 4399 SeekBar.prototype.handleMouseDown = function handleMouseDown(event) { 4400 this.player_.scrubbing(true); 4401 4402 this.videoWasPlaying = !this.player_.paused(); 4403 this.player_.pause(); 4404 4405 _Slider.prototype.handleMouseDown.call(this, event); 4406 }; 4407 4408 /** 4409 * Handle mouse move on seek bar 4410 * 4411 * @param {EventTarget~Event} event 4412 * The `mousemove` event that caused this to run. 4413 * 4414 * @listens mousemove 4415 */ 4416 4417 4418 SeekBar.prototype.handleMouseMove = function handleMouseMove(event) { 4419 var newTime = this.calculateDistance(event) * this.player_.duration(); 4420 4421 // Don't let video end while scrubbing. 4422 if (newTime === this.player_.duration()) { 4423 newTime = newTime - 0.1; 4424 } 4425 4426 // Set new time (tell player to seek to new time) 4427 this.player_.currentTime(newTime); 4428 }; 4429 4430 /** 4431 * Handle mouse up on seek bar 4432 * 4433 * @param {EventTarget~Event} event 4434 * The `mouseup` event that caused this to run. 4435 * 4436 * @listens mouseup 4437 */ 4438 4439 4440 SeekBar.prototype.handleMouseUp = function handleMouseUp(event) { 4441 _Slider.prototype.handleMouseUp.call(this, event); 4442 4443 this.player_.scrubbing(false); 4444 if (this.videoWasPlaying) { 4445 this.player_.play(); 4446 } 4447 }; 4448 4449 /** 4450 * Move more quickly fast forward for keyboard-only users 4451 */ 4452 4453 4454 SeekBar.prototype.stepForward = function stepForward() { 4455 // more quickly fast forward for keyboard-only users 4456 this.player_.currentTime(this.player_.currentTime() + 5); 4457 }; 4458 4459 /** 4460 * Move more quickly rewind for keyboard-only users 4461 */ 4462 4463 4464 SeekBar.prototype.stepBack = function stepBack() { 4465 // more quickly rewind for keyboard-only users 4466 this.player_.currentTime(this.player_.currentTime() - 5); 4467 }; 4468 4469 return SeekBar; 4470}(_slider2['default']); 4471 4472/** 4473 * Default options for the `SeekBar` 4474 * 4475 * @type {Object} 4476 * @private 4477 */ 4478 4479 4480SeekBar.prototype.options_ = { 4481 children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'], 4482 barName: 'playProgressBar' 4483}; 4484 4485/** 4486 * Call the update event for this Slider when this event happens on the player. 4487 * 4488 * @type {string} 4489 */ 4490SeekBar.prototype.playerEvent = 'timeupdate'; 4491 4492_component2['default'].registerComponent('SeekBar', SeekBar); 4493exports['default'] = SeekBar; 4494 4495},{"15":15,"17":17,"20":20,"5":5,"57":57,"80":80,"83":83,"84":84}],20:[function(_dereq_,module,exports){ 4496'use strict'; 4497 4498exports.__esModule = true; 4499 4500var _component = _dereq_(5); 4501 4502var _component2 = _interopRequireDefault(_component); 4503 4504var _fn = _dereq_(83); 4505 4506var Fn = _interopRequireWildcard(_fn); 4507 4508var _formatTime = _dereq_(84); 4509 4510var _formatTime2 = _interopRequireDefault(_formatTime); 4511 4512function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 4513 4514function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4515 4516function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4517 4518function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 4519 4520function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
4520onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4521 * @file play-progress-bar.js 4522 */ 4523 4524 4525/** 4526 * Shows play progress 4527 * 4528 * @extends Component 4529 */ 4530var TooltipProgressBar = function (_Component) { 4531 _inherits(TooltipProgressBar, _Component); 4532 4533 /** 4534 * Creates an instance of this class. 4535 * 4536 * @param {Player} player 4537 * The `Player` that this class should be attached to. 4538 * 4539 * @param {Object} [options] 4540 * The key/value store of player options. 4541 */ 4542 function TooltipProgressBar(player, options) { 4543 _classCallCheck(this, TooltipProgressBar); 4544 4545 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 4546 4547 _this.updateDataAttr(); 4548 _this.on(player, 'timeupdate', _this.updateDataAttr); 4549 player.ready(Fn.bind(_this, _this.updateDataAttr)); 4550 return _this; 4551 } 4552 4553 /** 4554 * Create the `Component`'s DOM element 4555 * 4556 * @return {Element} 4557 * The element that was created. 4558 */ 4559 4560 4561 TooltipProgressBar.prototype.createEl = function createEl() { 4562 var el = _Component.prototype.createEl.call(this, 'div', { 4563 className: 'vjs-tooltip-progress-bar vjs-slider-bar', 4564 innerHTML: '<div class="vjs-time-tooltip"></div>\n <span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>' 4565 }); 4566 4567 this.tooltip = el.querySelector('.vjs-time-tooltip'); 4568 4569 return el; 4570 }; 4571 4572 /** 4573 * Updatet the data-current-time attribute for TooltipProgressBar 4574 * 4575 * @param {EventTarget~Event} [event] 4576 * The `timeupdate` event that caused this function to run. 4577 * 4578 * @listens Player#timeupdate 4579 */ 4580 4581 4582 TooltipProgressBar.prototype.updateDataAttr = function updateDataAttr(event) { 4583 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 4584 var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration()); 4585 4586 this.el_.setAttribute('data-current-time', formattedTime); 4587 this.tooltip.innerHTML = formattedTime; 4588 }; 4589 4590 return TooltipProgressBar; 4591}(_component2['default']); 4592 4593_component2['default'].registerComponent('TooltipProgressBar', TooltipProgressBar); 4594exports['default'] = TooltipProgressBar; 4595 4596},{"5":5,"83":83,"84":84}],21:[function(_dereq_,module,exports){ 4597'use strict'; 4598 4599exports.__esModule = true; 4600 4601var _spacer = _dereq_(22); 4602 4603var _spacer2 = _interopRequireDefault(_spacer); 4604 4605var _component = _dereq_(5); 4606 4607var _component2 = _interopRequireDefault(_component); 4608 4609function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4610 4611function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4612 4613function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 4614 4615function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
4615onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4616 * @file custom-control-spacer.js 4617 */ 4618 4619 4620/** 4621 * Spacer specifically meant to be used as an insertion point for new plugins, etc. 4622 * 4623 * @extends Spacer 4624 */ 4625var CustomControlSpacer = function (_Spacer) { 4626 _inherits(CustomControlSpacer, _Spacer); 4627 4628 function CustomControlSpacer() { 4629 _classCallCheck(this, CustomControlSpacer); 4630 4631 return _possibleConstructorReturn(this, _Spacer.apply(this, arguments)); 4632 } 4633 4634 /** 4635 * Builds the default DOM `className`. 4636 * 4637 * @return {string} 4638 * The DOM `className` for this object. 4639 */ 4640 CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() { 4641 return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this); 4642 }; 4643 4644 /** 4645 * Create the `Component`'s DOM element 4646 * 4647 * @return {Element} 4648 * The element that was created. 4649 */ 4650 4651 4652 CustomControlSpacer.prototype.createEl = function createEl() { 4653 var el = _Spacer.prototype.createEl.call(this, { 4654 className: this.buildCSSClass() 4655 }); 4656 4657 // No-flex/table-cell mode requires there be some content 4658 // in the cell to fill the remaining space of the table. 4659 el.innerHTML = ' '; 4660 return el; 4661 }; 4662 4663 return CustomControlSpacer; 4664}(_spacer2['default']); 4665 4666_component2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer); 4667exports['default'] = CustomControlSpacer; 4668 4669},{"22":22,"5":5}],22:[function(_dereq_,module,exports){ 4670'use strict'; 4671 4672exports.__esModule = true; 4673 4674var _component = _dereq_(5); 4675 4676var _component2 = _interopRequireDefault(_component); 4677 4678function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4679 4680function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4681 4682function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 4683 4684function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4685 * @file spacer.js 4686 */ 4687 4688 4689/** 4690 * Just an empty spacer element that can be used as an append point for plugins, etc. 4691 * Also can be used to create space between elements when necessary. 4692 * 4693 * @extends Component 4694 */ 4695var Spacer = function (_Component) { 4696 _inherits(Spacer, _Component); 4697 4698 function Spacer() { 4699 _classCallCheck(this, Spacer); 4700 4701 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 4702 } 4703 4704 /** 4705 * Builds the default DOM `className`. 4706 * 4707 * @return {string} 4708 * The DOM `className` for this object. 4709 */ 4710 Spacer.prototype.buildCSSClass = function buildCSSClass() { 4711 return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this); 4712 }; 4713 4714 /** 4715 * Create the `Component`'s DOM element 4716 * 4717 * @return {Element} 4718 * The element that was created. 4719 */ 4720 4721 4722 Spacer.prototype.createEl = function createEl() { 4723 return _Component.prototype.createEl.call(this, 'div', { 4724 className: this.buildCSSClass() 4725 }); 4726 }; 4727 4728 return Spacer; 4729}(_component2['default']); 4730 4731_component2['default'].registerComponent('Spacer', Spacer); 4732 4733exports['default'] = Spacer; 4734 4735},{"5":5}],23:[function(_dereq_,module,exports){ 4736'use strict'; 4737 4738exports.__esModule = true; 4739 4740var _textTrackMenuItem = _dereq_(31); 4741 4742var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem); 4743 4744var _component = _dereq_(5); 4745 4746var _component2 = _interopRequireDefault(_component); 4747 4748function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4749 4750function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4751 4752function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 4753 4754function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
4754onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4755 * @file caption-settings-menu-item.js 4756 */ 4757 4758 4759/** 4760 * The menu item for caption track settings menu 4761 * 4762 * @extends TextTrackMenuItem 4763 */ 4764var CaptionSettingsMenuItem = function (_TextTrackMenuItem) { 4765 _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem); 4766 4767 /** 4768 * Creates an instance of this class. 4769 * 4770 * @param {Player} player 4771 * The `Player` that this class should be attached to. 4772 * 4773 * @param {Object} [options] 4774 * The key/value store of player options. 4775 */ 4776 function CaptionSettingsMenuItem(player, options) { 4777 _classCallCheck(this, CaptionSettingsMenuItem); 4778 4779 options.track = { 4780 player: player, 4781 kind: options.kind, 4782 label: options.kind + ' settings', 4783 selectable: false, 4784 'default': false, 4785 mode: 'disabled' 4786 }; 4787 4788 // CaptionSettingsMenuItem has no concept of 'selected' 4789 options.selectable = false; 4790 4791 var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options)); 4792 4793 _this.addClass('vjs-texttrack-settings'); 4794 _this.controlText(', opens ' + options.kind + ' settings dialog'); 4795 return _this; 4796 } 4797 4798 /** 4799 * This gets called when an `CaptionSettingsMenuItem` is "clicked". See 4800 * {@link ClickableComponent} for more detailed information on what a click can be. 4801 * 4802 * @param {EventTarget~Event} [event] 4803 * The `keydown`, `tap`, or `click` event that caused this function to be 4804 * called. 4805 * 4806 * @listens tap 4807 * @listens click 4808 */ 4809 4810 4811 CaptionSettingsMenuItem.prototype.handleClick = function handleClick(event) { 4812 this.player().getChild('textTrackSettings').show(); 4813 this.player().getChild('textTrackSettings').el_.focus(); 4814 }; 4815 4816 return CaptionSettingsMenuItem; 4817}(_textTrackMenuItem2['default']); 4818 4819_component2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem); 4820exports['default'] = CaptionSettingsMenuItem; 4821 4822},{"31":31,"5":5}],24:[function(_dereq_,module,exports){ 4823'use strict'; 4824 4825exports.__esModule = true; 4826 4827var _textTrackButton = _dereq_(30); 4828 4829var _textTrackButton2 = _interopRequireDefault(_textTrackButton); 4830 4831var _component = _dereq_(5); 4832 4833var _component2 = _interopRequireDefault(_component); 4834 4835var _captionSettingsMenuItem = _dereq_(23); 4836 4837var _captionSettingsMenuItem2 = _interopRequireDefault(_captionSettingsMenuItem); 4838 4839function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4840 4841function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4842 4843function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 4844 4845function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
4845onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4846 * @file captions-button.js 4847 */ 4848 4849 4850/** 4851 * The button component for toggling and selecting captions 4852 * 4853 * @extends TextTrackButton 4854 */ 4855var CaptionsButton = function (_TextTrackButton) { 4856 _inherits(CaptionsButton, _TextTrackButton); 4857 4858 /** 4859 * Creates an instance of this class. 4860 * 4861 * @param {Player} player 4862 * The `Player` that this class should be attached to. 4863 * 4864 * @param {Object} [options] 4865 * The key/value store of player options. 4866 * 4867 * @param {Component~ReadyCallback} [ready] 4868 * The function to call when this component is ready. 4869 */ 4870 function CaptionsButton(player, options, ready) { 4871 _classCallCheck(this, CaptionsButton); 4872 4873 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready)); 4874 4875 _this.el_.setAttribute('aria-label', 'Captions Menu'); 4876 return _this; 4877 } 4878 4879 /** 4880 * Builds the default DOM `className`. 4881 * 4882 * @return {string} 4883 * The DOM `className` for this object. 4884 */ 4885 4886 4887 CaptionsButton.prototype.buildCSSClass = function buildCSSClass() { 4888 return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 4889 }; 4890 4891 /** 4892 * Create caption menu items 4893 * 4894 * @return {CaptionSettingsMenuItem[]} 4895 * The array of current menu items. 4896 */ 4897 4898 4899 CaptionsButton.prototype.createItems = function createItems() { 4900 var items = []; 4901 4902 if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) { 4903 items.push(new _captionSettingsMenuItem2['default'](this.player_, { kind: this.kind_ })); 4904 4905 this.hideThreshold_ += 1; 4906 } 4907 4908 return _TextTrackButton.prototype.createItems.call(this, items); 4909 }; 4910 4911 return CaptionsButton; 4912}(_textTrackButton2['default']); 4913 4914/** 4915 * `kind` of TextTrack to look for to associate it with this menu. 4916 * 4917 * @type {string} 4918 * @private 4919 */ 4920 4921 4922CaptionsButton.prototype.kind_ = 'captions'; 4923 4924/** 4925 * The text that should display over the `CaptionsButton`s controls. Added for localization. 4926 * 4927 * @type {string} 4928 * @private 4929 */ 4930CaptionsButton.prototype.controlText_ = 'Captions'; 4931 4932_component2['default'].registerComponent('CaptionsButton', CaptionsButton); 4933exports['default'] = CaptionsButton; 4934 4935},{"23":23,"30":30,"5":5}],25:[function(_dereq_,module,exports){ 4936'use strict'; 4937 4938exports.__esModule = true; 4939 4940var _textTrackButton = _dereq_(30); 4941 4942var _textTrackButton2 = _interopRequireDefault(_textTrackButton); 4943 4944var _component = _dereq_(5); 4945 4946var _component2 = _interopRequireDefault(_component); 4947 4948var _chaptersTrackMenuItem = _dereq_(26); 4949 4950var _chaptersTrackMenuItem2 = _interopRequireDefault(_chaptersTrackMenuItem); 4951 4952var _toTitleCase = _dereq_(91); 4953 4954var _toTitleCase2 = _interopRequireDefault(_toTitleCase); 4955 4956function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4957 4958function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4959 4960function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 4961 4962function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
vendor: 4,377 bytes, lines 4962-5079
4962onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4963 * @file chapters-button.js 4964 */ 4965 4966 4967/** 4968 * The button component for toggling and selecting chapters 4969 * Chapters act much differently than other text tracks 4970 * Cues are navigation vs. other tracks of alternative languages 4971 * 4972 * @extends TextTrackButton 4973 */ 4974var ChaptersButton = function (_TextTrackButton) { 4975 _inherits(ChaptersButton, _TextTrackButton); 4976 4977 /** 4978 * Creates an instance of this class. 4979 * 4980 * @param {Player} player 4981 * The `Player` that this class should be attached to. 4982 * 4983 * @param {Object} [options] 4984 * The key/value store of player options. 4985 * 4986 * @param {Component~ReadyCallback} [ready] 4987 * The function to call when this function is ready. 4988 */ 4989 function ChaptersButton(player, options, ready) { 4990 _classCallCheck(this, ChaptersButton); 4991 4992 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready)); 4993 4994 _this.el_.setAttribute('aria-label', 'Chapters Menu'); 4995 return _this; 4996 } 4997 4998 /** 4999 * Builds the default DOM `className`. 5000 * 5001 * @return {string} 5002 * The DOM `className` for this object. 5003 */ 5004 5005 5006 ChaptersButton.prototype.buildCSSClass = function buildCSSClass() { 5007 return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 5008 }; 5009 5010 /** 5011 * Update the menu based on the current state of its items. 5012 * 5013 * @param {EventTarget~Event} [event] 5014 * An event that triggered this function to run. 5015 * 5016 * @listens TextTrackList#addtrack 5017 * @listens TextTrackList#removetrack 5018 * @listens TextTrackList#change 5019 */ 5020 5021 5022 ChaptersButton.prototype.update = function update(event) { 5023 if (!this.track_ || event && (event.type === 'addtrack' || event.type === 'removetrack')) { 5024 this.setTrack(this.findChaptersTrack()); 5025 } 5026 _TextTrackButton.prototype.update.call(this); 5027 }; 5028 5029 /** 5030 * Set the currently selected track for the chapters button. 5031 * 5032 * @param {TextTrack} track 5033 * The new track to select. Nothing will change if this is the currently selected 5034 * track. 5035 */ 5036 5037 5038 ChaptersButton.prototype.setTrack = function setTrack(track) { 5039 if (this.track_ === track) { 5040 return; 5041 } 5042 5043 if (!this.updateHandler_) { 5044 this.updateHandler_ = this.update.bind(this); 5045 } 5046 5047 // here this.track_ refers to the old track instance 5048 if (this.track_) { 5049 var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_); 5050 5051 if (remoteTextTrackEl) { 5052 remoteTextTrackEl.removeEventListener('load', this.updateHandler_); 5053 } 5054 5055 this.track_ = null; 5056 } 5057 5058 this.track_ = track; 5059 5060 // here this.track_ refers to the new track instance 5061 if (this.track_) { 5062 this.track_.mode = 'hidden'; 5063 5064 var _remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_); 5065 5066 if (_remoteTextTrackEl) { 5067 _remoteTextTrackEl.addEventListener('load', this.updateHandler_); 5068 } 5069 } 5070 }; 5071 5072 /** 5073 * Find the track object that is currently in use by this ChaptersButton 5074 * 5075 * @return {TextTrack|undefined} 5076 * The current track or undefined if none was found. 5077 */ 5078 5079
5080 ChaptersButton.prototype.findChaptersTrack = function findChaptersTrack() { 5081 var tracks = this.player_.textTracks() || []; 5082 5083 for (var i = tracks.length - 1; i >= 0; i--) { 5084 // We will always choose the last track as our chaptersTrack 5085 var track = tracks[i]; 5086 5087 if (track.kind === this.kind_) { 5088 return track; 5089 } 5090 } 5091 }; 5092 5093 /** 5094 * Get the caption for the ChaptersButton based on the track label. This will also 5095 * use the current tracks localized kind as a fallback if a label does not exist. 5096 * 5097 * @return {string} 5098 * The tracks current label or the localized track kind. 5099 */ 5100 5101 5102 ChaptersButton.prototype.getMenuCaption = function getMenuCaption() { 5103 if (this.track_ && this.track_.label) { 5104 return this.track_.label; 5105 } 5106 return this.localize((0, _toTitleCase2['default'])(this.kind_)); 5107 }; 5108 5109 /** 5110 * Create menu from chapter track 5111 * 5112 * @return {Menu} 5113 * New menu for the chapter buttons 5114 */ 5115 5116 5117 ChaptersButton.prototype.createMenu = function createMenu() { 5118 this.options_.title = this.getMenuCaption(); 5119 return _TextTrackButton.prototype.createMenu.call(this); 5120 }; 5121 5122 /** 5123 * Create a menu item for each text track 5124 * 5125 * @return {TextTrackMenuItem[]} 5126 * Array of menu items 5127 */ 5128 5129 5130 ChaptersButton.prototype.createItems = function createItems() { 5131 var items = []; 5132 5133 if (!this.track_) { 5134 return items; 5135 } 5136 5137 var cues = this.track_.cues; 5138 5139 if (!cues) { 5140 return items; 5141 } 5142 5143 for (var i = 0, l = cues.length; i < l; i++) { 5144 var cue = cues[i]; 5145 var mi = new _chaptersTrackMenuItem2['default'](this.player_, { track: this.track_, cue: cue }); 5146 5147 items.push(mi); 5148 } 5149 5150 return items; 5151 }; 5152 5153 return ChaptersButton; 5154}(_textTrackButton2['default']); 5155 5156/** 5157 * `kind` of TextTrack to look for to associate it with this menu. 5158 * 5159 * @type {string} 5160 * @private 5161 */ 5162 5163 5164ChaptersButton.prototype.kind_ = 'chapters'; 5165 5166/** 5167 * The text that should display over the `ChaptersButton`s controls. Added for localization. 5168 * 5169 * @type {string} 5170 * @private 5171 */ 5172ChaptersButton.prototype.controlText_ = 'Chapters'; 5173 5174_component2['default'].registerComponent('ChaptersButton', ChaptersButton); 5175exports['default'] = ChaptersButton; 5176 5177},{"26":26,"30":30,"5":5,"91":91}],26:[function(_dereq_,module,exports){ 5178'use strict'; 5179 5180exports.__esModule = true; 5181 5182var _menuItem = _dereq_(48); 5183 5184var _menuItem2 = _interopRequireDefault(_menuItem); 5185 5186var _component = _dereq_(5); 5187 5188var _component2 = _interopRequireDefault(_component); 5189 5190var _fn = _dereq_(83); 5191 5192var Fn = _interopRequireWildcard(_fn); 5193 5194function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 5195 5196function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5197 5198function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5199 5200function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 5201 5202function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 5203 * @file chapters-track-menu-item.js 5204 */ 5205 5206 5207/** 5208 * The chapter track menu item 5209 * 5210 * @extends MenuItem 5211 */ 5212var ChaptersTrackMenuItem = function (_MenuItem) { 5213 _inherits(ChaptersTrackMenuItem, _MenuItem); 5214 5215 /** 5216 * Creates an instance of this class. 5217 * 5218 * @param {Player} player 5219 * The `Player` that this class should be attached to. 5220 * 5221 * @param {Object} [options] 5222 * The key/value store of player options. 5223 */ 5224 function ChaptersTrackMenuItem(player, options) { 5225 _classCallCheck(this, ChaptersTrackMenuItem); 5226 5227 var track = options.track; 5228 var cue = options.cue; 5229 var currentTime = player.currentTime(); 5230 5231 // Modify options for parent MenuItem class's init. 5232 options.selectable = true; 5233 options.label = cue.text; 5234 options.selected = cue.startTime <= currentTime && currentTime < cue.endTime; 5235 5236 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options)); 5237 5238 _this.track = track; 5239 _this.cue = cue; 5240 track.addEventListener('cuechange', Fn.bind(_this, _this.update)); 5241 return _this; 5242 } 5243 5244 /** 5245 * This gets called when an `ChaptersTrackMenuItem` is "clicked". See 5246 * {@link ClickableComponent} for more detailed information on what a click can be. 5247 * 5248 * @param {EventTarget~Event} [event]
5249 * The `keydown`, `tap`, or `click` event that caused this function to be 5250 * called. 5251 * 5252 * @listens tap 5253 * @listens click 5254 */ 5255 5256 5257 ChaptersTrackMenuItem.prototype.handleClick = function handleClick(event) { 5258 _MenuItem.prototype.handleClick.call(this); 5259 this.player_.currentTime(this.cue.startTime); 5260 this.update(this.cue.startTime); 5261 }; 5262 5263 /** 5264 * Update chapter menu item 5265 * 5266 * @param {EventTarget~Event} [event] 5267 * The `cuechange` event that caused this function to run. 5268 * 5269 * @listens TextTrack#cuechange 5270 */ 5271 5272 5273 ChaptersTrackMenuItem.prototype.update = function update(event) { 5274 var cue = this.cue; 5275 var currentTime = this.player_.currentTime(); 5276 5277 // vjs.log(currentTime, cue.startTime); 5278 this.selected(cue.startTime <= currentTime && currentTime < cue.endTime); 5279 }; 5280 5281 return ChaptersTrackMenuItem; 5282}(_menuItem2['default']); 5283 5284_component2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem); 5285exports['default'] = ChaptersTrackMenuItem; 5286 5287},{"48":48,"5":5,"83":83}],27:[function(_dereq_,module,exports){ 5288'use strict'; 5289 5290exports.__esModule = true; 5291 5292var _textTrackButton = _dereq_(30); 5293 5294var _textTrackButton2 = _interopRequireDefault(_textTrackButton); 5295 5296var _component = _dereq_(5); 5297 5298var _component2 = _interopRequireDefault(_component); 5299 5300var _fn = _dereq_(83); 5301 5302var Fn = _interopRequireWildcard(_fn); 5303 5304function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 5305 5306function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5307 5308function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5309 5310function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 5311 5312function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 5313 * @file descriptions-button.js 5314 */ 5315 5316 5317/** 5318 * The button component for toggling and selecting descriptions 5319 * 5320 * @extends TextTrackButton 5321 */ 5322var DescriptionsButton = function (_TextTrackButton) { 5323 _inherits(DescriptionsButton, _TextTrackButton); 5324 5325 /** 5326 * Creates an instance of this class. 5327 * 5328 * @param {Player} player 5329 * The `Player` that this class should be attached to. 5330 * 5331 * @param {Object} [options] 5332 * The key/value store of player options. 5333 * 5334 * @param {Component~ReadyCallback} [ready] 5335 * The function to call when this component is ready. 5336 */ 5337 function DescriptionsButton(player, options, ready) { 5338 _classCallCheck(this, DescriptionsButton); 5339 5340 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready)); 5341 5342 _this.el_.setAttribute('aria-label', 'Descriptions Menu'); 5343 5344 var tracks = player.textTracks(); 5345 5346 if (tracks) { 5347 var changeHandler = Fn.bind(_this, _this.handleTracksChange); 5348 5349 tracks.addEventListener('change', changeHandler); 5350 _this.on('dispose', function () { 5351 tracks.removeEventListener('change', changeHandler); 5352 }); 5353 } 5354 return _this; 5355 } 5356 5357 /** 5358 * Handle text track change 5359 * 5360 * @param {EventTarget~Event} event 5361 * The event that caused this function to run 5362 * 5363 * @listens TextTrackList#change 5364 */ 5365 5366 5367 DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) { 5368 var tracks = this.player().textTracks(); 5369 var disabled = false;
5370 5371 // Check whether a track of a different kind is showing 5372 for (var i = 0, l = tracks.length; i < l; i++) { 5373 var track = tracks[i]; 5374 5375 if (track.kind !== this.kind_ && track.mode === 'showing') { 5376 disabled = true; 5377 break; 5378 } 5379 } 5380 5381 // If another track is showing, disable this menu button 5382 if (disabled) { 5383 this.disable(); 5384 } else { 5385 this.enable(); 5386 } 5387 }; 5388 5389 /** 5390 * Builds the default DOM `className`. 5391 * 5392 * @return {string} 5393 * The DOM `className` for this object. 5394 */ 5395 5396 5397 DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() { 5398 return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 5399 }; 5400 5401 return DescriptionsButton; 5402}(_textTrackButton2['default']); 5403 5404/** 5405 * `kind` of TextTrack to look for to associate it with this menu. 5406 * 5407 * @type {string} 5408 * @private 5409 */ 5410 5411 5412DescriptionsButton.prototype.kind_ = 'descriptions'; 5413 5414/** 5415 * The text that should display over the `DescriptionsButton`s controls. Added for localization. 5416 * 5417 * @type {string} 5418 * @private 5419 */ 5420DescriptionsButton.prototype.controlText_ = 'Descriptions'; 5421 5422_component2['default'].registerComponent('DescriptionsButton', DescriptionsButton); 5423exports['default'] = DescriptionsButton; 5424 5425},{"30":30,"5":5,"83":83}],28:[function(_dereq_,module,exports){ 5426'use strict'; 5427 5428exports.__esModule = true; 5429 5430var _textTrackMenuItem = _dereq_(31); 5431 5432var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem); 5433 5434var _component = _dereq_(5); 5435 5436var _component2 = _interopRequireDefault(_component); 5437 5438function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5439 5440function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5441 5442function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 5443 5444function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 5445 * @file off-text-track-menu-item.js 5446 */ 5447 5448 5449/** 5450 * A special menu item for turning of a specific type of text track 5451 * 5452 * @extends TextTrackMenuItem 5453 */ 5454var OffTextTrackMenuItem = function (_TextTrackMenuItem) { 5455 _inherits(OffTextTrackMenuItem, _TextTrackMenuItem); 5456 5457 /** 5458 * Creates an instance of this class. 5459 * 5460 * @param {Player} player 5461 * The `Player` that this class should be attached to. 5462 * 5463 * @param {Object} [options] 5464 * The key/value store of player options. 5465 */ 5466 function OffTextTrackMenuItem(player, options) { 5467 _classCallCheck(this, OffTextTrackMenuItem); 5468 5469 // Create pseudo track info 5470 // Requires options['kind'] 5471 options.track = { 5472 player: player, 5473 kind: options.kind, 5474 label: options.kind + ' off', 5475 'default': false, 5476 mode: 'disabled' 5477 }; 5478 5479 // MenuItem is selectable 5480 options.selectable = true; 5481 5482 var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options)); 5483 5484 _this.selected(true); 5485 return _this; 5486 } 5487 5488 /** 5489 * Handle text track change 5490 * 5491 * @param {EventTarget~Event} event 5492 * The event that caused this function to run 5493 */ 5494 5495 5496 OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { 5497 var tracks = this.player().textTracks(); 5498 var selected = true; 5499 5500 for (var i = 0, l = tracks.length; i < l; i++) { 5501 var track = tracks[i]; 5502 5503 if (track.kind === this.track.kind && track.mode === 'showing') { 5504 selected = false;
5505 break; 5506 } 5507 } 5508 5509 this.selected(selected); 5510 }; 5511 5512 return OffTextTrackMenuItem; 5513}(_textTrackMenuItem2['default']); 5514 5515_component2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem); 5516exports['default'] = OffTextTrackMenuItem; 5517 5518},{"31":31,"5":5}],29:[function(_dereq_,module,exports){ 5519'use strict'; 5520 5521exports.__esModule = true; 5522 5523var _textTrackButton = _dereq_(30); 5524 5525var _textTrackButton2 = _interopRequireDefault(_textTrackButton); 5526 5527var _component = _dereq_(5); 5528 5529var _component2 = _interopRequireDefault(_component); 5530 5531function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5532 5533function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5534 5535function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 5536 5537function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 5538 * @file subtitles-button.js 5539 */ 5540 5541 5542/** 5543 * The button component for toggling and selecting subtitles 5544 * 5545 * @extends TextTrackButton 5546 */ 5547var SubtitlesButton = function (_TextTrackButton) { 5548 _inherits(SubtitlesButton, _TextTrackButton); 5549 5550 /** 5551 * Creates an instance of this class. 5552 * 5553 * @param {Player} player 5554 * The `Player` that this class should be attached to. 5555 * 5556 * @param {Object} [options] 5557 * The key/value store of player options. 5558 * 5559 * @param {Component~ReadyCallback} [ready] 5560 * The function to call when this component is ready. 5561 */ 5562 function SubtitlesButton(player, options, ready) { 5563 _classCallCheck(this, SubtitlesButton); 5564 5565 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready)); 5566 5567 _this.el_.setAttribute('aria-label', 'Subtitles Menu'); 5568 return _this; 5569 } 5570 5571 /** 5572 * Builds the default DOM `className`. 5573 * 5574 * @return {string} 5575 * The DOM `className` for this object. 5576 */ 5577 5578 5579 SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() { 5580 return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 5581 }; 5582 5583 return SubtitlesButton; 5584}(_textTrackButton2['default']); 5585 5586/** 5587 * `kind` of TextTrack to look for to associate it with this menu. 5588 * 5589 * @type {string} 5590 * @private 5591 */ 5592 5593 5594SubtitlesButton.prototype.kind_ = 'subtitles'; 5595 5596/** 5597 * The text that should display over the `SubtitlesButton`s controls. Added for localization. 5598 * 5599 * @type {string} 5600 * @private 5601 */ 5602SubtitlesButton.prototype.controlText_ = 'Subtitles'; 5603 5604_component2['default'].registerComponent('SubtitlesButton', SubtitlesButton); 5605exports['default'] = SubtitlesButton; 5606 5607},{"30":30,"5":5}],30:[function(_dereq_,module,exports){ 5608'use strict'; 5609 5610exports.__esModule = true; 5611 5612var _trackButton = _dereq_(36); 5613 5614var _trackButton2 = _interopRequireDefault(_trackButton); 5615 5616var _component = _dereq_(5); 5617 5618var _component2 = _interopRequireDefault(_component); 5619 5620var _textTrackMenuItem = _dereq_(31); 5621 5622var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem); 5623 5624var _offTextTrackMenuItem = _dereq_(28); 5625 5626var _offTextTrackMenuItem2 = _interopRequireDefault(_offTextTrackMenuItem); 5627 5628function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5629 5630function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5631 5632function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 5633 5634function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
5634onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 5635 * @file text-track-button.js 5636 */ 5637 5638 5639/** 5640 * The base class for buttons that toggle specific text track types (e.g. subtitles) 5641 * 5642 * @extends MenuButton 5643 */ 5644var TextTrackButton = function (_TrackButton) { 5645 _inherits(TextTrackButton, _TrackButton); 5646 5647 /** 5648 * Creates an instance of this class. 5649 * 5650 * @param {Player} player 5651 * The `Player` that this class should be attached to. 5652 * 5653 * @param {Object} [options={}] 5654 * The key/value store of player options. 5655 */ 5656 function TextTrackButton(player) { 5657 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 5658 5659 _classCallCheck(this, TextTrackButton); 5660 5661 options.tracks = player.textTracks(); 5662 5663 return _possibleConstructorReturn(this, _TrackButton.call(this, player, options)); 5664 } 5665 5666 /** 5667 * Create a menu item for each text track 5668 * 5669 * @param {TextTrackMenuItem[]} [items=[]] 5670 * Existing array of items to use during creation 5671 * 5672 * @return {TextTrackMenuItem[]} 5673 * Array of menu items that were created 5674 */ 5675 5676 5677 TextTrackButton.prototype.createItems = function createItems() { 5678 var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 5679 5680 // Add an OFF menu item to turn all tracks off 5681 items.push(new _offTextTrackMenuItem2['default'](this.player_, { kind: this.kind_ })); 5682 this.hideThreshold_ += 1; 5683 5684 var tracks = this.player_.textTracks(); 5685 5686 if (!tracks) { 5687 return items; 5688 } 5689 5690 for (var i = 0; i < tracks.length; i++) { 5691 var track = tracks[i]; 5692 5693 // only add tracks that are of the appropriate kind and have a label 5694 if (track.kind === this.kind_) { 5695 items.push(new _textTrackMenuItem2['default'](this.player_, { 5696 track: track, 5697 // MenuItem is selectable 5698 selectable: true 5699 })); 5700 } 5701 } 5702 5703 return items; 5704 }; 5705 5706 return TextTrackButton; 5707}(_trackButton2['default']); 5708 5709_component2['default'].registerComponent('TextTrackButton', TextTrackButton); 5710exports['default'] = TextTrackButton; 5711 5712},{"28":28,"31":31,"36":36,"5":5}],31:[function(_dereq_,module,exports){ 5713'use strict'; 5714 5715exports.__esModule = true; 5716 5717var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 5718 5719var _menuItem = _dereq_(48); 5720 5721var _menuItem2 = _interopRequireDefault(_menuItem); 5722 5723var _component = _dereq_(5); 5724 5725var _component2 = _interopRequireDefault(_component); 5726 5727var _fn = _dereq_(83); 5728 5729var Fn = _interopRequireWildcard(_fn); 5730 5731var _window = _dereq_(95); 5732 5733var _window2 = _interopRequireDefault(_window); 5734 5735var _document = _dereq_(94); 5736 5737var _document2 = _interopRequireDefault(_document); 5738 5739function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 5740 5741function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5742 5743function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5744 5745function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 5746 5747function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
5747onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 5748 * @file text-track-menu-item.js 5749 */ 5750 5751 5752/** 5753 * The specific menu item type for selecting a language within a text track kind 5754 * 5755 * @extends MenuItem 5756 */ 5757var TextTrackMenuItem = function (_MenuItem) { 5758 _inherits(TextTrackMenuItem, _MenuItem); 5759 5760 /** 5761 * Creates an instance of this class. 5762 * 5763 * @param {Player} player 5764 * The `Player` that this class should be attached to. 5765 * 5766 * @param {Object} [options] 5767 * The key/value store of player options. 5768 */ 5769 function TextTrackMenuItem(player, options) { 5770 _classCallCheck(this, TextTrackMenuItem); 5771 5772 var track = options.track; 5773 var tracks = player.textTracks(); 5774 5775 // Modify options for parent MenuItem class's init. 5776 options.label = track.label || track.language || 'Unknown'; 5777 options.selected = track['default'] || track.mode === 'showing'; 5778 5779 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options)); 5780 5781 _this.track = track; 5782 5783 if (tracks) { 5784 var changeHandler = Fn.bind(_this, _this.handleTracksChange); 5785 5786 player.on(['loadstart', 'texttrackchange'], changeHandler); 5787 tracks.addEventListener('change', changeHandler); 5788 _this.on('dispose', function () { 5789 tracks.removeEventListener('change', changeHandler); 5790 }); 5791 } 5792 5793 // iOS7 doesn't dispatch change events to TextTrackLists when an 5794 // associated track's mode changes. Without something like 5795 // Object.observe() (also not present on iOS7), it's not 5796 // possible to detect changes to the mode attribute and polyfill 5797 // the change event. As a poor substitute, we manually dispatch 5798 // change events whenever the controls modify the mode. 5799 if (tracks && tracks.onchange === undefined) { 5800 var event = void 0; 5801 5802 _this.on(['tap', 'click'], function () { 5803 if (_typeof(_window2['default'].Event) !== 'object') { 5804 // Android 2.3 throws an Illegal Constructor error for window.Event 5805 try { 5806 event = new _window2['default'].Event('change'); 5807 } catch (err) { 5808 // continue regardless of error 5809 } 5810 } 5811 5812 if (!event) { 5813 event = _document2['default'].createEvent('Event'); 5814 event.initEvent('change', true, true); 5815 } 5816 5817 tracks.dispatchEvent(event); 5818 }); 5819 } 5820 return _this; 5821 } 5822 5823 /** 5824 * This gets called when an `TextTrackMenuItem` is "clicked". See 5825 * {@link ClickableComponent} for more detailed information on what a click can be. 5826 * 5827 * @param {EventTarget~Event} event 5828 * The `keydown`, `tap`, or `click` event that caused this function to be 5829 * called. 5830 * 5831 * @listens tap 5832 * @listens click 5833 */ 5834 5835 5836 TextTrackMenuItem.prototype.handleClick = function handleClick(event) { 5837 var kind = this.track.kind; 5838 var tracks = this.player_.textTracks(); 5839 5840 _MenuItem.prototype.handleClick.call(this, event); 5841 5842 if (!tracks) { 5843 return; 5844 } 5845 5846 for (var i = 0; i < tracks.length; i++) { 5847 var track = tracks[i]; 5848 5849 if (track.kind !== kind) { 5850 continue; 5851 } 5852 5853 if (track === this.track) { 5854 track.mode = 'showing'; 5855 } else { 5856 track.mode = 'disabled'; 5857 } 5858 } 5859 }; 5860 5861 /** 5862 * Handle text track list change 5863 * 5864 * @param {EventTarget~Event} event 5865 * The `change` event that caused this function to be called. 5866 * 5867 * @listens TextTrackList#change 5868 */ 5869 5870 5871 TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { 5872 this.selected(this.track.mode === 'showing'); 5873 }; 5874 5875 return TextTrackMenuItem; 5876}(_menuItem2['default']); 5877 5878_component2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem); 5879exports['default'] = TextTrackMenuItem; 5880 5881},{"48":48,"5":5,"83":83,"94":94,"95":95}],32:[function(_dereq_,module,exports){ 5882'use strict'; 5883 5884exports.__esModule = true; 5885 5886var _component = _dereq_(5); 5887 5888var _component2 = _interopRequireDefault(_component); 5889 5890var _dom = _dereq_(81); 5891 5892var Dom = _interopRequireWildcard(_dom); 5893 5894var _formatTime = _dereq_(84); 5895 5896var _formatTime2 = _interopRequireDefault(_formatTime); 5897 5898function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 5899 5900function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5901 5902function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5903 5904function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 5905 5906function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
5906onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 5907 * @file current-time-display.js 5908 */ 5909 5910 5911/** 5912 * Displays the current time 5913 * 5914 * @extends Component 5915 */ 5916var CurrentTimeDisplay = function (_Component) { 5917 _inherits(CurrentTimeDisplay, _Component); 5918 5919 /** 5920 * Creates an instance of this class. 5921 * 5922 * @param {Player} player 5923 * The `Player` that this class should be attached to. 5924 * 5925 * @param {Object} [options] 5926 * The key/value store of player options. 5927 */ 5928 function CurrentTimeDisplay(player, options) { 5929 _classCallCheck(this, CurrentTimeDisplay); 5930 5931 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 5932 5933 _this.on(player, 'timeupdate', _this.updateContent); 5934 return _this; 5935 } 5936 5937 /** 5938 * Create the `Component`'s DOM element 5939 * 5940 * @return {Element} 5941 * The element that was created. 5942 */ 5943 5944 5945 CurrentTimeDisplay.prototype.createEl = function createEl() { 5946 var el = _Component.prototype.createEl.call(this, 'div', { 5947 className: 'vjs-current-time vjs-time-control vjs-control' 5948 }); 5949 5950 this.contentEl_ = Dom.createEl('div', { 5951 className: 'vjs-current-time-display', 5952 // label the current time for screen reader users 5953 innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00' 5954 }, { 5955 // tell screen readers not to automatically read the time as it changes 5956 'aria-live': 'off' 5957 }); 5958 5959 el.appendChild(this.contentEl_); 5960 return el; 5961 }; 5962 5963 /** 5964 * Update current time display 5965 * 5966 * @param {EventTarget~Event} [event] 5967 * The `timeupdate` event that caused this function to run. 5968 * 5969 * @listens Player#timeupdate 5970 */ 5971 5972 5973 CurrentTimeDisplay.prototype.updateContent = function updateContent(event) { 5974 // Allows for smooth scrubbing, when player can't keep up. 5975 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 5976 var localizedText = this.localize('Current Time'); 5977 var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration()); 5978 5979 if (formattedTime !== this.formattedTime_) { 5980 this.formattedTime_ = formattedTime; 5981 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; 5982 } 5983 }; 5984 5985 return CurrentTimeDisplay; 5986}(_component2['default']); 5987 5988_component2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay); 5989exports['default'] = CurrentTimeDisplay; 5990 5991},{"5":5,"81":81,"84":84}],33:[function(_dereq_,module,exports){ 5992'use strict'; 5993 5994exports.__esModule = true; 5995 5996var _component = _dereq_(5); 5997 5998var _component2 = _interopRequireDefault(_component); 5999 6000var _dom = _dereq_(81); 6001 6002var Dom = _interopRequireWildcard(_dom); 6003 6004var _formatTime = _dereq_(84); 6005 6006var _formatTime2 = _interopRequireDefault(_formatTime); 6007 6008function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 6009 6010function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6011 6012function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6013 6014function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 6015 6016function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
6016onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6017 * @file duration-display.js 6018 */ 6019 6020 6021/** 6022 * Displays the duration 6023 * 6024 * @extends Component 6025 */ 6026var DurationDisplay = function (_Component) { 6027 _inherits(DurationDisplay, _Component); 6028 6029 /** 6030 * Creates an instance of this class. 6031 * 6032 * @param {Player} player 6033 * The `Player` that this class should be attached to. 6034 * 6035 * @param {Object} [options] 6036 * The key/value store of player options. 6037 */ 6038 function DurationDisplay(player, options) { 6039 _classCallCheck(this, DurationDisplay); 6040 6041 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 6042 6043 _this.on(player, 'durationchange', _this.updateContent); 6044 6045 // Also listen for timeupdate and loadedmetadata because removing those 6046 // listeners could have broken dependent applications/libraries. These 6047 // can likely be removed for 6.0. 6048 _this.on(player, 'timeupdate', _this.updateContent); 6049 _this.on(player, 'loadedmetadata', _this.updateContent); 6050 return _this; 6051 } 6052 6053 /** 6054 * Create the `Component`'s DOM element 6055 * 6056 * @return {Element} 6057 * The element that was created. 6058 */ 6059 6060 6061 DurationDisplay.prototype.createEl = function createEl() { 6062 var el = _Component.prototype.createEl.call(this, 'div', { 6063 className: 'vjs-duration vjs-time-control vjs-control' 6064 }); 6065 6066 this.contentEl_ = Dom.createEl('div', { 6067 className: 'vjs-duration-display', 6068 // label the duration time for screen reader users 6069 innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00' 6070 }, { 6071 // tell screen readers not to automatically read the time as it changes 6072 'aria-live': 'off' 6073 }); 6074 6075 el.appendChild(this.contentEl_); 6076 return el; 6077 }; 6078 6079 /** 6080 * Update duration time display. 6081 * 6082 * @param {EventTarget~Event} [event] 6083 * The `durationchange`, `timeupdate`, or `loadedmetadata` event that caused 6084 * this function to be called. 6085 * 6086 * @listens Player#durationchange 6087 * @listens Player#timeupdate 6088 * @listens Player#loadedmetadata 6089 */ 6090 6091 6092 DurationDisplay.prototype.updateContent = function updateContent(event) { 6093 var duration = this.player_.duration(); 6094 6095 if (duration && this.duration_ !== duration) { 6096 this.duration_ = duration; 6097 var localizedText = this.localize('Duration Time'); 6098 var formattedTime = (0, _formatTime2['default'])(duration); 6099 6100 // label the duration time for screen reader users 6101 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; 6102 } 6103 }; 6104 6105 return DurationDisplay; 6106}(_component2['default']); 6107 6108_component2['default'].registerComponent('DurationDisplay', DurationDisplay); 6109exports['default'] = DurationDisplay; 6110 6111},{"5":5,"81":81,"84":84}],34:[function(_dereq_,module,exports){ 6112'use strict'; 6113 6114exports.__esModule = true; 6115 6116var _component = _dereq_(5); 6117 6118var _component2 = _interopRequireDefault(_component); 6119 6120var _dom = _dereq_(81); 6121 6122var Dom = _interopRequireWildcard(_dom); 6123 6124var _formatTime = _dereq_(84); 6125 6126var _formatTime2 = _interopRequireDefault(_formatTime); 6127 6128function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 6129 6130function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6131 6132function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6133 6134function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 6135 6136function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
6136onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6137 * @file remaining-time-display.js 6138 */ 6139 6140 6141/** 6142 * Displays the time left in the video 6143 * 6144 * @extends Component 6145 */ 6146var RemainingTimeDisplay = function (_Component) { 6147 _inherits(RemainingTimeDisplay, _Component); 6148 6149 /** 6150 * Creates an instance of this class. 6151 * 6152 * @param {Player} player 6153 * The `Player` that this class should be attached to. 6154 * 6155 * @param {Object} [options] 6156 * The key/value store of player options. 6157 */ 6158 function RemainingTimeDisplay(player, options) { 6159 _classCallCheck(this, RemainingTimeDisplay); 6160 6161 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 6162 6163 _this.on(player, 'timeupdate', _this.updateContent); 6164 _this.on(player, 'durationchange', _this.updateContent); 6165 return _this; 6166 } 6167 6168 /** 6169 * Create the `Component`'s DOM element 6170 * 6171 * @return {Element} 6172 * The element that was created. 6173 */ 6174 6175 6176 RemainingTimeDisplay.prototype.createEl = function createEl() { 6177 var el = _Component.prototype.createEl.call(this, 'div', { 6178 className: 'vjs-remaining-time vjs-time-control vjs-control' 6179 }); 6180 6181 this.contentEl_ = Dom.createEl('div', { 6182 className: 'vjs-remaining-time-display', 6183 // label the remaining time for screen reader users 6184 innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00' 6185 }, { 6186 // tell screen readers not to automatically read the time as it changes 6187 'aria-live': 'off' 6188 }); 6189 6190 el.appendChild(this.contentEl_); 6191 return el; 6192 }; 6193 6194 /** 6195 * Update remaining time display. 6196 * 6197 * @param {EventTarget~Event} [event] 6198 * The `timeupdate` or `durationchange` event that caused this to run. 6199 * 6200 * @listens Player#timeupdate 6201 * @listens Player#durationchange 6202 */ 6203 6204 6205 RemainingTimeDisplay.prototype.updateContent = function updateContent(event) { 6206 if (this.player_.duration()) { 6207 var localizedText = this.localize('Remaining Time'); 6208 var formattedTime = (0, _formatTime2['default'])(this.player_.remainingTime()); 6209 6210 if (formattedTime !== this.formattedTime_) { 6211 this.formattedTime_ = formattedTime; 6212 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime; 6213 } 6214 } 6215 6216 // Allows for smooth scrubbing, when player can't keep up. 6217 // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime(); 6218 // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration()); 6219 }; 6220 6221 return RemainingTimeDisplay; 6222}(_component2['default']); 6223 6224_component2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay); 6225exports['default'] = RemainingTimeDisplay; 6226 6227},{"5":5,"81":81,"84":84}],35:[function(_dereq_,module,exports){ 6228'use strict'; 6229 6230exports.__esModule = true; 6231 6232var _component = _dereq_(5); 6233 6234var _component2 = _interopRequireDefault(_component); 6235 6236function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6237 6238function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6239 6240function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 6241 6242function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
6242onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6243 * @file time-divider.js 6244 */ 6245 6246 6247/** 6248 * The separator between the current time and duration. 6249 * Can be hidden if it's not needed in the design. 6250 * 6251 * @extends Component 6252 */ 6253var TimeDivider = function (_Component) { 6254 _inherits(TimeDivider, _Component); 6255 6256 function TimeDivider() { 6257 _classCallCheck(this, TimeDivider); 6258 6259 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 6260 } 6261 6262 /** 6263 * Create the component's DOM element 6264 * 6265 * @return {Element} 6266 * The element that was created. 6267 */ 6268 TimeDivider.prototype.createEl = function createEl() { 6269 return _Component.prototype.createEl.call(this, 'div', { 6270 className: 'vjs-time-control vjs-time-divider', 6271 innerHTML: '<div><span>/</span></div>' 6272 }); 6273 }; 6274 6275 return TimeDivider; 6276}(_component2['default']); 6277 6278_component2['default'].registerComponent('TimeDivider', TimeDivider); 6279exports['default'] = TimeDivider; 6280 6281},{"5":5}],36:[function(_dereq_,module,exports){ 6282'use strict'; 6283 6284exports.__esModule = true; 6285 6286var _menuButton = _dereq_(47); 6287 6288var _menuButton2 = _interopRequireDefault(_menuButton); 6289 6290var _component = _dereq_(5); 6291 6292var _component2 = _interopRequireDefault(_component); 6293 6294var _fn = _dereq_(83); 6295 6296var Fn = _interopRequireWildcard(_fn); 6297 6298function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 6299 6300function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6301 6302function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6303 6304function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 6305 6306function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6307 * @file track-button.js 6308 */ 6309 6310 6311/** 6312 * The base class for buttons that toggle specific track types (e.g. subtitles). 6313 * 6314 * @extends MenuButton 6315 */ 6316var TrackButton = function (_MenuButton) { 6317 _inherits(TrackButton, _MenuButton); 6318 6319 /** 6320 * Creates an instance of this class. 6321 * 6322 * @param {Player} player 6323 * The `Player` that this class should be attached to. 6324 * 6325 * @param {Object} [options] 6326 * The key/value store of player options. 6327 */ 6328 function TrackButton(player, options) { 6329 _classCallCheck(this, TrackButton); 6330 6331 var tracks = options.tracks; 6332 6333 var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options)); 6334 6335 if (_this.items.length <= 1) { 6336 _this.hide(); 6337 } 6338 6339 if (!tracks) { 6340 return _possibleConstructorReturn(_this); 6341 } 6342 6343 var updateHandler = Fn.bind(_this, _this.update); 6344 6345 tracks.addEventListener('removetrack', updateHandler); 6346 tracks.addEventListener('addtrack', updateHandler); 6347 6348 _this.player_.on('dispose', function () { 6349 tracks.removeEventListener('removetrack', updateHandler); 6350 tracks.removeEventListener('addtrack', updateHandler); 6351 }); 6352 return _this; 6353 } 6354 6355 return TrackButton; 6356}(_menuButton2['default']); 6357 6358_component2['default'].registerComponent('TrackButton', TrackButton); 6359exports['default'] = TrackButton; 6360 6361},{"47":47,"5":5,"83":83}],37:[function(_dereq_,module,exports){ 6362'use strict'; 6363 6364exports.__esModule = true; 6365 6366var _slider = _dereq_(57); 6367 6368var _slider2 = _interopRequireDefault(_slider); 6369 6370var _component = _dereq_(5); 6371 6372var _component2 = _interopRequireDefault(_component); 6373 6374var _fn = _dereq_(83); 6375 6376var Fn = _interopRequireWildcard(_fn); 6377 6378_dereq_(39); 6379 6380function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 6381 6382function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6383 6384function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6385 6386function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 6387 6388function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
6388onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6389 * @file volume-bar.js 6390 */ 6391 6392 6393// Required children 6394 6395 6396/** 6397 * The bar that contains the volume level and can be clicked on to adjust the level 6398 * 6399 * @extends Slider 6400 */ 6401var VolumeBar = function (_Slider) { 6402 _inherits(VolumeBar, _Slider); 6403 6404 /** 6405 * Creates an instance of this class. 6406 * 6407 * @param {Player} player 6408 * The `Player` that this class should be attached to. 6409 * 6410 * @param {Object} [options] 6411 * The key/value store of player options. 6412 */ 6413 function VolumeBar(player, options) { 6414 _classCallCheck(this, VolumeBar); 6415 6416 var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options)); 6417 6418 _this.on(player, 'volumechange', _this.updateARIAAttributes); 6419 player.ready(Fn.bind(_this, _this.updateARIAAttributes)); 6420 return _this; 6421 } 6422 6423 /** 6424 * Create the `Component`'s DOM element 6425 * 6426 * @return {Element} 6427 * The element that was created. 6428 */ 6429 6430 6431 VolumeBar.prototype.createEl = function createEl() { 6432 return _Slider.prototype.createEl.call(this, 'div', { 6433 className: 'vjs-volume-bar vjs-slider-bar' 6434 }, { 6435 'aria-label': 'volume level' 6436 }); 6437 }; 6438 6439 /** 6440 * Handle movement events on the {@link VolumeMenuButton}. 6441 * 6442 * @param {EventTarget~Event} event 6443 * The event that caused this function to run. 6444 * 6445 * @listens mousemove 6446 */ 6447 6448 6449 VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) { 6450 this.checkMuted(); 6451 this.player_.volume(this.calculateDistance(event)); 6452 }; 6453 6454 /** 6455 * If the player is muted unmute it. 6456 */ 6457 6458 6459 VolumeBar.prototype.checkMuted = function checkMuted() { 6460 if (this.player_.muted()) { 6461 this.player_.muted(false); 6462 } 6463 }; 6464 6465 /** 6466 * Get percent of volume level 6467 * 6468 * @return {number} 6469 * Volume level percent as a decimal number. 6470 */ 6471 6472 6473 VolumeBar.prototype.getPercent = function getPercent() { 6474 if (this.player_.muted()) { 6475 return 0; 6476 } 6477 return this.player_.volume(); 6478 }; 6479 6480 /** 6481 * Increase volume level for keyboard users 6482 */ 6483 6484 6485 VolumeBar.prototype.stepForward = function stepForward() { 6486 this.checkMuted(); 6487 this.player_.volume(this.player_.volume() + 0.1); 6488 }; 6489 6490 /** 6491 * Decrease volume level for keyboard users 6492 */ 6493 6494 6495 VolumeBar.prototype.stepBack = function stepBack() { 6496 this.checkMuted(); 6497 this.player_.volume(this.player_.volume() - 0.1); 6498 }; 6499 6500 /** 6501 * Update ARIA accessibility attributes 6502 * 6503 * @param {EventTarget~Event} [event] 6504 * The `volumechange` event that caused this function to run. 6505 * 6506 * @listens Player#volumechange 6507 */ 6508 6509 6510 VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes(event) { 6511 // Current value of volume bar as a percentage 6512 var volume = (this.player_.volume() * 100).toFixed(2); 6513 6514 this.el_.setAttribute('aria-valuenow', volume); 6515 this.el_.setAttribute('aria-valuetext', volume + '%'); 6516 }; 6517 6518 return VolumeBar; 6519}(_slider2['default']); 6520 6521/** 6522 * Default options for the `VolumeBar` 6523 * 6524 * @type {Object} 6525 * @private 6526 */ 6527 6528 6529VolumeBar.prototype.options_ = { 6530 children: ['volumeLevel'], 6531 barName: 'volumeLevel' 6532}; 6533 6534/** 6535 * Call the update event for this Slider when this event happens on the player. 6536 * 6537 * @type {string} 6538 */ 6539VolumeBar.prototype.playerEvent = 'volumechange'; 6540 6541_component2['default'].registerComponent('VolumeBar', VolumeBar); 6542exports['default'] = VolumeBar; 6543 6544},{"39":39,"5":5,"57":57,"83":83}],38:[function(_dereq_,module,exports){ 6545'use strict'; 6546 6547exports.__esModule = true; 6548 6549var _component = _dereq_(5); 6550 6551var _component2 = _interopRequireDefault(_component); 6552 6553_dereq_(37); 6554 6555function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6556 6557function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6558 6559function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 6560 6561function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
6561onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6562 * @file volume-control.js 6563 */ 6564 6565 6566// Required children 6567 6568 6569/** 6570 * The component for controlling the volume level 6571 * 6572 * @extends Component 6573 */ 6574var VolumeControl = function (_Component) { 6575 _inherits(VolumeControl, _Component); 6576 6577 /** 6578 * Creates an instance of this class. 6579 * 6580 * @param {Player} player 6581 * The `Player` that this class should be attached to. 6582 * 6583 * @param {Object} [options={}] 6584 * The key/value store of player options. 6585 */ 6586 function VolumeControl(player, options) { 6587 _classCallCheck(this, VolumeControl); 6588 6589 // hide volume controls when they're not supported by the current tech 6590 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 6591 6592 if (player.tech_ && player.tech_.featuresVolumeControl === false) { 6593 _this.addClass('vjs-hidden'); 6594 } 6595 _this.on(player, 'loadstart', function () { 6596 if (player.tech_.featuresVolumeControl === false) { 6597 this.addClass('vjs-hidden'); 6598 } else { 6599 this.removeClass('vjs-hidden'); 6600 } 6601 }); 6602 return _this; 6603 } 6604 6605 /** 6606 * Create the `Component`'s DOM element 6607 * 6608 * @return {Element} 6609 * The element that was created. 6610 */ 6611 6612 6613 VolumeControl.prototype.createEl = function createEl() { 6614 return _Component.prototype.createEl.call(this, 'div', { 6615 className: 'vjs-volume-control vjs-control' 6616 }); 6617 }; 6618 6619 return VolumeControl; 6620}(_component2['default']); 6621 6622/** 6623 * Default options for the `VolumeControl` 6624 * 6625 * @type {Object} 6626 * @private 6627 */ 6628 6629 6630VolumeControl.prototype.options_ = { 6631 children: ['volumeBar'] 6632}; 6633 6634_component2['default'].registerComponent('VolumeControl', VolumeControl); 6635exports['default'] = VolumeControl; 6636 6637},{"37":37,"5":5}],39:[function(_dereq_,module,exports){ 6638'use strict'; 6639 6640exports.__esModule = true; 6641 6642var _component = _dereq_(5); 6643 6644var _component2 = _interopRequireDefault(_component); 6645 6646function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6647 6648function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6649 6650function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 6651 6652function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6653 * @file volume-level.js 6654 */ 6655 6656 6657/** 6658 * Shows volume level 6659 * 6660 * @extends Component 6661 */ 6662var VolumeLevel = function (_Component) { 6663 _inherits(VolumeLevel, _Component); 6664 6665 function VolumeLevel() { 6666 _classCallCheck(this, VolumeLevel); 6667 6668 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 6669 } 6670 6671 /** 6672 * Create the `Component`'s DOM element 6673 * 6674 * @return {Element} 6675 * The element that was created. 6676 */ 6677 VolumeLevel.prototype.createEl = function createEl() { 6678 return _Component.prototype.createEl.call(this, 'div', { 6679 className: 'vjs-volume-level', 6680 innerHTML: '<span class="vjs-control-text"></span>' 6681 }); 6682 }; 6683 6684 return VolumeLevel; 6685}(_component2['default']); 6686 6687_component2['default'].registerComponent('VolumeLevel', VolumeLevel); 6688exports['default'] = VolumeLevel; 6689 6690},{"5":5}],40:[function(_dereq_,module,exports){ 6691'use strict'; 6692 6693exports.__esModule = true; 6694 6695var _fn = _dereq_(83); 6696 6697var Fn = _interopRequireWildcard(_fn); 6698 6699var _component = _dereq_(5); 6700 6701var _component2 = _interopRequireDefault(_component); 6702 6703var _popup = _dereq_(54); 6704 6705var _popup2 = _interopRequireDefault(_popup); 6706 6707var _popupButton = _dereq_(53); 6708 6709var _popupButton2 = _interopRequireDefault(_popupButton); 6710 6711var _muteToggle = _dereq_(11); 6712 6713var _muteToggle2 = _interopRequireDefault(_muteToggle); 6714 6715var _volumeBar = _dereq_(37); 6716 6717var _volumeBar2 = _interopRequireDefault(_volumeBar); 6718 6719function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6720 6721function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 6722 6723function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6724 6725function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 6726 6727function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
6727onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6728 * @file volume-menu-button.js 6729 */ 6730 6731 6732/** 6733 * Button for volume popup 6734 * 6735 * @extends PopupButton 6736 */ 6737var VolumeMenuButton = function (_PopupButton) { 6738 _inherits(VolumeMenuButton, _PopupButton); 6739 6740 /** 6741 * Creates an instance of this class. 6742 * 6743 * @param {Player} player 6744 * The `Player` that this class should be attached to. 6745 * 6746 * @param {Object} [options={}] 6747 * The key/value store of player options. 6748 */ 6749 function VolumeMenuButton(player) { 6750 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 6751 6752 _classCallCheck(this, VolumeMenuButton); 6753 6754 // Default to inline 6755 if (options.inline === undefined) { 6756 options.inline = true; 6757 } 6758 6759 // If the vertical option isn't passed at all, default to true. 6760 if (options.vertical === undefined) { 6761 // If an inline volumeMenuButton is used, we should default to using 6762 // a horizontal slider for obvious reasons. 6763 if (options.inline) { 6764 options.vertical = false;
6765 } else { 6766 options.vertical = true; 6767 } 6768 } 6769 6770 // The vertical option needs to be set on the volumeBar as well, 6771 // since that will need to be passed along to the VolumeBar constructor 6772 options.volumeBar = options.volumeBar || {}; 6773 options.volumeBar.vertical = !!options.vertical; 6774 6775 // Same listeners as MuteToggle 6776 var _this = _possibleConstructorReturn(this, _PopupButton.call(this, player, options)); 6777 6778 _this.on(player, 'volumechange', _this.volumeUpdate); 6779 _this.on(player, 'loadstart', _this.volumeUpdate); 6780 6781 // hide mute toggle if the current tech doesn't support volume control 6782 function updateVisibility() { 6783 if (player.tech_ && player.tech_.featuresVolumeControl === false) { 6784 this.addClass('vjs-hidden'); 6785 } else { 6786 this.removeClass('vjs-hidden'); 6787 } 6788 } 6789 6790 updateVisibility.call(_this); 6791 _this.on(player, 'loadstart', updateVisibility); 6792 6793 _this.on(_this.volumeBar, ['slideractive', 'focus'], function () { 6794 this.addClass('vjs-slider-active'); 6795 }); 6796 6797 _this.on(_this.volumeBar, ['sliderinactive', 'blur'], function () { 6798 this.removeClass('vjs-slider-active'); 6799 }); 6800 6801 _this.on(_this.volumeBar, ['focus'], function () { 6802 this.addClass('vjs-lock-showing'); 6803 }); 6804 6805 _this.on(_this.volumeBar, ['blur'], function () { 6806 this.removeClass('vjs-lock-showing'); 6807 }); 6808 return _this; 6809 } 6810 6811 /** 6812 * Builds the default DOM `className`. 6813 * 6814 * @return {string} 6815 * The DOM `className` for this object. 6816 */ 6817 6818 6819 VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() { 6820 var orientationClass = ''; 6821 6822 if (this.options_.vertical) { 6823 orientationClass = 'vjs-volume-menu-button-vertical'; 6824 } else { 6825 orientationClass = 'vjs-volume-menu-button-horizontal'; 6826 } 6827 6828 return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass; 6829 }; 6830 6831 /** 6832 * Create the VolumeMenuButton popup 6833 * 6834 * @return {Popup} 6835 * The popup that was created 6836 */ 6837 6838 6839 VolumeMenuButton.prototype.createPopup = function createPopup() { 6840 var popup = new _popup2['default'](this.player_, { 6841 contentElType: 'div' 6842 }); 6843 6844 var vb = new _volumeBar2['default'](this.player_, this.options_.volumeBar); 6845 6846 popup.addChild(vb); 6847 6848 this.menuContent = popup; 6849 this.volumeBar = vb; 6850 6851 this.attachVolumeBarEvents(); 6852 6853 return popup; 6854 }; 6855 6856 /** 6857 * This gets called when an `VolumeMenuButton` is "clicked". See 6858 * {@link ClickableComponent} for more detailed information on what a click can be. 6859 * 6860 * @param {EventTarget~Event} [event] 6861 * The `keydown`, `tap`, or `click` event that caused this function to be 6862 * called. 6863 * 6864 * @listens tap 6865 * @listens click 6866 */ 6867 6868 6869 VolumeMenuButton.prototype.handleClick = function handleClick(event) { 6870 _muteToggle2['default'].prototype.handleClick.call(this); 6871 _PopupButton.prototype.handleClick.call(this); 6872 }; 6873 6874 /** 6875 * Add events listeners to the created `VolumeBar`. 6876 */ 6877 6878 6879 VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() { 6880 this.menuContent.on(['mousedown', 'touchdown'], Fn.bind(this, this.handleMouseDown)); 6881 }; 6882 6883 /** 6884 * Handle the `mousedown` and `touchdown` events on the `VolumeBar` 6885 * 6886 * @param {EventTarget~Event} [event] 6887 * The `mousedown` or `touchdown` event that caused this to run. 6888 * 6889 * @listens mousedown 6890 * @listens touchdown 6891 */ 6892 6893 6894 VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) { 6895 this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove)); 6896 this.on(this.el_.ownerDocument, ['mouseup', 'touchend'], this.handleMouseUp); 6897 }; 6898 6899 /** 6900 * Handle the `mouseup` and `touchend` events on the `VolumeBar` 6901 * 6902 * @param {EventTarget~Event} [event] 6903 * The `mouseup` or `touchend` event that caused this to run. 6904 * 6905 * @listens mouseup 6906 * @listens touchend 6907 */ 6908 6909 6910 VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) { 6911 this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove)); 6912 }; 6913 6914 return VolumeMenuButton; 6915}(_popupButton2['default']); 6916 6917/** 6918 * @borrows MuteToggle#update as VolumeMenuButton#volumeUpdate 6919 */ 6920 6921 6922VolumeMenuButton.prototype.volumeUpdate = _muteToggle2['default'].prototype.update; 6923 6924/** 6925 * The text that should display over the `VolumeMenuButton`s controls. Added for localization. 6926 * 6927 * @type {string} 6928 * @private 6929 */ 6930VolumeMenuButton.prototype.controlText_ = 'Mute'; 6931 6932_component2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton); 6933exports['default'] = VolumeMenuButton; 6934 6935},{"11":11,"37":37,"5":5,"53":53,"54":54,"83":83}],41:[function(_dereq_,module,exports){ 6936'use strict'; 6937 6938exports.__esModule = true; 6939 6940var _component = _dereq_(5); 6941 6942var _component2 = _interopRequireDefault(_component); 6943 6944var _modalDialog = _dereq_(50); 6945 6946var _modalDialog2 = _interopRequireDefault(_modalDialog); 6947 6948var _mergeOptions = _dereq_(87); 6949 6950var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 6951 6952function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6953 6954function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6955 6956function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 6957 6958function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
6958onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6959 * @file error-display.js 6960 */ 6961 6962 6963/** 6964 * A display that indicates an error has occurred. This means that the video 6965 * is unplayable. 6966 * 6967 * @extends ModalDialog 6968 */ 6969var ErrorDisplay = function (_ModalDialog) { 6970 _inherits(ErrorDisplay, _ModalDialog); 6971 6972 /** 6973 * Creates an instance of this class. 6974 * 6975 * @param {Player} player 6976 * The `Player` that this class should be attached to. 6977 * 6978 * @param {Object} [options] 6979 * The key/value store of player options. 6980 */ 6981 function ErrorDisplay(player, options) { 6982 _classCallCheck(this, ErrorDisplay); 6983 6984 var _this = _possibleConstructorReturn(this, _ModalDialog.call(this, player, options)); 6985 6986 _this.on(player, 'error', _this.open); 6987 return _this; 6988 } 6989 6990 /** 6991 * Builds the default DOM `className`. 6992 * 6993 * @return {string} 6994 * The DOM `className` for this object. 6995 * 6996 * @deprecated Since version 5. 6997 */ 6998 6999 7000 ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() { 7001 return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this); 7002 }; 7003 7004 /** 7005 * Gets the localized error message based on the `Player`s error. 7006 * 7007 * @return {string} 7008 * The `Player`s error message localized or an empty string. 7009 */ 7010 7011 7012 ErrorDisplay.prototype.content = function content() { 7013 var error = this.player().error(); 7014 7015 return error ? this.localize(error.message) : ''; 7016 }; 7017 7018 return ErrorDisplay; 7019}(_modalDialog2['default']); 7020 7021/** 7022 * The default options for an `ErrorDisplay`. 7023 * 7024 * @private 7025 */ 7026 7027 7028ErrorDisplay.prototype.options_ = (0, _mergeOptions2['default'])(_modalDialog2['default'].prototype.options_, { 7029 pauseOnOpen: false, 7030 fillAlways: true, 7031 temporary: false, 7032 uncloseable: true 7033}); 7034 7035_component2['default'].registerComponent('ErrorDisplay', ErrorDisplay); 7036exports['default'] = ErrorDisplay; 7037 7038},{"5":5,"50":50,"87":87}],42:[function(_dereq_,module,exports){ 7039'use strict'; 7040 7041exports.__esModule = true; 7042 7043var _events = _dereq_(82); 7044 7045var Events = _interopRequireWildcard(_events); 7046 7047function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 7048 7049/** 7050 * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It 7051 * adds shorthand functions that wrap around lengthy functions. For example: 7052 * the `on` function is a wrapper around `addEventListener`. 7053 * 7054 * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget} 7055 * @class EventTarget 7056 */ 7057var EventTarget = function EventTarget() {}; 7058 7059/** 7060 * A Custom DOM event. 7061 * 7062 * @typedef {Object} EventTarget~Event 7063 * @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent} 7064 */ 7065 7066/** 7067 * All event listeners should follow the following format. 7068 * 7069 * @callback EventTarget~EventListener 7070 * @this {EventTarget} 7071 * 7072 * @param {EventTarget~Event} event 7073 * the event that triggered this function 7074 * 7075 * @param {Object} [hash] 7076 * hash of data sent during the event 7077 */ 7078 7079/**
7080 * An object containing event names as keys and booleans as values. 7081 * 7082 * > NOTE: If an event name is set to a true value here {@link EventTarget#trigger} 7083 * will have extra functionality. See that function for more information. 7084 * 7085 * @property EventTarget.prototype.allowedEvents_ 7086 * @private 7087 */ 7088/** 7089 * @file src/js/event-target.js 7090 */ 7091EventTarget.prototype.allowedEvents_ = {}; 7092 7093/** 7094 * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a 7095 * function that will get called when an event with a certain name gets triggered. 7096 * 7097 * @param {string|string[]} type 7098 * An event name or an array of event names. 7099 * 7100 * @param {EventTarget~EventListener} fn 7101 * The function to call with `EventTarget`s 7102 */ 7103EventTarget.prototype.on = function (type, fn) { 7104 // Remove the addEventListener alias before calling Events.on 7105 // so we don't get into an infinite type loop 7106 var ael = this.addEventListener; 7107 7108 this.addEventListener = function () {}; 7109 Events.on(this, type, fn); 7110 this.addEventListener = ael; 7111}; 7112 7113/** 7114 * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic 7115 * the standard DOM API. 7116 * 7117 * @function 7118 * @see {@link EventTarget#on} 7119 */ 7120EventTarget.prototype.addEventListener = EventTarget.prototype.on; 7121 7122/** 7123 * Removes an `event listener` for a specific event from an instance of `EventTarget`. 7124 * This makes it so that the `event listener` will no longer get called when the 7125 * named event happens. 7126 * 7127 * @param {string|string[]} type 7128 * An event name or an array of event names. 7129 * 7130 * @param {EventTarget~EventListener} fn 7131 * The function to remove. 7132 */ 7133EventTarget.prototype.off = function (type, fn) { 7134 Events.off(this, type, fn); 7135}; 7136 7137/** 7138 * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic 7139 * the standard DOM API. 7140 * 7141 * @function 7142 * @see {@link EventTarget#off} 7143 */ 7144EventTarget.prototype.removeEventListener = EventTarget.prototype.off; 7145 7146/** 7147 * This function will add an `event listener` that gets triggered only once. After the 7148 * first trigger it will get removed. This is like adding an `event listener` 7149 * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself. 7150 * 7151 * @param {string|string[]} type 7152 * An event name or an array of event names. 7153 * 7154 * @param {EventTarget~EventListener} fn 7155 * The function to be called once for each event name. 7156 */ 7157EventTarget.prototype.one = function (type, fn) { 7158 // Remove the addEventListener alialing Events.on 7159 // so we don't get into an infinite type loop 7160 var ael = this.addEventListener; 7161 7162 this.addEventListener = function () {}; 7163 Events.one(this, type, fn); 7164 this.addEventListener = ael; 7165}; 7166 7167/** 7168 * This function causes an event to happen. This will then cause any `event listeners` 7169 * that are waiting for that event, to get called. If there are no `event listeners` 7170 * for an event then nothing will happen. 7171 * 7172 * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`. 7173 * Trigger will also call the `on` + `uppercaseEventName` function. 7174 * 7175 * Example: 7176 * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call 7177 * `onClick` if it exists. 7178 * 7179 * @param {string|EventTarget~Event|Object} event 7180 * The name of the event, an `Event`, or an object with a key of type set to 7181 * an event name. 7182 */ 7183EventTarget.prototype.trigger = function (event) { 7184 var type = event.type || event; 7185 7186 if (typeof event === 'string') { 7187 event = { type: type }; 7188 } 7189 event = Events.fixEvent(event); 7190 7191 if (this.allowedEvents_[type] && this['on' + type]) { 7192 this['on' + type](event); 7193 } 7194 7195 Events.trigger(this, event); 7196}; 7197 7198/** 7199 * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic 7200 * the standard DOM API. 7201 * 7202 * @function 7203 * @see {@link EventTarget#trigger} 7204 */ 7205EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger; 7206 7207exports['default'] = EventTarget; 7208 7209},{"82":82}],43:[function(_dereq_,module,exports){ 7210'use strict'; 7211 7212exports.__esModule = true; 7213 7214var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 7215 7216var _log = _dereq_(86); 7217 7218var _log2 = _interopRequireDefault(_log); 7219 7220var _obj = _dereq_(88); 7221 7222function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7223 7224/** 7225 * @file extend.js 7226 * @module extend 7227 */ 7228
7229/** 7230 * A combination of node inherits and babel's inherits (after transpile). 7231 * Both work the same but node adds `super_` to the subClass 7232 * and Bable adds the superClass as __proto__. Both seem useful. 7233 * 7234 * @param {Object} subClass 7235 * The class to inherit to 7236 * 7237 * @param {Object} superClass 7238 * The class to inherit from 7239 * 7240 * @private 7241 */ 7242var _inherits = function _inherits(subClass, superClass) { 7243 if (typeof superClass !== 'function' && superClass !== null) { 7244 throw new TypeError('Super expression must either be null or a function, not ' + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass))); 7245 } 7246 7247 subClass.prototype = Object.create(superClass && superClass.prototype, { 7248 constructor: { 7249 value: subClass, 7250 enumerable: false, 7251 writable: true, 7252 configurable: true 7253 } 7254 }); 7255 7256 if (superClass) { 7257 // node 7258 subClass.super_ = superClass; 7259 } 7260}; 7261 7262/** 7263 * Function for subclassing using the same inheritance that 7264 * videojs uses internally 7265 * 7266 * @param {Object} superClass 7267 * The class to inherit from 7268 * 7269 * @param {Object} [subClassMethods={}] 7270 * The class to inherit to 7271 * 7272 * @return {Object} 7273 * The new object with subClassMethods that inherited superClass. 7274 */ 7275var extendFn = function extendFn(superClass) { 7276 var subClassMethods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 7277 7278 var subClass = function subClass() { 7279 superClass.apply(this, arguments); 7280 }; 7281 7282 var methods = {}; 7283 7284 if ((0, _obj.isObject)(subClassMethods)) { 7285 if (typeof subClassMethods.init === 'function') { 7286 _log2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.'); 7287 subClassMethods.constructor = subClassMethods.init; 7288 } 7289 if (subClassMethods.constructor !== Object.prototype.constructor) { 7290 subClass = subClassMethods.constructor; 7291 } 7292 methods = subClassMethods; 7293 } else if (typeof subClassMethods === 'function') { 7294 subClass = subClassMethods; 7295 } 7296 7297 _inherits(subClass, superClass); 7298 7299 // Extend subObj's prototype with functions and other properties from props 7300 for (var name in methods) { 7301 if (methods.hasOwnProperty(name)) { 7302 subClass.prototype[name] = methods[name]; 7303 } 7304 } 7305 7306 return subClass; 7307}; 7308 7309exports['default'] = extendFn; 7310 7311},{"86":86,"88":88}],44:[function(_dereq_,module,exports){ 7312'use strict'; 7313 7314exports.__esModule = true; 7315 7316var _document = _dereq_(94); 7317 7318var _document2 = _interopRequireDefault(_document); 7319 7320function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7321 7322/** 7323 * Store the browser-specific methods for the fullscreen API. 7324 * 7325 * @type {Object} 7326 * @see [Specification]{@link https://fullscreen.spec.whatwg.org} 7327 * @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js} 7328 */ 7329var FullscreenApi = {}; 7330 7331// browser API methods 7332/** 7333 * @file fullscreen-api.js 7334 * @module fullscreen-api 7335 * @private 7336 */ 7337var apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'], 7338// WebKit 7339['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'], 7340// Old WebKit (Safari 5.1) 7341['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'], 7342// Mozilla 7343['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'], 7344// Microsoft 7345['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']]; 7346 7347var specApi = apiMap[0]; 7348var browserApi = void 0; 7349 7350// determine the supported set of functions 7351for (var i = 0; i < apiMap.length; i++) { 7352 // check for exitFullscreen function 7353 if (apiMap[i][1] in _document2['default']) { 7354 browserApi = apiMap[i]; 7355 break; 7356 } 7357} 7358 7359// map the browser API names to the spec API names 7360if (browserApi) { 7361 for (var _i = 0; _i < browserApi.length; _i++) { 7362 FullscreenApi[specApi[_i]] = browserApi[_i]; 7363 } 7364} 7365 7366exports['default'] = FullscreenApi; 7367 7368},{"94":94}],45:[function(_dereq_,module,exports){ 7369'use strict'; 7370 7371exports.__esModule = true; 7372 7373var _component = _dereq_(5); 7374 7375var _component2 = _interopRequireDefault(_component); 7376 7377function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7378 7379function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 7380 7381function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 7382 7383function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
7383onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 7384 * @file loading-spinner.js 7385 */ 7386 7387 7388/** 7389 * A loading spinner for use during waiting/loading events. 7390 * 7391 * @extends Component 7392 */ 7393var LoadingSpinner = function (_Component) { 7394 _inherits(LoadingSpinner, _Component); 7395 7396 function LoadingSpinner() { 7397 _classCallCheck(this, LoadingSpinner); 7398 7399 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 7400 } 7401 7402 /** 7403 * Create the `LoadingSpinner`s DOM element. 7404 * 7405 * @return {Element} 7406 * The dom element that gets created. 7407 */ 7408 LoadingSpinner.prototype.createEl = function createEl() { 7409 return _Component.prototype.createEl.call(this, 'div', { 7410 className: 'vjs-loading-spinner', 7411 dir: 'ltr' 7412 }); 7413 }; 7414 7415 return LoadingSpinner; 7416}(_component2['default']); 7417 7418_component2['default'].registerComponent('LoadingSpinner', LoadingSpinner); 7419exports['default'] = LoadingSpinner; 7420 7421},{"5":5}],46:[function(_dereq_,module,exports){ 7422'use strict'; 7423 7424exports.__esModule = true; 7425 7426var _obj = _dereq_(88); 7427 7428/** 7429 * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class. 7430 * 7431 * @param {number|string|Object|MediaError} value 7432 * This can be of multiple types: 7433 * - number: should be a standard error code 7434 * - string: an error message (the code will be 0) 7435 * - Object: arbitrary properties 7436 * - `MediaError` (native): used to populate a video.js `MediaError` object 7437 * - `MediaError` (video.js): will return itself if it's already a 7438 * video.js `MediaError` object. 7439 * 7440 * @see [MediaError Spec]{@link https://dev.w3.org/html5/spec-author-view/video.html#mediaerror} 7441 * @see [Encrypted MediaError Spec]{@link https://www.w3.org/TR/2013/WD-encrypted-media-20130510/#error-codes} 7442 * 7443 * @class MediaError 7444 */ 7445function MediaError(value) { 7446 7447 // Allow redundant calls to this constructor to avoid having `instanceof` 7448 // checks peppered around the code. 7449 if (value instanceof MediaError) { 7450 return value; 7451 } 7452 7453 if (typeof value === 'number') { 7454 this.code = value; 7455 } else if (typeof value === 'string') {
7456 // default code is zero, so this is a custom error 7457 this.message = value; 7458 } else if ((0, _obj.isObject)(value)) { 7459 7460 // We assign the `code` property manually because native `MediaError` objects 7461 // do not expose it as an own/enumerable property of the object. 7462 if (typeof value.code === 'number') { 7463 this.code = value.code; 7464 } 7465 7466 (0, _obj.assign)(this, value); 7467 } 7468 7469 if (!this.message) { 7470 this.message = MediaError.defaultMessages[this.code] || ''; 7471 } 7472} 7473 7474/** 7475 * The error code that refers two one of the defined `MediaError` types 7476 * 7477 * @type {Number} 7478 */ 7479/** 7480 * @file media-error.js 7481 */ 7482MediaError.prototype.code = 0; 7483 7484/** 7485 * An optional message that to show with the error. Message is not part of the HTML5 7486 * video spec but allows for more informative custom errors. 7487 * 7488 * @type {String} 7489 */ 7490MediaError.prototype.message = ''; 7491 7492/** 7493 * An optional status code that can be set by plugins to allow even more detail about 7494 * the error. For example a plugin might provide a specific HTTP status code and an 7495 * error message for that code. Then when the plugin gets that error this class will 7496 * know how to display an error message for it. This allows a custom message to show 7497 * up on the `Player` error overlay. 7498 * 7499 * @type {Array} 7500 */ 7501MediaError.prototype.status = null; 7502 7503/** 7504 * Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the 7505 * specification listed under {@link MediaError} for more information. 7506 * 7507 * @enum {array} 7508 * @readonly 7509 * @property {string} 0 - MEDIA_ERR_CUSTOM 7510 * @property {string} 1 - MEDIA_ERR_CUSTOM 7511 * @property {string} 2 - MEDIA_ERR_ABORTED 7512 * @property {string} 3 - MEDIA_ERR_NETWORK 7513 * @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED 7514 * @property {string} 5 - MEDIA_ERR_ENCRYPTED 7515 */ 7516MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED']; 7517 7518/** 7519 * The default `MediaError` messages based on the {@link MediaError.errorTypes}. 7520 * 7521 * @type {Array} 7522 * @constant 7523 */ 7524MediaError.defaultMessages = { 7525 1: 'You aborted the media playback', 7526 2: 'A network error caused the media download to fail part-way.', 7527 3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.', 7528 4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.', 7529 5: 'The media is encrypted and we do not have the keys to decrypt it.' 7530}; 7531 7532// Add types as properties on MediaError 7533// e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4; 7534for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) { 7535 MediaError[MediaError.errorTypes[errNum]] = errNum; 7536 // values should be accessible on both the class and instance 7537 MediaError.prototype[MediaError.errorTypes[errNum]] = errNum; 7538} 7539 7540// jsdocs for instance/static members added above 7541// instance methods use `#` and static methods use `.` 7542/** 7543 * W3C error code for any custom error. 7544 * 7545 * @member MediaError#MEDIA_ERR_CUSTOM 7546 * @constant {number} 7547 * @default 0 7548 */ 7549/** 7550 * W3C error code for any custom error. 7551 * 7552 * @member MediaError.MEDIA_ERR_CUSTOM 7553 * @constant {number} 7554 * @default 0 7555 */ 7556 7557/** 7558 * W3C error code for media error aborted. 7559 * 7560 * @member MediaError#MEDIA_ERR_ABORTED 7561 * @constant {number} 7562 * @default 1 7563 */ 7564/** 7565 * W3C error code for media error aborted. 7566 * 7567 * @member MediaError.MEDIA_ERR_ABORTED 7568 * @constant {number} 7569 * @default 1 7570 */ 7571 7572/** 7573 * W3C error code for any network error. 7574 * 7575 * @member MediaError#MEDIA_ERR_NETWORK 7576 * @constant {number} 7577 * @default 2 7578 */ 7579/** 7580 * W3C error code for any network error. 7581 * 7582 * @member MediaError.MEDIA_ERR_NETWORK 7583 * @constant {number} 7584 * @default 2 7585 */ 7586 7587/** 7588 * W3C error code for any decoding error. 7589 * 7590 * @member MediaError#MEDIA_ERR_DECODE 7591 * @constant {number} 7592 * @default 3 7593 */ 7594/** 7595 * W3C error code for any decoding error. 7596 * 7597 * @member MediaError.MEDIA_ERR_DECODE 7598 * @constant {number} 7599 * @default 3 7600 */ 7601 7602/** 7603 * W3C error code for any time that a source is not supported. 7604 * 7605 * @member MediaError#MEDIA_ERR_SRC_NOT_SUPPORTED 7606 * @constant {number} 7607 * @default 4 7608 */ 7609/** 7610 * W3C error code for any time that a source is not supported. 7611 * 7612 * @member MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED 7613 * @constant {number} 7614 * @default 4 7615 */ 7616 7617/** 7618 * W3C error code for any time that a source is encrypted. 7619 * 7620 * @member MediaError#MEDIA_ERR_ENCRYPTED 7621 * @constant {number} 7622 * @default 5 7623 */ 7624/** 7625 * W3C error code for any time that a source is encrypted. 7626 * 7627 * @member MediaError.MEDIA_ERR_ENCRYPTED 7628 * @constant {number} 7629 * @default 5 7630 */ 7631 7632exports['default'] = MediaError; 7633 7634},{"88":88}],47:[function(_dereq_,module,exports){ 7635'use strict'; 7636 7637exports.__esModule = true; 7638 7639var _clickableComponent = _dereq_(3); 7640 7641var _clickableComponent2 = _interopRequireDefault(_clickableComponent); 7642 7643var _component = _dereq_(5); 7644 7645var _component2 = _interopRequireDefault(_component); 7646 7647var _menu = _dereq_(49); 7648 7649var _menu2 = _interopRequireDefault(_menu); 7650 7651var _dom = _dereq_(81); 7652 7653var Dom = _interopRequireWildcard(_dom); 7654 7655var _fn = _dereq_(83); 7656 7657var Fn = _interopRequireWildcard(_fn); 7658 7659var _toTitleCase = _dereq_(91); 7660 7661var _toTitleCase2 = _interopRequireDefault(_toTitleCase); 7662 7663function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 7664 7665function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7666 7667function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 7668 7669function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 7670 7671function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
vendor: 5,173 bytes, lines 7671-7836
7671onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 7672 * @file menu-button.js 7673 */ 7674 7675 7676/** 7677 * A `MenuButton` class for any popup {@link Menu}. 7678 * 7679 * @extends ClickableComponent 7680 */ 7681var MenuButton = function (_ClickableComponent) { 7682 _inherits(MenuButton, _ClickableComponent); 7683 7684 /** 7685 * Creates an instance of this class. 7686 * 7687 * @param {Player} player 7688 * The `Player` that this class should be attached to. 7689 * 7690 * @param {Object} [options={}] 7691 * The key/value store of player options. 7692 */ 7693 function MenuButton(player) { 7694 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 7695 7696 _classCallCheck(this, MenuButton); 7697 7698 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options)); 7699 7700 _this.update(); 7701 7702 _this.enabled_ = true; 7703 7704 _this.el_.setAttribute('aria-haspopup', 'true'); 7705 _this.el_.setAttribute('role', 'menuitem'); 7706 _this.on('keydown', _this.handleSubmenuKeyPress); 7707 return _this; 7708 } 7709 7710 /** 7711 * Update the menu based on the current state of its items. 7712 */ 7713 7714 7715 MenuButton.prototype.update = function update() { 7716 var menu = this.createMenu(); 7717 7718 if (this.menu) { 7719 this.removeChild(this.menu); 7720 } 7721 7722 this.menu = menu; 7723 this.addChild(menu); 7724 7725 /** 7726 * Track the state of the menu button 7727 * 7728 * @type {Boolean} 7729 * @private 7730 */ 7731 this.buttonPressed_ = false; 7732 this.el_.setAttribute('aria-expanded', 'false'); 7733 7734 if (this.items && this.items.length <= this.hideThreshold_) { 7735 this.hide(); 7736 } else { 7737 this.show(); 7738 } 7739 }; 7740 7741 /** 7742 * Create the menu and add all items to it. 7743 * 7744 * @return {Menu} 7745 * The constructed menu 7746 */ 7747 7748 7749 MenuButton.prototype.createMenu = function createMenu() { 7750 var menu = new _menu2['default'](this.player_); 7751 7752 /** 7753 * Hide the menu if the number of items is less than or equal to this threshold. This defaults 7754 * to 0 and whenever we add items which can be hidden to the menu we'll increment it. We list 7755 * it here because every time we run `createMenu` we need to reset the value. 7756 * 7757 * @protected 7758 * @type {Number} 7759 */ 7760 this.hideThreshold_ = 0; 7761 7762 // Add a title list item to the top 7763 if (this.options_.title) { 7764 var title = Dom.createEl('li', { 7765 className: 'vjs-menu-title', 7766 innerHTML: (0, _toTitleCase2['default'])(this.options_.title), 7767 tabIndex: -1 7768 }); 7769 7770 this.hideThreshold_ += 1; 7771 7772 menu.children_.unshift(title); 7773 Dom.insertElFirst(title, menu.contentEl()); 7774 } 7775 7776 this.items = this.createItems(); 7777 7778 if (this.items) { 7779 // Add menu items to the menu 7780 for (var i = 0; i < this.items.length; i++) { 7781 menu.addItem(this.items[i]); 7782 } 7783 } 7784 7785 return menu; 7786 }; 7787 7788 /** 7789 * Create the list of menu items. Specific to each subclass. 7790 * 7791 * @abstract 7792 */ 7793 7794 7795 MenuButton.prototype.createItems = function createItems() {}; 7796 7797 /** 7798 * Create the `MenuButtons`s DOM element. 7799 * 7800 * @return {Element} 7801 * The element that gets created. 7802 */ 7803 7804 7805 MenuButton.prototype.createEl = function createEl() { 7806 return _ClickableComponent.prototype.createEl.call(this, 'div', { 7807 className: this.buildCSSClass() 7808 }); 7809 }; 7810 7811 /** 7812 * Builds the default DOM `className`. 7813 * 7814 * @return {string} 7815 * The DOM `className` for this object. 7816 */ 7817 7818 7819 MenuButton.prototype.buildCSSClass = function buildCSSClass() { 7820 var menuButtonClass = 'vjs-menu-button'; 7821 7822 // If the inline option is passed, we want to use different styles altogether. 7823 if (this.options_.inline === true) { 7824 menuButtonClass += '-inline'; 7825 } else { 7826 menuButtonClass += '-popup'; 7827 } 7828 7829 return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this); 7830 }; 7831 7832 /** 7833 * Handle a click on a `MenuButton`. 7834 * See {@link ClickableComponent#handleClick} for instances where this is called. 7835 * 7836 * @param {EventTarget~Event} event
7837 * The `keydown`, `tap`, or `click` event that caused this function to be 7838 * called. 7839 * 7840 * @listens tap 7841 * @listens click 7842 */ 7843 7844 7845 MenuButton.prototype.handleClick = function handleClick(event) { 7846 // When you click the button it adds focus, which will show the menu. 7847 // So we'll remove focus when the mouse leaves the button. Focus is needed 7848 // for tab navigation. 7849 7850 this.one(this.menu.contentEl(), 'mouseleave', Fn.bind(this, function (e) { 7851 this.unpressButton(); 7852 this.el_.blur(); 7853 })); 7854 if (this.buttonPressed_) { 7855 this.unpressButton(); 7856 } else { 7857 this.pressButton(); 7858 } 7859 }; 7860 7861 /** 7862 * Handle tab, escape, down arrow, and up arrow keys for `MenuButton`. See 7863 * {@link ClickableComponent#handleKeyPress} for instances where this is called. 7864 * 7865 * @param {EventTarget~Event} event 7866 * The `keydown` event that caused this function to be called. 7867 * 7868 * @listens keydown 7869 */ 7870 7871 7872 MenuButton.prototype.handleKeyPress = function handleKeyPress(event) { 7873 7874 // Escape (27) key or Tab (9) key unpress the 'button' 7875 if (event.which === 27 || event.which === 9) { 7876 if (this.buttonPressed_) { 7877 this.unpressButton(); 7878 } 7879 // Don't preventDefault for Tab key - we still want to lose focus 7880 if (event.which !== 9) { 7881 event.preventDefault(); 7882 } 7883 // Up (38) key or Down (40) key press the 'button' 7884 } else if (event.which === 38 || event.which === 40) { 7885 if (!this.buttonPressed_) { 7886 this.pressButton(); 7887 event.preventDefault(); 7888 } 7889 } else { 7890 _ClickableComponent.prototype.handleKeyPress.call(this, event); 7891 } 7892 }; 7893 7894 /** 7895 * Handle a `keydown` event on a sub-menu. The listener for this is added in 7896 * the constructor. 7897 * 7898 * @param {EventTarget~Event} event 7899 * Key press event 7900 * 7901 * @listens keydown 7902 */ 7903 7904 7905 MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) { 7906 7907 // Escape (27) key or Tab (9) key unpress the 'button' 7908 if (event.which === 27 || event.which === 9) { 7909 if (this.buttonPressed_) { 7910 this.unpressButton(); 7911 } 7912 // Don't preventDefault for Tab key - we still want to lose focus 7913 if (event.which !== 9) { 7914 event.preventDefault(); 7915 } 7916 } 7917 }; 7918 7919 /** 7920 * Put the current `MenuButton` into a pressed state. 7921 */ 7922 7923 7924 MenuButton.prototype.pressButton = function pressButton() { 7925 if (this.enabled_) { 7926 this.buttonPressed_ = true; 7927 this.menu.lockShowing(); 7928 this.el_.setAttribute('aria-expanded', 'true'); 7929 // set the focus into the submenu 7930 this.menu.focus(); 7931 } 7932 }; 7933 7934 /** 7935 * Take the current `MenuButton` out of a pressed state. 7936 */ 7937 7938 7939 MenuButton.prototype.unpressButton = function unpressButton() { 7940 if (this.enabled_) { 7941 this.buttonPressed_ = false; 7942 this.menu.unlockShowing(); 7943 this.el_.setAttribute('aria-expanded', 'false'); 7944 // Set focus back to this menu button 7945 this.el_.focus(); 7946 } 7947 }; 7948 7949 /** 7950 * Disable the `MenuButton`. Don't allow it to be clicked. 7951 * 7952 * @return {MenuButton} 7953 * Returns itself; method can be chained. 7954 */ 7955 7956 7957 MenuButton.prototype.disable = function disable() { 7958 // Unpress, but don't force focus on this button 7959 this.buttonPressed_ = false; 7960 this.menu.unlockShowing(); 7961 this.el_.setAttribute('aria-expanded', 'false'); 7962 7963 this.enabled_ = false; 7964 7965 return _ClickableComponent.prototype.disable.call(this); 7966 }; 7967 7968 /** 7969 * Enable the `MenuButton`. Allow it to be clicked. 7970 * 7971 * @return {MenuButton} 7972 * Returns itself; method can be chained. 7973 */ 7974 7975 7976 MenuButton.prototype.enable = function enable() { 7977 this.enabled_ = true; 7978 7979 return _ClickableComponent.prototype.enable.call(this); 7980 }; 7981 7982 return MenuButton; 7983}(_clickableComponent2['default']); 7984 7985_component2['default'].registerComponent('MenuButton', MenuButton); 7986exports['default'] = MenuButton; 7987 7988},{"3":3,"49":49,"5":5,"81":81,"83":83,"91":91}],48:[function(_dereq_,module,exports){ 7989'use strict'; 7990 7991exports.__esModule = true; 7992 7993var _clickableComponent = _dereq_(3); 7994 7995var _clickableComponent2 = _interopRequireDefault(_clickableComponent); 7996 7997var _component = _dereq_(5); 7998 7999var _component2 = _interopRequireDefault(_component); 8000 8001var _obj = _dereq_(88); 8002 8003function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8004 8005function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 8006 8007function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 8008 8009function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
vendor: 4,334 bytes, lines 8009-8121
8009onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 8010 * @file menu-item.js 8011 */ 8012 8013 8014/** 8015 * The component for a menu item. `<li>` 8016 * 8017 * @extends ClickableComponent 8018 */ 8019var MenuItem = function (_ClickableComponent) { 8020 _inherits(MenuItem, _ClickableComponent); 8021 8022 /** 8023 * Creates an instance of the this class. 8024 * 8025 * @param {Player} player 8026 * The `Player` that this class should be attached to. 8027 * 8028 * @param {Object} [options={}] 8029 * The key/value store of player options. 8030 * 8031 */ 8032 function MenuItem(player, options) { 8033 _classCallCheck(this, MenuItem); 8034 8035 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options)); 8036 8037 _this.selectable = options.selectable; 8038 8039 _this.selected(options.selected); 8040 8041 if (_this.selectable) { 8042 // TODO: May need to be either menuitemcheckbox or menuitemradio, 8043 // and may need logical grouping of menu items. 8044 _this.el_.setAttribute('role', 'menuitemcheckbox'); 8045 } else { 8046 _this.el_.setAttribute('role', 'menuitem'); 8047 } 8048 return _this; 8049 } 8050 8051 /** 8052 * Create the `MenuItem's DOM element 8053 * 8054 * @param {string} [type=li] 8055 * Element's node type, not actually used, always set to `li`. 8056 * 8057 * @param {Object} [props={}] 8058 * An object of properties that should be set on the element 8059 * 8060 * @param {Object} [attrs={}] 8061 * An object of attributes that should be set on the element 8062 * 8063 * @return {Element} 8064 * The element that gets created. 8065 */ 8066 8067 8068 MenuItem.prototype.createEl = function createEl(type, props, attrs) { 8069 // The control is textual, not just an icon 8070 this.nonIconControl = true; 8071 8072 return _ClickableComponent.prototype.createEl.call(this, 'li', (0, _obj.assign)({ 8073 className: 'vjs-menu-item', 8074 innerHTML: this.localize(this.options_.label), 8075 tabIndex: -1 8076 }, props), attrs); 8077 }; 8078 8079 /** 8080 * Any click on a `MenuItem` puts int into the selected state. 8081 * See {@link ClickableComponent#handleClick} for instances where this is called. 8082 * 8083 * @param {EventTarget~Event} event 8084 * The `keydown`, `tap`, or `click` event that caused this function to be 8085 * called. 8086 * 8087 * @listens tap 8088 * @listens click 8089 */ 8090 8091 8092 MenuItem.prototype.handleClick = function handleClick(event) { 8093 this.selected(true); 8094 }; 8095 8096 /** 8097 * Set the state for this menu item as selected or not. 8098 * 8099 * @param {boolean} selected 8100 * if the menu item is selected or not 8101 */ 8102 8103 8104 MenuItem.prototype.selected = function selected(_selected) { 8105 if (this.selectable) { 8106 if (_selected) { 8107 this.addClass('vjs-selected'); 8108 this.el_.setAttribute('aria-checked', 'true'); 8109 // aria-checked isn't fully supported by browsers/screen readers, 8110 // so indicate selected state to screen reader in the control text. 8111 this.controlText(', selected'); 8112 } else { 8113 this.removeClass('vjs-selected'); 8114 this.el_.setAttribute('aria-checked', 'false'); 8115 // Indicate un-selected state to screen reader 8116 // Note that a space clears out the selected state text 8117 this.controlText(' '); 8118 } 8119 } 8120 }; 8121
8122 return MenuItem; 8123}(_clickableComponent2['default']); 8124 8125_component2['default'].registerComponent('MenuItem', MenuItem); 8126exports['default'] = MenuItem; 8127 8128},{"3":3,"5":5,"88":88}],49:[function(_dereq_,module,exports){ 8129'use strict'; 8130 8131exports.__esModule = true; 8132 8133var _component = _dereq_(5); 8134 8135var _component2 = _interopRequireDefault(_component); 8136 8137var _dom = _dereq_(81); 8138 8139var Dom = _interopRequireWildcard(_dom); 8140 8141var _fn = _dereq_(83); 8142 8143var Fn = _interopRequireWildcard(_fn); 8144 8145var _events = _dereq_(82); 8146 8147var Events = _interopRequireWildcard(_events); 8148 8149function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 8150 8151function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8152 8153function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 8154 8155function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 8156 8157function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 8158 * @file menu.js 8159 */ 8160 8161 8162/** 8163 * The Menu component is used to build popup menus, including subtitle and 8164 * captions selection menus. 8165 * 8166 * @extends Component 8167 */ 8168var Menu = function (_Component) { 8169 _inherits(Menu, _Component); 8170 8171 /** 8172 * Create an instance of this class. 8173 * 8174 * @param {Player} player 8175 * the player that this component should attach to 8176 * 8177 * @param {Object} [options] 8178 * Object of option names and values 8179 * 8180 */ 8181 function Menu(player, options) { 8182 _classCallCheck(this, Menu); 8183 8184 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 8185 8186 _this.focusedChild_ = -1; 8187 8188 _this.on('keydown', _this.handleKeyPress); 8189 return _this; 8190 } 8191 8192 /** 8193 * Add a {@link MenuItem} to the menu. 8194 * 8195 * @param {Object|string} component 8196 * The name or instance of the `MenuItem` to add. 8197 * 8198 */ 8199 8200 8201 Menu.prototype.addItem = function addItem(component) { 8202 this.addChild(component); 8203 component.on('click', Fn.bind(this, function (event) { 8204 this.unlockShowing(); 8205 // TODO: Need to set keyboard focus back to the menuButton 8206 })); 8207 }; 8208 8209 /** 8210 * Create the `Menu`s DOM element. 8211 * 8212 * @return {Element} 8213 * the element that was created 8214 */ 8215 8216 8217 Menu.prototype.createEl = function createEl() { 8218 var contentElType = this.options_.contentElType || 'ul'; 8219 8220 this.contentEl_ = Dom.createEl(contentElType, { 8221 className: 'vjs-menu-content' 8222 }); 8223 8224 this.contentEl_.setAttribute('role', 'menu'); 8225 8226 var el = _Component.prototype.createEl.call(this, 'div', { 8227 append: this.contentEl_, 8228 className: 'vjs-menu' 8229 }); 8230 8231 el.setAttribute('role', 'presentation'); 8232 el.appendChild(this.contentEl_); 8233 8234 // Prevent clicks from bubbling up. Needed for Menu Buttons, 8235 // where a click on the parent is significant 8236 Events.on(el, 'click', function (event) { 8237 event.preventDefault(); 8238 event.stopImmediatePropagation(); 8239 }); 8240 8241 return el; 8242 }; 8243 8244 /** 8245 * Handle a `keydown` event on this menu. This listener is added in the constructor. 8246 * 8247 * @param {EventTarget~Event} event 8248 * A `keydown` event that happened on the menu. 8249 * 8250 * @listens keydown 8251 */ 8252 8253 8254 Menu.prototype.handleKeyPress = function handleKeyPress(event) { 8255 // Left and Down Arrows 8256 if (event.which === 37 || event.which === 40) { 8257 event.preventDefault(); 8258 this.stepForward(); 8259 8260 // Up and Right Arrows 8261 } else if (event.which === 38 || event.which === 39) { 8262 event.preventDefault(); 8263 this.stepBack(); 8264 } 8265 }; 8266 8267 /** 8268 * Move to next (lower) menu item for keyboard users. 8269 */ 8270 8271 8272 Menu.prototype.stepForward = function stepForward() {
8273 var stepChild = 0; 8274 8275 if (this.focusedChild_ !== undefined) { 8276 stepChild = this.focusedChild_ + 1; 8277 } 8278 this.focus(stepChild); 8279 }; 8280 8281 /** 8282 * Move to previous (higher) menu item for keyboard users. 8283 */ 8284 8285 8286 Menu.prototype.stepBack = function stepBack() { 8287 var stepChild = 0; 8288 8289 if (this.focusedChild_ !== undefined) { 8290 stepChild = this.focusedChild_ - 1; 8291 } 8292 this.focus(stepChild); 8293 }; 8294 8295 /** 8296 * Set focus on a {@link MenuItem} in the `Menu`. 8297 * 8298 * @param {Object|string} [item=0] 8299 * Index of child item set focus on. 8300 */ 8301 8302 8303 Menu.prototype.focus = function focus() { 8304 var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 8305 8306 var children = this.children().slice(); 8307 var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className); 8308 8309 if (haveTitle) { 8310 children.shift(); 8311 } 8312 8313 if (children.length > 0) { 8314 if (item < 0) { 8315 item = 0; 8316 } else if (item >= children.length) { 8317 item = children.length - 1; 8318 } 8319 8320 this.focusedChild_ = item; 8321 8322 children[item].el_.focus(); 8323 } 8324 }; 8325 8326 return Menu; 8327}(_component2['default']); 8328 8329_component2['default'].registerComponent('Menu', Menu); 8330exports['default'] = Menu; 8331 8332},{"5":5,"81":81,"82":82,"83":83}],50:[function(_dereq_,module,exports){ 8333'use strict'; 8334 8335exports.__esModule = true; 8336 8337var _dom = _dereq_(81); 8338 8339var Dom = _interopRequireWildcard(_dom); 8340 8341var _fn = _dereq_(83); 8342 8343var Fn = _interopRequireWildcard(_fn); 8344 8345var _component = _dereq_(5); 8346 8347var _component2 = _interopRequireDefault(_component); 8348 8349function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8350 8351function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 8352 8353function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 8354 8355function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 8356 8357function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 8358 * @file modal-dialog.js 8359 */ 8360 8361 8362var MODAL_CLASS_NAME = 'vjs-modal-dialog'; 8363var ESC = 27; 8364 8365/** 8366 * The `ModalDialog` displays over the video and its controls, which blocks 8367 * interaction with the player until it is closed. 8368 * 8369 * Modal dialogs include a "Close" button and will close when that button 8370 * is activated - or when ESC is pressed anywhere. 8371 * 8372 * @extends Component 8373 */ 8374 8375var ModalDialog = function (_Component) { 8376 _inherits(ModalDialog, _Component); 8377 8378 /** 8379 * Create an instance of this class. 8380 * 8381 * @param {Player} player 8382 * The `Player` that this class should be attached to. 8383 * 8384 * @param {Object} [options] 8385 * The key/value store of player options. 8386 * 8387 * @param {Mixed} [options.content=undefined] 8388 * Provide customized content for this modal. 8389 * 8390 * @param {string} [options.description] 8391 * A text description for the modal, primarily for accessibility. 8392 * 8393 * @param {boolean} [options.fillAlways=false] 8394 * Normally, modals are automatically filled only the first time 8395 * they open. This tells the modal to refresh its content 8396 * every time it opens. 8397 * 8398 * @param {string} [options.label] 8399 * A text label for the modal, primarily for accessibility. 8400 * 8401 * @param {boolean} [options.temporary=true] 8402 * If `true`, the modal can only be opened once; it will be 8403 * disposed as soon as it's closed. 8404 * 8405 * @param {boolean} [options.uncloseable=false] 8406 * If `true`, the user will not be able to close the modal 8407 * through the UI in the normal ways. Programmatic closing is 8408 * still possible. 8409 */ 8410 function ModalDialog(player, options) { 8411 _classCallCheck(this, ModalDialog); 8412 8413 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 8414 8415 _this.opened_ = _this.hasBeenOpened_ = _this.hasBeenFilled_ = false;
vendor: 5,078 bytes, lines 8416-8613
8416 8417 _this.closeable(!_this.options_.uncloseable); 8418 _this.content(_this.options_.content); 8419 8420 // Make sure the contentEl is defined AFTER any children are initialized 8421 // because we only want the contents of the modal in the contentEl 8422 // (not the UI elements like the close button). 8423 _this.contentEl_ = Dom.createEl('div', { 8424 className: MODAL_CLASS_NAME + '-content' 8425 }, { 8426 role: 'document' 8427 }); 8428 8429 _this.descEl_ = Dom.createEl('p', { 8430 className: MODAL_CLASS_NAME + '-description vjs-offscreen', 8431 id: _this.el().getAttribute('aria-describedby') 8432 }); 8433 8434 Dom.textContent(_this.descEl_, _this.description()); 8435 _this.el_.appendChild(_this.descEl_); 8436 _this.el_.appendChild(_this.contentEl_); 8437 return _this; 8438 } 8439 8440 /** 8441 * Create the `ModalDialog`'s DOM element 8442 * 8443 * @return {Element} 8444 * The DOM element that gets created. 8445 */ 8446 8447 8448 ModalDialog.prototype.createEl = function createEl() { 8449 return _Component.prototype.createEl.call(this, 'div', { 8450 className: this.buildCSSClass(), 8451 tabIndex: -1 8452 }, { 8453 'aria-describedby': this.id() + '_description', 8454 'aria-hidden': 'true', 8455 'aria-label': this.label(), 8456 'role': 'dialog' 8457 }); 8458 }; 8459 8460 /** 8461 * Builds the default DOM `className`. 8462 * 8463 * @return {string} 8464 * The DOM `className` for this object. 8465 */ 8466 8467 8468 ModalDialog.prototype.buildCSSClass = function buildCSSClass() { 8469 return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this); 8470 }; 8471 8472 /** 8473 * Handles `keydown` events on the document, looking for ESC, which closes 8474 * the modal. 8475 * 8476 * @param {EventTarget~Event} e 8477 * The keypress that triggered this event. 8478 * 8479 * @listens keydown 8480 */ 8481 8482 8483 ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) { 8484 if (e.which === ESC && this.closeable()) { 8485 this.close(); 8486 } 8487 }; 8488 8489 /** 8490 * Returns the label string for this modal. Primarily used for accessibility. 8491 * 8492 * @return {string} 8493 * the localized or raw label of this modal. 8494 */ 8495 8496 8497 ModalDialog.prototype.label = function label() { 8498 return this.options_.label || this.localize('Modal Window'); 8499 }; 8500 8501 /** 8502 * Returns the description string for this modal. Primarily used for 8503 * accessibility. 8504 * 8505 * @return {string} 8506 * The localized or raw description of this modal. 8507 */ 8508 8509 8510 ModalDialog.prototype.description = function description() { 8511 var desc = this.options_.description || this.localize('This is a modal window.'); 8512 8513 // Append a universal closeability message if the modal is closeable. 8514 if (this.closeable()) { 8515 desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.'); 8516 } 8517 8518 return desc; 8519 }; 8520 8521 /** 8522 * Opens the modal. 8523 * 8524 * @fires ModalDialog#beforemodalopen 8525 * @fires ModalDialog#modalopen 8526 * 8527 * @return {ModalDialog} 8528 * Returns itself; method can be chained. 8529 */ 8530 8531 8532 ModalDialog.prototype.open = function open() { 8533 if (!this.opened_) { 8534 var player = this.player(); 8535 8536 /** 8537 * Fired just before a `ModalDialog` is opened. 8538 * 8539 * @event ModalDialog#beforemodalopen 8540 * @type {EventTarget~Event} 8541 */ 8542 this.trigger('beforemodalopen'); 8543 this.opened_ = true; 8544 8545 // Fill content if the modal has never opened before and 8546 // never been filled. 8547 if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) { 8548 this.fill(); 8549 } 8550 8551 // If the player was playing, pause it and take note of its previously 8552 // playing state. 8553 this.wasPlaying_ = !player.paused(); 8554 8555 if (this.options_.pauseOnOpen && this.wasPlaying_) { 8556 player.pause(); 8557 } 8558 8559 if (this.closeable()) { 8560 this.on(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress)); 8561 } 8562 8563 player.controls(false); 8564 this.show(); 8565 this.el().setAttribute('aria-hidden', 'false'); 8566 8567 /** 8568 * Fired just after a `ModalDialog` is opened. 8569 * 8570 * @event ModalDialog#modalopen 8571 * @type {EventTarget~Event} 8572 */ 8573 this.trigger('modalopen'); 8574 this.hasBeenOpened_ = true; 8575 } 8576 return this; 8577 }; 8578 8579 /** 8580 * If the `ModalDialog` is currently open or closed. 8581 * 8582 * @param {boolean} [value] 8583 * If given, it will open (`true`) or close (`false`) the modal. 8584 * 8585 * @return {boolean} 8586 * the current open state of the modaldialog 8587 */ 8588 8589 8590 ModalDialog.prototype.opened = function opened(value) { 8591 if (typeof value === 'boolean') { 8592 this[value ? 'open' : 'close'](); 8593 } 8594 return this.opened_; 8595 }; 8596 8597 /** 8598 * Closes the modal, does nothing if the `ModalDialog` is 8599 * not open. 8600 * 8601 * @fires ModalDialog#beforemodalclose 8602 * @fires ModalDialog#modalclose 8603 * 8604 * @return {ModalDialog} 8605 * Returns itself; method can be chained. 8606 */ 8607 8608 8609 ModalDialog.prototype.close = function close() { 8610 if (this.opened_) { 8611 var player = this.player(); 8612 8613 /**
8614 * Fired just before a `ModalDialog` is closed. 8615 * 8616 * @event ModalDialog#beforemodalclose 8617 * @type {EventTarget~Event} 8618 */ 8619 this.trigger('beforemodalclose'); 8620 this.opened_ = false; 8621 8622 if (this.wasPlaying_ && this.options_.pauseOnOpen) { 8623 player.play(); 8624 } 8625 8626 if (this.closeable()) { 8627 this.off(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress)); 8628 } 8629 8630 player.controls(true); 8631 this.hide(); 8632 this.el().setAttribute('aria-hidden', 'true'); 8633 8634 /** 8635 * Fired just after a `ModalDialog` is closed. 8636 * 8637 * @event ModalDialog#modalclose 8638 * @type {EventTarget~Event} 8639 */ 8640 this.trigger('modalclose'); 8641 8642 if (this.options_.temporary) { 8643 this.dispose(); 8644 } 8645 } 8646 return this; 8647 }; 8648 8649 /** 8650 * Check to see if the `ModalDialog` is closeable via the UI. 8651 * 8652 * @param {boolean} [value] 8653 * If given as a boolean, it will set the `closeable` option. 8654 * 8655 * @return {boolean} 8656 * Returns the final value of the closable option. 8657 */ 8658 8659 8660 ModalDialog.prototype.closeable = function closeable(value) { 8661 if (typeof value === 'boolean') { 8662 var closeable = this.closeable_ = !!value; 8663 var close = this.getChild('closeButton'); 8664 8665 // If this is being made closeable and has no close button, add one. 8666 if (closeable && !close) { 8667 8668 // The close button should be a child of the modal - not its 8669 // content element, so temporarily change the content element. 8670 var temp = this.contentEl_; 8671 8672 this.contentEl_ = this.el_; 8673 close = this.addChild('closeButton', { controlText: 'Close Modal Dialog' }); 8674 this.contentEl_ = temp; 8675 this.on(close, 'close', this.close); 8676 } 8677 8678 // If this is being made uncloseable and has a close button, remove it. 8679 if (!closeable && close) { 8680 this.off(close, 'close', this.close); 8681 this.removeChild(close); 8682 close.dispose(); 8683 } 8684 } 8685 return this.closeable_; 8686 }; 8687 8688 /**
8689 * Fill the modal's content element with the modal's "content" option. 8690 * The content element will be emptied before this change takes place. 8691 * 8692 * @return {ModalDialog} 8693 * Returns itself; method can be chained. 8694 */ 8695 8696 8697 ModalDialog.prototype.fill = function fill() { 8698 return this.fillWith(this.content()); 8699 }; 8700 8701 /** 8702 * Fill the modal's content element with arbitrary content. 8703 * The content element will be emptied before this change takes place. 8704 * 8705 * @fires ModalDialog#beforemodalfill 8706 * @fires ModalDialog#modalfill 8707 * 8708 * @param {Mixed} [content] 8709 * The same rules apply to this as apply to the `content` option. 8710 * 8711 * @return {ModalDialog} 8712 * Returns itself; method can be chained. 8713 */ 8714 8715 8716 ModalDialog.prototype.fillWith = function fillWith(content) { 8717 var contentEl = this.contentEl(); 8718 var parentEl = contentEl.parentNode; 8719 var nextSiblingEl = contentEl.nextSibling; 8720 8721 /** 8722 * Fired just before a `ModalDialog` is filled with content. 8723 * 8724 * @event ModalDialog#beforemodalfill 8725 * @type {EventTarget~Event} 8726 */ 8727 this.trigger('beforemodalfill'); 8728 this.hasBeenFilled_ = true; 8729 8730 // Detach the content element from the DOM before performing 8731 // manipulation to avoid modifying the live DOM multiple times. 8732 parentEl.removeChild(contentEl); 8733 this.empty(); 8734 Dom.insertContent(contentEl, content); 8735 /** 8736 * Fired just after a `ModalDialog` is filled with content. 8737 * 8738 * @event ModalDialog#modalfill 8739 * @type {EventTarget~Event} 8740 */ 8741 this.trigger('modalfill'); 8742 8743 // Re-inject the re-filled content element. 8744 if (nextSiblingEl) { 8745 parentEl.insertBefore(contentEl, nextSiblingEl); 8746 } else { 8747 parentEl.appendChild(contentEl); 8748 } 8749 8750 return this; 8751 }; 8752 8753 /** 8754 * Empties the content element. This happens anytime the modal is filled. 8755 * 8756 * @fires ModalDialog#beforemodalempty 8757 * @fires ModalDialog#modalempty 8758 * 8759 * @return {ModalDialog} 8760 * Returns itself; method can be chained. 8761 */ 8762 8763 8764 ModalDialog.prototype.empty = function empty() { 8765 /** 8766 * Fired just before a `ModalDialog` is emptied. 8767 * 8768 * @event ModalDialog#beforemodalempty 8769 * @type {EventTarget~Event} 8770 */ 8771 this.trigger('beforemodalempty'); 8772 Dom.emptyEl(this.contentEl()); 8773 8774 /** 8775 * Fired just after a `ModalDialog` is emptied. 8776 * 8777 * @event ModalDialog#modalempty 8778 * @type {EventTarget~Event} 8779 */ 8780 this.trigger('modalempty'); 8781 return this; 8782 }; 8783 8784 /** 8785 * Gets or sets the modal content, which gets normalized before being 8786 * rendered into the DOM. 8787 * 8788 * This does not update the DOM or fill the modal, but it is called during 8789 * that process. 8790 * 8791 * @param {Mixed} [value] 8792 * If defined, sets the internal content value to be used on the 8793 * next call(s) to `fill`. This value is normalized before being 8794 * inserted. To "clear" the internal content value, pass `null`. 8795 * 8796 * @return {Mixed} 8797 * The current content of the modal dialog 8798 */ 8799 8800 8801 ModalDialog.prototype.content = function content(value) { 8802 if (typeof value !== 'undefined') { 8803 this.content_ = value; 8804 } 8805 return this.content_; 8806 }; 8807 8808 return ModalDialog; 8809}(_component2['default']); 8810 8811/** 8812 * Default options for `ModalDialog` default options. 8813 * 8814 * @type {Object} 8815 * @private 8816 */ 8817 8818 8819ModalDialog.prototype.options_ = { 8820 pauseOnOpen: true, 8821 temporary: true 8822}; 8823 8824_component2['default'].registerComponent('ModalDialog', ModalDialog); 8825exports['default'] = ModalDialog; 8826 8827},{"5":5,"81":81,"83":83}],51:[function(_dereq_,module,exports){ 8828'use strict'; 8829 8830exports.__esModule = true; 8831 8832var _component = _dereq_(5); 8833 8834var _component2 = _interopRequireDefault(_component); 8835 8836var _document = _dereq_(94); 8837 8838var _document2 = _interopRequireDefault(_document); 8839 8840var _window = _dereq_(95); 8841 8842var _window2 = _interopRequireDefault(_window); 8843 8844var _events = _dereq_(82); 8845 8846var Events = _interopRequireWildcard(_events); 8847 8848var _dom = _dereq_(81); 8849 8850var Dom = _interopRequireWildcard(_dom); 8851 8852var _fn = _dereq_(83); 8853 8854var Fn = _interopRequireWildcard(_fn); 8855 8856var _guid = _dereq_(85); 8857 8858var Guid = _interopRequireWildcard(_guid); 8859 8860var _browser = _dereq_(78); 8861 8862var browser = _interopRequireWildcard(_browser); 8863 8864var _log = _dereq_(86); 8865 8866var _log2 = _interopRequireDefault(_log); 8867 8868var _toTitleCase = _dereq_(91); 8869 8870var _toTitleCase2 = _interopRequireDefault(_toTitleCase); 8871 8872var _timeRanges = _dereq_(90); 8873 8874var _buffer = _dereq_(79); 8875 8876var _stylesheet = _dereq_(89); 8877 8878var stylesheet = _interopRequireWildcard(_stylesheet); 8879 8880var _fullscreenApi = _dereq_(44); 8881 8882var _fullscreenApi2 = _interopRequireDefault(_fullscreenApi); 8883 8884var _mediaError = _dereq_(46); 8885 8886var _mediaError2 = _interopRequireDefault(_mediaError); 8887 8888var _tuple = _dereq_(97); 8889 8890var _tuple2 = _interopRequireDefault(_tuple); 8891 8892var _obj = _dereq_(88); 8893 8894var _mergeOptions = _dereq_(87); 8895 8896var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 8897 8898var _textTrackListConverter = _dereq_(69); 8899 8900var _textTrackListConverter2 = _interopRequireDefault(_textTrackListConverter); 8901 8902var _modalDialog = _dereq_(50); 8903 8904var _modalDialog2 = _interopRequireDefault(_modalDialog); 8905 8906var _tech = _dereq_(62); 8907 8908var _tech2 = _interopRequireDefault(_tech); 8909 8910var _audioTrackList = _dereq_(63); 8911 8912var _audioTrackList2 = _interopRequireDefault(_audioTrackList); 8913 8914var _videoTrackList = _dereq_(76); 8915 8916var _videoTrackList2 = _interopRequireDefault(_videoTrackList); 8917 8918_dereq_(61); 8919 8920_dereq_(59); 8921 8922_dereq_(55); 8923 8924_dereq_(68); 8925 8926_dereq_(45); 8927 8928_dereq_(1); 8929 8930_dereq_(4); 8931 8932_dereq_(8); 8933 8934_dereq_(41); 8935 8936_dereq_(71); 8937 8938_dereq_(60); 8939 8940function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 8941 8942function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8943 8944function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 8945 8946function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 8947 8948function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
8948onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 8949 * @file player.js 8950 */ 8951// Subclasses Component 8952 8953 8954// The following imports are used only to ensure that the corresponding modules 8955// are always included in the video.js package. Importing the modules will 8956// execute them and they will register themselves with video.js. 8957 8958 8959// Import Html5 tech, at least for disposing the original video tag. 8960 8961 8962// The following tech events are simply re-triggered 8963// on the player when they happen 8964var TECH_EVENTS_RETRIGGER = [ 8965/** 8966 * Fired while the user agent is downloading media data. 8967 * 8968 * @event Player#progress 8969 * @type {EventTarget~Event} 8970 */ 8971/** 8972 * Retrigger the `progress` event that was triggered by the {@link Tech}. 8973 * 8974 * @private 8975 * @method Player#handleTechProgress_ 8976 * @fires Player#progress 8977 * @listens Tech#progress 8978 */ 8979'progress', 8980 8981/** 8982 * Fires when the loading of an audio/video is aborted. 8983 * 8984 * @event Player#abort 8985 * @type {EventTarget~Event} 8986 */ 8987/** 8988 * Retrigger the `abort` event that was triggered by the {@link Tech}. 8989 * 8990 * @private 8991 * @method Player#handleTechAbort_ 8992 * @fires Player#abort 8993 * @listens Tech#abort 8994 */ 8995'abort', 8996 8997/** 8998 * Fires when the browser is intentionally not getting media data. 8999 * 9000 * @event Player#suspend 9001 * @type {EventTarget~Event} 9002 */ 9003/** 9004 * Retrigger the `suspend` event that was triggered by the {@link Tech}. 9005 * 9006 * @private 9007 * @method Player#handleTechSuspend_ 9008 * @fires Player#suspend 9009 * @listens Tech#suspend 9010 */ 9011'suspend', 9012 9013/** 9014 * Fires when the current playlist is empty. 9015 * 9016 * @event Player#emptied 9017 * @type {EventTarget~Event} 9018 */ 9019/** 9020 * Retrigger the `emptied` event that was triggered by the {@link Tech}. 9021 * 9022 * @private 9023 * @method Player#handleTechEmptied_ 9024 * @fires Player#emptied 9025 * @listens Tech#emptied 9026 */ 9027'emptied', 9028/** 9029 * Fires when the browser is trying to get media data, but data is not available. 9030 * 9031 * @event Player#stalled 9032 * @type {EventTarget~Event} 9033 */ 9034/** 9035 * Retrigger the `stalled` event that was triggered by the {@link Tech}. 9036 * 9037 * @private 9038 * @method Player#handleTechStalled_ 9039 * @fires Player#stalled 9040 * @listens Tech#stalled 9041 */ 9042'stalled', 9043 9044/** 9045 * Fires when the browser has loaded meta data for the audio/video. 9046 * 9047 * @event Player#loadedmetadata 9048 * @type {EventTarget~Event} 9049 */ 9050/** 9051 * Retrigger the `stalled` event that was triggered by the {@link Tech}. 9052 * 9053 * @private 9054 * @method Player#handleTechLoadedmetadata_ 9055 * @fires Player#loadedmetadata 9056 * @listens Tech#loadedmetadata 9057 */ 9058'loadedmetadata', 9059 9060/** 9061 * Fires when the browser has loaded the current frame of the audio/video. 9062 * 9063 * @event player#loadeddata 9064 * @type {event} 9065 */ 9066/** 9067 * Retrigger the `loadeddata` event that was triggered by the {@link Tech}. 9068 * 9069 * @private 9070 * @method Player#handleTechLoaddeddata_ 9071 * @fires Player#loadeddata 9072 * @listens Tech#loadeddata 9073 */ 9074'loadeddata', 9075 9076/** 9077 * Fires when the current playback position has changed. 9078 * 9079 * @event player#timeupdate 9080 * @type {event} 9081 */ 9082/** 9083 * Retrigger the `timeupdate` event that was triggered by the {@link Tech}. 9084 * 9085 * @private 9086 * @method Player#handleTechTimeUpdate_ 9087 * @fires Player#timeupdate 9088 * @listens Tech#timeupdate 9089 */ 9090'timeupdate', 9091 9092/** 9093 * Fires when the playing speed of the audio/video is changed 9094 * 9095 * @event player#ratechange 9096 * @type {event} 9097 */ 9098/** 9099 * Retrigger the `ratechange` event that was triggered by the {@link Tech}. 9100 * 9101 * @private 9102 * @method Player#handleTechRatechange_ 9103 * @fires Player#ratechange 9104 * @listens Tech#ratechange 9105 */ 9106'ratechange', 9107 9108/** 9109 * Fires when the volume has been changed 9110 * 9111 * @event player#volumechange 9112 * @type {event} 9113 */ 9114/** 9115 * Retrigger the `volumechange` event that was triggered by the {@link Tech}. 9116 * 9117 * @private 9118 * @method Player#handleTechVolumechange_ 9119 * @fires Player#volumechange 9120 * @listens Tech#volumechange 9121 */ 9122'volumechange', 9123 9124/** 9125 * Fires when the text track has been changed 9126 * 9127 * @event player#texttrackchange 9128 * @type {event} 9129 */ 9130/** 9131 * Retrigger the `texttrackchange` event that was triggered by the {@link Tech}. 9132 * 9133 * @private 9134 * @method Player#handleTechTexttrackchange_ 9135 * @fires Player#texttrackchange 9136 * @listens Tech#texttrackchange 9137 */ 9138'texttrackchange']; 9139 9140/** 9141 * An instance of the `Player` class is created when any of the Video.js setup methods 9142 * are used to initialize a video. 9143 * 9144 * After an instance has been created it can be accessed globally in two ways: 9145 * 1. By calling `videojs('example_video_1');` 9146 * 2. By using it directly via `videojs.players.example_video_1;` 9147 * 9148 * @extends Component 9149 */ 9150 9151var Player = function (_Component) { 9152 _inherits(Player, _Component); 9153 9154 /** 9155 * Create an instance of this class. 9156 * 9157 * @param {Element} tag
9158 * The original video DOM element used for configuring options. 9159 * 9160 * @param {Object} [options] 9161 * Object of option names and values. 9162 * 9163 * @param {Component~ReadyCallback} [ready] 9164 * Ready callback function. 9165 */ 9166 function Player(tag, options, ready) { 9167 _classCallCheck(this, Player); 9168 9169 // Make sure tag ID exists 9170 tag.id = tag.id || 'vjs_video_' + Guid.newGUID(); 9171 9172 // Set Options 9173 // The options argument overrides options set in the video tag 9174 // which overrides globally set options. 9175 // This latter part coincides with the load order 9176 // (tag must exist before Player) 9177 options = (0, _obj.assign)(Player.getTagSettings(tag), options); 9178 9179 // Delay the initialization of children because we need to set up 9180 // player properties first, and can't use `this` before `super()` 9181 options.initChildren = false; 9182 9183 // Same with creating the element 9184 options.createEl = false; 9185 9186 // we don't want the player to report touch activity on itself 9187 // see enableTouchActivity in Component 9188 options.reportTouchActivity = false; 9189 9190 // If language is not set, get the closest lang attribute 9191 if (!options.language) { 9192 if (typeof tag.closest === 'function') { 9193 var closest = tag.closest('[lang]'); 9194 9195 if (closest) { 9196 options.language = closest.getAttribute('lang'); 9197 } 9198 } else { 9199 var element = tag; 9200 9201 while (element && element.nodeType === 1) { 9202 if (Dom.getElAttributes(element).hasOwnProperty('lang')) { 9203 options.language = element.getAttribute('lang'); 9204 break; 9205 } 9206 element = element.parentNode; 9207 } 9208 } 9209 } 9210 9211 // Run base component initializing with new options 9212 9213 // if the global option object was accidentally blown away by 9214 // someone, bail early with an informative error 9215 var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready)); 9216 9217 if (!_this.options_ || !_this.options_.techOrder || !_this.options_.techOrder.length) { 9218 throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?'); 9219 } 9220 9221 // Store the original tag used to set options 9222 _this.tag = tag; 9223 9224 // Store the tag attributes used to restore html5 element 9225 _this.tagAttributes = tag && Dom.getElAttributes(tag); 9226 9227 // Update current language 9228 _this.language(_this.options_.language); 9229 9230 // Update Supported Languages 9231 if (options.languages) { 9232 // Normalise player option languages to lowercase 9233 var languagesToLower = {}; 9234 9235 Object.getOwnPropertyNames(options.languages).forEach(function (name) { 9236 languagesToLower[name.toLowerCase()] = options.languages[name]; 9237 }); 9238 _this.languages_ = languagesToLower; 9239 } else { 9240 _this.languages_ = Player.prototype.options_.languages; 9241 } 9242 9243 // Cache for video property values. 9244 _this.cache_ = {}; 9245 9246 // Set poster 9247 _this.poster_ = options.poster || ''; 9248 9249 // Set controls 9250 _this.controls_ = !!options.controls; 9251 9252 // Original tag settings stored in options 9253 // now remove immediately so native controls don't flash. 9254 // May be turned back on by HTML5 tech if nativeControlsForTouch is true 9255 tag.controls = false; 9256 9257 /* 9258 * Store the internal state of scrubbing 9259 * 9260 * @private 9261 * @return {Boolean} True if the user is scrubbing 9262 */ 9263 _this.scrubbing_ = false; 9264 9265 _this.el_ = _this.createEl(); 9266 9267 // We also want to pass the original player options to each component and plugin 9268 // as well so they don't need to reach back into the player for options later. 9269 // We also need to do another copy of this.options_ so we don't end up with 9270 // an infinite loop. 9271 var playerOptionsCopy = (0, _mergeOptions2['default'])(_this.options_); 9272 9273 // Load plugins 9274 if (options.plugins) { 9275 var plugins = options.plugins; 9276 9277 Object.getOwnPropertyNames(plugins).forEach(function (name) { 9278 if (typeof this[name] === 'function') { 9279 this[name](plugins[name]); 9280 } else { 9281 _log2['default'].error('Unable to find plugin:', name); 9282 } 9283 }, _this); 9284 } 9285 9286 _this.options_.playerOptions = playerOptionsCopy; 9287 9288 _this.initChildren(); 9289 9290 // Set isAudio based on whether or not an audio tag was used 9291 _this.isAudio(tag.nodeName.toLowerCase() === 'audio'); 9292 9293 // Update controls className. Can't do this when the controls are initially 9294 // set because the element doesn't exist yet. 9295 if (_this.controls()) { 9296 _this.addClass('vjs-controls-enabled'); 9297 } else { 9298 _this.addClass('vjs-controls-disabled'); 9299 } 9300 9301 // Set ARIA label and region role depending on player type 9302 _this.el_.setAttribute('role', 'region'); 9303 if (_this.isAudio()) { 9304 _this.el_.setAttribute('aria-label', 'audio player'); 9305 } else { 9306 _this.el_.setAttribute('aria-label', 'video player'); 9307 } 9308 9309 if (_this.isAudio()) { 9310 _this.addClass('vjs-audio'); 9311 } 9312 9313 if (_this.flexNotSupported_()) { 9314 _this.addClass('vjs-no-flex'); 9315 } 9316 9317 // TODO: Make this smarter. Toggle user state between touching/mousing 9318 // using events, since devices can have both touch and mouse events. 9319 // if (browser.TOUCH_ENABLED) { 9320 // this.addClass('vjs-touch-enabled'); 9321 // } 9322 9323 // iOS Safari has broken hover handling 9324 if (!browser.IS_IOS) { 9325 _this.addClass('vjs-workinghover'); 9326 } 9327 9328 // Make player easily findable by ID 9329 Player.players[_this.id_] = _this; 9330 9331 // When the player is first initialized, trigger activity so components 9332 // like the control bar show themselves if needed 9333 _this.userActive(true); 9334 _this.reportUserActivity(); 9335 _this.listenForUserActivity_(); 9336 9337 _this.on('fullscreenchange', _this.handleFullscreenChange_); 9338 _this.on('stageclick', _this.handleStageClick_); 9339 return _this; 9340 } 9341 9342 /** 9343 * Destroys the video player and does any necessary cleanup. 9344 * 9345 * This is especially helpful if you are dynamically adding and removing videos 9346 * to/from the DOM. 9347 * 9348 * @fires Player#dispose 9349 */ 9350 9351 9352 Player.prototype.dispose = function dispose() { 9353 /** 9354 * Called when the player is being disposed of. 9355 * 9356 * @event Player#dispose 9357 * @type {EventTarget~Event} 9358 */ 9359 this.trigger('dispose'); 9360 // prevent dispose from being called twice 9361 this.off('dispose'); 9362 9363 if (this.styleEl_ && this.styleEl_.parentNode) { 9364 this.styleEl_.parentNode.removeChild(this.styleEl_); 9365 } 9366 9367 // Kill reference to this player 9368 Player.players[this.id_] = null; 9369 9370 if (this.tag && this.tag.player) { 9371 this.tag.player = null; 9372 } 9373 9374 if (this.el_ && this.el_.player) { 9375 this.el_.player = null; 9376 } 9377 9378 if (this.tech_) { 9379 this.tech_.dispose(); 9380 } 9381 9382 _Component.prototype.dispose.call(this); 9383 }; 9384 9385 /** 9386 * Create the `Player`'s DOM element. 9387 * 9388 * @return {Element} 9389 * The DOM element that gets created. 9390 */ 9391 9392 9393 Player.prototype.createEl = function createEl() { 9394 var tag = this.tag; 9395 var el = void 0; 9396 var playerElIngest = this.playerElIngest_ = tag.parentNode && tag.parentNode.hasAttribute && tag.parentNode.hasAttribute('data-vjs-player'); 9397 9398 if (playerElIngest) { 9399 el = this.el_ = tag.parentNode; 9400 } else { 9401 el = this.el_ = _Component.prototype.createEl.call(this, 'div'); 9402 } 9403 9404 // set tabindex to -1 so we could focus on the player element 9405 tag.setAttribute('tabindex', '-1'); 9406 9407 // Remove width/height attrs from tag so CSS can make it 100% width/height 9408 tag.removeAttribute('width'); 9409 tag.removeAttribute('height'); 9410 9411 // Copy over all the attributes from the tag, including ID and class 9412 // ID will now reference player box, not the video tag 9413 var attrs = Dom.getElAttributes(tag); 9414
9415 Object.getOwnPropertyNames(attrs).forEach(function (attr) { 9416 // workaround so we don't totally break IE7 9417 // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7 9418 if (attr === 'class') { 9419 el.className += ' ' + attrs[attr]; 9420 } else { 9421 el.setAttribute(attr, attrs[attr]); 9422 } 9423 }); 9424 9425 // Update tag id/class for use as HTML5 playback tech 9426 // Might think we should do this after embedding in container so .vjs-tech class 9427 // doesn't flash 100% width/height, but class only applies with .video-js parent 9428 tag.playerId = tag.id; 9429 tag.id += '_html5_api'; 9430 tag.className = 'vjs-tech'; 9431 9432 // Make player findable on elements 9433 tag.player = el.player = this; 9434 // Default state of video is paused 9435 this.addClass('vjs-paused'); 9436 9437 // Add a style element in the player that we'll use to set the width/height 9438 // of the player in a way that's still overrideable by CSS, just like the 9439 // video element 9440 if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) { 9441 this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions'); 9442 var defaultsStyleEl = Dom.$('.vjs-styles-defaults'); 9443 var head = Dom.$('head'); 9444 9445 head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild); 9446 } 9447 9448 // Pass in the width/height/aspectRatio options which will update the style el 9449 this.width(this.options_.width); 9450 this.height(this.options_.height); 9451 this.fluid(this.options_.fluid); 9452 this.aspectRatio(this.options_.aspectRatio); 9453 9454 // Hide any links within the video/audio tag, because IE doesn't hide them completely. 9455 var links = tag.getElementsByTagName('a'); 9456 9457 for (var i = 0; i < links.length; i++) { 9458 var linkEl = links.item(i); 9459 9460 Dom.addElClass(linkEl, 'vjs-hidden'); 9461 linkEl.setAttribute('hidden', 'hidden'); 9462 } 9463 9464 // insertElFirst seems to cause the networkState to flicker from 3 to 2, so 9465 // keep track of the original for later so we can know if the source originally failed 9466 tag.initNetworkState_ = tag.networkState; 9467 9468 // Wrap video tag in div (el/box) container 9469 if (tag.parentNode && !playerElIngest) { 9470 tag.parentNode.insertBefore(el, tag); 9471 } 9472 9473 // insert the tag as the first child of the player element 9474 // then manually add it to the children array so that this.addChild 9475 // will work properly for other components 9476 // 9477 // Breaks iPhone, fixed in HTML5 setup. 9478 Dom.insertElFirst(tag, el); 9479 this.children_.unshift(tag); 9480 9481 this.el_ = el; 9482 9483 return el; 9484 }; 9485 9486 /** 9487 * A getter/setter for the `Player`'s width. 9488 * 9489 * @param {number} [value] 9490 * The value to set the `Player's width to. 9491 * 9492 * @return {number} 9493 * The current width of the `Player`. 9494 */ 9495 9496 9497 Player.prototype.width = function width(value) { 9498 return this.dimension('width', value); 9499 }; 9500 9501 /** 9502 * A getter/setter for the `Player`'s height. 9503 * 9504 * @param {number} [value] 9505 * The value to set the `Player's heigth to. 9506 * 9507 * @return {number} 9508 * The current heigth of the `Player`. 9509 */ 9510 9511 9512 Player.prototype.height = function height(value) { 9513 return this.dimension('height', value); 9514 }; 9515 9516 /** 9517 * A getter/setter for the `Player`'s width & height. 9518 * 9519 * @param {string} dimension 9520 * This string can be: 9521 * - 'width' 9522 * - 'height' 9523 * 9524 * @param {number} [value] 9525 * Value for dimension specified in the first argument. 9526 * 9527 * @return {Player|number} 9528 * - Returns itself when setting; method can be chained. 9529 * - The dimension arguments value when getting (width/height). 9530 */ 9531 9532 9533 Player.prototype.dimension = function dimension(_dimension, value) { 9534 var privDimension = _dimension + '_'; 9535 9536 if (value === undefined) { 9537 return this[privDimension] || 0; 9538 } 9539 9540 if (value === '') { 9541 // If an empty string is given, reset the dimension to be automatic 9542 this[privDimension] = undefined; 9543 } else { 9544 var parsedVal = parseFloat(value); 9545 9546 if (isNaN(parsedVal)) { 9547 _log2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension); 9548 return this; 9549 } 9550 9551 this[privDimension] = parsedVal; 9552 } 9553 9554 this.updateStyleEl_(); 9555 return this; 9556 }; 9557 9558 /** 9559 * A getter/setter/toggler for the vjs-fluid `className` on the `Player`. 9560 * 9561 * @param {boolean} [bool] 9562 * - A value of true adds the class. 9563 * - A value of false removes the class. 9564 * - No value will toggle the fluid class. 9565 * 9566 * @return {boolean|undefined} 9567 * - The value of fluid when getting. 9568 * - `undefined` when setting. 9569 */ 9570 9571 9572 Player.prototype.fluid = function fluid(bool) { 9573 if (bool === undefined) { 9574 return !!this.fluid_; 9575 } 9576 9577 this.fluid_ = !!bool; 9578 9579 if (bool) { 9580 this.addClass('vjs-fluid'); 9581 } else { 9582 this.removeClass('vjs-fluid'); 9583 } 9584 9585 this.updateStyleEl_(); 9586 }; 9587 9588 /** 9589 * Get/Set the aspect ratio 9590 * 9591 * @param {string} [ratio] 9592 * Aspect ratio for player 9593 * 9594 * @return {string|undefined} 9595 * returns the current aspect ratio when getting 9596 */ 9597 9598 /** 9599 * A getter/setter for the `Player`'s aspect ratio. 9600 * 9601 * @param {string} [ratio] 9602 * The value to set the `Player's aspect ratio to. 9603 * 9604 * @return {string|undefined} 9605 * - The current aspect ratio of the `Player` when getting. 9606 * - undefined when setting 9607 */ 9608 9609 9610 Player.prototype.aspectRatio = function aspectRatio(ratio) { 9611 if (ratio === undefined) { 9612 return this.aspectRatio_; 9613 } 9614 9615 // Check for width:height format 9616 if (!/^\d+\:\d+$/.test(ratio)) { 9617 throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.'); 9618 } 9619 this.aspectRatio_ = ratio; 9620 9621 // We're assuming if you set an aspect ratio you want fluid mode, 9622 // because in fixed mode you could calculate width and height yourself. 9623 this.fluid(true); 9624 9625 this.updateStyleEl_(); 9626 }; 9627 9628 /** 9629 * Update styles of the `Player` element (height, width and aspect ratio). 9630 * 9631 * @private 9632 * @listens Tech#loadedmetadata 9633 */ 9634 9635 9636 Player.prototype.updateStyleEl_ = function updateStyleEl_() { 9637 if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE === true) { 9638 var _width = typeof this.width_ === 'number' ? this.width_ : this.options_.width; 9639 var _height = typeof this.height_ === 'number' ? this.height_ : this.options_.height; 9640 var techEl = this.tech_ && this.tech_.el(); 9641 9642 if (techEl) { 9643 if (_width >= 0) { 9644 techEl.width = _width; 9645 } 9646 if (_height >= 0) {
9647 techEl.height = _height; 9648 } 9649 } 9650 9651 return; 9652 } 9653 9654 var width = void 0; 9655 var height = void 0; 9656 var aspectRatio = void 0; 9657 var idClass = void 0; 9658 9659 // The aspect ratio is either used directly or to calculate width and height. 9660 if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') { 9661 // Use any aspectRatio that's been specifically set 9662 aspectRatio = this.aspectRatio_; 9663 } else if (this.videoWidth() > 0) { 9664 // Otherwise try to get the aspect ratio from the video metadata 9665 aspectRatio = this.videoWidth() + ':' + this.videoHeight(); 9666 } else { 9667 // Or use a default. The video element's is 2:1, but 16:9 is more common. 9668 aspectRatio = '16:9'; 9669 } 9670 9671 // Get the ratio as a decimal we can use to calculate dimensions 9672 var ratioParts = aspectRatio.split(':'); 9673 var ratioMultiplier = ratioParts[1] / ratioParts[0]; 9674 9675 if (this.width_ !== undefined) { 9676 // Use any width that's been specifically set 9677 width = this.width_; 9678 } else if (this.height_ !== undefined) { 9679 // Or calulate the width from the aspect ratio if a height has been set 9680 width = this.height_ / ratioMultiplier; 9681 } else { 9682 // Or use the video's metadata, or use the video el's default of 300 9683 width = this.videoWidth() || 300; 9684 } 9685 9686 if (this.height_ !== undefined) { 9687 // Use any height that's been specifically set 9688 height = this.height_; 9689 } else { 9690 // Otherwise calculate the height from the ratio and the width 9691 height = width * ratioMultiplier; 9692 } 9693 9694 // Ensure the CSS class is valid by starting with an alpha character 9695 if (/^[^a-zA-Z]/.test(this.id())) { 9696 idClass = 'dimensions-' + this.id(); 9697 } else { 9698 idClass = this.id() + '-dimensions'; 9699 } 9700 9701 // Ensure the right class is still on the player for the style element 9702 this.addClass(idClass); 9703 9704 stylesheet.setTextContent(this.styleEl_, '\n .' + idClass + ' {\n width: ' + width + 'px;\n height: ' + height + 'px;\n }\n\n .' + idClass + '.vjs-fluid {\n padding-top: ' + ratioMultiplier * 100 + '%;\n }\n '); 9705 }; 9706 9707 /** 9708 * Load/Create an instance of playback {@link Tech} including element 9709 * and API methods. Then append the `Tech` element in `Player` as a child. 9710 * 9711 * @param {string} techName 9712 * name of the playback technology 9713 * 9714 * @param {string} source 9715 * video source 9716 * 9717 * @private 9718 */ 9719 9720 9721 Player.prototype.loadTech_ = function loadTech_(techName, source) { 9722 var _this2 = this; 9723 9724 // Pause and remove current playback technology 9725 if (this.tech_) { 9726 this.unloadTech_(); 9727 } 9728 9729 // get rid of the HTML5 video tag as soon as we are using another tech 9730 if (techName !== 'Html5' && this.tag) { 9731 _tech2['default'].getTech('Html5').disposeMediaElement(this.tag); 9732 this.tag.player = null; 9733 this.tag = null; 9734 } 9735 9736 this.techName_ = techName; 9737 9738 // Turn off API access because we're loading a new tech that might load asynchronously 9739 this.isReady_ = false; 9740 9741 // Grab tech-specific options from player options and add source and parent element to use. 9742 var techOptions = (0, _obj.assign)({ 9743 source: source, 9744 'nativeControlsForTouch': this.options_.nativeControlsForTouch, 9745 'playerId': this.id(), 9746 'techId': this.id() + '_' + techName + '_api', 9747 'videoTracks': this.videoTracks_, 9748 'textTracks': this.textTracks_, 9749 'audioTracks': this.audioTracks_, 9750 'autoplay': this.options_.autoplay, 9751 'preload': this.options_.preload, 9752 'loop': this.options_.loop, 9753 'muted': this.options_.muted, 9754 'poster': this.poster(), 9755 'language': this.language(), 9756 'playerElIngest': this.playerElIngest_ || false, 9757 'vtt.js': this.options_['vtt.js'] 9758 }, this.options_[techName.toLowerCase()]); 9759 9760 if (this.tag) { 9761 techOptions.tag = this.tag; 9762 } 9763 9764 if (source) { 9765 this.currentType_ = source.type; 9766 9767 if (source.src === this.cache_.src && this.cache_.currentTime > 0) { 9768 techOptions.startTime = this.cache_.currentTime; 9769 } 9770 9771 this.cache_.sources = null; 9772 this.cache_.source = source; 9773 this.cache_.src = source.src; 9774 } 9775 9776 // Initialize tech instance 9777 var TechComponent = _tech2['default'].getTech(techName); 9778
9779 // Support old behavior of techs being registered as components. 9780 // Remove once that deprecated behavior is removed. 9781 if (!TechComponent) { 9782 TechComponent = _component2['default'].getComponent(techName); 9783 } 9784 this.tech_ = new TechComponent(techOptions); 9785 9786 // player.triggerReady is always async, so don't need this to be async 9787 this.tech_.ready(Fn.bind(this, this.handleTechReady_), true); 9788 9789 _textTrackListConverter2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_); 9790 9791 // Listen to all HTML5-defined events and trigger them on the player 9792 TECH_EVENTS_RETRIGGER.forEach(function (event) { 9793 _this2.on(_this2.tech_, event, _this2['handleTech' + (0, _toTitleCase2['default'])(event) + '_']); 9794 }); 9795 this.on(this.tech_, 'loadstart', this.handleTechLoadStart_); 9796 this.on(this.tech_, 'waiting', this.handleTechWaiting_); 9797 this.on(this.tech_, 'canplay', this.handleTechCanPlay_); 9798 this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_); 9799 this.on(this.tech_, 'playing', this.handleTechPlaying_); 9800 this.on(this.tech_, 'ended', this.handleTechEnded_); 9801 this.on(this.tech_, 'seeking', this.handleTechSeeking_); 9802 this.on(this.tech_, 'seeked', this.handleTechSeeked_); 9803 this.on(this.tech_, 'play', this.handleTechPlay_); 9804 this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_); 9805 this.on(this.tech_, 'pause', this.handleTechPause_); 9806 this.on(this.tech_, 'durationchange', this.handleTechDurationChange_); 9807 this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_); 9808 this.on(this.tech_, 'error', this.handleTechError_); 9809 this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_); 9810 this.on(this.tech_, 'posterchange', this.handleTechPosterChange_); 9811 this.on(this.tech_, 'textdata', this.handleTechTextData_); 9812 9813 this.usingNativeControls(this.techGet_('controls')); 9814 9815 if (this.controls() && !this.usingNativeControls()) { 9816 this.addTechControlsListeners_(); 9817 } 9818 9819 // Add the tech element in the DOM if it was not already there 9820 // Make sure to not insert the original video element if using Html5 9821 if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) { 9822 Dom.insertElFirst(this.tech_.el(), this.el()); 9823 } 9824 9825 // Get rid of the original video tag reference after the first tech is loaded 9826 if (this.tag) { 9827 this.tag.player = null; 9828 this.tag = null; 9829 } 9830 }; 9831 9832 /** 9833 * Unload and dispose of the current playback {@link Tech}. 9834 * 9835 * @private 9836 */ 9837 9838 9839 Player.prototype.unloadTech_ = function unloadTech_() { 9840 // Save the current text tracks so that we can reuse the same text tracks with the next tech 9841 this.videoTracks_ = this.videoTracks(); 9842 this.textTracks_ = this.textTracks(); 9843 this.audioTracks_ = this.audioTracks(); 9844 this.textTracksJson_ = _textTrackListConverter2['default'].textTracksToJson(this.tech_); 9845 9846 this.isReady_ = false; 9847 9848 this.tech_.dispose(); 9849 9850 this.tech_ = false;
9851 }; 9852 9853 /** 9854 * Return a reference to the current {@link Tech}, but only if given an object with the 9855 * `IWillNotUseThisInPlugins` property having a true value. This is try and prevent misuse 9856 * of techs by plugins. 9857 * 9858 * @param {Object} safety 9859 * An object that must contain `{IWillNotUseThisInPlugins: true}` 9860 * 9861 * @param {boolean} safety.IWillNotUseThisInPlugins 9862 * Must be set to true or else this function will throw an error. 9863 * 9864 * @return {Tech} 9865 * The Tech 9866 */ 9867 9868 9869 Player.prototype.tech = function tech(safety) { 9870 if (safety && safety.IWillNotUseThisInPlugins) { 9871 return this.tech_; 9872 } 9873 var errorText = '\n Please make sure that you are not using this inside of a plugin.\n To disable this alert and error, please pass in an object with\n `IWillNotUseThisInPlugins` to the `tech` method. See\n https://github.com/videojs/video.js/issues/2617 for more info.\n '; 9874 9875 _window2['default'].alert(errorText); 9876 throw new Error(errorText); 9877 }; 9878 9879 /** 9880 * Set up click and touch listeners for the playback element 9881 * 9882 * - On desktops: a click on the video itself will toggle playback 9883 * - On mobile devices: a click on the video toggles controls 9884 * which is done by toggling the user state between active and 9885 * inactive 9886 * - A tap can signal that a user has become active or has become inactive 9887 * e.g. a quick tap on an iPhone movie should reveal the controls. Another 9888 * quick tap should hide them again (signaling the user is in an inactive 9889 * viewing state) 9890 * - In addition to this, we still want the user to be considered inactive after 9891 * a few seconds of inactivity. 9892 * 9893 * > Note: the only part of iOS interaction we can't mimic with this setup 9894 * is a touch and hold on the video element counting as activity in order to 9895 * keep the controls showing, but that shouldn't be an issue. A touch and hold 9896 * on any controls will still keep the user active 9897 * 9898 * @private 9899 */ 9900 9901 9902 Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() { 9903 // Make sure to remove all the previous listeners in case we are called multiple times. 9904 this.removeTechControlsListeners_(); 9905 9906 // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do 9907 // trigger mousedown/up. 9908 // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object 9909 // Any touch events are set to block the mousedown event from happening 9910 this.on(this.tech_, 'mousedown', this.handleTechClick_); 9911 9912 // If the controls were hidden we don't want that to change without a tap event 9913 // so we'll check if the controls were already showing before reporting user 9914 // activity 9915 this.on(this.tech_, 'touchstart', this.handleTechTouchStart_); 9916 this.on(this.tech_, 'touchmove', this.handleTechTouchMove_); 9917 this.on(this.tech_, 'touchend', this.handleTechTouchEnd_); 9918 9919 // The tap listener needs to come after the touchend listener because the tap 9920 // listener cancels out any reportedUserActivity when setting userActive(false) 9921 this.on(this.tech_, 'tap', this.handleTechTap_); 9922 }; 9923 9924 /** 9925 * Remove the listeners used for click and tap controls. This is needed for 9926 * toggling to controls disabled, where a tap/touch should do nothing. 9927 * 9928 * @private 9929 */ 9930 9931 9932 Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() { 9933 // We don't want to just use `this.off()` because there might be other needed 9934 // listeners added by techs that extend this. 9935 this.off(this.tech_, 'tap', this.handleTechTap_); 9936 this.off(this.tech_, 'touchstart', this.handleTechTouchStart_); 9937 this.off(this.tech_, 'touchmove', this.handleTechTouchMove_); 9938 this.off(this.tech_, 'touchend', this.handleTechTouchEnd_); 9939 this.off(this.tech_, 'mousedown', this.handleTechClick_); 9940 }; 9941 9942 /** 9943 * Player waits for the tech to be ready 9944 * 9945 * @private 9946 */ 9947 9948 9949 Player.prototype.handleTechReady_ = function handleTechReady_() { 9950 this.triggerReady(); 9951 9952 // Keep the same volume as before 9953 if (this.cache_.volume) { 9954 this.techCall_('setVolume', this.cache_.volume); 9955 } 9956 9957 // Look if the tech found a higher resolution poster while loading 9958 this.handleTechPosterChange_(); 9959 9960 // Update the duration if available 9961 this.handleTechDurationChange_(); 9962 9963 // Chrome and Safari both have issues with autoplay. 9964 // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work. 9965 // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays) 9966 // This fixes both issues. Need to wait for API, so it updates displays correctly 9967 if ((this.src() || this.currentSrc()) && this.tag && this.options_.autoplay && this.paused()) {
9968 try { 9969 // Chrome Fix. Fixed in Chrome v16. 9970 delete this.tag.poster; 9971 } catch (e) { 9972 (0, _log2['default'])('deleting tag.poster throws in some browsers', e); 9973 } 9974 this.play(); 9975 } 9976 }; 9977 9978 /** 9979 * Retrigger the `loadstart` event that was triggered by the {@link Tech}. This 9980 * function will also trigger {@link Player#firstplay} if it is the first loadstart 9981 * for a video. 9982 * 9983 * @fires Player#loadstart 9984 * @fires Player#firstplay 9985 * @listens Tech#loadstart 9986 * @private 9987 */ 9988 9989 9990 Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() { 9991 // TODO: Update to use `emptied` event instead. See #1277. 9992 9993 this.removeClass('vjs-ended'); 9994 this.removeClass('vjs-seeking'); 9995 9996 // reset the error state 9997 this.error(null); 9998 9999 // If it's already playing we want to trigger a firstplay event now. 10000 // The firstplay event relies on both the play and loadstart events 10001 // which can happen in any order for a new source 10002 if (!this.paused()) { 10003 /** 10004 * Fired when the user agent begins looking for media data 10005 * 10006 * @event Player#loadstart 10007 * @type {EventTarget~Event} 10008 */ 10009 this.trigger('loadstart'); 10010 this.trigger('firstplay'); 10011 } else { 10012 // reset the hasStarted state 10013 this.hasStarted(false); 10014 this.trigger('loadstart'); 10015 } 10016 }; 10017 10018 /** 10019 * Add/remove the vjs-has-started class 10020 * 10021 * @fires Player#firstplay 10022 * 10023 * @param {boolean} hasStarted 10024 * - true: adds the class 10025 * - false: remove the class 10026 * 10027 * @return {boolean} 10028 * the boolean value of hasStarted 10029 */ 10030 10031 10032 Player.prototype.hasStarted = function hasStarted(_hasStarted) { 10033 if (_hasStarted !== undefined) { 10034 // only update if this is a new value 10035 if (this.hasStarted_ !== _hasStarted) { 10036 this.hasStarted_ = _hasStarted; 10037 if (_hasStarted) { 10038 this.addClass('vjs-has-started'); 10039 // trigger the firstplay event if this newly has played 10040 this.trigger('firstplay'); 10041 } else { 10042 this.removeClass('vjs-has-started'); 10043 } 10044 } 10045 return this; 10046 } 10047 return !!this.hasStarted_; 10048 }; 10049 10050 /** 10051 * Fired whenever the media begins or resumes playback 10052 * 10053 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play} 10054 * @fires Player#play 10055 * @listens Tech#play 10056 * @private 10057 */ 10058 10059 10060 Player.prototype.handleTechPlay_ = function handleTechPlay_() { 10061 this.removeClass('vjs-ended'); 10062 this.removeClass('vjs-paused'); 10063 this.addClass('vjs-playing'); 10064 10065 // hide the poster when the user hits play 10066 this.hasStarted(true); 10067 /** 10068 * Triggered whenever an {@link Tech#play} event happens. Indicates that 10069 * playback has started or resumed. 10070 * 10071 * @event Player#play 10072 * @type {EventTarget~Event} 10073 */ 10074 this.trigger('play'); 10075 }; 10076 10077 /** 10078 * Retrigger the `waiting` event that was triggered by the {@link Tech}. 10079 * 10080 * @fires Player#waiting 10081 * @listens Tech#waiting 10082 * @private 10083 */ 10084 10085 10086 Player.prototype.handleTechWaiting_ = function handleTechWaiting_() { 10087 var _this3 = this; 10088 10089 this.addClass('vjs-waiting'); 10090 /** 10091 * A readyState change on the DOM element has caused playback to stop. 10092 * 10093 * @event Player#waiting 10094 * @type {EventTarget~Event} 10095 */ 10096 this.trigger('waiting'); 10097 this.one('timeupdate', function () { 10098 return _this3.removeClass('vjs-waiting'); 10099 }); 10100 }; 10101 10102 /** 10103 * Retrigger the `canplay` event that was triggered by the {@link Tech}. 10104 * > Note: This is not consistent between browsers. See #1351 10105 * 10106 * @fires Player#canplay 10107 * @listens Tech#canplay 10108 * @private 10109 */ 10110 10111 10112 Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() { 10113 this.removeClass('vjs-waiting'); 10114 /** 10115 * The media has a readyState of HAVE_FUTURE_DATA or greater. 10116 * 10117 * @event Player#canplay 10118 * @type {EventTarget~Event} 10119 */ 10120 this.trigger('canplay'); 10121 }; 10122 10123 /** 10124 * Retrigger the `canplaythrough` event that was triggered by the {@link Tech}. 10125 * 10126 * @fires Player#canplaythrough 10127 * @listens Tech#canplaythrough 10128 * @private 10129 */ 10130 10131 10132 Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() { 10133 this.removeClass('vjs-waiting'); 10134 /** 10135 * The media has a readyState of HAVE_ENOUGH_DATA or greater. This means that the 10136 * entire media file can be played without buffering. 10137 * 10138 * @event Player#canplaythrough 10139 * @type {EventTarget~Event} 10140 */ 10141 this.trigger('canplaythrough'); 10142 }; 10143 10144 /** 10145 * Retrigger the `playing` event that was triggered by the {@link Tech}. 10146 * 10147 * @fires Player#playing 10148 * @listens Tech#playing 10149 * @private 10150 */ 10151 10152 10153 Player.prototype.handleTechPlaying_ = function handleTechPlaying_() { 10154 this.removeClass('vjs-waiting'); 10155 /** 10156 * The media is no longer blocked from playback, and has started playing. 10157 * 10158 * @event Player#playing 10159 * @type {EventTarget~Event} 10160 */ 10161 this.trigger('playing'); 10162 }; 10163 10164 /** 10165 * Retrigger the `seeking` event that was triggered by the {@link Tech}. 10166 * 10167 * @fires Player#seeking 10168 * @listens Tech#seeking 10169 * @private 10170 */ 10171 10172 10173 Player.prototype.handleTechSeeking_ = function handleTechSeeking_() { 10174 this.addClass('vjs-seeking'); 10175 /** 10176 * Fired whenever the player is jumping to a new time 10177 * 10178 * @event Player#seeking 10179 * @type {EventTarget~Event} 10180 */ 10181 this.trigger('seeking'); 10182 }; 10183 10184 /** 10185 * Retrigger the `seeked` event that was triggered by the {@link Tech}. 10186 * 10187 * @fires Player#seeked 10188 * @listens Tech#seeked 10189 * @private 10190 */ 10191 10192 10193 Player.prototype.handleTechSeeked_ = function handleTechSeeked_() { 10194 this.removeClass('vjs-seeking'); 10195 /** 10196 * Fired when the player has finished jumping to a new time 10197 * 10198 * @event Player#seeked 10199 * @type {EventTarget~Event} 10200 */ 10201 this.trigger('seeked'); 10202 }; 10203 10204 /** 10205 * Retrigger the `firstplay` event that was triggered by the {@link Tech}. 10206 * 10207 * @fires Player#firstplay 10208 * @listens Tech#firstplay 10209 * @deprecated As of 6.0 passing the `starttime` option to the player will be deprecated 10210 * @private 10211 */ 10212 10213 10214 Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() { 10215 // If the first starttime attribute is specified 10216 // then we will start at the given offset in seconds 10217 if (this.options_.starttime) { 10218 _log2['default'].warn('Passing the `starttime` option to the player will be deprecated
vendor: 6,466 bytes, lines 10218-10508
10218in 6.0'); 10219 this.currentTime(this.options_.starttime); 10220 } 10221 10222 this.addClass('vjs-has-started'); 10223 /** 10224 * Fired the first time a video is played. Not part of the HLS spec, and this is 10225 * probably not the best implementation yet, so use sparingly. If you don't have a 10226 * reason to prevent playback, use `myPlayer.one('play');` instead. 10227 * 10228 * @event Player#firstplay 10229 * @type {EventTarget~Event} 10230 */ 10231 this.trigger('firstplay'); 10232 }; 10233 10234 /** 10235 * Retrigger the `pause` event that was triggered by the {@link Tech}. 10236 * 10237 * @fires Player#pause 10238 * @listens Tech#pause 10239 * @private 10240 */ 10241 10242 10243 Player.prototype.handleTechPause_ = function handleTechPause_() { 10244 this.removeClass('vjs-playing'); 10245 this.addClass('vjs-paused'); 10246 /** 10247 * Fired whenever the media has been paused 10248 * 10249 * @event Player#pause 10250 * @type {EventTarget~Event} 10251 */ 10252 this.trigger('pause'); 10253 }; 10254 10255 /** 10256 * Retrigger the `ended` event that was triggered by the {@link Tech}. 10257 * 10258 * @fires Player#ended 10259 * @listens Tech#ended 10260 * @private 10261 */ 10262 10263 10264 Player.prototype.handleTechEnded_ = function handleTechEnded_() { 10265 this.addClass('vjs-ended'); 10266 if (this.options_.loop) { 10267 this.currentTime(0); 10268 this.play(); 10269 } else if (!this.paused()) { 10270 this.pause(); 10271 } 10272 10273 /** 10274 * Fired when the end of the media resource is reached (currentTime == duration) 10275 * 10276 * @event Player#ended 10277 * @type {EventTarget~Event} 10278 */ 10279 this.trigger('ended'); 10280 }; 10281 10282 /** 10283 * Fired when the duration of the media resource is first known or changed 10284 * 10285 * @listens Tech#durationchange 10286 * @private 10287 */ 10288 10289 10290 Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() { 10291 this.duration(this.techGet_('duration')); 10292 }; 10293 10294 /** 10295 * Handle a click on the media element to play/pause 10296 * 10297 * @param {EventTarget~Event} event 10298 * the event that caused this function to trigger 10299 * 10300 * @listens Tech#mousedown 10301 * @private 10302 */ 10303 10304 10305 Player.prototype.handleTechClick_ = function handleTechClick_(event) { 10306 // We're using mousedown to detect clicks thanks to Flash, but mousedown 10307 // will also be triggered with right-clicks, so we need to prevent that 10308 if (event.button !== 0) { 10309 return; 10310 } 10311 10312 // When controls are disabled a click should not toggle playback because 10313 // the click is considered a control 10314 if (this.controls()) { 10315 if (this.paused()) { 10316 this.play(); 10317 } else { 10318 this.pause(); 10319 } 10320 } 10321 }; 10322 10323 /** 10324 * Handle a tap on the media element. It will toggle the user 10325 * activity state, which hides and shows the controls. 10326 * 10327 * @listens Tech#tap 10328 * @private 10329 */ 10330 10331 10332 Player.prototype.handleTechTap_ = function handleTechTap_() { 10333 this.userActive(!this.userActive()); 10334 }; 10335 10336 /** 10337 * Handle touch to start 10338 * 10339 * @listens Tech#touchstart 10340 * @private 10341 */ 10342 10343 10344 Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() { 10345 this.userWasActive = this.userActive(); 10346 }; 10347 10348 /** 10349 * Handle touch to move 10350 * 10351 * @listens Tech#touchmove 10352 * @private 10353 */ 10354 10355 10356 Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() { 10357 if (this.userWasActive) { 10358 this.reportUserActivity(); 10359 } 10360 }; 10361 10362 /** 10363 * Handle touch to end 10364 * 10365 * @param {EventTarget~Event} event 10366 * the touchend event that triggered 10367 * this function 10368 * 10369 * @listens Tech#touchend 10370 * @private 10371 */ 10372 10373 10374 Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) { 10375 // Stop the mouse events from also happening 10376 event.preventDefault(); 10377 }; 10378 10379 /** 10380 * Fired when the player switches in or out of fullscreen mode 10381 * 10382 * @private 10383 * @listens Player#fullscreenchange 10384 */ 10385 10386 10387 Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() { 10388 if (this.isFullscreen()) { 10389 this.addClass('vjs-fullscreen'); 10390 } else { 10391 this.removeClass('vjs-fullscreen'); 10392 } 10393 }; 10394 10395 /** 10396 * native click events on the SWF aren't triggered on IE11, Win8.1RT 10397 * use stageclick events triggered from inside the SWF instead 10398 * 10399 * @private 10400 * @listens stageclick 10401 */ 10402 10403 10404 Player.prototype.handleStageClick_ = function handleStageClick_() { 10405 this.reportUserActivity(); 10406 }; 10407 10408 /** 10409 * Handle Tech Fullscreen Change 10410 * 10411 * @param {EventTarget~Event} event 10412 * the fullscreenchange event that triggered this function 10413 * 10414 * @param {Object} data 10415 * the data that was sent with the event 10416 * 10417 * @private 10418 * @listens Tech#fullscreenchange 10419 * @fires Player#fullscreenchange 10420 */ 10421 10422 10423 Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) { 10424 if (data) { 10425 this.isFullscreen(data.isFullscreen); 10426 } 10427 /** 10428 * Fired when going in and out of fullscreen. 10429 * 10430 * @event Player#fullscreenchange 10431 * @type {EventTarget~Event} 10432 */ 10433 this.trigger('fullscreenchange'); 10434 }; 10435 10436 /** 10437 * Fires when an error occurred during the loading of an audio/video. 10438 * 10439 * @private 10440 * @listens Tech#error 10441 */ 10442 10443 10444 Player.prototype.handleTechError_ = function handleTechError_() { 10445 var error = this.tech_.error(); 10446 10447 this.error(error); 10448 }; 10449 10450 /** 10451 * Retrigger the `textdata` event that was triggered by the {@link Tech}. 10452 * 10453 * @fires Player#textdata 10454 * @listens Tech#textdata 10455 * @private 10456 */ 10457 10458 10459 Player.prototype.handleTechTextData_ = function handleTechTextData_() { 10460 var data = null; 10461 10462 if (arguments.length > 1) { 10463 data = arguments[1]; 10464 } 10465 10466 /** 10467 * Fires when we get a textdata event from tech 10468 * 10469 * @event Player#textdata 10470 * @type {EventTarget~Event} 10471 */ 10472 this.trigger('textdata', data); 10473 }; 10474 10475 /** 10476 * Get object for cached values. 10477 * 10478 * @return {Object} 10479 * get the current object cache 10480 */ 10481 10482 10483 Player.prototype.getCache = function getCache() { 10484 return this.cache_; 10485 }; 10486 10487 /** 10488 * Pass values to the playback tech 10489 * 10490 * @param {string} [method] 10491 * the method to call 10492 * 10493 * @param {Object} arg 10494 * the argument to pass 10495 * 10496 * @private 10497 */ 10498 10499 10500 Player.prototype.techCall_ = function techCall_(method, arg) { 10501 // If it's not ready yet, call method when it is 10502 if (this.tech_ && !this.tech_.isReady_) { 10503 this.tech_.ready(function () { 10504 this[method](arg); 10505 }, true); 10506 10507 // Otherwise call method now 10508 } else {
10509 try { 10510 if (this.tech_) { 10511 this.tech_[method](arg); 10512 } 10513 } catch (e) { 10514 (0, _log2['default'])(e); 10515 throw e; 10516 } 10517 } 10518 }; 10519 10520 /** 10521 * Get calls can't wait for the tech, and sometimes don't need to. 10522 * 10523 * @param {string} method 10524 * Tech method 10525 * 10526 * @return {Function|undefined} 10527 * the method or undefined 10528 * 10529 * @private 10530 */ 10531 10532 10533 Player.prototype.techGet_ = function techGet_(method) { 10534 if (this.tech_ && this.tech_.isReady_) { 10535 10536 // Flash likes to die and reload when you hide or reposition it. 10537 // In these cases the object methods go away and we get errors. 10538 // When that happens we'll catch the errors and inform tech that it's not ready any more. 10539 try { 10540 return this.tech_[method](); 10541 } catch (e) { 10542 // When building additional tech libs, an expected method may not be defined yet 10543 if (this.tech_[method] === undefined) { 10544 (0, _log2['default'])('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e); 10545 10546 // When a method isn't available on the object it throws a TypeError 10547 } else if (e.name === 'TypeError') { 10548 (0, _log2['default'])('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e); 10549 this.tech_.isReady_ = false; 10550 } else { 10551 (0, _log2['default'])(e); 10552 } 10553 throw e; 10554 } 10555 } 10556 10557 return; 10558 }; 10559 10560 /** 10561 * start media playback 10562 * 10563 * @return {Player} 10564 * A reference to the player object this function was called on 10565 */ 10566 10567 10568 Player.prototype.play = function play() { 10569 // Only calls the tech's play if we already have a src loaded 10570 if (this.src() || this.currentSrc()) { 10571 this.techCall_('play'); 10572 } else { 10573 this.tech_.one('loadstart', function () { 10574 this.play(); 10575 }); 10576 } 10577 10578 return this; 10579 }; 10580 10581 /** 10582 * Pause the video playback 10583 * 10584 * @return {Player} 10585 * A reference to the player object this function was called on 10586 */ 10587 10588 10589 Player.prototype.pause = function pause() { 10590 this.techCall_('pause'); 10591 return this; 10592 }; 10593 10594 /** 10595 * Check if the player is paused or has yet to play 10596 * 10597 * @return {boolean} 10598 * - false: if the media is currently playing 10599 * - true: if media is not currently playing 10600 */ 10601 10602 10603 Player.prototype.paused = function paused() { 10604 // The initial state of paused should be true (in Safari it's actually false) 10605 return this.techGet_('paused') === false ? false : true; 10606 }; 10607 10608 /** 10609 * Returns whether or not the user is "scrubbing". Scrubbing is 10610 * when the user has clicked the progress bar handle and is 10611 * dragging it along the progress bar. 10612 * 10613 * @param {boolean} [isScrubbing] 10614 * wether the user is or is not scrubbing 10615 * 10616 * @return {boolean|Player} 10617 * A instance of the player that called this function when setting, 10618 * and the value of scrubbing when getting 10619 */ 10620 10621 10622 Player.prototype.scrubbing = function scrubbing(isScrubbing) { 10623 if (isScrubbing !== undefined) { 10624 this.scrubbing_ = !!isScrubbing; 10625 10626 if (isScrubbing) { 10627 this.addClass('vjs-scrubbing'); 10628 } else { 10629 this.removeClass('vjs-scrubbing'); 10630 } 10631 10632 return this; 10633 } 10634 10635 return this.scrubbing_; 10636 }; 10637 10638 /** 10639 * Get or set the current time (in seconds) 10640 * 10641 * @param {number|string} [seconds] 10642 * The time to seek to in seconds 10643 * 10644 * @return {Player|number} 10645 * - the current time in seconds when getting 10646 * - a reference to the current player object when setting 10647 */ 10648 10649 10650 Player.prototype.currentTime = function currentTime(seconds) { 10651 if (seconds !== undefined) { 10652 10653 this.techCall_('setCurrentTime', seconds); 10654 10655 return this; 10656 } 10657 10658 // cache last currentTime and return. default to 0 seconds 10659 // 10660 // Caching the currentTime is meant to prevent a massive amount of reads on the tech's 10661 // currentTime when scrubbing, but may not provide much performance benefit afterall. 10662 // Should be tested. Also something has to read the actual current time or the cache will 10663 // never get updated. 10664 this.cache_.currentTime = this.techGet_('currentTime') || 0; 10665 return this.cache_.currentTime; 10666 }; 10667 10668 /** 10669 * Normally gets the length in time of the video in seconds; 10670 * in all but the rarest use cases an argument will NOT be passed to the method 10671 * 10672 * > **NOTE**: The video must have started loading before the duration can be 10673 * known, and in the case of Flash, may not be known until the video starts 10674 * playing. 10675 * 10676 * @fires Player#durationchange 10677 * 10678 * @param {number} [seconds] 10679 * The duration of the video to set in seconds 10680 * 10681 * @return {number|Player} 10682 * - The duration of the video in seconds when getting 10683 * - A reference to the player that called this function 10684 * when setting 10685 */ 10686 10687 10688 Player.prototype.duration = function duration(seconds) { 10689 if (seconds === undefined) { 10690 return this.cache_.duration || 0; 10691 } 10692 10693 seconds = parseFloat(seconds) || 0; 10694 10695 // Standardize on Inifity for signaling video is live 10696 if (seconds < 0) { 10697 seconds = Infinity; 10698 } 10699 10700 if (seconds !== this.cache_.duration) { 10701 // Cache the last set value for optimized scrubbing (esp. Flash) 10702 this.cache_.duration = seconds; 10703 10704 if (seconds === Infinity) { 10705 this.addClass('vjs-live'); 10706 } else { 10707 this.removeClass('vjs-live'); 10708 } 10709 /** 10710 * @event Player#durationchange 10711 * @type {EventTarget~Event} 10712 */ 10713 this.trigger('durationchange'); 10714 } 10715 10716 return this; 10717 }; 10718 10719 /** 10720 * Calculates how much time is left in the video. Not part 10721 * of the native video API. 10722 * 10723 * @return {number} 10724 * The time remaining in seconds 10725 */ 10726 10727 10728 Player.prototype.remainingTime = function remainingTime() { 10729 return this.duration() - this.currentTime(); 10730 }; 10731 10732 // 10733 // Kind of like an array of portions of the video that have been downloaded.
10734 10735 /** 10736 * Get a TimeRange object with an array of the times of the video 10737 * that have been downloaded. If you just want the percent of the 10738 * video that's been downloaded, use bufferedPercent. 10739 * 10740 * @see [Buffered Spec]{@link http://dev.w3.org/html5/spec/video.html#dom-media-buffered} 10741 * 10742 * @return {TimeRange} 10743 * A mock TimeRange object (following HTML spec) 10744 */ 10745 10746 10747 Player.prototype.buffered = function buffered() { 10748 var buffered = this.techGet_('buffered'); 10749 10750 if (!buffered || !buffered.length) { 10751 buffered = (0, _timeRanges.createTimeRange)(0, 0); 10752 } 10753 10754 return buffered; 10755 }; 10756 10757 /** 10758 * Get the percent (as a decimal) of the video that's been downloaded. 10759 * This method is not a part of the native HTML video API. 10760 * 10761 * @return {number} 10762 * A decimal between 0 and 1 representing the percent 10763 * that is bufferred 0 being 0% and 1 being 100% 10764 */ 10765 10766 10767 Player.prototype.bufferedPercent = function bufferedPercent() { 10768 return (0, _buffer.bufferedPercent)(this.buffered(), this.duration()); 10769 }; 10770 10771 /** 10772 * Get the ending time of the last buffered time range 10773 * This is used in the progress bar to encapsulate all time ranges. 10774 * 10775 * @return {number} 10776 * The end of the last buffered time range 10777 */ 10778 10779 10780 Player.prototype.bufferedEnd = function bufferedEnd() { 10781 var buffered = this.buffered(); 10782 var duration = this.duration(); 10783 var end = buffered.end(buffered.length - 1); 10784 10785 if (end > duration) { 10786 end = duration; 10787 } 10788 10789 return end; 10790 }; 10791 10792 /** 10793 * Get or set the current volume of the media 10794 * 10795 * @param {number} [percentAsDecimal] 10796 * The new volume as a decimal percent: 10797 * - 0 is muted/0%/off 10798 * - 1.0 is 100%/full 10799 * - 0.5 is half volume or 50% 10800 * 10801 * @return {Player|number} 10802 * a reference to the calling player when setting and the 10803 * current volume as a percent when getting 10804 */ 10805 10806 10807 Player.prototype.volume = function volume(percentAsDecimal) { 10808 var vol = void 0; 10809 10810 if (percentAsDecimal !== undefined) { 10811 // Force value to between 0 and 1 10812 vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); 10813 this.cache_.volume = vol; 10814 this.techCall_('setVolume', vol); 10815 10816 return this; 10817 } 10818 10819 // Default to 1 when returning current volume. 10820 vol = parseFloat(this.techGet_('volume')); 10821 return isNaN(vol) ? 1 : vol; 10822 }; 10823 10824 /** 10825 * Get the current muted state, or turn mute on or off 10826 * 10827 * @param {boolean} [muted] 10828 * - true to mute 10829 * - false to unmute 10830 * 10831 * @return {boolean|Player} 10832 * - true if mute is on and getting 10833 * - false if mute is off and getting 10834 * - A reference to the current player when setting 10835 */ 10836 10837 10838 Player.prototype.muted = function muted(_muted) { 10839 if (_muted !== undefined) { 10840 this.techCall_('setMuted', _muted); 10841 return this; 10842 } 10843 return this.techGet_('muted') || false; 10844 }; 10845 10846 /** 10847 * Check if current tech can support native fullscreen 10848 * (e.g. with built in controls like iOS, so not our flash swf) 10849 * 10850 * @return {boolean} 10851 * if native fullscreen is supported 10852 */ 10853 10854 10855 Player.prototype.supportsFullScreen = function supportsFullScreen() { 10856 return this.techGet_('supportsFullScreen') || false; 10857 }; 10858 10859 /** 10860 * Check if the player is in fullscreen mode or tell the player that it 10861 * is or is not in fullscreen mode. 10862 * 10863 * > NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official 10864 * property and instead document.fullscreenElement is used. But isFullscreen is 10865 * still a valuable property for internal player workings. 10866 * 10867 * @param {boolean} [isFS] 10868 * Set the players current fullscreen state 10869 * 10870 * @return {boolean|Player} 10871 * - true if fullscreen is on and getting 10872 * - false if fullscreen is off and getting 10873 * - A reference to the current player when setting 10874 */ 10875 10876 10877 Player.prototype.isFullscreen = function isFullscreen(isFS) { 10878 if (isFS !== undefined) { 10879 this.isFullscreen_ = !!isFS; 10880 return this; 10881 } 10882 return !!this.isFullscreen_; 10883 }; 10884 10885 /** 10886 * Increase the size of the video to full screen 10887 * In some browsers, full screen is not supported natively, so it enters 10888 * "full window mode", where the video fills the browser window. 10889 * In browsers and devices that support native full screen, sometimes the 10890 * browser's default controls will be shown, and not the Video.js custom skin. 10891 * This includes most mobile devices (iOS, Android) and older versions of 10892 * Safari. 10893 * 10894 * @fires Player#fullscreenchange 10895 * @return {Player} 10896 * A reference to the current player 10897 */ 10898 10899 10900 Player.prototype.requestFullscreen = function requestFullscreen() { 10901 var fsApi = _fullscreenApi2['default']; 10902 10903 this.isFullscreen(true); 10904 10905 if (fsApi.requestFullscreen) { 10906 // the browser supports going fullscreen at the element level so we can 10907 // take the controls fullscreen as well as the video 10908 10909 // Trigger fullscreenchange event after change 10910 // We have to specifically add this each time, and remove 10911 // when canceling fullscreen. Otherwise if there's multiple 10912 // players on a page, they would all be reacting to the same fullscreen 10913 // events 10914 Events.on(_document2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) { 10915 this.isFullscreen(_document2['default'][fsApi.fullscreenElement]); 10916 10917 // If cancelling fullscreen, remove event listener. 10918 if (this.isFullscreen() === false) { 10919 Events.off(_document2['default'], fsApi.fullscreenchange, documentFullscreenChange); 10920 } 10921 /** 10922 * @event Player#fullscreenchange 10923 * @type {EventTarget~Event} 10924 */ 10925 this.trigger('fullscreenchange'); 10926 })); 10927 10928 this.el_[fsApi.requestFullscreen](); 10929 } else if (this.tech_.supportsFullScreen()) { 10930 // we can't take the video.js controls fullscreen but we can go fullscreen 10931 // with native controls 10932 this.techCall_('enterFullScreen'); 10933 } else { 10934 // fullscreen isn't supported so we'll just stretch the video element to 10935 // fill the viewport 10936 this.enterFullWindow(); 10937 /** 10938 * @event Player#fullscreenchange 10939 * @type {EventTarget~Event} 10940 */ 10941 this.trigger('fullscreenchange'); 10942 } 10943 10944 return this; 10945 }; 10946 10947 /** 10948 * Return the video to its normal size after having been in full screen mode 10949 * 10950 * @fires Player#fullscreenchange 10951 * 10952 * @return {Player} 10953 * A reference to the current player 10954 */ 10955 10956 10957 Player.prototype.exitFullscreen = function exitFullscreen() { 10958 var fsApi = _fullscreenApi2['default']; 10959 10960 this.isFullscreen(false); 10961 10962 // Check for browser element fullscreen support 10963 if (fsApi.requestFullscreen) { 10964 _document2['default'][fsApi.exitFullscreen](); 10965 } else if (this.tech_.supportsFullScreen()) { 10966 this.techCall_('exitFullScreen'); 10967 } else { 10968 this.exitFullWindow(); 10969 /** 10970 * @event Player#fullscreenchange 10971 * @type {EventTarget~Event} 10972 */ 10973 this.trigger('fullscreenchange'); 10974 } 10975 10976 return this; 10977 }; 10978 10979 /** 10980 * When fullscreen isn't supported we can stretch the 10981 * video container to as wide as the browser will let us. 10982 * 10983 * @fires Player#enterFullWindow 10984 */ 10985 10986 10987 Player.prototype.enterFullWindow = function enterFullWindow() { 10988 this.isFullWindow = true; 10989 10990 // Storing original doc overflow value to return to when fullscreen is off 10991 this.docOrigOverflow = _document2['default'].documentElement.style.overflow; 10992 10993 // Add listener for esc key to exit fullscreen 10994 Events.on(_document2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey)); 10995 10996 // Hide any scroll bars 10997 _document2['default'].documentElement.style.overflow = 'hidden'; 10998 10999 // Apply fullscreen styles 11000 Dom.addElClass(_document2['default'].body, 'vjs-full-window'); 11001 11002 /** 11003 * @event Player#enterFullWindow 11004 * @type {EventTarget~Event} 11005 */ 11006 this.trigger('enterFullWindow'); 11007 }; 11008 11009 /** 11010 * Check for call to either exit full window or 11011 * full screen on ESC key 11012 * 11013 * @param {string} event 11014 * Event to check for key press 11015 */ 11016 11017 11018 Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) { 11019 if (event.keyCode === 27) { 11020 if (this.isFullscreen() === true) { 11021 this.exitFullscreen(); 11022 } else { 11023 this.exitFullWindow(); 11024 } 11025 } 11026 }; 11027 11028 /** 11029 * Exit full window 11030 * 11031 * @fires Player#exitFullWindow 11032 */ 11033 11034 11035 Player.prototype.exitFullWindow = function exitFullWindow() { 11036 this.isFullWindow = false;
11037 Events.off(_document2['default'], 'keydown', this.fullWindowOnEscKey); 11038 11039 // Unhide scroll bars. 11040 _document2['default'].documentElement.style.overflow = this.docOrigOverflow; 11041 11042 // Remove fullscreen styles 11043 Dom.removeElClass(_document2['default'].body, 'vjs-full-window'); 11044 11045 // Resize the box, controller, and poster to original sizes 11046 // this.positionAll(); 11047 /** 11048 * @event Player#exitFullWindow 11049 * @type {EventTarget~Event} 11050 */ 11051 this.trigger('exitFullWindow'); 11052 }; 11053 11054 /** 11055 * Check whether the player can play a given mimetype 11056 * 11057 * @see https://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-navigator-canplaytype 11058 * 11059 * @param {string} type 11060 * The mimetype to check 11061 * 11062 * @return {string} 11063 * 'probably', 'maybe', or '' (empty string) 11064 */ 11065 11066 11067 Player.prototype.canPlayType = function canPlayType(type) { 11068 var can = void 0; 11069 11070 // Loop through each playback technology in the options order 11071 for (var i = 0, j = this.options_.techOrder; i < j.length; i++) { 11072 var techName = (0, _toTitleCase2['default'])(j[i]); 11073 var tech = _tech2['default'].getTech(techName); 11074 11075 // Support old behavior of techs being registered as components. 11076 // Remove once that deprecated behavior is removed. 11077 if (!tech) { 11078 tech = _component2['default'].getComponent(techName); 11079 } 11080 11081 // Check if the current tech is defined before continuing 11082 if (!tech) { 11083 _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.'); 11084 continue; 11085 } 11086 11087 // Check if the browser supports this technology 11088 if (tech.isSupported()) { 11089 can = tech.canPlayType(type); 11090 11091 if (can) { 11092 return can; 11093 } 11094 } 11095 } 11096 11097 return ''; 11098 }; 11099 11100 /** 11101 * Select source based on tech-order or source-order 11102 * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise, 11103 * defaults to tech-order selection 11104 * 11105 * @param {Array} sources 11106 * The sources for a media asset 11107 * 11108 * @return {Object|boolean} 11109 * Object of source and tech order or false 11110 */ 11111 11112 11113 Player.prototype.selectSource = function selectSource(sources) { 11114 var _this4 = this; 11115 11116 // Get only the techs specified in `techOrder` that exist and are supported by the 11117 // current platform 11118 var techs = this.options_.techOrder.map(_toTitleCase2['default']).map(function (techName) { 11119 // `Component.getComponent(...)` is for support of old behavior of techs 11120 // being registered as components. 11121 // Remove once that deprecated behavior is removed. 11122 return [techName, _tech2['default'].getTech(techName) || _component2['default'].getComponent(techName)]; 11123 }).filter(function (_ref) { 11124 var techName = _ref[0], 11125 tech = _ref[1]; 11126 11127 // Check if the current tech is defined before continuing 11128 if (tech) { 11129 // Check if the browser supports this technology 11130 return tech.isSupported(); 11131 } 11132 11133 _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.'); 11134 return false; 11135 }); 11136 11137 // Iterate over each `innerArray` element once per `outerArray` element and execute 11138 // `tester` with both. If `tester` returns a non-falsy value, exit early and return 11139 // that value. 11140 var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) { 11141 var found = void 0; 11142 11143 outerArray.some(function (outerChoice) { 11144 return innerArray.some(function (innerChoice) { 11145 found = tester(outerChoice, innerChoice); 11146 11147 if (found) { 11148 return true; 11149 } 11150 }); 11151 }); 11152 11153 return found; 11154 }; 11155 11156 var foundSourceAndTech = void 0; 11157 var flip = function flip(fn) { 11158 return function (a, b) { 11159 return fn(b, a); 11160 }; 11161 }; 11162 var finder = function finder(_ref2, source) { 11163 var techName = _ref2[0], 11164 tech = _ref2[1]; 11165 11166 if (tech.canPlaySource(source, _this4.options_[techName.toLowerCase()])) { 11167 return { source: source, tech: techName }; 11168 } 11169 }; 11170 11171 // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources 11172 // to select from them based on their priority. 11173 if (this.options_.sourceOrder) { 11174 // Source-first ordering 11175 foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder)); 11176 } else { 11177 // Tech-first ordering 11178 foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder); 11179 } 11180 11181 return foundSourceAndTech || false; 11182 }; 11183 11184 /** 11185 * The source function updates the video source 11186 * There are three types of variables you can pass as the argument. 11187 * **URL string**: A URL to the the video file. Use this method if you are sure 11188 * the current playback technology (HTML5/Flash) can support the source you 11189 * provide. Currently only MP4 files can be used in both HTML5 and Flash. 11190 * 11191 * @param {Tech~SourceObject|Tech~SourceObject[]} [source] 11192 * One SourceObject or an array of SourceObjects 11193 * 11194 * @return {string|Player} 11195 * - The current video source when getting 11196 * - The player when setting 11197 */ 11198 11199 11200 Player.prototype.src = function src(source) { 11201 if (source === undefined) { 11202 return this.techGet_('src'); 11203 } 11204 11205 var currentTech = _tech2['default'].getTech(this.techName_); 11206
11207 // Support old behavior of techs being registered as components. 11208 // Remove once that deprecated behavior is removed. 11209 if (!currentTech) { 11210 currentTech = _component2['default'].getComponent(this.techName_); 11211 } 11212 11213 // case: Array of source objects to choose from and pick the best to play 11214 if (Array.isArray(source)) { 11215 this.sourceList_(source); 11216 11217 // case: URL String (http://myvideo...) 11218 } else if (typeof source === 'string') { 11219 // create a source object from the string 11220 this.src({ src: source }); 11221 11222 // case: Source object { src: '', type: '' ... } 11223 } else if (source instanceof Object) { 11224 // check if the source has a type and the loaded tech cannot play the source 11225 // if there's no type we'll just try the current tech 11226 if (source.type && !currentTech.canPlaySource(source, this.options_[this.techName_.toLowerCase()])) { 11227 // create a source list with the current source and send through 11228 // the tech loop to check for a compatible technology 11229 this.sourceList_([source]); 11230 } else { 11231 this.cache_.sources = null; 11232 this.cache_.source = source; 11233 this.cache_.src = source.src; 11234 11235 this.currentType_ = source.type || ''; 11236 11237 // wait until the tech is ready to set the source 11238 this.ready(function () { 11239 11240 // The setSource tech method was added with source handlers 11241 // so older techs won't support it 11242 // We need to check the direct prototype for the case where subclasses 11243 // of the tech do not support source handlers 11244 if (currentTech.prototype.hasOwnProperty('setSource')) { 11245 this.techCall_('setSource', source); 11246 } else { 11247 this.techCall_('src', source.src); 11248 } 11249 11250 if (this.options_.preload === 'auto') { 11251 this.load(); 11252 } 11253 11254 if (this.options_.autoplay) { 11255 this.play(); 11256 } 11257 11258 // Set the source synchronously if possible (#2326) 11259 }, true); 11260 } 11261 } 11262 11263 return this; 11264 }; 11265 11266 /** 11267 * Handle an array of source objects 11268 * 11269 * @param {Tech~SourceObject[]} sources 11270 * Array of source objects 11271 * 11272 * @private 11273 */ 11274 11275 11276 Player.prototype.sourceList_ = function sourceList_(sources) { 11277 var sourceTech = this.selectSource(sources); 11278 11279 if (sourceTech) { 11280 if (sourceTech.tech === this.techName_) { 11281 // if this technology is already loaded, set the source 11282 this.src(sourceTech.source); 11283 } else { 11284 // load this technology with the chosen source 11285 this.loadTech_(sourceTech.tech, sourceTech.source); 11286 } 11287 11288 this.cache_.sources = sources; 11289 } else { 11290 // We need to wrap this in a timeout to give folks a chance to add error event handlers 11291 this.setTimeout(function () { 11292 this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) }); 11293 }, 0); 11294 11295 // we could not find an appropriate tech, but let's still notify the delegate that this is it 11296 // this needs a better comment about why this is needed 11297 this.triggerReady(); 11298 } 11299 }; 11300 11301 /** 11302 * Begin loading the src data. 11303 * 11304 * @return {Player} 11305 * A reference to the player 11306 */ 11307 11308 11309 Player.prototype.load = function load() { 11310 this.techCall_('load'); 11311 return this; 11312 }; 11313 11314 /** 11315 * Reset the player. Loads the first tech in the techOrder, 11316 * and calls `reset` on the tech`. 11317 * 11318 * @return {Player} 11319 * A reference to the player 11320 */ 11321 11322 11323 Player.prototype.reset = function reset() { 11324 this.loadTech_((0, _toTitleCase2['default'])(this.options_.techOrder[0]), null); 11325 this.techCall_('reset'); 11326 return this; 11327 }; 11328 11329 /** 11330 * Returns all of the current source objects. 11331 * 11332 * @return {Tech~SourceObject[]} 11333 * The current source objects 11334 */ 11335 11336 11337 Player.prototype.currentSources = function currentSources() { 11338 var source = this.currentSource(); 11339 var sources = []; 11340 11341 // assume `{}` or `{ src }` 11342 if (Object.keys(source).length !== 0) { 11343 sources.push(source); 11344 } 11345 11346 return this.cache_.sources || sources; 11347 }; 11348 11349 /** 11350 * Returns the current source object. 11351 * 11352 * @return {Tech~SourceObject} 11353 * The current source object 11354 */ 11355 11356 11357 Player.prototype.currentSource = function currentSource() { 11358 var source = {}; 11359 var src = this.currentSrc(); 11360 11361 if (src) { 11362 source.src = src; 11363 } 11364 11365 return this.cache_.source || source; 11366 }; 11367 11368 /** 11369 * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4 11370 * Can be used in conjuction with `currentType` to assist in rebuilding the current source object. 11371 * 11372 * @return {string} 11373 * The current source 11374 */ 11375 11376 11377 Player.prototype.currentSrc = function currentSrc() { 11378 return this.techGet_('currentSrc') || this.cache_.src || ''; 11379 }; 11380 11381 /** 11382 * Get the current source type e.g. video/mp4 11383 * This can allow you rebuild the current source object so that you could load the same 11384 * source and tech later 11385 * 11386 * @return {string} 11387 * The source MIME type 11388 */ 11389 11390 11391 Player.prototype.currentType = function currentType() { 11392 return this.currentType_ || ''; 11393 }; 11394 11395 /** 11396 * Get or set the preload attribute 11397 * 11398 * @param {boolean} [value] 11399 * - true means that we should preload 11400 * - false maens that we should not preload 11401 * 11402 * @return {string|Player} 11403 * - the preload attribute value when getting 11404 * - the player when setting 11405 */ 11406 11407 11408 Player.prototype.preload = function preload(value) { 11409 if (value !== undefined) { 11410 this.techCall_('setPreload', value); 11411 this.options_.preload = value; 11412 return this; 11413 } 11414 return this.techGet_('preload'); 11415 }; 11416 11417 /** 11418 * Get or set the autoplay attribute. 11419 * 11420 * @param {boolean} [value] 11421 * - true means that we should autoplay 11422 * - false maens that we should not autoplay 11423 * 11424 * @return {string|Player} 11425 * - the current value of autoplay 11426 * - the player when setting 11427 */ 11428 11429 11430 Player.prototype.autoplay = function autoplay(value) { 11431 if (value !== undefined) { 11432 this.techCall_('setAutoplay', value); 11433 this.options_.autoplay = value; 11434 return this; 11435 } 11436 return this.techGet_('autoplay', value); 11437 }; 11438 11439 /** 11440 * Get or set the loop attribute on the video element. 11441 * 11442 * @param {boolean} [value] 11443 * - true means that we should loop the video 11444 * - false means that we should not loop the video 11445 * 11446 * @return {string|Player} 11447 * - the current value of loop when getting 11448 * - the player when setting 11449 */ 11450 11451 11452 Player.prototype.loop = function loop(value) { 11453 if (value !== undefined) { 11454 this.techCall_('setLoop', value); 11455 this.options_.loop = value; 11456 return this; 11457 } 11458 return this.techGet_('loop'); 11459 }; 11460 11461 /** 11462 * Get or set the poster image source url 11463 * 11464 * @fires Player#posterchange 11465 * 11466 * @param {string} [src] 11467 * Poster image source URL 11468 * 11469 * @return {string|Player} 11470 * - the current value of poster when getting 11471 * - the player when setting 11472 */ 11473 11474 11475 Player.prototype.poster = function poster(src) { 11476 if (src === undefined) { 11477 return this.poster_; 11478 } 11479 11480 // The correct way to remove a poster is to set as an empty string 11481 // other falsey values will throw errors 11482 if (!src) { 11483 src = ''; 11484 } 11485 11486 // update the internal poster variable 11487 this.poster_ = src; 11488 11489 // update the tech's poster 11490 this.techCall_('setPoster', src); 11491 11492 // alert components that the poster has been set 11493 /** 11494 * This event fires when the poster image is changed on the player. 11495 * 11496 * @event Player#posterchange 11497 * @type {EventTarget~Event} 11498 */ 11499 this.trigger('posterchange'); 11500 11501 return this; 11502 }; 11503 11504 /** 11505 * Some techs (e.g. YouTube) can provide a poster source in an 11506 * asynchronous way. We want the poster component to use this 11507 * poster source so that it covers up the tech's controls. 11508 * (YouTube's play button). However we only want to use this 11509 * soruce if the player user hasn't set a poster through 11510 * the normal APIs. 11511 * 11512 * @fires Player#posterchange 11513 * @listens Tech#posterchange 11514 * @private 11515 */ 11516 11517 11518 Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() { 11519 if (!this.poster_ && this.tech_ && this.tech_.poster) { 11520 this.poster_ = this.tech_.poster() || ''; 11521 11522 // Let components know the poster has changed 11523 this.trigger('posterchange'); 11524 } 11525 }; 11526 11527 /** 11528 * Get or set whether or not the controls are showing. 11529 * 11530 * @fires Player#controlsenabled 11531 * 11532 * @param {boolean} [bool] 11533 * - true to turn controls on 11534 * - false to turn controls off 11535 * 11536 * @return {boolean|Player} 11537 * - the current value of controls when getting 11538 * - the player when setting 11539 */ 11540 11541 11542 Player.prototype.controls = function controls(bool) { 11543 if (bool !== undefined) { 11544 bool = !!bool; 11545 11546 // Don't trigger a change event unless it actually changed 11547 if (this.controls_ !== bool) { 11548 this.controls_ = bool; 11549 11550 if (this.usingNativeControls()) { 11551 this.techCall_('setControls', bool); 11552 } 11553 11554 if (bool) { 11555 this.removeClass('vjs-controls-disabled'); 11556 this.addClass('vjs-controls-enabled'); 11557 /** 11558 * @event Player#controlsenabled 11559 * @type {EventTarget~Event} 11560 */ 11561 this.trigger('controlsenabled'); 11562 11563 if (!this.usingNativeControls()) {
11564 this.addTechControlsListeners_(); 11565 } 11566 } else { 11567 this.removeClass('vjs-controls-enabled'); 11568 this.addClass('vjs-controls-disabled'); 11569 /** 11570 * @event Player#controlsdisabled 11571 * @type {EventTarget~Event} 11572 */ 11573 this.trigger('controlsdisabled'); 11574 11575 if (!this.usingNativeControls()) { 11576 this.removeTechControlsListeners_(); 11577 } 11578 } 11579 } 11580 return this; 11581 } 11582 return !!this.controls_; 11583 }; 11584 11585 /** 11586 * Toggle native controls on/off. Native controls are the controls built into 11587 * devices (e.g. default iPhone controls), Flash, or other techs 11588 * (e.g. Vimeo Controls) 11589 * **This should only be set by the current tech, because only the tech knows 11590 * if it can support native controls** 11591 * 11592 * @fires Player#usingnativecontrols 11593 * @fires Player#usingcustomcontrols 11594 * 11595 * @param {boolean} [bool] 11596 * - true to turn native controls on 11597 * - false to turn native controls off 11598 * 11599 * @return {boolean|Player} 11600 * - the current value of native controls when getting 11601 * - the player when setting 11602 */ 11603 11604 11605 Player.prototype.usingNativeControls = function usingNativeControls(bool) { 11606 if (bool !== undefined) { 11607 bool = !!bool; 11608 11609 // Don't trigger a change event unless it actually changed 11610 if (this.usingNativeControls_ !== bool) { 11611 this.usingNativeControls_ = bool; 11612 if (bool) { 11613 this.addClass('vjs-using-native-controls'); 11614 11615 /** 11616 * player is using the native device controls 11617 * 11618 * @event Player#usingnativecontrols 11619 * @type {EventTarget~Event} 11620 */ 11621 this.trigger('usingnativecontrols'); 11622 } else { 11623 this.removeClass('vjs-using-native-controls'); 11624 11625 /** 11626 * player is using the custom HTML controls 11627 * 11628 * @event Player#usingcustomcontrols 11629 * @type {EventTarget~Event} 11630 */ 11631 this.trigger('usingcustomcontrols'); 11632 } 11633 } 11634 return this; 11635 } 11636 return !!this.usingNativeControls_; 11637 }; 11638 11639 /** 11640 * Set or get the current MediaError 11641 * 11642 * @fires Player#error 11643 * 11644 * @param {MediaError|string|number} [err] 11645 * A MediaError or a string/number to be turned 11646 * into a MediaError 11647 * 11648 * @return {MediaError|null|Player} 11649 * - The current MediaError when getting (or null) 11650 * - The player when setting 11651 */ 11652 11653 11654 Player.prototype.error = function error(err) { 11655 if (err === undefined) { 11656 return this.error_ || null; 11657 } 11658 11659 // restoring to default 11660 if (err === null) { 11661 this.error_ = err; 11662 this.removeClass('vjs-error'); 11663 if (this.errorDisplay) { 11664 this.errorDisplay.close(); 11665 } 11666 return this; 11667 } 11668 11669 this.error_ = new _mediaError2['default'](err); 11670 11671 // add the vjs-error classname to the player 11672 this.addClass('vjs-error'); 11673 11674 // log the name of the error type and any message 11675 // ie8 just logs "[object object]" if you just log the error object 11676 _log2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaError2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_); 11677 11678 /** 11679 * @event Player#error 11680 * @type {EventTarget~Event} 11681 */ 11682 this.trigger('error'); 11683 11684 return this; 11685 }; 11686 11687 /** 11688 * Report user activity 11689 * 11690 * @param {Object} event 11691 * Event object 11692 */ 11693 11694 11695 Player.prototype.reportUserActivity = function reportUserActivity(event) { 11696 this.userActivity_ = true; 11697 }; 11698 11699 /** 11700 * Get/set if user is active 11701 * 11702 * @fires Player#useractive 11703 * @fires Player#userinactive 11704 * 11705 * @param {boolean} [bool] 11706 * - true if the user is active 11707 * - false if the user is inactive 11708 * @return {boolean|Player} 11709 * - the current value of userActive when getting 11710 * - the player when setting 11711 */ 11712 11713 11714 Player.prototype.userActive = function userActive(bool) { 11715 if (bool !== undefined) { 11716 bool = !!bool; 11717 if (bool !== this.userActive_) { 11718 this.userActive_ = bool; 11719 if (bool) { 11720 // If the user was inactive and is now active we want to reset the 11721 // inactivity timer 11722 this.userActivity_ = true; 11723 this.removeClass('vjs-user-inactive'); 11724 this.addClass('vjs-user-active'); 11725 /** 11726 * @event Player#useractive 11727 * @type {EventTarget~Event} 11728 */ 11729 this.trigger('useractive'); 11730 } else { 11731 // We're switching the state to inactive manually, so erase any other 11732 // activity 11733 this.userActivity_ = false;
vendor: 3,493 bytes, lines 11734-11826
11734 11735 // Chrome/Safari/IE have bugs where when you change the cursor it can 11736 // trigger a mousemove event. This causes an issue when you're hiding 11737 // the cursor when the user is inactive, and a mousemove signals user 11738 // activity. Making it impossible to go into inactive mode. Specifically 11739 // this happens in fullscreen when we really need to hide the cursor. 11740 // 11741 // When this gets resolved in ALL browsers it can be removed 11742 // https://code.google.com/p/chromium/issues/detail?id=103041 11743 if (this.tech_) { 11744 this.tech_.one('mousemove', function (e) { 11745 e.stopPropagation(); 11746 e.preventDefault(); 11747 }); 11748 } 11749 11750 this.removeClass('vjs-user-active'); 11751 this.addClass('vjs-user-inactive'); 11752 /** 11753 * @event Player#userinactive 11754 * @type {EventTarget~Event} 11755 */ 11756 this.trigger('userinactive'); 11757 } 11758 } 11759 return this; 11760 } 11761 return this.userActive_; 11762 }; 11763 11764 /** 11765 * Listen for user activity based on timeout value 11766 * 11767 * @private 11768 */ 11769 11770 11771 Player.prototype.listenForUserActivity_ = function listenForUserActivity_() { 11772 var mouseInProgress = void 0; 11773 var lastMoveX = void 0; 11774 var lastMoveY = void 0; 11775 var handleActivity = Fn.bind(this, this.reportUserActivity); 11776 11777 var handleMouseMove = function handleMouseMove(e) { 11778 // #1068 - Prevent mousemove spamming 11779 // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970 11780 if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) { 11781 lastMoveX = e.screenX; 11782 lastMoveY = e.screenY; 11783 handleActivity(); 11784 } 11785 }; 11786 11787 var handleMouseDown = function handleMouseDown() { 11788 handleActivity(); 11789 // For as long as the they are touching the device or have their mouse down, 11790 // we consider them active even if they're not moving their finger or mouse. 11791 // So we want to continue to update that they are active 11792 this.clearInterval(mouseInProgress); 11793 // Setting userActivity=true now and setting the interval to the same time 11794 // as the activityCheck interval (250) should ensure we never miss the 11795 // next activityCheck 11796 mouseInProgress = this.setInterval(handleActivity, 250); 11797 }; 11798 11799 var handleMouseUp = function handleMouseUp(event) { 11800 handleActivity(); 11801 // Stop the interval that maintains activity if the mouse/touch is down 11802 this.clearInterval(mouseInProgress); 11803 }; 11804 11805 // Any mouse movement will be considered user activity 11806 this.on('mousedown', handleMouseDown); 11807 this.on('mousemove', handleMouseMove); 11808 this.on('mouseup', handleMouseUp); 11809 11810 // Listen for keyboard navigation 11811 // Shouldn't need to use inProgress interval because of key repeat 11812 this.on('keydown', handleActivity); 11813 this.on('keyup', handleActivity); 11814 11815 // Run an interval every 250 milliseconds instead of stuffing everything into 11816 // the mousemove/touchmove function itself, to prevent performance degradation. 11817 // `this.reportUserActivity` simply sets this.userActivity_ to true, which 11818 // then gets picked up by this loop 11819 // http://ejohn.org/blog/learning-from-twitter/ 11820 var inactivityTimeout = void 0; 11821 11822 this.setInterval(function () { 11823 // Check to see if mouse/touch activity has happened 11824 if (this.userActivity_) { 11825 // Reset the activity tracker 11826 this.userActivity_ = false;
11827 11828 // If the user state was inactive, set the state to active 11829 this.userActive(true); 11830 11831 // Clear any existing inactivity timeout to start the timer over 11832 this.clearTimeout(inactivityTimeout); 11833 11834 var timeout = this.options_.inactivityTimeout; 11835 11836 if (timeout > 0) { 11837 // In <timeout> milliseconds, if no more activity has occurred the 11838 // user will be considered inactive 11839 inactivityTimeout = this.setTimeout(function () { 11840 // Protect against the case where the inactivityTimeout can trigger just 11841 // before the next user activity is picked up by the activity check loop 11842 // causing a flicker 11843 if (!this.userActivity_) { 11844 this.userActive(false); 11845 } 11846 }, timeout); 11847 } 11848 } 11849 }, 250); 11850 }; 11851 11852 /** 11853 * Gets or sets the current playback rate. A playback rate of 11854 * 1.0 represents normal speed and 0.5 would indicate half-speed 11855 * playback, for instance. 11856 * 11857 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate 11858 * 11859 * @param {number} [rate] 11860 * New playback rate to set. 11861 * 11862 * @return {number|Player} 11863 * - The current playback rate when getting or 1.0 11864 * - the player when setting 11865 */ 11866 11867 11868 Player.prototype.playbackRate = function playbackRate(rate) { 11869 if (rate !== undefined) { 11870 this.techCall_('setPlaybackRate', rate); 11871 return this; 11872 } 11873 11874 if (this.tech_ && this.tech_.featuresPlaybackRate) { 11875 return this.techGet_('playbackRate'); 11876 } 11877 return 1.0; 11878 }; 11879 11880 /** 11881 * Gets or sets the audio flag 11882 * 11883 * @param {boolean} bool 11884 * - true signals that this is an audio player 11885 * - false signals that this is not an audio player 11886 * 11887 * @return {Player|boolean} 11888 * - the current value of isAudio when getting 11889 * - the player if setting 11890 */ 11891 11892 11893 Player.prototype.isAudio = function isAudio(bool) { 11894 if (bool !== undefined) { 11895 this.isAudio_ = !!bool; 11896 return this; 11897 } 11898 11899 return !!this.isAudio_; 11900 }; 11901 11902 /** 11903 * Get the {@link VideoTrackList} 11904 * 11905 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist 11906 * 11907 * @return {VideoTrackList} 11908 * the current video track list 11909 */ 11910 11911 11912 Player.prototype.videoTracks = function videoTracks() { 11913 // if we have not yet loadTech_, we create videoTracks_ 11914 // these will be passed to the tech during loading 11915 if (!this.tech_) { 11916 this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default'](); 11917 return this.videoTracks_; 11918 } 11919 11920 return this.tech_.videoTracks(); 11921 }; 11922 11923 /** 11924 * Get the {@link AudioTrackList} 11925 * 11926 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist 11927 * 11928 * @return {AudioTrackList} 11929 * the current audio track list 11930 */ 11931 11932 11933 Player.prototype.audioTracks = function audioTracks() { 11934 // if we have not yet loadTech_, we create videoTracks_ 11935 // these will be passed to the tech during loading 11936 if (!this.tech_) { 11937 this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default'](); 11938 return this.audioTracks_; 11939 } 11940 11941 return this.tech_.audioTracks(); 11942 }; 11943 11944 /** 11945 * Get the {@link TextTrackList} 11946 * 11947 * Text tracks are tracks of timed text events. 11948 * - Captions: text displayed over the video 11949 * for the hearing impaired 11950 * - Subtitles: text displayed over the video for 11951 * those who don't understand language in the video 11952 * - Chapters: text displayed in a menu allowing the user to jump 11953 * to particular points (chapters) in the video 11954 * - Descriptions: (not yet implemented) audio descriptions that are read back to 11955 * the user by a screen reading device 11956 * 11957 * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks 11958 * 11959 * @return {TextTrackList|undefined} 11960 * The current TextTrackList or undefined if 11961 * or undefined if we don't have a tech 11962 */ 11963 11964 11965 Player.prototype.textTracks = function textTracks() { 11966 // cannot use techGet_ directly because it checks to see whether the tech is ready. 11967 // Flash is unlikely to be ready in time but textTracks should still work. 11968 if (this.tech_) { 11969 return this.tech_.textTracks(); 11970 } 11971 }; 11972 11973 /** 11974 * Get the "remote" {@link TextTrackList}. Remote Text Tracks 11975 * are tracks that were added to the HTML video element and can 11976 * be removed, whereas normal texttracks cannot be removed. 11977 * 11978 * 11979 * @return {TextTrackList|undefined} 11980 * The current remote text track list or undefined 11981 * if we don't have a tech 11982 */ 11983 11984 11985 Player.prototype.remoteTextTracks = function remoteTextTracks() { 11986 if (this.tech_) { 11987 return this.tech_.remoteTextTracks(); 11988 } 11989 }; 11990 11991 /** 11992 * Get the "remote" {@link HTMLTrackElementList}. 11993 * This gives the user all of the DOM elements that match up 11994 * with the remote {@link TextTrackList}. 11995 * 11996 * @return {HTMLTrackElementList} 11997 * The current remote text track list elements 11998 * or undefined if we don't have a tech 11999 */ 12000 12001 12002 Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() { 12003 if (this.tech_) { 12004 return this.tech_.remoteTextTrackEls(); 12005 } 12006 }; 12007 12008 /** 12009 * A helper method for adding a {@link TextTrack} to our 12010 * {@link TextTrackList}. 12011 * 12012 * In addition to the W3C settings we allow adding additional info through options. 12013 * 12014 * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack 12015 * 12016 * @param {string} [kind] 12017 * the kind of TextTrack you are adding 12018 * 12019 * @param {string} [label] 12020 * the label to give the TextTrack label 12021 * 12022 * @param {string} [language] 12023 * the language to set on the TextTrack 12024 * 12025 * @return {TextTrack|undefined} 12026 * the TextTrack that was added or undefined 12027 * if there is no tech 12028 */ 12029 12030 12031 Player.prototype.addTextTrack = function addTextTrack(kind, label, language) { 12032 if (this.tech_) { 12033 return this.tech_.addTextTrack(kind, label, language); 12034 } 12035 }; 12036 12037 /** 12038 * Create a remote {@link TextTrack} and an {@link HTMLTrackElement}. It will 12039 * automatically removed from the video element whenever the source changes, unless 12040 * manualCleanup is set to false. 12041 * 12042 * @param {Object} options 12043 * Options to pass to {@link HTMLTrackElement} during creation. See 12044 * {@link HTMLTrackElement} for object properties that you should use. 12045 * 12046 * @param {boolean} [manualCleanup=true] if set to false, the TextTrack will be 12047 * 12048 * @return {HTMLTrackElement} 12049 * the HTMLTrackElement that was created and added 12050 * to the HTMLTrackElementList and the remote 12051 * TextTrackList 12052 * 12053 * @deprecated The default value of the "manualCleanup" parameter will default
12054 * to "false" in upcoming versions of Video.js 12055 */ 12056 12057 12058 Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) { 12059 if (this.tech_) { 12060 return this.tech_.addRemoteTextTrack(options, manualCleanup); 12061 } 12062 }; 12063 12064 /** 12065 * Remove a remote {@link TextTrack} from the respective 12066 * {@link TextTrackList} and {@link HTMLTrackElementList}. 12067 * 12068 * @param {Object} track 12069 * Remote {@link TextTrack} to remove 12070 * 12071 * @return {undefined} 12072 * does not return anything 12073 */ 12074 12075 12076 Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack() { 12077 var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, 12078 _ref3$track = _ref3.track, 12079 track = _ref3$track === undefined ? arguments[0] : _ref3$track; 12080 12081 // destructure the input into an object with a track argument, defaulting to arguments[0] 12082 // default the whole argument to an empty object if nothing was passed in 12083 12084 if (this.tech_) { 12085 return this.tech_.removeRemoteTextTrack(track); 12086 } 12087 }; 12088 12089 /** 12090 * Get video width 12091 * 12092 * @return {number} 12093 * current video width 12094 */ 12095 12096 12097 Player.prototype.videoWidth = function videoWidth() { 12098 return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0; 12099 }; 12100 12101 /** 12102 * Get video height 12103 * 12104 * @return {number} 12105 * current video height 12106 */ 12107 12108 12109 Player.prototype.videoHeight = function videoHeight() { 12110 return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0; 12111 }; 12112 12113 // Methods to add support for 12114 // initialTime: function() { return this.techCall_('initialTime'); }, 12115 // startOffsetTime: function() { return this.techCall_('startOffsetTime'); }, 12116 // played: function() { return this.techCall_('played'); }, 12117 // defaultPlaybackRate: function() { return this.techCall_('defaultPlaybackRate'); }, 12118 // defaultMuted: function() { return this.techCall_('defaultMuted'); } 12119 12120 /** 12121 * The player's language code 12122 * NOTE: The language should be set in the player options if you want the 12123 * the controls to be built with a specific language. Changing the lanugage 12124 * later will not update controls text. 12125 * 12126 * @param {string} [code] 12127 * the language code to set the player to 12128 * 12129 * @return {string|Player} 12130 * - The current language code when getting 12131 * - A reference to the player when setting 12132 */ 12133 12134 12135 Player.prototype.language = function language(code) { 12136 if (code === undefined) { 12137 return this.language_; 12138 } 12139 12140 this.language_ = String(code).toLowerCase(); 12141 return this; 12142 }; 12143 12144 /** 12145 * Get the player's language dictionary 12146 * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time 12147 * Languages specified directly in the player options have precedence 12148 * 12149 * @return {Array} 12150 * An array of of supported languages 12151 */ 12152 12153 12154 Player.prototype.languages = function languages() { 12155 return (0, _mergeOptions2['default'])(Player.prototype.options_.languages, this.languages_); 12156 }; 12157 12158 /** 12159 * returns a JavaScript object reperesenting the current track 12160 * information. **DOES not return it as JSON** 12161 * 12162 * @return {Object} 12163 * Object representing the current of track info 12164 */ 12165 12166 12167 Player.prototype.toJSON = function toJSON() { 12168 var options = (0, _mergeOptions2['default'])(this.options_); 12169 var tracks = options.tracks; 12170 12171 options.tracks = []; 12172 12173 for (var i = 0; i < tracks.length; i++) { 12174 var track = tracks[i]; 12175 12176 // deep merge tracks and null out player so no circular references 12177 track = (0, _mergeOptions2['default'])(track); 12178 track.player = undefined; 12179 options.tracks[i] = track; 12180 } 12181 12182 return options; 12183 }; 12184 12185 /** 12186 * Creates a simple modal dialog (an instance of the {@link ModalDialog} 12187 * component) that immediately overlays the player with arbitrary 12188 * content and removes itself when closed. 12189 * 12190 * @param {string|Function|Element|Array|null} content 12191 * Same as {@link ModalDialog#content}'s param of the same name. 12192 * The most straight-forward usage is to provide a string or DOM 12193 * element. 12194 * 12195 * @param {Object} [options] 12196 * Extra options which will be passed on to the {@link ModalDialog}. 12197 * 12198 * @return {ModalDialog} 12199 * the {@link ModalDialog} that was created 12200 */ 12201 12202 12203 Player.prototype.createModal = function createModal(content, options) { 12204 var _this5 = this; 12205 12206 options = options || {}; 12207 options.content = content || ''; 12208 12209 var modal = new _modalDialog2['default'](this, options); 12210 12211 this.addChild(modal); 12212 modal.on('dispose', function () { 12213 _this5.removeChild(modal); 12214 }); 12215 12216 return modal.open(); 12217 }; 12218 12219 /** 12220 * Gets tag settings 12221 * 12222 * @param {Element} tag 12223 * The player tag 12224 * 12225 * @return {Object}
12226 * An object containing all of the settings 12227 * for a player tag 12228 */ 12229 12230 12231 Player.getTagSettings = function getTagSettings(tag) { 12232 var baseOptions = { 12233 sources: [], 12234 tracks: [] 12235 }; 12236 12237 var tagOptions = Dom.getElAttributes(tag); 12238 var dataSetup = tagOptions['data-setup']; 12239 12240 if (Dom.hasElClass(tag, 'vjs-fluid')) { 12241 tagOptions.fluid = true; 12242 } 12243 12244 // Check if data-setup attr exists. 12245 if (dataSetup !== null) { 12246 // Parse options JSON 12247 // If empty string, make it a parsable json object. 12248 var _safeParseTuple = (0, _tuple2['default'])(dataSetup || '{}'), 12249 err = _safeParseTuple[0], 12250 data = _safeParseTuple[1]; 12251 12252 if (err) { 12253 _log2['default'].error(err); 12254 } 12255 (0, _obj.assign)(tagOptions, data); 12256 } 12257 12258 (0, _obj.assign)(baseOptions, tagOptions); 12259 12260 // Get tag children settings 12261 if (tag.hasChildNodes()) { 12262 var children = tag.childNodes; 12263 12264 for (var i = 0, j = children.length; i < j; i++) { 12265 var child = children[i]; 12266 // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/ 12267 var childName = child.nodeName.toLowerCase(); 12268 12269 if (childName === 'source') { 12270 baseOptions.sources.push(Dom.getElAttributes(child)); 12271 } else if (childName === 'track') { 12272 baseOptions.tracks.push(Dom.getElAttributes(child)); 12273 } 12274 } 12275 } 12276 12277 return baseOptions; 12278 }; 12279 12280 /** 12281 * Determine wether or not flexbox is supported 12282 * 12283 * @return {boolean} 12284 * - true if flexbox is supported 12285 * - false if flexbox is not supported 12286 */ 12287 12288 12289 Player.prototype.flexNotSupported_ = function flexNotSupported_() { 12290 var elem = _document2['default'].createElement('i'); 12291 12292 // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more 12293 // common flex features that we can rely on when checking for flex support. 12294 return !('flexBasis' in elem.style || 'webkitFlexBasis' in elem.style || 'mozFlexBasis' in elem.style || 'msFlexBasis' in elem.style || 12295 // IE10-specific (2012 flex spec) 12296 'msFlexOrder' in elem.style); 12297 }; 12298 12299 return Player; 12300}(_component2['default']); 12301 12302/** 12303 * Global player list 12304 * 12305 * @type {Object} 12306 */ 12307 12308 12309Player.players = {}; 12310 12311var navigator = _window2['default'].navigator; 12312 12313/* 12314 * Player instance options, surfaced using options 12315 * options = Player.prototype.options_ 12316 * Make changes in options, not here. 12317 * 12318 * @type {Object} 12319 * @private 12320 */ 12321Player.prototype.options_ = { 12322 // Default order of fallback technology 12323 techOrder: ['html5', 'flash'], 12324 // techOrder: ['flash','html5'], 12325 12326 html5: {}, 12327 flash: {}, 12328 12329 // defaultVolume: 0.85, 12330 defaultVolume: 0.00, 12331 12332 // default inactivity timeout 12333 inactivityTimeout: 2000, 12334 12335 // default playback rates 12336 playbackRates: [], 12337 // Add playback rate selection by adding rates 12338 // 'playbackRates': [0.5, 1, 1.5, 2], 12339 12340 // Included control sets 12341 children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'], 12342 12343 language: navigator && (navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language) || 'en', 12344 12345 // locales and their language translations 12346 languages: {}, 12347 12348 // Default message to show when a video cannot be played. 12349 notSupportedMessage: 'No compatible source was found for this media.' 12350}; 12351 12352[ 12353/** 12354 * Returns whether or not the player is in the "ended" state. 12355 * 12356 * @return {Boolean} True if the player is in the ended state, false if not. 12357 * @method Player#ended 12358 */ 12359'ended', 12360/** 12361 * Returns whether or not the player is in the "seeking" state. 12362 * 12363 * @return {Boolean} True if the player is in the seeking state, false if not. 12364 * @method Player#seeking 12365 */ 12366'seeking', 12367/** 12368 * Returns the TimeRanges of the media that are currently available 12369 * for seeking to. 12370 * 12371 * @return {TimeRanges} the seekable intervals of the media timeline 12372 * @method Player#seekable 12373 */ 12374'seekable', 12375/** 12376 * Returns the current state of network activity for the element, from 12377 * the codes in the list below. 12378 * - NETWORK_EMPTY (numeric value 0) 12379 * The element has not yet been initialised. All attributes are in 12380 * their initial states. 12381 * - NETWORK_IDLE (numeric value 1) 12382 * The element's resource selection algorithm is active and has 12383 * selected a resource, but it is not actually using the network at 12384 * this time. 12385 * - NETWORK_LOADING (numeric value 2) 12386 * The user agent is actively trying to download data. 12387 * - NETWORK_NO_SOURCE (numeric value 3) 12388 * The element's resource selection algorithm is active, but it has 12389 * not yet found a resource to use. 12390 * 12391 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states 12392 * @return {number} the current network activity state 12393 * @method Player#networkState 12394 */ 12395'networkState', 12396/** 12397 * Returns a value that expresses the current state of the element 12398 * with respect to rendering the current playback position, from the 12399 * codes in the list below.
12400 * - HAVE_NOTHING (numeric value 0) 12401 * No information regarding the media resource is available. 12402 * - HAVE_METADATA (numeric value 1) 12403 * Enough of the resource has been obtained that the duration of the 12404 * resource is available. 12405 * - HAVE_CURRENT_DATA (numeric value 2) 12406 * Data for the immediate current playback position is available. 12407 * - HAVE_FUTURE_DATA (numeric value 3) 12408 * Data for the immediate current playback position is available, as 12409 * well as enough data for the user agent to advance the current 12410 * playback position in the direction of playback. 12411 * - HAVE_ENOUGH_DATA (numeric value 4) 12412 * The user agent estimates that enough data is available for 12413 * playback to proceed uninterrupted. 12414 * 12415 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate 12416 * @return {number} the current playback rendering state 12417 * @method Player#readyState 12418 */ 12419'readyState'].forEach(function (fn) { 12420 Player.prototype[fn] = function () { 12421 return this.techGet_(fn); 12422 }; 12423}); 12424 12425TECH_EVENTS_RETRIGGER.forEach(function (event) { 12426 Player.prototype['handleTech' + (0, _toTitleCase2['default'])(event) + '_'] = function () { 12427 return this.trigger(event); 12428 }; 12429}); 12430 12431/** 12432 * Fired when the player has initial duration and dimension information 12433 * 12434 * @event Player#loadedmetadata 12435 * @type {EventTarget~Event} 12436 */ 12437 12438/** 12439 * Fired when the player has downloaded data at the current playback position 12440 * 12441 * @event Player#loadeddata 12442 * @type {EventTarget~Event} 12443 */ 12444 12445/** 12446 * Fired when the current playback position has changed * 12447 * During playback this is fired every 15-250 milliseconds, depending on the 12448 * playback technology in use. 12449 * 12450 * @event Player#timeupdate 12451 * @type {EventTarget~Event} 12452 */ 12453 12454/** 12455 * Fired when the volume changes 12456 * 12457 * @event Player#volumechange 12458 * @type {EventTarget~Event} 12459 */ 12460 12461_component2['default'].registerComponent('Player', Player); 12462exports['default'] = Player; 12463 12464},{"1":1,"4":4,"41":41,"44":44,"45":45,"46":46,"5":5,"50":50,"55":55,"59":59,"60":60,"61":61,"62":62,"63":63,"68":68,"69":69,"71":71,"76":76,"78":78,"79":79,"8":8,"81":81,"82":82,"83":83,"85":85,"86":86,"87":87,"88":88,"89":89,"90":90,"91":91,"94":94,"95":95,"97":97}],52:[function(_dereq_,module,exports){ 12465'use strict'; 12466 12467exports.__esModule = true; 12468 12469var _player = _dereq_(51); 12470 12471var _player2 = _interopRequireDefault(_player); 12472 12473function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12474 12475/** 12476 * The method for registering a video.js plugin. {@link videojs:videojs.registerPlugin]. 12477 * 12478 * @param {string} name 12479 * The name of the plugin that is being registered 12480 * 12481 * @param {plugins:PluginFn} init 12482 * The function that gets run when a `Player` initializes. 12483 */ 12484var plugin = function plugin(name, init) { 12485 _player2['default'].prototype[name] = init; 12486}; /** 12487 * @file plugins.js 12488 * @module plugins 12489 */ 12490exports['default'] = plugin; 12491 12492},{"51":51}],53:[function(_dereq_,module,exports){ 12493'use strict'; 12494 12495exports.__esModule = true; 12496 12497var _clickableComponent = _dereq_(3); 12498 12499var _clickableComponent2 = _interopRequireDefault(_clickableComponent); 12500 12501var _component = _dereq_(5); 12502 12503var _component2 = _interopRequireDefault(_component); 12504 12505function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12506 12507function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 12508 12509function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 12510 12511function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 12512 * @file popup-button.js 12513 */ 12514 12515 12516/** 12517 * A button class for use with {@link Popup} controls 12518 * 12519 * @extends ClickableComponent 12520 */ 12521var PopupButton = function (_ClickableComponent) { 12522 _inherits(PopupButton, _ClickableComponent); 12523 12524 /** 12525 * Create an instance of this class. 12526 * 12527 * @param {Player} player 12528 * The `Player` that this class should be attached to. 12529 * 12530 * @param {Object} [options] 12531 * The key/value store of player options. 12532 */ 12533 function PopupButton(player) { 12534 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 12535 12536 _classCallCheck(this, PopupButton); 12537 12538 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options)); 12539 12540 _this.update(); 12541 return _this; 12542 } 12543 12544 /** 12545 * Update the `Popup` that this button is attached to. 12546 */ 12547 12548
12549 PopupButton.prototype.update = function update() { 12550 var popup = this.createPopup(); 12551 12552 if (this.popup) { 12553 this.removeChild(this.popup); 12554 } 12555 12556 this.popup = popup; 12557 this.addChild(popup); 12558 12559 if (this.items && this.items.length === 0) { 12560 this.hide(); 12561 } else if (this.items && this.items.length > 1) { 12562 this.show(); 12563 } 12564 }; 12565 12566 /** 12567 * Create a `Popup`. - Override with specific functionality for component 12568 * 12569 * @abstract 12570 */ 12571 12572 12573 PopupButton.prototype.createPopup = function createPopup() {}; 12574 12575 /** 12576 * Create the `PopupButton`s DOM element. 12577 * 12578 * @return {Element} 12579 * The element that gets created. 12580 */ 12581 12582 12583 PopupButton.prototype.createEl = function createEl() { 12584 return _ClickableComponent.prototype.createEl.call(this, 'div', { 12585 className: this.buildCSSClass() 12586 }); 12587 }; 12588 12589 /** 12590 * Builds the default DOM `className`. 12591 * 12592 * @return {string} 12593 * The DOM `className` for this object. 12594 */ 12595 12596 12597 PopupButton.prototype.buildCSSClass = function buildCSSClass() { 12598 var menuButtonClass = 'vjs-menu-button'; 12599 12600 // If the inline option is passed, we want to use different styles altogether. 12601 if (this.options_.inline === true) { 12602 menuButtonClass += '-inline'; 12603 } else { 12604 menuButtonClass += '-popup'; 12605 } 12606 12607 return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this); 12608 }; 12609 12610 return PopupButton; 12611}(_clickableComponent2['default']); 12612 12613_component2['default'].registerComponent('PopupButton', PopupButton); 12614exports['default'] = PopupButton; 12615 12616},{"3":3,"5":5}],54:[function(_dereq_,module,exports){ 12617'use strict'; 12618 12619exports.__esModule = true; 12620 12621var _component = _dereq_(5); 12622 12623var _component2 = _interopRequireDefault(_component); 12624 12625var _dom = _dereq_(81); 12626 12627var Dom = _interopRequireWildcard(_dom); 12628 12629var _fn = _dereq_(83); 12630 12631var Fn = _interopRequireWildcard(_fn); 12632 12633var _events = _dereq_(82); 12634 12635var Events = _interopRequireWildcard(_events); 12636 12637function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 12638 12639function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12640 12641function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 12642 12643function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 12644 12645function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 12646 * @file popup.js 12647 */ 12648 12649 12650/** 12651 * The Popup component is used to build pop up controls. 12652 * 12653 * @extends Component 12654 */ 12655var Popup = function (_Component) { 12656 _inherits(Popup, _Component); 12657 12658 function Popup() { 12659 _classCallCheck(this, Popup); 12660 12661 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 12662 } 12663 12664 /**
12665 * Add a popup item to the popup 12666 * 12667 * @param {Object|string} component 12668 * Component or component type to add 12669 * 12670 */ 12671 Popup.prototype.addItem = function addItem(component) { 12672 this.addChild(component); 12673 component.on('click', Fn.bind(this, function () { 12674 this.unlockShowing(); 12675 })); 12676 }; 12677 12678 /** 12679 * Create the `PopupButton`s DOM element. 12680 * 12681 * @return {Element} 12682 * The element that gets created. 12683 */ 12684 12685 12686 Popup.prototype.createEl = function createEl() { 12687 var contentElType = this.options_.contentElType || 'ul'; 12688 12689 this.contentEl_ = Dom.createEl(contentElType, { 12690 className: 'vjs-menu-content' 12691 }); 12692 12693 var el = _Component.prototype.createEl.call(this, 'div', { 12694 append: this.contentEl_, 12695 className: 'vjs-menu' 12696 }); 12697 12698 el.appendChild(this.contentEl_); 12699 12700 // Prevent clicks from bubbling up. Needed for Popup Buttons, 12701 // where a click on the parent is significant 12702 Events.on(el, 'click', function (event) { 12703 event.preventDefault(); 12704 event.stopImmediatePropagation(); 12705 }); 12706 12707 return el; 12708 }; 12709 12710 return Popup; 12711}(_component2['default']); 12712 12713_component2['default'].registerComponent('Popup', Popup); 12714exports['default'] = Popup; 12715 12716},{"5":5,"81":81,"82":82,"83":83}],55:[function(_dereq_,module,exports){ 12717'use strict'; 12718 12719exports.__esModule = true; 12720 12721var _clickableComponent = _dereq_(3); 12722 12723var _clickableComponent2 = _interopRequireDefault(_clickableComponent); 12724 12725var _component = _dereq_(5); 12726 12727var _component2 = _interopRequireDefault(_component); 12728 12729var _fn = _dereq_(83); 12730 12731var Fn = _interopRequireWildcard(_fn); 12732 12733var _dom = _dereq_(81); 12734 12735var Dom = _interopRequireWildcard(_dom); 12736 12737var _browser = _dereq_(78); 12738 12739var browser = _interopRequireWildcard(_browser); 12740 12741function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 12742 12743function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12744 12745function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 12746 12747function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 12748 12749function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 12750 * @file poster-image.js 12751 */ 12752 12753 12754/** 12755 * A `ClickableComponent` that handles showing the poster image for the player. 12756 * 12757 * @extends ClickableComponent 12758 */ 12759var PosterImage = function (_ClickableComponent) { 12760 _inherits(PosterImage, _ClickableComponent); 12761 12762 /** 12763 * Create an instance of this class. 12764 * 12765 * @param {Player} player 12766 * The `Player` that this class should attach to. 12767 * 12768 * @param {Object} [options] 12769 * The key/value store of player options. 12770 */ 12771 function PosterImage(player, options) { 12772 _classCallCheck(this, PosterImage); 12773 12774 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options)); 12775 12776 _this.update(); 12777 player.on('posterchange', Fn.bind(_this, _this.update)); 12778 return _this; 12779 } 12780 12781 /** 12782 * Clean up and dispose of the `PosterImage`. 12783 */ 12784 12785 12786 PosterImage.prototype.dispose = function dispose() { 12787 this.player().off('posterchange', this.update); 12788 _ClickableComponent.prototype.dispose.call(this); 12789 }; 12790 12791 /** 12792 * Create the `PosterImage`s DOM element. 12793 * 12794 * @return {Element} 12795 * The element that gets created. 12796 */ 12797 12798 12799 PosterImage.prototype.createEl = function createEl() { 12800 var el = Dom.createEl('div', { 12801 className: 'vjs-poster', 12802 12803 // Don't want poster to be tabbable. 12804 tabIndex: -1 12805 }); 12806 12807 // To ensure the poster image resizes while maintaining its original aspect 12808 // ratio, use a div with `background-size` when available. For browsers that 12809 // do not support `background-size` (e.g. IE8), fall back on using a regular
12810 // img element. 12811 if (!browser.BACKGROUND_SIZE_SUPPORTED) { 12812 this.fallbackImg_ = Dom.createEl('img'); 12813 el.appendChild(this.fallbackImg_); 12814 } 12815 12816 return el; 12817 }; 12818 12819 /** 12820 * An {@link EventTarget~EventListener} for {@link Player#posterchange} events. 12821 * 12822 * @listens Player#posterchange 12823 * 12824 * @param {EventTarget~Event} [event] 12825 * The `Player#posterchange` event that triggered this function. 12826 */ 12827 12828 12829 PosterImage.prototype.update = function update(event) { 12830 var url = this.player().poster(); 12831 12832 this.setSrc(url); 12833 12834 // If there's no poster source we should display:none on this component 12835 // so it's not still clickable or right-clickable 12836 if (url) { 12837 this.show(); 12838 } else { 12839 this.hide(); 12840 } 12841 }; 12842 12843 /** 12844 * Set the source of the `PosterImage` depending on the display method. 12845 * 12846 * @param {string} url 12847 * The URL to the source for the `PosterImage`. 12848 */ 12849 12850 12851 PosterImage.prototype.setSrc = function setSrc(url) { 12852 if (this.fallbackImg_) { 12853 this.fallbackImg_.src = url; 12854 } else { 12855 var backgroundImage = ''; 12856 12857 // Any falsey values should stay as an empty string, otherwise 12858 // this will throw an extra error 12859 if (url) { 12860 backgroundImage = 'url("' + url + '")'; 12861 } 12862 12863 this.el_.style.backgroundImage = backgroundImage; 12864 } 12865 }; 12866 12867 /** 12868 * An {@link EventTarget~EventListener} for clicks on the `PosterImage`. See 12869 * {@link ClickableComponent#handleClick} for instances where this will be triggered. 12870 * 12871 * @listens tap 12872 * @listens click 12873 * @listens keydown 12874 * 12875 * @param {EventTarget~Event} event 12876 + The `click`, `tap` or `keydown` event that caused this function to be called. 12877 */ 12878 12879 12880 PosterImage.prototype.handleClick = function handleClick(event) { 12881 // We don't want a click to trigger playback when controls are disabled 12882 if (!this.player_.controls()) { 12883 return; 12884 } 12885 12886 if (this.player_.paused()) { 12887 this.player_.play(); 12888 } else { 12889 this.player_.pause(); 12890 } 12891 }; 12892 12893 return PosterImage; 12894}(_clickableComponent2['default']); 12895 12896_component2['default'].registerComponent('PosterImage', PosterImage); 12897exports['default'] = PosterImage; 12898 12899},{"3":3,"5":5,"78":78,"81":81,"83":83}],56:[function(_dereq_,module,exports){ 12900'use strict'; 12901 12902exports.__esModule = true; 12903exports.hasLoaded = exports.autoSetupTimeout = exports.autoSetup = undefined; 12904 12905var _dom = _dereq_(81); 12906 12907var Dom = _interopRequireWildcard(_dom); 12908 12909var _events = _dereq_(82); 12910 12911var Events = _interopRequireWildcard(_events); 12912 12913var _document = _dereq_(94); 12914 12915var _document2 = _interopRequireDefault(_document); 12916 12917var _window = _dereq_(95); 12918 12919var _window2 = _interopRequireDefault(_window); 12920 12921function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12922 12923function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 12924 12925/** 12926 * @file setup.js - Functions for setting up a player without 12927 * user interaction based on the data-setup `attribute` of the video tag. 12928 * 12929 * @module setup 12930 */ 12931var _windowLoaded = false; 12932var videojs = void 0; 12933 12934/** 12935 * Set up any tags that have a data-setup `attribute` when the player is started. 12936 */ 12937var autoSetup = function autoSetup() { 12938 12939 // Protect against breakage in non-browser environments. 12940 if (!Dom.isReal()) { 12941 return; 12942 } 12943 12944 // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack* 12945 // var vids = Array.prototype.slice.call(document.getElementsByTagName('video')); 12946 // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio')); 12947 // var mediaEls = vids.concat(audios); 12948 12949 // Because IE8 doesn't support calling slice on a node list, we need to loop 12950 // through each list of elements to build up a new, combined list of elements. 12951 var vids = _document2['default'].getElementsByTagName('video'); 12952 var audios = _document2['default'].getElementsByTagName('audio'); 12953 var mediaEls = []; 12954 12955 if (vids && vids.length > 0) { 12956 for (var i = 0, e = vids.length; i < e; i++) { 12957 mediaEls.push(vids[i]); 12958 } 12959 } 12960 12961 if (audios && audios.length > 0) { 12962 for (var _i = 0, _e = audios.length; _i < _e; _i++) { 12963 mediaEls.push(audios[_i]); 12964 } 12965 } 12966 12967 // Check if any media elements exist 12968 if (mediaEls && mediaEls.length > 0) { 12969 12970 for (var _i2 = 0, _e2 = mediaEls.length; _i2 < _e2; _i2++) { 12971 var mediaEl = mediaEls[_i2]; 12972 12973 // Check if element exists, has getAttribute func. 12974 // IE seems to consider typeof el.getAttribute == 'object' instead of 12975 // 'function' like expected, at least when loading the player immediately. 12976 if (mediaEl && mediaEl.getAttribute) { 12977 12978 // Make sure this player hasn't already been set up. 12979 if (mediaEl.player === undefined) { 12980 var options = mediaEl.getAttribute('data-setup'); 12981 12982 // Check if data-setup attr exists. 12983 // We only auto-setup if they've added the data-setup attr. 12984 if (options !== null) { 12985 // Create new video.js instance. 12986 videojs(mediaEl); 12987 } 12988 } 12989 12990 // If getAttribute isn't defined, we need to wait for the DOM. 12991 } else { 12992 autoSetupTimeout(1); 12993 break; 12994 } 12995 } 12996 12997 // No videos were found, so keep looping unless page is finished loading. 12998 } else if (!_windowLoaded) { 12999 autoSetupTimeout(1); 13000 } 13001}; 13002 13003/** 13004 * Wait until the page is loaded before running autoSetup. This will be called in 13005 * autoSetup if `hasLoaded` returns false. 13006 * 13007 * @param {number} wait 13008 * How long to wait in ms 13009 * 13010 * @param {videojs} [vjs] 13011 * The videojs library function 13012 */ 13013function autoSetupTimeout(wait, vjs) { 13014 if (vjs) { 13015 videojs = vjs; 13016 } 13017 13018 _window2['default'].setTimeout(autoSetup, wait); 13019} 13020 13021if (Dom.isReal() && _document2['default'].readyState === 'complete') { 13022 _windowLoaded = true; 13023} else { 13024 /** 13025 * Listen for the load event on window, and set _windowLoaded to true. 13026 * 13027 * @listens load 13028 */ 13029 Events.one(_window2['default'], 'load', function () { 13030 _windowLoaded = true; 13031 }); 13032} 13033 13034/** 13035 * check if the document has been loaded 13036 */ 13037var hasLoaded = function hasLoaded() { 13038 return _windowLoaded; 13039}; 13040 13041exports.autoSetup = autoSetup; 13042exports.autoSetupTimeout = autoSetupTimeout; 13043exports.hasLoaded = hasLoaded; 13044 13045},{"81":81,"82":82,"94":94,"95":95}],57:[function(_dereq_,module,exports){ 13046'use strict'; 13047 13048exports.__esModule = true; 13049 13050var _component = _dereq_(5); 13051 13052var _component2 = _interopRequireDefault(_component); 13053 13054var _dom = _dereq_(81); 13055 13056var Dom = _interopRequireWildcard(_dom); 13057 13058var _obj = _dereq_(88); 13059 13060function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 13061 13062function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 13063 13064function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 13065 13066function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 13067 13068function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
vendor: 5,996 bytes, lines 13068-13241
13068onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 13069 * @file slider.js 13070 */ 13071 13072 13073/** 13074 * The base functionality for a slider. Can be vertical or horizontal. 13075 * For instance the volume bar or the seek bar on a video is a slider. 13076 * 13077 * @extends Component 13078 */ 13079var Slider = function (_Component) { 13080 _inherits(Slider, _Component); 13081 13082 /** 13083 * Create an instance of this class 13084 * 13085 * @param {Player} player 13086 * The `Player` that this class should be attached to. 13087 * 13088 * @param {Object} [options] 13089 * The key/value store of player options. 13090 */ 13091 function Slider(player, options) { 13092 _classCallCheck(this, Slider); 13093 13094 // Set property names to bar to match with the child Slider class is looking for 13095 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 13096 13097 _this.bar = _this.getChild(_this.options_.barName); 13098 13099 // Set a horizontal or vertical class on the slider depending on the slider type 13100 _this.vertical(!!_this.options_.vertical); 13101 13102 _this.on('mousedown', _this.handleMouseDown); 13103 _this.on('touchstart', _this.handleMouseDown); 13104 _this.on('focus', _this.handleFocus); 13105 _this.on('blur', _this.handleBlur); 13106 _this.on('click', _this.handleClick); 13107 13108 _this.on(player, 'controlsvisible', _this.update); 13109 _this.on(player, _this.playerEvent, _this.update); 13110 return _this; 13111 } 13112 13113 /** 13114 * Create the `Button`s DOM element. 13115 * 13116 * @param {string} type 13117 * Type of element to create. 13118 * 13119 * @param {Object} [props={}] 13120 * List of properties in Object form. 13121 * 13122 * @param {Object} [attributes={}] 13123 * list of attributes in Object form. 13124 * 13125 * @return {Element} 13126 * The element that gets created. 13127 */ 13128 13129 13130 Slider.prototype.createEl = function createEl(type) { 13131 var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 13132 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 13133 13134 // Add the slider element class to all sub classes 13135 props.className = props.className + ' vjs-slider'; 13136 props = (0, _obj.assign)({ 13137 tabIndex: 0 13138 }, props); 13139 13140 attributes = (0, _obj.assign)({ 13141 'role': 'slider', 13142 'aria-valuenow': 0, 13143 'aria-valuemin': 0, 13144 'aria-valuemax': 100, 13145 'tabIndex': 0 13146 }, attributes); 13147 13148 return _Component.prototype.createEl.call(this, type, props, attributes); 13149 }; 13150 13151 /** 13152 * Handle `mousedown` or `touchstart` events on the `Slider`. 13153 * 13154 * @param {EventTarget~Event} event 13155 * `mousedown` or `touchstart` event that triggered this function 13156 * 13157 * @listens mousedown 13158 * @listens touchstart 13159 * @fires Slider#slideractive 13160 */ 13161 13162 13163 Slider.prototype.handleMouseDown = function handleMouseDown(event) { 13164 var doc = this.bar.el_.ownerDocument; 13165 13166 event.preventDefault(); 13167 Dom.blockTextSelection(); 13168 13169 this.addClass('vjs-sliding'); 13170 /** 13171 * Triggered when the slider is in an active state 13172 * 13173 * @event Slider#slideractive 13174 * @type {EventTarget~Event} 13175 */ 13176 this.trigger('slideractive'); 13177 13178 this.on(doc, 'mousemove', this.handleMouseMove); 13179 this.on(doc, 'mouseup', this.handleMouseUp); 13180 this.on(doc, 'touchmove', this.handleMouseMove); 13181 this.on(doc, 'touchend', this.handleMouseUp); 13182 13183 this.handleMouseMove(event); 13184 }; 13185 13186 /** 13187 * Handle the `mousemove`, `touchmove`, and `mousedown` events on this `Slider`. 13188 * The `mousemove` and `touchmove` events will only only trigger this function during 13189 * `mousedown` and `touchstart`. This is due to {@link Slider#handleMouseDown} and 13190 * {@link Slider#handleMouseUp}. 13191 * 13192 * @param {EventTarget~Event} event 13193 * `mousedown`, `mousemove`, `touchstart`, or `touchmove` event that triggered 13194 * this function 13195 * 13196 * @listens mousemove 13197 * @listens touchmove 13198 */ 13199 13200 13201 Slider.prototype.handleMouseMove = function handleMouseMove(event) {}; 13202 13203 /** 13204 * Handle `mouseup` or `touchend` events on the `Slider`. 13205 * 13206 * @param {EventTarget~Event} event 13207 * `mouseup` or `touchend` event that triggered this function. 13208 * 13209 * @listens touchend 13210 * @listens mouseup 13211 * @fires Slider#sliderinactive 13212 */ 13213 13214 13215 Slider.prototype.handleMouseUp = function handleMouseUp() { 13216 var doc = this.bar.el_.ownerDocument; 13217 13218 Dom.unblockTextSelection(); 13219 13220 this.removeClass('vjs-sliding'); 13221 /** 13222 * Triggered when the slider is no longer in an active state. 13223 * 13224 * @event Slider#sliderinactive 13225 * @type {EventTarget~Event} 13226 */ 13227 this.trigger('sliderinactive'); 13228 13229 this.off(doc, 'mousemove', this.handleMouseMove); 13230 this.off(doc, 'mouseup', this.handleMouseUp); 13231 this.off(doc, 'touchmove', this.handleMouseMove); 13232 this.off(doc, 'touchend', this.handleMouseUp); 13233 13234 this.update(); 13235 }; 13236 13237 /** 13238 * Update the progress bar of the `Slider`. 13239 */ 13240 13241
13242 Slider.prototype.update = function update() { 13243 // In VolumeBar init we have a setTimeout for update that pops and update to the end of the 13244 // execution stack. The player is destroyed before then update will cause an error 13245 if (!this.el_) { 13246 return; 13247 } 13248 13249 // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse. 13250 // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later. 13251 // var progress = (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration(); 13252 var progress = this.getPercent(); 13253 var bar = this.bar; 13254 13255 // If there's no bar... 13256 if (!bar) { 13257 return; 13258 } 13259 13260 // Protect against no duration and other division issues 13261 if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) { 13262 progress = 0; 13263 } 13264 13265 // Convert to a percentage for setting 13266 var percentage = (progress * 100).toFixed(2) + '%'; 13267 13268 // Set the new bar width or height 13269 if (this.vertical()) { 13270 bar.el().style.height = percentage; 13271 } else { 13272 bar.el().style.width = percentage; 13273 } 13274 }; 13275 13276 /** 13277 * Calculate distance for slider 13278 * 13279 * @param {EventTarget~Event} event 13280 * The event that caused this function to run. 13281 * 13282 * @return {number} 13283 * The current position of the Slider. 13284 * - postition.x for vertical `Slider`s 13285 * - postition.y for horizontal `Slider`s 13286 */ 13287 13288 13289 Slider.prototype.calculateDistance = function calculateDistance(event) { 13290 var position = Dom.getPointerPosition(this.el_, event); 13291 13292 if (this.vertical()) { 13293 return position.y; 13294 } 13295 return position.x; 13296 }; 13297 13298 /** 13299 * Handle a `focus` event on this `Slider`. 13300 * 13301 * @param {EventTarget~Event} event 13302 * The `focus` event that caused this function to run. 13303 * 13304 * @listens focus 13305 */ 13306 13307 13308 Slider.prototype.handleFocus = function handleFocus() { 13309 this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress); 13310 }; 13311 13312 /** 13313 * Handle a `keydown` event on the `Slider`. Watches for left, rigth, up, and down 13314 * arrow keys. This function will only be called when the slider has focus. See 13315 * {@link Slider#handleFocus} and {@link Slider#handleBlur}. 13316 * 13317 * @param {EventTarget~Event} event 13318 * the `keydown` event that caused this function to run. 13319 * 13320 * @listens keydown 13321 */ 13322 13323 13324 Slider.prototype.handleKeyPress = function handleKeyPress(event) { 13325 // Left and Down Arrows 13326 if (event.which === 37 || event.which === 40) { 13327 event.preventDefault(); 13328 this.stepBack(); 13329 13330 // Up and Right Arrows 13331 } else if (event.which === 38 || event.which === 39) { 13332 event.preventDefault(); 13333 this.stepForward(); 13334 } 13335 }; 13336 13337 /** 13338 * Handle a `blur` event on this `Slider`. 13339 * 13340 * @param {EventTarget~Event} event 13341 * The `blur` event that caused this function to run. 13342 * 13343 * @listens blur 13344 */ 13345 13346 Slider.prototype.handleBlur = function handleBlur() { 13347 this.off(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress); 13348 }; 13349 13350 /** 13351 * Listener for click events on slider, used to prevent clicks 13352 * from bubbling up to parent elements like button menus. 13353 * 13354 * @param {Object} event 13355 * Event that caused this object to run 13356 */ 13357 13358 13359 Slider.prototype.handleClick = function handleClick(event) { 13360 event.stopImmediatePropagation(); 13361 event.preventDefault(); 13362 }; 13363 13364 /** 13365 * Get/set if slider is horizontal for vertical 13366 * 13367 * @param {boolean} [bool] 13368 * - true if slider is vertical, 13369 * - false is horizontal 13370 * 13371 * @return {boolean|Slider} 13372 * - true if slider is vertical, and getting 13373 * - false is horizontal, and getting 13374 * - a reference to this object when setting 13375 */ 13376 13377 13378 Slider.prototype.vertical = function vertical(bool) { 13379 if (bool === undefined) { 13380 return this.vertical_ || false; 13381 } 13382 13383 this.vertical_ = !!bool; 13384 13385 if (this.vertical_) { 13386 this.addClass('vjs-slider-vertical'); 13387 } else { 13388 this.addClass('vjs-slider-horizontal'); 13389 } 13390 13391 return this; 13392 }; 13393 13394 return Slider; 13395}(_component2['default']); 13396 13397_component2['default'].registerComponent('Slider', Slider); 13398exports['default'] = Slider; 13399 13400},{"5":5,"81":81,"88":88}],58:[function(_dereq_,module,exports){ 13401'use strict'; 13402 13403exports.__esModule = true; 13404/** 13405 * @file flash-rtmp.js 13406 * @module flash-rtmp 13407 */ 13408 13409/** 13410 * Add RTMP properties to the {@link Flash} Tech. 13411 *
vendor: 4,097 bytes, lines 13412-13582
13412 * @param {Flash} Flash 13413 * The flash tech class. 13414 * 13415 * @mixin FlashRtmpDecorator 13416 */ 13417function FlashRtmpDecorator(Flash) { 13418 Flash.streamingFormats = { 13419 'rtmp/mp4': 'MP4', 13420 'rtmp/flv': 'FLV' 13421 }; 13422 13423 /** 13424 * Join connection and stream with an ampersand. 13425 * 13426 * @param {string} connection 13427 * The connection string. 13428 * 13429 * @param {string} stream 13430 * The stream string. 13431 */ 13432 Flash.streamFromParts = function (connection, stream) { 13433 return connection + '&' + stream; 13434 }; 13435 13436 /** 13437 * The flash parts object that contains connection and stream info. 13438 * 13439 * @typedef {Object} Flash~PartsObject 13440 * 13441 * @property {string} connection 13442 * The connection string of a source, defaults to an empty string. 13443 * 13444 * @property {string} stream 13445 * The stream string of the source, defaults to an empty string. 13446 */ 13447 13448 /** 13449 * Convert a source url into a stream and connection parts. 13450 * 13451 * @param {string} src 13452 * the source url 13453 * 13454 * @return {Flash~PartsObject} 13455 * The parts object that contains a connection and a stream 13456 */ 13457 Flash.streamToParts = function (src) { 13458 var parts = { 13459 connection: '', 13460 stream: '' 13461 }; 13462 13463 if (!src) { 13464 return parts; 13465 } 13466 13467 // Look for the normal URL separator we expect, '&'. 13468 // If found, we split the URL into two pieces around the 13469 // first '&'. 13470 var connEnd = src.search(/&(?!\w+=)/); 13471 var streamBegin = void 0; 13472 13473 if (connEnd !== -1) { 13474 streamBegin = connEnd + 1; 13475 } else { 13476 // If there's not a '&', we use the last '/' as the delimiter. 13477 connEnd = streamBegin = src.lastIndexOf('/') + 1; 13478 if (connEnd === 0) { 13479 // really, there's not a '/'? 13480 connEnd = streamBegin = src.length; 13481 } 13482 } 13483 13484 parts.connection = src.substring(0, connEnd); 13485 parts.stream = src.substring(streamBegin, src.length); 13486 13487 return parts; 13488 }; 13489 13490 /** 13491 * Check if the source type is a streaming type. 13492 * 13493 * @param {string} srcType 13494 * The mime type to check. 13495 * 13496 * @return {boolean} 13497 * - True if the source type is a streaming type. 13498 * - False if the source type is not a streaming type. 13499 */ 13500 Flash.isStreamingType = function (srcType) { 13501 return srcType in Flash.streamingFormats; 13502 }; 13503 13504 // RTMP has four variations, any string starting 13505 // with one of these protocols should be valid 13506 13507 /** 13508 * Regular expression used to check if the source is an rtmp source. 13509 * 13510 * @property {RegExp} Flash.RTMP_RE 13511 */ 13512 Flash.RTMP_RE = /^rtmp[set]?:\/\//i; 13513 13514 /** 13515 * Check if the source itself is a streaming type. 13516 * 13517 * @param {string} src 13518 * The url to the source. 13519 * 13520 * @return {boolean} 13521 * - True if the source url indicates that the source is streaming. 13522 * - False if the shource url indicates that the source url is not streaming. 13523 */ 13524 Flash.isStreamingSrc = function (src) { 13525 return Flash.RTMP_RE.test(src); 13526 }; 13527 13528 /** 13529 * A source handler for RTMP urls 13530 * @type {Object} 13531 */ 13532 Flash.rtmpSourceHandler = {}; 13533 13534 /** 13535 * Check if Flash can play the given mime type. 13536 * 13537 * @param {string} type 13538 * The mime type to check 13539 * 13540 * @return {string} 13541 * 'maybe', or '' (empty string) 13542 */ 13543 Flash.rtmpSourceHandler.canPlayType = function (type) { 13544 if (Flash.isStreamingType(type)) { 13545 return 'maybe'; 13546 } 13547 13548 return ''; 13549 }; 13550 13551 /** 13552 * Check if Flash can handle the source natively 13553 * 13554 * @param {Object} source 13555 * The source object 13556 * 13557 * @param {Object} [options] 13558 * The options passed to the tech 13559 * 13560 * @return {string} 13561 * 'maybe', or '' (empty string) 13562 */ 13563 Flash.rtmpSourceHandler.canHandleSource = function (source, options) { 13564 var can = Flash.rtmpSourceHandler.canPlayType(source.type); 13565 13566 if (can) { 13567 return can; 13568 } 13569 13570 if (Flash.isStreamingSrc(source.src)) { 13571 return 'maybe'; 13572 } 13573 13574 return ''; 13575 }; 13576 13577 /** 13578 * Pass the source to the flash object. 13579 * 13580 * @param {Object} source 13581 * The source object 13582 *
13583 * @param {Flash} tech 13584 * The instance of the Flash tech 13585 * 13586 * @param {Object} [options] 13587 * The options to pass to the source 13588 */ 13589 Flash.rtmpSourceHandler.handleSource = function (source, tech, options) { 13590 var srcParts = Flash.streamToParts(source.src); 13591 13592 tech.setRtmpConnection(srcParts.connection); 13593 tech.setRtmpStream(srcParts.stream); 13594 }; 13595 13596 // Register the native source handler 13597 Flash.registerSourceHandler(Flash.rtmpSourceHandler); 13598 13599 return Flash; 13600} 13601 13602exports['default'] = FlashRtmpDecorator; 13603 13604},{}],59:[function(_dereq_,module,exports){ 13605'use strict'; 13606 13607exports.__esModule = true; 13608 13609var _tech = _dereq_(62); 13610 13611var _tech2 = _interopRequireDefault(_tech); 13612 13613var _dom = _dereq_(81); 13614 13615var Dom = _interopRequireWildcard(_dom); 13616 13617var _url = _dereq_(92); 13618 13619var Url = _interopRequireWildcard(_url); 13620 13621var _timeRanges = _dereq_(90); 13622 13623var _flashRtmp = _dereq_(58); 13624 13625var _flashRtmp2 = _interopRequireDefault(_flashRtmp); 13626 13627var _component = _dereq_(5); 13628 13629var _component2 = _interopRequireDefault(_component); 13630 13631var _window = _dereq_(95); 13632 13633var _window2 = _interopRequireDefault(_window); 13634 13635var _obj = _dereq_(88); 13636 13637function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 13638 13639function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 13640 13641function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 13642 13643function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 13644 13645function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 13646 * @file flash.js 13647 * VideoJS-SWF - Custom Flash Player with HTML5-ish API 13648 * https://github.com/zencoder/video-js-swf 13649 * Not using setupTriggers. Using global onEvent func to distribute events 13650 */ 13651 13652var navigator = _window2['default'].navigator; 13653 13654/** 13655 * Flash Media Controller - Wrapper for Flash Media API 13656 * 13657 * @mixes FlashRtmpDecorator 13658 * @mixes Tech~SouceHandlerAdditions 13659 * @extends Tech 13660 */ 13661 13662var Flash = function (_Tech) { 13663 _inherits(Flash, _Tech); 13664 13665 /** 13666 * Create an instance of this Tech. 13667 * 13668 * @param {Object} [options] 13669 * The key/value store of player options. 13670 * 13671 * @param {Component~ReadyCallback} ready 13672 * Callback function to call when the `Flash` Tech is ready. 13673 */ 13674 function Flash(options, ready) { 13675 _classCallCheck(this, Flash); 13676 13677 // Set the source when ready 13678 var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready)); 13679 13680 if (options.source) { 13681 _this.ready(function () { 13682 this.setSource(options.source); 13683 }, true); 13684 } 13685 13686 // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers 13687 // This allows resetting the playhead when we catch the reload 13688 if (options.startTime) { 13689 _this.ready(function () { 13690 this.load(); 13691 this.play(); 13692 this.currentTime(options.startTime); 13693 }, true); 13694 } 13695 13696 // Add global window functions that the swf expects 13697 // A 4.x workflow we weren't able to solve for in 5.0 13698 // because of the need to hard code these functions 13699 // into the swf for security reasons 13700 _window2['default'].videojs = _window2['default'].videojs || {}; 13701 _window2['default'].videojs.Flash = _window2['default'].videojs.Flash || {}; 13702 _window2['default'].videojs.Flash.onReady = Flash.onReady; 13703 _window2['default'].videojs.Flash.onEvent = Flash.onEvent; 13704 _window2['default'].videojs.Flash.onError = Flash.onError; 13705 13706 _this.on('seeked', function () { 13707 this.lastSeekTarget_ = undefined; 13708 }); 13709 13710 return _this; 13711 } 13712 13713 /** 13714 * Create the `Flash` Tech's DOM element. 13715 * 13716 * @return {Element} 13717 * The element that gets created. 13718 */ 13719 13720 13721 Flash.prototype.createEl = function createEl() { 13722 var options = this.options_; 13723 13724 // If video.js is hosted locally you should also set the location 13725 // for the hosted swf, which should be relative to the page (not video.js) 13726 // Otherwise this adds a CDN url. 13727 // The CDN also auto-adds a swf URL for that specific version. 13728 if (!options.swf) { 13729 var ver = '5.3.0'; 13730 13731 options.swf = '//vjs.zencdn.net/swf/' + ver + '/video-js.swf'; 13732 } 13733 13734 // Generate ID for swf object 13735 var objId = options.techId; 13736 13737 // Merge default flashvars with ones passed in to init 13738 var flashVars = (0, _obj.assign)({ 13739 13740 // SWF Callback Functions 13741 readyFunction: 'videojs.Flash.onReady', 13742 eventProxyFunction: 'videojs.Flash.onEvent', 13743 errorEventProxyFunction: 'videojs.Flash.onError', 13744 13745 // Player Settings 13746 autoplay: options.autoplay, 13747 preload: options.preload, 13748 loop: options.loop, 13749 muted: options.muted 13750 13751 }, options.flashVars); 13752 13753 // Merge default parames with ones passed in 13754 var params = (0, _obj.assign)({ 13755 // Opaque is needed to overlay controls, but can affect playback performance 13756 wmode: 'opaque', 13757 // Using bgcolor prevents a white flash when the object is loading 13758 bgcolor: '#000000' 13759 }, options.params); 13760 13761 // Merge default attributes with ones passed in 13762 var attributes = (0, _obj.assign)({ 13763 // Both ID and Name needed or swf to identify itself 13764 id: objId, 13765 name: objId, 13766 'class': 'vjs-tech' 13767 }, options.attributes); 13768 13769 this.el_ = Flash.embed(options.swf, flashVars, params, attributes); 13770 this.el_.tech = this; 13771 13772 return this.el_; 13773 }; 13774 13775 /** 13776 * Called by {@link Player#play} to play using the `Flash` `Tech`. 13777 */ 13778 13779 13780 Flash.prototype.play = function play() { 13781 if (this.ended()) { 13782 this.setCurrentTime(0); 13783 } 13784 this.el_.vjs_play(); 13785 }; 13786 13787 /** 13788 * Called by {@link Player#pause} to pause using the `Flash` `Tech`. 13789 */ 13790 13791 13792 Flash.prototype.pause = function pause() { 13793 this.el_.vjs_pause(); 13794 }; 13795 13796 /** 13797 * A getter/setter for the `Flash` Tech's source object. 13798 * > Note: Please use {@link Flash#setSource} 13799 * 13800 * @param {Tech~SourceObject} [src] 13801 * The source object you want to set on the `Flash` techs. 13802 * 13803 * @return {Tech~SourceObject|undefined} 13804 * - The current source object when a source is not passed in. 13805 * - undefined when setting 13806 * 13807 * @deprecated Since version 5. 13808 */ 13809 13810 13811 Flash.prototype.src = function src(_src) { 13812 if (_src === undefined) { 13813 return this.currentSrc(); 13814 } 13815 13816 // Setting src through `src` not `setSrc` will be deprecated 13817 return this.setSrc(_src); 13818 }; 13819 13820 /** 13821 * A getter/setter for the `Flash` Tech's source object. 13822 * 13823 * @param {Tech~SourceObject} [src] 13824 * The source object you want to set on the `Flash` techs. 13825 * 13826 * @return {Tech~SourceObject|undefined} 13827 * - The current source object when a source is not passed in. 13828 * - undefined when setting 13829 */ 13830 13831 13832 Flash.prototype.setSrc = function setSrc(src) { 13833 var _this2 = this; 13834 13835 // Make sure source URL is absolute. 13836 src = Url.getAbsoluteURL(src); 13837 this.el_.vjs_src(src); 13838 13839 // Currently the SWF doesn't autoplay if you load a source later. 13840 // e.g. Load player w/ no source, wait 2s, set src. 13841 if (this.autoplay()) { 13842 this.setTimeout(function () { 13843 return _this2.play(); 13844 }, 0); 13845 } 13846 }; 13847 13848 /** 13849 * Indicates whether the media is currently seeking to a new position or not. 13850 * 13851 * @return {boolean} 13852 * - True if seeking to a new position 13853 * - False otherwise 13854 */ 13855 13856 13857 Flash.prototype.seeking = function seeking() { 13858 return this.lastSeekTarget_ !== undefined; 13859 }; 13860 13861 /** 13862 * Returns the current time in seconds that the media is at in playback. 13863 * 13864 * @param {number} time 13865 * Current playtime of the media in seconds. 13866 */ 13867 13868 13869 Flash.prototype.setCurrentTime = function setCurrentTime(time) { 13870 var seekable = this.seekable(); 13871 13872 if (seekable.length) { 13873 // clamp to the current seekable range 13874 time = time > seekable.start(0) ? time : seekable.start(0); 13875 time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1); 13876 13877 this.lastSeekTarget_ = time; 13878 this.trigger('seeking'); 13879 this.el_.vjs_setProperty('currentTime', time); 13880 _Tech.prototype.setCurrentTime.call(this); 13881 } 13882 }; 13883 13884 /** 13885 * Get the current playback time in seconds 13886 * 13887 * @return {number} 13888 * The current time of playback in seconds. 13889 */ 13890 13891 13892 Flash.prototype.currentTime = function currentTime() { 13893 // when seeking make the reported time keep up with the requested time 13894 // by reading the time we're seeking to 13895 if (this.seeking()) { 13896 return this.lastSeekTarget_ || 0; 13897 } 13898 return this.el_.vjs_getProperty('currentTime'); 13899 }; 13900 13901 /** 13902 * Get the current source 13903 * 13904 * @method currentSrc 13905 * @return {Tech~SourceObject} 13906 * The current source 13907 */ 13908 13909 13910 Flash.prototype.currentSrc = function currentSrc() { 13911 if (this.currentSource_) { 13912 return this.currentSource_.src; 13913 } 13914 return this.el_.vjs_getProperty('currentSrc'); 13915 }; 13916 13917 /** 13918 * Get the total duration of the current media. 13919 * 13920 * @return {number} 13921 8 The total duration of the current media. 13922 */ 13923 13924 13925 Flash.prototype.duration = function duration() { 13926 if (this.readyState() === 0) { 13927 return NaN; 13928 } 13929 var duration = this.el_.vjs_getProperty('duration'); 13930 13931 return duration >= 0 ? duration : Infinity; 13932 }; 13933 13934 /** 13935 * Load media into Tech. 13936 */ 13937 13938 13939 Flash.prototype.load = function load() { 13940 this.el_.vjs_load(); 13941 }; 13942 13943 /** 13944 * Get the poster image that was set on the tech. 13945 */ 13946 13947 13948 Flash.prototype.poster = function poster() { 13949 this.el_.vjs_getProperty('poster'); 13950 }; 13951 13952 /** 13953 * Poster images are not handled by the Flash tech so make this is a no-op. 13954 */ 13955 13956 13957 Flash.prototype.setPoster = function setPoster() {}; 13958 13959 /** 13960 * Determine the time ranges that can be seeked to in the media. 13961 * 13962 * @return {TimeRange} 13963 * Returns the time ranges that can be seeked to. 13964 */ 13965 13966 13967 Flash.prototype.seekable = function seekable() { 13968 var duration = this.duration(); 13969 13970 if (duration === 0) { 13971 return (0, _timeRanges.createTimeRange)(); 13972 } 13973 return (0, _timeRanges.createTimeRange)(0, duration); 13974 }; 13975 13976 /** 13977 * Get and create a `TimeRange` object for buffering. 13978 * 13979 * @return {TimeRange} 13980 * The time range object that was created. 13981 */ 13982 13983 13984 Flash.prototype.buffered = function buffered() { 13985 var ranges = this.el_.vjs_getProperty('buffered'); 13986 13987 if (ranges.length === 0) { 13988 return (0, _timeRanges.createTimeRange)(); 13989 } 13990 return (0, _timeRanges.createTimeRange)(ranges[0][0], ranges[0][1]); 13991 }; 13992 13993 /** 13994 * Get fullscreen support - 13995 * 13996 * Flash does not allow fullscreen through javascript 13997 * so this always returns false. 13998 * 13999 * @return {boolean}
14000 * The Flash tech does not support fullscreen, so it will always return false. 14001 */ 14002 14003 14004 Flash.prototype.supportsFullScreen = function supportsFullScreen() { 14005 // Flash does not allow fullscreen through javascript 14006 return false; 14007 }; 14008 14009 /** 14010 * Flash does not allow fullscreen through javascript 14011 * so this always returns false. 14012 * 14013 * @return {boolean} 14014 * The Flash tech does not support fullscreen, so it will always return false. 14015 */ 14016 14017 14018 Flash.prototype.enterFullScreen = function enterFullScreen() { 14019 return false; 14020 }; 14021 14022 return Flash; 14023}(_tech2['default']); 14024 14025// Create setters and getters for attributes 14026 14027 14028var _api = Flash.prototype; 14029var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(','); 14030var _readOnly = 'networkState,readyState,initialTime,startOffsetTime,paused,ended,videoWidth,videoHeight'.split(','); 14031 14032function _createSetter(attr) { 14033 var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1); 14034 14035 _api['set' + attrUpper] = function (val) { 14036 return this.el_.vjs_setProperty(attr, val); 14037 }; 14038}
vendor: 12,234 bytes, lines 14039-14440
14039 14040function _createGetter(attr) { 14041 _api[attr] = function () { 14042 return this.el_.vjs_getProperty(attr); 14043 }; 14044} 14045 14046// Create getter and setters for all read/write attributes 14047for (var i = 0; i < _readWrite.length; i++) { 14048 _createGetter(_readWrite[i]); 14049 _createSetter(_readWrite[i]); 14050} 14051 14052// Create getters for read-only attributes 14053for (var _i = 0; _i < _readOnly.length; _i++) { 14054 _createGetter(_readOnly[_i]); 14055} 14056 14057/** ------------------------------ Getters ------------------------------ **/ 14058/** 14059 * Get the value of `rtmpConnection` from the swf. 14060 * 14061 * @method Flash#rtmpConnection 14062 * @return {string} 14063 * The current value of `rtmpConnection` on the swf. 14064 */ 14065 14066/** 14067 * Get the value of `rtmpStream` from the swf. 14068 * 14069 * @method Flash#rtmpStream 14070 * @return {string} 14071 * The current value of `rtmpStream` on the swf. 14072 */ 14073 14074/** 14075 * Get the value of `preload` from the swf. `preload` indicates 14076 * what should download before the media is interacted with. It can have the following 14077 * values: 14078 * - none: nothing should be downloaded 14079 * - metadata: poster and the first few frames of the media may be downloaded to get 14080 * media dimensions and other metadata 14081 * - auto: allow the media and metadata for the media to be downloaded before 14082 * interaction 14083 * 14084 * @method Flash#preload 14085 * @return {string} 14086 * The value of `preload` from the swf. Will be 'none', 'metadata', 14087 * or 'auto'. 14088 */ 14089 14090/** 14091 * Get the value of `defaultPlaybackRate` from the swf. 14092 * 14093 * @method Flash#defaultPlaybackRate 14094 * @return {number} 14095 * The current value of `defaultPlaybackRate` on the swf. 14096 */ 14097 14098/** 14099 * Get the value of `playbackRate` from the swf. `playbackRate` indicates 14100 * the rate at which the media is currently playing back. Examples: 14101 * - if playbackRate is set to 2, media will play twice as fast. 14102 * - if playbackRate is set to 0.5, media will play half as fast. 14103 * 14104 * @method Flash#playbackRate 14105 * @return {number} 14106 * The value of `playbackRate` from the swf. A number indicating 14107 * the current playback speed of the media, where 1 is normal speed. 14108 */ 14109 14110/** 14111 * Get the value of `autoplay` from the swf. `autoplay` indicates 14112 * that the media should start to play as soon as the page is ready. 14113 * 14114 * @method Flash#autoplay 14115 * @return {boolean} 14116 * - The value of `autoplay` from the swf. 14117 * - True indicates that the media ashould start as soon as the page loads. 14118 * - False indicates that the media should not start as soon as the page loads. 14119 */ 14120 14121/** 14122 * Get the value of `loop` from the swf. `loop` indicates 14123 * that the media should return to the start of the media and continue playing once 14124 * it reaches the end. 14125 * 14126 * @method Flash#loop 14127 * @return {boolean} 14128 * - The value of `loop` from the swf. 14129 * - True indicates that playback should seek back to start once 14130 * the end of a media is reached. 14131 * - False indicates that playback should not loop back to the start when the 14132 * end of the media is reached. 14133 */ 14134 14135/** 14136 * Get the value of `mediaGroup` from the swf. 14137 * 14138 * @method Flash#mediaGroup 14139 * @return {string} 14140 * The current value of `mediaGroup` on the swf. 14141 */ 14142 14143/** 14144 * Get the value of `controller` from the swf. 14145 * 14146 * @method Flash#controller 14147 * @return {string} 14148 * The current value of `controller` on the swf. 14149 */ 14150 14151/** 14152 * Get the value of `controls` from the swf. `controls` indicates 14153 * whether the native flash controls should be shown or hidden. 14154 * 14155 * @method Flash#controls 14156 * @return {boolean} 14157 * - The value of `controls` from the swf. 14158 * - True indicates that native controls should be showing. 14159 * - False indicates that native controls should be hidden. 14160 */ 14161 14162/** 14163 * Get the value of the `volume` from the swf. `volume` indicates the current 14164 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and 14165 * so on. 14166 * 14167 * @method Flash#volume 14168 * @return {number} 14169 * The volume percent as a decimal. Value will be between 0-1. 14170 */ 14171 14172/** 14173 * Get the value of the `muted` from the swf. `muted` indicates the current 14174 * audio level should be silent. 14175 * 14176 * @method Flash#muted 14177 * @return {boolean} 14178 * - True if the audio should be set to silent 14179 * - False otherwise 14180 */ 14181 14182/** 14183 * Get the value of `defaultMuted` from the swf. `defaultMuted` indicates 14184 * whether the media should start muted or not. Only changes the default state of the 14185 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the 14186 * current state. 14187 * 14188 * @method Flash#defaultMuted 14189 * @return {boolean} 14190 * - The value of `defaultMuted` from the swf. 14191 * - True indicates that the media should start muted. 14192 * - False indicates that the media should not start muted. 14193 */ 14194 14195/** 14196 * Get the value of `networkState` from the swf. `networkState` indicates 14197 * the current network state. It returns an enumeration from the following list: 14198 * - 0: NETWORK_EMPTY 14199 * - 1: NEWORK_IDLE 14200 * - 2: NETWORK_LOADING 14201 * - 3: NETWORK_NO_SOURCE 14202 * 14203 * @method Flash#networkState 14204 * @return {number} 14205 * The value of `networkState` from the swf. This will be a number 14206 * from the list in the description. 14207 */ 14208 14209/** 14210 * Get the value of `readyState` from the swf. `readyState` indicates 14211 * the current state of the media element. It returns an enumeration from the 14212 * following list: 14213 * - 0: HAVE_NOTHING 14214 * - 1: HAVE_METADATA 14215 * - 2: HAVE_CURRENT_DATA 14216 * - 3: HAVE_FUTURE_DATA 14217 * - 4: HAVE_ENOUGH_DATA 14218 * 14219 * @method Flash#readyState 14220 * @return {number} 14221 * The value of `readyState` from the swf. This will be a number 14222 * from the list in the description. 14223 */ 14224 14225/** 14226 * Get the value of `readyState` from the swf. `readyState` indicates 14227 * the current state of the media element. It returns an enumeration from the 14228 * following list: 14229 * - 0: HAVE_NOTHING 14230 * - 1: HAVE_METADATA 14231 * - 2: HAVE_CURRENT_DATA 14232 * - 3: HAVE_FUTURE_DATA 14233 * - 4: HAVE_ENOUGH_DATA 14234 * 14235 * @method Flash#readyState 14236 * @return {number} 14237 * The value of `readyState` from the swf. This will be a number 14238 * from the list in the description. 14239 */ 14240 14241/** 14242 * Get the value of `initialTime` from the swf. 14243 * 14244 * @method Flash#initialTime 14245 * @return {number} 14246 * The `initialTime` proprety on the swf. 14247 */ 14248 14249/** 14250 * Get the value of `startOffsetTime` from the swf. 14251 * 14252 * @method Flash#startOffsetTime 14253 * @return {number} 14254 * The `startOffsetTime` proprety on the swf. 14255 */ 14256 14257/** 14258 * Get the value of `paused` from the swf. `paused` indicates whether the swf 14259 * is current paused or not. 14260 * 14261 * @method Flash#paused 14262 * @return {boolean} 14263 * The value of `paused` from the swf. 14264 */ 14265 14266/** 14267 * Get the value of `ended` from the swf. `ended` indicates whether 14268 * the media has reached the end or not. 14269 * 14270 * @method Flash#ended 14271 * @return {boolean} 14272 * - True indicates that the media has ended. 14273 * - False indicates that the media has not ended. 14274 * 14275 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended} 14276 */ 14277 14278/** 14279 * Get the value of `videoWidth` from the swf. `videoWidth` indicates 14280 * the current width of the media in css pixels. 14281 * 14282 * @method Flash#videoWidth 14283 * @return {number} 14284 * The value of `videoWidth` from the swf. This will be a number 14285 * in css pixels. 14286 */ 14287 14288/** 14289 * Get the value of `videoHeight` from the swf. `videoHeigth` indicates 14290 * the current height of the media in css pixels. 14291 * 14292 * @method Flassh.prototype.videoHeight 14293 * @return {number} 14294 * The value of `videoHeight` from the swf. This will be a number 14295 * in css pixels. 14296 */ 14297/** ------------------------------ Setters ------------------------------ **/ 14298 14299/** 14300 * Set the value of `rtmpConnection` on the swf. 14301 * 14302 * @method Flash#setRtmpConnection 14303 * @param {string} rtmpConnection 14304 * New value to set the `rtmpConnection` property to. 14305 */ 14306 14307/** 14308 * Set the value of `rtmpStream` on the swf. 14309 * 14310 * @method Flash#setRtmpStream 14311 * @param {string} rtmpStream 14312 * New value to set the `rtmpStream` property to. 14313 */ 14314 14315/** 14316 * Set the value of `preload` on the swf. `preload` indicates 14317 * what should download before the media is interacted with. It can have the following 14318 * values: 14319 * - none: nothing should be downloaded 14320 * - metadata: poster and the first few frames of the media may be downloaded to get 14321 * media dimensions and other metadata 14322 * - auto: allow the media and metadata for the media to be downloaded before 14323 * interaction 14324 * 14325 * @method Flash#setPreload 14326 * @param {string} preload 14327 * The value of `preload` to set on the swf. Should be 'none', 'metadata', 14328 * or 'auto'. 14329 */ 14330 14331/** 14332 * Set the value of `defaultPlaybackRate` on the swf. 14333 * 14334 * @method Flash#setDefaultPlaybackRate 14335 * @param {number} defaultPlaybackRate 14336 * New value to set the `defaultPlaybackRate` property to. 14337 */ 14338 14339/** 14340 * Set the value of `playbackRate` on the swf. `playbackRate` indicates 14341 * the rate at which the media is currently playing back. Examples: 14342 * - if playbackRate is set to 2, media will play twice as fast. 14343 * - if playbackRate is set to 0.5, media will play half as fast. 14344 * 14345 * @method Flash#setPlaybackRate 14346 * @param {number} playbackRate 14347 * New value of `playbackRate` on the swf. A number indicating 14348 * the current playback speed of the media, where 1 is normal speed. 14349 */ 14350 14351/** 14352 * Set the value of `autoplay` on the swf. `autoplay` indicates 14353 * that the media should start to play as soon as the page is ready. 14354 * 14355 * @method Flash#setAutoplay 14356 * @param {boolean} autoplay 14357 * - The value of `autoplay` from the swf. 14358 * - True indicates that the media ashould start as soon as the page loads. 14359 * - False indicates that the media should not start as soon as the page loads. 14360 */ 14361 14362/** 14363 * Set the value of `loop` on the swf. `loop` indicates 14364 * that the media should return to the start of the media and continue playing once 14365 * it reaches the end. 14366 * 14367 * @method Flash#setLoop 14368 * @param {boolean} loop 14369 * - True indicates that playback should seek back to start once 14370 * the end of a media is reached. 14371 * - False indicates that playback should not loop back to the start when the 14372 * end of the media is reached. 14373 */ 14374 14375/** 14376 * Set the value of `mediaGroup` on the swf. 14377 * 14378 * @method Flash#setMediaGroup 14379 * @param {string} mediaGroup 14380 * New value of `mediaGroup` to set on the swf. 14381 */ 14382 14383/** 14384 * Set the value of `controller` on the swf. 14385 * 14386 * @method Flash#setController 14387 * @param {string} controller 14388 * New value the current value of `controller` on the swf. 14389 */ 14390 14391/** 14392 * Get the value of `controls` from the swf. `controls` indicates 14393 * whether the native flash controls should be shown or hidden. 14394 * 14395 * @method Flash#controls 14396 * @return {boolean} 14397 * - The value of `controls` from the swf. 14398 * - True indicates that native controls should be showing. 14399 * - False indicates that native controls should be hidden. 14400 */ 14401 14402/** 14403 * Set the value of the `volume` on the swf. `volume` indicates the current 14404 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and 14405 * so on. 14406 * 14407 * @method Flash#setVolume 14408 * @param {number} percentAsDecimal 14409 * The volume percent as a decimal. Value will be between 0-1. 14410 */ 14411 14412/** 14413 * Set the value of the `muted` on the swf. `muted` indicates that the current 14414 * audio level should be silent. 14415 * 14416 * @method Flash#setMuted 14417 * @param {boolean} muted 14418 * - True if the audio should be set to silent 14419 * - False otherwise 14420 */ 14421 14422/** 14423 * Set the value of `defaultMuted` on the swf. `defaultMuted` indicates 14424 * whether the media should start muted or not. Only changes the default state of the 14425 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the 14426 * current state. 14427 * 14428 * @method Flash#setDefaultMuted 14429 * @param {boolean} defaultMuted 14430 * - True indicates that the media should start muted. 14431 * - False indicates that the media should not start muted. 14432 */ 14433 14434/* Flash Support Testing -------------------------------------------------------- */ 14435 14436/** 14437 * Check if the Flash tech is currently supported. 14438 * 14439 * @return {boolean} 14440 * - True
vendor: 5,749 bytes, lines 14440-14674
14440if the flash tech is supported. 14441 * - False otherwise. 14442 */ 14443Flash.isSupported = function () { 14444 return Flash.version()[0] >= 10; 14445 // return swfobject.hasFlashPlayerVersion('10'); 14446}; 14447 14448// Add Source Handler pattern functions to this tech 14449_tech2['default'].withSourceHandlers(Flash); 14450 14451/* 14452 * Native source handler for flash, simply passes the source to the swf element. 14453 * 14454 * @property {Tech~SourceObject} source 14455 * The source object 14456 * 14457 * @property {Flash} tech 14458 * The instance of the Flash tech 14459 */ 14460Flash.nativeSourceHandler = {}; 14461 14462/** 14463 * Check if the Flash can play the given mime type. 14464 * 14465 * @param {string} type 14466 * The mimetype to check 14467 * 14468 * @return {string} 14469 * 'maybe', or '' (empty string) 14470 */ 14471Flash.nativeSourceHandler.canPlayType = function (type) { 14472 if (type in Flash.formats) { 14473 return 'maybe'; 14474 } 14475 14476 return ''; 14477}; 14478 14479/** 14480 * Check if the media element can handle a source natively. 14481 * 14482 * @param {Tech~SourceObject} source 14483 * The source object 14484 * 14485 * @param {Object} [options] 14486 * Options to be passed to the tech. 14487 * 14488 * @return {string} 14489 * 'maybe', or '' (empty string). 14490 */ 14491Flash.nativeSourceHandler.canHandleSource = function (source, options) { 14492 var type = void 0; 14493 14494 function guessMimeType(src) { 14495 var ext = Url.getFileExtension(src); 14496 14497 if (ext) { 14498 return 'video/' + ext; 14499 } 14500 return ''; 14501 } 14502 14503 if (!source.type) { 14504 type = guessMimeType(source.src); 14505 } else { 14506 // Strip code information from the type because we don't get that specific 14507 type = source.type.replace(/;.*/, '').toLowerCase(); 14508 } 14509 14510 return Flash.nativeSourceHandler.canPlayType(type); 14511}; 14512 14513/** 14514 * Pass the source to the swf. 14515 * 14516 * @param {Tech~SourceObject} source 14517 * The source object 14518 * 14519 * @param {Flash} tech 14520 * The instance of the Flash tech 14521 * 14522 * @param {Object} [options] 14523 * The options to pass to the source 14524 */ 14525Flash.nativeSourceHandler.handleSource = function (source, tech, options) { 14526 tech.setSrc(source.src); 14527}; 14528 14529/** 14530 * noop for native source handler dispose, as cleanup will happen automatically. 14531 */ 14532Flash.nativeSourceHandler.dispose = function () {}; 14533 14534// Register the native source handler 14535Flash.registerSourceHandler(Flash.nativeSourceHandler); 14536 14537/** 14538 * Flash supported mime types. 14539 * 14540 * @constant {Object} 14541 */ 14542Flash.formats = { 14543 'video/flv': 'FLV', 14544 'video/x-flv': 'FLV', 14545 'video/mp4': 'MP4', 14546 'video/m4v': 'MP4' 14547}; 14548 14549/** 14550 * Called when the the swf is "ready", and makes sure that the swf is really 14551 * ready using {@link Flash#checkReady} 14552 */ 14553Flash.onReady = function (currSwf) { 14554 var el = Dom.getEl(currSwf); 14555 var tech = el && el.tech; 14556 14557 // if there is no el then the tech has been disposed 14558 // and the tech element was removed from the player div 14559 if (tech && tech.el()) { 14560 // check that the flash object is really ready 14561 Flash.checkReady(tech); 14562 } 14563}; 14564 14565/** 14566 * The SWF isn't always ready when it says it is. Sometimes the API functions still 14567 * need to be added to the object. If it's not ready, we set a timeout to check again 14568 * shortly. 14569 * 14570 * @param {Flash} tech 14571 * The instance of the flash tech to check. 14572 */ 14573Flash.checkReady = function (tech) { 14574 // stop worrying if the tech has been disposed 14575 if (!tech.el()) { 14576 return; 14577 } 14578 14579 // check if API property exists 14580 if (tech.el().vjs_getProperty) { 14581 // tell tech it's ready 14582 tech.triggerReady(); 14583 } else { 14584 // wait longer 14585 this.setTimeout(function () { 14586 Flash.checkReady(tech); 14587 }, 50); 14588 } 14589}; 14590 14591/** 14592 * Trigger events from the swf on the Flash Tech. 14593 * 14594 * @param {number} swfID 14595 * The id of the swf that had the event 14596 * 14597 * @param {string} eventName 14598 * The name of the event to trigger 14599 */ 14600Flash.onEvent = function (swfID, eventName) { 14601 var tech = Dom.getEl(swfID).tech; 14602 var args = Array.prototype.slice.call(arguments, 2); 14603 14604 // dispatch Flash events asynchronously for two reasons: 14605 // - Flash swallows any exceptions generated by javascript it 14606 // invokes 14607 // - Flash is suspended until the javascript returns which may cause 14608 // playback performance issues 14609 tech.setTimeout(function () { 14610 tech.trigger(eventName, args); 14611 }, 1); 14612}; 14613 14614/** 14615 * Log errors from the swf on the Flash tech. 14616 * 14617 * @param {number} swfID 14618 * The id of the swf that had an error. 14619 * 14620 * @param {string} The error string 14621 * The error to set on the Flash Tech. 14622 * 14623 * @return {MediaError|undefined} 14624 * - Returns a MediaError when err is 'srcnotfound' 14625 * - Returns undefined otherwise. 14626 */ 14627Flash.onError = function (swfID, err) { 14628 var tech = Dom.getEl(swfID).tech; 14629 14630 // trigger MEDIA_ERR_SRC_NOT_SUPPORTED 14631 if (err === 'srcnotfound') { 14632 return tech.error(4); 14633 } 14634 14635 // trigger a custom error 14636 tech.error('FLASH: ' + err); 14637}; 14638 14639/** 14640 * Get the current version of Flash that is in use on the page. 14641 * 14642 * @return {Array} 14643 * an array of versions that are available. 14644 */ 14645Flash.version = function () { 14646 var version = '0,0,0'; 14647 14648 // IE 14649 try { 14650 version = new _window2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; 14651 14652 // other browsers 14653 } catch (e) { 14654 try { 14655 if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) { 14656 version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; 14657 } 14658 } catch (err) { 14659 // satisfy linter 14660 } 14661 } 14662 return version.split(','); 14663}; 14664 14665/** 14666 * Only use for non-iframe embeds. 14667 * 14668 * @param {Object} swf 14669 * The videojs-swf object. 14670 * 14671 * @param {Object} flashVars 14672 * Names and values to use as flash option variables. 14673 * 14674 * @param {Object} params
14675 * Style parameters to set on the object. 14676 * 14677 * @param {Object} attributes 14678 * Attributes to set on the element. 14679 * 14680 * @return {Element} 14681 * The embeded Flash DOM element. 14682 */ 14683Flash.embed = function (swf, flashVars, params, attributes) { 14684 var code = Flash.getEmbedCode(swf, flashVars, params, attributes); 14685 14686 // Get element by embedding code and retrieving created element 14687 var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0]; 14688 14689 return obj; 14690}; 14691 14692/** 14693 * Only use for non-iframe embeds. 14694 * 14695 * @param {Object} swf 14696 * The videojs-swf object. 14697 * 14698 * @param {Object} flashVars 14699 * Names and values to use as flash option variables. 14700 * 14701 * @param {Object} params 14702 * Style parameters to set on the object. 14703 * 14704 * @param {Object} attributes 14705 * Attributes to set on the element. 14706 * 14707 * @return {Element} 14708 * The embeded Flash DOM element. 14709 */ 14710Flash.getEmbedCode = function (swf, flashVars, params, attributes) { 14711 var objTag = '<object type="application/x-shockwave-flash" '; 14712 var flashVarsString = ''; 14713 var paramsString = ''; 14714 var attrsString = ''; 14715 14716 // Convert flash vars to string 14717 if (flashVars) { 14718 Object.getOwnPropertyNames(flashVars).forEach(function (key) { 14719 flashVarsString += key + '=' + flashVars[key] + '&'; 14720 }); 14721 } 14722 14723 // Add swf, flashVars, and other default params 14724 params = (0, _obj.assign)({ 14725 movie: swf, 14726 flashvars: flashVarsString, 14727 // Required to talk to swf 14728 allowScriptAccess: 'always', 14729 // All should be default, but having security issues. 14730 allowNetworking: 'all' 14731 }, params); 14732 14733 // Create param tags string 14734 Object.getOwnPropertyNames(params).forEach(function (key) { 14735 paramsString += '<param name="' + key + '" value="' + params[key] + '" />'; 14736 }); 14737 14738 attributes = (0, _obj.assign)({ 14739 // Add swf to attributes (need both for IE and Others to work) 14740 data: swf, 14741 14742 // Default to 100% width/height 14743 width: '100%', 14744 height: '100%' 14745 14746 }, attributes); 14747 14748 // Create Attributes string 14749 Object.getOwnPropertyNames(attributes).forEach(function (key) { 14750 attrsString += key + '="' + attributes[key] + '" '; 14751 }); 14752 14753 return '' + objTag + attrsString + '>' + paramsString + '</object>'; 14754}; 14755 14756// Run Flash through the RTMP decorator 14757(0, _flashRtmp2['default'])(Flash); 14758 14759_component2['default'].registerComponent('Flash', Flash); 14760_tech2['default'].registerTech('Flash', Flash); 14761exports['default'] = Flash; 14762 14763},{"5":5,"58":58,"62":62,"81":81,"88":88,"90":90,"92":92,"95":95}],60:[function(_dereq_,module,exports){ 14764'use strict'; 14765 14766exports.__esModule = true; 14767 14768var _templateObject = _taggedTemplateLiteralLoose(['Text Tracks are being loaded from another origin but the crossorigin attribute isn\'t used.\n This may prevent text tracks from loading.'], ['Text Tracks are being loaded from another origin but the crossorigin attribute isn\'t used.\n This may prevent text tracks from loading.']); 14769 14770var _tech = _dereq_(62); 14771 14772var _tech2 = _interopRequireDefault(_tech); 14773 14774var _component = _dereq_(5); 14775 14776var _component2 = _interopRequireDefault(_component); 14777 14778var _dom = _dereq_(81); 14779 14780var Dom = _interopRequireWildcard(_dom); 14781 14782var _url = _dereq_(92); 14783 14784var Url = _interopRequireWildcard(_url); 14785 14786var _fn = _dereq_(83); 14787 14788var Fn = _interopRequireWildcard(_fn); 14789 14790var _log = _dereq_(86); 14791 14792var _log2 = _interopRequireDefault(_log); 14793 14794var _tsml = _dereq_(98); 14795 14796var _tsml2 = _interopRequireDefault(_tsml); 14797 14798var _browser = _dereq_(78); 14799 14800var browser = _interopRequireWildcard(_browser); 14801 14802var _document = _dereq_(94); 14803 14804var _document2 = _interopRequireDefault(_document); 14805 14806var _window = _dereq_(95); 14807 14808var _window2 = _interopRequireDefault(_window); 14809 14810var _obj = _dereq_(88); 14811 14812var _mergeOptions = _dereq_(87); 14813 14814var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 14815 14816var _toTitleCase = _dereq_(91); 14817 14818var _toTitleCase2 = _interopRequireDefault(_toTitleCase); 14819 14820function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 14821 14822function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 14823 14824function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } 14825 14826function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 14827 14828function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 14829 14830function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
14830onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 14831 * @file html5.js 14832 */ 14833 14834 14835/** 14836 * HTML5 Media Controller - Wrapper for HTML5 Media API 14837 * 14838 * @mixes Tech~SouceHandlerAdditions 14839 * @extends Tech 14840 */ 14841var Html5 = function (_Tech) { 14842 _inherits(Html5, _Tech); 14843 14844 /** 14845 * Create an instance of this Tech. 14846 * 14847 * @param {Object} [options] 14848 * The key/value store of player options. 14849 * 14850 * @param {Component~ReadyCallback} ready 14851 * Callback function to call when the `HTML5` Tech is ready. 14852 */ 14853 function Html5(options, ready) { 14854 _classCallCheck(this, Html5); 14855 14856 var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready)); 14857 14858 var source = options.source; 14859 var crossoriginTracks = false; 14860 14861 // Set the source if one is provided 14862 // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted) 14863 // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source 14864 // anyway so the error gets fired. 14865 if (source && (_this.el_.currentSrc !== source.src || options.tag && options.tag.
14865initNetworkState_ === 3)) { 14866 _this.setSource(source); 14867 } else { 14868 _this.handleLateInit_(_this.el_); 14869 } 14870 14871 if (_this.el_.hasChildNodes()) { 14872 14873 var nodes = _this.el_.childNodes; 14874 var nodesLength = nodes.length; 14875 var removeNodes = []; 14876 14877 while (nodesLength--) { 14878 var node = nodes[nodesLength]; 14879 var nodeName = node.nodeName.toLowerCase(); 14880 14881 if (nodeName === 'track') { 14882 if (!_this.featuresNativeTextTracks) { 14883 // Empty video tag tracks so the built-in player doesn't use them also. 14884 // This may not be fast enough to stop HTML5 browsers from reading the tags 14885 // so we'll need to turn off any default tracks if we're manually doing 14886 // captions and subtitles. videoElement.textTracks 14887 removeNodes.push(node); 14888 } else { 14889 // store HTMLTrackElement and TextTrack to remote list 14890 _this.remoteTextTrackEls().addTrackElement_(node); 14891 _this.remoteTextTracks().addTrack_(node.track); 14892 if (!crossoriginTracks && !_this.el_.hasAttribute('crossorigin') && Url.isCrossOrigin(node.src)) { 14893 crossoriginTracks = true; 14894 } 14895 } 14896 } 14897 } 14898 14899 for (var i = 0; i < removeNodes.length; i++) { 14900 _this.el_.removeChild(removeNodes[i]); 14901 } 14902 } 14903 14904 // TODO: add text tracks into this list 14905 var trackTypes = ['audio', 'video']; 14906 14907 // ProxyNative Video/Audio Track 14908 trackTypes.forEach(function (type) { 14909 var elTracks = _this.el()[type + 'Tracks']; 14910 var techTracks = _this[type + 'Tracks'](); 14911 var capitalType = (0, _toTitleCase2['default'])(type); 14912 14913 if (!_this['featuresNative' + capitalType + 'Tracks'] || !elTracks || !elTracks.addEventListener) { 14914 return; 14915 } 14916 14917 _this['handle' + capitalType + 'TrackChange_'] = function (e) { 14918 techTracks.trigger({ 14919 type: 'change', 14920 target: techTracks, 14921 currentTarget: techTracks, 14922 srcElement: techTracks 14923 }); 14924 }; 14925 14926 _this['handle' + capitalType + 'TrackAdd_'] = function (e) { 14927 return techTracks.addTrack(e.track); 14928 }; 14929 _this['handle' + capitalType + 'TrackRemove_'] = function (e) { 14930 return techTracks.removeTrack(e.track); 14931 }; 14932 14933 elTracks.addEventListener('change', _this['handle' + capitalType + 'TrackChange_']); 14934 elTracks.addEventListener('addtrack', _this['handle' + capitalType + 'TrackAdd_']); 14935 elTracks.addEventListener('removetrack', _this['handle' + capitalType + 'TrackRemove_']); 14936 _this['removeOld' + capitalType + 'Tracks_'] = function (e) { 14937 return _this.removeOldTracks_(techTracks, elTracks); 14938 }; 14939 14940 // Remove (native) tracks that are not used anymore 14941 _this.on('loadstart', _this['removeOld' + capitalType + 'Tracks_']); 14942 }); 14943 14944 if (_this.featuresNativeTextTracks) { 14945 if (crossoriginTracks) { 14946 _log2['default'].warn((0, _tsml2['default'])(_templateObject)); 14947 } 14948 14949 _this.handleTextTrackChange_ = Fn.bind(_this, _this.handleTextTrackChange); 14950 _this.handleTextTrackAdd_ = Fn.bind(_this, _this.handleTextTrackAdd); 14951 _this.handleTextTrackRemove_ = Fn.bind(_this, _this.handleTextTrackRemove); 14952 _this.proxyNativeTextTracks_(); 14953 } 14954 14955 // Determine if native controls should be used 14956 // Our goal should be to get the custom controls on mobile solid everywhere 14957 // so we can remove this all together. Right now this will block custom 14958 // controls on touch enabled laptops like the Chrome Pixel 14959 if ((browser.TOUCH_ENABLED || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) && options.nativeControlsForTouch === true) { 14960 _this.setControls(true); 14961 } 14962 14963 // on iOS, we want to proxy `webkitbeginfullscreen` and `webkitendfullscreen` 14964 // into a `fullscreenchange` event 14965 _this.proxyWebkitFullscreen_(); 14966 14967 _this.triggerReady(); 14968 return _this; 14969 } 14970 14971 /** 14972 * Dispose of `HTML5` media element and remove all tracks. 14973 */ 14974 14975 14976 Html5.prototype.dispose = function dispose() { 14977 var _this2 = this; 14978 14979 // Un-ProxyNativeTracks 14980 ['audio', 'video', 'text'].forEach(function (type) { 14981 var capitalType = (0, _toTitleCase2['default'])(type); 14982 var tl = _this2.el_[type + 'Tracks']; 14983 14984 if (tl && tl.removeEventListener) { 14985 tl.removeEventListener('change', _this2['handle' + capitalType + 'TrackChange_']); 14986 tl.removeEventListener('addtrack', _this2['handle' + capitalType + 'TrackAdd_']); 14987 tl.removeEventListener('removetrack', _this2['handle' + capitalType + 'TrackRemove_']); 14988 } 14989 14990 // Stop removing old text tracks 14991 if (tl) { 14992 _this2.off('loadstart', _this2['removeOld' + capitalType + 'Tracks_']); 14993 } 14994 }); 14995 14996 Html5.disposeMediaElement(this.el_); 14997 // tech will handle clearing of the emulated track list 14998 _Tech.prototype.dispose.call(this); 14999 }; 15000 15001 /** 15002 * Create the `Html5` Tech's DOM element. 15003 * 15004 * @return {Element} 15005 * The element that gets created. 15006 */ 15007 15008 15009 Html5.prototype.createEl = function createEl() { 15010 var el = this.options_.tag; 15011 15012 // Check if this browser supports moving the element into the box. 15013 // On the iPhone video will break if you move the element, 15014 // So we have to create a brand new element. 15015 // If we ingested the player div, we do not need to move the media element. 15016 if (!el || !(this.options_.playerElIngest || this.movingMediaElementInDOM)) { 15017 15018 // If the original tag is still there, clone and remove it. 15019 if (el) { 15020 var clone = el.cloneNode(true); 15021 15022 if (el.parentNode) { 15023 el.parentNode.insertBefore(clone, el); 15024 } 15025 Html5.disposeMediaElement(el); 15026 el = clone; 15027 } else { 15028 el = _document2['default'].createElement('video'); 15029 15030 // determine if native controls should be used 15031 var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag); 15032 var attributes = (0, _mergeOptions2['default'])({}, tagAttributes); 15033 15034 if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) { 15035 delete attributes.controls; 15036 } 15037 15038 Dom.setElAttributes(el, (0, _obj.assign)(attributes, { 15039 id: this.options_.techId, 15040 'class': 'vjs-tech' 15041 })); 15042 } 15043 15044 el.playerId = this.options_.playerId; 15045 } 15046 15047 // Update specific tag settings, in case they were overridden 15048 var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted']; 15049 15050 for (var i = settingsAttrs.length - 1; i >= 0; i--) { 15051 var attr = settingsAttrs[i]; 15052 var overwriteAttrs = {}; 15053 15054 if (typeof this.options_[attr] !== 'undefined') { 15055 overwriteAttrs[attr] = this.options_[attr]; 15056 } 15057 Dom.setElAttributes(el, overwriteAttrs); 15058 } 15059 15060 return el; 15061 }; 15062 15063 /** 15064 * This will be triggered if the loadstart event has already fired, before videojs was 15065 * ready. Two known examples of when this can happen are: 15066 * 1. If we're loading the playback object after it has started loading 15067 * 2. The media is already playing the (often with autoplay on) then 15068 * 15069 * This function will fire another loadstart so that videojs can catchup. 15070 * 15071 * @fires Tech#loadstart 15072 * 15073 * @return {undefined} 15074 * returns nothing. 15075 */ 15076 15077 15078 Html5.prototype.handleLateInit_ = function handleLateInit_(el) { 15079 if (el.networkState === 0 || el.networkState === 3) { 15080 // The video element hasn't started loading the source yet 15081 // or didn't find a source 15082 return; 15083 } 15084 15085 if (el.readyState === 0) { 15086 // NetworkState is set synchronously BUT loadstart is fired at the 15087 // end of the current stack, usually before setInterval(fn, 0). 15088 // So at this point we know loadstart may have already fired or is 15089 // about to fire, and either way the player hasn't seen it yet. 15090 // We don't want to fire loadstart prematurely here and cause a 15091 // double loadstart so we'll wait and see if it happens between now 15092 // and the next loop, and fire it if not. 15093 // HOWEVER, we also want to make sure it fires before loadedmetadata 15094 // which could also happen between now and the next loop, so we'll 15095 // watch for that also. 15096 var loadstartFired = false;
vendor: 4,620 bytes, lines 15097-15259
15097 var setLoadstartFired = function setLoadstartFired() { 15098 loadstartFired = true; 15099 }; 15100 15101 this.on('loadstart', setLoadstartFired); 15102 15103 var triggerLoadstart = function triggerLoadstart() { 15104 // We did miss the original loadstart. Make sure the player 15105 // sees loadstart before loadedmetadata 15106 if (!loadstartFired) { 15107 this.trigger('loadstart'); 15108 } 15109 }; 15110 15111 this.on('loadedmetadata', triggerLoadstart); 15112 15113 this.ready(function () { 15114 this.off('loadstart', setLoadstartFired); 15115 this.off('loadedmetadata', triggerLoadstart); 15116 15117 if (!loadstartFired) { 15118 // We did miss the original native loadstart. Fire it now. 15119 this.trigger('loadstart'); 15120 } 15121 }); 15122 15123 return; 15124 } 15125 15126 // From here on we know that loadstart already fired and we missed it. 15127 // The other readyState events aren't as much of a problem if we double 15128 // them, so not going to go to as much trouble as loadstart to prevent 15129 // that unless we find reason to. 15130 var eventsToTrigger = ['loadstart']; 15131 15132 // loadedmetadata: newly equal to HAVE_METADATA (1) or greater 15133 eventsToTrigger.push('loadedmetadata'); 15134 15135 // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater 15136 if (el.readyState >= 2) { 15137 eventsToTrigger.push('loadeddata'); 15138 } 15139 15140 // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater 15141 if (el.readyState >= 3) { 15142 eventsToTrigger.push('canplay'); 15143 } 15144 15145 // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4) 15146 if (el.readyState >= 4) { 15147 eventsToTrigger.push('canplaythrough'); 15148 } 15149 15150 // We still need to give the player time to add event listeners 15151 this.ready(function () { 15152 eventsToTrigger.forEach(function (type) { 15153 this.trigger(type); 15154 }, this); 15155 }); 15156 }; 15157 15158 /** 15159 * Add event listeners to native text track events. This adds the native text tracks 15160 * to our emulated {@link TextTrackList}. 15161 */ 15162 15163 15164 Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() { 15165 var tt = this.el().textTracks; 15166 15167 if (tt) { 15168 // Add tracks - if player is initialised after DOM loaded, textTracks 15169 // will not trigger addtrack 15170 for (var i = 0; i < tt.length; i++) { 15171 this.textTracks().addTrack_(tt[i]); 15172 } 15173 15174 if (tt.addEventListener) { 15175 tt.addEventListener('change', this.handleTextTrackChange_); 15176 tt.addEventListener('addtrack', this.handleTextTrackAdd_); 15177 tt.addEventListener('removetrack', this.handleTextTrackRemove_); 15178 } 15179 15180 // Remove (native) texttracks that are not used anymore 15181 this.on('loadstart', this.removeOldTextTracks_); 15182 } 15183 }; 15184 15185 /** 15186 * Handle any {@link TextTrackList} `change` event. 15187 * 15188 * @param {EventTarget~Event} e 15189 * The `change` event that caused this to run. 15190 * 15191 * @listens TextTrackList#change 15192 */ 15193 15194 15195 Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) { 15196 var tt = this.textTracks(); 15197 15198 this.textTracks().trigger({ 15199 type: 'change', 15200 target: tt, 15201 currentTarget: tt, 15202 srcElement: tt 15203 }); 15204 }; 15205 15206 /** 15207 * Handle any {@link TextTrackList} `addtrack` event. 15208 * 15209 * @param {EventTarget~Event} e 15210 * The `addtrack` event that caused this to run. 15211 * 15212 * @listens TextTrackList#addtrack 15213 */ 15214 15215 15216 Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) { 15217 this.textTracks().addTrack_(e.track); 15218 }; 15219 15220 /** 15221 * Handle any {@link TextTrackList} `removetrack` event. 15222 * 15223 * @param {EventTarget~Event} e 15224 * The `removetrack` event that caused this to run. 15225 * 15226 * @listens TextTrackList#removetrack 15227 */ 15228 15229 15230 Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) { 15231 this.textTracks().removeTrack_(e.track); 15232 }; 15233 15234 /** 15235 * This function removes any {@link AudioTrack}s, {@link VideoTrack}s, or 15236 * {@link TextTrack}s that are not in the media elements TrackList. 15237 * 15238 * @param {TrackList} techTracks 15239 * HTML5 Tech's TrackList to search through 15240 * 15241 * @param {TrackList} elTracks 15242 * HTML5 media elements TrackList to search trough. 15243 * 15244 * @private 15245 */ 15246 15247 15248 Html5.prototype.removeOldTracks_ = function removeOldTracks_(techTracks, elTracks) { 15249 // This will loop over the techTracks and check if they are still used by the HTML5 media element 15250 // If not, they will be removed from the emulated list 15251 var removeTracks = []; 15252 15253 if (!elTracks) { 15254 return; 15255 } 15256 15257 for (var i = 0; i < techTracks.length; i++) { 15258 var techTrack = techTracks[i]; 15259 var found = false;
15260 15261 for (var j = 0; j < elTracks.length; j++) { 15262 if (elTracks[j] === techTrack) { 15263 found = true; 15264 break; 15265 } 15266 } 15267 15268 if (!found) { 15269 removeTracks.push(techTrack); 15270 } 15271 } 15272 15273 for (var _i = 0; _i < removeTracks.length; _i++) { 15274 var track = removeTracks[_i]; 15275 15276 techTracks.removeTrack_(track); 15277 } 15278 }; 15279 15280 /** 15281 * Remove {@link TextTrack}s that dont exist in the native track list from our 15282 * emulated {@link TextTrackList}. 15283 * 15284 * @listens Tech#loadstart 15285 */ 15286 15287 15288 Html5.prototype.removeOldTextTracks_ = function removeOldTextTracks_(e) { 15289 var techTracks = this.textTracks(); 15290 var elTracks = this.el().textTracks; 15291 15292 this.removeOldTracks_(techTracks, elTracks); 15293 }; 15294 15295 /** 15296 * Called by {@link Player#play} to play using the `Html5` `Tech`. 15297 */ 15298 15299 15300 Html5.prototype.play = function play() { 15301 var playPromise = this.el_.play(); 15302 15303 // Catch/silence error when a pause interrupts a play request 15304 // on browsers which return a promise 15305 if (playPromise !== undefined && typeof playPromise.then === 'function') { 15306 playPromise.then(null, function (e) {}); 15307 } 15308 }; 15309 15310 /** 15311 * Set current time for the `HTML5` tech. 15312 * 15313 * @param {number} seconds 15314 * Set the current time of the media to this. 15315 */ 15316 15317 15318 Html5.prototype.setCurrentTime = function setCurrentTime(seconds) { 15319 try { 15320 this.el_.currentTime = seconds; 15321 } catch (e) { 15322 (0, _log2['default'])(e, 'Video is not ready. (Video.js)'); 15323 // this.warning(VideoJS.warnings.videoNotReady); 15324 } 15325 }; 15326 15327 /** 15328 * Get the current duration of the HTML5 media element. 15329 * 15330 * @return {number} 15331 * The duration of the media or 0 if there is no duration. 15332 */ 15333 15334 15335 Html5.prototype.duration = function duration() { 15336 var _this3 = this; 15337 15338 // Android Chrome will report duration as Infinity for VOD HLS until after 15339 // playback has started, which triggers the live display erroneously. 15340 // Return NaN if playback has not started and trigger a durationupdate once 15341 // the duration can be reliably known. 15342 if (this.el_.duration === Infinity && browser.IS_ANDROID && browser.IS_CHROME) { 15343 if (this.el_.currentTime === 0) { 15344 // Wait for the first `timeupdate` with currentTime > 0 - there may be 15345 // several with 0 15346 var checkProgress = function checkProgress() { 15347 if (_this3.el_.currentTime > 0) { 15348 // Trigger durationchange for genuinely live video 15349 if (_this3.el_.duration === Infinity) { 15350 _this3.trigger('durationchange'); 15351 } 15352 _this3.off('timeupdate', checkProgress); 15353 } 15354 }; 15355 15356 this.on('timeupdate', checkProgress); 15357 return NaN; 15358 } 15359 } 15360 return this.el_.duration || NaN; 15361 }; 15362 15363 /** 15364 * Get the current width of the HTML5 media element. 15365 * 15366 * @return {number} 15367 * The width of the HTML5 media element. 15368 */ 15369 15370 15371 Html5.prototype.width = function width() { 15372 return this.el_.offsetWidth; 15373 }; 15374 15375 /** 15376 * Get the current height of the HTML5 media element. 15377 * 15378 * @return {number} 15379 * The heigth of the HTML5 media element. 15380 */ 15381 15382 15383 Html5.prototype.height = function height() { 15384 return this.el_.offsetHeight; 15385 }; 15386 15387 /** 15388 * Proxy iOS `webkitbeginfullscreen` and `webkitendfullscreen` into 15389 * `fullscreenchange` event. 15390 * 15391 * @private 15392 * @fires fullscreenchange 15393 * @listens webkitendfullscreen 15394 * @listens webkitbeginfullscreen 15395 * @listens webkitbeginfullscreen 15396 */ 15397 15398 15399 Html5.prototype.proxyWebkitFullscreen_ = function proxyWebkitFullscreen_() { 15400 var _this4 = this; 15401 15402 if (!('webkitDisplayingFullscreen' in this.el_)) { 15403 return; 15404 } 15405 15406 var endFn = function endFn() { 15407 this.trigger('fullscreenchange', { isFullscreen: false }); 15408 }; 15409 15410 var beginFn = function beginFn() { 15411 this.one('webkitendfullscreen', endFn); 15412 15413 this.trigger('fullscreenchange', { isFullscreen: true }); 15414 }; 15415 15416 this.on('webkitbeginfullscreen', beginFn); 15417 this.on('dispose', function () { 15418 _this4.off('webkitbeginfullscreen', beginFn); 15419 _this4.off('webkitendfullscreen', endFn); 15420 }); 15421 }; 15422 15423 /** 15424 * Check if fullscreen is supported on the current playback device. 15425 * 15426 * @return {boolean} 15427 * - True if fullscreen is supported. 15428 * - False if fullscreen is not supported. 15429 */ 15430 15431 15432 Html5.prototype.supportsFullScreen = function supportsFullScreen() { 15433 if (typeof this.el_.webkitEnterFullScreen === 'function') { 15434 var userAgent = _window2['default'].navigator && _window2['default'].navigator.userAgent || ''; 15435 15436 // Seems to be broken in Chromium/Chrome && Safari in Leopard 15437 if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) { 15438 return true; 15439 } 15440 } 15441 return false;
vendor: 22,527 bytes, lines 15442-16192
15442 }; 15443 15444 /** 15445 * Request that the `HTML5` Tech enter fullscreen. 15446 */ 15447 15448 15449 Html5.prototype.enterFullScreen = function enterFullScreen() { 15450 var video = this.el_; 15451 15452 if (video.paused && video.networkState <= video.HAVE_METADATA) { 15453 // attempt to prime the video element for programmatic access 15454 // this isn't necessary on the desktop but shouldn't hurt 15455 this.el_.play(); 15456 15457 // playing and pausing synchronously during the transition to fullscreen 15458 // can get iOS ~6.1 devices into a play/pause loop 15459 this.setTimeout(function () { 15460 video.pause(); 15461 video.webkitEnterFullScreen(); 15462 }, 0); 15463 } else { 15464 video.webkitEnterFullScreen(); 15465 } 15466 }; 15467 15468 /** 15469 * Request that the `HTML5` Tech exit fullscreen. 15470 */ 15471 15472 15473 Html5.prototype.exitFullScreen = function exitFullScreen() { 15474 this.el_.webkitExitFullScreen(); 15475 }; 15476 15477 /** 15478 * A getter/setter for the `Html5` Tech's source object. 15479 * > Note: Please use {@link Html5#setSource} 15480 * 15481 * @param {Tech~SourceObject} [src] 15482 * The source object you want to set on the `HTML5` techs element. 15483 * 15484 * @return {Tech~SourceObject|undefined} 15485 * - The current source object when a source is not passed in. 15486 * - undefined when setting 15487 * 15488 * @deprecated Since version 5. 15489 */ 15490 15491 15492 Html5.prototype.src = function src(_src) { 15493 if (_src === undefined) { 15494 return this.el_.src; 15495 } 15496 15497 // Setting src through `src` instead of `setSrc` will be deprecated 15498 this.setSrc(_src); 15499 }; 15500 15501 /** 15502 * Reset the tech by removing all sources and then calling 15503 * {@link Html5.resetMediaElement}. 15504 */ 15505 15506 15507 Html5.prototype.reset = function reset() { 15508 Html5.resetMediaElement(this.el_); 15509 }; 15510 15511 /** 15512 * Get the current source on the `HTML5` Tech. Falls back to returning the source from 15513 * the HTML5 media element. 15514 * 15515 * @return {Tech~SourceObject} 15516 * The current source object from the HTML5 tech. With a fallback to the 15517 * elements source. 15518 */ 15519 15520 15521 Html5.prototype.currentSrc = function currentSrc() { 15522 if (this.currentSource_) { 15523 return this.currentSource_.src; 15524 } 15525 return this.el_.currentSrc; 15526 }; 15527 15528 /** 15529 * Set controls attribute for the HTML5 media Element. 15530 * 15531 * @param {string} val 15532 * Value to set the controls attribute to 15533 */ 15534 15535 15536 Html5.prototype.setControls = function setControls(val) { 15537 this.el_.controls = !!val; 15538 }; 15539 15540 /** 15541 * Create and returns a remote {@link TextTrack} object. 15542 * 15543 * @param {string} kind 15544 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata) 15545 * 15546 * @param {string} [label] 15547 * Label to identify the text track 15548 * 15549 * @param {string} [language] 15550 * Two letter language abbreviation 15551 * 15552 * @return {TextTrack} 15553 * The TextTrack that gets created. 15554 */ 15555 15556 15557 Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) { 15558 if (!this.featuresNativeTextTracks) { 15559 return _Tech.prototype.addTextTrack.call(this, kind, label, language); 15560 } 15561 15562 return this.el_.addTextTrack(kind, label, language); 15563 }; 15564 15565 /** 15566 * Creates either native TextTrack or an emulated TextTrack depending 15567 * on the value of `featuresNativeTextTracks` 15568 * 15569 * @param {Object} options 15570 * The object should contain the options to intialize the TextTrack with. 15571 * 15572 * @param {string} [options.kind] 15573 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata). 15574 * 15575 * @param {string} [options.label]. 15576 * Label to identify the text track 15577 * 15578 * @param {string} [options.language] 15579 * Two letter language abbreviation. 15580 * 15581 * @param {boolean} [options.default] 15582 * Default this track to on. 15583 * 15584 * @param {string} [options.id] 15585 * The internal id to assign this track. 15586 * 15587 * @param {string} [options.src] 15588 * A source url for the track. 15589 * 15590 * @return {HTMLTrackElement} 15591 * The track element that gets created. 15592 */ 15593 15594 15595 Html5.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) { 15596 if (!this.featuresNativeTextTracks) { 15597 return _Tech.prototype.createRemoteTextTrack.call(this, options); 15598 } 15599 var htmlTrackElement = _document2['default'].createElement('track'); 15600 15601 if (options.kind) { 15602 htmlTrackElement.kind = options.kind; 15603 } 15604 if (options.label) { 15605 htmlTrackElement.label = options.label; 15606 } 15607 if (options.language || options.srclang) { 15608 htmlTrackElement.srclang = options.language || options.srclang; 15609 } 15610 if (options['default']) { 15611 htmlTrackElement['default'] = options['default']; 15612 } 15613 if (options.id) { 15614 htmlTrackElement.id = options.id; 15615 } 15616 if (options.src) { 15617 htmlTrackElement.src = options.src; 15618 } 15619 15620 return htmlTrackElement; 15621 }; 15622 15623 /** 15624 * Creates a remote text track object and returns an html track element. 15625 * 15626 * @param {Object} options The object should contain values for 15627 * kind, language, label, and src (location of the WebVTT file) 15628 * @param {Boolean} [manualCleanup=true] if set to false, the TextTrack will be 15629 * automatically removed from the video element whenever the source changes 15630 * @return {HTMLTrackElement} An Html Track Element. 15631 * This can be an emulated {@link HTMLTrackElement} or a native one. 15632 * @deprecated The default value of the "manualCleanup" parameter will default 15633 * to "false" in upcoming versions of Video.js 15634 */ 15635 15636 15637 Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) { 15638 var htmlTrackElement = _Tech.prototype.addRemoteTextTrack.call(this, options, manualCleanup); 15639 15640 if (this.featuresNativeTextTracks) { 15641 this.el().appendChild(htmlTrackElement); 15642 } 15643 15644 return htmlTrackElement; 15645 }; 15646 15647 /** 15648 * Remove remote `TextTrack` from `TextTrackList` object 15649 * 15650 * @param {TextTrack} track 15651 * `TextTrack` object to remove 15652 */ 15653 15654 15655 Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) { 15656 _Tech.prototype.removeRemoteTextTrack.call(this, track); 15657 15658 if (this.featuresNativeTextTracks) { 15659 var tracks = this.$$('track'); 15660 15661 var i = tracks.length; 15662 15663 while (i--) { 15664 if (track === tracks[i] || track === tracks[i].track) { 15665 this.el().removeChild(tracks[i]); 15666 } 15667 } 15668 } 15669 }; 15670 15671 return Html5; 15672}(_tech2['default']); 15673 15674/* HTML5 Support Testing ---------------------------------------------------- */ 15675 15676if (Dom.isReal()) { 15677 15678 /** 15679 * Element for testing browser HTML5 media capabilities 15680 * 15681 * @type {Element} 15682 * @constant 15683 * @private 15684 */ 15685 Html5.TEST_VID = _document2['default'].createElement('video'); 15686 var track = _document2['default'].createElement('track'); 15687 15688 track.kind = 'captions'; 15689 track.srclang = 'en'; 15690 track.label = 'English'; 15691 Html5.TEST_VID.appendChild(track); 15692} 15693 15694/** 15695 * Check if HTML5 media is supported by this browser/device. 15696 * 15697 * @return {boolean} 15698 * - True if HTML5 media is supported. 15699 * - False if HTML5 media is not supported. 15700 */ 15701Html5.isSupported = function () { 15702 // IE9 with no Media Player is a LIAR! (#984) 15703 try { 15704 Html5.TEST_VID.volume = 0.5; 15705 } catch (e) { 15706 return false; 15707 } 15708 15709 return !!(Html5.TEST_VID && Html5.TEST_VID.canPlayType); 15710}; 15711 15712/** 15713 * Check if the volume can be changed in this browser/device. 15714 * Volume cannot be changed in a lot of mobile devices. 15715 * Specifically, it can't be changed from 1 on iOS. 15716 * 15717 * @return {boolean} 15718 * - True if volume can be controlled 15719 * - False otherwise 15720 */ 15721Html5.canControlVolume = function () { 15722 // IE will error if Windows Media Player not installed #3315 15723 try { 15724 var volume = Html5.TEST_VID.volume; 15725 15726 Html5.TEST_VID.volume = volume / 2 + 0.1; 15727 return volume !== Html5.TEST_VID.volume; 15728 } catch (e) { 15729 return false; 15730 } 15731}; 15732 15733/** 15734 * Check if the playback rate can be changed in this browser/device. 15735 * 15736 * @return {boolean} 15737 * - True if playback rate can be controlled 15738 * - False otherwise 15739 */ 15740Html5.canControlPlaybackRate = function () { 15741 // Playback rate API is implemented in Android Chrome, but doesn't do anything 15742 // https://github.com/videojs/video.js/issues/3180 15743 if (browser.IS_ANDROID && browser.IS_CHROME) { 15744 return false; 15745 } 15746 // IE will error if Windows Media Player not installed #3315 15747 try { 15748 var playbackRate = Html5.TEST_VID.playbackRate; 15749 15750 Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1; 15751 return playbackRate !== Html5.TEST_VID.playbackRate; 15752 } catch (e) { 15753 return false; 15754 } 15755}; 15756 15757/** 15758 * Check to see if native `TextTrack`s are supported by this browser/device. 15759 * 15760 * @return {boolean} 15761 * - True if native `TextTrack`s are supported. 15762 * - False otherwise 15763 */ 15764Html5.supportsNativeTextTracks = function () { 15765 return browser.IS_ANY_SAFARI; 15766}; 15767 15768/** 15769 * Check to see if native `VideoTrack`s are supported by this browser/device 15770 * 15771 * @return {boolean} 15772 * - True if native `VideoTrack`s are supported. 15773 * - False otherwise 15774 */ 15775Html5.supportsNativeVideoTracks = function () { 15776 return !!(Html5.TEST_VID && Html5.TEST_VID.videoTracks); 15777}; 15778 15779/** 15780 * Check to see if native `AudioTrack`s are supported by this browser/device 15781 * 15782 * @return {boolean} 15783 * - True if native `AudioTrack`s are supported. 15784 * - False otherwise 15785 */ 15786Html5.supportsNativeAudioTracks = function () { 15787 return !!(Html5.TEST_VID && Html5.TEST_VID.audioTracks); 15788}; 15789 15790/** 15791 * An array of events available on the Html5 tech. 15792 * 15793 * @private 15794 * @type {Array} 15795 */ 15796Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange']; 15797 15798/** 15799 * Boolean indicating whether the `Tech` supports volume control. 15800 * 15801 * @type {boolean} 15802 * @default {@link Html5.canControlVolume} 15803 */ 15804Html5.prototype.featuresVolumeControl = Html5.canControlVolume(); 15805 15806/** 15807 * Boolean indicating whether the `Tech` supports changing the speed at which the media 15808 * plays. Examples: 15809 * - Set player to play 2x (twice) as fast 15810 * - Set player to play 0.5x (half) as fast 15811 * 15812 * @type {boolean} 15813 * @default {@link Html5.canControlPlaybackRate} 15814 */ 15815Html5.prototype.featuresPlaybackRate = Html5.canControlPlaybackRate(); 15816 15817/** 15818 * Boolean indicating whether the `HTML5` tech currently supports the media element 15819 * moving in the DOM. iOS breaks if you move the media element, so this is set this to 15820 * false there. Everywhere else this should be true. 15821 * 15822 * @type {boolean} 15823 * @default 15824 */ 15825Html5.prototype.movingMediaElementInDOM = !browser.IS_IOS; 15826 15827// TODO: Previous comment: No longer appears to be used. Can probably be removed. 15828// Is this true? 15829/** 15830 * Boolean indicating whether the `HTML5` tech currently supports automatic media resize 15831 * when going into fullscreen. 15832 * 15833 * @type {boolean} 15834 * @default 15835 */ 15836Html5.prototype.featuresFullscreenResize = true; 15837 15838/** 15839 * Boolean indicating whether the `HTML5` tech currently supports the progress event. 15840 * If this is false, manual `progress` events will be triggred instead. 15841 * 15842 * @type {boolean} 15843 * @default 15844 */ 15845Html5.prototype.featuresProgressEvents = true; 15846 15847/** 15848 * Boolean indicating whether the `HTML5` tech currently supports the timeupdate event. 15849 * If this is false, manual `timeupdate` events will be triggred instead. 15850 * 15851 * @default 15852 */ 15853Html5.prototype.featuresTimeupdateEvents = true; 15854 15855/** 15856 * Boolean indicating whether the `HTML5` tech currently supports native `TextTrack`s. 15857 * 15858 * @type {boolean} 15859 * @default {@link Html5.supportsNativeTextTracks} 15860 */ 15861Html5.prototype.featuresNativeTextTracks = Html5.supportsNativeTextTracks(); 15862 15863/** 15864 * Boolean indicating whether the `HTML5` tech currently supports native `VideoTrack`s. 15865 * 15866 * @type {boolean} 15867 * @default {@link Html5.supportsNativeVideoTracks} 15868 */ 15869Html5.prototype.featuresNativeVideoTracks = Html5.supportsNativeVideoTracks(); 15870 15871/** 15872 * Boolean indicating whether the `HTML5` tech currently supports native `AudioTrack`s. 15873 * 15874 * @type {boolean} 15875 * @default {@link Html5.supportsNativeAudioTracks} 15876 */ 15877Html5.prototype.featuresNativeAudioTracks = Html5.supportsNativeAudioTracks(); 15878 15879// HTML5 Feature detection and Device Fixes --------------------------------- // 15880var canPlayType = Html5.TEST_VID && Html5.TEST_VID.constructor.prototype.canPlayType; 15881var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i; 15882var mp4RE = /^video\/mp4/i; 15883 15884Html5.patchCanPlayType = function () { 15885 15886 // Android 4.0 and above can play HLS to some extent but it reports being unable to do so 15887 if (browser.ANDROID_VERSION >= 4.0 && !browser.IS_FIREFOX) { 15888 Html5.TEST_VID.constructor.prototype.canPlayType = function (type) { 15889 if (type && mpegurlRE.test(type)) { 15890 return 'maybe'; 15891 } 15892 return canPlayType.call(this, type); 15893 }; 15894 15895 // Override Android 2.2 and less canPlayType method which is broken 15896 } else if (browser.IS_OLD_ANDROID) { 15897 Html5.TEST_VID.constructor.prototype.canPlayType = function (type) { 15898 if (type && mp4RE.test(type)) { 15899 return 'maybe'; 15900 } 15901 return canPlayType.call(this, type); 15902 }; 15903 } 15904}; 15905 15906Html5.unpatchCanPlayType = function () { 15907 var r = Html5.TEST_VID.constructor.prototype.canPlayType; 15908 15909 Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType; 15910 return r; 15911}; 15912 15913// by default, patch the media element 15914Html5.patchCanPlayType(); 15915 15916Html5.disposeMediaElement = function (el) { 15917 if (!el) { 15918 return; 15919 } 15920 15921 if (el.parentNode) { 15922 el.parentNode.removeChild(el); 15923 } 15924 15925 // remove any child track or source nodes to prevent their loading 15926 while (el.hasChildNodes()) { 15927 el.removeChild(el.firstChild); 15928 } 15929 15930 // remove any src reference. not setting `src=''` because that causes a warning 15931 // in firefox 15932 el.removeAttribute('src'); 15933 15934 // force the media element to update its loading state by calling load() 15935 // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793) 15936 if (typeof el.load === 'function') { 15937 // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473) 15938 (function () { 15939 try { 15940 el.load(); 15941 } catch (e) { 15942 // not supported 15943 } 15944 })(); 15945 } 15946}; 15947 15948Html5.resetMediaElement = function (el) { 15949 if (!el) { 15950 return; 15951 } 15952 15953 var sources = el.querySelectorAll('source'); 15954 var i = sources.length; 15955 15956 while (i--) { 15957 el.removeChild(sources[i]); 15958 } 15959 15960 // remove any src reference. 15961 // not setting `src=''` because that throws an error 15962 el.removeAttribute('src'); 15963 15964 if (typeof el.load === 'function') { 15965 // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473) 15966 (function () { 15967 try { 15968 el.load(); 15969 } catch (e) { 15970 // satisfy linter 15971 } 15972 })(); 15973 } 15974}; 15975 15976/* Native HTML5 element property wrapping ----------------------------------- */ 15977// Wrap native properties with a getter 15978[ 15979/** 15980 * Get the value of `paused` from the media element. `paused` indicates whether the media element 15981 * is currently paused or not. 15982 * 15983 * @method Html5#paused 15984 * @return {boolean} 15985 * The value of `paused` from the media element. 15986 * 15987 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-paused} 15988 */ 15989'paused', 15990 15991/** 15992 * Get the value of `currentTime` from the media element. `currentTime` indicates 15993 * the current second that the media is at in playback. 15994 * 15995 * @method Html5#currentTime 15996 * @return {number} 15997 * The value of `currentTime` from the media element. 15998 * 15999 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-currenttime} 16000 */ 16001'currentTime', 16002 16003/** 16004 * Get the value of `buffered` from the media element. `buffered` is a `TimeRange` 16005 * object that represents the parts of the media that are already downloaded and 16006 * available for playback. 16007 * 16008 * @method Html5#buffered 16009 * @return {TimeRange} 16010 * The value of `buffered` from the media element. 16011 * 16012 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-buffered} 16013 */ 16014'buffered', 16015 16016/** 16017 * Get the value of `volume` from the media element. `volume` indicates 16018 * the current playback volume of audio for a media. `volume` will be a value from 0 16019 * (silent) to 1 (loudest and default). 16020 * 16021 * @method Html5#volume 16022 * @return {number} 16023 * The value of `volume` from the media element. Value will be between 0-1. 16024 * 16025 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume} 16026 */ 16027'volume', 16028 16029/** 16030 * Get the value of `muted` from the media element. `muted` indicates 16031 * that the volume for the media should be set to silent. This does not actually change 16032 * the `volume` attribute. 16033 * 16034 * @method Html5#muted 16035 * @return {boolean} 16036 * - True if the value of `volume` should be ignored and the audio set to silent. 16037 * - False if the value of `volume` should be used. 16038 * 16039 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted} 16040 */ 16041'muted', 16042 16043/** 16044 * Get the value of `poster` from the media element. `poster` indicates 16045 * that the url of an image file that can/will be shown when no media data is available. 16046 * 16047 * @method Html5#poster 16048 * @return {string} 16049 * The value of `poster` from the media element. Value will be a url to an 16050 * image. 16051 * 16052 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-video-poster} 16053 */ 16054'poster', 16055 16056/** 16057 * Get the value of `preload` from the media element. `preload` indicates 16058 * what should download before the media is interacted with. It can have the following 16059 * values: 16060 * - none: nothing should be downloaded 16061 * - metadata: poster and the first few frames of the media may be downloaded to get 16062 * media dimensions and other metadata 16063 * - auto: allow the media and metadata for the media to be downloaded before 16064 * interaction 16065 * 16066 * @method Html5#preload 16067 * @return {string} 16068 * The value of `preload` from the media element. Will be 'none', 'metadata', 16069 * or 'auto'. 16070 * 16071 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload} 16072 */ 16073'preload', 16074 16075/** 16076 * Get the value of `autoplay` from the media element. `autoplay` indicates 16077 * that the media should start to play as soon as the page is ready. 16078 * 16079 * @method Html5#autoplay 16080 * @return {boolean} 16081 * - The value of `autoplay` from the media element. 16082 * - True indicates that the media should start as soon as the page loads. 16083 * - False indicates that the media should not start as soon as the page loads. 16084 * 16085 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay} 16086 */ 16087'autoplay', 16088 16089/** 16090 * Get the value of `controls` from the media element. `controls` indicates 16091 * whether the native media controls should be shown or hidden. 16092 * 16093 * @method Html5#controls 16094 * @return {boolean} 16095 * - The value of `controls` from the media element. 16096 * - True indicates that native controls should be showing. 16097 * - False indicates that native controls should be hidden. 16098 * 16099 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-controls} 16100 */ 16101'controls', 16102 16103/** 16104 * Get the value of `loop` from the media element. `loop` indicates 16105 * that the media should return to the start of the media and continue playing once 16106 * it reaches the end. 16107 * 16108 * @method Html5#loop 16109 * @return {boolean} 16110 * - The value of `loop` from the media element. 16111 * - True indicates that playback should seek back to start once 16112 * the end of a media is reached. 16113 * - False indicates that playback should not loop back to the start when the 16114 * end of the media is reached. 16115 * 16116 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop} 16117 */ 16118'loop', 16119 16120/** 16121 * Get the value of the `error` from the media element. `error` indicates any 16122 * MediaError that may have occured during playback. If error returns null there is no 16123 * current error. 16124 * 16125 * @method Html5#error 16126 * @return {MediaError|null} 16127 * The value of `error` from the media element. Will be `MediaError` if there 16128 * is a current error and null otherwise. 16129 * 16130 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-error} 16131 */ 16132'error', 16133 16134/** 16135 * Get the value of `seeking` from the media element. `seeking` indicates whether the 16136 * media is currently seeking to a new position or not. 16137 * 16138 * @method Html5#seeking 16139 * @return {boolean} 16140 * - The value of `seeking` from the media element. 16141 * - True indicates that the media is currently seeking to a new position. 16142 * - Flase indicates that the media is not seeking to a new position at this time. 16143 * 16144 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seeking} 16145 */ 16146'seeking', 16147 16148/** 16149 * Get the value of `seekable` from the media element. `seekable` returns a 16150 * `TimeRange` object indicating ranges of time that can currently be `seeked` to. 16151 * 16152 * @method Html5#seekable 16153 * @return {TimeRange} 16154 * The value of `seekable` from the media element. A `TimeRange` object 16155 * indicating the current ranges of time that can be seeked to. 16156 * 16157 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seekable} 16158 */ 16159'seekable', 16160 16161/** 16162 * Get the value of `ended` from the media element. `ended` indicates whether 16163 * the media has reached the end or not. 16164 * 16165 * @method Html5#ended 16166 * @return {boolean} 16167 * - The value of `ended` from the media element. 16168 * - True indicates that the media has ended. 16169 * - False indicates that the media has not ended. 16170 * 16171 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended} 16172 */ 16173'ended', 16174 16175/** 16176 * Get the value of `defaultMuted` from the media element. `defaultMuted` indicates 16177 * whether the media should start muted or not. Only changes the default state of the 16178 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the 16179 * current state. 16180 * 16181 * @method Html5#defaultMuted 16182 * @return {boolean} 16183 * - The value of `defaultMuted` from the media element. 16184 * - True indicates that the media should start muted. 16185 * - False indicates that the media should not start muted 16186 * 16187 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted} 16188 */ 16189'defaultMuted', 16190 16191/** 16192 * Get the value of `playbackRate` from the media element. `playbackRate` indicates
16193 * the rate at which the media is currently playing back. Examples: 16194 * - if playbackRate is set to 2, media will play twice as fast. 16195 * - if playbackRate is set to 0.5, media will play half as fast. 16196 * 16197 * @method Html5#playbackRate 16198 * @return {number} 16199 * The value of `playbackRate` from the media element. A number indicating 16200 * the current playback speed of the media, where 1 is normal speed. 16201 * 16202 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate} 16203 */ 16204'playbackRate', 16205 16206/** 16207 * Get the value of `played` from the media element. `played` returns a `TimeRange` 16208 * object representing points in the media timeline that have been played. 16209 * 16210 * @method Html5#played 16211 * @return {TimeRange} 16212 * The value of `played` from the media element. A `TimeRange` object indicating 16213 * the ranges of time that have been played. 16214 * 16215 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-played} 16216 */ 16217'played', 16218 16219/** 16220 * Get the value of `networkState` from the media element. `networkState` indicates 16221 * the current network state. It returns an enumeration from the following list: 16222 * - 0: NETWORK_EMPTY 16223 * - 1: NEWORK_IDLE 16224 * - 2: NETWORK_LOADING 16225 * - 3: NETWORK_NO_SOURCE 16226 * 16227 * @method Html5#networkState 16228 * @return {number} 16229 * The value of `networkState` from the media element. This will be a number 16230 * from the list in the description. 16231 * 16232 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-networkstate} 16233 */ 16234'networkState', 16235 16236/** 16237 * Get the value of `readyState` from the media element. `readyState` indicates 16238 * the current state of the media element. It returns an enumeration from the 16239 * following list: 16240 * - 0: HAVE_NOTHING 16241 * - 1: HAVE_METADATA 16242 * - 2: HAVE_CURRENT_DATA 16243 * - 3: HAVE_FUTURE_DATA 16244 * - 4: HAVE_ENOUGH_DATA 16245 * 16246 * @method Html5#readyState 16247 * @return {number} 16248 * The value of `readyState` from the media element. This will be a number 16249 * from the list in the description. 16250 * 16251 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#ready-states} 16252 */ 16253'readyState', 16254 16255/** 16256 * Get the value of `videoWidth` from the video element. `videoWidth` indicates 16257 * the current width of the video in css pixels. 16258 * 16259 * @method Html5#videoWidth 16260 * @return {number} 16261 * The value of `videoWidth` from the video element. This will be a number 16262 * in css pixels. 16263 * 16264 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth} 16265 */ 16266'videoWidth', 16267 16268/** 16269 * Get the value of `videoHeight` from the video element. `videoHeigth` indicates 16270 * the current height of the video in css pixels. 16271 * 16272 * @method Html5#videoHeight 16273 * @return {number} 16274 * The value of `videoHeight` from the video element. This will be a number 16275 * in css pixels. 16276 * 16277 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth} 16278 */ 16279'videoHeight'].forEach(function (prop) { 16280 Html5.prototype[prop] = function () { 16281 return this.el_[prop]; 16282 }; 16283}); 16284 16285// Wrap native properties with a setter in this format: 16286// set + toTitleCase(name) 16287[ 16288/** 16289 * Set the value of `volume` on the media element. `volume` indicates the current 16290 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and 16291 * so on. 16292 * 16293 * @method Html5#setVolume 16294 * @param {number} percentAsDecimal 16295 * The volume percent as a decimal. Valid range is from 0-1. 16296 * 16297 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume} 16298 */ 16299'volume', 16300 16301/** 16302 * Set the value of `muted` on the media element. `muted` indicates the current 16303 * audio level should be silent. 16304 * 16305 * @method Html5#setMuted 16306 * @param {boolean} muted 16307 * - True if the audio should be set to silent 16308 * - False otherwise 16309 * 16310 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted} 16311 */ 16312'muted', 16313 16314/** 16315 * Set the value of `src` on the media element. `src` indicates the current 16316 * {@link Tech~SourceObject} for the media. 16317 * 16318 * @method Html5#setSrc 16319 * @param {Tech~SourceObject} src 16320 * The source object to set as the current source. 16321 * 16322 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-src} 16323 */ 16324'src', 16325 16326/** 16327 * Set the value of `poster` on the media element. `poster` is the url to 16328 * an image file that can/will be shown when no media data is available. 16329 * 16330 * @method Html5#setPoster 16331 * @param {string} poster 16332 * The url to an image that should be used as the `poster` for the media 16333 * element. 16334 * 16335 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-poster} 16336 */ 16337'poster', 16338 16339/** 16340 * Set the value of `preload` on the media element. `preload` indicates 16341 * what should download before the media is interacted with. It can have the following 16342 * values: 16343 * - none: nothing should be downloaded 16344 * - metadata: poster and the first few frames of the media may be downloaded to get 16345 * media dimensions and other metadata 16346 * - auto: allow the media and metadata for the media to be downloaded before 16347 * interaction 16348 * 16349 * @method Html5#setPreload 16350 * @param {string} preload 16351 * The value of `preload` to set on the media element. Must be 'none', 'metadata', 16352 * or 'auto'. 16353 * 16354 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload} 16355 */ 16356'preload', 16357 16358/** 16359 * Set the value of `autoplay` on the media element. `autoplay` indicates 16360 * that the media should start to play as soon as the page is ready. 16361 * 16362 * @method Html5#setAutoplay 16363 * @param {boolean} autoplay 16364 * - True indicates that the media should start as soon as the page loads. 16365 * - False indicates that the media should not start as soon as the page loads. 16366 * 16367 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay} 16368 */ 16369'autoplay', 16370 16371/** 16372 * Set the value of `loop` on the media element. `loop` indicates 16373 * that the media should return to the start of the media and continue playing once 16374 * it reaches the end. 16375 * 16376 * @method Html5#setLoop 16377 * @param {boolean} loop 16378 * - True indicates that playback should seek back to start once 16379 * the end of a media is reached. 16380 * - False indicates that playback should not loop back to the start when the 16381 * end of the media is reached. 16382 * 16383 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop} 16384 */ 16385'loop', 16386 16387/** 16388 * Set the value of `playbackRate` on the media element. `playbackRate` indicates 16389 * the rate at which the media should play back. Examples: 16390 * - if playbackRate is set to 2, media will play twice as fast. 16391 * - if playbackRate is set to 0.5, media will play half as fast. 16392 * 16393 * @method Html5#setPlaybackRate 16394 * @return {number} 16395 * The value of `playbackRate` from the media element. A number indicating 16396 * the current playback speed of the media, where 1 is normal speed. 16397 * 16398 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate} 16399 */ 16400'playbackRate'].forEach(function (prop) { 16401 Html5.prototype['set' + (0, _toTitleCase2['default'])(prop)] = function (v) { 16402 this.el_[prop] = v; 16403 }; 16404}); 16405 16406// wrap native functions with a function 16407[ 16408/** 16409 * A wrapper around the media elements `pause` function. This will call the `HTML5` 16410 * media elements `pause` function. 16411 * 16412 * @method Html5#pause 16413 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-pause} 16414 */ 16415'pause', 16416 16417/** 16418 * A wrapper around the media elements `load` function. This will call the `HTML5`s 16419 * media element `load` function. 16420 * 16421 * @method Html5#load 16422 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-load} 16423 */ 16424'load'].forEach(function (prop) { 16425 Html5.prototype[prop] = function () { 16426 return this.el_[prop](); 16427 }; 16428}); 16429 16430_tech2['default'].withSourceHandlers(Html5); 16431 16432/** 16433 * Native source handler for Html5, simply passes the source to the media element. 16434 * 16435 * @proprety {Tech~SourceObject} source 16436 * The source object 16437 * 16438 * @proprety {Html5} tech 16439 * The instance of the HTML5 tech. 16440 */ 16441Html5.nativeSourceHandler = {}; 16442 16443/** 16444 * Check if the media element can play the given mime type. 16445 * 16446 * @param {string} type 16447 * The mimetype to check 16448 * 16449 * @return {string} 16450 * 'probably', 'maybe', or '' (empty string) 16451 */ 16452Html5.nativeSourceHandler.canPlayType = function (type) { 16453 // IE9 on Windows 7 without MediaPlayer throws an error here 16454 // https://github.com/videojs/video.js/issues/519 16455 try {
16456 return Html5.TEST_VID.canPlayType(type); 16457 } catch (e) { 16458 return ''; 16459 } 16460}; 16461 16462/** 16463 * Check if the media element can handle a source natively. 16464 * 16465 * @param {Tech~SourceObject} source 16466 * The source object 16467 * 16468 * @param {Object} [options] 16469 * Options to be passed to the tech. 16470 * 16471 * @return {string} 16472 * 'probably', 'maybe', or '' (empty string). 16473 */ 16474Html5.nativeSourceHandler.canHandleSource = function (source, options) { 16475 16476 // If a type was provided we should rely on that 16477 if (source.type) { 16478 return Html5.nativeSourceHandler.canPlayType(source.type); 16479 16480 // If no type, fall back to checking 'video/[EXTENSION]' 16481 } else if (source.src) { 16482 var ext = Url.getFileExtension(source.src); 16483 16484 return Html5.nativeSourceHandler.canPlayType('video/' + ext); 16485 } 16486 16487 return ''; 16488}; 16489 16490/** 16491 * Pass the source to the native media element. 16492 * 16493 * @param {Tech~SourceObject} source 16494 * The source object 16495 * 16496 * @param {Html5} tech 16497 * The instance of the Html5 tech 16498 * 16499 * @param {Object} [options] 16500 * The options to pass to the source 16501 */ 16502Html5.nativeSourceHandler.handleSource = function (source, tech, options) { 16503 tech.setSrc(source.src); 16504}; 16505 16506/** 16507 * A noop for the native dispose function, as cleanup is not needed. 16508 */ 16509Html5.nativeSourceHandler.dispose = function () {}; 16510 16511// Register the native source handler 16512Html5.registerSourceHandler(Html5.nativeSourceHandler); 16513 16514_component2['default'].registerComponent('Html5', Html5); 16515_tech2['default'].registerTech('Html5', Html5); 16516exports['default'] = Html5; 16517 16518},{"5":5,"62":62,"78":78,"81":81,"83":83,"86":86,"87":87,"88":88,"91":91,"92":92,"94":94,"95":95,"98":98}],61:[function(_dereq_,module,exports){ 16519'use strict'; 16520 16521exports.__esModule = true; 16522 16523var _component = _dereq_(5); 16524 16525var _component2 = _interopRequireDefault(_component); 16526 16527var _tech = _dereq_(62); 16528 16529var _tech2 = _interopRequireDefault(_tech); 16530 16531var _toTitleCase = _dereq_(91); 16532 16533var _toTitleCase2 = _interopRequireDefault(_toTitleCase); 16534 16535function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16536 16537function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 16538 16539function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 16540 16541function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 16542 * @file loader.js 16543 */ 16544 16545 16546/** 16547 * The `MediaLoader` is the `Component` that decides which playback technology to load 16548 * when a player is initialized. 16549 * 16550 * @extends Component 16551 */ 16552var MediaLoader = function (_Component) { 16553 _inherits(MediaLoader, _Component); 16554 16555 /** 16556 * Create an instance of this class. 16557 * 16558 * @param {Player} player 16559 * The `Player` that this class should attach to. 16560 * 16561 * @param {Object} [options] 16562 * The key/value stroe of player options. 16563 * 16564 * @param {Component~ReadyCallback} [ready] 16565 * The function that is run when this component is ready. 16566 */ 16567 function MediaLoader(player, options, ready) { 16568 _classCallCheck(this, MediaLoader); 16569 16570 // If there are no sources when the player is initialized, 16571 // load the first supported playback technology. 16572 16573 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready)); 16574 16575 if (!options.playerOptions.sources || options.playerOptions.sources.length === 0) { 16576 for (var i = 0, j = options.playerOptions.techOrder; i < j.length; i++) { 16577 var techName = (0, _toTitleCase2['default'])(j[i]); 16578 var tech = _tech2['default'].getTech(techName); 16579
16580 // Support old behavior of techs being registered as components. 16581 // Remove once that deprecated behavior is removed. 16582 if (!techName) { 16583 tech = _component2['default'].getComponent(techName); 16584 } 16585 16586 // Check if the browser supports this technology 16587 if (tech && tech.isSupported()) { 16588 player.loadTech_(techName); 16589 break; 16590 } 16591 } 16592 } else { 16593 // Loop through playback technologies (HTML5, Flash) and check for support. 16594 // Then load the best source. 16595 // A few assumptions here: 16596 // All playback technologies respect preload false. 16597 player.src(options.playerOptions.sources); 16598 } 16599 return _this; 16600 } 16601 16602 return MediaLoader; 16603}(_component2['default']); 16604 16605_component2['default'].registerComponent('MediaLoader', MediaLoader); 16606exports['default'] = MediaLoader; 16607 16608},{"5":5,"62":62,"91":91}],62:[function(_dereq_,module,exports){ 16609'use strict'; 16610 16611exports.__esModule = true; 16612 16613var _component = _dereq_(5); 16614 16615var _component2 = _interopRequireDefault(_component); 16616 16617var _htmlTrackElement = _dereq_(66); 16618 16619var _htmlTrackElement2 = _interopRequireDefault(_htmlTrackElement); 16620
16621var _htmlTrackElementList = _dereq_(65); 16622 16623var _htmlTrackElementList2 = _interopRequireDefault(_htmlTrackElementList); 16624 16625var _mergeOptions = _dereq_(87); 16626 16627var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 16628 16629var _textTrack = _dereq_(72); 16630 16631var _textTrack2 = _interopRequireDefault(_textTrack); 16632 16633var _textTrackList = _dereq_(70); 16634 16635var _textTrackList2 = _interopRequireDefault(_textTrackList); 16636 16637var _videoTrackList = _dereq_(76); 16638 16639var _videoTrackList2 = _interopRequireDefault(_videoTrackList); 16640 16641var _audioTrackList = _dereq_(63); 16642 16643var _audioTrackList2 = _interopRequireDefault(_audioTrackList); 16644 16645var _fn = _dereq_(83); 16646 16647var Fn = _interopRequireWildcard(_fn); 16648 16649var _log = _dereq_(86); 16650 16651var _log2 = _interopRequireDefault(_log); 16652 16653var _timeRanges = _dereq_(90); 16654 16655var _buffer = _dereq_(79); 16656 16657var _mediaError = _dereq_(46); 16658 16659var _mediaError2 = _interopRequireDefault(_mediaError); 16660 16661var _window = _dereq_(95); 16662 16663var _window2 = _interopRequireDefault(_window); 16664 16665var _document = _dereq_(94); 16666 16667var _document2 = _interopRequireDefault(_document); 16668 16669var _obj = _dereq_(88); 16670 16671function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 16672 16673function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16674 16675function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 16676 16677function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 16678 16679function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 16680 * @file tech.js 16681 */ 16682 16683/** 16684 * An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string 16685 * that just contains the src url alone. 16686 * * `var SourceObject = {src: 'http://ex.com/video.mp4', type: 'video/mp4'};` 16687 * `var SourceString = 'http://example.com/some-video.mp4';` 16688 * 16689 * @typedef {Object|string} Tech~SourceObject 16690 * 16691 * @property {string} src 16692 * The url to the source 16693 * 16694 * @property {string} type 16695 * The mime type of the source 16696 */ 16697 16698/** 16699 * A function used by {@link Tech} to create a new {@link TextTrack}. 16700 * 16701 * @param {Tech} self 16702 * An instance of the Tech class. 16703 * 16704 * @param {string} kind 16705 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata) 16706 * 16707 * @param {string} [label] 16708 * Label to identify the text track 16709 * 16710 * @param {string} [language] 16711 * Two letter language abbreviation 16712 * 16713 * @param {Object} [options={}] 16714 * An object with additional text track options 16715 * 16716 * @return {TextTrack} 16717 * The text track that was created. 16718 */ 16719function createTrackHelper(self, kind, label, language) { 16720 var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; 16721 16722 var tracks = self.textTracks(); 16723 16724 options.kind = kind; 16725 16726 if (label) { 16727 options.label = label; 16728 } 16729 if (language) { 16730 options.language = language; 16731 } 16732 options.tech = self; 16733 16734 var track = new _textTrack2['default'](options); 16735 16736 tracks.addTrack_(track); 16737 16738 return track; 16739} 16740 16741/** 16742 * This is the base class for media playback technology controllers, such as 16743 * {@link Flash} and {@link HTML5} 16744 * 16745 * @extends Component 16746 */ 16747 16748var Tech = function (_Component) { 16749 _inherits(Tech, _Component); 16750 16751 /** 16752 * Create an instance of this Tech. 16753 * 16754 * @param {Object} [options] 16755 * The key/value store of player options. 16756 * 16757 * @param {Component~ReadyCallback} ready 16758 * Callback function to call when the `HTML5` Tech is ready. 16759 */ 16760 function Tech() { 16761 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 16762 var ready = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; 16763 16764 _classCallCheck(this, Tech); 16765 16766 // we don't want the tech to report user activity automatically.
vendor: 5,704 bytes, lines 16767-16972
16767 // This is done manually in addControlsListeners 16768 options.reportTouchActivity = false; 16769 16770 // keep track of whether the current source has played at all to 16771 // implement a very limited played() 16772 var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready)); 16773 16774 _this.hasStarted_ = false; 16775 _this.on('playing', function () { 16776 this.hasStarted_ = true; 16777 }); 16778 _this.on('loadstart', function () { 16779 this.hasStarted_ = false; 16780 }); 16781 16782 _this.textTracks_ = options.textTracks; 16783 _this.videoTracks_ = options.videoTracks; 16784 _this.audioTracks_ = options.audioTracks; 16785 16786 // Manually track progress in cases where the browser/flash player doesn't report it. 16787 if (!_this.featuresProgressEvents) { 16788 _this.manualProgressOn(); 16789 } 16790 16791 // Manually track timeupdates in cases where the browser/flash player doesn't report it. 16792 if (!_this.featuresTimeupdateEvents) { 16793 _this.manualTimeUpdatesOn(); 16794 } 16795 16796 ['Text', 'Audio', 'Video'].forEach(function (track) { 16797 if (options['native' + track + 'Tracks'] === false) { 16798 _this['featuresNative' + track + 'Tracks'] = false; 16799 } 16800 }); 16801 16802 if (options.nativeCaptions === false) { 16803 _this.featuresNativeTextTracks = false; 16804 } 16805 16806 if (!_this.featuresNativeTextTracks) { 16807 _this.emulateTextTracks(); 16808 } 16809 16810 _this.autoRemoteTextTracks_ = new _textTrackList2['default'](); 16811 16812 _this.initTextTrackListeners(); 16813 _this.initTrackListeners(); 16814 16815 // Turn on component tap events only if not using native controls 16816 if (!options.nativeControlsForTouch) { 16817 _this.emitTapEvents(); 16818 } 16819 16820 if (_this.constructor) { 16821 _this.name_ = _this.constructor.name || 'Unknown Tech'; 16822 } 16823 return _this; 16824 } 16825 16826 /* Fallbacks for unsupported event types 16827 ================================================================================ */ 16828 16829 /** 16830 * Polyfill the `progress` event for browsers that don't support it natively. 16831 * 16832 * @see {@link Tech#trackProgress} 16833 */ 16834 16835 16836 Tech.prototype.manualProgressOn = function manualProgressOn() { 16837 this.on('durationchange', this.onDurationChange); 16838 16839 this.manualProgress = true; 16840 16841 // Trigger progress watching when a source begins loading 16842 this.one('ready', this.trackProgress); 16843 }; 16844 16845 /** 16846 * Turn off the polyfill for `progress` events that was created in 16847 * {@link Tech#manualProgressOn} 16848 */ 16849 16850 16851 Tech.prototype.manualProgressOff = function manualProgressOff() { 16852 this.manualProgress = false; 16853 this.stopTrackingProgress(); 16854 16855 this.off('durationchange', this.onDurationChange); 16856 }; 16857 16858 /** 16859 * This is used to trigger a `progress` event when the buffered percent changes. It 16860 * sets an interval function that will be called every 500 milliseconds to check if the 16861 * buffer end percent has changed. 16862 * 16863 * > This function is called by {@link Tech#manualProgressOn} 16864 * 16865 * @param {EventTarget~Event} event 16866 * The `ready` event that caused this to run. 16867 * 16868 * @listens Tech#ready 16869 * @fires Tech#progress 16870 */ 16871 16872 16873 Tech.prototype.trackProgress = function trackProgress(event) { 16874 this.stopTrackingProgress(); 16875 this.progressInterval = this.setInterval(Fn.bind(this, function () { 16876 // Don't trigger unless buffered amount is greater than last time 16877 16878 var numBufferedPercent = this.bufferedPercent(); 16879 16880 if (this.bufferedPercent_ !== numBufferedPercent) { 16881 /** 16882 * See {@link Player#progress} 16883 * 16884 * @event Tech#progress 16885 * @type {EventTarget~Event} 16886 */ 16887 this.trigger('progress'); 16888 } 16889 16890 this.bufferedPercent_ = numBufferedPercent; 16891 16892 if (numBufferedPercent === 1) { 16893 this.stopTrackingProgress(); 16894 } 16895 }), 500); 16896 }; 16897 16898 /** 16899 * Update our internal duration on a `durationchange` event by calling 16900 * {@link Tech#duration}. 16901 * 16902 * @param {EventTarget~Event} event 16903 * The `durationchange` event that caused this to run. 16904 * 16905 * @listens Tech#durationchange 16906 */ 16907 16908 16909 Tech.prototype.onDurationChange = function onDurationChange(event) { 16910 this.duration_ = this.duration(); 16911 }; 16912 16913 /** 16914 * Get and create a `TimeRange` object for buffering. 16915 * 16916 * @return {TimeRange} 16917 * The time range object that was created. 16918 */ 16919 16920 16921 Tech.prototype.buffered = function buffered() { 16922 return (0, _timeRanges.createTimeRange)(0, 0); 16923 }; 16924 16925 /** 16926 * Get the percentage of the current video that is currently buffered. 16927 * 16928 * @return {number} 16929 * A number from 0 to 1 that represents the decimal percentage of the 16930 * video that is buffered. 16931 * 16932 */ 16933 16934 16935 Tech.prototype.bufferedPercent = function bufferedPercent() { 16936 return (0, _buffer.bufferedPercent)(this.buffered(), this.duration_); 16937 }; 16938 16939 /** 16940 * Turn off the polyfill for `progress` events that was created in 16941 * {@link Tech#manualProgressOn} 16942 * Stop manually tracking progress events by clearing the interval that was set in 16943 * {@link Tech#trackProgress}. 16944 */ 16945 16946 16947 Tech.prototype.stopTrackingProgress = function stopTrackingProgress() { 16948 this.clearInterval(this.progressInterval); 16949 }; 16950 16951 /** 16952 * Polyfill the `timeupdate` event for browsers that don't support it. 16953 * 16954 * @see {@link Tech#trackCurrentTime} 16955 */ 16956 16957 16958 Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() { 16959 this.manualTimeUpdates = true; 16960 16961 this.on('play', this.trackCurrentTime); 16962 this.on('pause', this.stopTrackingCurrentTime); 16963 }; 16964 16965 /** 16966 * Turn off the polyfill for `timeupdate` events that was created in 16967 * {@link Tech#manualTimeUpdatesOn} 16968 */ 16969 16970 16971 Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() { 16972 this.manualTimeUpdates = false;
16973 this.stopTrackingCurrentTime(); 16974 this.off('play', this.trackCurrentTime); 16975 this.off('pause', this.stopTrackingCurrentTime); 16976 }; 16977 16978 /** 16979 * Sets up an interval function to track current time and trigger `timeupdate` every 16980 * 250 milliseconds. 16981 * 16982 * @listens Tech#play 16983 * @triggers Tech#timeupdate 16984 */ 16985 16986 16987 Tech.prototype.trackCurrentTime = function trackCurrentTime() { 16988 if (this.currentTimeInterval) { 16989 this.stopTrackingCurrentTime(); 16990 } 16991 this.currentTimeInterval = this.setInterval(function () { 16992 /** 16993 * Triggered at an interval of 250ms to indicated that time is passing in the video. 16994 * 16995 * @event Tech#timeupdate 16996 * @type {EventTarget~Event} 16997 */ 16998 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); 16999 17000 // 42 = 24 fps // 250 is what Webkit uses // FF uses 15 17001 }, 250); 17002 }; 17003 17004 /** 17005 * Stop the interval function created in {@link Tech#trackCurrentTime} so that the 17006 * `timeupdate` event is no longer triggered. 17007 * 17008 * @listens {Tech#pause} 17009 */ 17010 17011 17012 Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() { 17013 this.clearInterval(this.currentTimeInterval); 17014 17015 // #1002 - if the video ends right before the next timeupdate would happen, 17016 // the progress bar won't make it all the way to the end 17017 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); 17018 }; 17019 17020 /** 17021 * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList}, 17022 * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech. 17023 * 17024 * @fires Component#dispose 17025 */ 17026 17027 17028 Tech.prototype.dispose = function dispose() { 17029 17030 // clear out all tracks because we can't reuse them between techs 17031 this.clearTracks(['audio', 'video', 'text']); 17032 17033 // Turn off any manual progress or timeupdate tracking 17034 if (this.manualProgress) { 17035 this.manualProgressOff(); 17036 } 17037 17038 if (this.manualTimeUpdates) { 17039 this.manualTimeUpdatesOff(); 17040 } 17041 17042 _Component.prototype.dispose.call(this); 17043 }; 17044 17045 /** 17046 * Clear out a single `TrackList` or an array of `TrackLists` given their names. 17047 * 17048 * > Note: Techs without source handlers should call this between sources for `video` 17049 * & `audio` tracks. You don't want to use them between tracks! 17050 * 17051 * @param {string[]|string} types 17052 * TrackList names to clear, valid names are `video`, `audio`, and 17053 * `text`. 17054 */ 17055 17056 17057 Tech.prototype.clearTracks = function clearTracks(types) { 17058 var _this2 = this; 17059 17060 types = [].concat(types); 17061 // clear out all tracks because we can't reuse them between techs 17062 types.forEach(function (type) { 17063 var list = _this2[type + 'Tracks']() || []; 17064 var i = list.length; 17065 17066 while (i--) { 17067 var track = list[i]; 17068 17069 if (type === 'text') { 17070 _this2.removeRemoteTextTrack(track); 17071 } 17072 list.removeTrack_(track); 17073 } 17074 }); 17075 }; 17076 17077 /** 17078 * Remove any TextTracks added via addRemoteTextTrack that are 17079 * flagged for automatic garbage collection 17080 */ 17081 17082 17083 Tech.prototype.cleanupAutoTextTracks = function cleanupAutoTextTracks() { 17084 var list = this.autoRemoteTextTracks_ || []; 17085 var i = list.length; 17086 17087 while (i--) { 17088 var track = list[i]; 17089 17090 this.removeRemoteTextTrack(track); 17091 } 17092 }; 17093 17094 /** 17095 * Reset the tech, which will removes all sources and reset the internal readyState. 17096 * 17097 * @abstract 17098 */ 17099 17100 17101 Tech.prototype.reset = function reset() {}; 17102 17103 /** 17104 * Get or set an error on the Tech. 17105 * 17106 * @param {MediaError} [err] 17107 * Error to set on the Tech 17108 * 17109 * @return {MediaError|null} 17110 * The current error object on the tech, or null if there isn't one. 17111 */ 17112 17113 17114 Tech.prototype.error = function error(err) { 17115 if (err !== undefined) { 17116 this.error_ = new _mediaError2['default'](err); 17117 this.trigger('error'); 17118 } 17119 return this.error_; 17120 }; 17121 17122 /** 17123 * Returns the `TimeRange`s that have been played through for the current source. 17124 * 17125 * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`. 17126 * It only checks wether the source has played at all or not. 17127 * 17128 * @return {TimeRange} 17129 * - A single time range if this video has played 17130 * - An empty set of ranges if not. 17131 */ 17132 17133 17134 Tech.prototype.played = function played() { 17135 if (this.hasStarted_) { 17136 return (0, _timeRanges.createTimeRange)(0, 0); 17137 } 17138 return (0, _timeRanges.createTimeRange)(); 17139 }; 17140 17141 /** 17142 * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was 17143 * previously called. 17144 * 17145 * @fires Tech#timeupdate 17146 */ 17147 17148 17149 Tech.prototype.setCurrentTime = function setCurrentTime() { 17150 // improve the accuracy of manual timeupdates 17151 if (this.manualTimeUpdates) { 17152 /** 17153 * A manual `timeupdate` event. 17154 * 17155 * @event Tech#timeupdate 17156 * @type {EventTarget~Event} 17157 */ 17158 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); 17159 } 17160 }; 17161 17162 /** 17163 * Turn on listeners for {@link TextTrackList} events. This adds 17164 * {@link EventTarget~EventListeners} for `texttrackchange`, `addtrack` and 17165 * `removetrack`. 17166 * 17167 * @fires Tech#texttrackchange 17168 */ 17169 17170 17171 Tech.prototype.initTextTrackListeners = function initTextTrackListeners() { 17172 var textTrackListChanges = Fn.bind(this, function () { 17173 /** 17174 * Triggered when tracks are added or removed on the Tech {@link TextTrackList} 17175 * 17176 * @event Tech#texttrackchange 17177 * @type {EventTarget~Event} 17178 */ 17179 this.trigger('texttrackchange'); 17180 }); 17181 17182 var tracks = this.textTracks(); 17183 17184 if (!tracks) { 17185 return; 17186 } 17187 17188 tracks.addEventListener('removetrack', textTrackListChanges); 17189 tracks.addEventListener('addtrack', textTrackListChanges); 17190 17191 this.on('dispose', Fn.bind(this, function () { 17192 tracks.removeEventListener('removetrack', textTrackListChanges); 17193 tracks.removeEventListener('addtrack', textTrackListChanges); 17194 })); 17195 }; 17196 17197 /** 17198 * Turn on listeners for {@link VideoTrackList} and {@link {AudioTrackList} events. 17199 * This adds {@link EventTarget~EventListeners} for `addtrack`, and `removetrack`. 17200 * 17201 * @fires Tech#audiotrackchange 17202 * @fires Tech#videotrackchange 17203 */ 17204 17205 17206 Tech.prototype.initTrackListeners = function initTrackListeners() { 17207 var _this3 = this; 17208 17209 var trackTypes = ['video', 'audio']; 17210
17211 trackTypes.forEach(function (type) { 17212 /** 17213 * Triggered when tracks are added or removed on the Tech {@link AudioTrackList} 17214 * 17215 * @event Tech#audiotrackchange 17216 * @type {EventTarget~Event} 17217 */ 17218 17219 /** 17220 * Triggered when tracks are added or removed on the Tech {@link VideoTrackList} 17221 * 17222 * @event Tech#videotrackchange 17223 * @type {EventTarget~Event} 17224 */ 17225 var trackListChanges = function trackListChanges() { 17226 _this3.trigger(type + 'trackchange'); 17227 }; 17228 17229 var tracks = _this3[type + 'Tracks'](); 17230 17231 tracks.addEventListener('removetrack', trackListChanges); 17232 tracks.addEventListener('addtrack', trackListChanges); 17233 17234 _this3.on('dispose', function () { 17235 tracks.removeEventListener('removetrack', trackListChanges); 17236 tracks.removeEventListener('addtrack', trackListChanges); 17237 }); 17238 }); 17239 }; 17240 17241 /** 17242 * Emulate TextTracks using vtt.js if necessary 17243 * 17244 * @fires Tech#vttjsloaded 17245 * @fires Tech#vttjserror 17246 */ 17247 17248 17249 Tech.prototype.addWebVttScript_ = function addWebVttScript_() { 17250 var _this4 = this; 17251 17252 if (_window2['default'].WebVTT) { 17253 return; 17254 } 17255 17256 // Initially, Tech.el_ is a child of a dummy-div wait until the Component system 17257 // signals that the Tech is ready at which point Tech.el_ is part of the DOM 17258 // before inserting the WebVTT script 17259 if (_document2['default'].body.contains(this.el())) { 17260 var vtt = _dereq_(105); 17261 17262 // load via require if available and vtt.js script location was not passed in 17263 // as an option. novtt builds will turn the above require call into an empty object 17264 // which will cause this if check to always fail. 17265 if (!this.options_['vtt.js'] && (0, _obj.isPlain)(vtt) && Object.keys(vtt).length > 0) { 17266 this.trigger('vttjsloaded'); 17267 return; 17268 } 17269 17270 // load vtt.js via the script location option or the cdn of no location was 17271 // passed in 17272 var script = _document2['default'].createElement('script'); 17273 17274 script.src = this.options_['vtt.js'] || 'https://vjs.zencdn.net/vttjs/0.12.3/vtt.min.js'; 17275 script.onload = function () { 17276 /** 17277 * Fired when vtt.js is loaded. 17278 * 17279 * @event Tech#vttjsloaded 17280 * @type {EventTarget~Event} 17281 */ 17282 _this4.trigger('vttjsloaded'); 17283 }; 17284 script.onerror = function () { 17285 /** 17286 * Fired when vtt.js was not loaded due to an error 17287 * 17288 * @event Tech#vttjsloaded 17289 * @type {EventTarget~Event} 17290 */ 17291 _this4.trigger('vttjserror'); 17292 }; 17293 this.on('dispose', function () { 17294 script.onload = null; 17295 script.onerror = null; 17296 }); 17297 // but have not loaded yet and we set it to true before the inject so that 17298 // we don't overwrite the injected window.WebVTT if it loads right away 17299 _window2['default'].WebVTT = true; 17300 this.el().parentNode.appendChild(script); 17301 } else { 17302 this.ready(this.addWebVttScript_); 17303 } 17304 }; 17305 17306 /** 17307 * Emulate texttracks 17308 * 17309 * @method emulateTextTracks 17310 */ 17311 17312 17313 Tech.prototype.emulateTextTracks = function emulateTextTracks() { 17314 var _this5 = this; 17315 17316 var tracks = this.textTracks(); 17317 17318 if (!tracks) { 17319 return; 17320 } 17321 17322 var remoteTracks = this.remoteTextTracks(); 17323 var handleAddTrack = function handleAddTrack(e) { 17324 return tracks.addTrack_(e.track); 17325 }; 17326 var handleRemoveTrack = function handleRemoveTrack(e) { 17327 return tracks.removeTrack_(e.track); 17328 }; 17329 17330 remoteTracks.on('addtrack', handleAddTrack); 17331 remoteTracks.on('removetrack', handleRemoveTrack); 17332 17333 this.addWebVttScript_(); 17334 17335 var updateDisplay = function updateDisplay() { 17336 return _this5.trigger('texttrackchange'); 17337 }; 17338 17339 var textTracksChanges = function textTracksChanges() { 17340 updateDisplay(); 17341 17342 for (var i = 0; i < tracks.length; i++) { 17343 var track = tracks[i]; 17344 17345 track.removeEventListener('cuechange', updateDisplay); 17346 if (track.mode === 'showing') { 17347 track.addEventListener('cuechange', updateDisplay); 17348 } 17349 } 17350 }; 17351 17352 textTracksChanges(); 17353 tracks.addEventListener('change', textTracksChanges); 17354 tracks.addEventListener('addtrack', textTracksChanges); 17355 tracks.addEventListener('removetrack', textTracksChanges); 17356 17357 this.on('dispose', function () { 17358 remoteTracks.off('addtrack', handleAddTrack); 17359 remoteTracks.off('removetrack', handleRemoveTrack); 17360 tracks.removeEventListener('change', textTracksChanges); 17361 tracks.removeEventListener('addtrack', textTracksChanges); 17362 tracks.removeEventListener('removetrack', textTracksChanges); 17363 17364 for (var i = 0; i < tracks.length; i++) { 17365 var track = tracks[i]; 17366 17367 track.removeEventListener('cuechange', updateDisplay); 17368 } 17369 }); 17370 }; 17371 17372 /** 17373 * Get the `Tech`s {@link VideoTrackList}. 17374 * 17375 * @return {VideoTrackList} 17376 * The video track list that the Tech is currently using. 17377 */ 17378 17379 17380 Tech.prototype.videoTracks = function videoTracks() { 17381 this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default'](); 17382 return this.videoTracks_; 17383 }; 17384 17385 /** 17386 * Get the `Tech`s {@link AudioTrackList}. 17387 * 17388 * @return {AudioTrackList} 17389 * The audio track list that the Tech is currently using. 17390 */ 17391 17392 17393 Tech.prototype.audioTracks = function audioTracks() { 17394 this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default'](); 17395 return this.audioTracks_; 17396 }; 17397 17398 /** 17399 * Get the `Tech`s {@link TextTrackList}. 17400 * 17401 * @return {TextTrackList} 17402 * The text track list that the Tech is currently using. 17403 */ 17404 17405 17406 Tech.prototype.textTracks = function textTracks() { 17407 this.textTracks_ = this.textTracks_ || new _textTrackList2['default'](); 17408 return this.textTracks_; 17409 }; 17410 17411 /** 17412 * Get the `Tech`s remote {@link TextTrackList}, which is created from elements 17413 * that were added to the DOM. 17414 * 17415 * @return {TextTrackList} 17416 * The remote text track list that the Tech is currently using. 17417 */ 17418 17419 17420 Tech.prototype.remoteTextTracks = function remoteTextTracks() { 17421 this.remoteTextTracks_ = this.remoteTextTracks_ || new _textTrackList2['default'](); 17422 return this.remoteTextTracks_; 17423 }; 17424 17425 /** 17426 * Get The `Tech`s {HTMLTrackElementList}, which are the elements in the DOM that are 17427 * being used as TextTracks. 17428 * 17429 * @return {HTMLTrackElementList} 17430 * The current HTML track elements that exist for the tech. 17431 */ 17432 17433 17434 Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() { 17435 this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _htmlTrackElementList2['default'](); 17436 return this.remoteTextTrackEls_;
17437 }; 17438 17439 /** 17440 * Create and returns a remote {@link TextTrack} object. 17441 * 17442 * @param {string} kind 17443 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata) 17444 * 17445 * @param {string} [label] 17446 * Label to identify the text track 17447 * 17448 * @param {string} [language] 17449 * Two letter language abbreviation 17450 * 17451 * @return {TextTrack} 17452 * The TextTrack that gets created. 17453 */ 17454 17455 17456 Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) { 17457 if (!kind) { 17458 throw new Error('TextTrack kind is required but was not provided'); 17459 } 17460 17461 return createTrackHelper(this, kind, label, language); 17462 }; 17463 17464 /** 17465 * Create an emulated TextTrack for use by addRemoteTextTrack 17466 * 17467 * This is intended to be overridden by classes that inherit from 17468 * Tech in order to create native or custom TextTracks. 17469 * 17470 * @param {Object} options 17471 * The object should contain the options to initialize the TextTrack with. 17472 * 17473 * @param {string} [options.kind] 17474 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata). 17475 * 17476 * @param {string} [options.label]. 17477 * Label to identify the text track 17478 * 17479 * @param {string} [options.language] 17480 * Two letter language abbreviation. 17481 * 17482 * @return {HTMLTrackElement} 17483 * The track element that gets created. 17484 */ 17485 17486 17487 Tech.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) { 17488 var track = (0, _mergeOptions2['default'])(options, { 17489 tech: this 17490 }); 17491 17492 return new _htmlTrackElement2['default'](track); 17493 }; 17494 17495 /** 17496 * Creates a remote text track object and returns an html track element. 17497 * 17498 * > Note: This can be an emulated {@link HTMLTrackElement} or a native one. 17499 * 17500 * @param {Object} options 17501 * See {@link Tech#createRemoteTextTrack} for more detailed properties. 17502 * 17503 * @param {boolean} [manualCleanup=true] 17504 * - When false: the TextTrack will be automatically removed from the video 17505 * element whenever the source changes 17506 * - When True: The TextTrack will have to be cleaned up manually 17507 * 17508 * @return {HTMLTrackElement} 17509 * An Html Track Element. 17510 * 17511 * @deprecated The default functionality for this function will be equivalent 17512 * to "manualCleanup=false" in the future. The manualCleanup parameter will 17513 * also be removed. 17514 */ 17515 17516 17517 Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack() { 17518 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 17519 var manualCleanup = arguments[1]; 17520 17521 var htmlTrackElement = this.createRemoteTextTrack(options); 17522 17523 if (manualCleanup !== true && manualCleanup !== false) { 17524 // deprecation warning 17525 _log2['default'].warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js'); 17526 manualCleanup = true; 17527 } 17528 17529 // store HTMLTrackElement and TextTrack to remote list 17530 this.remoteTextTrackEls().addTrackElement_(htmlTrackElement); 17531 this.remoteTextTracks().addTrack_(htmlTrackElement.track); 17532 17533 if (manualCleanup !== true) { 17534 // create the TextTrackList if it doesn't exist 17535 this.autoRemoteTextTracks_.addTrack_(htmlTrackElement.track); 17536 } 17537 17538 return htmlTrackElement; 17539 }; 17540 17541 /** 17542 * Remove a remote text track from the remote `TextTrackList`. 17543 * 17544 * @param {TextTrack} track 17545 * `TextTrack` to remove from the `TextTrackList` 17546 */ 17547 17548 17549 Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) { 17550 var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track); 17551 17552 // remove HTMLTrackElement and TextTrack from remote list 17553 this.remoteTextTrackEls().removeTrackElement_(trackElement); 17554 this.remoteTextTracks().removeTrack_(track); 17555 this.autoRemoteTextTracks_.removeTrack_(track); 17556 }; 17557 17558 /** 17559 * A method to set a poster from a `Tech`. 17560 * 17561 * @abstract 17562 */ 17563 17564 17565 Tech.prototype.setPoster = function setPoster() {}; 17566 17567 /* 17568 * Check if the tech can support the given mime-type. 17569 * 17570 * The base tech does not support any type, but source handlers might 17571 * overwrite this. 17572 * 17573 * @param {string} type 17574 * The mimetype to check for support 17575 * 17576 * @return {string} 17577 * 'probably', 'maybe', or empty string 17578 * 17579 * @see [Spec]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType} 17580 * 17581 * @abstract 17582 */ 17583 17584 17585 Tech.prototype.canPlayType = function canPlayType() { 17586 return ''; 17587 }; 17588 17589 /* 17590 * Return whether the argument is a Tech or not. 17591 * Can be passed either a Class like `Html5` or a instance like `player.tech_` 17592 * 17593 * @param {Object} component 17594 * The item to check 17595 * 17596 * @return {boolean} 17597 * Whether it is a tech or not 17598 * - True if it is a tech 17599 * - False if it is not 17600 */ 17601 17602 17603 Tech.isTech = function isTech(component) { 17604 return component.prototype instanceof Tech || component instanceof Tech || component === Tech; 17605 }; 17606 17607 /** 17608 * Registers a `Tech` into a shared list for videojs. 17609 * 17610 * @param {string} name 17611 * Name of the `Tech` to register. 17612 * 17613 * @param {Object} tech 17614 * The `Tech` class to register. 17615 */ 17616 17617 17618 Tech.registerTech = function registerTech(name, tech) { 17619 if (!Tech.techs_) { 17620 Tech.techs_ = {}; 17621 } 17622 17623 if (!Tech.isTech(tech)) { 17624 throw new Error('Tech ' + name + ' must be a Tech'); 17625 } 17626 17627 Tech.techs_[name] = tech; 17628 return tech; 17629 }; 17630 17631 /** 17632 * Get a `Tech` from the shared list by name. 17633 * 17634 * @param {string} name 17635 * Name of the component to get 17636 * 17637 * @return {Tech|undefined} 17638 * The `Tech` or undefined if there was no tech with the name requsted. 17639 */ 17640 17641 17642 Tech.getTech = function getTech(name) {
17643 if (Tech.techs_ && Tech.techs_[name]) { 17644 return Tech.techs_[name]; 17645 } 17646 17647 if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) { 17648 _log2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)'); 17649 return _window2['default'].videojs[name]; 17650 } 17651 }; 17652 17653 return Tech; 17654}(_component2['default']); 17655 17656/** 17657 * List of associated text tracks. 17658 * 17659 * @type {TextTrackList} 17660 * @private 17661 */ 17662 17663 17664Tech.prototype.textTracks_; // eslint-disable-line 17665 17666/** 17667 * List of associated audio tracks. 17668 * 17669 * @type {AudioTrackList} 17670 * @private 17671 */ 17672Tech.prototype.audioTracks_; // eslint-disable-line 17673 17674/** 17675 * List of associated video tracks. 17676 * 17677 * @type {VideoTrackList} 17678 * @private 17679 */ 17680Tech.prototype.videoTracks_; // eslint-disable-line 17681 17682/** 17683 * Boolean indicating wether the `Tech` supports volume control. 17684 * 17685 * @type {boolean} 17686 * @default 17687 */ 17688Tech.prototype.featuresVolumeControl = true; 17689 17690/** 17691 * Boolean indicating wether the `Tech` support fullscreen resize control. 17692 * Resizing plugins using request fullscreen reloads the plugin 17693 * 17694 * @type {boolean} 17695 * @default 17696 */ 17697Tech.prototype.featuresFullscreenResize = false; 17698 17699/** 17700 * Boolean indicating wether the `Tech` supports changing the speed at which the video 17701 * plays. Examples: 17702 * - Set player to play 2x (twice) as fast 17703 * - Set player to play 0.5x (half) as fast 17704 * 17705 * @type {boolean} 17706 * @default 17707 */ 17708Tech.prototype.featuresPlaybackRate = false; 17709 17710/** 17711 * Boolean indicating wether the `Tech` supports the `progress` event. This is currently 17712 * not triggered by video-js-swf. This will be used to determine if 17713 * {@link Tech#manualProgressOn} should be called. 17714 * 17715 * @type {boolean} 17716 * @default 17717 */ 17718Tech.prototype.featuresProgressEvents = false; 17719 17720/** 17721 * Boolean indicating wether the `Tech` supports the `timeupdate` event. This is currently 17722 * not triggered by video-js-swf. This will be used to determine if 17723 * {@link Tech#manualTimeUpdates} should be called. 17724 * 17725 * @type {boolean} 17726 * @default 17727 */ 17728Tech.prototype.featuresTimeupdateEvents = false; 17729 17730/** 17731 * Boolean indicating wether the `Tech` supports the native `TextTrack`s. 17732 * This will help us integrate with native `TextTrack`s if the browser supports them. 17733 * 17734 * @type {boolean} 17735 * @default 17736 */ 17737Tech.prototype.featuresNativeTextTracks = false; 17738 17739/** 17740 * A functional mixin for techs that want to use the Source Handler pattern. 17741 * Source handlers are scripts for handling specific formats. 17742 * The source handler pattern is used for adaptive formats (HLS, DASH) that 17743 * manually load video data and feed it into a Source Buffer (Media Source Extensions) 17744 * Example: `Tech.withSourceHandlers.call(MyTech);` 17745 * 17746 * @param {Tech} _Tech 17747 * The tech to add source handler functions to. 17748 * 17749 * @mixes Tech~SourceHandlerAdditions 17750 */ 17751Tech.withSourceHandlers = function (_Tech) { 17752 17753 /** 17754 * Register a source handler 17755 * 17756 * @param {Function} handler 17757 * The source handler class 17758 * 17759 * @param {number} [index] 17760 * Register it at the following index 17761 */ 17762 _Tech.registerSourceHandler = function (handler, index) { 17763 var handlers = _Tech.sourceHandlers; 17764 17765 if (!handlers) { 17766 handlers = _Tech.sourceHandlers = []; 17767 } 17768 17769 if (index === undefined) { 17770 // add to the end of the list 17771 index = handlers.length; 17772 } 17773 17774 handlers.splice(index, 0, handler); 17775 }; 17776 17777 /** 17778 * Check if the tech can support the given type. Also checks the 17779 * Techs sourceHandlers. 17780 * 17781 * @param {string} type 17782 * The mimetype to check. 17783 * 17784 * @return {string} 17785 * 'probably', 'maybe', or '' (empty string) 17786 */ 17787 _Tech.canPlayType = function (type) { 17788 var handlers = _Tech.sourceHandlers || []; 17789 var can = void 0; 17790 17791 for (var i = 0; i < handlers.length; i++) { 17792 can = handlers[i].canPlayType(type); 17793 17794 if (can) { 17795 return can; 17796 } 17797 } 17798 17799 return ''; 17800 }; 17801 17802 /** 17803 * Returns the first source handler that supports the source. 17804 * 17805 * TODO: Answer question: should 'probably' be prioritized over 'maybe' 17806 * 17807 * @param {Tech~SourceObject} source 17808 * The source object 17809 * 17810 * @param {Object} options 17811 * The options passed to the tech 17812 * 17813 * @return {SourceHandler|null} 17814 * The first source handler that supports the source or null if 17815 * no SourceHandler supports the source 17816 */ 17817 _Tech.selectSourceHandler = function (source, options) { 17818 var handlers = _Tech.sourceHandlers || []; 17819 var can = void 0; 17820 17821 for (var i = 0; i < handlers.length; i++) { 17822 can = handlers[i].canHandleSource(source, options); 17823 17824 if (can) { 17825 return handlers[i]; 17826 } 17827 } 17828 17829 return null; 17830 }; 17831 17832 /** 17833 * Check if the tech can support the given source. 17834 * 17835 * @param {Tech~SourceObject} srcObj 17836 * The source object 17837 * 17838 * @param {Object} options 17839 * The options passed to the tech 17840 * 17841 * @return {string} 17842 * 'probably', 'maybe', or '' (empty string) 17843 */ 17844 _Tech.canPlaySource = function (srcObj, options) { 17845 var sh = _Tech.selectSourceHandler(srcObj, options); 17846 17847 if (sh) { 17848 return sh.canHandleSource(srcObj, options); 17849 } 17850 17851 return ''; 17852 }; 17853 17854 /** 17855 * When using a source handler, prefer its implementation of 17856 * any function normally provided by the tech. 17857 */ 17858 var deferrable = ['seekable', 'duration']; 17859 17860 /** 17861 * A wrapper around {@link Tech#seekable} that will call a `SourceHandler`s seekable 17862 * function if it exists, with a fallback to the Techs seekable function. 17863 * 17864 * @method _Tech.seekable 17865 */ 17866 17867 /** 17868 * A wrapper around {@link Tech#duration} that will call a `SourceHandler`s duration 17869 * function if it exists, otherwise it will fallback to the techs duration function. 17870 * 17871 * @method _Tech.duration 17872 */ 17873 17874 deferrable.forEach(function (fnName) { 17875 var originalFn = this[fnName]; 17876 17877 if (typeof originalFn !== 'function') { 17878 return; 17879 } 17880 17881 this[fnName] = function () { 17882 if (this.sourceHandler_ && this.sourceHandler_[fnName]) { 17883 return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments); 17884 } 17885 return originalFn.apply(this, arguments); 17886 }; 17887 }, _Tech.prototype); 17888 17889 /** 17890 * Create a function for setting the source using a source object 17891 * and source handlers. 17892 * Should never be called unless a source handler was found. 17893 * 17894 * @param {Tech~SourceObject} source 17895 * A source object with src and type keys 17896 * 17897 * @return {Tech} 17898 * Returns itself; this method is chainable 17899 */ 17900 _Tech.prototype.setSource = function (source) { 17901 var sh = _Tech.selectSourceHandler(source, this.options_); 17902 17903 if (!sh) { 17904 // Fall back to a native source hander when unsupported sources are 17905 // deliberately set 17906 if (_Tech.nativeSourceHandler) { 17907 sh = _Tech.nativeSourceHandler; 17908 } else { 17909 _log2['default'].error('No source hander found for the current source.'); 17910 } 17911 } 17912 17913 // Dispose any existing source handler 17914 this.disposeSourceHandler(); 17915 this.off('dispose', this.disposeSourceHandler); 17916 17917 if (sh !== _Tech.nativeSourceHandler) { 17918 this.currentSource_ = source; 17919 17920 // Catch if someone replaced the src without calling setSource. 17921 // If they do, set currentSource_ to null and dispose our source handler. 17922 this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_); 17923 this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); 17924 this.one(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_); 17925 } 17926 17927 this.sourceHandler_ = sh.handleSource(source, this, this.options_); 17928 this.on('dispose', this.disposeSourceHandler); 17929 17930 return this; 17931 }; 17932 17933 /** 17934 * Called once for the first loadstart of a video. 17935 * 17936 * @listens Tech#loadstart 17937 */ 17938 _Tech.prototype.firstLoadStartListener_ = function () { 17939 this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); 17940 }; 17941 17942 // On successive loadstarts when setSource has not been called again 17943 /** 17944 * Called after the first loadstart for a video occurs. 17945 * 17946 * @listens Tech#loadstart 17947 */ 17948 _Tech.prototype.successiveLoadStartListener_ = function () { 17949 this.disposeSourceHandler(); 17950 this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); 17951 }; 17952 17953 /** 17954 * Clean up any existing SourceHandlers and listeners when the Tech is disposed. 17955 * 17956 * @listens Tech#dispose 17957 */ 17958 _Tech.prototype.disposeSourceHandler = function () { 17959 // if we have a source and get another one 17960 // then we are loading something new 17961 // than clear all of our current tracks 17962 if (this.currentSource_) { 17963 this.clearTracks(['audio', 'video']); 17964 this.currentSource_ = null; 17965 } 17966 17967 // always clean up auto-text tracks 17968 this.cleanupAutoTextTracks(); 17969 17970 if (this.sourceHandler_) { 17971 this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_); 17972 this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); 17973 17974 if (this.sourceHandler_.dispose) { 17975 this.sourceHandler_.dispose(); 17976 } 17977 17978 this.sourceHandler_ = null; 17979 } 17980 }; 17981}; 17982 17983_component2['default'].registerComponent('Tech', Tech); 17984// Old name for Tech 17985// @deprecated 17986_component2['default'].registerComponent('MediaTechController', Tech);
17987Tech.registerTech('Tech', Tech); 17988exports['default'] = Tech; 17989 17990},{"105":105,"46":46,"5":5,"63":63,"65":65,"66":66,"70":70,"72":72,"76":76,"79":79,"83":83,"86":86,"87":87,"88":88,"90":90,"94":94,"95":95}],63:[function(_dereq_,module,exports){ 17991'use strict'; 17992 17993exports.__esModule = true; 17994 17995var _trackList = _dereq_(74); 17996 17997var _trackList2 = _interopRequireDefault(_trackList); 17998 17999var _browser = _dereq_(78); 18000 18001var browser = _interopRequireWildcard(_browser); 18002 18003var _document = _dereq_(94); 18004 18005var _document2 = _interopRequireDefault(_document); 18006 18007function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 18008 18009function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18010 18011function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 18012 18013function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 18014 18015function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 18016 * @file audio-track-list.js 18017 */ 18018 18019 18020/** 18021 * Anywhere we call this function we diverge from the spec 18022 * as we only support one enabled audiotrack at a time 18023 * 18024 * @param {AudioTrackList} list 18025 * list to work on 18026 * 18027 * @param {AudioTrack} track 18028 * The track to skip 18029 * 18030 * @private 18031 */ 18032var disableOthers = function disableOthers(list, track) { 18033 for (var i = 0; i < list.length; i++) { 18034 if (track.id === list[i].id) { 18035 continue; 18036 } 18037 // another audio track is enabled, disable it 18038 list[i].enabled = false; 18039 } 18040}; 18041 18042/** 18043 * The current list of {@link AudioTrack} for a media file. 18044 * 18045 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist} 18046 * @extends TrackList 18047 */ 18048 18049var AudioTrackList = function (_TrackList) { 18050 _inherits(AudioTrackList, _TrackList); 18051 18052 /** 18053 * Create an instance of this class. 18054 * 18055 * @param {AudioTrack[]} [tracks=[]] 18056 * A list of `AudioTrack` to instantiate the list with. 18057 */ 18058 function AudioTrackList() { 18059 var _this, _ret; 18060 18061 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 18062 18063 _classCallCheck(this, AudioTrackList); 18064 18065 var list = void 0; 18066 18067 // make sure only 1 track is enabled 18068 // sorted from last index to first index 18069 for (var i = tracks.length - 1; i >= 0; i--) { 18070 if (tracks[i].enabled) { 18071 disableOthers(tracks, tracks[i]); 18072 break; 18073 } 18074 } 18075 18076 // IE8 forces us to implement inheritance ourselves 18077 // as it does not support Object.defineProperty properly 18078 if (browser.IS_IE8) { 18079 list = _document2['default'].createElement('custom'); 18080 for (var prop in _trackList2['default'].prototype) { 18081 if (prop !== 'constructor') { 18082 list[prop] = _trackList2['default'].prototype[prop]; 18083 } 18084 } 18085 for (var _prop in AudioTrackList.prototype) { 18086 if (_prop !== 'constructor') { 18087 list[_prop] = AudioTrackList.prototype[_prop]; 18088 } 18089 } 18090 } 18091
18092 list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this); 18093 list.changing_ = false; 18094 18095 return _ret = list, _possibleConstructorReturn(_this, _ret); 18096 } 18097 18098 /** 18099 * Add an {@link AudioTrack} to the `AudioTrackList`. 18100 * 18101 * @param {AudioTrack} track 18102 * The AudioTrack to add to the list 18103 * 18104 * @fires Track#addtrack 18105 * @private 18106 */ 18107 18108 18109 AudioTrackList.prototype.addTrack_ = function addTrack_(track) { 18110 var _this2 = this; 18111 18112 if (track.enabled) { 18113 disableOthers(this, track); 18114 } 18115 18116 _TrackList.prototype.addTrack_.call(this, track); 18117 // native tracks don't have this 18118 if (!track.addEventListener) { 18119 return; 18120 } 18121 18122 /** 18123 * @listens AudioTrack#enabledchange 18124 * @fires TrackList#change 18125 */ 18126 track.addEventListener('enabledchange', function () { 18127 // when we are disabling other tracks (since we don't support 18128 // more than one track at a time) we will set changing_ 18129 // to true so that we don't trigger additional change events 18130 if (_this2.changing_) { 18131 return; 18132 } 18133 _this2.changing_ = true; 18134 disableOthers(_this2, track); 18135 _this2.changing_ = false; 18136 _this2.trigger('change'); 18137 }); 18138 }; 18139 18140 /** 18141 * Add an {@link AudioTrack} to the `AudioTrackList`. 18142 * 18143 * @param {AudioTrack} track 18144 * The AudioTrack to add to the list 18145 * 18146 * @fires Track#addtrack 18147 */ 18148 18149 18150 AudioTrackList.prototype.addTrack = function addTrack(track) { 18151 this.addTrack_(track); 18152 }; 18153 18154 /** 18155 * Remove an {@link AudioTrack} from the `AudioTrackList`. 18156 * 18157 * @param {AudioTrack} track 18158 * The AudioTrack to remove from the list 18159 * 18160 * @fires Track#removetrack 18161 */ 18162 18163 18164 AudioTrackList.prototype.removeTrack = function removeTrack(track) { 18165 _TrackList.prototype.removeTrack_.call(this, track); 18166 }; 18167 18168 return AudioTrackList; 18169}(_trackList2['default']); 18170 18171exports['default'] = AudioTrackList; 18172 18173},{"74":74,"78":78,"94":94}],64:[function(_dereq_,module,exports){ 18174'use strict'; 18175 18176exports.__esModule = true; 18177 18178var _trackEnums = _dereq_(73); 18179 18180var _track = _dereq_(75); 18181 18182var _track2 = _interopRequireDefault(_track); 18183 18184var _mergeOptions = _dereq_(87); 18185 18186var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 18187 18188var _browser = _dereq_(78); 18189 18190var browser = _interopRequireWildcard(_browser); 18191 18192function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 18193 18194function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18195 18196function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 18197 18198function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 18199 18200function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 18201 18202/** 18203 * A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList} 18204 * only one `AudioTrack` in the list will be enabled at a time. 18205 * 18206 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack} 18207 * @extends Track 18208 */ 18209var AudioTrack = function (_Track) { 18210 _inherits(AudioTrack, _Track); 18211 18212 /** 18213 * Create an instance of this class. 18214 * 18215 * @param {Object} [options={}] 18216 * Object of option names and values 18217 * 18218 * @param {AudioTrack~Kind} [options.kind=''] 18219 * A valid audio track kind 18220 * 18221 * @param {string} [options.id='vjs_track_' + Guid.newGUID()] 18222 * A unique id for this AudioTrack. 18223 * 18224 * @param {string} [options.label=''] 18225 * The menu label for this track. 18226 * 18227 * @param {string} [options.language=''] 18228 * A valid two character language code. 18229 * 18230 * @param {boolean} [options.enabled] 18231 * If this track is the one that is currently playing. If this track is part of 18232 * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled. 18233 */ 18234 function AudioTrack() { 18235 var _this, _ret; 18236 18237 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 18238 18239 _classCallCheck(this, AudioTrack); 18240 18241 var settings = (0, _mergeOptions2['default'])(options, { 18242 kind: _trackEnums.AudioTrackKind[options.kind] || '' 18243 }); 18244 // on IE8 this will be a document element 18245 // for every other browser this will be a normal object
18246 var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this); 18247 var enabled = false; 18248 18249 if (browser.IS_IE8) { 18250 for (var prop in AudioTrack.prototype) { 18251 if (prop !== 'constructor') { 18252 track[prop] = AudioTrack.prototype[prop]; 18253 } 18254 } 18255 } 18256 /** 18257 * @member {boolean} enabled 18258 * If this `AudioTrack` is enabled or not. When setting this will 18259 * fire {@link AudioTrack#enabledchange} if the state of enabled is changed. 18260 * 18261 * @fires VideoTrack#selectedchange 18262 */ 18263 Object.defineProperty(track, 'enabled', { 18264 get: function get() { 18265 return enabled; 18266 }, 18267 set: function set(newEnabled) { 18268 // an invalid or unchanged value 18269 if (typeof newEnabled !== 'boolean' || newEnabled === enabled) { 18270 return; 18271 } 18272 enabled = newEnabled; 18273 18274 /** 18275 * An event that fires when enabled changes on this track. This allows 18276 * the AudioTrackList that holds this track to act accordingly. 18277 * 18278 * > Note: This is not part of the spec! Native tracks will do 18279 * this internally without an event. 18280 * 18281 * @event AudioTrack#enabledchange 18282 * @type {EventTarget~Event} 18283 */ 18284 this.trigger('enabledchange'); 18285 } 18286 }); 18287 18288 // if the user sets this track to selected then 18289 // set selected to that true value otherwise 18290 // we keep it false 18291 if (settings.enabled) { 18292 track.enabled = settings.enabled; 18293 } 18294 track.loaded_ = true; 18295 18296 return _ret = track, _possibleConstructorReturn(_this, _ret); 18297 } 18298 18299 return AudioTrack; 18300}(_track2['default']); 18301 18302exports['default'] = AudioTrack; 18303 18304},{"73":73,"75":75,"78":78,"87":87}],65:[function(_dereq_,module,exports){ 18305'use strict'; 18306 18307exports.__esModule = true; 18308 18309var _browser = _dereq_(78); 18310 18311var browser = _interopRequireWildcard(_browser); 18312 18313var _document = _dereq_(94); 18314 18315var _document2 = _interopRequireDefault(_document); 18316 18317function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18318 18319function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 18320 18321function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** 18322 * @file html-track-element-list.js 18323 */ 18324 18325/** 18326 * The current list of {@link HtmlTrackElement}s. 18327 */ 18328var HtmlTrackElementList = function () { 18329 18330 /** 18331 * Create an instance of this class. 18332 * 18333 * @param {HtmlTrackElement[]} [tracks=[]] 18334 * A list of `HtmlTrackElement` to instantiate the list with. 18335 */ 18336 function HtmlTrackElementList() { 18337 var trackElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 18338 18339 _classCallCheck(this, HtmlTrackElementList); 18340 18341 var list = this; // eslint-disable-line 18342 18343 if (browser.IS_IE8) { 18344 list = _document2['default'].createElement('custom'); 18345 18346 for (var prop in HtmlTrackElementList.prototype) { 18347 if (prop !== 'constructor') { 18348 list[prop] = HtmlTrackElementList.prototype[prop]; 18349 } 18350 } 18351 } 18352 18353 list.trackElements_ = []; 18354 18355 /** 18356 * @member {number} length 18357 * The current number of `Track`s in the this Trackist. 18358 */ 18359 Object.defineProperty(list, 'length', { 18360 get: function get() { 18361 return this.trackElements_.length; 18362 } 18363 }); 18364 18365 for (var i = 0, length = trackElements.length; i < length; i++) { 18366 list.addTrackElement_(trackElements[i]); 18367 } 18368 18369 if (browser.IS_IE8) { 18370 return list; 18371 } 18372 } 18373 18374 /** 18375 * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList` 18376 * 18377 * @param {HtmlTrackElement} trackElement 18378 * The track element to add to the list. 18379 * 18380 * @private 18381 */ 18382 18383 18384 HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) { 18385 var index = this.trackElements_.length; 18386 18387 if (!('' + index in this)) { 18388 Object.defineProperty(this, index, { 18389 get: function get() { 18390 return this.trackElements_[index]; 18391 } 18392 }); 18393 } 18394
18395 // Do not add duplicate elements 18396 if (this.trackElements_.indexOf(trackElement) === -1) { 18397 this.trackElements_.push(trackElement); 18398 } 18399 }; 18400 18401 /** 18402 * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an 18403 * {@link TextTrack}. 18404 * 18405 * @param {TextTrack} track 18406 * The track associated with a track element. 18407 * 18408 * @return {HtmlTrackElement|undefined} 18409 * The track element that was found or undefined. 18410 * 18411 * @private 18412 */ 18413 18414 18415 HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) { 18416 var trackElement_ = void 0; 18417 18418 for (var i = 0, length = this.trackElements_.length; i < length; i++) { 18419 if (track === this.trackElements_[i].track) { 18420 trackElement_ = this.trackElements_[i]; 18421 18422 break; 18423 } 18424 } 18425 18426 return trackElement_; 18427 }; 18428 18429 /** 18430 * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList` 18431 * 18432 * @param {HtmlTrackElement} trackElement 18433 * The track element to remove from the list. 18434 * 18435 * @private 18436 */ 18437 18438 18439 HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) { 18440 for (var i = 0, length = this.trackElements_.length; i < length; i++) { 18441 if (trackElement === this.trackElements_[i]) { 18442 this.trackElements_.splice(i, 1); 18443 18444 break; 18445 } 18446 } 18447 }; 18448 18449 return HtmlTrackElementList; 18450}(); 18451 18452exports['default'] = HtmlTrackElementList; 18453 18454},{"78":78,"94":94}],66:[function(_dereq_,module,exports){ 18455'use strict'; 18456 18457exports.__esModule = true; 18458 18459var _browser = _dereq_(78); 18460 18461var browser = _interopRequireWildcard(_browser); 18462 18463var _document = _dereq_(94); 18464 18465var _document2 = _interopRequireDefault(_document); 18466 18467var _eventTarget = _dereq_(42); 18468 18469var _eventTarget2 = _interopRequireDefault(_eventTarget); 18470 18471var _textTrack = _dereq_(72); 18472 18473var _textTrack2 = _interopRequireDefault(_textTrack); 18474 18475function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18476 18477function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 18478 18479function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 18480 18481function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 18482 18483function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 18484 * @file html-track-element.js 18485 */ 18486 18487/** 18488 * @typedef {HTMLTrackElement~ReadyState} 18489 * @enum {number} 18490 */ 18491var NONE = 0; 18492var LOADING = 1; 18493var LOADED = 2; 18494var ERROR = 3; 18495 18496/** 18497 * A single track represented in the DOM. 18498 * 18499 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement}
18500 * @extends EventTarget 18501 */ 18502 18503var HTMLTrackElement = function (_EventTarget) { 18504 _inherits(HTMLTrackElement, _EventTarget); 18505 18506 /** 18507 * Create an instance of this class. 18508 * 18509 * @param {Object} options={} 18510 * Object of option names and values 18511 * 18512 * @param {Tech} options.tech 18513 * A reference to the tech that owns this HTMLTrackElement. 18514 * 18515 * @param {TextTrack~Kind} [options.kind='subtitles'] 18516 * A valid text track kind. 18517 * 18518 * @param {TextTrack~Mode} [options.mode='disabled'] 18519 * A valid text track mode. 18520 * 18521 * @param {string} [options.id='vjs_track_' + Guid.newGUID()] 18522 * A unique id for this TextTrack. 18523 * 18524 * @param {string} [options.label=''] 18525 * The menu label for this track. 18526 * 18527 * @param {string} [options.language=''] 18528 * A valid two character language code. 18529 * 18530 * @param {string} [options.srclang=''] 18531 * A valid two character language code. An alternative, but deprioritized 18532 * vesion of `options.language` 18533 * 18534 * @param {string} [options.src] 18535 * A url to TextTrack cues. 18536 * 18537 * @param {boolean} [options.default] 18538 * If this track should default to on or off. 18539 */ 18540 function HTMLTrackElement() { 18541 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 18542 18543 _classCallCheck(this, HTMLTrackElement); 18544 18545 var _this = _possibleConstructorReturn(this, _EventTarget.call(this)); 18546 18547 var readyState = void 0; 18548 var trackElement = _this; // eslint-disable-line 18549 18550 if (browser.IS_IE8) { 18551 trackElement = _document2['default'].createElement('custom'); 18552 18553 for (var prop in HTMLTrackElement.prototype) { 18554 if (prop !== 'constructor') { 18555 trackElement[prop] = HTMLTrackElement.prototype[prop]; 18556 } 18557 } 18558 } 18559 18560 var track = new _textTrack2['default'](options); 18561 18562 trackElement.kind = track.kind; 18563 trackElement.src = track.src; 18564 trackElement.srclang = track.language; 18565 trackElement.label = track.label; 18566 trackElement['default'] = track['default']; 18567 18568 /** 18569 * @member {HTMLTrackElement~ReadyState} readyState 18570 * The current ready state of the track element. 18571 */ 18572 Object.defineProperty(trackElement, 'readyState', { 18573 get: function get() { 18574 return readyState; 18575 } 18576 }); 18577 18578 /** 18579 * @member {TextTrack} track 18580 * The underlying TextTrack object. 18581 */ 18582 Object.defineProperty(trackElement, 'track', { 18583 get: function get() { 18584 return track; 18585 } 18586 }); 18587 18588 readyState = NONE; 18589 18590 /** 18591 * @listens TextTrack#loadeddata 18592 * @fires HTMLTrackElement#load 18593 */ 18594 track.addEventListener('loadeddata', function () { 18595 readyState = LOADED; 18596 18597 trackElement.trigger({ 18598 type: 'load', 18599 target: trackElement 18600 }); 18601 }); 18602 18603 if (browser.IS_IE8) { 18604 var _ret; 18605 18606 return _ret = trackElement, _possibleConstructorReturn(_this, _ret); 18607 } 18608 return _this; 18609 } 18610 18611 return HTMLTrackElement; 18612}(_eventTarget2['default']); 18613 18614HTMLTrackElement.prototype.allowedEvents_ = { 18615 load: 'load' 18616}; 18617 18618HTMLTrackElement.NONE = NONE; 18619HTMLTrackElement.LOADING = LOADING; 18620HTMLTrackElement.LOADED = LOADED; 18621HTMLTrackElement.ERROR = ERROR; 18622 18623exports['default'] = HTMLTrackElement; 18624 18625},{"42":42,"72":72,"78":78,"94":94}],67:[function(_dereq_,module,exports){ 18626'use strict'; 18627 18628exports.__esModule = true; 18629 18630var _browser = _dereq_(78); 18631 18632var browser = _interopRequireWildcard(_browser); 18633 18634var _document = _dereq_(94); 18635 18636var _document2 = _interopRequireDefault(_document); 18637 18638function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18639 18640function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 18641 18642function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** 18643 * @file text-track-cue-list.js 18644 */ 18645 18646 18647/** 18648 * @typedef {Object} TextTrackCue 18649 * 18650 * @property {string} id 18651 * The unique id for this text track cue 18652 * 18653 * @property {number} startTime 18654 * The start time for this text track cue 18655 * 18656 * @property {number} endTime 18657 * The end time for this text track cue 18658 * 18659 * @property {boolean} pauseOnExit 18660 * Pause when the end time is reached if true. 18661 * 18662 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue} 18663 */ 18664 18665/** 18666 * A List of TextTrackCues. 18667 * 18668 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist} 18669 */ 18670var TextTrackCueList = function () { 18671 18672 /** 18673 * Create an instance of this class.. 18674 * 18675 * @param {Array} cues 18676 * A list of cues to be initialized with 18677 */ 18678 function TextTrackCueList(cues) { 18679 _classCallCheck(this, TextTrackCueList); 18680 18681 var list = this; // eslint-disable-line 18682 18683 if (browser.IS_IE8) { 18684 list = _document2['default'].createElement('custom'); 18685 18686 for (var prop in TextTrackCueList.prototype) { 18687 if (prop !== 'constructor') { 18688 list[prop] = TextTrackCueList.prototype[prop]; 18689 } 18690 } 18691 } 18692 18693 TextTrackCueList.prototype.setCues_.call(list, cues); 18694 18695 /** 18696 * @member {number} length 18697 * The current number of `TextTrackCue`s in the TextTrackCueList. 18698 */ 18699 Object.defineProperty(list, 'length', { 18700 get: function get() { 18701 return this.length_; 18702 } 18703 }); 18704 18705 if (browser.IS_IE8) { 18706 return list; 18707 } 18708 } 18709 18710 /** 18711 * A setter for cues in this list. Creates getters 18712 * an an index for the cues. 18713 * 18714 * @param {Array} cues 18715 * An array of cues to set 18716 * 18717 * @private 18718 */ 18719 18720 18721 TextTrackCueList.prototype.setCues_ = function setCues_(cues) { 18722 var oldLength = this.length || 0; 18723 var i = 0; 18724 var l = cues.length; 18725 18726 this.cues_ = cues; 18727 this.length_ = cues.length; 18728 18729 var defineProp = function defineProp(index) { 18730 if (!('' + index in this)) { 18731 Object.defineProperty(this, '' + index, { 18732 get: function get() { 18733 return this.cues_[index]; 18734 } 18735 }); 18736 } 18737 }; 18738 18739 if (oldLength < l) { 18740 i = oldLength; 18741 18742 for (; i < l; i++) { 18743 defineProp.call(this, i); 18744 } 18745 } 18746 }; 18747 18748 /** 18749 * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id. 18750 * 18751 * @param {string} id 18752 * The id of the cue that should be searched for. 18753 * 18754 * @return {TextTrackCue|null} 18755 * A single cue or null if none was found. 18756 */ 18757 18758 18759 TextTrackCueList.prototype.getCueById = function getCueById(id) { 18760 var result = null; 18761 18762 for (var i = 0, l = this.length; i < l; i++) { 18763 var cue = this[i]; 18764 18765 if (cue.id === id) { 18766 result = cue; 18767 break; 18768 } 18769 } 18770 18771 return result; 18772 }; 18773 18774 return TextTrackCueList; 18775}(); 18776 18777exports['default'] = TextTrackCueList; 18778 18779},{"78":78,"94":94}],68:[function(_dereq_,module,exports){ 18780'use strict'; 18781 18782exports.__esModule = true; 18783 18784var _component = _dereq_(5); 18785 18786var _component2 = _interopRequireDefault(_component); 18787 18788var _fn = _dereq_(83); 18789 18790var Fn = _interopRequireWildcard(_fn); 18791 18792var _window = _dereq_(95); 18793 18794var _window2 = _interopRequireDefault(_window); 18795 18796function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 18797 18798function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18799 18800function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 18801 18802function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 18803 18804function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
18804onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 18805 * @file text-track-display.js 18806 */ 18807 18808 18809var darkGray = '#222'; 18810var lightGray = '#ccc'; 18811var fontMap = { 18812 monospace: 'monospace', 18813 sansSerif: 'sans-serif', 18814 serif: 'serif', 18815 monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace', 18816 monospaceSerif: '"Courier New", monospace', 18817 proportionalSansSerif: 'sans-serif', 18818 proportionalSerif: 'serif', 18819 casual: '"Comic Sans MS", Impact, fantasy', 18820 script: '"Monotype Corsiva", cursive', 18821 smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif' 18822}; 18823 18824/** 18825 * Construct an rgba color from a given hex color code. 18826 * 18827 * @param {number} color 18828 * Hex number for color, like #f0e. 18829 * 18830 * @param {number} opacity 18831 * Value for opacity, 0.0 - 1.0. 18832 * 18833 * @return {string} 18834 * The rgba color that was created, like 'rgba(255, 0, 0, 0.3)'. 18835 * 18836 * @private 18837 */ 18838function constructColor(color, opacity) { 18839 return 'rgba(' + 18840 // color looks like "#f0e" 18841 parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')'; 18842} 18843 18844/** 18845 * Try to update the style of a DOM element. Some style changes will throw an error, 18846 * particularly in IE8. Those should be noops. 18847 * 18848 * @param {Element} el 18849 * The DOM element to be styled. 18850 * 18851 * @param {string} style 18852 * The CSS property on the element that should be styled. 18853 * 18854 * @param {string} rule 18855 * The style rule that should be applied to the property. 18856 */ 18857function tryUpdateStyle(el, style, rule) { 18858 try { 18859 el.style[style] = rule; 18860 } catch (e) { 18861 18862 // Satisfies linter. 18863 return; 18864 } 18865} 18866 18867/** 18868 * The component for displaying text track cues. 18869 * 18870 * @extends Component 18871 */ 18872 18873var TextTrackDisplay = function (_Component) { 18874 _inherits(TextTrackDisplay, _Component); 18875 18876 /** 18877 * Creates an instance of this class. 18878 * 18879 * @param {Player} player 18880 * The `Player` that this class should be attached to. 18881 * 18882 * @param {Object} [options] 18883 * The key/value store of player options. 18884 * 18885 * @param {Component~ReadyCallback} [ready] 18886 * The function to call when `TextTrackDisplay` is ready. 18887 */ 18888 function TextTrackDisplay(player, options, ready) { 18889 _classCallCheck(this, TextTrackDisplay); 18890 18891 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready)); 18892 18893 player.on('loadstart', Fn.bind(_this, _this.toggleDisplay)); 18894 player.on('texttrackchange', Fn.bind(_this, _this.updateDisplay)); 18895 18896 // This used to be called during player init, but was causing an error 18897 // if a track should show by default and the display hadn't loaded yet. 18898 // Should probably be moved to an external track loader when we support 18899 // tracks that don't need a display. 18900 player.ready(Fn.bind(_this, function () { 18901 if (player.tech_ && player.tech_.featuresNativeTextTracks) { 18902 this.hide(); 18903 return; 18904 } 18905 18906 player.on('fullscreenchange', Fn.bind(this, this.updateDisplay)); 18907 18908 var tracks = this.options_.playerOptions.tracks || []; 18909 18910 for (var i = 0; i < tracks.length; i++) { 18911 this.player_.addRemoteTextTrack(tracks[i], true); 18912 } 18913 18914 var modes = { captions: 1, subtitles: 1 }; 18915 var trackList = this.player_.textTracks(); 18916 var firstDesc = void 0; 18917 var firstCaptions = void 0; 18918 18919 if (trackList) { 18920 for (var _i = 0; _i < trackList.length; _i++) { 18921 var track = trackList[_i]; 18922 18923 if (track['default']) { 18924 if (track.kind === 'descriptions' && !firstDesc) { 18925 firstDesc = track; 18926 } else if (track.kind in modes && !firstCaptions) { 18927 firstCaptions = track; 18928 } 18929 } 18930 } 18931 18932 // We want to show the first default track but captions and subtitles 18933 // take precedence over descriptions. 18934 // So, display the first default captions or subtitles track 18935 // and otherwise the first default descriptions track. 18936 if (firstCaptions) { 18937 firstCaptions.mode = 'showing'; 18938 } else if (firstDesc) { 18939 firstDesc.mode = 'showing'; 18940 } 18941 } 18942 })); 18943 return _this; 18944 } 18945 18946 /** 18947 * Turn display of {@link TextTrack}'s from the current state into the other state. 18948 * There are only two states: 18949 * - 'shown' 18950 * - 'hidden' 18951 * 18952 * @listens Player#loadstart 18953 */ 18954 18955 18956 TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() { 18957 if (this.player_.tech_ && this.player_.tech_.featuresNativeTextTracks) { 18958 this.hide(); 18959 } else { 18960 this.show(); 18961 } 18962 }; 18963 18964 /** 18965 * Create the {@link Component}'s DOM element. 18966 * 18967 * @return {Element} 18968 * The element that was created. 18969 */ 18970 18971 18972 TextTrackDisplay.prototype.createEl = function createEl() { 18973 return _Component.prototype.createEl.call(this, 'div', { 18974 className: 'vjs-text-track-display' 18975 }, {
18976 'aria-live': 'off', 18977 'aria-atomic': 'true' 18978 }); 18979 }; 18980 18981 /** 18982 * Clear all displayed {@link TextTrack}s. 18983 */ 18984 18985 18986 TextTrackDisplay.prototype.clearDisplay = function clearDisplay() { 18987 if (typeof _window2['default'].WebVTT === 'function') { 18988 _window2['default'].WebVTT.processCues(_window2['default'], [], this.el_); 18989 } 18990 }; 18991 18992 /** 18993 * Update the displayed TextTrack when a either a {@link Player#texttrackchange} or 18994 * a {@link Player#fullscreenchange} is fired. 18995 * 18996 * @listens Player#texttrackchange 18997 * @listens Player#fullscreenchange 18998 */ 18999 19000 19001 TextTrackDisplay.prototype.updateDisplay = function updateDisplay() { 19002 var tracks = this.player_.textTracks(); 19003 19004 this.clearDisplay(); 19005 19006 if (!tracks) { 19007 return; 19008 } 19009 19010 // Track display prioritization model: if multiple tracks are 'showing', 19011 // display the first 'subtitles' or 'captions' track which is 'showing', 19012 // otherwise display the first 'descriptions' track which is 'showing' 19013 19014 var descriptionsTrack = null; 19015 var captionsSubtitlesTrack = null; 19016 19017 var i = tracks.length; 19018 19019 while (i--) { 19020 var track = tracks[i]; 19021 19022 if (track.mode === 'showing') { 19023 if (track.kind === 'descriptions') { 19024 descriptionsTrack = track; 19025 } else { 19026 captionsSubtitlesTrack = track; 19027 } 19028 } 19029 } 19030 19031 if (captionsSubtitlesTrack) { 19032 if (this.getAttribute('aria-live') !== 'off') { 19033 this.setAttribute('aria-live', 'off'); 19034 } 19035 this.updateForTrack(captionsSubtitlesTrack); 19036 } else if (descriptionsTrack) { 19037 if (this.getAttribute('aria-live') !== 'assertive') { 19038 this.setAttribute('aria-live', 'assertive'); 19039 } 19040 this.updateForTrack(descriptionsTrack); 19041 } 19042 }; 19043 19044 /** 19045 * Add an {@link Texttrack} to to the {@link Tech}s {@link TextTrackList}. 19046 * 19047 * @param {TextTrack} track 19048 * Text track object to be added to the list. 19049 */ 19050 19051 19052 TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) { 19053 if (typeof _window2['default'].WebVTT !== 'function' || !track.activeCues) { 19054 return; 19055 } 19056 19057 var overrides = this.player_.textTrackSettings.getValues(); 19058 var cues = []; 19059 19060 for (var _i2 = 0; _i2 < track.activeCues.length; _i2++) { 19061 cues.push(track.activeCues[_i2]); 19062 } 19063 19064 _window2['default'].WebVTT.processCues(_window2['default'], cues, this.el_); 19065 19066 var i = cues.length; 19067 19068 while (i--) { 19069 var cue = cues[i]; 19070 19071 if (!cue) { 19072 continue; 19073 } 19074 19075 var cueDiv = cue.displayState; 19076 19077 if (overrides.color) { 19078 cueDiv.firstChild.style.color = overrides.color; 19079 } 19080 if (overrides.textOpacity) { 19081 tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity)); 19082 } 19083 if (overrides.backgroundColor) { 19084 cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor; 19085 } 19086 if (overrides.backgroundOpacity) { 19087 tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity)); 19088 } 19089 if (overrides.windowColor) { 19090 if (overrides.windowOpacity) { 19091 tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity)); 19092 } else { 19093 cueDiv.style.backgroundColor = overrides.windowColor; 19094 } 19095 } 19096 if (overrides.edgeStyle) { 19097 if (overrides.edgeStyle === 'dropshadow') { 19098 cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray; 19099 } else if (overrides.edgeStyle === 'raised') { 19100 cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray; 19101 } else if (overrides.edgeStyle === 'depressed') { 19102 cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray; 19103 } else if (overrides.edgeStyle === 'uniform') { 19104 cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray; 19105 } 19106 } 19107 if (overrides.fontPercent && overrides.fontPercent !== 1) { 19108 var fontSize = _window2['default'].parseFloat(cueDiv.style.fontSize); 19109 19110 cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px'; 19111 cueDiv.style.height = 'auto'; 19112 cueDiv.style.top = 'auto'; 19113 cueDiv.style.bottom = '2px'; 19114 } 19115 if (overrides.fontFamily && overrides.fontFamily !== 'default') { 19116 if (overrides.fontFamily === 'small-caps') { 19117 cueDiv.firstChild.style.fontVariant = 'small-caps'; 19118 } else { 19119 cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily]; 19120 } 19121 } 19122 } 19123 }; 19124 19125 return TextTrackDisplay; 19126}(_component2['default']); 19127 19128_component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay); 19129exports['default'] = TextTrackDisplay; 19130 19131},{"5":5,"83":83,"95":95}],69:[function(_dereq_,module,exports){ 19132'use strict'; 19133 19134exports.__esModule = true; 19135/** 19136 * @file text-track-list-converter.js Utilities for capturing text track state and 19137 * re-creating tracks based on a capture. 19138 * 19139 * @module text-track-list-converter 19140 */ 19141 19142/**
19143 * Examine a single {@link TextTrack} and return a JSON-compatible javascript object that 19144 * represents the {@link TextTrack}'s state. 19145 * 19146 * @param {TextTrack} track 19147 * The text track to query. 19148 * 19149 * @return {Object} 19150 * A serializable javascript representation of the TextTrack. 19151 * @private 19152 */ 19153var trackToJson_ = function trackToJson_(track) { 19154 var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) { 19155 19156 if (track[prop]) { 19157 acc[prop] = track[prop]; 19158 } 19159 19160 return acc; 19161 }, { 19162 cues: track.cues && Array.prototype.map.call(track.cues, function (cue) { 19163 return { 19164 startTime: cue.startTime, 19165 endTime: cue.endTime, 19166 text: cue.text, 19167 id: cue.id 19168 }; 19169 }) 19170 }); 19171 19172 return ret; 19173}; 19174 19175/** 19176 * Examine a {@link Tech} and return a JSON-compatible javascript array that represents the 19177 * state of all {@link TextTrack}s currently configured. The return array is compatible with 19178 * {@link text-track-list-converter:jsonToTextTracks}. 19179 * 19180 * @param {Tech} tech 19181 * The tech object to query 19182 * 19183 * @return {Array} 19184 * A serializable javascript representation of the {@link Tech}s 19185 * {@link TextTrackList}. 19186 */ 19187var textTracksToJson = function textTracksToJson(tech) { 19188 19189 var trackEls = tech.$$('track'); 19190 19191 var trackObjs = Array.prototype.map.call(trackEls, function (t) { 19192 return t.track; 19193 }); 19194 var tracks = Array.prototype.map.call(trackEls, function (trackEl) { 19195 var json = trackToJson_(trackEl.track); 19196 19197 if (trackEl.src) { 19198 json.src = trackEl.src; 19199 } 19200 return json; 19201 }); 19202 19203 return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) { 19204 return trackObjs.indexOf(track) === -1; 19205 }).map(trackToJson_)); 19206}; 19207 19208/** 19209 * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript 19210 * object {@link TextTrack} representations. 19211 * 19212 * @param {Array} json 19213 * An array of `TextTrack` representation objects, like those that would be 19214 * produced by `textTracksToJson`. 19215 * 19216 * @param {Tech} tech 19217 * The `Tech` to create the `TextTrack`s on. 19218 */ 19219var jsonToTextTracks = function jsonToTextTracks(json, tech) { 19220 json.forEach(function (track) { 19221 var addedTrack = tech.addRemoteTextTrack(track).track; 19222 19223 if (!track.src && track.cues) { 19224 track.cues.forEach(function (cue) { 19225 return addedTrack.addCue(cue); 19226 }); 19227 } 19228 }); 19229 19230 return tech.textTracks(); 19231}; 19232 19233exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ }; 19234 19235},{}],70:[function(_dereq_,module,exports){ 19236'use strict'; 19237 19238exports.__esModule = true; 19239 19240var _trackList = _dereq_(74); 19241 19242var _trackList2 = _interopRequireDefault(_trackList); 19243 19244var _fn = _dereq_(83); 19245 19246var Fn = _interopRequireWildcard(_fn); 19247 19248var _browser = _dereq_(78); 19249 19250var browser = _interopRequireWildcard(_browser); 19251 19252var _document = _dereq_(94); 19253 19254var _document2 = _interopRequireDefault(_document); 19255 19256function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 19257 19258function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19259 19260function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 19261 19262function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 19263 19264function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 19265 * @file text-track-list.js 19266 */ 19267 19268 19269/** 19270 * The current list of {@link TextTrack} for a media file. 19271 * 19272 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist} 19273 * @extends TrackList 19274 */ 19275var TextTrackList = function (_TrackList) { 19276 _inherits(TextTrackList, _TrackList); 19277 19278 /** 19279 * Create an instance of this class. 19280 * 19281 * @param {TextTrack[]} [tracks=[]] 19282 * A list of `TextTrack` to instantiate the list with. 19283 */ 19284 function TextTrackList() { 19285 var _this, _ret; 19286 19287 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 19288 19289 _classCallCheck(this, TextTrackList); 19290 19291 var list = void 0; 19292 19293 // IE8 forces us to implement inheritance ourselves 19294 // as it does not support Object.defineProperty properly 19295 if (browser.IS_IE8) { 19296 list = _document2['default'].createElement('custom'); 19297 for (var prop in _trackList2['default'].prototype) { 19298 if (prop !== 'constructor') { 19299 list[prop] = _trackList2['default'].prototype[prop]; 19300 } 19301 } 19302 for (var _prop in TextTrackList.prototype) { 19303 if (_prop !== 'constructor') { 19304 list[_prop] = TextTrackList.prototype[_prop]; 19305 } 19306 } 19307 } 19308
19309 list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this); 19310 return _ret = list, _possibleConstructorReturn(_this, _ret); 19311 } 19312 19313 /** 19314 * Add a {@link TextTrack} to the `TextTrackList` 19315 * 19316 * @param {TextTrack} track 19317 * The text track to add to the list. 19318 * 19319 * @fires TrackList#addtrack 19320 * @private 19321 */ 19322 19323 19324 TextTrackList.prototype.addTrack_ = function addTrack_(track) { 19325 _TrackList.prototype.addTrack_.call(this, track); 19326 19327 /** 19328 * @listens TextTrack#modechange 19329 * @fires TrackList#change 19330 */ 19331 track.addEventListener('modechange', Fn.bind(this, function () { 19332 this.trigger('change'); 19333 })); 19334 }; 19335 19336 return TextTrackList; 19337}(_trackList2['default']); 19338 19339exports['default'] = TextTrackList; 19340 19341},{"74":74,"78":78,"83":83,"94":94}],71:[function(_dereq_,module,exports){ 19342'use strict'; 19343 19344exports.__esModule = true; 19345 19346var _window = _dereq_(95); 19347 19348var _window2 = _interopRequireDefault(_window); 19349 19350var _component = _dereq_(5); 19351 19352var _component2 = _interopRequireDefault(_component); 19353 19354var _dom = _dereq_(81); 19355 19356var _fn = _dereq_(83); 19357 19358var Fn = _interopRequireWildcard(_fn); 19359 19360var _obj = _dereq_(88); 19361 19362var Obj = _interopRequireWildcard(_obj); 19363 19364var _log = _dereq_(86); 19365 19366var _log2 = _interopRequireDefault(_log); 19367 19368function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 19369 19370function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19371 19372function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 19373 19374function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 19375 19376function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 19377 * @file text-track-settings.js 19378 */ 19379 19380 19381var LOCAL_STORAGE_KEY = 'vjs-text-track-settings'; 19382 19383var COLOR_BLACK = ['#000', 'Black']; 19384var COLOR_BLUE = ['#00F', 'Blue']; 19385var COLOR_CYAN = ['#0FF', 'Cyan']; 19386var COLOR_GREEN = ['#0F0', 'Green']; 19387var COLOR_MAGENTA = ['#F0F', 'Magenta']; 19388var COLOR_RED = ['#F00', 'Red']; 19389var COLOR_WHITE = ['#FFF', 'White']; 19390var COLOR_YELLOW = ['#FF0', 'Yellow']; 19391 19392var OPACITY_OPAQUE = ['1', 'Opaque']; 19393var OPACITY_SEMI = ['0.5', 'Semi-Transparent']; 19394var OPACITY_TRANS = ['0', 'Transparent']; 19395 19396// Configuration for the various <select> elements in the DOM of this component. 19397// 19398// Possible keys include: 19399// 19400// `default`: 19401// The default option index. Only needs to be provided if not zero. 19402// `parser`: 19403// A function which is used to parse the value from the selected option in 19404// a customized way. 19405// `selector`: 19406// The selector used to find the associated <select> element. 19407var selectConfigs = { 19408 backgroundColor: { 19409 selector: '.vjs-bg-color > select', 19410 id: 'captions-background-color-%s', 19411 label: 'Color', 19412 options: [COLOR_BLACK, COLOR_WHITE, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN] 19413 }, 19414 19415 backgroundOpacity: { 19416 selector: '.vjs-bg-opacity > select', 19417 id: 'captions-background-opacity-%s', 19418 label: 'Transparency', 19419 options: [OPACITY_OPAQUE, OPACITY_SEMI, OPACITY_TRANS] 19420 }, 19421 19422 color: { 19423 selector: '.vjs-fg-color > select', 19424 id: 'captions-foreground-color-%s', 19425 label: 'Color', 19426 options: [COLOR_WHITE, COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN] 19427 }, 19428 19429 edgeStyle: { 19430 selector: '.vjs-edge-style > select', 19431 id: '%s', 19432 label: 'Text Edge Style', 19433 options: [['none', 'None'], ['raised', 'Raised'], ['depressed', 'Depressed'], ['uniform', 'Uniform'], ['dropshadow', 'Dropshadow']] 19434 }, 19435 19436 fontFamily: { 19437 selector: '.vjs-font-family > select', 19438 id: 'captions-font-family-%s', 19439 label: 'Font Family', 19440 options: [['proportionalSansSerif', 'Proportional Sans-Serif'], ['monospaceSansSerif', 'Monospace Sans-Serif'], ['proportionalSerif', 'Proportional Serif'], ['monospaceSerif', 'Monospace Serif'], ['casual', 'Casual'], ['script', 'Script'], ['small-caps', '
vendor: 4,800 bytes, lines 19440-19629
19440Small Caps']] 19441 }, 19442 19443 fontPercent: { 19444 selector: '.vjs-font-percent > select', 19445 id: 'captions-font-size-%s', 19446 label: 'Font Size', 19447 options: [['0.50', '50%'], ['0.75', '75%'], ['1.00', '100%'], ['1.25', '125%'], ['1.50', '150%'], ['1.75', '175%'], ['2.00', '200%'], ['3.00', '300%'], ['4.00', '400%']], 19448 'default': 2, 19449 parser: function parser(v) { 19450 return v === '1.00' ? null : Number(v); 19451 } 19452 }, 19453 19454 textOpacity: { 19455 selector: '.vjs-text-opacity > select', 19456 id: 'captions-foreground-opacity-%s', 19457 label: 'Transparency', 19458 options: [OPACITY_OPAQUE, OPACITY_SEMI] 19459 }, 19460 19461 // Options for this object are defined below. 19462 windowColor: { 19463 selector: '.vjs-window-color > select', 19464 id: 'captions-window-color-%s', 19465 label: 'Color' 19466 }, 19467 19468 // Options for this object are defined below. 19469 windowOpacity: { 19470 selector: '.vjs-window-opacity > select', 19471 id: 'captions-window-opacity-%s', 19472 label: 'Transparency', 19473 options: [OPACITY_TRANS, OPACITY_SEMI, OPACITY_OPAQUE] 19474 } 19475}; 19476 19477selectConfigs.windowColor.options = selectConfigs.backgroundColor.options; 19478 19479/** 19480 * Get the actual value of an option. 19481 * 19482 * @param {string} value 19483 * The value to get 19484 * 19485 * @param {Function} [parser] 19486 * Optional function to adjust the value. 19487 * 19488 * @return {Mixed} 19489 * - Will be `undefined` if no value exists 19490 * - Will be `undefined` if the given value is "none". 19491 * - Will be the actual value otherwise. 19492 * 19493 * @private 19494 */ 19495function parseOptionValue(value, parser) { 19496 if (parser) { 19497 value = parser(value); 19498 } 19499 19500 if (value && value !== 'none') { 19501 return value; 19502 } 19503} 19504 19505/** 19506 * Gets the value of the selected <option> element within a <select> element. 19507 * 19508 * @param {Element} el 19509 * the element to look in 19510 * 19511 * @param {Function} [parser] 19512 * Optional function to adjust the value. 19513 * 19514 * @return {Mixed} 19515 * - Will be `undefined` if no value exists 19516 * - Will be `undefined` if the given value is "none". 19517 * - Will be the actual value otherwise. 19518 * 19519 * @private 19520 */ 19521function getSelectedOptionValue(el, parser) { 19522 var value = el.options[el.options.selectedIndex].value; 19523 19524 return parseOptionValue(value, parser); 19525} 19526 19527/** 19528 * Sets the selected <option> element within a <select> element based on a 19529 * given value. 19530 * 19531 * @param {Element} el 19532 * The element to look in. 19533 * 19534 * @param {string} value 19535 * the property to look on. 19536 * 19537 * @param {Function} [parser] 19538 * Optional function to adjust the value before comparing. 19539 * 19540 * @private 19541 */ 19542function setSelectedOption(el, value, parser) { 19543 if (!value) { 19544 return; 19545 } 19546 19547 for (var i = 0; i < el.options.length; i++) { 19548 if (parseOptionValue(el.options[i].value, parser) === value) { 19549 el.selectedIndex = i; 19550 break; 19551 } 19552 } 19553} 19554 19555/** 19556 * Manipulate Text Tracks settings. 19557 * 19558 * @extends Component 19559 */ 19560 19561var TextTrackSettings = function (_Component) { 19562 _inherits(TextTrackSettings, _Component); 19563 19564 /** 19565 * Creates an instance of this class. 19566 * 19567 * @param {Player} player 19568 * The `Player` that this class should be attached to. 19569 * 19570 * @param {Object} [options] 19571 * The key/value store of player options. 19572 */ 19573 function TextTrackSettings(player, options) { 19574 _classCallCheck(this, TextTrackSettings); 19575 19576 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 19577 19578 _this.setDefaults(); 19579 _this.hide(); 19580 19581 _this.updateDisplay = Fn.bind(_this, _this.updateDisplay); 19582 19583 // Grab `persistTextTrackSettings` from the player options if not passed in child options 19584 if (options.persistTextTrackSettings === undefined) { 19585 _this.options_.persistTextTrackSettings = _this.options_.playerOptions.persistTextTrackSettings; 19586 } 19587 19588 _this.on(_this.$('.vjs-done-button'), 'click', function () { 19589 _this.saveSettings(); 19590 _this.hide(); 19591 }); 19592 19593 _this.on(_this.$('.vjs-default-button'), 'click', function () { 19594 _this.setDefaults(); 19595 _this.updateDisplay(); 19596 }); 19597 19598 Obj.each(selectConfigs, function (config) { 19599 _this.on(_this.$(config.selector), 'change', _this.updateDisplay); 19600 }); 19601 19602 if (_this.options_.persistTextTrackSettings) { 19603 _this.restoreSettings(); 19604 } 19605 return _this; 19606 } 19607 19608 /** 19609 * Create a <select> element with configured options. 19610 * 19611 * @param {string} key 19612 * Configuration key to use during creation. 19613 * 19614 * @return {Element} 19615 * The DOM element that gets created. 19616 * @private 19617 */ 19618 19619 19620 TextTrackSettings.prototype.createElSelect_ = function createElSelect_(key) { 19621 var _this2 = this; 19622 19623 var config = selectConfigs[key]; 19624 var id = config.id.replace('%s', this.id_); 19625 19626 return [(0, _dom.createEl)('label', { 19627 className: 'vjs-label', 19628 textContent: config.label 19629 }, {
19630 'for': id 19631 }), (0, _dom.createEl)('select', { id: id }, undefined, config.options.map(function (o) { 19632 return (0, _dom.createEl)('option', { 19633 textContent: _this2.localize(o[1]), 19634 value: o[0] 19635 }); 19636 }))]; 19637 }; 19638 19639 /** 19640 * Create foreground color element for the component 19641 * 19642 * @return {Element} 19643 * The element that was created. 19644 * 19645 * @private 19646 */ 19647 19648 19649 TextTrackSettings.prototype.createElFgColor_ = function createElFgColor_() { 19650 var legend = (0, _dom.createEl)('legend', { 19651 textContent: this.localize('Text') 19652 }); 19653 19654 var select = this.createElSelect_('color'); 19655 19656 var opacity = (0, _dom.createEl)('span', { 19657 className: 'vjs-text-opacity vjs-opacity' 19658 }, undefined, this.createElSelect_('textOpacity')); 19659 19660 return (0, _dom.createEl)('fieldset', { 19661 className: 'vjs-fg-color vjs-tracksetting' 19662 }, undefined, [legend].concat(select, opacity)); 19663 }; 19664 19665 /** 19666 * Create background color element for the component 19667 * 19668 * @return {Element} 19669 * The element that was created 19670 * 19671 * @private 19672 */ 19673 19674 19675 TextTrackSettings.prototype.createElBgColor_ = function createElBgColor_() { 19676 var legend = (0, _dom.createEl)('legend', { 19677 textContent: this.localize('Background') 19678 }); 19679 19680 var select = this.createElSelect_('backgroundColor'); 19681 19682 var opacity = (0, _dom.createEl)('span', { 19683 className: 'vjs-bg-opacity vjs-opacity' 19684 }, undefined, this.createElSelect_('backgroundOpacity')); 19685 19686 return (0, _dom.createEl)('fieldset', { 19687 className: 'vjs-bg-color vjs-tracksetting' 19688 }, undefined, [legend].concat(select, opacity)); 19689 }; 19690 19691 /** 19692 * Create window color element for the component 19693 * 19694 * @return {Element} 19695 * The element that was created 19696 * 19697 * @private 19698 */ 19699 19700 19701 TextTrackSettings.prototype.createElWinColor_ = function createElWinColor_() { 19702 var legend = (0, _dom.createEl)('legend', { 19703 textContent: this.localize('Window') 19704 }); 19705 19706 var select = this.createElSelect_('windowColor'); 19707 19708 var opacity = (0, _dom.createEl)('span', { 19709 className: 'vjs-window-opacity vjs-opacity' 19710 }, undefined, this.createElSelect_('windowOpacity')); 19711 19712 return (0, _dom.createEl)('fieldset', { 19713 className: 'vjs-window-color vjs-tracksetting' 19714 }, undefined, [legend].concat(select, opacity)); 19715 }; 19716 19717 /** 19718 * Create color elements for the component 19719 * 19720 * @return {Element} 19721 * The element that was created 19722 * 19723 * @private 19724 */ 19725 19726 19727 TextTrackSettings.prototype.createElColors_ = function createElColors_() { 19728 return (0, _dom.createEl)('div', { 19729 className: 'vjs-tracksettings-colors' 19730 }, undefined, [this.createElFgColor_(), this.createElBgColor_(), this.createElWinColor_()]); 19731 }; 19732 19733 /** 19734 * Create font elements for the component 19735 * 19736 * @return {Element} 19737 * The element that was created. 19738 * 19739 * @private 19740 */ 19741 19742 19743 TextTrackSettings.prototype.createElFont_ = function createElFont_() { 19744 var fontPercent = (0, _dom.createEl)('div', { 19745 className: 'vjs-font-percent vjs-tracksetting' 19746 }, undefined, this.createElSelect_('fontPercent')); 19747 19748 var edgeStyle = (0, _dom.createEl)('div', { 19749 className: 'vjs-edge-style vjs-tracksetting' 19750 }, undefined, this.createElSelect_('edgeStyle')); 19751 19752 var fontFamily = (0, _dom.createEl)('div', { 19753 className: 'vjs-font-family vjs-tracksetting' 19754 }, undefined, this.createElSelect_('fontFamily')); 19755 19756 return (0, _dom.createEl)('div', { 19757 className: 'vjs-tracksettings-font' 19758 }, undefined, [fontPercent, edgeStyle, fontFamily]); 19759 }; 19760 19761 /** 19762 * Create controls for the component 19763 * 19764 * @return {Element} 19765 * The element that was created. 19766 * 19767 * @private 19768 */ 19769 19770 19771 TextTrackSettings.prototype.createElControls_ = function createElControls_() { 19772 var defaultsButton = (0, _dom.createEl)('button', { 19773 className: 'vjs-default-button', 19774 textContent: this.localize('Defaults') 19775 }); 19776 19777 var doneButton = (0, _dom.createEl)('button', { 19778 className: 'vjs-done-button', 19779 textContent: 'Done' 19780 }); 19781 19782 return (0, _dom.createEl)('div', { 19783 className: 'vjs-tracksettings-controls' 19784 }, undefined, [defaultsButton, doneButton]); 19785 }; 19786 19787 /** 19788 * Create the component's DOM element 19789 * 19790 * @return {Element} 19791 * The element that was created. 19792 */ 19793 19794 19795 TextTrackSettings.prototype.createEl = function createEl() { 19796 var settings = (0, _dom.createEl)('div', { 19797 className: 'vjs-tracksettings' 19798 }, undefined, [this.createElColors_(), this.createElFont_(), this.createElControls_()]); 19799 19800 var heading = (0, _dom.createEl)('div', { 19801 className: 'vjs-control-text', 19802 id: 'TTsettingsDialogLabel-' + this.id_, 19803 textContent: 'Caption Settings Dialog' 19804 }, {
19805 'aria-level': '1', 19806 'role': 'heading' 19807 }); 19808 19809 var description = (0, _dom.createEl)('div', { 19810 className: 'vjs-control-text', 19811 id: 'TTsettingsDialogDescription-' + this.id_, 19812 textContent: 'Beginning of dialog window. Escape will cancel and close the window.' 19813 }); 19814 19815 var doc = (0, _dom.createEl)('div', undefined, { 19816 role: 'document' 19817 }, [heading, description, settings]); 19818 19819 return (0, _dom.createEl)('div', { 19820 className: 'vjs-caption-settings vjs-modal-overlay', 19821 tabIndex: -1 19822 }, { 19823 'role': 'dialog', 19824 'aria-labelledby': heading.id, 19825 'aria-describedby': description.id 19826 }, doc); 19827 }; 19828 19829 /** 19830 * Gets an object of text track settings (or null). 19831 * 19832 * @return {Object} 19833 * An object with config values parsed from the DOM or localStorage. 19834 */ 19835 19836 19837 TextTrackSettings.prototype.getValues = function getValues() { 19838 var _this3 = this; 19839 19840 return Obj.reduce(selectConfigs, function (accum, config, key) { 19841 var value = getSelectedOptionValue(_this3.$(config.selector), config.parser); 19842 19843 if (value !== undefined) { 19844 accum[key] = value; 19845 } 19846 19847 return accum; 19848 }, {}); 19849 }; 19850 19851 /** 19852 * Sets text track settings from an object of values. 19853 * 19854 * @param {Object} values 19855 * An object with config values parsed from the DOM or localStorage. 19856 */ 19857 19858 19859 TextTrackSettings.prototype.setValues = function setValues(values) { 19860 var _this4 = this; 19861 19862 Obj.each(selectConfigs, function (config, key) { 19863 setSelectedOption(_this4.$(config.selector), values[key], config.parser); 19864 }); 19865 }; 19866 19867 /** 19868 * Sets all <select> elements to their default values. 19869 */ 19870 19871 19872 TextTrackSettings.prototype.setDefaults = function setDefaults() { 19873 var _this5 = this; 19874 19875 Obj.each(selectConfigs, function (config) { 19876 var index = config.hasOwnProperty('default') ? config['default'] : 0; 19877 19878 _this5.$(config.selector).selectedIndex = index; 19879 }); 19880 }; 19881 19882 /** 19883 * Restore texttrack settings from localStorage 19884 */ 19885 19886 19887 TextTrackSettings.prototype.restoreSettings = function restoreSettings() { 19888 var values = void 0; 19889 19890 try { 19891 values = JSON.parse(_window2['default'].localStorage.getItem(LOCAL_STORAGE_KEY)); 19892 } catch (err) { 19893 _log2['default'].warn(err); 19894 } 19895 19896 if (values) { 19897 this.setValues(values); 19898 } 19899 }; 19900 19901 /** 19902 * Save text track settings to localStorage 19903 */ 19904 19905 19906 TextTrackSettings.prototype.saveSettings = function saveSettings() { 19907 if (!this.options_.persistTextTrackSettings) { 19908 return; 19909 } 19910 19911 var values = this.getValues(); 19912 19913 try { 19914 if (Object.keys(values).length) { 19915 _window2['default'].localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values)); 19916 } else { 19917 _window2['default'].localStorage.removeItem(LOCAL_STORAGE_KEY); 19918 } 19919 } catch (err) { 19920 _log2['default'].warn(err); 19921 } 19922 }; 19923 19924 /** 19925 * Update display of text track settings 19926 */ 19927 19928 19929 TextTrackSettings.prototype.updateDisplay = function updateDisplay() { 19930 var ttDisplay = this.player_.getChild('textTrackDisplay'); 19931 19932 if (ttDisplay) { 19933 ttDisplay.updateDisplay(); 19934 } 19935 }; 19936 19937 return TextTrackSettings; 19938}(_component2['default']); 19939 19940_component2['default'].registerComponent('TextTrackSettings', TextTrackSettings); 19941 19942exports['default'] = TextTrackSettings; 19943 19944},{"5":5,"81":81,"83":83,"86":86,"88":88,"95":95}],72:[function(_dereq_,module,exports){ 19945'use strict'; 19946 19947exports.__esModule = true; 19948 19949var _textTrackCueList = _dereq_(67); 19950 19951var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList); 19952 19953var _fn = _dereq_(83); 19954 19955var Fn = _interopRequireWildcard(_fn); 19956 19957var _trackEnums = _dereq_(73); 19958 19959var _log = _dereq_(86); 19960 19961var _log2 = _interopRequireDefault(_log); 19962 19963var _window = _dereq_(95); 19964 19965var _window2 = _interopRequireDefault(_window); 19966 19967var _track = _dereq_(75); 19968 19969var _track2 = _interopRequireDefault(_track); 19970 19971var _url = _dereq_(92); 19972 19973var _xhr = _dereq_(99); 19974 19975var _xhr2 = _interopRequireDefault(_xhr); 19976 19977var _mergeOptions = _dereq_(87); 19978 19979var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 19980 19981var _browser = _dereq_(78); 19982 19983var browser = _interopRequireWildcard(_browser); 19984 19985function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 19986 19987function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19988 19989function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 19990 19991function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 19992 19993function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
19993onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 19994 * @file text-track.js 19995 */ 19996 19997 19998/** 19999 * Takes a webvtt file contents and parses it into cues 20000 * 20001 * @param {string} srcContent 20002 * webVTT file contents 20003 * 20004 * @param {TextTrack} track 20005 * TextTrack to add cues to. Cues come from the srcContent. 20006 * 20007 * @private 20008 */ 20009var parseCues = function parseCues(srcContent, track) { 20010 var parser = new _window2['default'].WebVTT.Parser(_window2['default'], _window2['default'].vttjs, _window2['default'].WebVTT.StringDecoder()); 20011 var errors = []; 20012 20013 parser.oncue = function (cue) { 20014 track.addCue(cue); 20015 }; 20016 20017 parser.onparsingerror = function (error) { 20018 errors.push(error); 20019 }; 20020 20021 parser.onflush = function () { 20022 track.trigger({ 20023 type: 'loadeddata', 20024 target: track 20025 }); 20026 }; 20027 20028 parser.parse(srcContent); 20029 if (errors.length > 0) { 20030 if (_window2['default'].console && _window2['default'].console.groupCollapsed) { 20031 _window2['default'].console.groupCollapsed('Text Track parsing errors for ' + track.src); 20032 } 20033 errors.forEach(function (error) { 20034 return _log2['default'].error(error); 20035 }); 20036 if (_window2['default'].console && _window2['default'].console.groupEnd) { 20037 _window2['default'].console.groupEnd(); 20038 } 20039 } 20040 20041 parser.flush(); 20042}; 20043 20044/** 20045 * Load a `TextTrack` from a specifed url. 20046 * 20047 * @param {string} src 20048 * Url to load track from. 20049 * 20050 * @param {TextTrack} track 20051 * Track to add cues to. Comes from the content at the end of `url`. 20052 * 20053 * @private 20054 */ 20055var loadTrack = function loadTrack(src, track) { 20056 var opts = { 20057 uri: src 20058 }; 20059 var crossOrigin = (0, _url.isCrossOrigin)(src); 20060 20061 if (crossOrigin) { 20062 opts.cors = crossOrigin; 20063 } 20064 20065 (0, _xhr2['default'])(opts, Fn.bind(this, function (err, response, responseBody) { 20066 if (err) { 20067 return _log2['default'].error(err, response); 20068 } 20069 20070 track.loaded_ = true; 20071 20072 // Make sure that vttjs has loaded, otherwise, wait till it finished loading 20073 // NOTE: this is only used for the alt/video.novtt.js build 20074 if (typeof _window2['default'].WebVTT !== 'function') { 20075 if (track.tech_) { 20076 var loadHandler = function loadHandler() { 20077 return parseCues(responseBody, track); 20078 }; 20079 20080 track.tech_.on('vttjsloaded', loadHandler); 20081 track.tech_.on('vttjserror', function () { 20082 _log2['default'].error('vttjs failed to load, stopping trying to process ' + track.src); 20083 track.tech_.off('vttjsloaded', loadHandler); 20084 }); 20085 } 20086 } else { 20087 parseCues(responseBody, track); 20088 } 20089 })); 20090}; 20091 20092/** 20093 * A representation of a single `TextTrack`. 20094 * 20095 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack} 20096 * @extends Track 20097 */ 20098 20099var TextTrack = function (_Track) { 20100 _inherits(TextTrack, _Track); 20101 20102 /** 20103 * Create an instance of this class. 20104 * 20105 * @param {Object} options={} 20106 * Object of option names and values 20107 * 20108 * @param {Tech} options.tech 20109 * A reference to the tech that owns this TextTrack. 20110 * 20111 * @param {TextTrack~Kind} [options.kind='subtitles'] 20112 * A valid text track kind. 20113 * 20114 * @param {TextTrack~Mode} [options.mode='disabled'] 20115 * A valid text track mode. 20116 * 20117 * @param {string} [options.id='vjs_track_' + Guid.newGUID()] 20118 * A unique id for this TextTrack. 20119 * 20120 * @param {string} [options.label=''] 20121 * The menu label for this track. 20122 * 20123 * @param {string} [options.language=''] 20124 * A valid two character language code. 20125 * 20126 * @param {string} [options.srclang=''] 20127 * A valid two character language code. An alternative, but deprioritized 20128 * vesion of `options.language` 20129 * 20130 * @param {string} [options.src] 20131 * A url to TextTrack cues. 20132 * 20133 * @param {boolean} [options.default] 20134 * If this track should default to on or off. 20135 */ 20136 function TextTrack() { 20137 var _this, _ret; 20138 20139 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 20140 20141 _classCallCheck(this, TextTrack); 20142 20143 if (!options.tech) {
20144 throw new Error('A tech was not provided.'); 20145 } 20146 20147 var settings = (0, _mergeOptions2['default'])(options, { 20148 kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles', 20149 language: options.language || options.srclang || '' 20150 }); 20151 var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled'; 20152 var default_ = settings['default']; 20153 20154 if (settings.kind === 'metadata' || settings.kind === 'chapters') { 20155 mode = 'hidden'; 20156 } 20157 // on IE8 this will be a document element 20158 // for every other browser this will be a normal object 20159 var tt = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this); 20160 20161 tt.tech_ = settings.tech; 20162 20163 if (browser.IS_IE8) { 20164 for (var prop in TextTrack.prototype) { 20165 if (prop !== 'constructor') { 20166 tt[prop] = TextTrack.prototype[prop]; 20167 } 20168 } 20169 } 20170 20171 tt.cues_ = []; 20172 tt.activeCues_ = []; 20173 20174 var cues = new _textTrackCueList2['default'](tt.cues_); 20175 var activeCues = new _textTrackCueList2['default'](tt.activeCues_); 20176 var changed = false; 20177 var timeupdateHandler = Fn.bind(tt, function () { 20178 20179 // Accessing this.activeCues for the side-effects of updating itself 20180 // due to it's nature as a getter function. Do not remove or cues will 20181 // stop updating! 20182 /* eslint-disable no-unused-expressions */ 20183 this.activeCues; 20184 /* eslint-enable no-unused-expressions */ 20185 if (changed) { 20186 this.trigger('cuechange'); 20187 changed = false; 20188 } 20189 }); 20190 20191 if (mode !== 'disabled') { 20192 tt.tech_.ready(function () { 20193 tt.tech_.on('timeupdate', timeupdateHandler); 20194 }, true); 20195 } 20196 20197 /** 20198 * @member {boolean} default 20199 * If this track was set to be on or off by default. Cannot be changed after 20200 * creation. 20201 * 20202 * @readonly 20203 */ 20204 Object.defineProperty(tt, 'default', { 20205 get: function get() { 20206 return default_; 20207 }, 20208 set: function set() {} 20209 }); 20210 20211 /** 20212 * @member {string} mode 20213 * Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will 20214 * not be set if setting to an invalid mode. 20215 * 20216 * @fires TextTrack#modechange 20217 */ 20218 Object.defineProperty(tt, 'mode', { 20219 get: function get() { 20220 return mode; 20221 }, 20222 set: function set(newMode) { 20223 var _this2 = this; 20224 20225 if (!_trackEnums.TextTrackMode[newMode]) { 20226 return; 20227 } 20228 mode = newMode; 20229 if (mode === 'showing') { 20230 this.tech_.ready(function () { 20231 _this2.tech_.on('timeupdate', timeupdateHandler); 20232 }, true); 20233 } 20234 /** 20235 * An event that fires when mode changes on this track. This allows 20236 * the TextTrackList that holds this track to act accordingly. 20237 * 20238 * > Note: This is not part of the spec! 20239 * 20240 * @event TextTrack#modechange 20241 * @type {EventTarget~Event} 20242 */ 20243 this.trigger('modechange'); 20244 } 20245 }); 20246 20247 /** 20248 * @member {TextTrackCueList} cues 20249 * The text track cue list for this TextTrack. 20250 */ 20251 Object.defineProperty(tt, 'cues', { 20252 get: function get() { 20253 if (!this.loaded_) { 20254 return null; 20255 } 20256 20257 return cues; 20258 }, 20259 set: function set() {} 20260 }); 20261 20262 /** 20263 * @member {TextTrackCueList} activeCues 20264 * The list text track cues that are currently active for this TextTrack. 20265 */ 20266 Object.defineProperty(tt, 'activeCues', { 20267 get: function get() { 20268 if (!this.loaded_) { 20269 return null; 20270 } 20271 20272 // nothing to do 20273 if (this.cues.length === 0) { 20274 return activeCues; 20275 } 20276 20277 var ct = this.tech_.currentTime(); 20278 var active = []; 20279 20280 for (var i = 0, l = this.cues.length; i < l; i++) { 20281 var cue = this.cues[i]; 20282 20283 if (cue.startTime <= ct && cue.endTime >= ct) { 20284 active.push(cue); 20285 } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) { 20286 active.push(cue); 20287 } 20288 } 20289 20290 changed = false;
20291 20292 if (active.length !== this.activeCues_.length) { 20293 changed = true; 20294 } else { 20295 for (var _i = 0; _i < active.length; _i++) { 20296 if (this.activeCues_.indexOf(active[_i]) === -1) { 20297 changed = true; 20298 } 20299 } 20300 } 20301 20302 this.activeCues_ = active; 20303 activeCues.setCues_(this.activeCues_); 20304 20305 return activeCues; 20306 }, 20307 set: function set() {} 20308 }); 20309 20310 if (settings.src) { 20311 tt.src = settings.src; 20312 loadTrack(settings.src, tt); 20313 } else { 20314 tt.loaded_ = true; 20315 } 20316 20317 return _ret = tt, _possibleConstructorReturn(_this, _ret); 20318 } 20319 20320 /** 20321 * Add a cue to the internal list of cues. 20322 * 20323 * @param {TextTrack~Cue} cue 20324 * The cue to add to our internal list 20325 */ 20326 20327 20328 TextTrack.prototype.addCue = function addCue(originalCue) { 20329 var cue = originalCue; 20330 20331 if (_window2['default'].vttjs && !(originalCue instanceof _window2['default'].vttjs.VTTCue)) { 20332 cue = new _window2['default'].vttjs.VTTCue(originalCue.startTime, originalCue.endTime, originalCue.text); 20333 20334 for (var prop in originalCue) { 20335 if (!(prop in cue)) { 20336 cue[prop] = originalCue[prop]; 20337 } 20338 } 20339 20340 // make sure that `id` is copied over 20341 cue.id = originalCue.id; 20342 cue.originalCue_ = originalCue; 20343 } 20344 20345 var tracks = this.tech_.textTracks(); 20346 20347 if (tracks) { 20348 for (var i = 0; i < tracks.length; i++) { 20349 if (tracks[i] !== this) { 20350 tracks[i].removeCue(cue); 20351 } 20352 } 20353 } 20354 20355 this.cues_.push(cue); 20356 this.cues.setCues_(this.cues_); 20357 }; 20358 20359 /** 20360 * Remove a cue from our internal list 20361 * 20362 * @param {TextTrack~Cue} removeCue 20363 * The cue to remove from our internal list 20364 */ 20365 20366 20367 TextTrack.prototype.removeCue = function removeCue(_removeCue) { 20368 var i = this.cues_.length; 20369 20370 while (i--) { 20371 var cue = this.cues_[i]; 20372 20373 if (cue === _removeCue || cue.originalCue_ && cue.originalCue_ === _removeCue) { 20374 this.cues_.splice(i, 1); 20375 this.cues.setCues_(this.cues_); 20376 break; 20377 } 20378 } 20379 }; 20380 20381 return TextTrack; 20382}(_track2['default']); 20383 20384/** 20385 * cuechange - One or more cues in the track have become active or stopped being active. 20386 */ 20387 20388 20389TextTrack.prototype.allowedEvents_ = { 20390 cuechange: 'cuechange' 20391}; 20392 20393exports['default'] = TextTrack; 20394 20395},{"67":67,"73":73,"75":75,"78":78,"83":83,"86":86,"87":87,"92":92,"95":95,"99":99}],73:[function(_dereq_,module,exports){ 20396'use strict'; 20397 20398exports.__esModule = true; 20399/** 20400 * @file track-kinds.js 20401 */ 20402 20403/** 20404 * All possible `VideoTrackKind`s 20405 * 20406 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind 20407 * @typedef VideoTrack~Kind 20408 * @enum 20409 */ 20410var VideoTrackKind = exports.VideoTrackKind = { 20411 alternative: 'alternative', 20412 captions: 'captions', 20413 main: 'main', 20414 sign: 'sign', 20415 subtitles: 'subtitles', 20416 commentary: 'commentary' 20417}; 20418 20419/** 20420 * All possible `AudioTrackKind`s 20421 * 20422 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind 20423 * @typedef AudioTrack~Kind 20424 * @enum 20425 */ 20426var AudioTrackKind = exports.AudioTrackKind = { 20427 'alternative': 'alternative', 20428 'descriptions': 'descriptions', 20429 'main': 'main', 20430 'main-desc': 'main-desc', 20431 'translation': 'translation', 20432 'commentary': 'commentary' 20433}; 20434 20435/** 20436 * All possible `TextTrackKind`s 20437 * 20438 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-texttrack-kind 20439 * @typedef TextTrack~Kind 20440 * @enum 20441 */ 20442var TextTrackKind = exports.TextTrackKind = { 20443 subtitles: 'subtitles', 20444 captions: 'captions', 20445 descriptions: 'descriptions', 20446 chapters: 'chapters', 20447 metadata: 'metadata' 20448}; 20449 20450/** 20451 * All possible `TextTrackMode`s 20452 * 20453 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode 20454 * @typedef TextTrack~Mode 20455 * @enum 20456 */ 20457var TextTrackMode = exports.TextTrackMode = { 20458 disabled: 'disabled', 20459 hidden: 'hidden', 20460 showing: 'showing' 20461}; 20462 20463},{}],74:[function(_dereq_,module,exports){ 20464'use strict'; 20465 20466exports.__esModule = true; 20467 20468var _eventTarget = _dereq_(42); 20469 20470var _eventTarget2 = _interopRequireDefault(_eventTarget); 20471 20472var _browser = _dereq_(78); 20473 20474var browser = _interopRequireWildcard(_browser); 20475 20476var _document = _dereq_(94); 20477 20478var _document2 = _interopRequireDefault(_document); 20479 20480function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 20481 20482function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20483 20484function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 20485 20486function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 20487 20488function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
20488onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 20489 * @file track-list.js 20490 */ 20491 20492 20493/** 20494 * Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and 20495 * {@link VideoTrackList} 20496 * 20497 * @extends EventTarget 20498 */ 20499var TrackList = function (_EventTarget) { 20500 _inherits(TrackList, _EventTarget); 20501 20502 /** 20503 * Create an instance of this class 20504 * 20505 * @param {Track[]} tracks 20506 * A list of tracks to initialize the list with. 20507 * 20508 * @param {Object} [list] 20509 * The child object with inheritance done manually for ie8. 20510 * 20511 * @abstract 20512 */ 20513 function TrackList() { 20514 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 20515 20516 var _ret; 20517 20518 var list = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 20519 20520 _classCallCheck(this, TrackList); 20521 20522 var _this = _possibleConstructorReturn(this, _EventTarget.call(this)); 20523 20524 if (!list) { 20525 list = _this; // eslint-disable-line 20526 if (browser.IS_IE8) { 20527 list = _document2['default'].createElement('custom'); 20528 for (var prop in TrackList.prototype) { 20529 if (prop !== 'constructor') { 20530 list[prop] = TrackList.prototype[prop]; 20531 } 20532 } 20533 } 20534 } 20535 20536 list.tracks_ = []; 20537 20538 /** 20539 * @member {number} length 20540 * The current number of `Track`s in the this Trackist. 20541 */ 20542 Object.defineProperty(list, 'length', { 20543 get: function get() { 20544 return this.tracks_.length; 20545 } 20546 }); 20547 20548 for (var i = 0; i < tracks.length; i++) { 20549 list.addTrack_(tracks[i]); 20550 } 20551 20552 // must return the object, as for ie8 it will not be this 20553 // but a reference to a document object 20554 return _ret = list, _possibleConstructorReturn(_this, _ret); 20555 } 20556 20557 /** 20558 * Add a {@link Track} to the `TrackList` 20559 * 20560 * @param {Track} track 20561 * The audio, video, or text track to add to the list. 20562 * 20563 * @fires TrackList#addtrack 20564 * @private 20565 */ 20566 20567 20568 TrackList.prototype.addTrack_ = function addTrack_(track) { 20569 var index = this.tracks_.length; 20570 20571 if (!('' + index in this)) { 20572 Object.defineProperty(this, index, { 20573 get: function get() { 20574 return this.tracks_[index]; 20575 } 20576 }); 20577 } 20578 20579 // Do not add duplicate tracks 20580 if (this.tracks_.indexOf(track) === -1) { 20581 this.tracks_.push(track); 20582 /** 20583 * Triggered when a track is added to a track list. 20584 * 20585 * @event TrackList#addtrack 20586 * @type {EventTarget~Event} 20587 * @property {Track} track 20588 * A reference to track that was added. 20589 */ 20590 this.trigger({ 20591 track: track, 20592 type: 'addtrack' 20593 }); 20594 } 20595 }; 20596 20597 /** 20598 * Remove a {@link Track} from the `TrackList` 20599 * 20600 * @param {Track} track 20601 * The audio, video, or text track to remove from the list. 20602 * 20603 * @fires TrackList#removetrack 20604 * @private 20605 */ 20606 20607 20608 TrackList.prototype.removeTrack_ = function removeTrack_(rtrack) { 20609 var track = void 0; 20610 20611 for (var i = 0, l = this.length; i < l; i++) { 20612 if (this[i] === rtrack) { 20613 track = this[i]; 20614 if (track.off) { 20615 track.off(); 20616 } 20617 20618 this.tracks_.splice(i, 1); 20619 20620 break; 20621 } 20622 } 20623 20624 if (!track) { 20625 return; 20626 } 20627 20628 /** 20629 * Triggered when a track is removed from track list. 20630 * 20631 * @event TrackList#removetrack 20632 * @type {EventTarget~Event} 20633 * @property {Track} track 20634 * A reference to track that was removed. 20635 */ 20636 this.trigger({ 20637 track: track, 20638 type: 'removetrack' 20639 }); 20640 }; 20641 20642 /** 20643 * Get a Track from the TrackList by a tracks id 20644 * 20645 * @param {String} id - the id of the track to get 20646 * @method getTrackById 20647 * @return {Track} 20648 * @private 20649 */ 20650 20651 20652 TrackList.prototype.getTrackById = function getTrackById(id) { 20653 var result = null; 20654 20655 for (var i = 0, l = this.length; i < l; i++) { 20656 var track = this[i]; 20657 20658 if (track.id === id) { 20659 result = track; 20660 break; 20661 } 20662 } 20663 20664 return result; 20665 }; 20666 20667 return TrackList; 20668}(_eventTarget2['default']); 20669 20670/** 20671 * Triggered when a different track is selected/enabled. 20672 * 20673 * @event TrackList#change 20674 * @type {EventTarget~Event} 20675 */ 20676 20677/** 20678 * Events that can be called with on + eventName. See {@link EventHandler}. 20679 * 20680 * @property {Object} TrackList#allowedEvents_ 20681 * @private 20682 */ 20683 20684 20685TrackList.prototype.allowedEvents_ = { 20686 change: 'change', 20687 addtrack: 'addtrack', 20688 removetrack: 'removetrack' 20689}; 20690 20691// emulate attribute EventHandler support to allow for feature detection 20692for (var event in TrackList.prototype.allowedEvents_) { 20693 TrackList.prototype['on' + event] = null; 20694} 20695 20696exports['default'] = TrackList; 20697 20698},{"42":42,"78":78,"94":94}],75:[function(_dereq_,module,exports){ 20699'use strict'; 20700 20701exports.__esModule = true; 20702 20703var _browser = _dereq_(78); 20704 20705var browser = _interopRequireWildcard(_browser); 20706 20707var _document = _dereq_(94); 20708 20709var _document2 = _interopRequireDefault(_document); 20710 20711var _guid = _dereq_(85); 20712 20713var Guid = _interopRequireWildcard(_guid); 20714 20715var _eventTarget = _dereq_(42); 20716 20717var _eventTarget2 = _interopRequireDefault(_eventTarget); 20718 20719function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20720 20721function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 20722 20723function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 20724 20725function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 20726 20727function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
20727onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 20728 * @file track.js 20729 */ 20730 20731 20732/** 20733 * A Track class that contains all of the common functionality for {@link AudioTrack}, 20734 * {@link VideoTrack}, and {@link TextTrack}. 20735 * 20736 * > Note: This class should not be used directly 20737 * 20738 * @see {@link https://html.spec.whatwg.org/multipage/embedded-content.html} 20739 * @extends EventTarget 20740 * @abstract 20741 */ 20742var Track = function (_EventTarget) { 20743 _inherits(Track, _EventTarget); 20744 20745 /** 20746 * Create an instance of this class. 20747 * 20748 * @param {Object} [options={}] 20749 * Object of option names and values 20750 * 20751 * @param {string} [options.kind=''] 20752 * A valid kind for the track type you are creating. 20753 * 20754 * @param {string} [options.id='vjs_track_' + Guid.newGUID()] 20755 * A unique id for this AudioTrack. 20756 * 20757 * @param {string} [options.label=''] 20758 * The menu label for this track. 20759 * 20760 * @param {string} [options.language=''] 20761 * A valid two character language code. 20762 * 20763 * @abstract 20764 */ 20765 function Track() { 20766 var _ret; 20767 20768 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 20769 20770 _classCallCheck(this, Track); 20771 20772 var _this = _possibleConstructorReturn(this, _EventTarget.call(this)); 20773 20774 var track = _this; // eslint-disable-line 20775 20776 if (browser.IS_IE8) { 20777 track = _document2['default'].createElement('custom'); 20778 for (var prop in Track.prototype) { 20779 if (prop !== 'constructor') { 20780 track[prop] = Track.prototype[prop]; 20781 } 20782 } 20783 } 20784 20785 var trackProps = { 20786 id: options.id || 'vjs_track_' + Guid.newGUID(), 20787 kind: options.kind || '', 20788 label: options.label || '', 20789 language: options.language || '' 20790 }; 20791 20792 /** 20793 * @member {string} id 20794 * The id of this track. Cannot be changed after creation. 20795 * 20796 * @readonly 20797 */ 20798 20799 /** 20800 * @member {string} kind 20801 * The kind of track that this is. Cannot be changed after creation. 20802 * 20803 * @readonly 20804 */ 20805 20806 /** 20807 * @member {string} label 20808 * The label of this track. Cannot be changed after creation. 20809 * 20810 * @readonly 20811 */ 20812 20813 /** 20814 * @member {string} language 20815 * The two letter language code for this track. Cannot be changed after 20816 * creation. 20817 * 20818 * @readonly 20819 */ 20820 20821 var _loop = function _loop(key) { 20822 Object.defineProperty(track, key, { 20823 get: function get() { 20824 return trackProps[key]; 20825 }, 20826 set: function set() {} 20827 }); 20828 }; 20829 20830 for (var key in trackProps) { 20831 _loop(key); 20832 } 20833 20834 return _ret = track, _possibleConstructorReturn(_this, _ret); 20835 } 20836 20837 return Track; 20838}(_eventTarget2['default']); 20839 20840exports['default'] = Track; 20841 20842},{"42":42,"78":78,"85":85,"94":94}],76:[function(_dereq_,module,exports){ 20843'use strict'; 20844 20845exports.__esModule = true; 20846 20847var _trackList = _dereq_(74); 20848 20849var _trackList2 = _interopRequireDefault(_trackList); 20850 20851var _browser = _dereq_(78); 20852 20853var browser = _interopRequireWildcard(_browser); 20854 20855var _document = _dereq_(94); 20856 20857var _document2 = _interopRequireDefault(_document); 20858 20859function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 20860 20861function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20862 20863function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 20864 20865function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 20866 20867function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
20867onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 20868 * @file video-track-list.js 20869 */ 20870 20871 20872/** 20873 * Un-select all other {@link VideoTrack}s that are selected. 20874 * 20875 * @param {VideoTrackList} list 20876 * list to work on 20877 * 20878 * @param {VideoTrack} track 20879 * The track to skip 20880 * 20881 * @private 20882 */ 20883var disableOthers = function disableOthers(list, track) { 20884 for (var i = 0; i < list.length; i++) { 20885 if (track.id === list[i].id) { 20886 continue; 20887 } 20888 // another video track is enabled, disable it 20889 list[i].selected = false; 20890 } 20891}; 20892 20893/** 20894 * The current list of {@link VideoTrack} for a video. 20895 * 20896 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist} 20897 * @extends TrackList 20898 */ 20899 20900var VideoTrackList = function (_TrackList) { 20901 _inherits(VideoTrackList, _TrackList); 20902 20903 /** 20904 * Create an instance of this class. 20905 * 20906 * @param {VideoTrack[]} [tracks=[]] 20907 * A list of `VideoTrack` to instantiate the list with. 20908 */ 20909 function VideoTrackList() { 20910 var _this, _ret; 20911 20912 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 20913 20914 _classCallCheck(this, VideoTrackList); 20915 20916 var list = void 0; 20917 20918 // make sure only 1 track is enabled 20919 // sorted from last index to first index 20920 for (var i = tracks.length - 1; i >= 0; i--) { 20921 if (tracks[i].selected) { 20922 disableOthers(tracks, tracks[i]); 20923 break; 20924 } 20925 } 20926 20927 // IE8 forces us to implement inheritance ourselves 20928 // as it does not support Object.defineProperty properly 20929 if (browser.IS_IE8) { 20930 list = _document2['default'].createElement('custom'); 20931 for (var prop in _trackList2['default'].prototype) { 20932 if (prop !== 'constructor') { 20933 list[prop] = _trackList2['default'].prototype[prop]; 20934 } 20935 } 20936 for (var _prop in VideoTrackList.prototype) { 20937 if (_prop !== 'constructor') { 20938 list[_prop] = VideoTrackList.prototype[_prop]; 20939 } 20940 } 20941 } 20942
20943 list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this); 20944 list.changing_ = false; 20945 20946 /** 20947 * @member {number} VideoTrackList#selectedIndex 20948 * The current index of the selected {@link VideoTrack`}. 20949 */ 20950 Object.defineProperty(list, 'selectedIndex', { 20951 get: function get() { 20952 for (var _i = 0; _i < this.length; _i++) { 20953 if (this[_i].selected) { 20954 return _i; 20955 } 20956 } 20957 return -1; 20958 }, 20959 set: function set() {} 20960 }); 20961 20962 return _ret = list, _possibleConstructorReturn(_this, _ret); 20963 } 20964 20965 /** 20966 * Add a {@link VideoTrack} to the `VideoTrackList`. 20967 * 20968 * @param {VideoTrack} track 20969 * The VideoTrack to add to the list 20970 * 20971 * @fires TrackList#addtrack 20972 * @private 20973 */ 20974 20975 20976 VideoTrackList.prototype.addTrack_ = function addTrack_(track) { 20977 var _this2 = this; 20978 20979 if (track.selected) { 20980 disableOthers(this, track); 20981 } 20982 20983 _TrackList.prototype.addTrack_.call(this, track); 20984 // native tracks don't have this 20985 if (!track.addEventListener) { 20986 return; 20987 } 20988 20989 /** 20990 * @listens VideoTrack#selectedchange 20991 * @fires TrackList#change 20992 */ 20993 track.addEventListener('selectedchange', function () { 20994 if (_this2.changing_) { 20995 return; 20996 } 20997 _this2.changing_ = true; 20998 disableOthers(_this2, track); 20999 _this2.changing_ = false; 21000 _this2.trigger('change'); 21001 }); 21002 }; 21003 21004 /** 21005 * Add a {@link VideoTrack} to the `VideoTrackList`. 21006 * 21007 * @param {VideoTrack} track 21008 * The VideoTrack to add to the list 21009 * 21010 * @fires TrackList#addtrack 21011 */ 21012 21013 21014 VideoTrackList.prototype.addTrack = function addTrack(track) { 21015 this.addTrack_(track); 21016 }; 21017 21018 /** 21019 * Remove a {@link VideoTrack} to the `VideoTrackList`. 21020 * 21021 * @param {VideoTrack} track 21022 * The VideoTrack to remove from the list. 21023 * 21024 * @fires TrackList#removetrack 21025 */ 21026 21027 21028 VideoTrackList.prototype.removeTrack = function removeTrack(track) { 21029 _TrackList.prototype.removeTrack_.call(this, track); 21030 }; 21031 21032 return VideoTrackList; 21033}(_trackList2['default']); 21034 21035exports['default'] = VideoTrackList; 21036 21037},{"74":74,"78":78,"94":94}],77:[function(_dereq_,module,exports){ 21038'use strict'; 21039 21040exports.__esModule = true; 21041 21042var _trackEnums = _dereq_(73); 21043 21044var _track = _dereq_(75); 21045 21046var _track2 = _interopRequireDefault(_track); 21047 21048var _mergeOptions = _dereq_(87); 21049 21050var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 21051 21052var _browser = _dereq_(78); 21053 21054var browser = _interopRequireWildcard(_browser); 21055 21056function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 21057 21058function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21059 21060function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 21061 21062function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 21063 21064function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 21065 21066/** 21067 * A representation of a single `VideoTrack`. 21068 * 21069 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack} 21070 * @extends Track 21071 */ 21072var VideoTrack = function (_Track) { 21073 _inherits(VideoTrack, _Track); 21074 21075 /** 21076 * Create an instance of this class. 21077 * 21078 * @param {Object} [options={}] 21079 * Object of option names and values 21080 * 21081 * @param {string} [options.kind=''] 21082 * A valid {@link VideoTrack~Kind} 21083 * 21084 * @param {string} [options.id='vjs_track_' + Guid.newGUID()] 21085 * A unique id for this AudioTrack. 21086 * 21087 * @param {string} [options.label=''] 21088 * The menu label for this track. 21089 * 21090 * @param {string} [options.language=''] 21091 * A valid two character language code. 21092 * 21093 * @param {boolean} [options.selected] 21094 * If this track is the one that is currently playing. 21095 */ 21096 function VideoTrack() { 21097 var _this, _ret; 21098 21099 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 21100 21101 _classCallCheck(this, VideoTrack); 21102 21103 var settings = (0, _mergeOptions2['default'])(options, { 21104 kind: _trackEnums.VideoTrackKind[options.kind] || '' 21105 }); 21106 21107 // on IE8 this will be a document element 21108 // for every other browser this will be a normal object
21109 var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this); 21110 var selected = false; 21111 21112 if (browser.IS_IE8) { 21113 for (var prop in VideoTrack.prototype) { 21114 if (prop !== 'constructor') { 21115 track[prop] = VideoTrack.prototype[prop]; 21116 } 21117 } 21118 } 21119 21120 /** 21121 * @member {boolean} selected 21122 * If this `VideoTrack` is selected or not. When setting this will 21123 * fire {@link VideoTrack#selectedchange} if the state of selected changed. 21124 * 21125 * @fires VideoTrack#selectedchange 21126 */ 21127 Object.defineProperty(track, 'selected', { 21128 get: function get() { 21129 return selected; 21130 }, 21131 set: function set(newSelected) { 21132 // an invalid or unchanged value 21133 if (typeof newSelected !== 'boolean' || newSelected === selected) { 21134 return; 21135 } 21136 selected = newSelected; 21137 21138 /** 21139 * An event that fires when selected changes on this track. This allows 21140 * the VideoTrackList that holds this track to act accordingly. 21141 * 21142 * > Note: This is not part of the spec! Native tracks will do 21143 * this internally without an event. 21144 * 21145 * @event VideoTrack#selectedchange 21146 * @type {EventTarget~Event} 21147 */ 21148 this.trigger('selectedchange'); 21149 } 21150 }); 21151 21152 // if the user sets this track to selected then 21153 // set selected to that true value otherwise 21154 // we keep it false 21155 if (settings.selected) { 21156 track.selected = settings.selected; 21157 } 21158 21159 return _ret = track, _possibleConstructorReturn(_this, _ret); 21160 } 21161 21162 return VideoTrack; 21163}(_track2['default']); 21164 21165exports['default'] = VideoTrack; 21166 21167},{"73":73,"75":75,"78":78,"87":87}],78:[function(_dereq_,module,exports){ 21168'use strict'; 21169 21170exports.__esModule = true; 21171exports.BACKGROUND_SIZE_SUPPORTED = exports.TOUCH_ENABLED = exports.IS_ANY_SAFARI = exports.IS_SAFARI = exports.IE_VERSION = exports.IS_IE8 = exports.IS_CHROME = exports.IS_EDGE = exports.IS_FIREFOX = exports.IS_NATIVE_ANDROID = exp
21171orts.IS_OLD_ANDROID = exports.ANDROID_VERSION = exports.IS_ANDROID = exports.IOS_VERSION = exports.IS_IOS = exports.IS_IPOD = exports.IS_IPHONE = exports.IS_IPAD = undefined; 21172 21173var _dom = _dereq_(81); 21174 21175var Dom = _interopRequireWildcard(_dom); 21176 21177var _window = _dereq_(95); 21178 21179var _window2 = _interopRequireDefault(_window); 21180 21181function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21182 21183function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 21184 21185/** 21186 * @file browser.js 21187 * @module browser 21188 */ 21189var USER_AGENT = _window2['default'].navigator && _window2['default'].navigator.userAgent || ''; 21190var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT); 21191var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null; 21192 21193/* 21194 * Device is an iPhone 21195 * 21196 * @type {Boolean} 21197 * @constant 21198 * @private 21199 */ 21200var IS_IPAD = exports.IS_IPAD = /iPad/i.test(USER_AGENT); 21201 21202// The Facebook app's UIWebView identifies as both an iPhone and iPad, so 21203// to identify iPhones, we need to exclude iPads. 21204// http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/ 21205var IS_IPHONE = exports.IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD; 21206var IS_IPOD = exports.IS_IPOD = /iPod/i.test(USER_AGENT); 21207var IS_IOS = exports.IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD; 21208 21209var IOS_VERSION = exports.IOS_VERSION = function () { 21210 var match = USER_AGENT.match(/OS (\d+)_/i); 21211 21212 if (match && match[1]) { 21213 return match[1]; 21214 } 21215 return null; 21216}(); 21217
21218var IS_ANDROID = exports.IS_ANDROID = /Android/i.test(USER_AGENT); 21219var ANDROID_VERSION = exports.ANDROID_VERSION = function () { 21220 // This matches Android Major.Minor.Patch versions 21221 // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned 21222 var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i); 21223 21224 if (!match) { 21225 return null; 21226 } 21227 21228 var major = match[1] && parseFloat(match[1]); 21229 var minor = match[2] && parseFloat(match[2]); 21230 21231 if (major && minor) { 21232 return parseFloat(match[1] + '.' + match[2]); 21233 } else if (major) { 21234 return major; 21235 } 21236 return null; 21237}(); 21238 21239// Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser 21240var IS_OLD_ANDROID = exports.IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3; 21241var IS_NATIVE_ANDROID = exports.IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537; 21242 21243var IS_FIREFOX = exports.IS_FIREFOX = /Firefox/i.test(USER_AGENT); 21244var IS_EDGE = exports.IS_EDGE = /Edge/i.test(USER_AGENT); 21245var IS_CHROME = exports.IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT); 21246var IS_IE8 = exports.IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT); 21247var IE_VERSION = exports.IE_VERSION = function () { 21248 var result = /MSIE\s(\d+)\.\d/.exec(USER_AGENT); 21249 var version = result && parseFloat(result[1]); 21250 21251 if (!version && /Trident\/7.0/i.test(USER_AGENT) && /rv:11.0/.test(USER_AGENT)) { 21252 // IE 11 has a different user agent string than other IE versions 21253 version = 11.0; 21254 } 21255 21256 return version; 21257}(); 21258 21259var IS_SAFARI = exports.IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE; 21260var IS_ANY_SAFARI = exports.IS_ANY_SAFARI = IS_SAFARI || IS_IOS; 21261 21262var TOUCH_ENABLED = exports.TOUCH_ENABLED = Dom.isReal() && ('ontouchstart' in _window2['default'] || _window2['default'].DocumentTouch && _window2['default'].document instanceof _window2['default'].DocumentTouch); 21263 21264var BACKGROUND_SIZE_SUPPORTED = exports.BACKGROUND_SIZE_SUPPORTED = Dom.isReal() && 'backgroundSize' in _window2['default'].document.createElement('video').style; 21265 21266},{"81":81,"95":95}],79:[function(_dereq_,module,exports){ 21267'use strict'; 21268 21269exports.__esModule = true; 21270exports.bufferedPercent = bufferedPercent; 21271 21272var _timeRanges = _dereq_(90); 21273 21274/** 21275 * Compute the percentage of the media that has been buffered. 21276 * 21277 * @param {TimeRange} buffered 21278 * The current `TimeRange` object representing buffered time ranges 21279 * 21280 * @param {number} duration 21281 * Total duration of the media 21282 * 21283 * @return {number} 21284 * Percent buffered of the total duration in decimal form. 21285 */ 21286function bufferedPercent(buffered, duration) { 21287 var bufferedDuration = 0; 21288 var start = void 0; 21289 var end = void 0; 21290 21291 if (!duration) { 21292 return 0; 21293 } 21294 21295 if (!buffered || !buffered.length) { 21296 buffered = (0, _timeRanges.createTimeRange)(0, 0); 21297 } 21298 21299 for (var i = 0; i < buffered.length; i++) { 21300 start = buffered.start(i); 21301 end = buffered.end(i); 21302 21303 // buffered end can be bigger than duration by a very small fraction 21304 if (end > duration) { 21305 end = duration; 21306 } 21307 21308 bufferedDuration += end - start; 21309 } 21310 21311 return bufferedDuration / duration; 21312} /** 21313 * @file buffer.js 21314 * @module buffer 21315 */ 21316 21317},{"90":90}],80:[function(_dereq_,module,exports){ 21318'use strict'; 21319 21320exports.__esModule = true; 21321exports['default'] = computedStyle; 21322 21323var _window = _dereq_(95); 21324 21325var _window2 = _interopRequireDefault(_window); 21326 21327function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21328 21329/** 21330 * A safe getComputedStyle with an IE8 fallback. 21331 * 21332 * This is needed because in Firefox, if the player is loaded in an iframe with 21333 * `display:none`, then `getComputedStyle` returns `null`, so, we do a null-check to 21334 * make sure that the player doesn't break in these cases. 21335 * 21336 * @param {Element} el 21337 * The element you want the computed style of 21338 * 21339 * @param {string} prop 21340 * The property name you want 21341 * 21342 * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397 21343 */ 21344function computedStyle(el, prop) { 21345 if (!el || !prop) { 21346 return ''; 21347 } 21348 21349 if (typeof _window2['default'].getComputedStyle === 'function') { 21350 var cs = _window2['default'].getComputedStyle(el); 21351 21352 return cs ? cs[prop] : ''; 21353 } 21354 21355 return el.currentStyle[prop] || ''; 21356} /** 21357 * @file computed-style.js 21358 * @module computed-style 21359 */ 21360 21361},{"95":95}],81:[function(_dereq_,module,exports){ 21362'use strict'; 21363 21364exports.__esModule = true; 21365exports.$$ = exports.$ = undefined; 21366
21367var _templateObject = _taggedTemplateLiteralLoose(['Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set ', ' to ', '.'], ['Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set ', ' to ', '.']); 21368 21369exports.isReal = isReal; 21370exports.isEl = isEl; 21371exports.getEl = getEl; 21372exports.createEl = createEl; 21373exports.textContent = textContent; 21374exports.insertElFirst = insertElFirst; 21375exports.getElData = getElData; 21376exports.hasElData = hasElData; 21377exports.removeElData = removeElData; 21378exports.hasElClass = hasElClass; 21379exports.addElClass = addElClass; 21380exports.removeElClass = removeElClass; 21381exports.toggleElClass = toggleElClass; 21382exports.setElAttributes = setElAttributes; 21383exports.getElAttributes = getElAttributes; 21384exports.getAttribute = getAttribute; 21385exports.setAttribute = setAttribute; 21386exports.removeAttribute = removeAttribute; 21387exports.blockTextSelection = blockTextSelection; 21388exports.unblockTextSelection = unblockTextSelection; 21389exports.findElPosition = findElPosition; 21390exports.getPointerPosition = getPointerPosition; 21391exports.isTextNode = isTextNode; 21392exports.emptyEl = emptyEl; 21393exports.normalizeContent = normalizeContent; 21394exports.appendContent = appendContent; 21395exports.insertContent = insertContent; 21396 21397var _document = _dereq_(94); 21398 21399var _document2 = _interopRequireDefault(_document); 21400 21401var _window = _dereq_(95); 21402 21403var _window2 = _interopRequireDefault(_window); 21404 21405var _guid = _dereq_(85); 21406 21407var Guid = _interopRequireWildcard(_guid); 21408 21409var _log = _dereq_(86); 21410 21411var _log2 = _interopRequireDefault(_log); 21412 21413var _tsml = _dereq_(98); 21414 21415var _tsml2 = _interopRequireDefault(_tsml); 21416 21417var _obj = _dereq_(88); 21418 21419function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 21420 21421function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21422 21423function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } /** 21424 * @file dom.js 21425 * @module dom 21426 */ 21427 21428 21429/** 21430 * Detect if a value is a string with any non-whitespace characters. 21431 * 21432 * @param {string} str 21433 * The string to check 21434 * 21435 * @return {boolean} 21436 * - True if the string is non-blank 21437 * - False otherwise 21438 * 21439 */ 21440function isNonBlankString(str) { 21441 return typeof str === 'string' && /\S/.test(str); 21442} 21443 21444/** 21445 * Throws an error if the passed string has whitespace. This is used by 21446 * class methods to be relatively consistent with the classList API. 21447 * 21448 * @param {string} str 21449 * The string to check for whitespace. 21450 * 21451 * @throws {Error} 21452 * Throws an error if there is whitespace in the string. 21453 * 21454 */ 21455function throwIfWhitespace(str) { 21456 if (/\s/.test(str)) { 21457 throw new Error('class has illegal whitespace characters'); 21458 } 21459} 21460 21461/** 21462 * Produce a regular expression for matching a className within an elements className. 21463 * 21464 * @param {string} className 21465 * The className to generate the RegExp for. 21466 * 21467 * @return {RegExp} 21468 * The RegExp that will check for a specific `className` in an elements 21469 * className. 21470 */ 21471function classRegExp(className) { 21472 return new RegExp('(^|\\s)' + className + '($|\\s)'); 21473} 21474 21475/** 21476 * Whether the current DOM interface appears to be real. 21477 * 21478 * @return {Boolean} 21479 */ 21480function isReal() { 21481 return ( 21482 21483 // Both document and window will never be undefined thanks to `global`. 21484 _document2['default'] === _window2['default'].document && 21485 21486 // In IE < 9, DOM methods return "object" as their type, so all we can 21487 // confidently check is that it exists. 21488 typeof _document2['default'].createElement !== 'undefined' 21489 ); 21490} 21491 21492/** 21493 * Determines, via duck typing, whether or not a value is a DOM element. 21494 * 21495 * @param {Mixed} value 21496 * The thing to check 21497 * 21498 * @return {boolean} 21499 * - True if it is a DOM element 21500 * - False otherwise 21501 */ 21502function isEl(value) { 21503 return (0, _obj.isObject)(value) && value.nodeType === 1; 21504} 21505 21506/** 21507 * Creates functions to query the DOM using a given method. 21508 * 21509 * @param {string} method 21510 * The method to create the query with. 21511 * 21512 * @return {Function} 21513 * The query method 21514 */ 21515function createQuerier(method) { 21516 return function (selector, context) { 21517 if (!isNonBlankString(selector)) { 21518 return _document2['default'][method](null); 21519 } 21520 if (isNonBlankString(context)) { 21521 context = _document2['default'].querySelector(context); 21522 } 21523 21524 var ctx = isEl(context) ? context : _document2['default']; 21525 21526 return ctx[method] && ctx[method](selector); 21527 }; 21528} 21529 21530/** 21531 * Shorthand for document.getElementById() 21532 * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs. 21533 * 21534 * @param {string} id 21535 * The id of the element to get 21536 * 21537 * @return {Element|null} 21538 * Element with supplied ID or null if there wasn't one. 21539 */ 21540function getEl(id) { 21541 if (id.indexOf('#') === 0) { 21542 id = id.slice(1); 21543 } 21544 21545 return _document2['default'].getElementById(id); 21546} 21547 21548/** 21549 * Creates an element and applies properties. 21550 * 21551 * @param {string} [tagName='div'] 21552 * Name of tag to be created. 21553 * 21554 * @param {Object} [properties={}] 21555 * Element properties to be applied. 21556 * 21557 * @param {Object} [attributes={}] 21558 * Element attributes to be applied. 21559 * 21560 * @param {String|Element|TextNode|Array|Function} [content] 21561 * Contents for the element (see: {@link dom:normalizeContent}) 21562 * 21563 * @return {Element} 21564 * The element that was created. 21565 */ 21566function createEl() { 21567 var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div'; 21568 var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 21569 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 21570 var content = arguments[3]; 21571 21572 var el = _document2['default'].createElement(tagName); 21573
vendor: 8,890 bytes, lines 21574-21921
21574 Object.getOwnPropertyNames(properties).forEach(function (propName) { 21575 var val = properties[propName]; 21576 21577 // See #2176 21578 // We originally were accepting both properties and attributes in the 21579 // same object, but that doesn't work so well. 21580 if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') { 21581 _log2['default'].warn((0, _tsml2['default'])(_templateObject, propName, val)); 21582 el.setAttribute(propName, val); 21583 21584 // Handle textContent since it's not supported everywhere and we have a 21585 // method for it. 21586 } else if (propName === 'textContent') { 21587 textContent(el, val); 21588 } else { 21589 el[propName] = val; 21590 } 21591 }); 21592 21593 Object.getOwnPropertyNames(attributes).forEach(function (attrName) { 21594 el.setAttribute(attrName, attributes[attrName]); 21595 }); 21596 21597 if (content) { 21598 appendContent(el, content); 21599 } 21600 21601 return el; 21602} 21603 21604/** 21605 * Injects text into an element, replacing any existing contents entirely. 21606 * 21607 * @param {Element} el 21608 * The element to add text content into 21609 * 21610 * @param {string} text 21611 * The text content to add. 21612 * 21613 * @return {Element} 21614 * The element with added text content. 21615 */ 21616function textContent(el, text) { 21617 if (typeof el.textContent === 'undefined') { 21618 el.innerText = text; 21619 } else { 21620 el.textContent = text; 21621 } 21622 return el; 21623} 21624 21625/** 21626 * Insert an element as the first child node of another 21627 * 21628 * @param {Element} child 21629 * Element to insert 21630 * 21631 * @param {Element} parent 21632 * Element to insert child into 21633 * 21634 */ 21635function insertElFirst(child, parent) { 21636 if (parent.firstChild) { 21637 parent.insertBefore(child, parent.firstChild); 21638 } else { 21639 parent.appendChild(child); 21640 } 21641} 21642 21643/** 21644 * Element Data Store. Allows for binding data to an element without putting it directly on the element. 21645 * Ex. Event listeners are stored here. 21646 * (also from jsninja.com, slightly modified and updated for closure compiler) 21647 * 21648 * @type {Object} 21649 * @private 21650 */ 21651var elData = {}; 21652 21653/* 21654 * Unique attribute name to store an element's guid in 21655 * 21656 * @type {string} 21657 * @constant 21658 * @private 21659 */ 21660var elIdAttr = 'vdata' + new Date().getTime(); 21661 21662/** 21663 * Returns the cache object where data for an element is stored 21664 * 21665 * @param {Element} el 21666 * Element to store data for. 21667 * 21668 * @return {Object} 21669 * The cache object for that el that was passed in. 21670 */ 21671function getElData(el) { 21672 var id = el[elIdAttr]; 21673 21674 if (!id) { 21675 id = el[elIdAttr] = Guid.newGUID(); 21676 } 21677 21678 if (!elData[id]) { 21679 elData[id] = {}; 21680 } 21681 21682 return elData[id]; 21683} 21684 21685/** 21686 * Returns whether or not an element has cached data 21687 * 21688 * @param {Element} el 21689 * Check if this element has cached data. 21690 * 21691 * @return {boolean} 21692 * - True if the DOM element has cached data. 21693 * - False otherwise. 21694 */ 21695function hasElData(el) { 21696 var id = el[elIdAttr]; 21697 21698 if (!id) { 21699 return false; 21700 } 21701 21702 return !!Object.getOwnPropertyNames(elData[id]).length; 21703} 21704 21705/** 21706 * Delete data for the element from the cache and the guid attr from getElementById 21707 * 21708 * @param {Element} el 21709 * Remove cached data for this element. 21710 */ 21711function removeElData(el) { 21712 var id = el[elIdAttr]; 21713 21714 if (!id) { 21715 return; 21716 } 21717 21718 // Remove all stored data 21719 delete elData[id]; 21720 21721 // Remove the elIdAttr property from the DOM node 21722 try { 21723 delete el[elIdAttr]; 21724 } catch (e) { 21725 if (el.removeAttribute) { 21726 el.removeAttribute(elIdAttr); 21727 } else { 21728 // IE doesn't appear to support removeAttribute on the document element 21729 el[elIdAttr] = null; 21730 } 21731 } 21732} 21733 21734/** 21735 * Check if an element has a CSS class 21736 * 21737 * @param {Element} element 21738 * Element to check 21739 * 21740 * @param {string} classToCheck 21741 * Class name to check for 21742 * 21743 * @return {boolean} 21744 * - True if the element had the class 21745 * - False otherwise. 21746 * 21747 * @throws {Error} 21748 * Throws an error if `classToCheck` has white space. 21749 */ 21750function hasElClass(element, classToCheck) { 21751 throwIfWhitespace(classToCheck); 21752 if (element.classList) { 21753 return element.classList.contains(classToCheck); 21754 } 21755 return classRegExp(classToCheck).test(element.className); 21756} 21757 21758/** 21759 * Add a CSS class name to an element 21760 * 21761 * @param {Element} element 21762 * Element to add class name to. 21763 * 21764 * @param {string} classToAdd 21765 * Class name to add. 21766 * 21767 * @return {Element} 21768 * The dom element with the added class name. 21769 */ 21770function addElClass(element, classToAdd) { 21771 if (element.classList) { 21772 element.classList.add(classToAdd); 21773 21774 // Don't need to `throwIfWhitespace` here because `hasElClass` will do it 21775 // in the case of classList not being supported. 21776 } else if (!hasElClass(element, classToAdd)) { 21777 element.className = (element.className + ' ' + classToAdd).trim(); 21778 } 21779 21780 return element; 21781} 21782 21783/** 21784 * Remove a CSS class name from an element 21785 * 21786 * @param {Element} element 21787 * Element to remove a class name from. 21788 * 21789 * @param {string} classToRemove 21790 * Class name to remove 21791 * 21792 * @return {Element} 21793 * The dom element with class name removed. 21794 */ 21795function removeElClass(element, classToRemove) { 21796 if (element.classList) { 21797 element.classList.remove(classToRemove); 21798 } else { 21799 throwIfWhitespace(classToRemove); 21800 element.className = element.className.split(/\s+/).filter(function (c) { 21801 return c !== classToRemove; 21802 }).join(' '); 21803 } 21804 21805 return element; 21806} 21807 21808/** 21809 * The callback definition for toggleElClass. 21810 * 21811 * @callback Dom~PredicateCallback 21812 * @param {Element} element 21813 * The DOM element of the Component. 21814 * 21815 * @param {string} classToToggle 21816 * The `className` that wants to be toggled 21817 * 21818 * @return {boolean|undefined} 21819 * - If true the `classToToggle` will get added to `element`. 21820 * - If false the `classToToggle` will get removed from `element`. 21821 * - If undefined this callback will be ignored 21822 */ 21823 21824/** 21825 * Adds or removes a CSS class name on an element depending on an optional 21826 * condition or the presence/absence of the class name. 21827 * 21828 * @param {Element} element 21829 * The element to toggle a class name on. 21830 * 21831 * @param {string} classToToggle 21832 * The class that should be toggled 21833 * 21834 * @param {boolean|PredicateCallback} [predicate] 21835 * See the return value for {@link Dom~PredicateCallback} 21836 * 21837 * @return {Element} 21838 * The element with a class that has been toggled. 21839 */ 21840function toggleElClass(element, classToToggle, predicate) { 21841 21842 // This CANNOT use `classList` internally because IE does not support the 21843 // second parameter to the `classList.toggle()` method! Which is fine because 21844 // `classList` will be used by the add/remove functions. 21845 var has = hasElClass(element, classToToggle); 21846 21847 if (typeof predicate === 'function') { 21848 predicate = predicate(element, classToToggle); 21849 } 21850 21851 if (typeof predicate !== 'boolean') { 21852 predicate = !has; 21853 } 21854 21855 // If the necessary class operation matches the current state of the 21856 // element, no action is required. 21857 if (predicate === has) { 21858 return; 21859 } 21860 21861 if (predicate) { 21862 addElClass(element, classToToggle); 21863 } else { 21864 removeElClass(element, classToToggle); 21865 } 21866 21867 return element; 21868} 21869 21870/** 21871 * Apply attributes to an HTML element. 21872 * 21873 * @param {Element} el 21874 * Element to add attributes to. 21875 * 21876 * @param {Object} [attributes] 21877 * Attributes to be applied. 21878 */ 21879function setElAttributes(el, attributes) { 21880 Object.getOwnPropertyNames(attributes).forEach(function (attrName) { 21881 var attrValue = attributes[attrName]; 21882 21883 if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) { 21884 el.removeAttribute(attrName); 21885 } else { 21886 el.setAttribute(attrName, attrValue === true ? '' : attrValue); 21887 } 21888 }); 21889} 21890 21891/** 21892 * Get an element's attribute values, as defined on the HTML tag 21893 * Attributes are not the same as properties. They're defined on the tag 21894 * or with setAttribute (which shouldn't be used with HTML) 21895 * This will return true or false for boolean attributes. 21896 * 21897 * @param {Element} tag 21898 * Element from which to get tag attributes. 21899 * 21900 * @return {Object} 21901 * All attributes of the element. 21902 */ 21903function getElAttributes(tag) { 21904 var obj = {}; 21905 21906 // known boolean attributes 21907 // we can check for matching boolean properties, but older browsers 21908 // won't know about HTML5 boolean attributes that we still read from 21909 var knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ','; 21910 21911 if (tag && tag.attributes && tag.attributes.length > 0) { 21912 var attrs = tag.attributes; 21913 21914 for (var i = attrs.length - 1; i >= 0; i--) { 21915 var attrName = attrs[i].name; 21916 var attrVal = attrs[i].value; 21917 21918 // check for known booleans 21919 // the matching element property will return a value for typeof 21920 if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) { 21921 // the value of an included boolean attribute is typically an empty
21922 // string ('') which would equal false if we just check for a false value. 21923 // we also don't want support bad code like autoplay='false' 21924 attrVal = attrVal !== null ? true : false; 21925 } 21926 21927 obj[attrName] = attrVal; 21928 } 21929 } 21930 21931 return obj; 21932} 21933 21934/** 21935 * Get the value of an element's attribute 21936 * 21937 * @param {Element} el 21938 * A DOM element 21939 * 21940 * @param {string} attribute 21941 * Attribute to get the value of 21942 * 21943 * @return {string} 21944 * value of the attribute 21945 */ 21946function getAttribute(el, attribute) { 21947 return el.getAttribute(attribute); 21948} 21949 21950/** 21951 * Set the value of an element's attribute 21952 * 21953 * @param {Element} el 21954 * A DOM element 21955 * 21956 * @param {string} attribute 21957 * Attribute to set 21958 * 21959 * @param {string} value 21960 * Value to set the attribute to 21961 */ 21962function setAttribute(el, attribute, value) { 21963 el.setAttribute(attribute, value); 21964} 21965 21966/** 21967 * Remove an element's attribute 21968 * 21969 * @param {Element} el 21970 * A DOM element 21971 * 21972 * @param {string} attribute 21973 * Attribute to remove 21974 */ 21975function removeAttribute(el, attribute) { 21976 el.removeAttribute(attribute); 21977} 21978 21979/** 21980 * Attempt to block the ability to select text while dragging controls 21981 */ 21982function blockTextSelection() { 21983 _document2['default'].body.focus(); 21984 _document2['default'].onselectstart = function () { 21985 return false; 21986 }; 21987} 21988 21989/** 21990 * Turn off text selection blocking 21991 */ 21992function unblockTextSelection() { 21993 _document2['default'].onselectstart = function () { 21994 return true; 21995 }; 21996} 21997 21998/** 21999 * The postion of a DOM element on the page. 22000 * 22001 * @typedef {Object} Dom~Position 22002 * 22003 * @property {number} left 22004 * Pixels to the left 22005 * 22006 * @property {number} top 22007 * Pixels on top 22008 */ 22009 22010/** 22011 * Offset Left. 22012 * getBoundingClientRect technique from 22013 * John Resig 22014 * 22015 * @see http://ejohn.org/blog/getboundingclientrect-is-awesome/ 22016 * 22017 * @param {Element} el 22018 * Element from which to get offset 22019 * 22020 * @return {Dom~Position} 22021 * The position of the element that was passed in. 22022 */ 22023function findElPosition(el) { 22024 var box = void 0; 22025 22026 if (el.getBoundingClientRect && el.parentNode) { 22027 box = el.getBoundingClientRect(); 22028 } 22029 22030 if (!box) { 22031 return { 22032 left: 0, 22033 top: 0 22034 }; 22035 } 22036 22037 var docEl = _document2['default'].documentElement; 22038 var body = _document2['default'].body; 22039 22040 var clientLeft = docEl.clientLeft || body.clientLeft || 0; 22041 var scrollLeft = _window2['default'].pageXOffset || body.scrollLeft; 22042 var left = box.left + scrollLeft - clientLeft; 22043 22044 var clientTop = docEl.clientTop || body.clientTop || 0; 22045 var scrollTop = _window2['default'].pageYOffset || body.scrollTop; 22046 var top = box.top + scrollTop - clientTop; 22047 22048 // Android sometimes returns slightly off decimal values, so need to round 22049 return { 22050 left: Math.round(left), 22051 top: Math.round(top) 22052 }; 22053} 22054 22055/** 22056 * x and y coordinates for a dom element or mouse pointer 22057 * 22058 * @typedef {Object} Dom~Coordinates 22059 * 22060 * @property {number} x 22061 * x coordinate in pixels 22062 * 22063 * @property {number} y 22064 * y coordinate in pixels 22065 */ 22066 22067/** 22068 * Get pointer position in element 22069 * Returns an object with x and y coordinates. 22070 * The base on the coordinates are the bottom left of the element. 22071 * 22072 * @param {Element} el 22073 * Element on which to get the pointer position on 22074 * 22075 * @param {EventTarget~Event} event 22076 * Event object 22077 * 22078 * @return {Dom~Coordinates} 22079 * A Coordinates object corresponding to the mouse position. 22080 * 22081 */ 22082function getPointerPosition(el, event) { 22083 var position = {}; 22084 var box = findElPosition(el); 22085 var boxW = el.offsetWidth; 22086 var boxH = el.offsetHeight; 22087 22088 var boxY = box.top; 22089 var boxX = box.left; 22090 var pageY = event.pageY; 22091 var pageX = event.pageX; 22092 22093 if (event.changedTouches) { 22094 pageX = event.changedTouches[0].pageX; 22095 pageY = event.changedTouches[0].pageY; 22096 } 22097 22098 position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH)); 22099 position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW)); 22100 22101 return position; 22102} 22103 22104/** 22105 * Determines, via duck typing, whether or not a value is a text node. 22106 * 22107 * @param {Mixed} value 22108 * Check if this value is a text node. 22109 * 22110 * @return {boolean} 22111 * - True if it is a text node 22112 * - False otherwise 22113 */ 22114function isTextNode(value) { 22115 return (0, _obj.isObject)(value) && value.nodeType === 3; 22116} 22117
vendor: 4,080 bytes, lines 22118-22249
22118/** 22119 * Empties the contents of an element. 22120 * 22121 * @param {Element} el 22122 * The element to empty children from 22123 * 22124 * @return {Element} 22125 * The element with no children 22126 */ 22127function emptyEl(el) { 22128 while (el.firstChild) { 22129 el.removeChild(el.firstChild); 22130 } 22131 return el; 22132} 22133 22134/** 22135 * Normalizes content for eventual insertion into the DOM. 22136 * 22137 * This allows a wide range of content definition methods, but protects 22138 * from falling into the trap of simply writing to `innerHTML`, which is 22139 * an XSS concern. 22140 * 22141 * The content for an element can be passed in multiple types and 22142 * combinations, whose behavior is as follows: 22143 * 22144 * @param {String|Element|TextNode|Array|Function} content 22145 * - String: Normalized into a text node. 22146 * - Element/TextNode: Passed through. 22147 * - Array: A one-dimensional array of strings, elements, nodes, or functions 22148 * (which return single strings, elements, or nodes). 22149 * - Function: If the sole argument, is expected to produce a string, element, 22150 * node, or array as defined above. 22151 * 22152 * @return {Array} 22153 * All of the content that was passed in normalized. 22154 */ 22155function normalizeContent(content) { 22156 22157 // First, invoke content if it is a function. If it produces an array, 22158 // that needs to happen before normalization. 22159 if (typeof content === 'function') { 22160 content = content(); 22161 } 22162 22163 // Next up, normalize to an array, so one or many items can be normalized, 22164 // filtered, and returned. 22165 return (Array.isArray(content) ? content : [content]).map(function (value) { 22166 22167 // First, invoke value if it is a function to produce a new value, 22168 // which will be subsequently normalized to a Node of some kind. 22169 if (typeof value === 'function') { 22170 value = value(); 22171 } 22172 22173 if (isEl(value) || isTextNode(value)) { 22174 return value; 22175 } 22176 22177 if (typeof value === 'string' && /\S/.test(value)) { 22178 return _document2['default'].createTextNode(value); 22179 } 22180 }).filter(function (value) { 22181 return value; 22182 }); 22183} 22184 22185/** 22186 * Normalizes and appends content to an element. 22187 * 22188 * @param {Element} el 22189 * Element to append normalized content to. 22190 * 22191 * 22192 * @param {String|Element|TextNode|Array|Function} content 22193 * See the `content` argument of {@link dom:normalizeContent} 22194 * 22195 * @return {Element} 22196 * The element with appended normalized content. 22197 */ 22198function appendContent(el, content) { 22199 normalizeContent(content).forEach(function (node) { 22200 return el.appendChild(node); 22201 }); 22202 return el; 22203} 22204 22205/** 22206 * Normalizes and inserts content into an element; this is identical to 22207 * `appendContent()`, except it empties the element first. 22208 * 22209 * @param {Element} el 22210 * Element to insert normalized content into. 22211 * 22212 * @param {String|Element|TextNode|Array|Function} content 22213 * See the `content` argument of {@link dom:normalizeContent} 22214 * 22215 * @return {Element} 22216 * The element with inserted normalized content. 22217 * 22218 */ 22219function insertContent(el, content) { 22220 return appendContent(emptyEl(el), content); 22221} 22222 22223/** 22224 * Finds a single DOM element matching `selector` within the optional 22225 * `context` of another DOM element (defaulting to `document`). 22226 * 22227 * @param {string} selector 22228 * A valid CSS selector, which will be passed to `querySelector`. 22229 * 22230 * @param {Element|String} [context=document] 22231 * A DOM element within which to query. Can also be a selector 22232 * string in which case the first matching element will be used 22233 * as context. If missing (or no element matches selector), falls 22234 * back to `document`. 22235 * 22236 * @return {Element|null} 22237 * The element that was found or null. 22238 */ 22239var $ = exports.$ = createQuerier('querySelector'); 22240 22241/** 22242 * Finds a all DOM elements matching `selector` within the optional 22243 * `context` of another DOM element (defaulting to `document`). 22244 * 22245 * @param {string} selector 22246 * A valid CSS selector, which will be passed to `querySelectorAll`. 22247 * 22248 * @param {Element|String} [context=document] 22249 * A DOM element within which to query. Can also be a selector
22250 * string in which case the first matching element will be used 22251 * as context. If missing (or no element matches selector), falls 22252 * back to `document`. 22253 * 22254 * @return {NodeList} 22255 * A element list of elements that were found. Will be empty if none were found. 22256 * 22257 */ 22258var $$ = exports.$$ = createQuerier('querySelectorAll'); 22259 22260},{"85":85,"86":86,"88":88,"94":94,"95":95,"98":98}],82:[function(_dereq_,module,exports){ 22261'use strict'; 22262 22263exports.__esModule = true; 22264exports.fixEvent = fixEvent; 22265exports.on = on; 22266exports.off = off; 22267exports.trigger = trigger; 22268exports.one = one; 22269 22270var _dom = _dereq_(81); 22271 22272var Dom = _interopRequireWildcard(_dom); 22273 22274var _guid = _dereq_(85); 22275 22276var Guid = _interopRequireWildcard(_guid); 22277 22278var _log = _dereq_(86); 22279 22280var _log2 = _interopRequireDefault(_log); 22281 22282var _window = _dereq_(95); 22283 22284var _window2 = _interopRequireDefault(_window); 22285 22286var _document = _dereq_(94); 22287 22288var _document2 = _interopRequireDefault(_document); 22289 22290function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 22291 22292function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 22293 22294/** 22295 * Clean up the listener cache and dispatchers 22296 * 22297 * @param {Element|Object} elem 22298 * Element to clean up 22299 * 22300 * @param {string} type 22301 * Type of event to clean up 22302 */ 22303function _cleanUpEvents(elem, type) { 22304 var data = Dom.getElData(elem); 22305 22306 // Remove the events of a particular type if there are none left 22307 if (data.handlers[type].length === 0) { 22308 delete data.handlers[type]; 22309 // data.handlers[type] = null; 22310 // Setting to null was causing an error with data.handlers 22311 22312 // Remove the meta-handler from the element 22313 if (elem.removeEventListener) { 22314 elem.removeEventListener(type, data.dispatcher, false); 22315 } else if (elem.detachEvent) { 22316 elem.detachEvent('on' + type, data.dispatcher); 22317 } 22318 } 22319 22320 // Remove the events object if there are no types left 22321 if (Object.getOwnPropertyNames(data.handlers).length <= 0) { 22322 delete data.handlers; 22323 delete data.dispatcher; 22324 delete data.disabled; 22325 } 22326 22327 // Finally remove the element data if there is no data left 22328 if (Object.getOwnPropertyNames(data).length === 0) { 22329 Dom.removeElData(elem); 22330 } 22331} 22332 22333/** 22334 * Loops through an array of event types and calls the requested method for each type. 22335 * 22336 * @param {Function} fn 22337 * The event method we want to use. 22338 * 22339 * @param {Element|Object} elem 22340 * Element or object to bind listeners to 22341 * 22342 * @param {string} type 22343 * Type of event to bind to. 22344 * 22345 * @param {EventTarget~EventListener} callback 22346 * Event listener. 22347 */ 22348/** 22349 * @file events.js. An Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/) 22350 * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible) 22351 * This should work very similarly to jQuery's events, however it's based off the book version which isn't as 22352 * robust as jquery's, so there's probably some differences. 22353 * 22354 * @module events 22355 */ 22356 22357function _handleMultipleEvents(fn, elem, types, callback) { 22358 types.forEach(function (type) { 22359 // Call the event method for each one of the types 22360 fn(elem, type, callback); 22361 }); 22362} 22363 22364/** 22365 * Fix a native event to have standard property values 22366 * 22367 * @param {Object} event 22368 * Event object to fix. 22369 * 22370 * @return {Object} 22371 * Fixed event object. 22372 */ 22373function fixEvent(event) { 22374 22375 function returnTrue() { 22376 return true; 22377 } 22378 22379 function returnFalse() { 22380 return false; 22381 } 22382 22383 // Test if fixing up is needed 22384 // Used to check if !event.stopPropagation instead of isPropagationStopped 22385 // But native events return true for stopPropagation, but don't have 22386 // other expected methods like isPropagationStopped. Seems to be a problem 22387 // with the Javascript Ninja code. So we're just overriding all events now. 22388 if (!event || !event.isPropagationStopped) { 22389 var old = event || _window2['default'].event; 22390 22391 event = {}; 22392 // Clone the old object so that we can modify the values event = {}; 22393 // IE8 Doesn't like when you mess with native event properties 22394 // Firefox returns false for event.hasOwnProperty('type') and other props 22395 // which makes copying more difficult. 22396 // TODO: Probably best to create a whitelist of event props 22397 for (var key in old) {
vendor: 4,808 bytes, lines 22398-22563
22398 // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y 22399 // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation 22400 // and webkitMovementX/Y 22401 if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') { 22402 // Chrome 32+ warns if you try to copy deprecated returnValue, but 22403 // we still want to if preventDefault isn't supported (IE8). 22404 if (!(key === 'returnValue' && old.preventDefault)) { 22405 event[key] = old[key]; 22406 } 22407 } 22408 } 22409 22410 // The event occurred on this element 22411 if (!event.target) { 22412 event.target = event.srcElement || _document2['default']; 22413 } 22414 22415 // Handle which other element the event is related to 22416 if (!event.relatedTarget) { 22417 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; 22418 } 22419 22420 // Stop the default browser action 22421 event.preventDefault = function () { 22422 if (old.preventDefault) { 22423 old.preventDefault(); 22424 } 22425 event.returnValue = false; 22426 old.returnValue = false; 22427 event.defaultPrevented = true; 22428 }; 22429 22430 event.defaultPrevented = false; 22431 22432 // Stop the event from bubbling 22433 event.stopPropagation = function () { 22434 if (old.stopPropagation) { 22435 old.stopPropagation(); 22436 } 22437 event.cancelBubble = true; 22438 old.cancelBubble = true; 22439 event.isPropagationStopped = returnTrue; 22440 }; 22441 22442 event.isPropagationStopped = returnFalse; 22443 22444 // Stop the event from bubbling and executing other handlers 22445 event.stopImmediatePropagation = function () { 22446 if (old.stopImmediatePropagation) { 22447 old.stopImmediatePropagation(); 22448 } 22449 event.isImmediatePropagationStopped = returnTrue; 22450 event.stopPropagation(); 22451 }; 22452 22453 event.isImmediatePropagationStopped = returnFalse; 22454 22455 // Handle mouse position 22456 if (event.clientX !== null && event.clientX !== undefined) { 22457 var doc = _document2['default'].documentElement; 22458 var body = _document2['default'].body; 22459 22460 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); 22461 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); 22462 } 22463 22464 // Handle key presses 22465 event.which = event.charCode || event.keyCode; 22466 22467 // Fix button for mouse clicks: 22468 // 0 == left; 1 == middle; 2 == right 22469 if (event.button !== null && event.button !== undefined) { 22470 22471 // The following is disabled because it does not pass videojs-standard 22472 // and... yikes. 22473 /* eslint-disable */ 22474 event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0; 22475 /* eslint-enable */ 22476 } 22477 } 22478 22479 // Returns fixed-up instance 22480 return event; 22481} 22482 22483/** 22484 * Add an event listener to element 22485 * It stores the handler function in a separate cache object 22486 * and adds a generic handler to the element's event, 22487 * along with a unique id (guid) to the element. 22488 * 22489 * @param {Element|Object} elem 22490 * Element or object to bind listeners to 22491 * 22492 * @param {string|string[]} type 22493 * Type of event to bind to. 22494 * 22495 * @param {EventTarget~EventListener} fn 22496 * Event listener. 22497 */ 22498function on(elem, type, fn) { 22499 if (Array.isArray(type)) { 22500 return _handleMultipleEvents(on, elem, type, fn); 22501 } 22502 22503 var data = Dom.getElData(elem); 22504 22505 // We need a place to store all our handler data 22506 if (!data.handlers) { 22507 data.handlers = {}; 22508 } 22509 22510 if (!data.handlers[type]) { 22511 data.handlers[type] = []; 22512 } 22513 22514 if (!fn.guid) { 22515 fn.guid = Guid.newGUID(); 22516 } 22517 22518 data.handlers[type].push(fn); 22519 22520 if (!data.dispatcher) { 22521 data.disabled = false; 22522 22523 data.dispatcher = function (event, hash) { 22524 22525 if (data.disabled) { 22526 return; 22527 } 22528 22529 event = fixEvent(event); 22530 22531 var handlers = data.handlers[event.type]; 22532 22533 if (handlers) { 22534 // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off. 22535 var handlersCopy = handlers.slice(0); 22536 22537 for (var m = 0, n = handlersCopy.length; m < n; m++) { 22538 if (event.isImmediatePropagationStopped()) { 22539 break; 22540 } else { 22541 try { 22542 handlersCopy[m].call(elem, event, hash); 22543 } catch (e) { 22544 _log2['default'].error(e); 22545 } 22546 } 22547 } 22548 } 22549 }; 22550 } 22551 22552 if (data.handlers[type].length === 1) { 22553 if (elem.addEventListener) { 22554 elem.addEventListener(type, data.dispatcher, false); 22555 } else if (elem.attachEvent) { 22556 elem.attachEvent('on' + type, data.dispatcher); 22557 } 22558 } 22559} 22560 22561/** 22562 * Removes event listeners from an element 22563 *
22564 * @param {Element|Object} elem 22565 * Object to remove listeners from. 22566 * 22567 * @param {string|string[]} [type] 22568 * Type of listener to remove. Don't include to remove all events from element. 22569 * 22570 * @param {EventTarget~EventListener} [fn] 22571 * Specific listener to remove. Don't include to remove listeners for an event 22572 * type. 22573 */ 22574function off(elem, type, fn) { 22575 // Don't want to add a cache object through getElData if not needed 22576 if (!Dom.hasElData(elem)) { 22577 return; 22578 } 22579 22580 var data = Dom.getElData(elem); 22581 22582 // If no events exist, nothing to unbind 22583 if (!data.handlers) { 22584 return; 22585 } 22586 22587 if (Array.isArray(type)) { 22588 return _handleMultipleEvents(off, elem, type, fn); 22589 } 22590 22591 // Utility function 22592 var removeType = function removeType(t) { 22593 data.handlers[t] = []; 22594 _cleanUpEvents(elem, t); 22595 }; 22596 22597 // Are we removing all bound events? 22598 if (!type) { 22599 for (var t in data.handlers) { 22600 removeType(t); 22601 } 22602 return; 22603 } 22604 22605 var handlers = data.handlers[type]; 22606 22607 // If no handlers exist, nothing to unbind 22608 if (!handlers) { 22609 return; 22610 } 22611 22612 // If no listener was provided, remove all listeners for type 22613 if (!fn) { 22614 removeType(type); 22615 return; 22616 } 22617 22618 // We're only removing a single handler 22619 if (fn.guid) { 22620 for (var n = 0; n < handlers.length; n++) { 22621 if (handlers[n].guid === fn.guid) { 22622 handlers.splice(n--, 1); 22623 } 22624 } 22625 } 22626 22627 _cleanUpEvents(elem, type); 22628} 22629 22630/** 22631 * Trigger an event for an element 22632 * 22633 * @param {Element|Object} elem 22634 * Element to trigger an event on 22635 * 22636 * @param {EventTarget~Event|string} event 22637 * A string (the type) or an event object with a type attribute 22638 * 22639 * @param {Object} [hash] 22640 * data hash to pass along with the event 22641 * 22642 * @return {boolean|undefined} 22643 * - Returns the opposite of `defaultPrevented` if default was prevented 22644 * - Otherwise returns undefined 22645 */ 22646function trigger(elem, event, hash) { 22647 // Fetches element data and a reference to the parent (for bubbling). 22648 // Don't want to add a data object to cache for every parent, 22649 // so checking hasElData first. 22650 var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {}; 22651 var parent = elem.parentNode || elem.ownerDocument; 22652 // type = event.type || event, 22653 // handler; 22654 22655 // If an event name was passed as a string, creates an event out of it 22656 if (typeof event === 'string') { 22657 event = { type: event, target: elem }; 22658 } 22659 // Normalizes the event properties. 22660 event = fixEvent(event); 22661 22662 // If the passed element has a dispatcher, executes the established handlers. 22663 if (elemData.dispatcher) { 22664 elemData.dispatcher.call(elem, event, hash); 22665 } 22666 22667 // Unless explicitly stopped or the event does not bubble (e.g. media events) 22668 // recursively calls this function to bubble the event up the DOM. 22669 if (parent && !event.isPropagationStopped() && event.bubbles === true) { 22670 trigger.call(null, parent, event, hash); 22671 22672 // If at the top of the DOM, triggers the default action unless disabled. 22673 } else if (!parent && !event.defaultPrevented) { 22674 var targetData = Dom.getElData(event.target); 22675 22676 // Checks if the target has a default action for this event. 22677 if (event.target[event.type]) { 22678 // Temporarily disables event dispatching on the target as we have already executed the handler. 22679 targetData.disabled = true; 22680 // Executes the default action. 22681 if (typeof event.target[event.type] === 'function') { 22682 event.target[event.type](); 22683 } 22684 // Re-enables event dispatching. 22685 targetData.disabled = false; 22686 } 22687 } 22688 22689 // Inform the triggerer if the default was prevented by returning false 22690 return !event.defaultPrevented; 22691} 22692 22693/** 22694 * Trigger a listener only once for an event 22695 * 22696 * @param {Element|Object} elem 22697 * Element or object to bind to. 22698 * 22699 * @param {string|string[]} type 22700 * Name/type of event 22701 * 22702 * @param {Event~EventListener} fn 22703 * Event Listener function 22704 */ 22705function one(elem, type, fn) { 22706 if (Array.isArray(type)) { 22707 return _handleMultipleEvents(one, elem, type, fn); 22708 } 22709 var func = function func() { 22710 off(elem, type, func); 22711 fn.apply(this, arguments); 22712 }; 22713 22714 // copy the guid to the new function so it can removed using the original function's ID 22715 func.guid = fn.guid = fn.guid || Guid.newGUID(); 22716 on(elem, type, func); 22717} 22718 22719},{"81":81,"85":85,"86":86,"94":94,"95":95}],83:[function(_dereq_,module,exports){ 22720'use strict'; 22721 22722exports.__esModule = true; 22723exports.throttle = exports.bind = undefined; 22724 22725var _guid = _dereq_(85); 22726 22727/**
22728 * Bind (a.k.a proxy or Context). A simple method for changing the context of a function 22729 * It also stores a unique id on the function so it can be easily removed from events. 22730 * 22731 * @param {Mixed} context 22732 * The object to bind as scope. 22733 * 22734 * @param {Function} fn 22735 * The function to be bound to a scope. 22736 * 22737 * @param {number} [uid] 22738 * An optional unique ID for the function to be set 22739 * 22740 * @return {Function} 22741 * The new function that will be bound into the context given 22742 */ 22743var bind = exports.bind = function bind(context, fn, uid) { 22744 // Make sure the function has a unique ID 22745 if (!fn.guid) { 22746 fn.guid = (0, _guid.newGUID)(); 22747 } 22748 22749 // Create the new function that changes the context 22750 var bound = function bound() { 22751 return fn.apply(context, arguments); 22752 }; 22753 22754 // Allow for the ability to individualize this function 22755 // Needed in the case where multiple objects might share the same prototype 22756 // IF both items add an event listener with the same function, then you try to remove just one 22757 // it will remove both because they both have the same guid. 22758 // when using this, you need to use the bind method when you remove the listener as well. 22759 // currently used in text tracks 22760 bound.guid = uid ? uid + '_' + fn.guid : fn.guid; 22761 22762 return bound; 22763}; 22764 22765/** 22766 * Wraps the given function, `fn`, with a new function that only invokes `fn` 22767 * at most once per every `wait` milliseconds. 22768 * 22769 * @param {Function} fn 22770 * The function to be throttled. 22771 * 22772 * @param {Number} wait 22773 * The number of milliseconds by which to throttle. 22774 * 22775 * @return {Function} 22776 */ 22777/** 22778 * @file fn.js 22779 * @module fn 22780 */ 22781var throttle = exports.throttle = function throttle(fn, wait) { 22782 var last = Date.now(); 22783 22784 var throttled = function throttled() { 22785 var now = Date.now(); 22786 22787 if (now - last >= wait) { 22788 fn.apply(undefined, arguments); 22789 last = now; 22790 } 22791 }; 22792 22793 return throttled; 22794}; 22795 22796},{"85":85}],84:[function(_dereq_,module,exports){ 22797'use strict'; 22798 22799exports.__esModule = true; 22800/** 22801 * @file format-time.js 22802 * @module Format-time 22803 */ 22804 22805/** 22806 * Format seconds as a time string, H:MM:SS or M:SS. Supplying a guide (in seconds) 22807 * will force a number of leading zeros to cover the length of the guide. 22808 * 22809 * @param {number} seconds 22810 * Number of seconds to be turned into a string 22811 * 22812 * @param {number} guide 22813 * Number (in seconds) to model the string after 22814 * 22815 * @return {string} 22816 * Time formatted as H:MM:SS or M:SS 22817 */ 22818function formatTime(seconds) { 22819 var guide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : seconds; 22820 22821 seconds = seconds < 0 ? 0 : seconds; 22822 var s = Math.floor(seconds % 60); 22823 var m = Math.floor(seconds / 60 % 60); 22824 var h = Math.floor(seconds / 3600); 22825 var gm = Math.floor(guide / 60 % 60); 22826 var gh = Math.floor(guide / 3600); 22827 22828 // handle invalid times 22829 if (isNaN(seconds) || seconds === Infinity) { 22830 // '-' is false for all relational operators (e.g. <, >=) so this setting 22831 // will add the minimum number of fields specified by the guide 22832 h = m = s = '-'; 22833 } 22834 22835 // Check if we need to show hours 22836 h = h > 0 || gh > 0 ? h + ':' : ''; 22837 22838 // If hours are showing, we may need to add a leading zero. 22839 // Always show at least one digit of minutes. 22840 m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':'; 22841 22842 // Check if leading zero is need for seconds 22843 s = s < 10 ? '0' + s : s; 22844 22845 return h + m + s; 22846} 22847 22848exports['default'] = formatTime; 22849 22850},{}],85:[function(_dereq_,module,exports){ 22851"use strict"; 22852 22853exports.__esModule = true; 22854exports.newGUID = newGUID; 22855/** 22856 * @file guid.js 22857 * @module guid 22858 */ 22859 22860/** 22861 * Unique ID for an element or function 22862 * @type {Number} 22863 */ 22864var _guid = 1; 22865 22866/** 22867 * Get a unique auto-incrementing ID by number that has not been returned before. 22868 * 22869 * @return {number} 22870 * A new unique ID. 22871 */ 22872function newGUID() { 22873 return _guid++; 22874} 22875 22876},{}],86:[function(_dereq_,module,exports){ 22877'use strict'; 22878 22879exports.__esModule = true; 22880exports.logByType = undefined; 22881 22882var _window = _dereq_(95); 22883 22884var _window2 = _interopRequireDefault(_window); 22885 22886var _browser = _dereq_(78); 22887 22888var _obj = _dereq_(88); 22889 22890function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 22891 22892var log = void 0; 22893 22894/** 22895 * Log messages to the console and history based on the type of message 22896 * 22897 * @param {string} type 22898 * The name of the console method to use. 22899 * 22900 * @param {Array} args 22901 * The arguments to be passed to the matching console method. 22902 * 22903 * @param {boolean} [stringify] 22904 * By default, only old IEs should get console argument stringification, 22905 * but this is exposed as a parameter to facilitate testing. 22906 */ 22907/** 22908 * @file log.js 22909 * @module log 22910 */ 22911var logByType = exports.logByType = function logByType(type, args) { 22912 var stringify = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : !!_browser.IE_VERSION && _browser.IE_VERSION < 11; 22913 22914 22915 if (type !== 'log') { 22916 22917 // add the type to the front of the message when it's not "log" 22918 args.unshift(type.toUpperCase() + ':'); 22919 } 22920 22921 // add to history 22922 log.history.push(args); 22923 22924 // add console prefix after adding to history 22925 args.unshift('VIDEOJS:'); 22926 22927 // If there's no console then don't try to output messages, but they will 22928 // still be stored in `log.history`. 22929 // 22930 // Was setting these once outside of this function, but containing them 22931 // in the function makes it easier to test cases where console doesn't exist 22932 // when the module is executed. 22933 var fn = _window2['default'].console && _window2['default'].console[type]; 22934 22935 // Bail out if there's no console. 22936 if (!fn) { 22937 return; 22938 } 22939 22940 // IEs previous to 11 log objects uselessly as "[object Object]"; so, JSONify 22941 // objects and arrays for those less-capable browsers. 22942 if (stringify) { 22943 args = args.map(function (a) { 22944 if ((0, _obj.isObject)(a) || Array.isArray(a)) { 22945 try { 22946 return JSON.stringify(a); 22947 } catch (x) { 22948 return String(a); 22949 } 22950 } 22951 22952 // Cast to string before joining, so we get null and undefined explicitly 22953 // included in output (as we would in a modern console). 22954 return String(a); 22955 }).join(' '); 22956 } 22957 22958 // Old IE versions do not allow .apply() for console methods (they are 22959 // reported as objects rather than functions). 22960 if (!fn.apply) { 22961 fn(args); 22962 } else { 22963 fn[Array.isArray(args) ? 'apply' : 'call'](_window2['default'].console, args); 22964 } 22965}; 22966 22967/** 22968 * Log plain debug messages 22969 * 22970 * @param {Mixed[]} args 22971 * One or more messages or objects that should be logged. 22972 */ 22973log = function log() { 22974 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { 22975 args[_key] = arguments[_key]; 22976 } 22977 22978 logByType('log', args); 22979}; 22980 22981/** 22982 * Keep a history of log messages 22983 * 22984 * @type {Array} 22985 */ 22986log.history = []; 22987 22988/** 22989 * Log error messages 22990 * 22991 * @param {Mixed[]} args 22992 * One or more messages or objects that should be logged as an error 22993 */ 22994log.error = function () { 22995 for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 22996 args[_key2] = arguments[_key2]; 22997 } 22998 22999 return logByType('error', args); 23000}; 23001 23002/** 23003 * Log warning messages 23004 * 23005 * @param {Mixed[]} args 23006 * One or more messages or objects that should be logged as a warning. 23007 */ 23008log.warn = function () { 23009 for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { 23010 args[_key3] = arguments[_key3]; 23011 } 23012 23013 return logByType('warn', args); 23014}; 23015 23016exports['default'] = log; 23017 23018},{"78":78,"88":88,"95":95}],87:[function(_dereq_,module,exports){ 23019'use strict'; 23020 23021exports.__esModule = true; 23022exports['default'] = mergeOptions; 23023 23024var _obj = _dereq_(88); 23025 23026/** 23027 * Deep-merge one or more options objects, recursively merging **only** plain 23028 * object properties. 23029 * 23030 * @param {Object[]} sources
23031 * One or more objects to merge into a new object. 23032 * 23033 * @returns {Object} 23034 * A new object that is the merged result of all sources. 23035 */ 23036function mergeOptions() { 23037 var result = {}; 23038 23039 for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) { 23040 sources[_key] = arguments[_key]; 23041 } 23042 23043 sources.forEach(function (source) { 23044 if (!source) { 23045 return; 23046 } 23047 23048 (0, _obj.each)(source, function (value, key) { 23049 if (!(0, _obj.isPlain)(value)) { 23050 result[key] = value; 23051 return; 23052 } 23053 23054 if (!(0, _obj.isPlain)(result[key])) { 23055 result[key] = {}; 23056 } 23057 23058 result[key] = mergeOptions(result[key], value); 23059 }); 23060 }); 23061 23062 return result; 23063} /** 23064 * @file merge-options.js 23065 * @module merge-options 23066 */ 23067 23068},{"88":88}],88:[function(_dereq_,module,exports){ 23069'use strict'; 23070 23071exports.__esModule = true; 23072 23073var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 23074 23075exports.each = each; 23076exports.reduce = reduce; 23077exports.assign = assign; 23078exports.isObject = isObject; 23079exports.isPlain = isPlain; 23080/** 23081 * @file obj.js 23082 * @module obj 23083 */ 23084 23085/** 23086 * @callback obj:EachCallback 23087 * 23088 * @param {Mixed} value 23089 * The current key for the object that is being iterated over. 23090 * 23091 * @param {string} key 23092 * The current key-value for object that is being iterated over 23093 */ 23094 23095/** 23096 * @callback obj:ReduceCallback 23097 * 23098 * @param {Mixed} accum 23099 * The value that is accumulating over the reduce loop. 23100 * 23101 * @param {Mixed} value 23102 * The current key for the object that is being iterated over. 23103 * 23104 * @param {string} key 23105 * The current key-value for object that is being iterated over 23106 * 23107 * @return {Mixed} 23108 * The new accumulated value. 23109 */ 23110var toString = Object.prototype.toString; 23111 23112/** 23113 * Get the keys of an Object 23114 * 23115 * @param {Object} 23116 * The Object to get the keys from 23117 * 23118 * @return {string[]} 23119 * An array of the keys from the object. Returns an empty array if the 23120 * object passed in was invalid or had no keys. 23121 * 23122 * @private 23123 */ 23124var keys = function keys(object) { 23125 return isObject(object) ? Object.keys(object) : []; 23126}; 23127 23128/** 23129 * Array-like iteration for objects. 23130 * 23131 * @param {Object} object 23132 * The object to iterate over 23133 * 23134 * @param {obj:EachCallback} fn 23135 * The callback function which is called for each key in the object. 23136 */ 23137function each(object, fn) { 23138 keys(object).forEach(function (key) { 23139 return fn(object[key], key); 23140 }); 23141} 23142 23143/** 23144 * Array-like reduce for objects. 23145 * 23146 * @param {Object} object 23147 * The Object that you want to reduce. 23148 * 23149 * @param {Function} fn 23150 * A callback function which is called for each key in the object. It 23151 * receives the accumulated value and the per-iteration value and key 23152 * as arguments. 23153 * 23154 * @param {Mixed} [initial = 0] 23155 * Starting value 23156 * 23157 * @return {Mixed} 23158 * The final accumulated value. 23159 */ 23160function reduce(object, fn) { 23161 var initial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; 23162 23163 return keys(object).reduce(function (accum, key) { 23164 return fn(accum, object[key], key); 23165 }, initial); 23166} 23167 23168/** 23169 * Object.assign-style object shallow merge/extend. 23170 * 23171 * @param {Object} target 23172 * @param {Object} ...sources 23173 * @return {Object} 23174 */ 23175function assign(target) { 23176 for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 23177 sources[_key - 1] = arguments[_key]; 23178 } 23179 23180 if (Object.assign) { 23181 return Object.assign.apply(Object, [target].concat(sources)); 23182 } 23183 23184 sources.forEach(function (source) { 23185 if (!source) { 23186 return; 23187 } 23188 23189 each(source, function (value, key) { 23190 target[key] = value; 23191 }); 23192 }); 23193 23194 return target; 23195} 23196 23197/** 23198 * Returns whether a value is an object of any kind - including DOM nodes, 23199 * arrays, regular expressions, etc. Not functions, though. 23200 * 23201 * This avoids the gotcha where using `typeof` on a `null` value 23202 * results in `'object'`. 23203 * 23204 * @param {Object} value 23205 * @return {Boolean} 23206 */ 23207function isObject(value) { 23208 return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object'; 23209} 23210 23211/** 23212 * Returns whether an object appears to be a "plain" object - that is, a
23213 * direct instance of `Object`. 23214 * 23215 * @param {Object} value 23216 * @return {Boolean} 23217 */ 23218function isPlain(value) { 23219 return isObject(value) && toString.call(value) === '[object Object]' && value.constructor === Object; 23220} 23221 23222},{}],89:[function(_dereq_,module,exports){ 23223'use strict'; 23224 23225exports.__esModule = true; 23226exports.setTextContent = exports.createStyleElement = undefined; 23227 23228var _document = _dereq_(94); 23229 23230var _document2 = _interopRequireDefault(_document); 23231 23232function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 23233 23234/** 23235 * Create a DOM syle element given a className for it. 23236 * 23237 * @param {string} className 23238 * The className to add to the created style element. 23239 * 23240 * @return {Element} 23241 * The element that was created. 23242 */ 23243var createStyleElement = exports.createStyleElement = function createStyleElement(className) { 23244 var style = _document2['default'].createElement('style'); 23245 23246 style.className = className; 23247 23248 return style; 23249}; 23250 23251/** 23252 * Add text to a DOM element. 23253 * 23254 * @param {Element} el 23255 * The Element to add text content to. 23256 * 23257 * @param {string} content 23258 * The text to add to the element. 23259 */ 23260/** 23261 * @file stylesheet.js 23262 * @module stylesheet 23263 */ 23264var setTextContent = exports.setTextContent = function setTextContent(el, content) { 23265 if (el.styleSheet) { 23266 el.styleSheet.cssText = content; 23267 } else { 23268 el.textContent = content; 23269 } 23270}; 23271 23272},{"94":94}],90:[function(_dereq_,module,exports){ 23273'use strict'; 23274 23275exports.__esModule = true; 23276exports.createTimeRange = undefined; 23277exports.createTimeRanges = createTimeRanges; 23278 23279var _log = _dereq_(86); 23280 23281var _log2 = _interopRequireDefault(_log); 23282 23283function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 23284 23285/** 23286 * Returns the time for the specified index at the start or end 23287 * of a TimeRange object. 23288 * 23289 * @function time-ranges:indexFunction 23290 * 23291 * @param {number} [index=0] 23292 * The range number to return the time for. 23293 * 23294 * @return {number} 23295 * The time that offset at the specified index. 23296 * 23297 * @depricated index must be set to a value, in the future this will throw an error. 23298 */ 23299 23300/** 23301 * An object that contains ranges of time for various reasons. 23302 * 23303 * @typedef {Object} TimeRange 23304 * 23305 * @property {number} length 23306 * The number of time ranges represented by this Object 23307 * 23308 * @property {time-ranges:indexFunction} start 23309 * Returns the time offset at which a specified time range begins. 23310 * 23311 * @property {time-ranges:indexFunction} end 23312 * Returns the time offset at which a specified time range begins. 23313 * 23314 * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges 23315 */ 23316 23317/** 23318 * Check if any of the time ranges are over the maximum index. 23319 * 23320 * @param {string} fnName 23321 * The function name to use for logging 23322 * 23323 * @param {number} index 23324 * The index to check 23325 * 23326 * @param {number} maxIndex 23327 * The maximum possible index 23328 * 23329 * @throws {Error} if the timeRanges provided are over the maxIndex 23330 */ 23331function rangeCheck(fnName, index, maxIndex) { 23332 if (index < 0 || index > maxIndex) { 23333 throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').'); 23334 } 23335} 23336 23337/** 23338 * Check if any of the time ranges are over the maximum index. 23339 * 23340 * @param {string} fnName 23341 * The function name to use for logging 23342 * 23343 * @param {string} valueIndex 23344 * The proprety that should be used to get the time. should be 'start' or 'end' 23345 * 23346 * @param {Array} ranges 23347 * An array of time ranges 23348 * 23349 * @param {Array} [rangeIndex=0] 23350 * The index to start the search at 23351 * 23352 * @return {number} 23353 * The time that offset at the specified index. 23354 * 23355 * 23356 * @depricated rangeIndex must be set to a value, in the future this will throw an error. 23357 * @throws {Error} if rangeIndex is more than the length of ranges 23358 */ 23359/** 23360 * @file time-ranges.js 23361 * @module time-ranges 23362 */ 23363function getRange(fnName, valueIndex, ranges, rangeIndex) { 23364 if (rangeIndex === undefined) { 23365 _log2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.'); 23366 rangeIndex = 0; 23367 } 23368 rangeCheck(fnName, rangeIndex, ranges.length - 1); 23369 return ranges[rangeIndex][valueIndex]; 23370} 23371 23372/** 23373 * Create a time range object givent ranges of time. 23374 * 23375 * @param {Array} [ranges] 23376 * An array of time ranges. 23377 */ 23378function createTimeRangesObj(ranges) { 23379 if (ranges === undefined || ranges.length === 0) { 23380 return { 23381 length: 0, 23382 start: function start() { 23383 throw new Error('This TimeRanges object is empty'); 23384 }, 23385 end: function end() { 23386 throw new Error('This TimeRanges object is empty'); 23387 } 23388 }; 23389 } 23390 return { 23391 length: ranges.length, 23392 start: getRange.bind(null, 'start', 0, ranges), 23393 end: getRange.bind(null, 'end', 1, ranges) 23394 }; 23395} 23396 23397/** 23398 * Should create a fake `TimeRange` object which mimics an HTML5 time range instance. 23399 * 23400 * @param {number|Array} start 23401 * The start of a single range or an array of ranges 23402 * 23403 * @param {number} end 23404 * The end of a single range. 23405 * 23406 * @private 23407 */ 23408function createTimeRanges(start, end) { 23409 if (Array.isArray(start)) { 23410 return createTimeRangesObj(start); 23411 } else if (start === undefined || end === undefined) { 23412 return createTimeRangesObj(); 23413 } 23414 return createTimeRangesObj([[start, end]]); 23415} 23416 23417exports.createTimeRange = createTimeRanges; 23418 23419},{"86":86}],91:[function(_dereq_,module,exports){ 23420'use strict'; 23421 23422exports.__esModule = true; 23423/** 23424 * @file to-title-case.js 23425 * @module to-title-case 23426 */ 23427 23428/** 23429 * Uppercase the first letter of a string. 23430 * 23431 * @param {string} string 23432 * String to be uppercased 23433 * 23434 * @return {string} 23435 * The string with an uppercased first letter 23436 */ 23437function toTitleCase(string) { 23438 if (typeof string !== 'string') { 23439 return string; 23440 } 23441 23442 return string.charAt(0).toUpperCase() + string.slice(1); 23443} 23444 23445exports['default'] = toTitleCase; 23446 23447},{}],92:[function(_dereq_,module,exports){ 23448'use strict'; 23449 23450exports.__esModule = true; 23451exports.isCrossOrigin = exports.getFileExtension = exports.getAbsoluteURL = exports.parseUrl = undefined; 23452 23453var _document = _dereq_(94); 23454 23455var _document2 = _interopRequireDefault(_document); 23456 23457var _window = _dereq_(95); 23458 23459var _window2 = _interopRequireDefault(_window); 23460 23461function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 23462 23463/** 23464 * @typedef {Object} url:URLObject 23465 * 23466 * @property {string} protocol 23467 * The protocol of the url that was parsed. 23468 * 23469 * @property {string} hostname 23470 * The hostname of the url that was parsed. 23471 * 23472 * @property {string} port 23473 * The port of the url that was parsed. 23474 * 23475 * @property {string} pathname 23476 * The pathname of the url that was parsed. 23477 * 23478 * @property {string} search 23479 * The search query of the url that was parsed. 23480 * 23481 * @property {string} hash 23482 * The hash of the url that was parsed. 23483 * 23484 * @property {string} host 23485 * The host of the url that was parsed. 23486 */ 23487 23488/** 23489 * Resolve and parse the elements of a URL. 23490 * 23491 * @param {String} url 23492 * The url to parse 23493 * 23494 * @return {url:URLObject} 23495 * An object of url details 23496 */ 23497/** 23498 * @file url.js 23499 * @module url 23500 */ 23501var parseUrl = exports.parseUrl = function parseUrl(url) { 23502 var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host']; 23503 23504 // add the url to an anchor and let the browser parse the URL 23505 var a = _document2['default'].createElement('a'); 23506 23507 a.href = url; 23508 23509 // IE8 (and 9?) Fix
23510 // ie8 doesn't parse the URL correctly until the anchor is actually 23511 // added to the body, and an innerHTML is needed to trigger the parsing 23512 var addToBody = a.host === '' && a.protocol !== 'file:'; 23513 var div = void 0; 23514 23515 if (addToBody) { 23516 div = _document2['default'].createElement('div'); 23517 div.innerHTML = '<a href="' + url + '"></a>'; 23518 a = div.firstChild; 23519 // prevent the div from affecting layout 23520 div.setAttribute('style', 'display:none; position:absolute;'); 23521 _document2['default'].body.appendChild(div); 23522 } 23523 23524 // Copy the specific URL properties to a new object 23525 // This is also needed for IE8 because the anchor loses its 23526 // properties when it's removed from the dom 23527 var details = {}; 23528 23529 for (var i = 0; i < props.length; i++) { 23530 details[props[i]] = a[props[i]]; 23531 } 23532 23533 // IE9 adds the port to the host property unlike everyone else. If 23534 // a port identifier is added for standard ports, strip it. 23535 if (details.protocol === 'http:') { 23536 details.host = details.host.replace(/:80$/, ''); 23537 } 23538 23539 if (details.protocol === 'https:') { 23540 details.host = details.host.replace(/:443$/, ''); 23541 } 23542 23543 if (addToBody) { 23544 _document2['default'].body.removeChild(div); 23545 } 23546 23547 return details; 23548}; 23549 23550/** 23551 * Get absolute version of relative URL. Used to tell flash correct URL. 23552 * 23553 * 23554 * @param {string} url 23555 * URL to make absolute 23556 * 23557 * @return {string} 23558 * Absolute URL 23559 * 23560 * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue 23561 */ 23562var getAbsoluteURL = exports.getAbsoluteURL = function getAbsoluteURL(url) { 23563 // Check if absolute URL 23564 if (!url.match(/^https?:\/\//)) { 23565 // Convert to absolute URL. Flash hosted off-site needs an absolute URL. 23566 var div = _document2['default'].createElement('div'); 23567 23568 div.innerHTML = '<a href="' + url + '">x</a>'; 23569 url = div.firstChild.href; 23570 } 23571 23572 return url; 23573}; 23574 23575/** 23576 * Returns the extension of the passed file name. It will return an empty string 23577 * if passed an invalid path. 23578 * 23579 * @param {string} path 23580 * The fileName path like '/path/to/file.mp4' 23581 * 23582 * @returns {string} 23583 * The extension in lower case or an empty string if no 23584 * extension could be found. 23585 */ 23586var getFileExtension = exports.getFileExtension = function getFileExtension(path) { 23587 if (typeof path === 'string') { 23588 var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i; 23589 var pathParts = splitPathRe.exec(path); 23590 23591 if (pathParts) { 23592 return pathParts.pop().toLowerCase(); 23593 } 23594 } 23595 23596 return ''; 23597}; 23598 23599/** 23600 * Returns whether the url passed is a cross domain request or not. 23601 * 23602 * @param {string} url 23603 * The url to check. 23604 * 23605 * @return {boolean} 23606 * Whether it is a cross domain request or not. 23607 */ 23608var isCrossOrigin = exports.isCrossOrigin = function isCrossOrigin(url) { 23609 var winLoc = _window2['default'].location; 23610 var urlInfo = parseUrl(url); 23611 23612 // IE8 protocol relative urls will return ':' for protocol 23613 var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol; 23614 23615 // Check if url is for another domain/origin 23616 // IE8 doesn't know location.origin, so we won't rely on it here 23617 var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host; 23618 23619 return crossOrigin; 23620}; 23621 23622},{"94":94,"95":95}],93:[function(_dereq_,module,exports){ 23623'use strict'; 23624 23625exports.__esModule = true; 23626 23627var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /** 23628 * @file video.js 23629 * @module videojs 23630 */ 23631 23632/* global define */ 23633 23634// Include the built-in techs 23635 23636 23637var _window = _dereq_(95); 23638 23639var _window2 = _interopRequireDefault(_window); 23640 23641var _document = _dereq_(94); 23642 23643var _document2 = _interopRequireDefault(_document); 23644 23645var _setup = _dereq_(56); 23646 23647var setup = _interopRequireWildcard(_setup); 23648 23649var _stylesheet = _dereq_(89); 23650 23651var stylesheet = _interopRequireWildcard(_stylesheet); 23652 23653var _component = _dereq_(5); 23654 23655var _component2 = _interopRequireDefault(_component); 23656 23657var _eventTarget = _dereq_(42); 23658 23659var _eventTarget2 = _interopRequireDefault(_eventTarget); 23660 23661var _events = _dereq_(82); 23662 23663var Events = _interopRequireWildcard(_events); 23664 23665var _player = _dereq_(51); 23666 23667var _player2 = _interopRequireDefault(_player); 23668 23669var _plugins = _dereq_(52); 23670 23671var _plugins2 = _interopRequireDefault(_plugins); 23672 23673var _mergeOptions2 = _dereq_(87); 23674 23675var _mergeOptions3 = _interopRequireDefault(_mergeOptions2); 23676 23677var _fn = _dereq_(83); 23678 23679var Fn = _interopRequireWildcard(_fn); 23680 23681var _textTrack = _dereq_(72); 23682 23683var _textTrack2 = _interopRequireDefault(_textTrack); 23684 23685var _audioTrack = _dereq_(64); 23686 23687var _audioTrack2 = _interopRequireDefault(_audioTrack); 23688 23689var _videoTrack = _dereq_(77); 23690 23691var _videoTrack2 = _interopRequireDefault(_videoTrack); 23692 23693var _timeRanges = _dereq_(90); 23694 23695var _formatTime = _dereq_(84); 23696 23697var _formatTime2 = _interopRequireDefault(_formatTime); 23698 23699var _log = _dereq_(86); 23700 23701var _log2 = _interopRequireDefault(_log); 23702 23703var _dom = _dereq_(81); 23704 23705var Dom = _interopRequireWildcard(_dom); 23706 23707var _browser = _dereq_(78); 23708 23709var browser = _interopRequireWildcard(_browser); 23710 23711var _url = _dereq_(92); 23712 23713var Url = _interopRequireWildcard(_url); 23714 23715var _obj = _dereq_(88); 23716 23717var _computedStyle = _dereq_(80); 23718 23719var _computedStyle2 = _interopRequireDefault(_computedStyle); 23720 23721var _extend = _dereq_(43); 23722 23723var _extend2 = _interopRequireDefault(_extend); 23724 23725var _xhr = _dereq_(99); 23726
23727var _xhr2 = _interopRequireDefault(_xhr); 23728 23729var _tech = _dereq_(62); 23730 23731var _tech2 = _interopRequireDefault(_tech); 23732 23733function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } 23734 23735function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 23736 23737// HTML5 Element Shim for IE8 23738if (typeof HTMLVideoElement === 'undefined' && Dom.isReal()) { 23739 _document2['default'].createElement('video'); 23740 _document2['default'].createElement('audio'); 23741 _document2['default'].createElement('track'); 23742} 23743 23744/** 23745 * Doubles as the main function for users to create a player instance and also 23746 * the main library object. 23747 * The `videojs` function can be used to initialize or retrieve a player. 23748 * 23749 * @param {string|Element} id 23750 * Video element or video element ID 23751 * 23752 * @param {Object} [options] 23753 * Optional options object for config/settings 23754 * 23755 * @param {Component~ReadyCallback} [ready] 23756 * Optional ready callback 23757 * 23758 * @return {Player} 23759 * A player instance 23760 * 23761 * @mixes videojs 23762 */ 23763function videojs(id, options, ready) { 23764 var tag = void 0; 23765 23766 // Allow for element or ID to be passed in 23767 // String ID 23768 if (typeof id === 'string') { 23769 23770 // Adjust for jQuery ID syntax 23771 if (id.indexOf('#') === 0) { 23772 id = id.slice(1); 23773 } 23774 23775 // If a player instance has already been created for this ID return it. 23776 if (videojs.getPlayers()[id]) { 23777 23778 // If options or ready funtion are passed, warn 23779 if (options) { 23780 _log2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.'); 23781 } 23782 23783 if (ready) { 23784 videojs.getPlayers()[id].ready(ready); 23785 } 23786 23787 return videojs.getPlayers()[id]; 23788 } 23789 23790 // Otherwise get element for ID 23791 tag = Dom.getEl(id); 23792 23793 // ID is a media element 23794 } else { 23795 tag = id; 23796 } 23797 23798 // Check for a useable element 23799 // re: nodeName, could be a box div also 23800 if (!tag || !tag.nodeName) { 23801 throw new TypeError('The element or ID supplied is not valid. (videojs)'); 23802 } 23803 23804 // Element may have a player attr referring to an already created player instance. 23805 // If so return that otherwise set up a new player below 23806 if (tag.player || _player2['default'].players[tag.playerId]) { 23807 return tag.player || _player2['default'].players[tag.playerId]; 23808 } 23809 23810 options = options || {}; 23811 23812 videojs.hooks('beforesetup').forEach(function (hookFunction) { 23813 var opts = hookFunction(tag, (0, _mergeOptions3['default'])(options)); 23814 23815 if (!(0, _obj.isObject)(opts) || Array.isArray(opts)) { 23816 _log2['default'].error('please return an object in beforesetup hooks'); 23817 return; 23818 } 23819 23820 options = (0, _mergeOptions3['default'])(options, opts); 23821 }); 23822 23823 var PlayerComponent = _component2['default'].getComponent('Player'); 23824 // If not, set up a new player 23825 var player = new PlayerComponent(tag, options, ready); 23826 23827 videojs.hooks('setup').forEach(function (hookFunction) { 23828 return hookFunction(player); 23829 }); 23830 23831 return player; 23832} 23833 23834/** 23835 * An Object that contains lifecycle hooks as keys which point to an array 23836 * of functions that are run when a lifecycle is triggered 23837 */ 23838videojs.hooks_ = {}; 23839 23840/** 23841 * Get a list of hooks for a specific lifecycle 23842 * 23843 * @param {string} type 23844 * the lifecyle to get hooks from 23845 * 23846 * @param {Function} [fn] 23847 * Optionally add a hook to the lifecycle that your are getting. 23848 * 23849 * @return {Array} 23850 * an array of hooks, or an empty array if there are none. 23851 */ 23852videojs.hooks = function (type, fn) { 23853 videojs.hooks_[type] = videojs.hooks_[type] || []; 23854 if (fn) { 23855 videojs.hooks_[type] = videojs.hooks_[type].concat(fn); 23856 } 23857 return videojs.hooks_[type]; 23858}; 23859 23860/** 23861 * Add a function hook to a specific videojs lifecycle. 23862 * 23863 * @param {string} type 23864 * the lifecycle to hook the function to. 23865 * 23866 * @param {Function|Function[]} 23867 * The function or array of functions to attach. 23868 */
23869videojs.hook = function (type, fn) { 23870 videojs.hooks(type, fn); 23871}; 23872 23873/** 23874 * Remove a hook from a specific videojs lifecycle. 23875 * 23876 * @param {string} type 23877 * the lifecycle that the function hooked to 23878 * 23879 * @param {Function} fn 23880 * The hooked function to remove 23881 * 23882 * @return {boolean} 23883 * The function that was removed or undef 23884 */ 23885videojs.removeHook = function (type, fn) { 23886 var index = videojs.hooks(type).indexOf(fn); 23887 23888 if (index <= -1) { 23889 return false; 23890 } 23891 23892 videojs.hooks_[type] = videojs.hooks_[type].slice(); 23893 videojs.hooks_[type].splice(index, 1); 23894 23895 return true; 23896}; 23897 23898// Add default styles 23899if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true && Dom.isReal()) { 23900 var style = Dom.$('.vjs-styles-defaults'); 23901 23902 if (!style) { 23903 style = stylesheet.createStyleElement('vjs-styles-defaults'); 23904 var head = Dom.$('head'); 23905 23906 if (head) { 23907 head.insertBefore(style, head.firstChild); 23908 } 23909 stylesheet.setTextContent(style, '\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n '); 23910 } 23911} 23912 23913// Run Auto-load players 23914// You have to wait at least once in case this script is loaded after your 23915// video in the DOM (weird behavior only with minified version) 23916setup.autoSetupTimeout(1, videojs); 23917 23918/** 23919 * Current software version. Follows semver. 23920 * 23921 * @type {string} 23922 */ 23923videojs.VERSION = '5.19.2'; 23924 23925/** 23926 * The global options object. These are the settings that take effect 23927 * if no overrides are specified when the player is created. 23928 * 23929 * @type {Object} 23930 */ 23931videojs.options = _player2['default'].prototype.options_; 23932 23933/** 23934 * Get an object with the currently created players, keyed by player ID 23935 * 23936 * @return {Object} 23937 * The created players 23938 */ 23939videojs.getPlayers = function () { 23940 return _player2['default'].players; 23941}; 23942 23943/** 23944 * Expose players object. 23945 * 23946 * @memberOf videojs 23947 * @property {Object} players 23948 */ 23949videojs.players = _player2['default'].players; 23950 23951/** 23952 * Get a component class object by name 23953 * 23954 * @borrows Component.getComponent as videojs.getComponent 23955 */ 23956videojs.getComponent = _component2['default'].getComponent; 23957 23958/** 23959 * Register a component so it can referred to by name. Used when adding to other 23960 * components, either through addChild `component.addChild('myComponent')` or through 23961 * default children options `{ children: ['myComponent'] }`. 23962 * 23963 * > NOTE: You could also just initialize the component before adding. 23964 * `component.addChild(new MyComponent());` 23965 * 23966 * @param {string} name 23967 * The class name of the component 23968 * 23969 * @param {Component} comp 23970 * The component class 23971 * 23972 * @return {Component} 23973 * The newly registered component 23974 */ 23975videojs.registerComponent = function (name, comp) { 23976 if (_tech2['default'].isTech(comp)) { 23977 _log2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)'); 23978 } 23979 23980 _component2['default'].registerComponent.call(_component2['default'], name, comp); 23981}; 23982 23983/** 23984 * Get a Tech class object by name 23985 * 23986 * @borrows Tech.getTech as videojs.getTech 23987 */ 23988videojs.getTech = _tech2['default'].getTech; 23989 23990/** 23991 * Register a Tech so it can referred to by name. 23992 * This is used in the tech order for the player. 23993 * 23994 * @borrows Tech.registerTech as videojs.registerTech 23995 */ 23996videojs.registerTech = _tech2['default'].registerTech; 23997 23998/** 23999 * A suite of browser and device tests from {@link browser}. 24000 * 24001 * @type {Object} 24002 * @private 24003 */ 24004videojs.browser = browser; 24005 24006/** 24007 * Whether or not the browser supports touch events. Included for backward 24008 * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED` 24009 * instead going forward. 24010 * 24011 * @deprecated since version 5.0 24012 * @type {boolean} 24013 */ 24014videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED; 24015 24016/** 24017 * Subclass an existing class 24018 * Mimics ES6 subclassing with the `extend` keyword 24019 * 24020 * @borrows extend:extendFn as videojs.extend 24021 */ 24022videojs.extend = _extend2['default']; 24023 24024/** 24025 * Merge two options objects recursively 24026 * Performs a deep merge like lodash.merge but **only merges plain objects** 24027 * (not arrays, elements, anything else) 24028 * Other values will be copied directly from the second object. 24029 * 24030 * @borrows merge-options:mergeOptions as videojs.mergeOptions 24031 */ 24032videojs.mergeOptions = _mergeOptions3['default']; 24033 24034/** 24035 * Change the context (this) of a function 24036 * 24037 * > NOTE: as of v5.0 we require an ES5 shim, so you should use the native 24038 * `function() {}.bind(newContext);` instead of this. 24039 * 24040 * @borrows fn:bind as videojs.bind 24041 */ 24042videojs.bind = Fn.bind; 24043 24044/** 24045 * Create a Video.js player plugin. 24046 * Plugins are only initialized when options for the plugin are included 24047 * in the player options, or the plugin function on the player instance is 24048 * called. 24049 * 24050 * @borrows plugin:plugin as videojs.plugin 24051 */ 24052videojs.plugin = _plugins2['default']; 24053 24054/** 24055 * Adding languages so that they're available to all players. 24056 * Example: `videojs.addLanguage('es', { 'Hello': 'Hola' });` 24057 * 24058 * @param {string} code 24059 * The language code or dictionary property 24060 * 24061 * @param {Object} data 24062 * The data values to be translated 24063 * 24064 * @return {Object} 24065 * The resulting language dictionary object 24066 */ 24067videojs.addLanguage = function (code, data) { 24068 var _mergeOptions; 24069 24070 code = ('' + code).toLowerCase(); 24071 24072 videojs.options.languages = (0, _mergeOptions3['default'])(videojs.options.languages, (_mergeOptions = {}, _mergeOptions[code] = data, _mergeOptions)); 24073 24074 return videojs.options.languages[code]; 24075}; 24076 24077/** 24078 * Log messages 24079 * 24080 * @borrows log:log as videojs.log 24081 */ 24082videojs.log = _log2['default']; 24083 24084/** 24085 * Creates an emulated TimeRange object. 24086 * 24087 * @borrows time-ranges:createTimeRanges as videojs.createTimeRange 24088 */ 24089/** 24090 * @borrows time-ranges:createTimeRanges as videojs.createTimeRanges 24091 */ 24092videojs.createTimeRange = videojs.createTimeRanges = _timeRanges.createTimeRanges; 24093 24094/** 24095 * Format seconds as a time string, H:MM:SS or M:SS 24096 * Supplying a guide (in seconds) will force a number of leading zeros 24097 * to cover the length of the guide 24098 * 24099 * @borrows format-time:formatTime as videojs.formatTime 24100 */ 24101videojs.formatTime = _formatTime2['default']; 24102 24103/** 24104 * Resolve and parse the elements of a URL 24105 * 24106 * @borrows url:parseUrl as videojs.parseUrl 24107 */ 24108videojs.parseUrl = Url.parseUrl; 24109 24110/** 24111 * Returns whether the url passed is a cross domain request or not. 24112 * 24113 * @borrows url:isCrossOrigin as videojs.isCrossOrigin 24114 */
24115videojs.isCrossOrigin = Url.isCrossOrigin; 24116 24117/** 24118 * Event target class. 24119 * 24120 * @borrows EventTarget as videojs.EventTarget 24121 */ 24122videojs.EventTarget = _eventTarget2['default']; 24123 24124/** 24125 * Add an event listener to element 24126 * It stores the handler function in a separate cache object 24127 * and adds a generic handler to the element's event, 24128 * along with a unique id (guid) to the element. 24129 * 24130 * @borrows events:on as videojs.on 24131 */ 24132videojs.on = Events.on; 24133 24134/** 24135 * Trigger a listener only once for an event 24136 * 24137 * @borrows events:one as videojs.one 24138 */ 24139videojs.one = Events.one; 24140 24141/** 24142 * Removes event listeners from an element 24143 * 24144 * @borrows events:off as videojs.off 24145 */ 24146videojs.off = Events.off; 24147 24148/** 24149 * Trigger an event for an element 24150 * 24151 * @borrows events:trigger as videojs.trigger 24152 */ 24153videojs.trigger = Events.trigger; 24154 24155/** 24156 * A cross-browser XMLHttpRequest wrapper. Here's a simple example: 24157 * 24158 * @param {Object} options 24159 * settings for the request. 24160 * 24161 * @return {XMLHttpRequest|XDomainRequest} 24162 * The request object. 24163 * 24164 * @see https://github.com/Raynos/xhr 24165 */ 24166videojs.xhr = _xhr2['default']; 24167 24168/** 24169 * TextTrack class 24170 * 24171 * @borrows TextTrack as videojs.TextTrack 24172 */ 24173videojs.TextTrack = _textTrack2['default']; 24174 24175/** 24176 * export the AudioTrack class so that source handlers can create 24177 * AudioTracks and then add them to the players AudioTrackList 24178 * 24179 * @borrows AudioTrack as videojs.AudioTrack 24180 */ 24181videojs.AudioTrack = _audioTrack2['default']; 24182 24183/** 24184 * export the VideoTrack class so that source handlers can create 24185 * VideoTracks and then add them to the players VideoTrackList 24186 * 24187 * @borrows VideoTrack as videojs.VideoTrack 24188 */ 24189videojs.VideoTrack = _videoTrack2['default']; 24190 24191/** 24192 * Determines, via duck typing, whether or not a value is a DOM element. 24193 * 24194 * @borrows dom:isEl as videojs.isEl 24195 */ 24196videojs.isEl = Dom.isEl; 24197 24198/** 24199 * Determines, via duck typing, whether or not a value is a text node. 24200 * 24201 * @borrows dom:isTextNode as videojs.isTextNode 24202 */ 24203videojs.isTextNode = Dom.isTextNode; 24204 24205/** 24206 * Creates an element and applies properties. 24207 * 24208 * @borrows dom:createEl as videojs.createEl 24209 */ 24210videojs.createEl = Dom.createEl; 24211 24212/** 24213 * Check if an element has a CSS class 24214 * 24215 * @borrows dom:hasElClass as videojs.hasClass 24216 */ 24217videojs.hasClass = Dom.hasElClass; 24218 24219/** 24220 * Add a CSS class name to an element 24221 * 24222 * @borrows dom:addElClass as videojs.addClass 24223 */ 24224videojs.addClass = Dom.addElClass; 24225 24226/** 24227 * Remove a CSS class name from an element 24228 * 24229 * @borrows dom:removeElClass as videojs.removeClass 24230 */ 24231videojs.removeClass = Dom.removeElClass; 24232 24233/** 24234 * Adds or removes a CSS class name on an element depending on an optional 24235 * condition or the presence/absence of the class name. 24236 * 24237 * @borrows dom:toggleElClass as videojs.toggleClass 24238 */ 24239videojs.toggleClass = Dom.toggleElClass; 24240 24241/** 24242 * Apply attributes to an HTML element. 24243 * 24244 * @borrows dom:setElAttributes as videojs.setAttribute 24245 */ 24246videojs.setAttributes = Dom.setElAttributes; 24247 24248/** 24249 * Get an element's attribute values, as defined on the HTML tag 24250 * Attributes are not the same as properties. They're defined on the tag 24251 * or with setAttribute (which shouldn't be used with HTML) 24252 * This will return true or false for boolean attributes. 24253 * 24254 * @borrows dom:getElAttributes as videojs.getAttributes 24255 */ 24256videojs.getAttributes = Dom.getElAttributes; 24257 24258/** 24259 * Empties the contents of an element. 24260 * 24261 * @borrows dom:emptyEl as videojs.emptyEl 24262 */ 24263videojs.emptyEl = Dom.emptyEl; 24264 24265/** 24266 * Normalizes and appends content to an element. 24267 * 24268 * The content for an element can be passed in multiple types and 24269 * combinations, whose behavior is as follows: 24270 * 24271 * - String 24272 * Normalized into a text node. 24273 * 24274 * - Element, TextNode 24275 * Passed through. 24276 * 24277 * - Array 24278 * A one-dimensional array of strings, elements, nodes, or functions (which 24279 * return single strings, elements, or nodes). 24280 * 24281 * - Function 24282 * If the sole argument, is expected to produce a string, element, 24283 * node, or array. 24284 * 24285 * @borrows dom:appendContents as videojs.appendContet 24286 */ 24287videojs.appendContent = Dom.appendContent; 24288 24289/** 24290 * Normalizes and inserts content into an element; this is identical to 24291 * `appendContent()`, except it empties the element first. 24292 * 24293 * The content for an element can be passed in multiple types and 24294 * combinations, whose behavior is as follows: 24295 * 24296 * - String 24297 * Normalized into a text node. 24298 * 24299 * - Element, TextNode 24300 * Passed through. 24301 * 24302 * - Array
24303 * A one-dimensional array of strings, elements, nodes, or functions (which 24304 * return single strings, elements, or nodes). 24305 * 24306 * - Function 24307 * If the sole argument, is expected to produce a string, element, 24308 * node, or array. 24309 * 24310 * @borrows dom:insertContent as videojs.insertContent 24311 */ 24312videojs.insertContent = Dom.insertContent; 24313 24314/** 24315 * A safe getComputedStyle with an IE8 fallback. 24316 * 24317 * This is because in Firefox, if the player is loaded in an iframe with `display:none`, 24318 * then `getComputedStyle` returns `null`, so, we do a null-check to make sure 24319 * that the player doesn't break in these cases. 24320 * See https://bugzilla.mozilla.org/show_bug.cgi?id=548397 for more details. 24321 * 24322 * @borrows computed-style:computedStyle as videojs.computedStyle 24323 */ 24324videojs.computedStyle = _computedStyle2['default']; 24325 24326/* 24327 * Custom Universal Module Definition (UMD) 24328 * 24329 * Video.js will never be a non-browser lib so we can simplify UMD a bunch and 24330 * still support requirejs and browserify. This also needs to be closure 24331 * compiler compatible, so string keys are used. 24332 */ 24333if (typeof define === 'function' && define.amd) { 24334 define('videojs', [], function () { 24335 return videojs; 24336 }); 24337 24338 // checking that module is an object too because of umdjs/umd#35 24339} else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && (typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') { 24340 module.exports = videojs; 24341} 24342 24343exports['default'] = videojs; 24344 24345},{"42":42,"43":43,"5":5,"51":51,"52":52,"56":56,"62":62,"64":64,"72":72,"77":77,"78":78,"80":80,"81":81,"82":82,"83":83,"84":84,"86":86,"87":87,"88":88,"89":89,"90":90,"92":92,"94":94,"95":95,"99":99}],94:[function(_dereq_,module,exports){ 24346(function (global){ 24347var topLevel = typeof global !== 'undefined' ? global : 24348 typeof window !== 'undefined' ? window : {} 24349var minDoc = _dereq_(96); 24350 24351if (typeof document !== 'undefined') { 24352 module.exports = document; 24353} else { 24354 var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4']; 24355 24356 if (!doccy) { 24357 doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc; 24358 } 24359 24360 module.exports = doccy; 24361} 24362 24363}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 24364},{"96":96}],95:[function(_dereq_,module,exports){ 24365(function (global){ 24366if (typeof window !== "undefined") { 24367 module.exports = window; 24368} else if (typeof global !== "undefined") { 24369 module.exports = global; 24370} else if (typeof self !== "undefined"){ 24371 module.exports = self; 24372} else { 24373 module.exports = {}; 24374} 24375 24376}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 24377},{}],96:[function(_dereq_,module,exports){ 24378 24379},{}],97:[function(_dereq_,module,exports){ 24380module.exports = SafeParseTuple 24381 24382function SafeParseTuple(obj, reviver) { 24383 var json 24384 var error = null 24385 24386 try { 24387 json = JSON.parse(obj, reviver) 24388 } catch (err) { 24389 error = err 24390 } 24391 24392 return [error, json] 24393} 24394 24395},{}],98:[function(_dereq_,module,exports){ 24396function clean (s) { 24397 return s.replace(/\n\r?\s*/g, '') 24398} 24399 24400 24401module.exports = function tsml (sa) { 24402 var s = '' 24403 , i = 0 24404 24405 for (; i < arguments.length; i++) 24406 s += clean(sa[i]) + (arguments[i + 1] || '') 24407 24408 return s 24409} 24410},{}],99:[function(_dereq_,module,exports){ 24411"use strict"; 24412var window = _dereq_(95) 24413var isFunction = _dereq_(100) 24414var parseHeaders = _dereq_(103) 24415var xtend = _dereq_(104) 24416 24417module.exports = createXHR 24418createXHR.XMLHttpRequest = window.XMLHttpRequest || noop 24419createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest 24420 24421forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) { 24422 createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) { 24423 options = initParams(uri, options, callback) 24424 options.method = method.toUpperCase() 24425 return _createXHR(options) 24426 } 24427}) 24428 24429function forEachArray(array, iterator) { 24430 for (var i = 0; i < array.length; i++) { 24431 iterator(array[i]) 24432 } 24433} 24434 24435function isEmpty(obj){ 24436 for(var i in obj){ 24437 if(obj.hasOwnProperty(i)) return false 24438 } 24439 return true 24440} 24441 24442function initParams(uri, options, callback) { 24443 var params = uri 24444 24445 if (isFunction(options)) { 24446 callback = options 24447 if (typeof uri === "string") { 24448 params = {uri:uri} 24449 } 24450 } else { 24451 params = xtend(options, {uri: uri}) 24452 } 24453 24454 params.callback = callback 24455 return params 24456} 24457 24458function createXHR(uri, options, callback) { 24459 options = initParams(uri, options, callback) 24460 return _createXHR(options) 24461} 24462 24463function _createXHR(options) { 24464 if(typeof options.callback === "undefined"){ 24465 throw new Error("callback argument missing") 24466 } 24467 24468 var called = false 24469 var callback = function cbOnce(err, response, body){ 24470 if(!called){ 24471 called = true 24472 options.callback(err, response, body) 24473 } 24474 } 24475 24476 function readystatechange() { 24477 if (xhr.readyState === 4) { 24478 setTimeout(loadFunc, 0) 24479 } 24480 } 24481 24482 function getBody() { 24483 // Chrome with requestType=blob throws errors arround when even testing access to responseText 24484 var body = undefined 24485 24486 if (xhr.response) { 24487 body = xhr.response 24488 } else { 24489 body = xhr.responseText || getXml(xhr) 24490 } 24491 24492 if (isJson) { 24493 try { 24494 body = JSON.parse(body) 24495 } catch (e) {} 24496 } 24497 24498 return body 24499 } 24500 24501 function errorFunc(evt) { 24502 clearTimeout(timeoutTimer) 24503 if(!(evt instanceof Error)){ 24504 evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") ) 24505 } 24506 evt.statusCode = 0 24507 return callback(evt, failureResponse) 24508 } 24509 24510 // will load the data & process the response in a special response object 24511 function loadFunc() { 24512 if (aborted) return 24513 var status 24514 clearTimeout(timeoutTimer) 24515 if(options.useXDR && xhr.status===undefined) { 24516 //IE8 CORS GET successful response doesn't have a status field, but body is fine 24517 status = 200 24518 } else { 24519 status = (xhr.status === 1223 ? 204 : xhr.status) 24520 } 24521 var response = failureResponse 24522 var err = null 24523 24524 if (status !== 0){ 24525 response = { 24526 body: getBody(), 24527 statusCode: status, 24528 method: method, 24529 headers: {},
vendor: 4,883 bytes, lines 24530-24687
24530 url: uri, 24531 rawRequest: xhr 24532 } 24533 if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE 24534 response.headers = parseHeaders(xhr.getAllResponseHeaders()) 24535 } 24536 } else { 24537 err = new Error("Internal XMLHttpRequest Error") 24538 } 24539 return callback(err, response, response.body) 24540 } 24541 24542 var xhr = options.xhr || null 24543 24544 if (!xhr) { 24545 if (options.cors || options.useXDR) { 24546 xhr = new createXHR.XDomainRequest() 24547 }else{ 24548 xhr = new createXHR.XMLHttpRequest() 24549 } 24550 } 24551 24552 var key 24553 var aborted 24554 var uri = xhr.url = options.uri || options.url 24555 var method = xhr.method = options.method || "GET" 24556 var body = options.body || options.data 24557 var headers = xhr.headers = options.headers || {} 24558 var sync = !!options.sync 24559 var isJson = false 24560 var timeoutTimer 24561 var failureResponse = { 24562 body: undefined, 24563 headers: {}, 24564 statusCode: 0, 24565 method: method, 24566 url: uri, 24567 rawRequest: xhr 24568 } 24569 24570 if ("json" in options && options.json !== false) { 24571 isJson = true 24572 headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user 24573 if (method !== "GET" && method !== "HEAD") { 24574 headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user 24575 body = JSON.stringify(options.json === true ? body : options.json) 24576 } 24577 } 24578 24579 xhr.onreadystatechange = readystatechange 24580 xhr.onload = loadFunc 24581 xhr.onerror = errorFunc 24582 // IE9 must have onprogress be set to a unique function. 24583 xhr.onprogress = function () { 24584 // IE must die 24585 } 24586 xhr.onabort = function(){ 24587 aborted = true; 24588 } 24589 xhr.ontimeout = errorFunc 24590 xhr.open(method, uri, !sync, options.username, options.password) 24591 //has to be after open 24592 if(!sync) { 24593 xhr.withCredentials = !!options.withCredentials 24594 } 24595 // Cannot set timeout with sync request 24596 // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly 24597 // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent 24598 if (!sync && options.timeout > 0 ) { 24599 timeoutTimer = setTimeout(function(){ 24600 if (aborted) return 24601 aborted = true//IE9 may still call readystatechange 24602 xhr.abort("timeout") 24603 var e = new Error("XMLHttpRequest timeout") 24604 e.code = "ETIMEDOUT" 24605 errorFunc(e) 24606 }, options.timeout ) 24607 } 24608 24609 if (xhr.setRequestHeader) { 24610 for(key in headers){ 24611 if(headers.hasOwnProperty(key)){ 24612 xhr.setRequestHeader(key, headers[key]) 24613 } 24614 } 24615 } else if (options.headers && !isEmpty(options.headers)) { 24616 throw new Error("Headers cannot be set on an XDomainRequest object") 24617 } 24618 24619 if ("responseType" in options) { 24620 xhr.responseType = options.responseType 24621 } 24622 24623 if ("beforeSend" in options && 24624 typeof options.beforeSend === "function" 24625 ) { 24626 options.beforeSend(xhr) 24627 } 24628 24629 // Microsoft Edge browser sends "undefined" when send is called with undefined value. 24630 // XMLHttpRequest spec says to pass null as body to indicate no body 24631 // See https://github.com/naugtur/xhr/issues/100. 24632 xhr.send(body || null) 24633 24634 return xhr 24635 24636 24637} 24638 24639function getXml(xhr) { 24640 if (xhr.responseType === "document") { 24641 return xhr.responseXML 24642 } 24643 var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror" 24644 if (xhr.responseType === "" && !firefoxBugTakenEffect) { 24645 return xhr.responseXML 24646 } 24647 24648 return null 24649} 24650 24651function noop() {} 24652 24653},{"100":100,"103":103,"104":104,"95":95}],100:[function(_dereq_,module,exports){ 24654module.exports = isFunction 24655 24656var toString = Object.prototype.toString 24657 24658function isFunction (fn) { 24659 var string = toString.call(fn) 24660 return string === '[object Function]' || 24661 (typeof fn === 'function' && string !== '[object RegExp]') || 24662 (typeof window !== 'undefined' && 24663 // IE8 and below 24664 (fn === window.setTimeout || 24665 fn === window.alert || 24666 fn === window.confirm || 24667 fn === window.prompt)) 24668}; 24669 24670},{}],101:[function(_dereq_,module,exports){ 24671var isFunction = _dereq_(100) 24672 24673module.exports = forEach 24674 24675var toString = Object.prototype.toString 24676var hasOwnProperty = Object.prototype.hasOwnProperty 24677 24678function forEach(list, iterator, context) { 24679 if (!isFunction(iterator)) { 24680 throw new TypeError('iterator must be a function') 24681 } 24682 24683 if (arguments.length < 3) { 24684 context = this 24685 } 24686 24687 if (toString.call(list) === '[object Array]')
24688 forEachArray(list, iterator, context) 24689 else if (typeof list === 'string') 24690 forEachString(list, iterator, context) 24691 else 24692 forEachObject(list, iterator, context) 24693} 24694 24695function forEachArray(array, iterator, context) { 24696 for (var i = 0, len = array.length; i < len; i++) { 24697 if (hasOwnProperty.call(array, i)) { 24698 iterator.call(context, array[i], i, array) 24699 } 24700 } 24701} 24702 24703function forEachString(string, iterator, context) { 24704 for (var i = 0, len = string.length; i < len; i++) { 24705 // no such thing as a sparse string. 24706 iterator.call(context, string.charAt(i), i, string) 24707 } 24708} 24709 24710function forEachObject(object, iterator, context) { 24711 for (var k in object) { 24712 if (hasOwnProperty.call(object, k)) { 24713 iterator.call(context, object[k], k, object) 24714 } 24715 } 24716} 24717 24718},{"100":100}],102:[function(_dereq_,module,exports){ 24719 24720exports = module.exports = trim; 24721 24722function trim(str){ 24723 return str.replace(/^\s*|\s*$/g, ''); 24724} 24725 24726exports.left = function(str){ 24727 return str.replace(/^\s*/, ''); 24728}; 24729 24730exports.right = function(str){ 24731 return str.replace(/\s*$/, ''); 24732}; 24733 24734},{}],103:[function(_dereq_,module,exports){ 24735var trim = _dereq_(102) 24736 , forEach = _dereq_(101) 24737 , isArray = function(arg) { 24738 return Object.prototype.toString.call(arg) === '[object Array]'; 24739 } 24740 24741module.exports = function (headers) { 24742 if (!headers) 24743 return {} 24744 24745 var result = {} 24746 24747 forEach( 24748 trim(headers).split('\n') 24749 , function (row) { 24750 var index = row.indexOf(':') 24751 , key = trim(row.slice(0, index)).toLowerCase() 24752 , value = trim(row.slice(index + 1)) 24753 24754 if (typeof(result[key]) === 'undefined') { 24755 result[key] = value 24756 } else if (isArray(result[key])) { 24757 result[key].push(value) 24758 } else { 24759 result[key] = [ result[key], value ] 24760 } 24761 } 24762 ) 24763 24764 return result 24765} 24766},{"101":101,"102":102}],104:[function(_dereq_,module,exports){ 24767module.exports = extend 24768 24769var hasOwnProperty = Object.prototype.hasOwnProperty; 24770 24771function extend() { 24772 var target = {} 24773 24774 for (var i = 0; i < arguments.length; i++) { 24775 var source = arguments[i] 24776 24777 for (var key in source) { 24778 if (hasOwnProperty.call(source, key)) { 24779 target[key] = source[key] 24780 } 24781 } 24782 } 24783 24784 return target 24785} 24786 24787},{}],105:[function(_dereq_,module,exports){ 24788/** 24789 * Copyright 2013 vtt.js Contributors 24790 * 24791 * Licensed under the Apache License, Version 2.0 (the "License"); 24792 * you may not use this file except in compliance with the License. 24793 * You may obtain a copy of the License at 24794 * 24795 * http://www.apache.org/licenses/LICENSE-2.0 24796 * 24797 * Unless required by applicable law or agreed to in writing, software 24798 * distributed under the License is distributed on an "AS IS" BASIS, 24799 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24800 * See the License for the specific language governing permissions and 24801 * limitations under the License. 24802 */ 24803 24804// Default exports for Node. Export the extended versions of VTTCue and 24805// VTTRegion in Node since we likely want the capability to convert back and 24806// forth between JSON. If we don't then it's not that big of a deal since we're 24807// off browser. 24808 24809var window = _dereq_(109); 24810 24811var vttjs = module.exports = { 24812 WebVTT: _dereq_(106).WebVTT, 24813 VTTCue: _dereq_(107).VTTCue, 24814 VTTRegion: _dereq_(108).VTTRegion 24815}; 24816 24817window.vttjs = vttjs; 24818window.WebVTT = vttjs.WebVTT; 24819 24820var cueShim = vttjs.VTTCue; 24821var regionShim = vttjs.VTTRegion; 24822var nativeVTTCue = window.VTTCue; 24823var nativeVTTRegion = window.VTTRegion; 24824 24825vttjs.shim = function() { 24826 window.VTTCue = cueShim; 24827 window.VTTRegion = regionShim; 24828}; 24829 24830vttjs.restore = function() { 24831 window.VTTCue = nativeVTTCue; 24832 window.VTTRegion = nativeVTTRegion; 24833}; 24834 24835if (!window.VTTCue) { 24836 vttjs.shim(); 24837} 24838 24839},{"106":106,"107":107,"108":108,"109":109}],106:[function(_dereq_,module,exports){ 24840/** 24841 * Copyright 2013 vtt.js Contributors 24842 * 24843 * Licensed under the Apache License, Version 2.0 (the "License"); 24844 * you may not use this file except in compliance with the License. 24845 * You may obtain a copy of the License at 24846 * 24847 * http://www.apache.org/licenses/LICENSE-2.0 24848 * 24849 * Unless required by applicable law or agreed to in writing, softw
vendor: 17,184 bytes, lines 24849-25384
24849are 24850 * distributed under the License is distributed on an "AS IS" BASIS, 24851 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24852 * See the License for the specific language governing permissions and 24853 * limitations under the License. 24854 */ 24855 24856/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 24857/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 24858 24859(function(global) { 24860 24861 var _objCreate = Object.create || (function() { 24862 function F() {} 24863 return function(o) { 24864 if (arguments.length !== 1) { 24865 throw new Error('Object.create shim only accepts one parameter.'); 24866 } 24867 F.prototype = o; 24868 return new F(); 24869 }; 24870 })(); 24871 24872 // Creates a new ParserError object from an errorData object. The errorData 24873 // object should have default code and message properties. The default message 24874 // property can be overriden by passing in a message parameter. 24875 // See ParsingError.Errors below for acceptable errors. 24876 function ParsingError(errorData, message) { 24877 this.name = "ParsingError"; 24878 this.code = errorData.code; 24879 this.message = message || errorData.message; 24880 } 24881 ParsingError.prototype = _objCreate(Error.prototype); 24882 ParsingError.prototype.constructor = ParsingError; 24883 24884 // ParsingError metadata for acceptable ParsingErrors. 24885 ParsingError.Errors = { 24886 BadSignature: { 24887 code: 0, 24888 message: "Malformed WebVTT signature." 24889 }, 24890 BadTimeStamp: { 24891 code: 1, 24892 message: "Malformed time stamp." 24893 } 24894 }; 24895 24896 // Try to parse input as a time stamp. 24897 function parseTimeStamp(input) { 24898 24899 function computeSeconds(h, m, s, f) { 24900 return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000; 24901 } 24902 24903 var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/); 24904 if (!m) { 24905 return null; 24906 } 24907 24908 if (m[3]) { 24909 // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds] 24910 return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]); 24911 } else if (m[1] > 59) { 24912 // Timestamp takes the form of [hours]:[minutes].[milliseconds] 24913 // First position is hours as it's over 59. 24914 return computeSeconds(m[1], m[2], 0, m[4]); 24915 } else { 24916 // Timestamp takes the form of [minutes]:[seconds].[milliseconds] 24917 return computeSeconds(0, m[1], m[2], m[4]); 24918 } 24919 } 24920 24921 // A settings object holds key/value pairs and will ignore anything but the first 24922 // assignment to a specific key. 24923 function Settings() { 24924 this.values = _objCreate(null); 24925 } 24926 24927 Settings.prototype = { 24928 // Only accept the first assignment to any key. 24929 set: function(k, v) { 24930 if (!this.get(k) && v !== "") { 24931 this.values[k] = v; 24932 } 24933 }, 24934 // Return the value for a key, or a default value. 24935 // If 'defaultKey' is passed then 'dflt' is assumed to be an object with 24936 // a number of possible default values as properties where 'defaultKey' is 24937 // the key of the property that will be chosen; otherwise it's assumed to be 24938 // a single value. 24939 get: function(k, dflt, defaultKey) { 24940 if (defaultKey) { 24941 return this.has(k) ? this.values[k] : dflt[defaultKey]; 24942 } 24943 return this.has(k) ? this.values[k] : dflt; 24944 }, 24945 // Check whether we have a value for a key. 24946 has: function(k) { 24947 return k in this.values; 24948 }, 24949 // Accept a setting if its one of the given alternatives. 24950 alt: function(k, v, a) { 24951 for (var n = 0; n < a.length; ++n) { 24952 if (v === a[n]) { 24953 this.set(k, v); 24954 break; 24955 } 24956 } 24957 }, 24958 // Accept a setting if its a valid (signed) integer. 24959 integer: function(k, v) { 24960 if (/^-?\d+$/.test(v)) { // integer 24961 this.set(k, parseInt(v, 10)); 24962 } 24963 }, 24964 // Accept a setting if its a valid percentage. 24965 percent: function(k, v) { 24966 var m; 24967 if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) { 24968 v = parseFloat(v); 24969 if (v >= 0 && v <= 100) { 24970 this.set(k, v); 24971 return true; 24972 } 24973 } 24974 return false; 24975 } 24976 }; 24977 24978 // Helper function to parse input into groups separated by 'groupDelim', and 24979 // interprete each group as a key/value pair separated by 'keyValueDelim'. 24980 function parseOptions(input, callback, keyValueDelim, groupDelim) { 24981 var groups = groupDelim ? input.split(groupDelim) : [input]; 24982 for (var i in groups) { 24983 if (typeof groups[i] !== "string") { 24984 continue; 24985 } 24986 var kv = groups[i].split(keyValueDelim); 24987 if (kv.length !== 2) { 24988 continue; 24989 } 24990 var k = kv[0]; 24991 var v = kv[1]; 24992 callback(k, v); 24993 } 24994 } 24995 24996 function parseCue(input, cue, regionList) { 24997 // Remember the original input if we need to throw an error. 24998 var oInput = input; 24999 // 4.1 WebVTT timestamp 25000 function consumeTimeStamp() { 25001 var ts = parseTimeStamp(input); 25002 if (ts === null) { 25003 throw new ParsingError(ParsingError.Errors.BadTimeStamp, 25004 "Malformed timestamp: " + oInput); 25005 } 25006 // Remove time stamp from input. 25007 input = input.replace(/^[^\sa-zA-Z-]+/, ""); 25008 return ts; 25009 } 25010 25011 // 4.4.2 WebVTT cue settings 25012 function consumeCueSettings(input, cue) { 25013 var settings = new Settings(); 25014 25015 parseOptions(input, function (k, v) { 25016 switch (k) { 25017 case "region": 25018 // Find the last region we parsed with the same region id. 25019 for (var i = regionList.length - 1; i >= 0; i--) { 25020 if (regionList[i].id === v) { 25021 settings.set(k, regionList[i].region); 25022 break; 25023 } 25024 } 25025 break; 25026 case "vertical": 25027 settings.alt(k, v, ["rl", "lr"]); 25028 break; 25029 case "line": 25030 var vals = v.split(","), 25031 vals0 = vals[0]; 25032 settings.integer(k, vals0); 25033 settings.percent(k, vals0) ? settings.set("snapToLines", false) : null; 25034 settings.alt(k, vals0, ["auto"]); 25035 if (vals.length === 2) { 25036 settings.alt("lineAlign", vals[1], ["start", "middle", "end"]); 25037 } 25038 break; 25039 case "position": 25040 vals = v.split(","); 25041 settings.percent(k, vals[0]); 25042 if (vals.length === 2) { 25043 settings.alt("positionAlign", vals[1], ["start", "middle", "end"]); 25044 } 25045 break; 25046 case "size": 25047 settings.percent(k, v); 25048 break; 25049 case "align": 25050 settings.alt(k, v, ["start", "middle", "end", "left", "right"]); 25051 break; 25052 } 25053 }, /:/, /\s/); 25054 25055 // Apply default values for any missing fields. 25056 cue.region = settings.get("region", null); 25057 cue.vertical = settings.get("vertical", ""); 25058 cue.line = settings.get("line", "auto"); 25059 cue.lineAlign = settings.get("lineAlign", "start"); 25060 cue.snapToLines = settings.get("snapToLines", true); 25061 cue.size = settings.get("size", 100); 25062 cue.align = settings.get("align", "middle"); 25063 cue.position = settings.get("position", { 25064 start: 0, 25065 left: 0, 25066 middle: 50, 25067 end: 100, 25068 right: 100 25069 }, cue.align); 25070 cue.positionAlign = settings.get("positionAlign", { 25071 start: "start", 25072 left: "start", 25073 middle: "middle", 25074 end: "end", 25075 right: "end" 25076 }, cue.align); 25077 } 25078 25079 function skipWhitespace() { 25080 input = input.replace(/^\s+/, ""); 25081 } 25082 25083 // 4.1 WebVTT cue timings. 25084 skipWhitespace(); 25085 cue.startTime = consumeTimeStamp(); // (1) collect cue start time 25086 skipWhitespace(); 25087 if (input.substr(0, 3) !== "-->") { // (3) next characters must match "-->" 25088 throw new ParsingError(ParsingError.Errors.BadTimeStamp, 25089 "Malformed time stamp (time stamps must be separated by '-->'): " + 25090 oInput); 25091 } 25092 input = input.substr(3); 25093 skipWhitespace(); 25094 cue.endTime = consumeTimeStamp(); // (5) collect cue end time 25095 25096 // 4.1 WebVTT cue settings list. 25097 skipWhitespace(); 25098 consumeCueSettings(input, cue); 25099 } 25100 25101 var ESCAPE = { 25102 "&": "&", 25103 "<": "<", 25104 ">": ">", 25105 "‎": "\u200e", 25106 "‏": "\u200f", 25107 " ": "\u00a0" 25108 }; 25109 25110 var TAG_NAME = { 25111 c: "span", 25112 i: "i", 25113 b: "b", 25114 u: "u", 25115 ruby: "ruby", 25116 rt: "rt", 25117 v: "span", 25118 lang: "span" 25119 }; 25120 25121 var TAG_ANNOTATION = { 25122 v: "title", 25123 lang: "lang" 25124 }; 25125 25126 var NEEDS_PARENT = { 25127 rt: "ruby" 25128 }; 25129 25130 // Parse content into a document fragment. 25131 function parseContent(window, input) { 25132 function nextToken() { 25133 // Check for end-of-string. 25134 if (!input) { 25135 return null; 25136 } 25137 25138 // Consume 'n' characters from the input. 25139 function consume(result) { 25140 input = input.substr(result.length); 25141 return result; 25142 } 25143 25144 var m = input.match(/^([^<]*)(<[^>]+>?)?/); 25145 // If there is some text before the next tag, return it, otherwise return 25146 // the tag. 25147 return consume(m[1] ? m[1] : m[2]); 25148 } 25149 25150 // Unescape a string 's'. 25151 function unescape1(e) { 25152 return ESCAPE[e]; 25153 } 25154 function unescape(s) { 25155 while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) { 25156 s = s.replace(m[0], unescape1); 25157 } 25158 return s; 25159 } 25160 25161 function shouldAdd(current, element) { 25162 return !NEEDS_PARENT[element.localName] || 25163 NEEDS_PARENT[element.localName] === current.localName; 25164 } 25165 25166 // Create an element for this tag. 25167 function createElement(type, annotation) { 25168 var tagName = TAG_NAME[type]; 25169 if (!tagName) { 25170 return null; 25171 } 25172 var element = window.document.createElement(tagName); 25173 element.localName = tagName; 25174 var name = TAG_ANNOTATION[type]; 25175 if (name && annotation) { 25176 element[name] = annotation.trim(); 25177 } 25178 return element; 25179 } 25180 25181 var rootDiv = window.document.createElement("div"), 25182 current = rootDiv, 25183 t, 25184 tagStack = []; 25185 25186 while ((t = nextToken()) !== null) { 25187 if (t[0] === '<') { 25188 if (t[1] === "/") { 25189 // If the closing tag matches, move back up to the parent node. 25190 if (tagStack.length && 25191 tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) { 25192 tagStack.pop(); 25193 current = current.parentNode; 25194 } 25195 // Otherwise just ignore the end tag. 25196 continue; 25197 } 25198 var ts = parseTimeStamp(t.substr(1, t.length - 2)); 25199 var node; 25200 if (ts) { 25201 // Timestamps are lead nodes as well. 25202 node = window.document.createProcessingInstruction("timestamp", ts); 25203 current.appendChild(node); 25204 continue; 25205 } 25206 var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/); 25207 // If we can't parse the tag, skip to the next tag. 25208 if (!m) { 25209 continue; 25210 } 25211 // Try to construct an element, and ignore the tag if we couldn't. 25212 node = createElement(m[1], m[3]); 25213 if (!node) { 25214 continue; 25215 } 25216 // Determine if the tag should be added based on the context of where it 25217 // is placed in the cuetext. 25218 if (!shouldAdd(current, node)) { 25219 continue; 25220 } 25221 // Set the class list (as a list of classes, separated by space). 25222 if (m[2]) { 25223 node.className = m[2].substr(1).replace('.', ' '); 25224 } 25225 // Append the node to the current node, and enter the scope of the new 25226 // node. 25227 tagStack.push(m[1]); 25228 current.appendChild(node); 25229 current = node; 25230 continue; 25231 } 25232 25233 // Text nodes are leaf nodes. 25234 current.appendChild(window.document.createTextNode(unescape(t))); 25235 } 25236 25237 return rootDiv; 25238 } 25239 25240 // This is a list of all the Unicode characters that have a strong 25241 // right-to-left category. What this means is that these characters are 25242 // written right-to-left for sure. It was generated by pulling all the strong 25243 // right-to-left characters out of the Unicode data table. That table can 25244 // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt 25245 var strongRTLRanges = [[0x5be, 0x5be], [0x5c0, 0x5c0], [0x5c3, 0x5c3], [0x5c6, 0x5c6], 25246 [0x5d0, 0x5ea], [0x5f0, 0x5f4], [0x608, 0x608], [0x60b, 0x60b], [0x60d, 0x60d], 25247 [0x61b, 0x61b], [0x61e, 0x64a], [0x66d, 0x66f], [0x671, 0x6d5], [0x6e5, 0x6e6], 25248 [0x6ee, 0x6ef], [0x6fa, 0x70d], [0x70f, 0x710], [0x712, 0x72f], [0x74d, 0x7a5], 25249 [0x7b1, 0x7b1], [0x7c0, 0x7ea], [0x7f4, 0x7f5], [0x7fa, 0x7fa], [0x800, 0x815], 25250 [0x81a, 0x81a], [0x824, 0x824], [0x828, 0x828], [0x830, 0x83e], [0x840, 0x858], 25251 [0x85e, 0x85e], [0x8a0, 0x8a0], [0x8a2, 0x8ac], [0x200f, 0x200f], 25252 [0xfb1d, 0xfb1d], [0xfb1f, 0xfb28], [0xfb2a, 0xfb36], [0xfb38, 0xfb3c], 25253 [0xfb3e, 0xfb3e], [0xfb40, 0xfb41], [0xfb43, 0xfb44], [0xfb46, 0xfbc1], 25254 [0xfbd3, 0xfd3d], [0xfd50, 0xfd8f], [0xfd92, 0xfdc7], [0xfdf0, 0xfdfc], 25255 [0xfe70, 0xfe74], [0xfe76, 0xfefc], [0x10800, 0x10805], [0x10808, 0x10808], 25256 [0x1080a, 0x10835], [0x10837, 0x10838], [0x1083c, 0x1083c], [0x1083f, 0x10855], 25257 [0x10857, 0x1085f], [0x10900, 0x1091b], [0x10920, 0x10939], [0x1093f, 0x1093f], 25258 [0x10980, 0x109b7], [0x109be, 0x109bf], [0x10a00, 0x10a00], [0x10a10, 0x10a13], 25259 [0x10a15, 0x10a17], [0x10a19, 0x10a33], [0x10a40, 0x10a47], [0x10a50, 0x10a58], 25260 [0x10a60, 0x10a7f], [0x10b00, 0x10b35], [0x10b40, 0x10b55], [0x10b58, 0x10b72], 25261 [0x10b78, 0x10b7f], [0x10c00, 0x10c48], [0x1ee00, 0x1ee03], [0x1ee05, 0x1ee1f], 25262 [0x1ee21, 0x1ee22], [0x1ee24, 0x1ee24], [0x1ee27, 0x1ee27], [0x1ee29, 0x1ee32], 25263 [0x1ee34, 0x1ee37], [0x1ee39, 0x1ee39], [0x1ee3b, 0x1ee3b], [0x1ee42, 0x1ee42], 25264 [0x1ee47, 0x1ee47], [0x1ee49, 0x1ee49], [0x1ee4b, 0x1ee4b], [0x1ee4d, 0x1ee4f], 25265 [0x1ee51, 0x1ee52], [0x1ee54, 0x1ee54], [0x1ee57, 0x1ee57], [0x1ee59, 0x1ee59], 25266 [0x1ee5b, 0x1ee5b], [0x1ee5d, 0x1ee5d], [0x1ee5f, 0x1ee5f], [0x1ee61, 0x1ee62], 25267 [0x1ee64, 0x1ee64], [0x1ee67, 0x1ee6a], [0x1ee6c, 0x1ee72], [0x1ee74, 0x1ee77], 25268 [0x1ee79, 0x1ee7c], [0x1ee7e, 0x1ee7e], [0x1ee80, 0x1ee89], [0x1ee8b, 0x1ee9b], 25269 [0x1eea1, 0x1eea3], [0x1eea5, 0x1eea9], [0x1eeab, 0x1eebb], [0x10fffd, 0x10fffd]]; 25270 25271 function isStrongRTLChar(charCode) { 25272 for (var i = 0; i < strongRTLRanges.length; i++) { 25273 var currentRange = strongRTLRanges[i]; 25274 if (charCode >= currentRange[0] && charCode <= currentRange[1]) { 25275 return true; 25276 } 25277 } 25278 25279 return false; 25280 } 25281 25282 function determineBidi(cueDiv) { 25283 var nodeStack = [], 25284 text = "", 25285 charCode; 25286 25287 if (!cueDiv || !cueDiv.childNodes) { 25288 return "ltr"; 25289 } 25290 25291 function pushNodes(nodeStack, node) { 25292 for (var i = node.childNodes.length - 1; i >= 0; i--) { 25293 nodeStack.push(node.childNodes[i]); 25294 } 25295 } 25296 25297 function nextTextNode(nodeStack) { 25298 if (!nodeStack || !nodeStack.length) { 25299 return null; 25300 } 25301 25302 var node = nodeStack.pop(), 25303 text = node.textContent || node.innerText; 25304 if (text) { 25305 // TODO: This should match all unicode type B characters (paragraph 25306 // separator characters). See issue #115. 25307 var m = text.match(/^.*(\n|\r)/); 25308 if (m) { 25309 nodeStack.length = 0; 25310 return m[0]; 25311 } 25312 return text; 25313 } 25314 if (node.tagName === "ruby") { 25315 return nextTextNode(nodeStack); 25316 } 25317 if (node.childNodes) { 25318 pushNodes(nodeStack, node); 25319 return nextTextNode(nodeStack); 25320 } 25321 } 25322 25323 pushNodes(nodeStack, cueDiv); 25324 while ((text = nextTextNode(nodeStack))) { 25325 for (var i = 0; i < text.length; i++) { 25326 charCode = text.charCodeAt(i); 25327 if (isStrongRTLChar(charCode)) { 25328 return "rtl"; 25329 } 25330 } 25331 } 25332 return "ltr"; 25333 } 25334 25335 function computeLinePos(cue) { 25336 if (typeof cue.line === "number" && 25337 (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) { 25338 return cue.line; 25339 } 25340 if (!cue.track || !cue.track.textTrackList || 25341 !cue.track.textTrackList.mediaElement) { 25342 return -1; 25343 } 25344 var track = cue.track, 25345 trackList = track.textTrackList, 25346 count = 0; 25347 for (var i = 0; i < trackList.length && trackList[i] !== track; i++) { 25348 if (trackList[i].mode === "showing") { 25349 count++; 25350 } 25351 } 25352 return ++count * -1; 25353 } 25354 25355 function StyleBox() { 25356 } 25357 25358 // Apply styles to a div. If there is no div passed then it defaults to the 25359 // div on 'this'. 25360 StyleBox.prototype.applyStyles = function(styles, div) { 25361 div = div || this.div; 25362 for (var prop in styles) { 25363 if (styles.hasOwnProperty(prop)) { 25364 div.style[prop] = styles[prop]; 25365 } 25366 } 25367 }; 25368 25369 StyleBox.prototype.formatStyle = function(val, unit) { 25370 return val === 0 ? 0 : val + unit; 25371 }; 25372 25373 // Constructs the computed display state of the cue (a div). Places the div 25374 // into the overlay which should be a block level element (usually a div). 25375 function CueStyleBox(window, cue, styleOptions) { 25376 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); 25377 var color = "rgba(255, 255, 255, 1)"; 25378 var backgroundColor = "rgba(0, 0, 0, 0.8)"; 25379 25380 if (isIE8) { 25381 color = "rgb(255, 255, 255)"; 25382 backgroundColor = "rgb(0, 0, 0)"; 25383 } 25384
vendor: 6,200 bytes, lines 25385-25561
25385 StyleBox.call(this); 25386 this.cue = cue; 25387 25388 // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will 25389 // have inline positioning and will function as the cue background box. 25390 this.cueDiv = parseContent(window, cue.text); 25391 var styles = { 25392 color: color, 25393 backgroundColor: backgroundColor, 25394 position: "relative", 25395 left: 0, 25396 right: 0, 25397 top: 0, 25398 bottom: 0, 25399 display: "inline" 25400 }; 25401 25402 if (!isIE8) { 25403 styles.writingMode = cue.vertical === "" ? "horizontal-tb" 25404 : cue.vertical === "lr" ? "vertical-lr" 25405 : "vertical-rl"; 25406 styles.unicodeBidi = "plaintext"; 25407 } 25408 this.applyStyles(styles, this.cueDiv); 25409 25410 // Create an absolutely positioned div that will be used to position the cue 25411 // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS 25412 // mirrors of them except "middle" which is "center" in CSS. 25413 this.div = window.document.createElement("div"); 25414 styles = { 25415 textAlign: cue.align === "middle" ? "center" : cue.align, 25416 font: styleOptions.font, 25417 whiteSpace: "pre-line", 25418 position: "absolute" 25419 }; 25420 25421 if (!isIE8) { 25422 styles.direction = determineBidi(this.cueDiv); 25423 styles.writingMode = cue.vertical === "" ? "horizontal-tb" 25424 : cue.vertical === "lr" ? "vertical-lr" 25425 : "vertical-rl". 25426 stylesunicodeBidi = "plaintext"; 25427 } 25428 25429 this.applyStyles(styles); 25430 25431 this.div.appendChild(this.cueDiv); 25432 25433 // Calculate the distance from the reference edge of the viewport to the text 25434 // position of the cue box. The reference edge will be resolved later when 25435 // the box orientation styles are applied. 25436 var textPos = 0; 25437 switch (cue.positionAlign) { 25438 case "start": 25439 textPos = cue.position; 25440 break; 25441 case "middle": 25442 textPos = cue.position - (cue.size / 2); 25443 break; 25444 case "end": 25445 textPos = cue.position - cue.size; 25446 break; 25447 } 25448 25449 // Horizontal box orientation; textPos is the distance from the left edge of the 25450 // area to the left edge of the box and cue.size is the distance extending to 25451 // the right from there. 25452 if (cue.vertical === "") { 25453 this.applyStyles({ 25454 left: this.formatStyle(textPos, "%"), 25455 width: this.formatStyle(cue.size, "%") 25456 }); 25457 // Vertical box orientation; textPos is the distance from the top edge of the 25458 // area to the top edge of the box and cue.size is the height extending 25459 // downwards from there. 25460 } else { 25461 this.applyStyles({ 25462 top: this.formatStyle(textPos, "%"), 25463 height: this.formatStyle(cue.size, "%") 25464 }); 25465 } 25466 25467 this.move = function(box) { 25468 this.applyStyles({ 25469 top: this.formatStyle(box.top, "px"), 25470 bottom: this.formatStyle(box.bottom, "px"), 25471 left: this.formatStyle(box.left, "px"), 25472 right: this.formatStyle(box.right, "px"), 25473 height: this.formatStyle(box.height, "px"), 25474 width: this.formatStyle(box.width, "px") 25475 }); 25476 }; 25477 } 25478 CueStyleBox.prototype = _objCreate(StyleBox.prototype); 25479 CueStyleBox.prototype.constructor = CueStyleBox; 25480 25481 // Represents the co-ordinates of an Element in a way that we can easily 25482 // compute things with such as if it overlaps or intersects with another Element. 25483 // Can initialize it with either a StyleBox or another BoxPosition. 25484 function BoxPosition(obj) { 25485 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); 25486 25487 // Either a BoxPosition was passed in and we need to copy it, or a StyleBox 25488 // was passed in and we need to copy the results of 'getBoundingClientRect' 25489 // as the object returned is readonly. All co-ordinate values are in reference 25490 // to the viewport origin (top left). 25491 var lh, height, width, top; 25492 if (obj.div) { 25493 height = obj.div.offsetHeight; 25494 width = obj.div.offsetWidth; 25495 top = obj.div.offsetTop; 25496 25497 var rects = (rects = obj.div.childNodes) && (rects = rects[0]) && 25498 rects.getClientRects && rects.getClientRects(); 25499 obj = obj.div.getBoundingClientRect(); 25500 // In certain cases the outter div will be slightly larger then the sum of 25501 // the inner div's lines. This could be due to bold text, etc, on some platforms. 25502 // In this case we should get the average line height and use that. This will 25503 // result in the desired behaviour. 25504 lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length) 25505 : 0; 25506 25507 } 25508 this.left = obj.left; 25509 this.right = obj.right; 25510 this.top = obj.top || top; 25511 this.height = obj.height || height; 25512 this.bottom = obj.bottom || (top + (obj.height || height)); 25513 this.width = obj.width || width; 25514 this.lineHeight = lh !== undefined ? lh : obj.lineHeight; 25515 25516 if (isIE8 && !this.lineHeight) { 25517 this.lineHeight = 13; 25518 } 25519 } 25520 25521 // Move the box along a particular axis. Optionally pass in an amount to move 25522 // the box. If no amount is passed then the default is the line height of the 25523 // box. 25524 BoxPosition.prototype.move = function(axis, toMove) { 25525 toMove = toMove !== undefined ? toMove : this.lineHeight; 25526 switch (axis) { 25527 case "+x": 25528 this.left += toMove; 25529 this.right += toMove; 25530 break; 25531 case "-x": 25532 this.left -= toMove; 25533 this.right -= toMove; 25534 break; 25535 case "+y": 25536 this.top += toMove; 25537 this.bottom += toMove; 25538 break; 25539 case "-y": 25540 this.top -= toMove; 25541 this.bottom -= toMove; 25542 break; 25543 } 25544 }; 25545 25546 // Check if this box overlaps another box, b2. 25547 BoxPosition.prototype.overlaps = function(b2) { 25548 return this.left < b2.right && 25549 this.right > b2.left && 25550 this.top < b2.bottom && 25551 this.bottom > b2.top; 25552 }; 25553 25554 // Check if this box overlaps any other boxes in boxes. 25555 BoxPosition.prototype.overlapsAny = function(boxes) { 25556 for (var i = 0; i < boxes.length; i++) { 25557 if (this.overlaps(boxes[i])) { 25558 return true; 25559 } 25560 } 25561 return false;
vendor: 9,183 bytes, lines 25562-25824
25562 }; 25563 25564 // Check if this box is within another box. 25565 BoxPosition.prototype.within = function(container) { 25566 return this.top >= container.top && 25567 this.bottom <= container.bottom && 25568 this.left >= container.left && 25569 this.right <= container.right; 25570 }; 25571 25572 // Check if this box is entirely within the container or it is overlapping 25573 // on the edge opposite of the axis direction passed. For example, if "+x" is 25574 // passed and the box is overlapping on the left edge of the container, then 25575 // return true. 25576 BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) { 25577 switch (axis) { 25578 case "+x": 25579 return this.left < container.left; 25580 case "-x": 25581 return this.right > container.right; 25582 case "+y": 25583 return this.top < container.top; 25584 case "-y": 25585 return this.bottom > container.bottom; 25586 } 25587 }; 25588 25589 // Find the percentage of the area that this box is overlapping with another 25590 // box. 25591 BoxPosition.prototype.intersectPercentage = function(b2) { 25592 var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)), 25593 y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)), 25594 intersectArea = x * y; 25595 return intersectArea / (this.height * this.width); 25596 }; 25597 25598 // Convert the positions from this box to CSS compatible positions using 25599 // the reference container's positions. This has to be done because this 25600 // box's positions are in reference to the viewport origin, whereas, CSS 25601 // values are in referecne to their respective edges. 25602 BoxPosition.prototype.toCSSCompatValues = function(reference) { 25603 return { 25604 top: this.top - reference.top, 25605 bottom: reference.bottom - this.bottom, 25606 left: this.left - reference.left, 25607 right: reference.right - this.right, 25608 height: this.height, 25609 width: this.width 25610 }; 25611 }; 25612 25613 // Get an object that represents the box's position without anything extra. 25614 // Can pass a StyleBox, HTMLElement, or another BoxPositon. 25615 BoxPosition.getSimpleBoxPosition = function(obj) { 25616 var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0; 25617 var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0; 25618 var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0; 25619 25620 obj = obj.div ? obj.div.getBoundingClientRect() : 25621 obj.tagName ? obj.getBoundingClientRect() : obj; 25622 var ret = { 25623 left: obj.left, 25624 right: obj.right, 25625 top: obj.top || top, 25626 height: obj.height || height, 25627 bottom: obj.bottom || (top + (obj.height || height)), 25628 width: obj.width || width 25629 }; 25630 return ret; 25631 }; 25632 25633 // Move a StyleBox to its specified, or next best, position. The containerBox 25634 // is the box that contains the StyleBox, such as a div. boxPositions are 25635 // a list of other boxes that the styleBox can't overlap with. 25636 function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) { 25637 25638 // Find the best position for a cue box, b, on the video. The axis parameter 25639 // is a list of axis, the order of which, it will move the box along. For example: 25640 // Passing ["+x", "-x"] will move the box first along the x axis in the positive 25641 // direction. If it doesn't find a good position for it there it will then move 25642 // it along the x axis in the negative direction. 25643 function findBestPosition(b, axis) { 25644 var bestPosition, 25645 specifiedPosition = new BoxPosition(b), 25646 percentage = 1; // Highest possible so the first thing we get is better. 25647 25648 for (var i = 0; i < axis.length; i++) { 25649 while (b.overlapsOppositeAxis(containerBox, axis[i]) || 25650 (b.within(containerBox) && b.overlapsAny(boxPositions))) { 25651 b.move(axis[i]); 25652 } 25653 // We found a spot where we aren't overlapping anything. This is our 25654 // best position. 25655 if (b.within(containerBox)) { 25656 return b; 25657 } 25658 var p = b.intersectPercentage(containerBox); 25659 // If we're outside the container box less then we were on our last try 25660 // then remember this position as the best position. 25661 if (percentage > p) { 25662 bestPosition = new BoxPosition(b); 25663 percentage = p; 25664 } 25665 // Reset the box position to the specified position. 25666 b = new BoxPosition(specifiedPosition); 25667 } 25668 return bestPosition || specifiedPosition; 25669 } 25670 25671 var boxPosition = new BoxPosition(styleBox), 25672 cue = styleBox.cue, 25673 linePos = computeLinePos(cue), 25674 axis = []; 25675 25676 // If we have a line number to align the cue to. 25677 if (cue.snapToLines) { 25678 var size; 25679 switch (cue.vertical) { 25680 case "": 25681 axis = [ "+y", "-y" ]; 25682 size = "height"; 25683 break; 25684 case "rl": 25685 axis = [ "+x", "-x" ]; 25686 size = "width"; 25687 break; 25688 case "lr": 25689 axis = [ "-x", "+x" ]; 25690 size = "width"; 25691 break; 25692 } 25693 25694 var step = boxPosition.lineHeight, 25695 position = step * Math.round(linePos), 25696 maxPosition = containerBox[size] + step, 25697 initialAxis = axis[0]; 25698 25699 // If the specified intial position is greater then the max position then 25700 // clamp the box to the amount of steps it would take for the box to 25701 // reach the max position. 25702 if (Math.abs(position) > maxPosition) { 25703 position = position < 0 ? -1 : 1; 25704 position *= Math.ceil(maxPosition / step) * step; 25705 } 25706 25707 // If computed line position returns negative then line numbers are 25708 // relative to the bottom of the video instead of the top. Therefore, we 25709 // need to increase our initial position by the length or width of the 25710 // video, depending on the writing direction, and reverse our axis directions. 25711 if (linePos < 0) { 25712 position += cue.vertical === "" ? containerBox.height : containerBox.width; 25713 axis = axis.reverse(); 25714 } 25715 25716 // Move the box to the specified position. This may not be its best 25717 // position. 25718 boxPosition.move(initialAxis, position); 25719 25720 } else { 25721 // If we have a percentage line value for the cue. 25722 var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100; 25723 25724 switch (cue.lineAlign) { 25725 case "middle": 25726 linePos -= (calculatedPercentage / 2); 25727 break; 25728 case "end": 25729 linePos -= calculatedPercentage; 25730 break; 25731 } 25732 25733 // Apply initial line position to the cue box. 25734 switch (cue.vertical) { 25735 case "": 25736 styleBox.applyStyles({ 25737 top: styleBox.formatStyle(linePos, "%") 25738 }); 25739 break; 25740 case "rl": 25741 styleBox.applyStyles({ 25742 left: styleBox.formatStyle(linePos, "%") 25743 }); 25744 break; 25745 case "lr": 25746 styleBox.applyStyles({ 25747 right: styleBox.formatStyle(linePos, "%") 25748 }); 25749 break; 25750 } 25751 25752 axis = [ "+y", "-x", "+x", "-y" ]; 25753 25754 // Get the box position again after we've applied the specified positioning 25755 // to it. 25756 boxPosition = new BoxPosition(styleBox); 25757 } 25758 25759 var bestPosition = findBestPosition(boxPosition, axis); 25760 styleBox.move(bestPosition.toCSSCompatValues(containerBox)); 25761 } 25762 25763 function WebVTT() { 25764 // Nothing 25765 } 25766 25767 // Helper to allow strings to be decoded instead of the default binary utf8 data. 25768 WebVTT.StringDecoder = function() { 25769 return { 25770 decode: function(data) { 25771 if (!data) { 25772 return ""; 25773 } 25774 if (typeof data !== "string") { 25775 throw new Error("Error - expected string data."); 25776 } 25777 return decodeURIComponent(encodeURIComponent(data)); 25778 } 25779 }; 25780 }; 25781 25782 WebVTT.convertCueToDOMTree = function(window, cuetext) { 25783 if (!window || !cuetext) { 25784 return null; 25785 } 25786 return parseContent(window, cuetext); 25787 }; 25788 25789 var FONT_SIZE_PERCENT = 0.05; 25790 var FONT_STYLE = "sans-serif"; 25791 var CUE_BACKGROUND_PADDING = "1.5%"; 25792 25793 // Runs the processing model over the cues and regions passed to it. 25794 // @param overlay A block level element (usually a div) that the computed cues 25795 // and regions will be placed into. 25796 WebVTT.processCues = function(window, cues, overlay) { 25797 if (!window || !cues || !overlay) { 25798 return null; 25799 } 25800 25801 // Remove all previous children. 25802 while (overlay.firstChild) { 25803 overlay.removeChild(overlay.firstChild); 25804 } 25805 25806 var paddedOverlay = window.document.createElement("div"); 25807 paddedOverlay.style.position = "absolute"; 25808 paddedOverlay.style.left = "0"; 25809 paddedOverlay.style.right = "0"; 25810 paddedOverlay.style.top = "0"; 25811 paddedOverlay.style.bottom = "0"; 25812 paddedOverlay.style.margin = CUE_BACKGROUND_PADDING; 25813 overlay.appendChild(paddedOverlay); 25814 25815 // Determine if we need to compute the display states of the cues. This could 25816 // be the case if a cue's state has been changed since the last computation or 25817 // if it has not been computed yet. 25818 function shouldCompute(cues) { 25819 for (var i = 0; i < cues.length; i++) { 25820 if (cues[i].hasBeenReset || !cues[i].displayState) { 25821 return true; 25822 } 25823 } 25824 return false;
vendor: 6,307 bytes, lines 25825-26027
25825 } 25826 25827 // We don't need to recompute the cues' display states. Just reuse them. 25828 if (!shouldCompute(cues)) { 25829 for (var i = 0; i < cues.length; i++) { 25830 paddedOverlay.appendChild(cues[i].displayState); 25831 } 25832 return; 25833 } 25834 25835 var boxPositions = [], 25836 containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay), 25837 fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100; 25838 var styleOptions = { 25839 font: fontSize + "px " + FONT_STYLE 25840 }; 25841 25842 (function() { 25843 var styleBox, cue; 25844 25845 for (var i = 0; i < cues.length; i++) { 25846 cue = cues[i]; 25847 25848 // Compute the intial position and styles of the cue div. 25849 styleBox = new CueStyleBox(window, cue, styleOptions); 25850 paddedOverlay.appendChild(styleBox.div); 25851 25852 // Move the cue div to it's correct line position. 25853 moveBoxToLinePosition(window, styleBox, containerBox, boxPositions); 25854 25855 // Remember the computed div so that we don't have to recompute it later 25856 // if we don't have too. 25857 cue.displayState = styleBox.div; 25858 25859 boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox)); 25860 } 25861 })(); 25862 }; 25863 25864 WebVTT.Parser = function(window, vttjs, decoder) { 25865 if (!decoder) { 25866 decoder = vttjs; 25867 vttjs = {}; 25868 } 25869 if (!vttjs) { 25870 vttjs = {}; 25871 } 25872 25873 this.window = window; 25874 this.vttjs = vttjs; 25875 this.state = "INITIAL"; 25876 this.buffer = ""; 25877 this.decoder = decoder || new TextDecoder("utf8"); 25878 this.regionList = []; 25879 }; 25880 25881 WebVTT.Parser.prototype = { 25882 // If the error is a ParsingError then report it to the consumer if 25883 // possible. If it's not a ParsingError then throw it like normal. 25884 reportOrThrowError: function(e) { 25885 if (e instanceof ParsingError) { 25886 this.onparsingerror && this.onparsingerror(e); 25887 } else { 25888 throw e; 25889 } 25890 }, 25891 parse: function (data) { 25892 var self = this; 25893 25894 // If there is no data then we won't decode it, but will just try to parse 25895 // whatever is in buffer already. This may occur in circumstances, for 25896 // example when flush() is called. 25897 if (data) { 25898 // Try to decode the data that we received. 25899 self.buffer += self.decoder.decode(data, {stream: true}); 25900 } 25901 25902 function collectNextLine() { 25903 var buffer = self.buffer; 25904 var pos = 0; 25905 while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') { 25906 ++pos; 25907 } 25908 var line = buffer.substr(0, pos); 25909 // Advance the buffer early in case we fail below. 25910 if (buffer[pos] === '\r') { 25911 ++pos; 25912 } 25913 if (buffer[pos] === '\n') { 25914 ++pos; 25915 } 25916 self.buffer = buffer.substr(pos); 25917 return line; 25918 } 25919 25920 // 3.4 WebVTT region and WebVTT region settings syntax 25921 function parseRegion(input) { 25922 var settings = new Settings(); 25923 25924 parseOptions(input, function (k, v) { 25925 switch (k) { 25926 case "id": 25927 settings.set(k, v); 25928 break; 25929 case "width": 25930 settings.percent(k, v); 25931 break; 25932 case "lines": 25933 settings.integer(k, v); 25934 break; 25935 case "regionanchor": 25936 case "viewportanchor": 25937 var xy = v.split(','); 25938 if (xy.length !== 2) { 25939 break; 25940 } 25941 // We have to make sure both x and y parse, so use a temporary 25942 // settings object here. 25943 var anchor = new Settings(); 25944 anchor.percent("x", xy[0]); 25945 anchor.percent("y", xy[1]); 25946 if (!anchor.has("x") || !anchor.has("y")) { 25947 break; 25948 } 25949 settings.set(k + "X", anchor.get("x")); 25950 settings.set(k + "Y", anchor.get("y")); 25951 break; 25952 case "scroll": 25953 settings.alt(k, v, ["up"]); 25954 break; 25955 } 25956 }, /=/, /\s/); 25957 25958 // Create the region, using default values for any values that were not 25959 // specified. 25960 if (settings.has("id")) { 25961 var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)(); 25962 region.width = settings.get("width", 100); 25963 region.lines = settings.get("lines", 3); 25964 region.regionAnchorX = settings.get("regionanchorX", 0); 25965 region.regionAnchorY = settings.get("regionanchorY", 100); 25966 region.viewportAnchorX = settings.get("viewportanchorX", 0); 25967 region.viewportAnchorY = settings.get("viewportanchorY", 100); 25968 region.scroll = settings.get("scroll", ""); 25969 // Register the region. 25970 self.onregion && self.onregion(region); 25971 // Remember the VTTRegion for later in case we parse any VTTCues that 25972 // reference it. 25973 self.regionList.push({ 25974 id: settings.get("id"), 25975 region: region 25976 }); 25977 } 25978 } 25979 25980 // draft-pantos-http-live-streaming-20 25981 // https://tools.ietf.org/html/draft-pantos-http-live-streaming-20#section-3.5 25982 // 3.5 WebVTT 25983 function parseTimestampMap(input) { 25984 var settings = new Settings(); 25985 25986 parseOptions(input, function(k, v) { 25987 switch(k) { 25988 case "MPEGT": 25989 settings.integer(k + 'S', v); 25990 break; 25991 case "LOCA": 25992 settings.set(k + 'L', parseTimeStamp(v)); 25993 break; 25994 } 25995 }, /[^\d]:/, /,/); 25996 25997 self.ontimestampmap && self.ontimestampmap({ 25998 "MPEGTS": settings.get("MPEGTS"), 25999 "LOCAL": settings.get("LOCAL") 26000 }); 26001 } 26002 26003 // 3.2 WebVTT metadata header syntax 26004 function parseHeader(input) { 26005 if (input.match(/X-TIMESTAMP-MAP/)) { 26006 // This line contains HLS X-TIMESTAMP-MAP metadata 26007 parseOptions(input, function(k, v) { 26008 switch(k) { 26009 case "X-TIMESTAMP-MAP": 26010 parseTimestampMap(v); 26011 break; 26012 } 26013 }, /=/); 26014 } else { 26015 parseOptions(input, function (k, v) { 26016 switch (k) { 26017 case "Region": 26018 // 3.3 WebVTT region metadata header syntax 26019 parseRegion(v); 26020 break; 26021 } 26022 }, /:/); 26023 } 26024 26025 } 26026 26027 // 5.1 WebVTT file parsing.
vendor: 4,082 bytes, lines 26028-26149
26028 try { 26029 var line; 26030 if (self.state === "INITIAL") { 26031 // We can't start parsing until we have the first line. 26032 if (!/\r\n|\n/.test(self.buffer)) { 26033 return this; 26034 } 26035 26036 line = collectNextLine(); 26037 26038 var m = line.match(/^WEBVTT([ \t].*)?$/); 26039 if (!m || !m[0]) { 26040 throw new ParsingError(ParsingError.Errors.BadSignature); 26041 } 26042 26043 self.state = "HEADER"; 26044 } 26045 26046 var alreadyCollectedLine = false; 26047 while (self.buffer) { 26048 // We can't parse a line until we have the full line. 26049 if (!/\r\n|\n/.test(self.buffer)) { 26050 return this; 26051 } 26052 26053 if (!alreadyCollectedLine) { 26054 line = collectNextLine(); 26055 } else { 26056 alreadyCollectedLine = false; 26057 } 26058 26059 switch (self.state) { 26060 case "HEADER": 26061 // 13-18 - Allow a header (metadata) under the WEBVTT line. 26062 if (/:/.test(line)) { 26063 parseHeader(line); 26064 } else if (!line) { 26065 // An empty line terminates the header and starts the body (cues). 26066 self.state = "ID"; 26067 } 26068 continue; 26069 case "NOTE": 26070 // Ignore NOTE blocks. 26071 if (!line) { 26072 self.state = "ID"; 26073 } 26074 continue; 26075 case "ID": 26076 // Check for the start of NOTE blocks. 26077 if (/^NOTE($|[ \t])/.test(line)) { 26078 self.state = "NOTE"; 26079 break; 26080 } 26081 // 19-29 - Allow any number of line terminators, then initialize new cue values. 26082 if (!line) { 26083 continue; 26084 } 26085 self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, ""); 26086 self.state = "CUE"; 26087 // 30-39 - Check if self line contains an optional identifier or timing data. 26088 if (line.indexOf("-->") === -1) { 26089 self.cue.id = line; 26090 continue; 26091 } 26092 // Process line as start of a cue. 26093 /*falls through*/ 26094 case "CUE": 26095 // 40 - Collect cue timings and settings. 26096 try { 26097 parseCue(line, self.cue, self.regionList); 26098 } catch (e) { 26099 self.reportOrThrowError(e); 26100 // In case of an error ignore rest of the cue. 26101 self.cue = null; 26102 self.state = "BADCUE"; 26103 continue; 26104 } 26105 self.state = "CUETEXT"; 26106 continue; 26107 case "CUETEXT": 26108 var hasSubstring = line.indexOf("-->") !== -1; 26109 // 34 - If we have an empty line then report the cue. 26110 // 35 - If we have the special substring '-->' then report the cue, 26111 // but do not collect the line as we need to process the current 26112 // one as a new cue. 26113 if (!line || hasSubstring && (alreadyCollectedLine = true)) { 26114 // We are done parsing self cue. 26115 self.oncue && self.oncue(self.cue); 26116 self.cue = null; 26117 self.state = "ID"; 26118 continue; 26119 } 26120 if (self.cue.text) { 26121 self.cue.text += "\n"; 26122 } 26123 self.cue.text += line; 26124 continue; 26125 case "BADCUE": // BADCUE 26126 // 54-62 - Collect and discard the remaining cue. 26127 if (!line) { 26128 self.state = "ID"; 26129 } 26130 continue; 26131 } 26132 } 26133 } catch (e) { 26134 self.reportOrThrowError(e); 26135 26136 // If we are currently parsing a cue, report what we have. 26137 if (self.state === "CUETEXT" && self.cue && self.oncue) { 26138 self.oncue(self.cue); 26139 } 26140 self.cue = null; 26141 // Enter BADWEBVTT state if header was not parsed correctly otherwise 26142 // another exception occurred so enter BADCUE state. 26143 self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE"; 26144 } 26145 return this; 26146 }, 26147 flush: function () { 26148 var self = this; 26149 try {
26150 // Finish decoding the stream. 26151 self.buffer += self.decoder.decode(); 26152 // Synthesize the end of the current cue or region. 26153 if (self.cue || self.state === "HEADER") { 26154 self.buffer += "\n\n"; 26155 self.parse(); 26156 } 26157 // If we've flushed, parsed, and we're still on the INITIAL state then 26158 // that means we don't have enough of the stream to parse the first 26159 // line. 26160 if (self.state === "INITIAL") { 26161 throw new ParsingError(ParsingError.Errors.BadSignature); 26162 } 26163 } catch(e) { 26164 self.reportOrThrowError(e); 26165 } 26166 self.onflush && self.onflush(); 26167 return this; 26168 } 26169 }; 26170 26171 global.WebVTT = WebVTT; 26172 26173}(this, (this.vttjs || {}))); 26174 26175},{}],107:[function(_dereq_,module,exports){ 26176/** 26177 * Copyright 2013 vtt.js Contributors 26178 * 26179 * Licensed under the Apache License, Version 2.0 (the "License"); 26180 * you may not use this file except in compliance with the License. 26181 * You may obtain a copy of the License at 26182 * 26183 * http://www.apache.org/licenses/LICENSE-2.0 26184 * 26185 * Unless required by applicable law or agreed to in writing, software 26186 * distributed under the License is distributed on an "AS IS" BASIS, 26187 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26188 * See the License for the specific language governing permissions and 26189 * limitations under the License. 26190 */ 26191 26192(function(root, vttjs) { 26193 26194 var autoKeyword = "auto"; 26195 var directionSetting = { 26196 "": true, 26197 "lr": true, 26198 "rl": true 26199 }; 26200 var alignSetting = { 26201 "start": true, 26202 "middle": true, 26203 "end": true, 26204 "left": true, 26205 "right": true 26206 }; 26207 26208 function findDirectionSetting(value) { 26209 if (typeof value !== "string") { 26210 return false; 26211 } 26212 var dir = directionSetting[value.toLowerCase()]; 26213 return dir ? value.toLowerCase() : false; 26214 } 26215 26216 function findAlignSetting(value) { 26217 if (typeof value !== "string") { 26218 return false; 26219 } 26220 var align = alignSetting[value.toLowerCase()]; 26221 return align ? value.toLowerCase() : false; 26222 } 26223 26224 function extend(obj) { 26225 var i = 1; 26226 for (; i < arguments.length; i++) { 26227 var cobj = arguments[i]; 26228 for (var p in cobj) { 26229 obj[p] = cobj[p]; 26230 } 26231 } 26232 26233 return obj; 26234 } 26235 26236 function VTTCue(startTime, endTime, text) { 26237 var cue = this; 26238 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); 26239 var baseObj = {}; 26240 26241 if (isIE8) { 26242 cue = document.createElement('custom'); 26243 } else { 26244 baseObj.enumerable = true; 26245 } 26246 26247 /** 26248 * Shim implementation specific properties. These properties are not in 26249 * the spec. 26250 */ 26251 26252 // Lets us know when the VTTCue's data has changed in such a way that we need 26253 // to recompute its display state. This lets us compute its display state 26254 // lazily. 26255 cue.hasBeenReset = false; 26256 26257 /** 26258 * VTTCue and TextTrackCue properties 26259 * http://dev.w3.org/html5/webvtt/#vttcue-interface 26260 */ 26261 26262 var _id = ""; 26263 var _pauseOnExit = false; 26264 var _startTime = startTime; 26265 var _endTime = endTime; 26266 var _text = text; 26267 var _region = null; 26268 var _vertical = ""; 26269 var _snapToLines = true; 26270 var _line = "auto"; 26271 var _lineAlign = "start"; 26272 var _position = 50; 26273 var _positionAlign = "middle"; 26274 var _size = 50; 26275 var _align = "middle"; 26276 26277 Object.defineProperty(cue, 26278 "id", extend({}, baseObj, { 26279 get: function() { 26280 return _id; 26281 }, 26282 set: function(value) { 26283 _id = "" + value; 26284 } 26285 })); 26286 26287 Object.defineProperty(cue, 26288 "pauseOnExit", extend({}, baseObj, { 26289 get: function() { 26290 return _pauseOnExit; 26291 }, 26292 set: function(value) { 26293 _pauseOnExit = !!value; 26294 } 26295 })); 26296 26297 Object.defineProperty(cue, 26298 "startTime", extend({}, baseObj, { 26299 get: function() { 26300 return _startTime; 26301 }, 26302 set: function(value) { 26303 if (typeof value !== "number") { 26304 throw new TypeError("Start time must be set to a number."); 26305 } 26306 _startTime = value; 26307 this.hasBeenReset = true; 26308 } 26309 })); 26310 26311 Object.defineProperty(cue, 26312 "endTime", extend({}, baseObj, { 26313 get: function() { 26314 return _endTime; 26315 }, 26316 set: function(value) {
26317 if (typeof value !== "number") { 26318 throw new TypeError("End time must be set to a number."); 26319 } 26320 _endTime = value; 26321 this.hasBeenReset = true; 26322 } 26323 })); 26324 26325 Object.defineProperty(cue, 26326 "text", extend({}, baseObj, { 26327 get: function() { 26328 return _text; 26329 }, 26330 set: function(value) { 26331 _text = "" + value; 26332 this.hasBeenReset = true; 26333 } 26334 })); 26335 26336 Object.defineProperty(cue, 26337 "region", extend({}, baseObj, { 26338 get: function() { 26339 return _region; 26340 }, 26341 set: function(value) { 26342 _region = value; 26343 this.hasBeenReset = true; 26344 } 26345 })); 26346 26347 Object.defineProperty(cue, 26348 "vertical", extend({}, baseObj, { 26349 get: function() { 26350 return _vertical; 26351 }, 26352 set: function(value) { 26353 var setting = findDirectionSetting(value); 26354 // Have to check for false because the setting an be an empty string. 26355 if (setting === false) { 26356 throw new SyntaxError("An invalid or illegal string was specified."); 26357 } 26358 _vertical = setting; 26359 this.hasBeenReset = true; 26360 } 26361 })); 26362 26363 Object.defineProperty(cue, 26364 "snapToLines", extend({}, baseObj, { 26365 get: function() { 26366 return _snapToLines; 26367 }, 26368 set: function(value) { 26369 _snapToLines = !!value; 26370 this.hasBeenReset = true; 26371 } 26372 })); 26373 26374 Object.defineProperty(cue, 26375 "line", extend({}, baseObj, { 26376 get: function() { 26377 return _line; 26378 }, 26379 set: function(value) { 26380 if (typeof value !== "number" && value !== autoKeyword) { 26381 throw new SyntaxError("An invalid number or illegal string was specified."); 26382 } 26383 _line = value; 26384 this.hasBeenReset = true; 26385 } 26386 })); 26387 26388 Object.defineProperty(cue, 26389 "lineAlign", extend({}, baseObj, { 26390 get: function() { 26391 return _lineAlign; 26392 }, 26393 set: function(value) { 26394 var setting = findAlignSetting(value); 26395 if (!setting) { 26396 throw new SyntaxError("An invalid or illegal string was specified."); 26397 } 26398 _lineAlign = setting; 26399 this.hasBeenReset = true; 26400 } 26401 })); 26402 26403 Object.defineProperty(cue, 26404 "position", extend({}, baseObj, { 26405 get: function() { 26406 return _position; 26407 }, 26408 set: function(value) { 26409 if (value < 0 || value > 100) { 26410 throw new Error("Position must be between 0 and 100."); 26411 } 26412 _position = value; 26413 this.hasBeenReset = true; 26414 } 26415 })); 26416 26417 Object.defineProperty(cue, 26418 "positionAlign", extend({}, baseObj, { 26419 get: function() { 26420 return _positionAlign; 26421 }, 26422 set: function(value) { 26423 var setting = findAlignSetting(value); 26424 if (!setting) { 26425 throw new SyntaxError("An invalid or illegal string was specified."); 26426 } 26427 _positionAlign = setting; 26428 this.hasBeenReset = true; 26429 } 26430 })); 26431 26432 Object.defineProperty(cue, 26433 "size", extend({}, baseObj, { 26434 get: function() { 26435 return _size; 26436 }, 26437 set: function(value) { 26438 if (value < 0 || value > 100) { 26439 throw new Error("Size must be between 0 and 100."); 26440 } 26441 _size = value; 26442 this.hasBeenReset = true; 26443 } 26444 })); 26445 26446 Object.defineProperty(cue, 26447 "align", extend({}, baseObj, { 26448 get: function() { 26449 return _align; 26450 }, 26451 set: function(value) { 26452 var setting = findAlignSetting(value); 26453 if (!setting) { 26454 throw new SyntaxError("An invalid or illegal string was specified."); 26455 } 26456 _align = setting; 26457 this.hasBeenReset = true; 26458 } 26459 })); 26460 26461 /** 26462 * Other <track> spec defined properties 26463 */ 26464 26465 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state 26466 cue.displayState = undefined; 26467 26468 if (isIE8) { 26469 return cue; 26470 } 26471 } 26472 26473 /** 26474 * VTTCue methods 26475 */ 26476 26477 VTTCue.prototype.getCueAsHTML = function() { 26478 // Assume WebVTT.convertCueToDOMTree is on the global. 26479 return WebVTT.convertCueToDOMTree(window, this.text); 26480 }; 26481 26482 root.VTTCue = root.VTTCue || VTTCue; 26483 vttjs.VTTCue = VTTCue; 26484}(this, (this.vttjs || {}))); 26485 26486},{}],108:[function(_dereq_,module,exports){ 26487/** 26488 * Copyright 2013 vtt.js Contributors 26489 * 26490 * Licensed under the Apache License, Version 2.0 (the "License");
26491 * you may not use this file except in compliance with the License. 26492 * You may obtain a copy of the License at 26493 * 26494 * http://www.apache.org/licenses/LICENSE-2.0 26495 * 26496 * Unless required by applicable law or agreed to in writing, software 26497 * distributed under the License is distributed on an "AS IS" BASIS, 26498 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26499 * See the License for the specific language governing permissions and 26500 * limitations under the License. 26501 */ 26502 26503(function(root, vttjs) { 26504 26505 var scrollSetting = { 26506 "": true, 26507 "up": true 26508 }; 26509 26510 function findScrollSetting(value) { 26511 if (typeof value !== "string") { 26512 return false; 26513 } 26514 var scroll = scrollSetting[value.toLowerCase()]; 26515 return scroll ? value.toLowerCase() : false; 26516 } 26517 26518 function isValidPercentValue(value) { 26519 return typeof value === "number" && (value >= 0 && value <= 100); 26520 } 26521 26522 // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface 26523 function VTTRegion() { 26524 var _width = 100; 26525 var _lines = 3; 26526 var _regionAnchorX = 0; 26527 var _regionAnchorY = 100; 26528 var _viewportAnchorX = 0; 26529 var _viewportAnchorY = 100; 26530 var _scroll = ""; 26531 26532 Object.defineProperties(this, { 26533 "width": { 26534 enumerable: true, 26535 get: function() { 26536 return _width; 26537 }, 26538 set: function(value) { 26539 if (!isValidPercentValue(value)) { 26540 throw new Error("Width must be between 0 and 100."); 26541 } 26542 _width = value; 26543 } 26544 }, 26545 "lines": { 26546 enumerable: true, 26547 get: function() { 26548 return _lines; 26549 }, 26550 set: function(value) { 26551 if (typeof value !== "number") { 26552 throw new TypeError("Lines must be set to a number."); 26553 } 26554 _lines = value; 26555 } 26556 }, 26557 "regionAnchorY": { 26558 enumerable: true, 26559 get: function() { 26560 return _regionAnchorY; 26561 }, 26562 set: function(value) { 26563 if (!isValidPercentValue(value)) { 26564 throw new Error("RegionAnchorX must be between 0 and 100."); 26565 } 26566 _regionAnchorY = value; 26567 } 26568 }, 26569 "regionAnchorX": { 26570 enumerable: true, 26571 get: function() { 26572 return _regionAnchorX; 26573 }, 26574 set: function(value) { 26575 if(!isValidPercentValue(value)) { 26576 throw new Error("RegionAnchorY must be between 0 and 100."); 26577 } 26578 _regionAnchorX = value; 26579 } 26580 }, 26581 "viewportAnchorY": { 26582 enumerable: true, 26583 get: function() { 26584 return _viewportAnchorY; 26585 }, 26586 set: function(value) { 26587 if (!isValidPercentValue(value)) { 26588 throw new Error("ViewportAnchorY must be between 0 and 100."); 26589 } 26590 _viewportAnchorY = value; 26591 } 26592 }, 26593 "viewportAnchorX": { 26594 enumerable: true, 26595 get: function() { 26596 return _viewportAnchorX; 26597 }, 26598 set: function(value) { 26599 if (!isValidPercentValue(value)) { 26600 throw new Error("ViewportAnchorX must be between 0 and 100."); 26601 } 26602 _viewportAnchorX = value; 26603 } 26604 }, 26605 "scroll": { 26606 enumerable: true, 26607 get: function() { 26608 return _scroll; 26609 }, 26610 set: function(value) { 26611 var setting = findScrollSetting(value); 26612 // Have to check for false as an empty string is a legal value. 26613 if (setting === false) { 26614 throw new SyntaxError("An invalid or illegal string was specified."); 26615 } 26616 _scroll = setting; 26617 } 26618 } 26619 }); 26620 } 26621 26622 root.VTTRegion = root.VTTRegion || VTTRegion; 26623 vttjs.VTTRegion = VTTRegion; 26624}(this, (this.vttjs || {}))); 26625 26626},{}],109:[function(_dereq_,module,exports){ 26627arguments[4][95][0].apply(exports,arguments) 26628},{"95":95}]},{},[93])(93) 26629}); 26630!function(){!function(a){var b=a&&a.videojs;if(b){b.CDN_VERSION="5.19.2";var c="https:"===a.location.protocol?"https://":"http://";b.options.flash.swf=c+"vjs.zencdn.net/swf/5.3.0/video-js.swf"}}(window),function(a,b,c,d,e,f,g){b&&b.HELP_IMPROVE_VIDEOJS!==!1&&(e.random()>.01||(f=b.location,g=b.videojs||{},a.src="//www.google-analytics.com/__utm.gif?utmwv=5.4.2&utmac=UA-16505296-3&utmn=1&utmhn="+d(f.hostname)+"&utmsr="+b.screen.availWi
26630dth+"x"+b.screen.availHeight+"&utmul="+(c.language||c.userLanguage||"").toLowerCase()+"&utmr="+d(f.href)+"&utmp="+d(f.hostname+f.pathname)+"&utmcc=__utma%3D1."+e.floor(1e10*e.random())+".1.1.1.1%3B&utme=8(vjsv*cdnv)9("+g.VERSION+"*"+g.CDN_VERSION+")"))}(new Image,window,navigator,encodeURIComponent,Math)}();
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.