1/** 2 * @license 3 * Video.js 5.17.0 <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 79 return BigPlayButton; 80}(_button2['default']); 81 82/** 83 * The text that should display over the `BigPlayButton`s controls. Added to for localization. 84 * 85 * @type {string} 86 * @private 87 */ 88 89 90BigPlayButton.prototype.controlText_ = 'Watch Video'; 91 92_component2['default'].registerComponent('BigPlayButton', BigPlayButton); 93exports['default'] = BigPlayButton; 94 95},{"2":2,"5":5}],2:[function(_dereq_,module,exports){ 96'use strict'; 97 98exports.__esModule = true; 99 100var _clickableComponent = _dereq_(3); 101 102var _clickableComponent2 = _interopRequireDefault(_clickableComponent); 103 104var _component = _dereq_(5); 105 106var _component2 = _interopRequireDefault(_component); 107 108var _log = _dereq_(86); 109 110var _log2 = _interopRequireDefault(_log); 111 112var _obj = _dereq_(88); 113 114function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 115 116function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 117 118function _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; } 119 120function _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; } /** 121 * @file button.js 122 */ 123 124 125/** 126 * Base class for all buttons. 127 * 128 * @extends ClickableComponent 129 */ 130var Button = function (_ClickableComponent) { 131 _inherits(Button, _ClickableComponent); 132 133 function Button() { 134 _classCallCheck(this, Button); 135 136 return _possibleConstructorReturn(this, _ClickableComponent.apply(this, arguments)); 137 } 138 139 /** 140 * Create the `Button`s DOM element. 141 * 142 * @param {string} [tag=button] 143 * Element's node type. e.g. 'button' 144 * 145 * @param {Object} [props={}] 146 * An object of properties that should be set on the element. 147 * 148 * @param {Object} [attributes={}] 149 * An object of attributes that should be set on the element. 150 * 151 * @return {Element} 152 * The element that gets created. 153 */ 154 Button.prototype.createEl = function createEl() { 155 var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'button'; 156 var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 157 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 158 159 props = (0, _obj.assign)({ 160 className: this.buildCSSClass() 161 }, props); 162 163 if (tag !== 'button') { 164 _log2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.'); 165 166 // Add properties for clickable element which is not a native HTML button 167 props = (0, _obj.assign)({ 168 tabIndex: 0 169 }, props); 170 171 // Add ARIA attributes for clickable element which is not a native HTML button 172 attributes = (0, _obj.assign)({ 173 role: 'button' 174 }, attributes); 175 } 176 177 // Add attributes for button element 178 attributes = (0, _obj.assign)({ 179 180 // Necessary since the default button type is "submit" 181 'type': 'button', 182 183 // let the screen reader user know that the text of the button may change 184 'aria-live': 'polite' 185 }, attributes); 186 187 var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes); 188 189 this.createControlTextEl(el); 190 191 return el; 192 }; 193 194 /** 195 * Add a child `Component` inside of this `Button`. 196 * 197 * @param {string|Component} child 198 * The name or instance of a child to add. 199 * 200 * @param {Object} [options={}] 201 * The key/value store of options that will get passed to children of 202 * the child. 203 * 204 * @return {Component} 205 * The `Component` that gets added as a child. When using a string the 206 * `Component` will get created by this process. 207 * 208 * @deprecated since version 5 209 */ 210 211 212 Button.prototype.addChild = function addChild(child) { 213 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 214 215 var className = this.constructor.name; 216 217 _log2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.'); 218 219 // Avoid the error message generated by ClickableComponent's addChild method 220 return _component2['default'].prototype.addChild.call(this, child, options); 221 }; 222 223 /** 224 * Enable the `Button` element so that it can be activated or clicked. Use this with 225 * {@link Button#disable}. 226 */ 227 228 229 Button.prototype.enable = function enable() { 230 _ClickableComponent.prototype.enable.call(this); 231 this.el_.removeAttribute('disabled'); 232 }; 233 234 /** 235 * Enable the `Button` element so that it cannot be activated or clicked. Use this with 236 * {@link Button#enable}. 237 */ 238 239 240 Button.prototype.disable = function disable() { 241 _ClickableComponent.prototype.disable.call(this); 242 this.el_.setAttribute('disabled', 'disabled'); 243 }; 244 245 /** 246 * This gets called when a `Button` has focus and `keydown` is triggered via a key 247 * press. 248 * 249 * @param {EventTarget~Event} event 250 * The event that caused this function to get called. 251 * 252 * @listens keydown 253 */ 254 255 256 Button.prototype.handleKeyPress = function handleKeyPress(event) { 257 258 // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button. 259 if (event.which === 32 || event.which === 13) { 260 return; 261 } 262 263 // Pass keypress handling up for unsupported keys 264 _ClickableComponent.prototype.handleKeyPress.call(this, event); 265 }; 266 267 return Button; 268}(_clickableComponent2['default']); 269 270_component2['default'].registerComponent('Button', Button); 271exports['default'] = Button; 272 273},{"3":3,"5":5,"86":86,"88":88}],3:[function(_dereq_,module,exports){ 274'use strict'; 275 276exports.__esModule = true; 277 278var _component = _dereq_(5); 279 280var _component2 = _interopRequireDefault(_component); 281 282var _dom = _dereq_(81); 283 284var Dom = _interopRequireWildcard(_dom); 285 286var _events = _dereq_(82); 287 288var Events = _interopRequireWildcard(_events); 289 290var _fn = _dereq_(83); 291 292var Fn = _interopRequireWildcard(_fn); 293 294var _log = _dereq_(86); 295 296var _log2 = _interopRequireDefault(_log); 297 298var _document = _dereq_(94); 299 300var _document2 = _interopRequireDefault(_document); 301 302var _obj = _dereq_(88); 303 304function _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; } } 305 306function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 307 308function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 309 310function _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; } 311 312function _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
312onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 313 * @file button.js 314 */ 315 316 317/** 318 * Clickable Component which is clickable or keyboard actionable, 319 * but is not a native HTML button. 320 * 321 * @extends Component 322 */ 323var ClickableComponent = function (_Component) { 324 _inherits(ClickableComponent, _Component); 325 326 /** 327 * Creates an instance of this class. 328 * 329 * @param {Player} player 330 * The `Player` that this class should be attached to. 331 * 332 * @param {Object} [options] 333 * The key/value store of player options. 334 */ 335 function ClickableComponent(player, options) { 336 _classCallCheck(this, ClickableComponent); 337 338 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 339 340 _this.emitTapEvents(); 341 342 _this.enable(); 343 return _this; 344 } 345 346 /** 347 * Create the `Component`s DOM element. 348 * 349 * @param {string} [tag=div] 350 * The element's node type. 351 * 352 * @param {Object} [props={}] 353 * An object of properties that should be set on the element. 354 * 355 * @param {Object} [attributes={}] 356 * An object of attributes that should be set on the element. 357 * 358 * @return {Element} 359 * The element that gets created. 360 */ 361 362 363 ClickableComponent.prototype.createEl = function createEl() { 364 var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div'; 365 var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 366 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 367 368 props = (0, _obj.assign)({ 369 className: this.buildCSSClass(), 370 tabIndex: 0 371 }, props); 372 373 if (tag === 'button') { 374 _log2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.'); 375 } 376 377 // Add ARIA attributes for clickable element which is not a native HTML button 378 attributes = (0, _obj.assign)({ 379 'role': 'button', 380 381 // let the screen reader user know that the text of the element may change 382 'aria-live': 'polite' 383 }, attributes); 384 385 this.tabIndex_ = props.tabIndex; 386 387 var el = _Component.prototype.createEl.call(this, tag, props, attributes); 388 389 this.createControlTextEl(el); 390 391 return el; 392 }; 393 394 /** 395 * Create a control text element on this `Component` 396 * 397 * @param {Element} [el] 398 * Parent element for the control text. 399 * 400 * @return {Element} 401 * The control text element that gets created. 402 */ 403 404 405 ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) { 406 this.controlTextEl_ = Dom.createEl('span', { 407 className: 'vjs-control-text' 408 }); 409 410 if (el) { 411 el.appendChild(this.controlTextEl_); 412 } 413 414 this.controlText(this.controlText_, el); 415 416 return this.controlTextEl_; 417 }; 418 419 /** 420 * Get or set the localize text to use for the controls on the `Component`. 421 * 422 * @param {string} [text] 423 * Control text for element. 424 * 425 * @param {Element} [el=this.el()] 426 * Element to set the title on. 427 * 428 * @return {string|ClickableComponent} 429 * - The control text when getting 430 * - Returns itself when setting; method can be chained. 431 */ 432 433 434 ClickableComponent.prototype.controlText = function controlText(text) { 435 var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.el(); 436 437 if (!text) { 438 return this.controlText_ || 'Need Text'; 439 } 440 441 var localizedText = this.localize(text); 442 443 this.controlText_ = text; 444 this.controlTextEl_.innerHTML = localizedText; 445 446 if (!this.nonIconControl) { 447 // Set title attribute if only an icon is shown 448 el.setAttribute('title', localizedText); 449 } 450 451 return this; 452 }; 453 454 /** 455 * Builds the default DOM `className`. 456 * 457 * @return {string} 458 * The DOM `className` for this object. 459 */ 460 461 462 ClickableComponent.prototype.buildCSSClass = function buildCSSClass() { 463 return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this); 464 }; 465 466 /** 467 * Enable this `Component`s element. 468 * 469 * @return {ClickableComponent} 470 * Returns itself; method can be chained. 471 */ 472 473 474 ClickableComponent.prototype.enable = function enable() { 475 this.removeClass('vjs-disabled'); 476 this.el_.setAttribute('aria-disabled', 'false'); 477 if (typeof this.tabIndex_ !== 'undefined') { 478 this.el_.setAttribute('tabIndex', this.tabIndex_); 479 } 480 this.on('tap', this.handleClick); 481 this.on('click', this.handleClick); 482 this.on('focus', this.handleFocus); 483 this.on('blur', this.handleBlur); 484 return this; 485 }; 486 487 /** 488 * Disable this `Component`s element. 489 * 490 * @return {ClickableComponent} 491 * Returns itself; method can be chained. 492 */ 493 494 495 ClickableComponent.prototype.disable = function disable() { 496 this.addClass('vjs-disabled'); 497 this.el_.setAttribute('aria-disabled', 'true'); 498 if (typeof this.tabIndex_ !== 'undefined') { 499 this.el_.removeAttribute('tabIndex'); 500 } 501 this.off('tap', this.handleClick); 502 this.off('click', this.handleClick); 503 this.off('focus', this.handleFocus); 504 this.off('blur', this.handleBlur); 505 return this; 506 }; 507 508 /** 509 * This gets called when a `ClickableComponent` gets: 510 * - Clicked (via the `click` event, listening starts in the constructor) 511 * - Tapped (via the `tap` event, listening starts in the constructor) 512 * - The following things happen in order: 513 * 1. {@link ClickableComponent#handleFocus} is called via a `focus` event on the 514 * `ClickableComponent`. 515 * 2. {@link ClickableComponent#handleFocus} adds a listener for `keydown` on using 516 * {@link ClickableComponent#handleKeyPress}. 517 * 3. `ClickableComponent` has not had a `blur` event (`blur` means that focus was lost). The user presses 518 * the space or enter key. 519 * 4. {@link ClickableComponent#handleKeyPress} calls this function with the `keydown` 520 * event as a parameter. 521 * 522 * @param {EventTarget~Event} event
523 * The `keydown`, `tap`, or `click` event that caused this function to be 524 * called. 525 * 526 * @listens tap 527 * @listens click 528 * @abstract 529 */ 530 531 532 ClickableComponent.prototype.handleClick = function handleClick(event) {}; 533 534 /** 535 * This gets called when a `ClickableComponent` gains focus via a `focus` event. 536 * Turns on listening for `keydown` events. When they happen it 537 * calls `this.handleKeyPress`. 538 * 539 * @param {EventTarget~Event} event 540 * The `focus` event that caused this function to be called. 541 * 542 * @listens focus 543 */ 544 545 546 ClickableComponent.prototype.handleFocus = function handleFocus(event) { 547 Events.on(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); 548 }; 549 550 /** 551 * Called when this ClickableComponent has focus and a key gets pressed down. By 552 * default it will call `this.handleClick` when the key is space or enter. 553 * 554 * @param {EventTarget~Event} event 555 * The `keydown` event that caused this function to be called. 556 * 557 * @listens keydown 558 */ 559 560 561 ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) { 562 563 // Support Space (32) or Enter (13) key operation to fire a click event 564 if (event.which === 32 || event.which === 13) { 565 event.preventDefault(); 566 this.handleClick(event); 567 } else if (_Component.prototype.handleKeyPress) { 568 569 // Pass keypress handling up for unsupported keys 570 _Component.prototype.handleKeyPress.call(this, event); 571 } 572 }; 573 574 /** 575 * Called when a `ClickableComponent` loses focus. Turns off the listener for 576 * `keydown` events. Which Stops `this.handleKeyPress` from getting called. 577 * 578 * @param {EventTarget~Event} event 579 * The `blur` event that caused this function to be called. 580 * 581 * @listens blur 582 */ 583 584 585 ClickableComponent.prototype.handleBlur = function handleBlur(event) { 586 Events.off(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); 587 }; 588 589 return ClickableComponent; 590}(_component2['default']); 591 592_component2['default'].registerComponent('ClickableComponent', ClickableComponent); 593exports['default'] = ClickableComponent; 594 595},{"5":5,"81":81,"82":82,"83":83,"86":86,"88":88,"94":94}],4:[function(_dereq_,module,exports){ 596'use strict'; 597 598exports.__esModule = true; 599 600var _button = _dereq_(2); 601 602var _button2 = _interopRequireDefault(_button); 603 604var _component = _dereq_(5); 605 606var _component2 = _interopRequireDefault(_component); 607 608function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 609 610function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 611 612function _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; } 613 614function _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; } /** 615 * @file close-button.js 616 */ 617 618 619/** 620 * The `CloseButton` is a `{@link Button}` that fires a `close` event when 621 * it gets clicked. 622 * 623 * @extends Button 624 */ 625var CloseButton = function (_Button) { 626 _inherits(CloseButton, _Button); 627 628 /** 629 * Creates an instance of the this class. 630 * 631 * @param {Player} player 632 * The `Player` that this class should be attached to. 633 * 634 * @param {Object} [options] 635 * The key/value store of player options. 636 */ 637 function CloseButton(player, options) { 638 _classCallCheck(this, CloseButton); 639 640 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options)); 641 642 _this.controlText(options && options.controlText || _this.localize('Close')); 643 return _this; 644 } 645 646 /** 647 * Builds the default DOM `className`. 648 * 649 * @return {string} 650 * The DOM `className` for this object. 651 */ 652 653 654 CloseButton.prototype.buildCSSClass = function buildCSSClass() { 655 return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this); 656 }; 657 658 /** 659 * This gets called when a `CloseButton` gets clicked. See 660 * {@link ClickableComponent#handleClick} for more information on when this will be 661 * triggered 662 * 663 * @param {EventTarget~Event} event
664 * The `keydown`, `tap`, or `click` event that caused this function to be 665 * called. 666 * 667 * @listens tap 668 * @listens click 669 * @fires CloseButton#close 670 */ 671 672 673 CloseButton.prototype.handleClick = function handleClick(event) { 674 675 /** 676 * Triggered when the a `CloseButton` is clicked. 677 * 678 * @event CloseButton#close 679 * @type {EventTarget~Event} 680 * 681 * @property {boolean} [bubbles=false] 682 * set to false so that the close event does not 683 * bubble up to parents if there is no listener 684 */ 685 this.trigger({ type: 'close', bubbles: false }); 686 }; 687 688 return CloseButton; 689}(_button2['default']); 690 691_component2['default'].registerComponent('CloseButton', CloseButton); 692exports['default'] = CloseButton; 693 694},{"2":2,"5":5}],5:[function(_dereq_,module,exports){ 695'use strict'; 696 697exports.__esModule = true; 698 699var _window = _dereq_(95); 700 701var _window2 = _interopRequireDefault(_window); 702 703var _dom = _dereq_(81); 704 705var Dom = _interopRequireWildcard(_dom); 706 707var _fn = _dereq_(83); 708 709var Fn = _interopRequireWildcard(_fn); 710 711var _guid = _dereq_(85); 712 713var Guid = _interopRequireWildcard(_guid); 714 715var _events = _dereq_(82); 716 717var Events = _interopRequireWildcard(_events); 718 719var _log = _dereq_(86); 720 721var _log2 = _interopRequireDefault(_log); 722 723var _toTitleCase = _dereq_(91); 724 725var _toTitleCase2 = _interopRequireDefault(_toTitleCase); 726 727var _mergeOptions = _dereq_(87); 728 729var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 730 731function _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; } } 732 733function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 734 735function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** 736 * Player Component - Base class for all UI objects 737 * 738 * @file component.js 739 */ 740 741 742/** 743 * Base class for all UI Components. 744 * Components are UI objects which represent both a javascript object and an element 745 * in the DOM. They can be children of other components, and can have 746 * children themselves. 747 * 748 * Components can also use methods from {@link EventTarget} 749 */ 750var Component = function () { 751 752 /** 753 * A callback that is called when a component is ready. Does not have any 754 * paramters and any callback value will be ignored. 755 * 756 * @callback Component~ReadyCallback 757 * @this Component 758 */ 759 760 /** 761 * Creates an instance of this class. 762 * 763 * @param {Player} player 764 * The `Player` that this class should be attached to. 765 * 766 * @param {Object} [options] 767 * The key/value store of player options. 768 # 769 * @param {Object[]} [options.children] 770 * An array of children objects to intialize this component with. Children objects have 771 * a name property that will be used if more than one component of the same type needs to be 772 * added. 773 * 774 * @param {Component~ReadyCallback} [ready] 775 * Function that gets called when the `Component` is ready. 776 */ 777 function Component(player, options, ready) { 778 _classCallCheck(this, Component); 779 780 // The component might be the player itself and we can't pass `this` to super 781 if (!player && this.play) { 782 this.player_ = player = this; // eslint-disable-line 783 } else { 784 this.player_ = player; 785 } 786 787 // Make a copy of prototype.options_ to protect against overriding defaults 788 this.options_ = (0, _mergeOptions2['default'])({}, this.options_); 789 790 // Updated options with supplied options 791 options = this.options_ = (0, _mergeOptions2['default'])(this.options_, options); 792 793 // Get ID from options or options element if one is supplied 794 this.id_ = options.id || options.el && options.el.id; 795 796 // If there was no ID from the options, generate one 797 if (!this.id_) { 798 // Don't require the player ID function in the case of mock players 799 var id = player && player.id && player.id() || 'no_player'; 800 801 this.id_ = id + '_component_' + Guid.newGUID(); 802 } 803 804 this.name_ = options.name || null; 805 806 // Create element if one wasn't provided in options 807 if (options.el) { 808 this.el_ = options.el; 809 } else if (options.createEl !== false) { 810 this.el_ = this.createEl(); 811 } 812 813 this.children_ = []; 814 this.childIndex_ = {}; 815 this.childNameIndex_ = {}; 816 817 // Add any child components in options 818 if (options.initChildren !== false) { 819 this.initChildren(); 820 } 821 822 this.ready(ready); 823 // Don't want to trigger ready here or it will before init is actually 824 // finished for all children that run this constructor 825 826 if (options.reportTouchActivity !== false) { 827 this.enableTouchActivity(); 828 } 829 } 830 831 /** 832 * Dispose of the `Component` and all child components. 833 * 834 * @fires Component#dispose 835 */ 836 837 838 Component.prototype.dispose = function dispose() { 839 840 /** 841 * Triggered when a `Component` is disposed. 842 * 843 * @event Component#dispose 844 * @type {EventTarget~Event} 845 * 846 * @property {boolean} [bubbles=false] 847 * set to false so that the close event does not 848 * bubble up 849 */ 850 this.trigger({ type: 'dispose', bubbles: false }); 851 852 // Dispose all children. 853 if (this.children_) { 854 for (var i = this.children_.length - 1; i >= 0; i--) { 855 if (this.children_[i].dispose) { 856 this.children_[i].dispose(); 857 } 858 } 859 } 860 861 // Delete child references 862 this.children_ = null; 863 this.childIndex_ = null; 864 this.childNameIndex_ = null; 865 866 // Remove all event listeners. 867 this.off(); 868 869 // Remove element from DOM 870 if (this.el_.parentNode) { 871 this.el_.parentNode.removeChild(this.el_); 872 } 873 874 Dom.removeElData(this.el_); 875 this.el_ = null; 876 }; 877 878 /** 879 * Return the {@link Player}
879 that the `Component` has attached to. 880 * 881 * @return {Player} 882 * The player that this `Component` has attached to. 883 */ 884 885 886 Component.prototype.player = function player() { 887 return this.player_; 888 }; 889 890 /** 891 * Deep merge of options objects with new options. 892 * > Note: When both `obj` and `options` contain properties whose values are objects. 893 * The two properties get merged using {@link module:mergeOptions} 894 * 895 * @param {Object} obj 896 * The object that contains new options. 897 * 898 * @return {Object} 899 * A new object of `this.options_` and `obj` merged together. 900 * 901 * @deprecated since version 5 902 */ 903 904 905 Component.prototype.options = function options(obj) { 906 _log2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0'); 907 908 if (!obj) { 909 return this.options_; 910 } 911 912 this.options_ = (0, _mergeOptions2['default'])(this.options_, obj); 913 return this.options_; 914 }; 915 916 /** 917 * Get the `Component`s DOM element 918 * 919 * @return {Element} 920 * The DOM element for this `Component`. 921 */ 922 923 924 Component.prototype.el = function el() { 925 return this.el_; 926 }; 927 928 /** 929 * Create the `Component`s DOM element. 930 * 931 * @param {string} [tagName] 932 * Element's DOM node type. e.g. 'div' 933 * 934 * @param {Object} [properties] 935 * An object of properties that should be set. 936 * 937 * @param {Object} [attributes] 938 * An object of attributes that should be set. 939 * 940 * @return {Element} 941 * The element that gets created. 942 */ 943 944 945 Component.prototype.createEl = function createEl(tagName, properties, attributes) { 946 return Dom.createEl(tagName, properties, attributes); 947 }; 948 949 /** 950 * Localize a string given the string in english. 951 * 952 * @param {string} string 953 * The string to localize. 954 * 955 * @return {string} 956 * The localized string or if no localization exists the english string. 957 */ 958 959 960 Component.prototype.localize = function localize(string) { 961 var code = this.player_.language && this.player_.language(); 962 var languages = this.player_.languages && this.player_.languages(); 963 964 if (!code || !languages) { 965 return string; 966 } 967 968 var language = languages[code]; 969 970 if (language && language[string]) { 971 return language[string]; 972 } 973 974 var primaryCode = code.split('-')[0]; 975 var primaryLang = languages[primaryCode]; 976 977 if (primaryLang && primaryLang[string]) { 978 return primaryLang[string]; 979 } 980 981 return string; 982 }; 983 984 /** 985 * Return the `Component`s DOM element. This is where children get inserted. 986 * This will usually be the the same as the element returned in {@link Component#el}. 987 * 988 * @return {Element} 989 * The content element for this `Component`. 990 */ 991 992 993 Component.prototype.contentEl = function contentEl() { 994 return this.contentEl_ || this.el_; 995 }; 996 997 /** 998 * Get this `Component`s ID 999 * 1000 * @return {string} 1001 * The id of this `Component` 1002 */ 1003 1004 1005 Component.prototype.id = function id() { 1006 return this.id_; 1007 }; 1008 1009 /** 1010 * Get the `Component`s name. The name gets used to reference the `Component` 1011 * and is set during registration. 1012 * 1013 * @return {string} 1014 * The name of this `Component`. 1015 */ 1016 1017 1018 Component.prototype.name = function name() { 1019 return this.name_; 1020 }; 1021 1022 /** 1023 * Get an array of all child components 1024 * 1025 * @return {Array} 1026 * The children 1027 */ 1028 1029 1030 Component.prototype.children = function children() { 1031 return this.children_; 1032 }; 1033 1034 /** 1035 * Returns the child `Component` with the given `id`. 1036 * 1037 * @param {string} id 1038 * The id of the child `Component` to get. 1039 * 1040 * @return {Component|undefined} 1041 * The child `Component` with the given `id` or undefined. 1042 */ 1043 1044 1045 Component.prototype.getChildById = function getChildById(id) { 1046 return this.childIndex_[id]; 1047 }; 1048 1049 /** 1050 * Returns the child `Component` with the given `name`. 1051 * 1052 * @param {string} name 1053 * The name of the child `Component` to get. 1054 * 1055 * @return {Component|undefined} 1056 * The child `Component` with the given `name` or undefined. 1057 */ 1058 1059 1060 Component.prototype.getChild = function getChild(name) { 1061 if (!name) { 1062 return; 1063 } 1064 1065 name = (0, _toTitleCase2['default'])(name); 1066 1067 return this.childNameIndex_[name]; 1068 }; 1069 1070 /** 1071 * Add a child `Component` inside the current `Component`. 1072 * 1073 * 1074 * @param {string|Component} child 1075 * The name or instance of a child to add. 1076 * 1077 * @param {Object} [options={}] 1078 * The key/value store of options that will get passed to children of 1079 * the child. 1080 * 1081 * @param {number} [index=this.children_.length] 1082 * The index to attempt to add a child into. 1083 * 1084 * @return {Component} 1085 * The `Component` that gets added as a child. When using a string the 1086 * `Component` will get created by this process. 1087 */ 1088 1089 1090 Component.prototype.addChild = function addChild(child) { 1091 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 1092 var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.children_.length; 1093 1094 var component = void 0; 1095 var componentName = void 0; 1096 1097 // If child is a string, create component with options 1098 if (typeof child === 'string') { 1099 componentName = (0, _toTitleCase2['default'])(child); 1100 1101 // Options can also be specified as a boolean, 1102 // so convert to an empty object if false. 1103 if (!options) { 1104 options = {}; 1105 } 1106 1107 // Same as above, but true is deprecated so show a warning. 1108 if (options === true) { 1109 _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`.'); 1110 options = {}; 1111 } 1112 1113 var componentClassName = options.componentClass || componentName; 1114 1115 // Set name through options 1116 options.name = componentName; 1117 1118 // Create a new object & element for this controls set 1119 // If there's no .player_, this is a player 1120 var ComponentClass = Component.getComponent(componentClassName); 1121 1122 if (!ComponentClass) { 1123 throw new Error('Component ' + componentClassName + ' does not exist'); 1124 } 1125 1126 // data stored directly on the videojs object may be 1127 // misidentified as a component to retain 1128 // backwards-compatibility with 4.x. check to make sure the 1129 // component class can be instantiated. 1130 if (typeof ComponentClass !== 'function') { 1131 return null; 1132 } 1133 1134 component = new ComponentClass(this.player_ || this, options); 1135 1136 // child is a component instance 1137 } else { 1138 component = child; 1139 } 1140 1141 this.children_.splice(index, 0, component); 1142 1143 if (typeof component.id === 'function') { 1144 this.childIndex_[component.id()] = component; 1145 } 1146 1147 // If a name wasn't used to create the component, check if we can use the 1148 // name function of the component 1149 componentName = componentName || component.name && component.name(); 1150 1151 if (componentName) { 1152 this.childNameIndex_[componentName] = component; 1153 } 1154 1155 // Add the UI object's element to the container div (box) 1156 // Having an element is not required 1157 if (typeof component.el === 'function' && component.el()) { 1158 var childNodes = this.contentEl().children;
vendor: 4,507 bytes, lines 1159-1304
1159 var refNode = childNodes[index] || null; 1160 1161 this.contentEl().insertBefore(component.el(), refNode); 1162 } 1163 1164 // Return so it can stored on parent object if desired. 1165 return component; 1166 }; 1167 1168 /** 1169 * Remove a child `Component` from this `Component`s list of children. Also removes 1170 * the child `Component`s element from this `Component`s element. 1171 * 1172 * @param {Component} component 1173 * The child `Component` to remove. 1174 */ 1175 1176 1177 Component.prototype.removeChild = function removeChild(component) { 1178 if (typeof component === 'string') { 1179 component = this.getChild(component); 1180 } 1181 1182 if (!component || !this.children_) { 1183 return; 1184 } 1185 1186 var childFound = false; 1187 1188 for (var i = this.children_.length - 1; i >= 0; i--) { 1189 if (this.children_[i] === component) { 1190 childFound = true; 1191 this.children_.splice(i, 1); 1192 break; 1193 } 1194 } 1195 1196 if (!childFound) { 1197 return; 1198 } 1199 1200 this.childIndex_[component.id()] = null; 1201 this.childNameIndex_[component.name()] = null; 1202 1203 var compEl = component.el(); 1204 1205 if (compEl && compEl.parentNode === this.contentEl()) { 1206 this.contentEl().removeChild(component.el()); 1207 } 1208 }; 1209 1210 /** 1211 * Add and initialize default child `Component`s based upon options. 1212 */ 1213 1214 1215 Component.prototype.initChildren = function initChildren() { 1216 var _this = this; 1217 1218 var children = this.options_.children; 1219 1220 if (children) { 1221 (function () { 1222 // `this` is `parent` 1223 var parentOptions = _this.options_; 1224 1225 var handleAdd = function handleAdd(child) { 1226 var name = child.name; 1227 var opts = child.opts; 1228 1229 // Allow options for children to be set at the parent options 1230 // e.g. videojs(id, { controlBar: false }); 1231 // instead of videojs(id, { children: { controlBar: false }); 1232 if (parentOptions[name] !== undefined) { 1233 opts = parentOptions[name]; 1234 } 1235 1236 // Allow for disabling default components 1237 // e.g. options['children']['posterImage'] = false 1238 if (opts === false) { 1239 return; 1240 } 1241 1242 // Allow options to be passed as a simple boolean if no configuration 1243 // is necessary. 1244 if (opts === true) { 1245 opts = {}; 1246 } 1247 1248 // We also want to pass the original player options 1249 // to each component as well so they don't need to 1250 // reach back into the player for options later. 1251 opts.playerOptions = _this.options_.playerOptions; 1252 1253 // Create and add the child component. 1254 // Add a direct reference to the child by name on the parent instance. 1255 // If two of the same component are used, different names should be supplied 1256 // for each 1257 var newChild = _this.addChild(name, opts); 1258 1259 if (newChild) { 1260 _this[name] = newChild; 1261 } 1262 }; 1263 1264 // Allow for an array of children details to passed in the options 1265 var workingChildren = void 0; 1266 var Tech = Component.getComponent('Tech'); 1267 1268 if (Array.isArray(children)) { 1269 workingChildren = children; 1270 } else { 1271 workingChildren = Object.keys(children); 1272 } 1273 1274 workingChildren 1275 // children that are in this.options_ but also in workingChildren would 1276 // give us extra children we do not want. So, we want to filter them out. 1277 .concat(Object.keys(_this.options_).filter(function (child) { 1278 return !workingChildren.some(function (wchild) { 1279 if (typeof wchild === 'string') { 1280 return child === wchild; 1281 } 1282 return child === wchild.name; 1283 }); 1284 })).map(function (child) { 1285 var name = void 0; 1286 var opts = void 0; 1287 1288 if (typeof child === 'string') { 1289 name = child; 1290 opts = children[name] || _this.options_[name] || {}; 1291 } else { 1292 name = child.name; 1293 opts = child; 1294 } 1295 1296 return { name: name, opts: opts }; 1297 }).filter(function (child) { 1298 // we have to make sure that child.name isn't in the techOrder since 1299 // techs are registerd as Components but can't aren't compatible 1300 // See https://github.com/videojs/video.js/issues/2772 1301 var c = Component.getComponent(child.opts.componentClass || (0, _toTitleCase2['default'])(child.name)); 1302 1303 return c && !Tech.isTech(c); 1304 }
1304).forEach(handleAdd); 1305 })(); 1306 } 1307 }; 1308 1309 /** 1310 * Builds the default DOM class name. Should be overriden by sub-components. 1311 * 1312 * @return {string} 1313 * The DOM class name for this object. 1314 * 1315 * @abstract 1316 */ 1317 1318 1319 Component.prototype.buildCSSClass = function buildCSSClass() { 1320 // Child classes can include a function that does: 1321 // return 'CLASS NAME' + this._super(); 1322 return ''; 1323 }; 1324 1325 /** 1326 * Add an `event listener` to this `Component`s element. 1327 * 1328 * The benefit of using this over the following: 1329 * - `VjsEvents.on(otherElement, 'eventName', myFunc)` 1330 * - `otherComponent.on('eventName', myFunc)` 1331 * 1332 * 1. Is that the listeners will get cleaned up when either component gets disposed. 1333 * 1. It will also bind `myComponent` as the context of `myFunc`. 1334 * > NOTE: If you remove the element from the DOM that has used `on` you need to 1335 * clean up references using: `myComponent.trigger(el, 'dispose')` 1336 * This will also allow the browser to garbage collect it. In special 1337 * cases such as with `window` and `document`, which are both permanent, 1338 * this is not necessary. 1339 * 1340 * @param {string|Component|string[]} [first] 1341 * The event name, and array of event names, or another `Component`. 1342 * 1343 * @param {EventTarget~EventListener|string|string[]} [second] 1344 * The listener function, an event name, or an Array of events names. 1345 * 1346 * @param {EventTarget~EventListener} [third] 1347 * The event handler if `first` is a `Component` and `second` is an event name 1348 * or an Array of event names. 1349 * 1350 * @return {Component} 1351 * Returns itself; method can be chained. 1352 * 1353 * @listens Component#dispose 1354 */ 1355 1356 1357 Component.prototype.on = function on(first, second, third) { 1358 var _this2 = this; 1359 1360 if (typeof first === 'string' || Array.isArray(first)) { 1361 Events.on(this.el_, first, Fn.bind(this, second)); 1362 1363 // Targeting another component or element 1364 } else { 1365 (function () { 1366 var target = first; 1367 var type = second; 1368 var fn = Fn.bind(_this2, third); 1369 1370 // When this component is disposed, remove the listener from the other component 1371 var removeOnDispose = function removeOnDispose() { 1372 return _this2.off(target, type, fn); 1373 }; 1374 1375 // Use the same function ID so we can remove it later it using the ID 1376 // of the original listener 1377 removeOnDispose.guid = fn.guid; 1378 _this2.on('dispose', removeOnDispose); 1379 1380 // If the other component is disposed first we need to clean the reference 1381 // to the other component in this component's removeOnDispose listener 1382 // Otherwise we create a memory leak. 1383 var cleanRemover = function cleanRemover() { 1384 return _this2.off('dispose', removeOnDispose); 1385 }; 1386 1387 // Add the same function ID so we can easily remove it later 1388 cleanRemover.guid = fn.guid; 1389 1390 // Check if this is a DOM node 1391 if (first.nodeName) { 1392 // Add the listener to the other element 1393 Events.on(target, type, fn); 1394 Events.on(target, 'dispose', cleanRemover); 1395 1396 // Should be a component 1397 // Not using `instanceof Component` because it makes mock players difficult 1398 } else if (typeof first.on === 'function') { 1399 // Add the listener to the other component 1400 target.on(type, fn); 1401 target.on('dispose', cleanRemover); 1402 } 1403 })(); 1404 } 1405 1406 return this; 1407 }; 1408 1409 /** 1410 * Remove an event listener from this `Component`s element. If the second argument is 1411 * exluded all listeners for the type passed in as the first argument will be removed. 1412 * 1413 * @param {string|Component|string[]} [first] 1414 * The event name, and array of event names, or another `Component`. 1415 * 1416 * @param {EventTarget~EventListener|string|string[]} [second] 1417 * The listener function, an event name, or an Array of events names. 1418 * 1419 * @param {EventTarget~EventListener} [third] 1420 * The event handler if `first` is a `Component` and `second` is an event name 1421 * or an Array of event names. 1422 * 1423 * @return {Component} 1424 * Returns itself; method can be chained. 1425 */ 1426 1427 1428 Component.prototype.off = function off(first, second, third) { 1429 if (!first || typeof first === 'string' || Array.isArray(first)) { 1430 Events.off(this.el_, first, second); 1431 } else { 1432 var target = first; 1433 var type = second; 1434 // Ensure there's at least a guid, even if the function hasn't been used 1435 var fn = Fn.bind(this, third); 1436 1437 // Remove the dispose listener on this component, 1438 // which was given the same guid as the event listener 1439 this.off('dispose', fn); 1440 1441 if (first.nodeName) { 1442 // Remove the listener 1443 Events.off(target, type, fn); 1444 // Remove the listener for cleaning the dispose listener 1445 Events.off(target, 'dispose', fn); 1446 } else {
1447 target.off(type, fn); 1448 target.off('dispose', fn); 1449 } 1450 } 1451 1452 return this; 1453 }; 1454 1455 /** 1456 * Add an event listener that gets triggered only once and then gets removed. 1457 * 1458 * @param {string|Component|string[]} [first] 1459 * The event name, and array of event names, or another `Component`. 1460 * 1461 * @param {EventTarget~EventListener|string|string[]} [second] 1462 * The listener function, an event name, or an Array of events names. 1463 * 1464 * @param {EventTarget~EventListener} [third] 1465 * The event handler if `first` is a `Component` and `second` is an event name 1466 * or an Array of event names. 1467 * 1468 * @return {Component} 1469 * Returns itself; method can be chained. 1470 */ 1471 1472 1473 Component.prototype.one = function one(first, second, third) { 1474 var _this3 = this, 1475 _arguments = arguments; 1476 1477 if (typeof first === 'string' || Array.isArray(first)) { 1478 Events.one(this.el_, first, Fn.bind(this, second)); 1479 } else { 1480 (function () { 1481 var target = first; 1482 var type = second; 1483 var fn = Fn.bind(_this3, third); 1484 1485 var newFunc = function newFunc() { 1486 _this3.off(target, type, newFunc); 1487 fn.apply(null, _arguments); 1488 }; 1489 1490 // Keep the same function ID so we can remove it later 1491 newFunc.guid = fn.guid; 1492 1493 _this3.on(target, type, newFunc); 1494 })(); 1495 } 1496 1497 return this; 1498 }; 1499 1500 /** 1501 * Trigger an event on an element. 1502 * 1503 * @param {EventTarget~Event|Object|string} event 1504 * The event name, and Event, or an event-like object with a type attribute 1505 * set to the event name. 1506 * 1507 * @param {Object} [hash] 1508 * Data hash to pass along with the event 1509 * 1510 * @return {Component} 1511 * Returns itself; method can be chained. 1512 */ 1513 1514 1515 Component.prototype.trigger = function trigger(event, hash) { 1516 Events.trigger(this.el_, event, hash); 1517 return this; 1518 }; 1519 1520 /** 1521 * Bind a listener to the component's ready state. If the ready event has already 1522 * happened it will trigger the function immediately. 1523 * 1524 * @param {Component~ReadyCallback} fn 1525 * A function to call when ready is triggered. 1526 * 1527 * @param {boolean} [sync=false] 1528 * Execute the listener synchronously if `Component` is ready. 1529 * 1530 * @return {Component} 1531 * Returns itself; method can be chained. 1532 */ 1533 1534 1535 Component.prototype.ready = function ready(fn) { 1536 var sync = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 1537 1538 if (fn) { 1539 if (this.isReady_) { 1540 if (sync) { 1541 fn.call(this); 1542 } else { 1543 // Call the function asynchronously by default for consistency 1544 this.setTimeout(fn, 1); 1545 } 1546 } else { 1547 this.readyQueue_ = this.readyQueue_ || []; 1548 this.readyQueue_.push(fn); 1549 } 1550 } 1551 return this; 1552 }; 1553 1554 /** 1555 * Trigger all the ready listeners for this `Component`. 1556 * 1557 * @fires Component#ready 1558 */ 1559 1560 1561 Component.prototype.triggerReady = function triggerReady() { 1562 this.isReady_ = true; 1563 1564 // Ensure ready is triggerd asynchronously 1565 this.setTimeout(function () { 1566 var readyQueue = this.readyQueue_; 1567 1568 // Reset Ready Queue 1569 this.readyQueue_ = []; 1570 1571 if (readyQueue && readyQueue.length > 0) { 1572 readyQueue.forEach(function (fn) { 1573 fn.call(this); 1574 }, this); 1575 } 1576 1577 // Allow for using event listeners also 1578 /** 1579 * Triggered when a `Component` is ready. 1580 * 1581 * @event Component#ready 1582 * @type {EventTarget~Event} 1583 */ 1584 this.trigger('ready'); 1585 }, 1); 1586 }; 1587 1588 /** 1589 * Find a single DOM element matching a `selector`. This can be within the `Component`s 1590 * `contentEl()` or another custom context. 1591 * 1592 * @param {string} selector 1593 * A valid CSS selector, which will be passed to `querySelector`. 1594 * 1595 * @param {Element|string} [context=this.contentEl()] 1596 * A DOM element within which to query. Can also be a selector string in 1597 * which case the first matching element will get used as context. If 1598 * missing `this.contentEl()` gets used. If `this.contentEl()` returns 1599 * nothing it falls back to `document`. 1600 * 1601 * @return {Element|null} 1602 * the dom element that was found, or null 1603 * 1604 * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) 1605 */ 1606 1607 1608 Component.prototype.$ = function $(selector, context) { 1609 return Dom.$(selector, context || this.contentEl()); 1610 }; 1611 1612 /** 1613 * Finds all DOM element matching a `selector`. This can be within the `Component`s 1614 * `contentEl()` or another custom context. 1615 * 1616 * @param {string} selector 1617 * A valid CSS selector, which will be passed to `querySelectorAll`. 1618 * 1619 * @param {Element|string} [context=this.contentEl()] 1620 * A DOM element within which to query. Can also be a selector string in 1621 * which case the first matching element will get used as context. If 1622 * missing `this.contentEl()` gets used. If `this.contentEl()` returns 1623 * nothing it falls back to `document`. 1624 * 1625 * @return {NodeList} 1626 * a list of dom elements that were found 1627 * 1628 * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) 1629 */ 1630 1631 1632 Component.prototype.$$ = function $$(selector, context) { 1633 return Dom.$$(selector, context || this.contentEl()); 1634 }; 1635 1636 /** 1637 * Check if a component's element has a CSS class name. 1638 * 1639 * @param {string} classToCheck 1640 * CSS class name to check. 1641 * 1642 * @return {boolean}
1643 * - True if the `Component` has the class. 1644 * - False if the `Component` does not have the class` 1645 */ 1646 1647 1648 Component.prototype.hasClass = function hasClass(classToCheck) { 1649 return Dom.hasElClass(this.el_, classToCheck); 1650 }; 1651 1652 /** 1653 * Add a CSS class name to the `Component`s element. 1654 * 1655 * @param {string} classToAdd 1656 * CSS class name to add 1657 * 1658 * @return {Component} 1659 * Returns itself; method can be chained. 1660 */ 1661 1662 1663 Component.prototype.addClass = function addClass(classToAdd) { 1664 Dom.addElClass(this.el_, classToAdd); 1665 return this; 1666 }; 1667 1668 /** 1669 * Remove a CSS class name from the `Component`s element. 1670 * 1671 * @param {string} classToRemove 1672 * CSS class name to remove 1673 * 1674 * @return {Component} 1675 * Returns itself; method can be chained. 1676 */ 1677 1678 1679 Component.prototype.removeClass = function removeClass(classToRemove) { 1680 Dom.removeElClass(this.el_, classToRemove); 1681 return this; 1682 }; 1683 1684 /** 1685 * Add or remove a CSS class name from the component's element. 1686 * - `classToToggle` gets added when {@link Component#hasClass} would return false. 1687 * - `classToToggle` gets removed when {@link Component#hasClass} would return true. 1688 * 1689 * @param {string} classToToggle 1690 * The class to add or remove based on (@link Component#hasClass} 1691 * 1692 * @param {boolean|Dom~predicate} [predicate] 1693 * An {@link Dom~predicate} function or a boolean 1694 * 1695 * @return {Component} 1696 * Returns itself; method can be chained. 1697 */ 1698 1699 1700 Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) { 1701 Dom.toggleElClass(this.el_, classToToggle, predicate); 1702 return this; 1703 }; 1704 1705 /** 1706 * Show the `Component`s element if it is hidden by removing the 1707 * 'vjs-hidden' class name from it. 1708 * 1709 * @return {Component} 1710 * Returns itself; method can be chained. 1711 */ 1712 1713 1714 Component.prototype.show = function show() { 1715 this.removeClass('vjs-hidden'); 1716 return this; 1717 }; 1718 1719 /** 1720 * Hide the `Component`s element if it is currently showing by adding the 1721 * 'vjs-hidden` class name to it. 1722 * 1723 * @return {Component} 1724 * Returns itself; method can be chained. 1725 */ 1726 1727 1728 Component.prototype.hide = function hide() { 1729 this.addClass('vjs-hidden'); 1730 return this; 1731 }; 1732 1733 /** 1734 * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing' 1735 * class name to it. Used during fadeIn/fadeOut. 1736 * 1737 * @return {Component} 1738 * Returns itself; method can be chained. 1739 * 1740 * @private 1741 */ 1742 1743 1744 Component.prototype.lockShowing = function lockShowing() { 1745 this.addClass('vjs-lock-showing'); 1746 return this; 1747 }; 1748 1749 /** 1750 * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing' 1751 * class name from it. Used during fadeIn/fadeOut. 1752 * 1753 * @return {Component} 1754 * Returns itself; method can be chained. 1755 * 1756 * @private 1757 */ 1758 1759 1760 Component.prototype.unlockShowing = function unlockShowing() { 1761 this.removeClass('vjs-lock-showing'); 1762 return this; 1763 }; 1764 1765 /** 1766 * Get the value of an attribute on the `Component`s element. 1767 * 1768 * @param {string} attribute 1769 * Name of the attribute to get the value from. 1770 * 1771 * @return {string|null} 1772 * - The value of the attribute that was asked for. 1773 * - Can be an empty string on some browsers if the attribute does not exist 1774 * or has no value 1775 * - Most browsers will return null if the attibute does not exist or has 1776 * no value. 1777 * 1778 * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute} 1779 */ 1780 1781 1782 Component.prototype.getAttribute = function getAttribute(attribute) { 1783 return Dom.getAttribute(this.el_, attribute); 1784 }; 1785 1786 /** 1787 * Set the value of an attribute on the `Component`'s element 1788 * 1789 * @param {string} attribute 1790 * Name of the attribute to set. 1791 * 1792 * @param {string} value 1793 * Value to set the attribute to. 1794 * 1795 * @return {Component} 1796 * Returns itself; method can be chained. 1797 * 1798 * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute} 1799 */ 1800 1801 1802 Component.prototype.setAttribute = function setAttribute(attribute, value) { 1803 Dom.setAttribute(this.el_, attribute, value); 1804 return this; 1805 }; 1806 1807 /** 1808 * Remove an attribute from the `Component`s element. 1809 * 1810 * @param {string} attribute 1811 * Name of the attribute to remove. 1812 * 1813 * @return {Component} 1814 * Returns itself; method can be chained. 1815 * 1816 * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute} 1817 */ 1818 1819 1820 Component.prototype.removeAttribute = function removeAttribute(attribute) { 1821 Dom.removeAttribute(this.el_, attribute); 1822 return this; 1823 }; 1824 1825 /** 1826 * Get or set the width of the component based upon the CSS styles. 1827 * See {@link Component#dimension} for more detailed information. 1828 * 1829 * @param {number|string} [num] 1830 * The width that you want to set postfixed with '%', 'px' or nothing. 1831 * 1832 * @param {boolean} [skipListeners] 1833 * Skip the resize event trigger 1834 * 1835 * @return {Component|number|string} 1836 * - The width when getting, zero if there is no width. Can be a string 1837 * postpixed with '%' or 'px'. 1838 * - Returns itself when setting; method can be chained. 1839 */ 1840 1841 1842 Component.prototype.width = function width(num, skipListeners) { 1843 return this.dimension('width', num, skipListeners); 1844 }; 1845 1846 /** 1847 * Get or set the height of the component based upon the CSS styles. 1848 * See {@link Component#dimension} for more detailed information. 1849 * 1850 * @param {number|string} [num] 1851 * The height that you want to set postfixed with '%', 'px' or nothing. 1852 * 1853 * @param {boolean} [skipListeners] 1854 * Skip the resize event trigger 1855 * 1856 * @return {Component|number|string} 1857 * - The width when getting, zero if there is no width. Can be a string 1858 * postpixed with '%' or 'px'. 1859 * - Returns itself when setting; method can be chained. 1860 */ 1861 1862 1863 Component.prototype.height = function height(num, skipListeners) { 1864 return this.dimension('height', num, skipListeners); 1865 }; 1866 1867 /** 1868 * Set both the width and height of the `Component` element at the same time. 1869 * 1870 * @param {number|string} width 1871 * Width to set the `Component`s element to. 1872 * 1873 * @param {number|string} height 1874 * Height to set the `Component`s element to. 1875 * 1876 * @return {Component} 1877 * Returns itself; method can be chained. 1878 */ 1879 1880 1881 Component.prototype.dimensions = function dimensions(width, height) { 1882 // Skip resize listeners on width for optimization 1883 return this.width(width, true).height(height); 1884 }; 1885 1886 /** 1887 * Get or set width or height of the `Component` element. This is the shared code 1888 * for the {@link Component#width} and {@link Component#height}. 1889 * 1890 * Things to know: 1891 * - If the width or height in an number this will return the number postfixed with 'px'. 1892 * - If the width/height is a percent this will return the percent postfixed with '%' 1893 * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function 1894 * defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`. 1895 * See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-u
1895sing-width/} 1896 * for more information 1897 * - If you want the computed style of the component, use {@link Component#currentWidth} 1898 * and {@link {Component#currentHeight} 1899 * 1900 * @fires Component#resize 1901 * 1902 * @param {string} widthOrHeight 1903 8 'width' or 'height' 1904 * 1905 * @param {number|string} [num] 1906 8 New dimension 1907 * 1908 * @param {boolean} [skipListeners] 1909 * Skip resize event trigger 1910 * 1911 * @return {Component} 1912 * - the dimension when getting or 0 if unset 1913 * - Returns itself when setting; method can be chained. 1914 */ 1915 1916 1917 Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) { 1918 if (num !== undefined) { 1919 // Set to zero if null or literally NaN (NaN !== NaN) 1920 if (num === null || num !== num) { 1921 num = 0; 1922 } 1923 1924 // Check if using css width/height (% or px) and adjust 1925 if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) { 1926 this.el_.style[widthOrHeight] = num; 1927 } else if (num === 'auto') { 1928 this.el_.style[widthOrHeight] = ''; 1929 } else { 1930 this.el_.style[widthOrHeight] = num + 'px'; 1931 } 1932 1933 // skipListeners allows us to avoid triggering the resize event when setting both width and height 1934 if (!skipListeners) { 1935 /** 1936 * Triggered when a component is resized. 1937 * 1938 * @event Component#resize 1939 * @type {EventTarget~Event} 1940 */ 1941 this.trigger('resize'); 1942 } 1943 1944 // Return component 1945 return this; 1946 } 1947 1948 // Not setting a value, so getting it 1949 // Make sure element exists 1950 if (!this.el_) { 1951 return 0; 1952 } 1953 1954 // Get dimension value from style 1955 var val = this.el_.style[widthOrHeight]; 1956 var pxIndex = val.indexOf('px'); 1957 1958 if (pxIndex !== -1) { 1959 // Return the pixel value with no 'px' 1960 return parseInt(val.slice(0, pxIndex), 10); 1961 } 1962 1963 // No px so using % or no style was set, so falling back to offsetWidth/height 1964 // If component has display:none, offset will return 0 1965 // TODO: handle display:none and no dimension style using px 1966 return parseInt(this.el_['offset' + (0, _toTitleCase2['default'])(widthOrHeight)], 10); 1967 }; 1968 1969 /** 1970 * Get the width or the height of the `Component` elements computed style. Uses 1971 * `window.getComputedStyle`. 1972 * 1973 * @param {string} widthOrHeight 1974 * A string containing 'width' or 'height'. Whichever one you want to get. 1975 * 1976 * @return {number} 1977 * The dimension that gets asked for or 0 if nothing was set 1978 * for that dimension. 1979 */ 1980 1981 1982 Component.prototype.currentDimension = function currentDimension(widthOrHeight) { 1983 var computedWidthOrHeight = 0; 1984 1985 if (widthOrHeight !== 'width' && widthOrHeight !== 'height') { 1986 throw new Error('currentDimension only accepts width or height value'); 1987 } 1988 1989 if (typeof _window2['default'].getComputedStyle === 'function') { 1990 var computedStyle = _window2['default'].getComputedStyle(this.el_); 1991 1992 computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight]; 1993 } 1994 1995 // remove 'px' from variable and parse as integer 1996 computedWidthOrHeight = parseFloat(computedWidthOrHeight); 1997 1998 // if the computed value is still 0, it's possible that the browser is lying 1999 // and we want to check the offset values. 2000 // This code also runs on IE8 and wherever getComputedStyle doesn't exist. 2001 if (computedWidthOrHeight === 0) { 2002 var rule = 'offset' + (0, _toTitleCase2['default'])(widthOrHeight); 2003 2004 computedWidthOrHeight = this.el_[rule]; 2005 } 2006 2007 return computedWidthOrHeight; 2008 }; 2009 2010 /** 2011 * An object that contains width and height values of the `Component`s 2012 * computed style. Uses `window.getComputedStyle`. 2013 * 2014 * @typedef {Object} Component~DimensionObject 2015 * 2016 * @property {number} width 2017 * The width of the `Component`s computed style. 2018 * 2019 * @property {number} height 2020 * The height of the `Component`s computed style. 2021 */ 2022 2023 /** 2024 * Get an object that contains width and height values of the `Component`s 2025 * computed style. 2026 * 2027 * @return {Component~DimensionObject} 2028 * The dimensions of the components element 2029 */ 2030 2031 2032 Component.prototype.currentDimensions = function currentDimensions() { 2033 return { 2034 width: this.currentDimension('width'), 2035 height: this.currentDimension('height') 2036 }; 2037 }; 2038 2039 /** 2040 * Get the width of the `Component`s computed style. Uses `window.getComputedStyle`. 2041 * 2042 * @return {number} width 2043 * The width of the `Component`s computed style. 2044 */ 2045 2046 2047 Component.prototype.currentWidth = function currentWidth() { 2048 return this.currentDimension('width'); 2049 }; 2050 2051 /** 2052 * Get the height of the `Component`s computed style. Uses `window.getComputedStyle`. 2053 * 2054 * @return {number} height 2055 * The height of the `Component`s computed style. 2056 */ 2057 2058 2059 Component.prototype.currentHeight = function currentHeight() { 2060 return this.currentDimension('height'); 2061 }; 2062 2063 /** 2064 * Emit a 'tap' events when touch event support gets detected. This gets used to 2065 * support toggling the controls through a tap on the video. They get enabled 2066 * because every sub-component would have extra overhead otherwise. 2067 * 2068 * @private 2069 * @fires Component#tap 2070 * @listens Component#touchstart 2071 * @listens Component#touchmove 2072 * @listens Component#touchleave 2073 * @listens Component#touchcancel 2074 * @listens Component#touchend 2075 */ 2076 2077 2078 Component.prototype.emitTapEvents = function emitTapEvents() { 2079 // Track the start time so we can determine how long the touch lasted 2080 var touchStart = 0; 2081 var firstTouch = null; 2082 2083 // Maximum movement allowed during a touch event to still be considered a tap 2084 // Other popular libs use anywhere from 2 (hammer.js) to 15, 2085 // so 10 seems like a nice, round number. 2086 var tapMovementThreshold = 10; 2087 2088 // The maximum length a touch can be while still being considered a tap 2089 var touchTimeThreshold = 200; 2090 2091 var couldBeTap = void 0; 2092 2093 this.on('touchstart', function (event) { 2094 // If more than one finger, don't consider treating this as a click 2095 if (event.touches.length === 1) { 2096 // Copy pageX/pageY from the object 2097 firstTouch = { 2098 pageX: event.touches[0].pageX, 2099 pageY: event.touches[0].pageY 2100 }; 2101 // Record start time so we can detect a tap vs. "touch and hold" 2102 touchStart = new Date().getTime(); 2103 // Reset couldBeTap tracking 2104 couldBeTap = true; 2105 } 2106 }); 2107 2108 this.on('touchmove', function (event) { 2109 // If more than one finger, don't consider treating this as a click 2110 if (event.touches.length > 1) { 2111 couldBeTap = false;
vendor: 7,461 bytes, lines 2112-2310
2112 } else if (firstTouch) { 2113 // Some devices will throw touchmoves for all but the slightest of taps. 2114 // So, if we moved only a small distance, this could still be a tap 2115 var xdiff = event.touches[0].pageX - firstTouch.pageX; 2116 var ydiff = event.touches[0].pageY - firstTouch.pageY; 2117 var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff); 2118 2119 if (touchDistance > tapMovementThreshold) { 2120 couldBeTap = false; 2121 } 2122 } 2123 }); 2124 2125 var noTap = function noTap() { 2126 couldBeTap = false; 2127 }; 2128 2129 // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s 2130 this.on('touchleave', noTap); 2131 this.on('touchcancel', noTap); 2132 2133 // When the touch ends, measure how long it took and trigger the appropriate 2134 // event 2135 this.on('touchend', function (event) { 2136 firstTouch = null; 2137 // Proceed only if the touchmove/leave/cancel event didn't happen 2138 if (couldBeTap === true) { 2139 // Measure how long the touch lasted 2140 var touchTime = new Date().getTime() - touchStart; 2141 2142 // Make sure the touch was less than the threshold to be considered a tap 2143 if (touchTime < touchTimeThreshold) { 2144 // Don't let browser turn this into a click 2145 event.preventDefault(); 2146 /** 2147 * Triggered when a `Component` is tapped. 2148 * 2149 * @event Component#tap 2150 * @type {EventTarget~Event} 2151 */ 2152 this.trigger('tap'); 2153 // It may be good to copy the touchend event object and change the 2154 // type to tap, if the other event properties aren't exact after 2155 // Events.fixEvent runs (e.g. event.target) 2156 } 2157 } 2158 }); 2159 }; 2160 2161 /** 2162 * This function reports user activity whenever touch events happen. This can get 2163 * turned off by any sub-components that wants touch events to act another way. 2164 * 2165 * Report user touch activity when touch events occur. User activity gets used to 2166 * determine when controls should show/hide. It is simple when it comes to mouse 2167 * events, because any mouse event should show the controls. So we capture mouse 2168 * events that bubble up to the player and report activity when that happens. 2169 * With touch events it isn't as easy as `touchstart` and `touchend` toggle player 2170 * controls. So touch events can't help us at the player level either. 2171 * 2172 * User activity gets checked asynchronously. So what could happen is a tap event 2173 * on the video turns the controls off. Then the `touchend` event bubbles up to 2174 * the player. Which, if it reported user activity, would turn the controls right 2175 * back on. We also don't want to completely block touch events from bubbling up. 2176 * Furthermore a `touchmove` event and anything other than a tap, should not turn 2177 * controls back on. 2178 * 2179 * @listens Component#touchstart 2180 * @listens Component#touchmove 2181 * @listens Component#touchend 2182 * @listens Component#touchcancel 2183 */ 2184 2185 2186 Component.prototype.enableTouchActivity = function enableTouchActivity() { 2187 // Don't continue if the root player doesn't support reporting user activity 2188 if (!this.player() || !this.player().reportUserActivity) { 2189 return; 2190 } 2191 2192 // listener for reporting that the user is active 2193 var report = Fn.bind(this.player(), this.player().reportUserActivity); 2194 2195 var touchHolding = void 0; 2196 2197 this.on('touchstart', function () { 2198 report(); 2199 // For as long as the they are touching the device or have their mouse down, 2200 // we consider them active even if they're not moving their finger or mouse. 2201 // So we want to continue to update that they are active 2202 this.clearInterval(touchHolding); 2203 // report at the same interval as activityCheck 2204 touchHolding = this.setInterval(report, 250); 2205 }); 2206 2207 var touchEnd = function touchEnd(event) { 2208 report(); 2209 // stop the interval that maintains activity if the touch is holding 2210 this.clearInterval(touchHolding); 2211 }; 2212 2213 this.on('touchmove', report); 2214 this.on('touchend', touchEnd); 2215 this.on('touchcancel', touchEnd); 2216 }; 2217 2218 /** 2219 * A callback that has no parameters and is bound into `Component`s context. 2220 * 2221 * @callback Component~GenericCallback 2222 * @this Component 2223 */ 2224 2225 /** 2226 * Creates a function that runs after an `x` millisecond timeout. This function is a 2227 * wrapper around `window.setTimeout`. There are a few reasons to use this one 2228 * instead though: 2229 * 1. It gets cleared via {@link Component#clearTimeout} when 2230 * {@link Component#dispose} gets called. 2231 * 2. The function callback will gets turned into a {@link Component~GenericCallback} 2232 * 2233 * > Note: You can use `window.clearTimeout` on the id returned by this function. This 2234 * will cause its dispose listener not to get cleaned up! Please use 2235 * {@link Component#clearTimeout} or {@link Component#dispose}. 2236 * 2237 * @param {Component~GenericCallback} fn 2238 * The function that will be run after `timeout`. 2239 * 2240 * @param {number} timeout 2241 * Timeout in milliseconds to delay before executing the specified function. 2242 * 2243 * @return {number} 2244 * Returns a timeout ID that gets used to identify the timeout. It can also 2245 * get used in {@link Component#clearTimeout} to clear the timeout that 2246 * was set. 2247 * 2248 * @listens Component#dispose 2249 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout} 2250 */ 2251 2252 2253 Component.prototype.setTimeout = function setTimeout(fn, timeout) { 2254 fn = Fn.bind(this, fn); 2255 2256 var timeoutId = _window2['default'].setTimeout(fn, timeout); 2257 var disposeFn = function disposeFn() { 2258 this.clearTimeout(timeoutId); 2259 }; 2260 2261 disposeFn.guid = 'vjs-timeout-' + timeoutId; 2262 2263 this.on('dispose', disposeFn); 2264 2265 return timeoutId; 2266 }; 2267 2268 /** 2269 * Clears a timeout that gets created via `window.setTimeout` or 2270 * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout} 2271 * use this function instead of `window.clearTimout`. If you don't your dispose 2272 * listener will not get cleaned up until {@link Component#dispose}! 2273 * 2274 * @param {number} timeoutId 2275 * The id of the timeout to clear. The return value of 2276 * {@link Component#setTimeout} or `window.setTimeout`. 2277 * 2278 * @return {number} 2279 * Returns the timeout id that was cleared. 2280 * 2281 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout} 2282 */ 2283 2284 2285 Component.prototype.clearTimeout = function clearTimeout(timeoutId) { 2286 _window2['default'].clearTimeout(timeoutId); 2287 2288 var disposeFn = function disposeFn() {}; 2289 2290 disposeFn.guid = 'vjs-timeout-' + timeoutId; 2291 2292 this.off('dispose', disposeFn); 2293 2294 return timeoutId; 2295 }; 2296 2297 /** 2298 * Creates a function that gets run every `x` milliseconds. This function is a wrapper 2299 * around `window.setInterval`. There are a few reasons to use this one instead though. 2300 * 1. It gets cleared via {@link Component#clearInterval} when 2301 * {@link Component#dispose} gets called. 2302 * 2. The function callback will be a {@link Component~GenericCallback} 2303 * 2304 * @param {Component~GenericCallback} fn 2305 * The function to run every `x` seconds. 2306 * 2307 * @param {number} interval 2308 * Execute the specified function every `x` milliseconds. 2309 * 2310 * @return {number}
2311 * Returns an id that can be used to identify the interval. It can also be be used in 2312 * {@link Component#clearInterval} to clear the interval. 2313 * 2314 * @listens Component#dispose 2315 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval} 2316 */ 2317 2318 2319 Component.prototype.setInterval = function setInterval(fn, interval) { 2320 fn = Fn.bind(this, fn); 2321 2322 var intervalId = _window2['default'].setInterval(fn, interval); 2323 2324 var disposeFn = function disposeFn() { 2325 this.clearInterval(intervalId); 2326 }; 2327 2328 disposeFn.guid = 'vjs-interval-' + intervalId; 2329 2330 this.on('dispose', disposeFn); 2331 2332 return intervalId; 2333 }; 2334 2335 /** 2336 * Clears an interval that gets created via `window.setInterval` or 2337 * {@link Component#setInterval}. If you set an inteval via {@link Component#setInterval} 2338 * use this function instead of `window.clearInterval`. If you don't your dispose 2339 * listener will not get cleaned up until {@link Component#dispose}! 2340 * 2341 * @param {number} intervalId 2342 * The id of the interval to clear. The return value of 2343 * {@link Component#setInterval} or `window.setInterval`. 2344 * 2345 * @return {number} 2346 * Returns the interval id that was cleared. 2347 * 2348 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval} 2349 */ 2350 2351 2352 Component.prototype.clearInterval = function clearInterval(intervalId) { 2353 _window2['default'].clearInterval(intervalId); 2354 2355 var disposeFn = function disposeFn() {}; 2356 2357 disposeFn.guid = 'vjs-interval-' + intervalId; 2358 2359 this.off('dispose', disposeFn); 2360 2361 return intervalId; 2362 }; 2363 2364 /** 2365 * Register a `Component` with `videojs` given the name and the component. 2366 * 2367 * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s 2368 * should be registered using {@link Tech.registerTech} or 2369 * {@link videojs:videojs.registerTech}. 2370 * 2371 * > NOTE: This function can also be seen on videojs as 2372 * {@link videojs:videojs.registerComponent}. 2373 * 2374 * @param {string} name 2375 * The name of the `Component` to register. 2376 * 2377 * @param {Component} comp 2378 * The `Component` class to register. 2379 * 2380 * @return {Component} 2381 * The `Component` that was registered. 2382 */ 2383 2384 2385 Component.registerComponent = function registerComponent(name, comp) { 2386 if (!name) { 2387 return; 2388 } 2389 2390 name = (0, _toTitleCase2['default'])(name); 2391 2392 if (!Component.components_) { 2393 Component.components_ = {}; 2394 } 2395 2396 if (name === 'Player' && Component.components_[name]) { 2397 (function () { 2398 var Player = Component.components_[name]; 2399 2400 // If we have players that were disposed, then their name will still be 2401 // in Players.players. So, we must loop through and verify that the value 2402 // for each item is not null. This allows registration of the Player component 2403 // after all players have been disposed or before any were created. 2404 if (Player.players && Object.keys(Player.players).length > 0 && Object.keys(Player.players).map(function (playerName) { 2405 return Player.players[playerName]; 2406 }).every(Boolean)) { 2407 throw new Error('Can not register Player component after player has been created'); 2408 } 2409 })(); 2410 } 2411 2412 Component.components_[name] = comp; 2413 2414 return comp; 2415 }; 2416 2417 /** 2418 * Get a `Component` based on the name it was registered with. 2419 * 2420 * @param {string} name 2421 * The Name of the component to get. 2422 * 2423 * @return {Component} 2424 * The `Component` that got registered under the given name. 2425 * 2426 * @deprecated In `videojs` 6 this will not return `Component`s that were not 2427 * registered using {@link Component.registerComponent}. Currently we 2428 * check the global `videojs` object for a `Component` name and 2429 * return that if it exists. 2430 */ 2431 2432 2433 Component.getComponent = function getComponent(name) { 2434 if (!name) { 2435 return; 2436 } 2437 2438 name = (0, _toTitleCase2['default'])(name); 2439 2440 if (Component.components_ && Component.components_[name]) { 2441 return Component.components_[name]; 2442 } 2443 2444 if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) { 2445 _log2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)'); 2446 2447 return _window2['default'].videojs[name]; 2448 } 2449 }; 2450 2451 /** 2452 * Sets up the constructor using the supplied init method or uses the init of the 2453 * parent object. 2454 * 2455 * @param {Object} [props={}] 2456 * An object of properties. 2457 * 2458 * @return {Object} 2459 * the extended object. 2460 * 2461 * @deprecated since version 5 2462 */ 2463 2464 2465 Component.extend = function extend(props) { 2466 props = props || {}; 2467 2468 _log2['default'].warn('Component.extend({}) has been deprecated, ' + ' use videojs.extend(Component, {}) instead'); 2469 2470 // Set up the constructor using the supplied init method 2471 // or using the init of the parent object 2472 // Make sure to check the unobfuscated version for external libs 2473 var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {}; 2474 // In Resig's simple class inheritance (previously used) the constructor 2475 // is a function that calls `this.init.apply(arguments)` 2476 // However that would prevent us from using `ParentObject.call(this);` 2477 // in a Child constructor because the `this` in `this.init` 2478 // would still refer to the Child and cause an infinite loop. 2479 // We would instead have to do
2480 // `ParentObject.prototype.init.apply(this, arguments);` 2481 // Bleh. We're not creating a _super() function, so it's good to keep 2482 // the parent constructor reference simple. 2483 var subObj = function subObj() { 2484 init.apply(this, arguments); 2485 }; 2486 2487 // Inherit from this object's prototype 2488 subObj.prototype = Object.create(this.prototype); 2489 // Reset the constructor property for subObj otherwise 2490 // instances of subObj would have the constructor of the parent Object 2491 subObj.prototype.constructor = subObj; 2492 2493 // Make the class extendable 2494 subObj.extend = Component.extend; 2495 2496 // Extend subObj's prototype with functions and other properties from props 2497 for (var name in props) { 2498 if (props.hasOwnProperty(name)) { 2499 subObj.prototype[name] = props[name]; 2500 } 2501 } 2502 2503 return subObj; 2504 }; 2505 2506 return Component; 2507}(); 2508 2509Component.registerComponent('Component', Component); 2510exports['default'] = Component; 2511 2512},{"81":81,"82":82,"83":83,"85":85,"86":86,"87":87,"91":91,"95":95}],6:[function(_dereq_,module,exports){ 2513'use strict'; 2514 2515exports.__esModule = true; 2516 2517var _trackButton = _dereq_(36); 2518 2519var _trackButton2 = _interopRequireDefault(_trackButton); 2520 2521var _component = _dereq_(5); 2522 2523var _component2 = _interopRequireDefault(_component); 2524 2525var _audioTrackMenuItem = _dereq_(7); 2526 2527var _audioTrackMenuItem2 = _interopRequireDefault(_audioTrackMenuItem); 2528 2529function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2530 2531function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 2532 2533function _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; } 2534 2535function _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; } /** 2536 * @file audio-track-button.js 2537 */ 2538 2539 2540/** 2541 * The base class for buttons that toggle specific {@link AudioTrack} types. 2542 * 2543 * @extends TrackButton 2544 */ 2545var AudioTrackButton = function (_TrackButton) { 2546 _inherits(AudioTrackButton, _TrackButton); 2547 2548 /** 2549 * Creates an instance of this class. 2550 * 2551 * @param {Player} player 2552 * The `Player` that this class should be attached to. 2553 * 2554 * @param {Object} [options={}] 2555 * The key/value store of player options. 2556 */ 2557 function AudioTrackButton(player) { 2558 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 2559 2560 _classCallCheck(this, AudioTrackButton); 2561 2562 options.tracks = player.audioTracks && player.audioTracks(); 2563 2564 var _this = _possibleConstructorReturn(this, _TrackButton.call(this, player, options)); 2565 2566 _this.el_.setAttribute('aria-label', 'Audio Menu'); 2567 return _this; 2568 } 2569 2570 /** 2571 * Builds the default DOM `className`. 2572 * 2573 * @return {string} 2574 * The DOM `className` for this object. 2575 */ 2576 2577 2578 AudioTrackButton.prototype.buildCSSClass = function buildCSSClass() { 2579 return 'vjs-audio-button ' + _TrackButton.prototype.buildCSSClass.call(this); 2580 }; 2581 2582 /** 2583 * Create a menu item for each audio track 2584 * 2585 * @param {AudioTrackMenuItem[]} [items=[]] 2586 * An array of existing menu items to use. 2587 * 2588 * @return {AudioTrackMenuItem[]} 2589 * An array of menu items 2590 */ 2591 2592 2593 AudioTrackButton.prototype.createItems = function createItems() { 2594 var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 2595 2596 var tracks = this.player_.audioTracks && this.player_.audioTracks(); 2597 2598 if (!tracks) { 2599 return items; 2600 } 2601 2602 for (var i = 0; i < tracks.length; i++) { 2603 var track = tracks[i]; 2604 2605 items.push(new _audioTrackMenuItem2['default'](this.player_, { 2606 track: track, 2607 // MenuItem is selectable 2608 selectable: true 2609 })); 2610 } 2611 2612 return items; 2613 }; 2614 2615 return AudioTrackButton; 2616}(_trackButton2['default']); 2617 2618/** 2619 * The text that should display over the `AudioTrackButton`s controls. Added for localization. 2620 * 2621 * @type {string} 2622 * @private 2623 */ 2624 2625 2626AudioTrackButton.prototype.controlText_ = 'Audio Track'; 2627_component2['default'].registerComponent('AudioTrackButton', AudioTrackButton); 2628exports['default'] = AudioTrackButton; 2629 2630},{"36":36,"5":5,"7":7}],7:[function(_dereq_,module,exports){ 2631'use strict'; 2632 2633exports.__esModule = true; 2634 2635var _menuItem = _dereq_(48); 2636 2637var _menuItem2 = _interopRequireDefault(_menuItem); 2638 2639var _component = _dereq_(5); 2640 2641var _component2 = _interopRequireDefault(_component); 2642 2643var _fn = _dereq_(83); 2644 2645var Fn = _interopRequireWildcard(_fn); 2646 2647function _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; } } 2648 2649function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2650 2651function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 2652 2653function _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; } 2654 2655function _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
2655onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 2656 * @file audio-track-menu-item.js 2657 */ 2658 2659 2660/** 2661 * An {@link AudioTrack} {@link MenuItem} 2662 * 2663 * @extends MenuItem 2664 */ 2665var AudioTrackMenuItem = function (_MenuItem) { 2666 _inherits(AudioTrackMenuItem, _MenuItem); 2667 2668 /** 2669 * Creates an instance of this class. 2670 * 2671 * @param {Player} player 2672 * The `Player` that this class should be attached to. 2673 * 2674 * @param {Object} [options] 2675 * The key/value store of player options. 2676 */ 2677 function AudioTrackMenuItem(player, options) { 2678 _classCallCheck(this, AudioTrackMenuItem); 2679 2680 var track = options.track; 2681 var tracks = player.audioTracks(); 2682 2683 // Modify options for parent MenuItem class's init. 2684 options.label = track.label || track.language || 'Unknown'; 2685 options.selected = track.enabled; 2686 2687 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options)); 2688 2689 _this.track = track; 2690 2691 if (tracks) { 2692 (function () { 2693 var changeHandler = Fn.bind(_this, _this.handleTracksChange); 2694 2695 tracks.addEventListener('change', changeHandler); 2696 _this.on('dispose', function () { 2697 tracks.removeEventListener('change', changeHandler); 2698 }); 2699 })(); 2700 } 2701 return _this; 2702 } 2703 2704 /** 2705 * This gets called when an `AudioTrackMenuItem is "clicked". See {@link ClickableComponent} 2706 * for more detailed information on what a click can be. 2707 * 2708 * @param {EventTarget~Event} [event] 2709 * The `keydown`, `tap`, or `click` event that caused this function to be 2710 * called. 2711 * 2712 * @listens tap 2713 * @listens click 2714 */ 2715 2716 2717 AudioTrackMenuItem.prototype.handleClick = function handleClick(event) { 2718 var tracks = this.player_.audioTracks(); 2719 2720 _MenuItem.prototype.handleClick.call(this, event); 2721 2722 if (!tracks) { 2723 return; 2724 } 2725 2726 for (var i = 0; i < tracks.length; i++) { 2727 var track = tracks[i]; 2728 2729 track.enabled = track === this.track; 2730 } 2731 }; 2732 2733 /** 2734 * Handle any {@link AudioTrack} change. 2735 * 2736 * @param {EventTarget~Event} [event] 2737 * The {@link AudioTrackList#change} event that caused this to run. 2738 * 2739 * @listens AudioTrackList#change 2740 */ 2741 2742 2743 AudioTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { 2744 this.selected(this.track.enabled); 2745 }; 2746 2747 return AudioTrackMenuItem; 2748}(_menuItem2['default']); 2749 2750_component2['default'].registerComponent('AudioTrackMenuItem', AudioTrackMenuItem); 2751exports['default'] = AudioTrackMenuItem; 2752 2753},{"48":48,"5":5,"83":83}],8:[function(_dereq_,module,exports){ 2754'use strict'; 2755 2756exports.__esModule = true; 2757 2758var _component = _dereq_(5); 2759 2760var _component2 = _interopRequireDefault(_component); 2761 2762_dereq_(12); 2763 2764_dereq_(32); 2765 2766_dereq_(33); 2767 2768_dereq_(35); 2769 2770_dereq_(34); 2771 2772_dereq_(10); 2773 2774_dereq_(18); 2775 2776_dereq_(9); 2777 2778_dereq_(38); 2779 2780_dereq_(40); 2781 2782_dereq_(11); 2783 2784_dereq_(25); 2785 2786_dereq_(27); 2787 2788_dereq_(29); 2789 2790_dereq_(24); 2791 2792_dereq_(6); 2793 2794_dereq_(13); 2795 2796_dereq_(21); 2797 2798function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2799 2800function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 2801 2802function _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; } 2803 2804function _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
2804onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 2805 * @file control-bar.js 2806 */ 2807 2808 2809// Required children 2810 2811 2812/** 2813 * Container of main controls. 2814 * 2815 * @extends Component 2816 */ 2817var ControlBar = function (_Component) { 2818 _inherits(ControlBar, _Component); 2819 2820 function ControlBar() { 2821 _classCallCheck(this, ControlBar); 2822 2823 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 2824 } 2825 2826 /** 2827 * Create the `Component`'s DOM element 2828 * 2829 * @return {Element} 2830 * The element that was created. 2831 */ 2832 ControlBar.prototype.createEl = function createEl() { 2833 return _Component.prototype.createEl.call(this, 'div', { 2834 className: 'vjs-control-bar', 2835 dir: 'ltr' 2836 }, { 2837 // The control bar is a group, so it can contain menuitems 2838 role: 'group' 2839 }); 2840 }; 2841 2842 return ControlBar; 2843}(_component2['default']); 2844 2845/** 2846 * Default options for `ControlBar` 2847 * 2848 * @type {Object} 2849 * @private 2850 */ 2851 2852 2853ControlBar.prototype.options_ = { 2854 children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subtitlesButton', 'captionsButton', 'audioTrackButton', 'fullscreenToggle'] 2855}; 2856 2857_component2['default'].registerComponent('ControlBar', ControlBar); 2858exports['default'] = ControlBar; 2859 2860},{"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){ 2861'use strict'; 2862 2863exports.__esModule = true; 2864 2865var _button = _dereq_(2); 2866 2867var _button2 = _interopRequireDefault(_button); 2868 2869var _component = _dereq_(5); 2870 2871var _component2 = _interopRequireDefault(_component); 2872 2873function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2874 2875function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 2876 2877function _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; } 2878 2879function _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; } /** 2880 * @file fullscreen-toggle.js 2881 */ 2882 2883 2884/** 2885 * Toggle fullscreen video 2886 * 2887 * @extends Button 2888 */ 2889var FullscreenToggle = function (_Button) { 2890 _inherits(FullscreenToggle, _Button); 2891 2892 /** 2893 * Creates an instance of this class. 2894 * 2895 * @param {Player} player 2896 * The `Player` that this class should be attached to. 2897 * 2898 * @param {Object} [options] 2899 * The key/value store of player options. 2900 */ 2901 function FullscreenToggle(player, options) { 2902 _classCallCheck(this, FullscreenToggle); 2903 2904 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options)); 2905 2906 _this.on(player, 'fullscreenchange', _this.handleFullscreenChange); 2907 return _this; 2908 } 2909 2910 /** 2911 * Builds the default DOM `className`. 2912 * 2913 * @return {string} 2914 * The DOM `className` for this object. 2915 */ 2916 2917 2918 FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() { 2919 return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this); 2920 }; 2921 2922 /** 2923 * Handles fullscreenchange on the player and change control text accordingly. 2924 * 2925 * @param {EventTarget~Event} [event] 2926 * The {@link Player#fullscreenchange} event that caused this function to be 2927 * called. 2928 * 2929 * @listens Player#fullscreenchange 2930 */ 2931 2932 2933 FullscreenToggle.prototype.handleFullscreenChange = function handleFullscreenChange(event) { 2934 if (this.player_.isFullscreen()) { 2935 this.controlText('Non-Fullscreen'); 2936 } else { 2937 this.controlText('Fullscreen'); 2938 } 2939 }; 2940 2941 /** 2942 * This gets called when an `FullscreenToggle` is "clicked". See 2943 * {@link ClickableComponent} for more detailed information on what a click can be. 2944 * 2945 * @param {EventTarget~Event} [event]
2946 * The `keydown`, `tap`, or `click` event that caused this function to be 2947 * called. 2948 * 2949 * @listens tap 2950 * @listens click 2951 */ 2952 2953 2954 FullscreenToggle.prototype.handleClick = function handleClick(event) { 2955 if (!this.player_.isFullscreen()) { 2956 this.player_.requestFullscreen(); 2957 } else { 2958 this.player_.exitFullscreen(); 2959 } 2960 }; 2961 2962 return FullscreenToggle; 2963}(_button2['default']); 2964 2965/** 2966 * The text that should display over the `FullscreenToggle`s controls. Added for localization. 2967 * 2968 * @type {string} 2969 * @private 2970 */ 2971 2972 2973FullscreenToggle.prototype.controlText_ = 'Fullscreen'; 2974 2975_component2['default'].registerComponent('FullscreenToggle', FullscreenToggle); 2976exports['default'] = FullscreenToggle; 2977 2978},{"2":2,"5":5}],10:[function(_dereq_,module,exports){ 2979'use strict'; 2980 2981exports.__esModule = true; 2982 2983var _component = _dereq_(5); 2984 2985var _component2 = _interopRequireDefault(_component); 2986 2987var _dom = _dereq_(81); 2988 2989var Dom = _interopRequireWildcard(_dom); 2990 2991function _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; } } 2992 2993function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2994 2995function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 2996 2997function _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; } 2998 2999function _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; } /** 3000 * @file live-display.js 3001 */ 3002 3003 3004// TODO - Future make it click to snap to live 3005 3006/** 3007 * Displays the live indicator when duration is Infinity. 3008 * 3009 * @extends Component 3010 */ 3011var LiveDisplay = function (_Component) { 3012 _inherits(LiveDisplay, _Component); 3013 3014 /** 3015 * Creates an instance of this class. 3016 * 3017 * @param {Player} player 3018 * The `Player` that this class should be attached to. 3019 * 3020 * @param {Object} [options] 3021 * The key/value store of player options. 3022 */ 3023 function LiveDisplay(player, options) { 3024 _classCallCheck(this, LiveDisplay); 3025 3026 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 3027 3028 _this.updateShowing(); 3029 _this.on(_this.player(), 'durationchange', _this.updateShowing); 3030 return _this; 3031 } 3032 3033 /** 3034 * Create the `Component`'s DOM element 3035 * 3036 * @return {Element} 3037 * The element that was created. 3038 */ 3039 3040 3041 LiveDisplay.prototype.createEl = function createEl() { 3042 var el = _Component.prototype.createEl.call(this, 'div', { 3043 className: 'vjs-live-control vjs-control' 3044 }); 3045 3046 this.contentEl_ = Dom.createEl('div', { 3047 className: 'vjs-live-display', 3048 innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE') 3049 }, {
3050 'aria-live': 'off' 3051 }); 3052 3053 el.appendChild(this.contentEl_); 3054 return el; 3055 }; 3056 3057 /** 3058 * Check the duration to see if the LiveDisplay should be showing or not. Then show/hide 3059 * it accordingly 3060 * 3061 * @param {EventTarget~Event} [event] 3062 * The {@link Player#durationchange} event that caused this function to run. 3063 * 3064 * @listens Player#durationchange 3065 */ 3066 3067 3068 LiveDisplay.prototype.updateShowing = function updateShowing(event) { 3069 if (this.player().duration() === Infinity) { 3070 this.show(); 3071 } else { 3072 this.hide(); 3073 } 3074 }; 3075 3076 return LiveDisplay; 3077}(_component2['default']); 3078 3079_component2['default'].registerComponent('LiveDisplay', LiveDisplay); 3080exports['default'] = LiveDisplay; 3081 3082},{"5":5,"81":81}],11:[function(_dereq_,module,exports){ 3083'use strict'; 3084 3085exports.__esModule = true; 3086 3087var _button = _dereq_(2); 3088 3089var _button2 = _interopRequireDefault(_button); 3090 3091var _component = _dereq_(5); 3092 3093var _component2 = _interopRequireDefault(_component); 3094 3095var _dom = _dereq_(81); 3096 3097var Dom = _interopRequireWildcard(_dom); 3098 3099function _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; } } 3100 3101function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3102 3103function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 3104 3105function _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; } 3106 3107function _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; } /** 3108 * @file mute-toggle.js 3109 */ 3110 3111 3112/** 3113 * A button component for muting the audio. 3114 * 3115 * @extends Button 3116 */ 3117var MuteToggle = function (_Button) { 3118 _inherits(MuteToggle, _Button); 3119 3120 /** 3121 * Creates an instance of this class. 3122 * 3123 * @param {Player} player 3124 * The `Player` that this class should be attached to. 3125 * 3126 * @param {Object} [options] 3127 * The key/value store of player options. 3128 */ 3129 function MuteToggle(player, options) { 3130 _classCallCheck(this, MuteToggle); 3131 3132 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options)); 3133 3134 _this.on(player, 'volumechange', _this.update); 3135 3136 // hide mute toggle if the current tech doesn't support volume control 3137 if (player.tech_ && player.tech_.featuresVolumeControl === false) { 3138 _this.addClass('vjs-hidden'); 3139 } 3140 3141 _this.on(player, 'loadstart', function () { 3142 // We need to update the button to account for a default muted state. 3143 this.update(); 3144 3145 if (player.tech_.featuresVolumeControl === false) { 3146 this.addClass('vjs-hidden'); 3147 } else { 3148 this.removeClass('vjs-hidden'); 3149 } 3150 }); 3151 return _this; 3152 } 3153 3154 /** 3155 * Builds the default DOM `className`. 3156 * 3157 * @return {string} 3158 * The DOM `className` for this object. 3159 */ 3160 3161 3162 MuteToggle.prototype.buildCSSClass = function buildCSSClass() { 3163 return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this); 3164 }; 3165 3166 /** 3167 * This gets called when an `MuteToggle` is "clicked". See 3168 * {@link ClickableComponent} for more detailed information on what a click can be. 3169 * 3170 * @param {EventTarget~Event} [event]
3171 * The `keydown`, `tap`, or `click` event that caused this function to be 3172 * called. 3173 * 3174 * @listens tap 3175 * @listens click 3176 */ 3177 3178 3179 MuteToggle.prototype.handleClick = function handleClick(event) { 3180 this.player_.muted(this.player_.muted() ? false : true); 3181 }; 3182 3183 /** 3184 * Update the state of volume. 3185 * 3186 * @param {EventTarget~Event} [event] 3187 * The {@link Player#loadstart} event if this function was called through an 3188 * event. 3189 * 3190 * @listens Player#loadstart 3191 */ 3192 3193 3194 MuteToggle.prototype.update = function update(event) { 3195 var vol = this.player_.volume(); 3196 var level = 3; 3197 3198 if (vol === 0 || this.player_.muted()) { 3199 level = 0; 3200 } else if (vol < 0.33) { 3201 level = 1; 3202 } else if (vol < 0.67) { 3203 level = 2; 3204 } 3205 3206 // Don't rewrite the button text if the actual text doesn't change. 3207 // This causes unnecessary and confusing information for screen reader users. 3208 // This check is needed because this function gets called every time the volume level is changed. 3209 var toMute = this.player_.muted() ? 'Unmute' : 'Mute'; 3210 3211 if (this.controlText() !== toMute) { 3212 this.controlText(toMute); 3213 } 3214 3215 // TODO improve muted icon classes 3216 for (var i = 0; i < 4; i++) { 3217 Dom.removeElClass(this.el_, 'vjs-vol-' + i); 3218 } 3219 Dom.addElClass(this.el_, 'vjs-vol-' + level); 3220 }; 3221 3222 return MuteToggle; 3223}(_button2['default']); 3224 3225/** 3226 * The text that should display over the `MuteToggle`s controls. Added for localization. 3227 * 3228 * @type {string} 3229 * @private 3230 */ 3231 3232 3233MuteToggle.prototype.controlText_ = 'Mute'; 3234 3235_component2['default'].registerComponent('MuteToggle', MuteToggle); 3236exports['default'] = MuteToggle; 3237 3238},{"2":2,"5":5,"81":81}],12:[function(_dereq_,module,exports){ 3239'use strict'; 3240 3241exports.__esModule = true; 3242 3243var _button = _dereq_(2); 3244 3245var _button2 = _interopRequireDefault(_button); 3246 3247var _component = _dereq_(5); 3248 3249var _component2 = _interopRequireDefault(_component); 3250 3251function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3252 3253function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 3254 3255function _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; } 3256 3257function _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; } /** 3258 * @file play-toggle.js 3259 */ 3260 3261 3262/** 3263 * Button to toggle between play and pause. 3264 * 3265 * @extends Button 3266 */ 3267var PlayToggle = function (_Button) { 3268 _inherits(PlayToggle, _Button); 3269 3270 /** 3271 * Creates an instance of this class. 3272 * 3273 * @param {Player} player 3274 * The `Player` that this class should be attached to. 3275 * 3276 * @param {Object} [options] 3277 * The key/value store of player options. 3278 */ 3279 function PlayToggle(player, options) { 3280 _classCallCheck(this, PlayToggle); 3281 3282 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options)); 3283 3284 _this.on(player, 'play', _this.handlePlay); 3285 _this.on(player, 'pause', _this.handlePause); 3286 return _this; 3287 } 3288 3289 /** 3290 * Builds the default DOM `className`. 3291 * 3292 * @return {string} 3293 * The DOM `className` for this object. 3294 */ 3295 3296 3297 PlayToggle.prototype.buildCSSClass = function buildCSSClass() { 3298 return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this); 3299 }; 3300 3301 /** 3302 * This gets called when an `PlayToggle` is "clicked". See 3303 * {@link ClickableComponent} for more detailed information on what a click can be. 3304 * 3305 * @param {EventTarget~Event} [event]
3306 * The `keydown`, `tap`, or `click` event that caused this function to be 3307 * called. 3308 * 3309 * @listens tap 3310 * @listens click 3311 */ 3312 3313 3314 PlayToggle.prototype.handleClick = function handleClick(event) { 3315 if (this.player_.paused()) { 3316 this.player_.play(); 3317 } else { 3318 this.player_.pause(); 3319 } 3320 }; 3321 3322 /** 3323 * Add the vjs-playing class to the element so it can change appearance. 3324 * 3325 * @param {EventTarget~Event} [event] 3326 * The event that caused this function to run. 3327 * 3328 * @listens Player#play 3329 */ 3330 3331 3332 PlayToggle.prototype.handlePlay = function handlePlay(event) { 3333 this.removeClass('vjs-paused'); 3334 this.addClass('vjs-playing'); 3335 // change the button text to "Pause" 3336 this.controlText('Pause'); 3337 }; 3338 3339 /** 3340 * Add the vjs-paused class to the element so it can change appearance. 3341 * 3342 * @param {EventTarget~Event} [event] 3343 * The event that caused this function to run. 3344 * 3345 * @listens Player#pause 3346 */ 3347 3348 3349 PlayToggle.prototype.handlePause = function handlePause(event) { 3350 this.removeClass('vjs-playing'); 3351 this.addClass('vjs-paused'); 3352 // change the button text to "Play" 3353 this.controlText('Play'); 3354 }; 3355 3356 return PlayToggle; 3357}(_button2['default']); 3358 3359/** 3360 * The text that should display over the `PlayToggle`s controls. Added for localization. 3361 * 3362 * @type {string} 3363 * @private 3364 */ 3365 3366 3367PlayToggle.prototype.controlText_ = 'Play'; 3368 3369_component2['default'].registerComponent('PlayToggle', PlayToggle); 3370exports['default'] = PlayToggle; 3371 3372},{"2":2,"5":5}],13:[function(_dereq_,module,exports){ 3373'use strict'; 3374 3375exports.__esModule = true; 3376 3377var _menuButton = _dereq_(47); 3378 3379var _menuButton2 = _interopRequireDefault(_menuButton); 3380 3381var _menu = _dereq_(49); 3382 3383var _menu2 = _interopRequireDefault(_menu); 3384 3385var _playbackRateMenuItem = _dereq_(14); 3386 3387var _playbackRateMenuItem2 = _interopRequireDefault(_playbackRateMenuItem); 3388 3389var _component = _dereq_(5); 3390 3391var _component2 = _interopRequireDefault(_component); 3392 3393var _dom = _dereq_(81); 3394 3395var Dom = _interopRequireWildcard(_dom); 3396 3397function _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; } } 3398 3399function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3400 3401function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 3402 3403function _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; } 3404 3405function _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; } /** 3406 * @file playback-rate-menu-button.js 3407 */ 3408 3409 3410/** 3411 * The component for controlling the playback rate. 3412 * 3413 * @extends MenuButton 3414 */ 3415var PlaybackRateMenuButton = function (_MenuButton) { 3416 _inherits(PlaybackRateMenuButton, _MenuButton); 3417 3418 /** 3419 * Creates an instance of this class. 3420 * 3421 * @param {Player} player 3422 * The `Player` that this class should be attached to. 3423 * 3424 * @param {Object} [options] 3425 * The key/value store of player options. 3426 */ 3427 function PlaybackRateMenuButton(player, options) { 3428 _classCallCheck(this, PlaybackRateMenuButton); 3429 3430 var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options)); 3431 3432 _this.updateVisibility(); 3433 _this.updateLabel(); 3434 3435 _this.on(player, 'loadstart', _this.updateVisibility); 3436 _this.on(player, 'ratechange', _this.updateLabel); 3437 return _this; 3438 } 3439 3440 /** 3441 * Create the `Component`'s DOM element 3442 * 3443 * @return {Element} 3444 * The element that was created. 3445 */ 3446 3447 3448 PlaybackRateMenuButton.prototype.createEl = function createEl() { 3449 var el = _MenuButton.prototype.createEl.call(this); 3450 3451 this.labelEl_ = Dom.createEl('div', { 3452 className: 'vjs-playback-rate-value', 3453 innerHTML: 1.0 3454 }); 3455 3456 el.appendChild(this.labelEl_); 3457 3458 return el; 3459 }; 3460 3461 /** 3462 * Builds the default DOM `className`. 3463 * 3464 * @return {string} 3465 * The DOM `className` for this object. 3466 */ 3467 3468 3469 PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() { 3470 return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this); 3471 }; 3472 3473 /** 3474 * Create the playback rate menu 3475 * 3476 * @return {Menu} 3477 * Menu object populated with {@link PlaybackRateMenuItem}s 3478 */ 3479 3480 3481 PlaybackRateMenuButton.prototype.createMenu = function createMenu() { 3482 var menu = new _menu2['default'](this.player()); 3483 var rates = this.playbackRates(); 3484 3485 if (rates) { 3486 for (var i = rates.length - 1; i >= 0; i--) { 3487 menu.addChild(new _playbackRateMenuItem2['default'](this.player(), { rate: rates[i] + 'x' })); 3488 } 3489 } 3490 3491 return menu; 3492 }; 3493 3494 /** 3495 * Updates ARIA accessibility attributes 3496 */ 3497 3498 3499 PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() { 3500 // Current playback rate 3501 this.el().setAttribute('aria-valuenow', this.player().playbackRate()); 3502 }; 3503 3504 /** 3505 * This gets called when an `PlaybackRateMenuButton` is "clicked". See 3506 * {@link ClickableComponent} for more detailed information on what a click can be. 3507 * 3508 * @param {EventTarget~Event} [event]
vendor: 6,098 bytes, lines 3509-3673
3509 * The `keydown`, `tap`, or `click` event that caused this function to be 3510 * called. 3511 * 3512 * @listens tap 3513 * @listens click 3514 */ 3515 3516 3517 PlaybackRateMenuButton.prototype.handleClick = function handleClick(event) { 3518 // select next rate option 3519 var currentRate = this.player().playbackRate(); 3520 var rates = this.playbackRates(); 3521 3522 // this will select first one if the last one currently selected 3523 var newRate = rates[0]; 3524 3525 for (var i = 0; i < rates.length; i++) { 3526 if (rates[i] > currentRate) { 3527 newRate = rates[i]; 3528 break; 3529 } 3530 } 3531 this.player().playbackRate(newRate); 3532 }; 3533 3534 /** 3535 * Get possible playback rates 3536 * 3537 * @return {Array} 3538 * All possible playback rates 3539 */ 3540 3541 3542 PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() { 3543 return this.options_.playbackRates || this.options_.playerOptions && this.options_.playerOptions.playbackRates; 3544 }; 3545 3546 /** 3547 * Get whether playback rates is supported by the tech 3548 * and an array of playback rates exists 3549 * 3550 * @return {boolean} 3551 * Whether changing playback rate is supported 3552 */ 3553 3554 3555 PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() { 3556 return this.player().tech_ && this.player().tech_.featuresPlaybackRate && this.playbackRates() && this.playbackRates().length > 0; 3557 }; 3558 3559 /** 3560 * Hide playback rate controls when they're no playback rate options to select 3561 * 3562 * @param {EventTarget~Event} [event] 3563 * The event that caused this function to run. 3564 * 3565 * @listens Player#loadstart 3566 */ 3567 3568 3569 PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility(event) { 3570 if (this.playbackRateSupported()) { 3571 this.removeClass('vjs-hidden'); 3572 } else { 3573 this.addClass('vjs-hidden'); 3574 } 3575 }; 3576 3577 /** 3578 * Update button label when rate changed 3579 * 3580 * @param {EventTarget~Event} [event] 3581 * The event that caused this function to run. 3582 * 3583 * @listens Player#ratechange 3584 */ 3585 3586 3587 PlaybackRateMenuButton.prototype.updateLabel = function updateLabel(event) { 3588 if (this.playbackRateSupported()) { 3589 this.labelEl_.innerHTML = this.player().playbackRate() + 'x'; 3590 } 3591 }; 3592 3593 return PlaybackRateMenuButton; 3594}(_menuButton2['default']); 3595 3596/** 3597 * The text that should display over the `FullscreenToggle`s controls. Added for localization. 3598 * 3599 * @type {string} 3600 * @private 3601 */ 3602 3603 3604PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate'; 3605 3606_component2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton); 3607exports['default'] = PlaybackRateMenuButton; 3608 3609},{"14":14,"47":47,"49":49,"5":5,"81":81}],14:[function(_dereq_,module,exports){ 3610'use strict'; 3611 3612exports.__esModule = true; 3613 3614var _menuItem = _dereq_(48); 3615 3616var _menuItem2 = _interopRequireDefault(_menuItem); 3617 3618var _component = _dereq_(5); 3619 3620var _component2 = _interopRequireDefault(_component); 3621 3622function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3623 3624function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 3625 3626function _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; } 3627 3628function _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; } /** 3629 * @file playback-rate-menu-item.js 3630 */ 3631 3632 3633/** 3634 * The specific menu item type for selecting a playback rate. 3635 * 3636 * @extends MenuItem 3637 */ 3638var PlaybackRateMenuItem = function (_MenuItem) { 3639 _inherits(PlaybackRateMenuItem, _MenuItem); 3640 3641 /** 3642 * Creates an instance of this class. 3643 * 3644 * @param {Player} player 3645 * The `Player` that this class should be attached to. 3646 * 3647 * @param {Object} [options] 3648 * The key/value store of player options. 3649 */ 3650 function PlaybackRateMenuItem(player, options) { 3651 _classCallCheck(this, PlaybackRateMenuItem); 3652 3653 var label = options.rate; 3654 var rate = parseFloat(label, 10); 3655 3656 // Modify options for parent MenuItem class's init. 3657 options.label = label; 3658 options.selected = rate === 1; 3659 3660 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options)); 3661 3662 _this.label = label; 3663 _this.rate = rate; 3664 3665 _this.on(player, 'ratechange', _this.update); 3666 return _this; 3667 } 3668 3669 /** 3670 * This gets called when an `PlaybackRateMenuItem` is "clicked". See 3671 * {@link ClickableComponent} for more detailed information on what a click can be. 3672 * 3673 * @param {EventTarget~Event} [event]
3674 * The `keydown`, `tap`, or `click` event that caused this function to be 3675 * called. 3676 * 3677 * @listens tap 3678 * @listens click 3679 */ 3680 3681 3682 PlaybackRateMenuItem.prototype.handleClick = function handleClick(event) { 3683 _MenuItem.prototype.handleClick.call(this); 3684 this.player().playbackRate(this.rate); 3685 }; 3686 3687 /** 3688 * Update the PlaybackRateMenuItem when the playbackrate changes. 3689 * 3690 * @param {EventTarget~Event} [event] 3691 * The `ratechange` event that caused this function to run. 3692 * 3693 * @listens Player#ratechange 3694 */ 3695 3696 3697 PlaybackRateMenuItem.prototype.update = function update(event) { 3698 this.selected(this.player().playbackRate() === this.rate); 3699 }; 3700 3701 return PlaybackRateMenuItem; 3702}(_menuItem2['default']); 3703 3704/** 3705 * The text that should display over the `PlaybackRateMenuItem`s controls. Added for localization. 3706 * 3707 * @type {string} 3708 * @private 3709 */ 3710 3711 3712PlaybackRateMenuItem.prototype.contentElType = 'button'; 3713 3714_component2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem); 3715exports['default'] = PlaybackRateMenuItem; 3716 3717},{"48":48,"5":5}],15:[function(_dereq_,module,exports){ 3718'use strict'; 3719 3720exports.__esModule = true; 3721 3722var _component = _dereq_(5); 3723 3724var _component2 = _interopRequireDefault(_component); 3725 3726var _dom = _dereq_(81); 3727 3728var Dom = _interopRequireWildcard(_dom); 3729 3730function _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; } } 3731 3732function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3733 3734function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 3735 3736function _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; } 3737 3738function _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; } /** 3739 * @file load-progress-bar.js 3740 */ 3741 3742 3743/** 3744 * Shows loading progress 3745 * 3746 * @extends Component 3747 */ 3748var LoadProgressBar = function (_Component) { 3749 _inherits(LoadProgressBar, _Component); 3750 3751 /** 3752 * Creates an instance of this class. 3753 * 3754 * @param {Player} player 3755 * The `Player` that this class should be attached to. 3756 * 3757 * @param {Object} [options] 3758 * The key/value store of player options. 3759 */ 3760 function LoadProgressBar(player, options) { 3761 _classCallCheck(this, LoadProgressBar); 3762 3763 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 3764 3765 _this.partEls_ = []; 3766 _this.on(player, 'progress', _this.update); 3767 return _this; 3768 } 3769 3770 /** 3771 * Create the `Component`'s DOM element 3772 * 3773 * @return {Element} 3774 * The element that was created. 3775 */ 3776 3777 3778 LoadProgressBar.prototype.createEl = function createEl() { 3779 return _Component.prototype.createEl.call(this, 'div', { 3780 className: 'vjs-load-progress', 3781 innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>' 3782 }); 3783 }; 3784 3785 /** 3786 * Update progress bar 3787 * 3788 * @param {EventTarget~Event} [event] 3789 * The `progress` event that caused this function to run. 3790 * 3791 * @listens Player#progress 3792 */ 3793 3794 3795 LoadProgressBar.prototype.update = function update(event) { 3796 var buffered = this.player_.buffered(); 3797 var duration = this.player_.duration(); 3798 var bufferedEnd = this.player_.bufferedEnd(); 3799 var children = this.partEls_; 3800 3801 // get the percent width of a time compared to the total end 3802 var percentify = function percentify(time, end) { 3803 // no NaN 3804 var percent = time / end || 0; 3805 3806 return (percent >= 1 ? 1 : percent) * 100 + '%'; 3807 }; 3808 3809 // update the width of the progress bar 3810 this.el_.style.width = percentify(bufferedEnd, duration); 3811 3812 // add child elements to represent the individual buffered time ranges 3813 for (var i = 0; i < buffered.length; i++) { 3814 var start = buffered.start(i); 3815 var end = buffered.end(i); 3816 var part = children[i]; 3817 3818 if (!part) { 3819 part = this.el_.appendChild(Dom.createEl()); 3820 children[i] = part;
3821 } 3822 3823 // set the percent based on the width of the progress bar (bufferedEnd) 3824 part.style.left = percentify(start, bufferedEnd); 3825 part.style.width = percentify(end - start, bufferedEnd); 3826 } 3827 3828 // remove unused buffered range elements 3829 for (var _i = children.length; _i > buffered.length; _i--) { 3830 this.el_.removeChild(children[_i - 1]); 3831 } 3832 children.length = buffered.length; 3833 }; 3834 3835 return LoadProgressBar; 3836}(_component2['default']); 3837 3838_component2['default'].registerComponent('LoadProgressBar', LoadProgressBar); 3839exports['default'] = LoadProgressBar; 3840 3841},{"5":5,"81":81}],16:[function(_dereq_,module,exports){ 3842'use strict'; 3843 3844exports.__esModule = true; 3845 3846var _component = _dereq_(5); 3847 3848var _component2 = _interopRequireDefault(_component); 3849 3850var _dom = _dereq_(81); 3851 3852var Dom = _interopRequireWildcard(_dom); 3853 3854var _fn = _dereq_(83); 3855 3856var Fn = _interopRequireWildcard(_fn); 3857 3858var _formatTime = _dereq_(84); 3859 3860var _formatTime2 = _interopRequireDefault(_formatTime); 3861 3862var _computedStyle = _dereq_(80); 3863 3864var _computedStyle2 = _interopRequireDefault(_computedStyle); 3865 3866function _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; } } 3867 3868function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3869 3870function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 3871 3872function _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; } 3873 3874function _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; } /** 3875 * @file mouse-time-display.js 3876 */ 3877 3878 3879/** 3880 * The Mouse Time Display component shows the time you will seek to 3881 * when hovering over the progress bar 3882 * 3883 * @extends Component 3884 */ 3885var MouseTimeDisplay = function (_Component) { 3886 _inherits(MouseTimeDisplay, _Component); 3887 3888 /** 3889 * Creates an instance of this class. 3890 * 3891 * @param {Player} player 3892 * The `Player` that this class should be attached to. 3893 * 3894 * @param {Object} [options] 3895 * The key/value store of player options. 3896 */ 3897 function MouseTimeDisplay(player, options) { 3898 _classCallCheck(this, MouseTimeDisplay); 3899 3900 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 3901 3902 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) { 3903 _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside; 3904 } 3905 3906 if (_this.keepTooltipsInside) { 3907 _this.tooltip = Dom.createEl('div', { className: 'vjs-time-tooltip' }); 3908 _this.el().appendChild(_this.tooltip); 3909 _this.addClass('vjs-keep-tooltips-inside'); 3910 } 3911 3912 _this.update(0, 0); 3913 3914 player.on('ready', function () { 3915 _this.on(player.controlBar.progressControl.el(), 'mousemove', Fn.throttle(Fn.bind(_this, _this.handleMouseMove), 25)); 3916 }); 3917 return _this; 3918 } 3919 3920 /** 3921 * Create the `Component`'s DOM element 3922 * 3923 * @return {Element} 3924 * The element that was created. 3925 */ 3926 3927 3928 MouseTimeDisplay.prototype.createEl = function createEl() { 3929 return _Component.prototype.createEl.call(this, 'div', { 3930 className: 'vjs-mouse-display' 3931 }); 3932 }; 3933 3934 /** 3935 * Handle the mouse move event on the `MouseTimeDisplay`. 3936 * 3937 * @param {EventTarget~Event} event 3938 * The `mousemove` event that caused this to event to run. 3939 * 3940 * @listen mousemove 3941 */ 3942 3943 3944 MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) { 3945 var duration = this.player_.duration(); 3946 var newTime = this.calculateDistance(event) * duration; 3947 var position = event.pageX - Dom.findElPosition(this.el().parentNode).left; 3948 3949 this.update(newTime, position); 3950 }; 3951 3952 /** 3953 * Update the time and posistion of the `MouseTimeDisplay`. 3954 * 3955 * @param {number} newTime 3956 * Time to change the `MouseTimeDisplay` to. 3957 * 3958 * @param {nubmer} position 3959 * Postion from the left of the in pixels. 3960 */ 3961 3962 3963 MouseTimeDisplay.prototype.update = function update(newTime, position) { 3964 var time = (0, _formatTime2['default'])(newTime, this.player_.duration()); 3965 3966 this.el().style.left = position + 'px'; 3967 this.el().setAttribute('data-current-time', time); 3968 3969 if (this.keepTooltipsInside) { 3970 var clampedPosition = this.clampPosition_(position); 3971 var difference = position - clampedPosition + 1; 3972 var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width')); 3973 var tooltipWidthHalf = tooltipWidth / 2; 3974 3975 this.tooltip.innerHTML = time; 3976 this.tooltip.style.right = '-' + (tooltipWidthHalf - difference) + 'px'; 3977 } 3978 }; 3979 3980 /** 3981 * Get the mouse pointers x coordinate in pixels. 3982 * 3983 * @param {EventTarget~Event} [event] 3984 * The `mousemove` event that was passed to this function by 3985 * {@link MouseTimeDisplay#handleMouseMove} 3986 * 3987 * @return {number} 3988 * THe x position in pixels of the mouse pointer. 3989 */ 3990 3991 3992 MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) { 3993 return Dom.getPointerPosition(this.el().parentNode, event).x; 3994 }; 3995 3996 /** 3997 * This takes in a horizontal position for the bar and returns a clamped position. 3998 * Clamped position means that it will keep the position greater than half the width 3999 * of the tooltip and smaller than the player width minus half the width o the tooltip. 4000 * It will only clamp the position if `keepTooltipsInside` option is set. 4001 * 4002 * @param {number} position 4003 * The position the bar wants to be 4004 * 4005 * @return {number} 4006 * The (potentially) new clamped position. 4007 * 4008 * @private 4009 */ 4010 4011 4012 MouseTimeDisplay.prototype.clampPosition_ = function clampPosition_(position) { 4013 if (!this.keepTooltipsInside) { 4014 return position; 4015 } 4016 4017 var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width')); 4018 var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width')); 4019 var tooltipWidthHalf = tooltipWidth / 2; 4020 var actualPosition = position; 4021 4022 if (position < tooltipWidthHalf) { 4023 actualPosition = Math.ceil(tooltipWidthHalf); 4024 } else if (position > playerWidth - tooltipWidthHalf) { 4025 actualPosition = Math.floor(playerWidth - tooltipWidthHalf); 4026 } 4027 4028 return actualPosition; 4029 }; 4030 4031 return MouseTimeDisplay; 4032}(_component2['default']); 4033 4034_component2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay); 4035exports['default'] = MouseTimeDisplay; 4036 4037},{"5":5,"80":80,"81":81,"83":83,"84":84}],17:[function(_dereq_,module,exports){ 4038'use strict'; 4039 4040exports.__esModule = true; 4041 4042var _component = _dereq_(5); 4043 4044var _component2 = _interopRequireDefault(_component); 4045 4046var _fn = _dereq_(83); 4047 4048var Fn = _interopRequireWildcard(_fn); 4049 4050var _formatTime = _dereq_(84); 4051 4052var _formatTime2 = _interopRequireDefault(_formatTime); 4053 4054function _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; } } 4055 4056function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4057 4058function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4059 4060function _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; } 4061 4062function _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
4062onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4063 * @file play-progress-bar.js 4064 */ 4065 4066 4067/** 4068 * Shows play progress 4069 * 4070 * @extends Component 4071 */ 4072var PlayProgressBar = function (_Component) { 4073 _inherits(PlayProgressBar, _Component); 4074 4075 /** 4076 * Creates an instance of this class. 4077 * 4078 * @param {Player} player 4079 * The `Player` that this class should be attached to. 4080 * 4081 * @param {Object} [options] 4082 * The key/value store of player options. 4083 */ 4084 function PlayProgressBar(player, options) { 4085 _classCallCheck(this, PlayProgressBar); 4086 4087 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 4088 4089 _this.updateDataAttr(); 4090 _this.on(player, 'timeupdate', _this.updateDataAttr); 4091 player.ready(Fn.bind(_this, _this.updateDataAttr)); 4092 4093 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) { 4094 _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside; 4095 } 4096 4097 if (_this.keepTooltipsInside) { 4098 _this.addClass('vjs-keep-tooltips-inside'); 4099 } 4100 return _this; 4101 } 4102 4103 /** 4104 * Create the `Component`'s DOM element 4105 * 4106 * @return {Element} 4107 * The element that was created. 4108 */ 4109 4110 4111 PlayProgressBar.prototype.createEl = function createEl() { 4112 return _Component.prototype.createEl.call(this, 'div', { 4113 className: 'vjs-play-progress vjs-slider-bar', 4114 innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>' 4115 }); 4116 }; 4117 4118 /** 4119 * Update the data-current-time attribute on the `PlayProgressBar`. 4120 * 4121 * @param {EventTarget~Event} [event] 4122 * The `timeupdate` event that caused this to run. 4123 * 4124 * @listens Player#timeupdate 4125 */ 4126 4127 4128 PlayProgressBar.prototype.updateDataAttr = function updateDataAttr(event) { 4129 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 4130 4131 this.el_.setAttribute('data-current-time', (0, _formatTime2['default'])(time, this.player_.duration())); 4132 }; 4133 4134 return PlayProgressBar; 4135}(_component2['default']); 4136 4137_component2['default'].registerComponent('PlayProgressBar', PlayProgressBar); 4138exports['default'] = PlayProgressBar; 4139 4140},{"5":5,"83":83,"84":84}],18:[function(_dereq_,module,exports){ 4141'use strict'; 4142 4143exports.__esModule = true; 4144 4145var _component = _dereq_(5); 4146 4147var _component2 = _interopRequireDefault(_component); 4148 4149_dereq_(19); 4150 4151_dereq_(16); 4152 4153function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4154 4155function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4156 4157function _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; } 4158 4159function _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
4159onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4160 * @file progress-control.js 4161 */ 4162 4163 4164/** 4165 * The Progress Control component contains the seek bar, load progress, 4166 * and play progress. 4167 * 4168 * @extends Component 4169 */ 4170var ProgressControl = function (_Component) { 4171 _inherits(ProgressControl, _Component); 4172 4173 function ProgressControl() { 4174 _classCallCheck(this, ProgressControl); 4175 4176 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 4177 } 4178 4179 /** 4180 * Create the `Component`'s DOM element 4181 * 4182 * @return {Element} 4183 * The element that was created. 4184 */ 4185 ProgressControl.prototype.createEl = function createEl() { 4186 return _Component.prototype.createEl.call(this, 'div', { 4187 className: 'vjs-progress-control vjs-control' 4188 }); 4189 }; 4190 4191 return ProgressControl; 4192}(_component2['default']); 4193 4194/** 4195 * Default options for `ProgressControl` 4196 * 4197 * @type {Object} 4198 * @private 4199 */ 4200 4201 4202ProgressControl.prototype.options_ = { 4203 children: ['seekBar'] 4204}; 4205 4206_component2['default'].registerComponent('ProgressControl', ProgressControl); 4207exports['default'] = ProgressControl; 4208 4209},{"16":16,"19":19,"5":5}],19:[function(_dereq_,module,exports){ 4210'use strict'; 4211 4212exports.__esModule = true; 4213 4214var _slider = _dereq_(57); 4215 4216var _slider2 = _interopRequireDefault(_slider); 4217 4218var _component = _dereq_(5); 4219 4220var _component2 = _interopRequireDefault(_component); 4221 4222var _fn = _dereq_(83); 4223 4224var Fn = _interopRequireWildcard(_fn); 4225 4226var _formatTime = _dereq_(84); 4227 4228var _formatTime2 = _interopRequireDefault(_formatTime); 4229 4230var _computedStyle = _dereq_(80); 4231 4232var _computedStyle2 = _interopRequireDefault(_computedStyle); 4233 4234_dereq_(15); 4235 4236_dereq_(17); 4237 4238_dereq_(20); 4239 4240function _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; } } 4241 4242function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4243 4244function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4245 4246function _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; } 4247 4248function _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; } /** 4249 * @file seek-bar.js 4250 */ 4251 4252 4253/** 4254 * Seek Bar and holder for the progress bars 4255 * 4256 * @extends Slider 4257 */
4258var SeekBar = function (_Slider) { 4259 _inherits(SeekBar, _Slider); 4260 4261 /** 4262 * Creates an instance of this class. 4263 * 4264 * @param {Player} player 4265 * The `Player` that this class should be attached to. 4266 * 4267 * @param {Object} [options] 4268 * The key/value store of player options. 4269 */ 4270 function SeekBar(player, options) { 4271 _classCallCheck(this, SeekBar); 4272 4273 var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options)); 4274 4275 _this.on(player, 'timeupdate', _this.updateProgress); 4276 _this.on(player, 'ended', _this.updateProgress); 4277 player.ready(Fn.bind(_this, _this.updateProgress)); 4278 4279 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) { 4280 _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside; 4281 } 4282 4283 if (_this.keepTooltipsInside) { 4284 _this.tooltipProgressBar = _this.addChild('TooltipProgressBar'); 4285 } 4286 return _this; 4287 } 4288 4289 /** 4290 * Create the `Component`'s DOM element 4291 * 4292 * @return {Element} 4293 * The element that was created. 4294 */ 4295 4296 4297 SeekBar.prototype.createEl = function createEl() { 4298 return _Slider.prototype.createEl.call(this, 'div', { 4299 className: 'vjs-progress-holder' 4300 }, { 4301 'aria-label': 'progress bar' 4302 }); 4303 }; 4304 4305 /** 4306 * Update the seek bars tooltip and width. 4307 * 4308 * @param {EventTarget~Event} [event] 4309 * The `timeupdate` or `ended` event that caused this to run. 4310 * 4311 * @listens Player#timeupdate 4312 * @listens Player#ended 4313 */ 4314 4315 4316 SeekBar.prototype.updateProgress = function updateProgress(event) { 4317 this.updateAriaAttributes(this.el_); 4318 4319 if (this.keepTooltipsInside) { 4320 this.updateAriaAttributes(this.tooltipProgressBar.el_); 4321 this.tooltipProgressBar.el_.style.width = this.bar.el_.style.width; 4322 4323 var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width')); 4324 var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltipProgressBar.tooltip, 'width')); 4325 var tooltipStyle = this.tooltipProgressBar.el().style; 4326 4327 tooltipStyle.maxWidth = Math.floor(playerWidth - tooltipWidth / 2) + 'px'; 4328 tooltipStyle.minWidth = Math.ceil(tooltipWidth / 2) + 'px'; 4329 tooltipStyle.right = '-' + tooltipWidth / 2 + 'px'; 4330 } 4331 }; 4332 4333 /** 4334 * Update ARIA accessibility attributes 4335 * 4336 * @param {Element} el 4337 * The element to update with aria accessibility attributes. 4338 */ 4339 4340 4341 SeekBar.prototype.updateAriaAttributes = function updateAriaAttributes(el) { 4342 // Allows for smooth scrubbing, when player can't keep up. 4343 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 4344 4345 // machine readable value of progress bar (percentage complete) 4346 el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2)); 4347 // human readable value of progress bar (time complete) 4348 el.setAttribute('aria-valuetext', (0, _formatTime2['default'])(time, this.player_.duration())); 4349 }; 4350 4351 /** 4352 * Get percentage of video played 4353 * 4354 * @return {number} 4355 * The percentage played 4356 */ 4357 4358 4359 SeekBar.prototype.getPercent = function getPercent() { 4360 var percent = this.player_.currentTime() / this.player_.duration(); 4361 4362 return percent >= 1 ? 1 : percent; 4363 }; 4364 4365 /** 4366 * Handle mouse down on seek bar 4367 * 4368 * @param {EventTarget~Event} event 4369 * The `mousedown` event that caused this to run. 4370 * 4371 * @listens mousedown 4372 */ 4373 4374 4375 SeekBar.prototype.handleMouseDown = function handleMouseDown(event) { 4376 this.player_.scrubbing(true); 4377 4378 this.videoWasPlaying = !this.player_.paused(); 4379 this.player_.pause(); 4380 4381 _Slider.prototype.handleMouseDown.call(this, event); 4382 }; 4383 4384 /** 4385 * Handle mouse move on seek bar 4386 * 4387 * @param {EventTarget~Event} event 4388 * The `mousemove` event that caused this to run. 4389 * 4390 * @listens mousemove 4391 */ 4392 4393 4394 SeekBar.prototype.handleMouseMove = function handleMouseMove(event) { 4395 var newTime = this.calculateDistance(event) * this.player_.duration(); 4396 4397 // Don't let video end while scrubbing. 4398 if (newTime === this.player_.duration()) { 4399 newTime = newTime - 0.1; 4400 } 4401 4402 // Set new time (tell player to seek to new time) 4403 this.player_.currentTime(newTime); 4404 }; 4405 4406 /** 4407 * Handle mouse up on seek bar 4408 * 4409 * @param {EventTarget~Event} event 4410 * The `mouseup` event that caused this to run. 4411 * 4412 * @listens mouseup 4413 */ 4414 4415 4416 SeekBar.prototype.handleMouseUp = function handleMouseUp(event) { 4417 _Slider.prototype.handleMouseUp.call(this, event); 4418 4419 this.player_.scrubbing(false); 4420 if (this.videoWasPlaying) { 4421 this.player_.play(); 4422 } 4423 }; 4424 4425 /** 4426 * Move more quickly fast forward for keyboard-only users 4427 */ 4428 4429 4430 SeekBar.prototype.stepForward = function stepForward() { 4431 // more quickly fast forward for keyboard-only users 4432 this.player_.currentTime(this.player_.currentTime() + 5); 4433 }; 4434 4435 /** 4436 * Move more quickly rewind for keyboard-only users 4437 */ 4438 4439 4440 SeekBar.prototype.stepBack = function stepBack() { 4441 // more quickly rewind for keyboard-only users 4442 this.player_.currentTime(this.player_.currentTime() - 5); 4443 }; 4444 4445 return SeekBar; 4446}(_slider2['default']); 4447 4448/** 4449 * Default options for the `SeekBar` 4450 * 4451 * @type {Object} 4452 * @private 4453 */ 4454 4455 4456SeekBar.prototype.options_ = { 4457 children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'], 4458 barName: 'playProgressBar' 4459}; 4460 4461/** 4462 * Call the update event for this Slider when this event happens on the player. 4463 * 4464 * @type {string} 4465 */ 4466SeekBar.prototype.playerEvent = 'timeupdate'; 4467 4468_component2['default'].registerComponent('SeekBar', SeekBar); 4469exports['default'] = SeekBar; 4470 4471},{"15":15,"17":17,"20":20,"5":5,"57":57,"80":80,"83":83,"84":84}],20:[function(_dereq_,module,exports){ 4472'use strict'; 4473 4474exports.__esModule = true; 4475 4476var _component = _dereq_(5); 4477 4478var _component2 = _interopRequireDefault(_component); 4479 4480var _fn = _dereq_(83); 4481 4482var Fn = _interopRequireWildcard(_fn); 4483 4484var _formatTime = _dereq_(84); 4485 4486var _formatTime2 = _interopRequireDefault(_formatTime); 4487 4488function _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; } } 4489 4490function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4491 4492function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4493 4494function _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; } 4495 4496function _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
4496onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4497 * @file play-progress-bar.js 4498 */ 4499 4500 4501/** 4502 * Shows play progress 4503 * 4504 * @extends Component 4505 */ 4506var TooltipProgressBar = function (_Component) { 4507 _inherits(TooltipProgressBar, _Component); 4508 4509 /** 4510 * Creates an instance of this class. 4511 * 4512 * @param {Player} player 4513 * The `Player` that this class should be attached to. 4514 * 4515 * @param {Object} [options] 4516 * The key/value store of player options. 4517 */ 4518 function TooltipProgressBar(player, options) { 4519 _classCallCheck(this, TooltipProgressBar); 4520 4521 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 4522 4523 _this.updateDataAttr(); 4524 _this.on(player, 'timeupdate', _this.updateDataAttr); 4525 player.ready(Fn.bind(_this, _this.updateDataAttr)); 4526 return _this; 4527 } 4528 4529 /** 4530 * Create the `Component`'s DOM element 4531 * 4532 * @return {Element} 4533 * The element that was created. 4534 */ 4535 4536 4537 TooltipProgressBar.prototype.createEl = function createEl() { 4538 var el = _Component.prototype.createEl.call(this, 'div', { 4539 className: 'vjs-tooltip-progress-bar vjs-slider-bar', 4540 innerHTML: '<div class="vjs-time-tooltip"></div>\n <span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>' 4541 }); 4542 4543 this.tooltip = el.querySelector('.vjs-time-tooltip'); 4544 4545 return el; 4546 }; 4547 4548 /** 4549 * Updatet the data-current-time attribute for TooltipProgressBar 4550 * 4551 * @param {EventTarget~Event} [event] 4552 * The `timeupdate` event that caused this function to run. 4553 * 4554 * @listens Player#timeupdate 4555 */ 4556 4557 4558 TooltipProgressBar.prototype.updateDataAttr = function updateDataAttr(event) { 4559 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 4560 var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration()); 4561 4562 this.el_.setAttribute('data-current-time', formattedTime); 4563 this.tooltip.innerHTML = formattedTime; 4564 }; 4565 4566 return TooltipProgressBar; 4567}(_component2['default']); 4568 4569_component2['default'].registerComponent('TooltipProgressBar', TooltipProgressBar); 4570exports['default'] = TooltipProgressBar; 4571 4572},{"5":5,"83":83,"84":84}],21:[function(_dereq_,module,exports){ 4573'use strict'; 4574 4575exports.__esModule = true; 4576 4577var _spacer = _dereq_(22); 4578 4579var _spacer2 = _interopRequireDefault(_spacer); 4580 4581var _component = _dereq_(5); 4582 4583var _component2 = _interopRequireDefault(_component); 4584 4585function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4586 4587function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4588 4589function _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; } 4590 4591function _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
4591onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4592 * @file custom-control-spacer.js 4593 */ 4594 4595 4596/** 4597 * Spacer specifically meant to be used as an insertion point for new plugins, etc. 4598 * 4599 * @extends Spacer 4600 */ 4601var CustomControlSpacer = function (_Spacer) { 4602 _inherits(CustomControlSpacer, _Spacer); 4603 4604 function CustomControlSpacer() { 4605 _classCallCheck(this, CustomControlSpacer); 4606 4607 return _possibleConstructorReturn(this, _Spacer.apply(this, arguments)); 4608 } 4609 4610 /** 4611 * Builds the default DOM `className`. 4612 * 4613 * @return {string} 4614 * The DOM `className` for this object. 4615 */ 4616 CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() { 4617 return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this); 4618 }; 4619 4620 /** 4621 * Create the `Component`'s DOM element 4622 * 4623 * @return {Element} 4624 * The element that was created. 4625 */ 4626 4627 4628 CustomControlSpacer.prototype.createEl = function createEl() { 4629 var el = _Spacer.prototype.createEl.call(this, { 4630 className: this.buildCSSClass() 4631 }); 4632 4633 // No-flex/table-cell mode requires there be some content 4634 // in the cell to fill the remaining space of the table. 4635 el.innerHTML = ' '; 4636 return el; 4637 }; 4638 4639 return CustomControlSpacer; 4640}(_spacer2['default']); 4641 4642_component2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer); 4643exports['default'] = CustomControlSpacer; 4644 4645},{"22":22,"5":5}],22:[function(_dereq_,module,exports){ 4646'use strict'; 4647 4648exports.__esModule = true; 4649 4650var _component = _dereq_(5); 4651 4652var _component2 = _interopRequireDefault(_component); 4653 4654function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4655 4656function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4657 4658function _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; } 4659 4660function _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; } /** 4661 * @file spacer.js 4662 */ 4663 4664 4665/** 4666 * Just an empty spacer element that can be used as an append point for plugins, etc. 4667 * Also can be used to create space between elements when necessary. 4668 * 4669 * @extends Component 4670 */ 4671var Spacer = function (_Component) { 4672 _inherits(Spacer, _Component); 4673 4674 function Spacer() { 4675 _classCallCheck(this, Spacer); 4676 4677 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 4678 } 4679 4680 /** 4681 * Builds the default DOM `className`. 4682 * 4683 * @return {string} 4684 * The DOM `className` for this object. 4685 */ 4686 Spacer.prototype.buildCSSClass = function buildCSSClass() { 4687 return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this); 4688 }; 4689 4690 /** 4691 * Create the `Component`'s DOM element 4692 * 4693 * @return {Element} 4694 * The element that was created. 4695 */ 4696 4697 4698 Spacer.prototype.createEl = function createEl() { 4699 return _Component.prototype.createEl.call(this, 'div', { 4700 className: this.buildCSSClass() 4701 }); 4702 }; 4703 4704 return Spacer; 4705}(_component2['default']); 4706 4707_component2['default'].registerComponent('Spacer', Spacer); 4708 4709exports['default'] = Spacer; 4710 4711},{"5":5}],23:[function(_dereq_,module,exports){ 4712'use strict'; 4713 4714exports.__esModule = true; 4715 4716var _textTrackMenuItem = _dereq_(31); 4717 4718var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem); 4719 4720var _component = _dereq_(5); 4721 4722var _component2 = _interopRequireDefault(_component); 4723 4724function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4725 4726function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4727 4728function _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; } 4729 4730function _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
4730onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4731 * @file caption-settings-menu-item.js 4732 */ 4733 4734 4735/** 4736 * The menu item for caption track settings menu 4737 * 4738 * @extends TextTrackMenuItem 4739 */ 4740var CaptionSettingsMenuItem = function (_TextTrackMenuItem) { 4741 _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem); 4742 4743 /** 4744 * Creates an instance of this class. 4745 * 4746 * @param {Player} player 4747 * The `Player` that this class should be attached to. 4748 * 4749 * @param {Object} [options] 4750 * The key/value store of player options. 4751 */ 4752 function CaptionSettingsMenuItem(player, options) { 4753 _classCallCheck(this, CaptionSettingsMenuItem); 4754 4755 options.track = { 4756 player: player, 4757 kind: options.kind, 4758 label: options.kind + ' settings', 4759 selectable: false, 4760 'default': false, 4761 mode: 'disabled' 4762 }; 4763 4764 // CaptionSettingsMenuItem has no concept of 'selected' 4765 options.selectable = false; 4766 4767 var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options)); 4768 4769 _this.addClass('vjs-texttrack-settings'); 4770 _this.controlText(', opens ' + options.kind + ' settings dialog'); 4771 return _this; 4772 } 4773 4774 /** 4775 * This gets called when an `CaptionSettingsMenuItem` is "clicked". See 4776 * {@link ClickableComponent} for more detailed information on what a click can be. 4777 * 4778 * @param {EventTarget~Event} [event] 4779 * The `keydown`, `tap`, or `click` event that caused this function to be 4780 * called. 4781 * 4782 * @listens tap 4783 * @listens click 4784 */ 4785 4786 4787 CaptionSettingsMenuItem.prototype.handleClick = function handleClick(event) { 4788 this.player().getChild('textTrackSettings').show(); 4789 this.player().getChild('textTrackSettings').el_.focus(); 4790 }; 4791 4792 return CaptionSettingsMenuItem; 4793}(_textTrackMenuItem2['default']); 4794 4795_component2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem); 4796exports['default'] = CaptionSettingsMenuItem; 4797 4798},{"31":31,"5":5}],24:[function(_dereq_,module,exports){ 4799'use strict'; 4800 4801exports.__esModule = true; 4802 4803var _textTrackButton = _dereq_(30); 4804 4805var _textTrackButton2 = _interopRequireDefault(_textTrackButton); 4806 4807var _component = _dereq_(5); 4808 4809var _component2 = _interopRequireDefault(_component); 4810 4811var _captionSettingsMenuItem = _dereq_(23); 4812 4813var _captionSettingsMenuItem2 = _interopRequireDefault(_captionSettingsMenuItem); 4814 4815function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4816 4817function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4818 4819function _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; } 4820 4821function _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
4821onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4822 * @file captions-button.js 4823 */ 4824 4825 4826/** 4827 * The button component for toggling and selecting captions 4828 * 4829 * @extends TextTrackButton 4830 */ 4831var CaptionsButton = function (_TextTrackButton) { 4832 _inherits(CaptionsButton, _TextTrackButton); 4833 4834 /** 4835 * Creates an instance of this class. 4836 * 4837 * @param {Player} player 4838 * The `Player` that this class should be attached to. 4839 * 4840 * @param {Object} [options] 4841 * The key/value store of player options. 4842 * 4843 * @param {Component~ReadyCallback} [ready] 4844 * The function to call when this component is ready. 4845 */ 4846 function CaptionsButton(player, options, ready) { 4847 _classCallCheck(this, CaptionsButton); 4848 4849 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready)); 4850 4851 _this.el_.setAttribute('aria-label', 'Captions Menu'); 4852 return _this; 4853 } 4854 4855 /** 4856 * Builds the default DOM `className`. 4857 * 4858 * @return {string} 4859 * The DOM `className` for this object. 4860 */ 4861 4862 4863 CaptionsButton.prototype.buildCSSClass = function buildCSSClass() { 4864 return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 4865 }; 4866 4867 /** 4868 * Update caption menu items 4869 * 4870 * @param {EventTarget~Event} [event] 4871 * The `addtrack` or `removetrack` event that caused this function to be 4872 * called. 4873 * 4874 * @listens TextTrackList#addtrack 4875 * @listens TextTrackList#removetrack 4876 */ 4877 4878 4879 CaptionsButton.prototype.update = function update(event) { 4880 var threshold = 2; 4881 4882 _TextTrackButton.prototype.update.call(this); 4883 4884 // if native, then threshold is 1 because no settings button 4885 if (this.player().tech_ && this.player().tech_.featuresNativeTextTracks) { 4886 threshold = 1; 4887 } 4888 4889 if (this.items && this.items.length > threshold) { 4890 this.show(); 4891 } else { 4892 this.hide(); 4893 } 4894 }; 4895 4896 /** 4897 * Create caption menu items 4898 * 4899 * @return {CaptionSettingsMenuItem[]} 4900 * The array of current menu items. 4901 */ 4902 4903 4904 CaptionsButton.prototype.createItems = function createItems() { 4905 var items = []; 4906 4907 if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) { 4908 items.push(new _captionSettingsMenuItem2['default'](this.player_, { kind: this.kind_ })); 4909 } 4910 4911 return _TextTrackButton.prototype.createItems.call(this, items); 4912 }; 4913 4914 return CaptionsButton; 4915}(_textTrackButton2['default']); 4916 4917/** 4918 * `kind` of TextTrack to look for to associate it with this menu. 4919 * 4920 * @type {string} 4921 * @private 4922 */ 4923 4924 4925CaptionsButton.prototype.kind_ = 'captions'; 4926 4927/** 4928 * The text that should display over the `CaptionsButton`s controls. Added for localization. 4929 * 4930 * @type {string} 4931 * @private 4932 */ 4933CaptionsButton.prototype.controlText_ = 'Captions'; 4934 4935_component2['default'].registerComponent('CaptionsButton', CaptionsButton); 4936exports['default'] = CaptionsButton; 4937 4938},{"23":23,"30":30,"5":5}],25:[function(_dereq_,module,exports){ 4939'use strict'; 4940 4941exports.__esModule = true; 4942 4943var _textTrackButton = _dereq_(30); 4944 4945var _textTrackButton2 = _interopRequireDefault(_textTrackButton); 4946 4947var _component = _dereq_(5); 4948 4949var _component2 = _interopRequireDefault(_component); 4950 4951var _chaptersTrackMenuItem = _dereq_(26); 4952 4953var _chaptersTrackMenuItem2 = _interopRequireDefault(_chaptersTrackMenuItem); 4954 4955var _toTitleCase = _dereq_(91); 4956 4957var _toTitleCase2 = _interopRequireDefault(_toTitleCase); 4958 4959function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4960 4961function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4962 4963function _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; } 4964 4965function _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 4965-5082
4965onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 4966 * @file chapters-button.js 4967 */ 4968 4969 4970/** 4971 * The button component for toggling and selecting chapters 4972 * Chapters act much differently than other text tracks 4973 * Cues are navigation vs. other tracks of alternative languages 4974 * 4975 * @extends TextTrackButton 4976 */ 4977var ChaptersButton = function (_TextTrackButton) { 4978 _inherits(ChaptersButton, _TextTrackButton); 4979 4980 /** 4981 * Creates an instance of this class. 4982 * 4983 * @param {Player} player 4984 * The `Player` that this class should be attached to. 4985 * 4986 * @param {Object} [options] 4987 * The key/value store of player options. 4988 * 4989 * @param {Component~ReadyCallback} [ready] 4990 * The function to call when this function is ready. 4991 */ 4992 function ChaptersButton(player, options, ready) { 4993 _classCallCheck(this, ChaptersButton); 4994 4995 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready)); 4996 4997 _this.el_.setAttribute('aria-label', 'Chapters Menu'); 4998 return _this; 4999 } 5000 5001 /** 5002 * Builds the default DOM `className`. 5003 * 5004 * @return {string} 5005 * The DOM `className` for this object. 5006 */ 5007 5008 5009 ChaptersButton.prototype.buildCSSClass = function buildCSSClass() { 5010 return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 5011 }; 5012 5013 /** 5014 * Update the menu based on the current state of its items. 5015 * 5016 * @param {EventTarget~Event} [event] 5017 * An event that triggered this function to run. 5018 * 5019 * @listens TextTrackList#addtrack 5020 * @listens TextTrackList#removetrack 5021 * @listens TextTrackList#change 5022 */ 5023 5024 5025 ChaptersButton.prototype.update = function update(event) { 5026 if (!this.track_ || event && (event.type === 'addtrack' || event.type === 'removetrack')) { 5027 this.setTrack(this.findChaptersTrack()); 5028 } 5029 _TextTrackButton.prototype.update.call(this); 5030 }; 5031 5032 /** 5033 * Set the currently selected track for the chapters button. 5034 * 5035 * @param {TextTrack} track 5036 * The new track to select. Nothing will change if this is the currently selected 5037 * track. 5038 */ 5039 5040 5041 ChaptersButton.prototype.setTrack = function setTrack(track) { 5042 if (this.track_ === track) { 5043 return; 5044 } 5045 5046 if (!this.updateHandler_) { 5047 this.updateHandler_ = this.update.bind(this); 5048 } 5049 5050 // here this.track_ refers to the old track instance 5051 if (this.track_) { 5052 var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_); 5053 5054 if (remoteTextTrackEl) { 5055 remoteTextTrackEl.removeEventListener('load', this.updateHandler_); 5056 } 5057 5058 this.track_ = null; 5059 } 5060 5061 this.track_ = track; 5062 5063 // here this.track_ refers to the new track instance 5064 if (this.track_) { 5065 this.track_.mode = 'hidden'; 5066 5067 var _remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_); 5068 5069 if (_remoteTextTrackEl) { 5070 _remoteTextTrackEl.addEventListener('load', this.updateHandler_); 5071 } 5072 } 5073 }; 5074 5075 /** 5076 * Find the track object that is currently in use by this ChaptersButton 5077 * 5078 * @return {TextTrack|undefined} 5079 * The current track or undefined if none was found. 5080 */ 5081 5082
5083 ChaptersButton.prototype.findChaptersTrack = function findChaptersTrack() { 5084 var tracks = this.player_.textTracks() || []; 5085 5086 for (var i = tracks.length - 1; i >= 0; i--) { 5087 // We will always choose the last track as our chaptersTrack 5088 var track = tracks[i]; 5089 5090 if (track.kind === this.kind_) { 5091 return track; 5092 } 5093 } 5094 }; 5095 5096 /** 5097 * Get the caption for the ChaptersButton based on the track label. This will also 5098 * use the current tracks localized kind as a fallback if a label does not exist. 5099 * 5100 * @return {string} 5101 * The tracks current label or the localized track kind. 5102 */ 5103 5104 5105 ChaptersButton.prototype.getMenuCaption = function getMenuCaption() { 5106 if (this.track_ && this.track_.label) { 5107 return this.track_.label; 5108 } 5109 return this.localize((0, _toTitleCase2['default'])(this.kind_)); 5110 }; 5111 5112 /** 5113 * Create menu from chapter track 5114 * 5115 * @return {Menu} 5116 * New menu for the chapter buttons 5117 */ 5118 5119 5120 ChaptersButton.prototype.createMenu = function createMenu() { 5121 this.options_.title = this.getMenuCaption(); 5122 return _TextTrackButton.prototype.createMenu.call(this); 5123 }; 5124 5125 /** 5126 * Create a menu item for each text track 5127 * 5128 * @return {TextTrackMenuItem[]} 5129 * Array of menu items 5130 */ 5131 5132 5133 ChaptersButton.prototype.createItems = function createItems() { 5134 var items = []; 5135 5136 if (!this.track_) { 5137 return items; 5138 } 5139 5140 var cues = this.track_.cues; 5141 5142 if (!cues) { 5143 return items; 5144 } 5145 5146 for (var i = 0, l = cues.length; i < l; i++) { 5147 var cue = cues[i]; 5148 var mi = new _chaptersTrackMenuItem2['default'](this.player_, { track: this.track_, cue: cue }); 5149 5150 items.push(mi); 5151 } 5152 5153 return items; 5154 }; 5155 5156 return ChaptersButton; 5157}(_textTrackButton2['default']); 5158 5159/** 5160 * `kind` of TextTrack to look for to associate it with this menu. 5161 * 5162 * @type {string} 5163 * @private 5164 */ 5165 5166 5167ChaptersButton.prototype.kind_ = 'chapters'; 5168 5169/** 5170 * The text that should display over the `ChaptersButton`s controls. Added for localization. 5171 * 5172 * @type {string} 5173 * @private 5174 */ 5175ChaptersButton.prototype.controlText_ = 'Chapters'; 5176 5177_component2['default'].registerComponent('ChaptersButton', ChaptersButton); 5178exports['default'] = ChaptersButton; 5179 5180},{"26":26,"30":30,"5":5,"91":91}],26:[function(_dereq_,module,exports){ 5181'use strict'; 5182 5183exports.__esModule = true; 5184 5185var _menuItem = _dereq_(48); 5186 5187var _menuItem2 = _interopRequireDefault(_menuItem); 5188 5189var _component = _dereq_(5); 5190 5191var _component2 = _interopRequireDefault(_component); 5192 5193var _fn = _dereq_(83); 5194 5195var Fn = _interopRequireWildcard(_fn); 5196 5197function _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; } } 5198 5199function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5200 5201function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5202 5203function _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; } 5204 5205function _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; } /** 5206 * @file chapters-track-menu-item.js 5207 */ 5208 5209 5210/** 5211 * The chapter track menu item 5212 * 5213 * @extends MenuItem 5214 */ 5215var ChaptersTrackMenuItem = function (_MenuItem) { 5216 _inherits(ChaptersTrackMenuItem, _MenuItem); 5217 5218 /** 5219 * Creates an instance of this class. 5220 * 5221 * @param {Player} player 5222 * The `Player` that this class should be attached to. 5223 * 5224 * @param {Object} [options] 5225 * The key/value store of player options. 5226 */ 5227 function ChaptersTrackMenuItem(player, options) { 5228 _classCallCheck(this, ChaptersTrackMenuItem); 5229 5230 var track = options.track; 5231 var cue = options.cue; 5232 var currentTime = player.currentTime(); 5233 5234 // Modify options for parent MenuItem class's init. 5235 options.selectable = true; 5236 options.label = cue.text; 5237 options.selected = cue.startTime <= currentTime && currentTime < cue.endTime; 5238 5239 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options)); 5240 5241 _this.track = track; 5242 _this.cue = cue; 5243 track.addEventListener('cuechange', Fn.bind(_this, _this.update)); 5244 return _this; 5245 } 5246 5247 /** 5248 * This gets called when an `ChaptersTrackMenuItem` is "clicked". See 5249 * {@link ClickableComponent} for more detailed information on what a click can be. 5250 * 5251 * @param {EventTarget~Event} [event]
5252 * The `keydown`, `tap`, or `click` event that caused this function to be 5253 * called. 5254 * 5255 * @listens tap 5256 * @listens click 5257 */ 5258 5259 5260 ChaptersTrackMenuItem.prototype.handleClick = function handleClick(event) { 5261 _MenuItem.prototype.handleClick.call(this); 5262 this.player_.currentTime(this.cue.startTime); 5263 this.update(this.cue.startTime); 5264 }; 5265 5266 /** 5267 * Update chapter menu item 5268 * 5269 * @param {EventTarget~Event} [event] 5270 * The `cuechange` event that caused this function to run. 5271 * 5272 * @listens TextTrack#cuechange 5273 */ 5274 5275 5276 ChaptersTrackMenuItem.prototype.update = function update(event) { 5277 var cue = this.cue; 5278 var currentTime = this.player_.currentTime(); 5279 5280 // vjs.log(currentTime, cue.startTime); 5281 this.selected(cue.startTime <= currentTime && currentTime < cue.endTime); 5282 }; 5283 5284 return ChaptersTrackMenuItem; 5285}(_menuItem2['default']); 5286 5287_component2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem); 5288exports['default'] = ChaptersTrackMenuItem; 5289 5290},{"48":48,"5":5,"83":83}],27:[function(_dereq_,module,exports){ 5291'use strict'; 5292 5293exports.__esModule = true; 5294 5295var _textTrackButton = _dereq_(30); 5296 5297var _textTrackButton2 = _interopRequireDefault(_textTrackButton); 5298 5299var _component = _dereq_(5); 5300 5301var _component2 = _interopRequireDefault(_component); 5302 5303var _fn = _dereq_(83); 5304 5305var Fn = _interopRequireWildcard(_fn); 5306 5307function _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; } } 5308 5309function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5310 5311function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5312 5313function _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; } 5314 5315function _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; } /** 5316 * @file descriptions-button.js 5317 */ 5318 5319 5320/** 5321 * The button component for toggling and selecting descriptions 5322 * 5323 * @extends TextTrackButton 5324 */ 5325var DescriptionsButton = function (_TextTrackButton) { 5326 _inherits(DescriptionsButton, _TextTrackButton); 5327 5328 /** 5329 * Creates an instance of this class. 5330 * 5331 * @param {Player} player 5332 * The `Player` that this class should be attached to. 5333 * 5334 * @param {Object} [options] 5335 * The key/value store of player options. 5336 * 5337 * @param {Component~ReadyCallback} [ready] 5338 * The function to call when this component is ready. 5339 */ 5340 function DescriptionsButton(player, options, ready) { 5341 _classCallCheck(this, DescriptionsButton); 5342 5343 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready)); 5344 5345 _this.el_.setAttribute('aria-label', 'Descriptions Menu'); 5346 5347 var tracks = player.textTracks(); 5348 5349 if (tracks) { 5350 (function () { 5351 var changeHandler = Fn.bind(_this, _this.handleTracksChange); 5352 5353 tracks.addEventListener('change', changeHandler); 5354 _this.on('dispose', function () { 5355 tracks.removeEventListener('change', changeHandler); 5356 }); 5357 })(); 5358 } 5359 return _this; 5360 } 5361 5362 /** 5363 * Handle text track change 5364 * 5365 * @param {EventTarget~Event} event 5366 * The event that caused this function to run 5367 * 5368 * @listens TextTrackList#change 5369 */ 5370 5371 5372 DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) { 5373 var tracks = this.player().textTracks(); 5374 var disabled = false;
5375 5376 // Check whether a track of a different kind is showing 5377 for (var i = 0, l = tracks.length; i < l; i++) { 5378 var track = tracks[i]; 5379 5380 if (track.kind !== this.kind_ && track.mode === 'showing') { 5381 disabled = true; 5382 break; 5383 } 5384 } 5385 5386 // If another track is showing, disable this menu button 5387 if (disabled) { 5388 this.disable(); 5389 } else { 5390 this.enable(); 5391 } 5392 }; 5393 5394 /** 5395 * Builds the default DOM `className`. 5396 * 5397 * @return {string} 5398 * The DOM `className` for this object. 5399 */ 5400 5401 5402 DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() { 5403 return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 5404 }; 5405 5406 return DescriptionsButton; 5407}(_textTrackButton2['default']); 5408 5409/** 5410 * `kind` of TextTrack to look for to associate it with this menu. 5411 * 5412 * @type {string} 5413 * @private 5414 */ 5415 5416 5417DescriptionsButton.prototype.kind_ = 'descriptions'; 5418 5419/** 5420 * The text that should display over the `DescriptionsButton`s controls. Added for localization. 5421 * 5422 * @type {string} 5423 * @private 5424 */ 5425DescriptionsButton.prototype.controlText_ = 'Descriptions'; 5426 5427_component2['default'].registerComponent('DescriptionsButton', DescriptionsButton); 5428exports['default'] = DescriptionsButton; 5429 5430},{"30":30,"5":5,"83":83}],28:[function(_dereq_,module,exports){ 5431'use strict'; 5432 5433exports.__esModule = true; 5434 5435var _textTrackMenuItem = _dereq_(31); 5436 5437var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem); 5438 5439var _component = _dereq_(5); 5440 5441var _component2 = _interopRequireDefault(_component); 5442 5443function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5444 5445function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5446 5447function _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; } 5448 5449function _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; } /** 5450 * @file off-text-track-menu-item.js 5451 */ 5452 5453 5454/** 5455 * A special menu item for turning of a specific type of text track 5456 * 5457 * @extends TextTrackMenuItem 5458 */ 5459var OffTextTrackMenuItem = function (_TextTrackMenuItem) { 5460 _inherits(OffTextTrackMenuItem, _TextTrackMenuItem); 5461 5462 /** 5463 * Creates an instance of this class. 5464 * 5465 * @param {Player} player 5466 * The `Player` that this class should be attached to. 5467 * 5468 * @param {Object} [options] 5469 * The key/value store of player options. 5470 */ 5471 function OffTextTrackMenuItem(player, options) { 5472 _classCallCheck(this, OffTextTrackMenuItem); 5473 5474 // Create pseudo track info 5475 // Requires options['kind'] 5476 options.track = { 5477 player: player, 5478 kind: options.kind, 5479 label: options.kind + ' off', 5480 'default': false, 5481 mode: 'disabled' 5482 }; 5483 5484 // MenuItem is selectable 5485 options.selectable = true; 5486 5487 var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options)); 5488 5489 _this.selected(true); 5490 return _this; 5491 } 5492 5493 /** 5494 * Handle text track change 5495 * 5496 * @param {EventTarget~Event} event 5497 * The event that caused this function to run 5498 */ 5499 5500 5501 OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { 5502 var tracks = this.player().textTracks(); 5503 var selected = true; 5504 5505 for (var i = 0, l = tracks.length; i < l; i++) { 5506 var track = tracks[i]; 5507 5508 if (track.kind === this.track.kind && track.mode === 'showing') { 5509 selected = false;
5510 break; 5511 } 5512 } 5513 5514 this.selected(selected); 5515 }; 5516 5517 return OffTextTrackMenuItem; 5518}(_textTrackMenuItem2['default']); 5519 5520_component2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem); 5521exports['default'] = OffTextTrackMenuItem; 5522 5523},{"31":31,"5":5}],29:[function(_dereq_,module,exports){ 5524'use strict'; 5525 5526exports.__esModule = true; 5527 5528var _textTrackButton = _dereq_(30); 5529 5530var _textTrackButton2 = _interopRequireDefault(_textTrackButton); 5531 5532var _component = _dereq_(5); 5533 5534var _component2 = _interopRequireDefault(_component); 5535 5536function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5537 5538function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5539 5540function _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; } 5541 5542function _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; } /** 5543 * @file subtitles-button.js 5544 */ 5545 5546 5547/** 5548 * The button component for toggling and selecting subtitles 5549 * 5550 * @extends TextTrackButton 5551 */ 5552var SubtitlesButton = function (_TextTrackButton) { 5553 _inherits(SubtitlesButton, _TextTrackButton); 5554 5555 /** 5556 * Creates an instance of this class. 5557 * 5558 * @param {Player} player 5559 * The `Player` that this class should be attached to. 5560 * 5561 * @param {Object} [options] 5562 * The key/value store of player options. 5563 * 5564 * @param {Component~ReadyCallback} [ready] 5565 * The function to call when this component is ready. 5566 */ 5567 function SubtitlesButton(player, options, ready) { 5568 _classCallCheck(this, SubtitlesButton); 5569 5570 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready)); 5571 5572 _this.el_.setAttribute('aria-label', 'Subtitles Menu'); 5573 return _this; 5574 } 5575 5576 /** 5577 * Builds the default DOM `className`. 5578 * 5579 * @return {string} 5580 * The DOM `className` for this object. 5581 */ 5582 5583 5584 SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() { 5585 return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 5586 }; 5587 5588 return SubtitlesButton; 5589}(_textTrackButton2['default']); 5590 5591/** 5592 * `kind` of TextTrack to look for to associate it with this menu. 5593 * 5594 * @type {string} 5595 * @private 5596 */ 5597 5598 5599SubtitlesButton.prototype.kind_ = 'subtitles'; 5600 5601/** 5602 * The text that should display over the `SubtitlesButton`s controls. Added for localization. 5603 * 5604 * @type {string} 5605 * @private 5606 */ 5607SubtitlesButton.prototype.controlText_ = 'Subtitles'; 5608 5609_component2['default'].registerComponent('SubtitlesButton', SubtitlesButton); 5610exports['default'] = SubtitlesButton; 5611 5612},{"30":30,"5":5}],30:[function(_dereq_,module,exports){ 5613'use strict'; 5614 5615exports.__esModule = true; 5616 5617var _trackButton = _dereq_(36); 5618 5619var _trackButton2 = _interopRequireDefault(_trackButton); 5620 5621var _component = _dereq_(5); 5622 5623var _component2 = _interopRequireDefault(_component); 5624 5625var _textTrackMenuItem = _dereq_(31); 5626 5627var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem); 5628 5629var _offTextTrackMenuItem = _dereq_(28); 5630 5631var _offTextTrackMenuItem2 = _interopRequireDefault(_offTextTrackMenuItem); 5632 5633function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5634 5635function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5636 5637function _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; } 5638 5639function _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
5639onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 5640 * @file text-track-button.js 5641 */ 5642 5643 5644/** 5645 * The base class for buttons that toggle specific text track types (e.g. subtitles) 5646 * 5647 * @extends MenuButton 5648 */ 5649var TextTrackButton = function (_TrackButton) { 5650 _inherits(TextTrackButton, _TrackButton); 5651 5652 /** 5653 * Creates an instance of this class. 5654 * 5655 * @param {Player} player 5656 * The `Player` that this class should be attached to. 5657 * 5658 * @param {Object} [options={}] 5659 * The key/value store of player options. 5660 */ 5661 function TextTrackButton(player) { 5662 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 5663 5664 _classCallCheck(this, TextTrackButton); 5665 5666 options.tracks = player.textTracks(); 5667 5668 return _possibleConstructorReturn(this, _TrackButton.call(this, player, options)); 5669 } 5670 5671 /** 5672 * Create a menu item for each text track 5673 * 5674 * @param {TextTrackMenuItem[]} [items=[]] 5675 * Existing array of items to use during creation 5676 * 5677 * @return {TextTrackMenuItem[]} 5678 * Array of menu items that were created 5679 */ 5680 5681 5682 TextTrackButton.prototype.createItems = function createItems() { 5683 var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 5684 5685 // Add an OFF menu item to turn all tracks off 5686 items.push(new _offTextTrackMenuItem2['default'](this.player_, { kind: this.kind_ })); 5687 5688 var tracks = this.player_.textTracks(); 5689 5690 if (!tracks) { 5691 return items; 5692 } 5693 5694 for (var i = 0; i < tracks.length; i++) { 5695 var track = tracks[i]; 5696 5697 // only add tracks that are of the appropriate kind and have a label 5698 if (track.kind === this.kind_) { 5699 items.push(new _textTrackMenuItem2['default'](this.player_, { 5700 track: track, 5701 // MenuItem is selectable 5702 selectable: true 5703 })); 5704 } 5705 } 5706 5707 return items; 5708 }; 5709 5710 return TextTrackButton; 5711}(_trackButton2['default']); 5712 5713_component2['default'].registerComponent('TextTrackButton', TextTrackButton); 5714exports['default'] = TextTrackButton; 5715 5716},{"28":28,"31":31,"36":36,"5":5}],31:[function(_dereq_,module,exports){ 5717'use strict'; 5718 5719exports.__esModule = true; 5720 5721var _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; }; 5722 5723var _menuItem = _dereq_(48); 5724 5725var _menuItem2 = _interopRequireDefault(_menuItem); 5726 5727var _component = _dereq_(5); 5728 5729var _component2 = _interopRequireDefault(_component); 5730 5731var _fn = _dereq_(83); 5732 5733var Fn = _interopRequireWildcard(_fn); 5734 5735var _window = _dereq_(95); 5736 5737var _window2 = _interopRequireDefault(_window); 5738 5739var _document = _dereq_(94); 5740 5741var _document2 = _interopRequireDefault(_document); 5742 5743function _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; } } 5744 5745function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5746 5747function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5748 5749function _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; } 5750 5751function _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
5751onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 5752 * @file text-track-menu-item.js 5753 */ 5754 5755 5756/** 5757 * The specific menu item type for selecting a language within a text track kind 5758 * 5759 * @extends MenuItem 5760 */ 5761var TextTrackMenuItem = function (_MenuItem) { 5762 _inherits(TextTrackMenuItem, _MenuItem); 5763 5764 /** 5765 * Creates an instance of this class. 5766 * 5767 * @param {Player} player 5768 * The `Player` that this class should be attached to. 5769 * 5770 * @param {Object} [options] 5771 * The key/value store of player options. 5772 */ 5773 function TextTrackMenuItem(player, options) { 5774 _classCallCheck(this, TextTrackMenuItem); 5775 5776 var track = options.track; 5777 var tracks = player.textTracks(); 5778 5779 // Modify options for parent MenuItem class's init. 5780 options.label = track.label || track.language || 'Unknown'; 5781 options.selected = track['default'] || track.mode === 'showing'; 5782 5783 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options)); 5784 5785 _this.track = track; 5786 5787 if (tracks) { 5788 (function () { 5789 var changeHandler = Fn.bind(_this, _this.handleTracksChange); 5790 5791 tracks.addEventListener('change', changeHandler); 5792 _this.on('dispose', function () { 5793 tracks.removeEventListener('change', changeHandler); 5794 }); 5795 })(); 5796 } 5797 5798 // iOS7 doesn't dispatch change events to TextTrackLists when an 5799 // associated track's mode changes. Without something like 5800 // Object.observe() (also not present on iOS7), it's not 5801 // possible to detect changes to the mode attribute and polyfill 5802 // the change event. As a poor substitute, we manually dispatch 5803 // change events whenever the controls modify the mode. 5804 if (tracks && tracks.onchange === undefined) { 5805 (function () { 5806 var event = void 0; 5807 5808 _this.on(['tap', 'click'], function () { 5809 if (_typeof(_window2['default'].Event) !== 'object') { 5810 // Android 2.3 throws an Illegal Constructor error for window.Event 5811 try { 5812 event = new _window2['default'].Event('change'); 5813 } catch (err) { 5814 // continue regardless of error 5815 } 5816 } 5817 5818 if (!event) { 5819 event = _document2['default'].createEvent('Event'); 5820 event.initEvent('change', true, true); 5821 } 5822 5823 tracks.dispatchEvent(event); 5824 }); 5825 })(); 5826 } 5827 return _this; 5828 } 5829 5830 /** 5831 * This gets called when an `TextTrackMenuItem` is "clicked". See 5832 * {@link ClickableComponent} for more detailed information on what a click can be. 5833 * 5834 * @param {EventTarget~Event} event 5835 * The `keydown`, `tap`, or `click` event that caused this function to be 5836 * called. 5837 * 5838 * @listens tap 5839 * @listens click 5840 */ 5841 5842 5843 TextTrackMenuItem.prototype.handleClick = function handleClick(event) { 5844 var kind = this.track.kind; 5845 var tracks = this.player_.textTracks(); 5846 5847 _MenuItem.prototype.handleClick.call(this, event); 5848 5849 if (!tracks) { 5850 return; 5851 } 5852 5853 for (var i = 0; i < tracks.length; i++) { 5854 var track = tracks[i]; 5855 5856 if (track.kind !== kind) { 5857 continue; 5858 } 5859 5860 if (track === this.track) { 5861 track.mode = 'showing'; 5862 } else { 5863 track.mode = 'disabled'; 5864 } 5865 } 5866 }; 5867 5868 /** 5869 * Handle text track list change 5870 * 5871 * @param {EventTarget~Event} event 5872 * The `change` event that caused this function to be called. 5873 * 5874 * @listens TextTrackList#change 5875 */ 5876 5877 5878 TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { 5879 this.selected(this.track.mode === 'showing'); 5880 }; 5881 5882 return TextTrackMenuItem; 5883}(_menuItem2['default']); 5884 5885_component2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem); 5886exports['default'] = TextTrackMenuItem; 5887 5888},{"48":48,"5":5,"83":83,"94":94,"95":95}],32:[function(_dereq_,module,exports){ 5889'use strict'; 5890 5891exports.__esModule = true; 5892 5893var _component = _dereq_(5); 5894 5895var _component2 = _interopRequireDefault(_component); 5896 5897var _dom = _dereq_(81); 5898 5899var Dom = _interopRequireWildcard(_dom); 5900 5901var _formatTime = _dereq_(84); 5902 5903var _formatTime2 = _interopRequireDefault(_formatTime); 5904 5905function _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; } } 5906 5907function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5908 5909function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5910 5911function _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; } 5912 5913function _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
5913onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 5914 * @file current-time-display.js 5915 */ 5916 5917 5918/** 5919 * Displays the current time 5920 * 5921 * @extends Component 5922 */ 5923var CurrentTimeDisplay = function (_Component) { 5924 _inherits(CurrentTimeDisplay, _Component); 5925 5926 /** 5927 * Creates an instance of this class. 5928 * 5929 * @param {Player} player 5930 * The `Player` that this class should be attached to. 5931 * 5932 * @param {Object} [options] 5933 * The key/value store of player options. 5934 */ 5935 function CurrentTimeDisplay(player, options) { 5936 _classCallCheck(this, CurrentTimeDisplay); 5937 5938 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 5939 5940 _this.on(player, 'timeupdate', _this.updateContent); 5941 return _this; 5942 } 5943 5944 /** 5945 * Create the `Component`'s DOM element 5946 * 5947 * @return {Element} 5948 * The element that was created. 5949 */ 5950 5951 5952 CurrentTimeDisplay.prototype.createEl = function createEl() { 5953 var el = _Component.prototype.createEl.call(this, 'div', { 5954 className: 'vjs-current-time vjs-time-control vjs-control' 5955 }); 5956 5957 this.contentEl_ = Dom.createEl('div', { 5958 className: 'vjs-current-time-display', 5959 // label the current time for screen reader users 5960 innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00' 5961 }, { 5962 // tell screen readers not to automatically read the time as it changes 5963 'aria-live': 'off' 5964 }); 5965 5966 el.appendChild(this.contentEl_); 5967 return el; 5968 }; 5969 5970 /** 5971 * Update current time display 5972 * 5973 * @param {EventTarget~Event} [event] 5974 * The `timeupdate` event that caused this function to run. 5975 * 5976 * @listens Player#timeupdate 5977 */ 5978 5979 5980 CurrentTimeDisplay.prototype.updateContent = function updateContent(event) { 5981 // Allows for smooth scrubbing, when player can't keep up. 5982 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 5983 var localizedText = this.localize('Current Time'); 5984 var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration()); 5985 5986 if (formattedTime !== this.formattedTime_) { 5987 this.formattedTime_ = formattedTime; 5988 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; 5989 } 5990 }; 5991 5992 return CurrentTimeDisplay; 5993}(_component2['default']); 5994 5995_component2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay); 5996exports['default'] = CurrentTimeDisplay; 5997 5998},{"5":5,"81":81,"84":84}],33:[function(_dereq_,module,exports){ 5999'use strict'; 6000 6001exports.__esModule = true; 6002 6003var _component = _dereq_(5); 6004 6005var _component2 = _interopRequireDefault(_component); 6006 6007var _dom = _dereq_(81); 6008 6009var Dom = _interopRequireWildcard(_dom); 6010 6011var _formatTime = _dereq_(84); 6012 6013var _formatTime2 = _interopRequireDefault(_formatTime); 6014 6015function _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; } } 6016 6017function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6018 6019function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6020 6021function _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; } 6022 6023function _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
6023onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6024 * @file duration-display.js 6025 */ 6026 6027 6028/** 6029 * Displays the duration 6030 * 6031 * @extends Component 6032 */ 6033var DurationDisplay = function (_Component) { 6034 _inherits(DurationDisplay, _Component); 6035 6036 /** 6037 * Creates an instance of this class. 6038 * 6039 * @param {Player} player 6040 * The `Player` that this class should be attached to. 6041 * 6042 * @param {Object} [options] 6043 * The key/value store of player options. 6044 */ 6045 function DurationDisplay(player, options) { 6046 _classCallCheck(this, DurationDisplay); 6047 6048 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 6049 6050 _this.on(player, 'durationchange', _this.updateContent); 6051 6052 // Also listen for timeupdate and loadedmetadata because removing those 6053 // listeners could have broken dependent applications/libraries. These 6054 // can likely be removed for 6.0. 6055 _this.on(player, 'timeupdate', _this.updateContent); 6056 _this.on(player, 'loadedmetadata', _this.updateContent); 6057 return _this; 6058 } 6059 6060 /** 6061 * Create the `Component`'s DOM element 6062 * 6063 * @return {Element} 6064 * The element that was created. 6065 */ 6066 6067 6068 DurationDisplay.prototype.createEl = function createEl() { 6069 var el = _Component.prototype.createEl.call(this, 'div', { 6070 className: 'vjs-duration vjs-time-control vjs-control' 6071 }); 6072 6073 this.contentEl_ = Dom.createEl('div', { 6074 className: 'vjs-duration-display', 6075 // label the duration time for screen reader users 6076 innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00' 6077 }, { 6078 // tell screen readers not to automatically read the time as it changes 6079 'aria-live': 'off' 6080 }); 6081 6082 el.appendChild(this.contentEl_); 6083 return el; 6084 }; 6085 6086 /** 6087 * Update duration time display. 6088 * 6089 * @param {EventTarget~Event} [event] 6090 * The `durationchange`, `timeupdate`, or `loadedmetadata` event that caused 6091 * this function to be called. 6092 * 6093 * @listens Player#durationchange 6094 * @listens Player#timeupdate 6095 * @listens Player#loadedmetadata 6096 */ 6097 6098 6099 DurationDisplay.prototype.updateContent = function updateContent(event) { 6100 var duration = this.player_.duration(); 6101 6102 if (duration && this.duration_ !== duration) { 6103 this.duration_ = duration; 6104 var localizedText = this.localize('Duration Time'); 6105 var formattedTime = (0, _formatTime2['default'])(duration); 6106 6107 // label the duration time for screen reader users 6108 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; 6109 } 6110 }; 6111 6112 return DurationDisplay; 6113}(_component2['default']); 6114 6115_component2['default'].registerComponent('DurationDisplay', DurationDisplay); 6116exports['default'] = DurationDisplay; 6117 6118},{"5":5,"81":81,"84":84}],34:[function(_dereq_,module,exports){ 6119'use strict'; 6120 6121exports.__esModule = true; 6122 6123var _component = _dereq_(5); 6124 6125var _component2 = _interopRequireDefault(_component); 6126 6127var _dom = _dereq_(81); 6128 6129var Dom = _interopRequireWildcard(_dom); 6130 6131var _formatTime = _dereq_(84); 6132 6133var _formatTime2 = _interopRequireDefault(_formatTime); 6134 6135function _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; } } 6136 6137function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6138 6139function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6140 6141function _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; } 6142 6143function _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
6143onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6144 * @file remaining-time-display.js 6145 */ 6146 6147 6148/** 6149 * Displays the time left in the video 6150 * 6151 * @extends Component 6152 */ 6153var RemainingTimeDisplay = function (_Component) { 6154 _inherits(RemainingTimeDisplay, _Component); 6155 6156 /** 6157 * Creates an instance of this class. 6158 * 6159 * @param {Player} player 6160 * The `Player` that this class should be attached to. 6161 * 6162 * @param {Object} [options] 6163 * The key/value store of player options. 6164 */ 6165 function RemainingTimeDisplay(player, options) { 6166 _classCallCheck(this, RemainingTimeDisplay); 6167 6168 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 6169 6170 _this.on(player, 'timeupdate', _this.updateContent); 6171 _this.on(player, 'durationchange', _this.updateContent); 6172 return _this; 6173 } 6174 6175 /** 6176 * Create the `Component`'s DOM element 6177 * 6178 * @return {Element} 6179 * The element that was created. 6180 */ 6181 6182 6183 RemainingTimeDisplay.prototype.createEl = function createEl() { 6184 var el = _Component.prototype.createEl.call(this, 'div', { 6185 className: 'vjs-remaining-time vjs-time-control vjs-control' 6186 }); 6187 6188 this.contentEl_ = Dom.createEl('div', { 6189 className: 'vjs-remaining-time-display', 6190 // label the remaining time for screen reader users 6191 innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00' 6192 }, { 6193 // tell screen readers not to automatically read the time as it changes 6194 'aria-live': 'off' 6195 }); 6196 6197 el.appendChild(this.contentEl_); 6198 return el; 6199 }; 6200 6201 /** 6202 * Update remaining time display. 6203 * 6204 * @param {EventTarget~Event} [event] 6205 * The `timeupdate` or `durationchange` event that caused this to run. 6206 * 6207 * @listens Player#timeupdate 6208 * @listens Player#durationchange 6209 */ 6210 6211 6212 RemainingTimeDisplay.prototype.updateContent = function updateContent(event) { 6213 if (this.player_.duration()) { 6214 var localizedText = this.localize('Remaining Time'); 6215 var formattedTime = (0, _formatTime2['default'])(this.player_.remainingTime()); 6216 6217 if (formattedTime !== this.formattedTime_) { 6218 this.formattedTime_ = formattedTime; 6219 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime; 6220 } 6221 } 6222 6223 // Allows for smooth scrubbing, when player can't keep up. 6224 // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime(); 6225 // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration()); 6226 }; 6227 6228 return RemainingTimeDisplay; 6229}(_component2['default']); 6230 6231_component2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay); 6232exports['default'] = RemainingTimeDisplay; 6233 6234},{"5":5,"81":81,"84":84}],35:[function(_dereq_,module,exports){ 6235'use strict'; 6236 6237exports.__esModule = true; 6238 6239var _component = _dereq_(5); 6240 6241var _component2 = _interopRequireDefault(_component); 6242 6243function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6244 6245function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6246 6247function _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; } 6248 6249function _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
6249onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6250 * @file time-divider.js 6251 */ 6252 6253 6254/** 6255 * The separator between the current time and duration. 6256 * Can be hidden if it's not needed in the design. 6257 * 6258 * @extends Component 6259 */ 6260var TimeDivider = function (_Component) { 6261 _inherits(TimeDivider, _Component); 6262 6263 function TimeDivider() { 6264 _classCallCheck(this, TimeDivider); 6265 6266 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 6267 } 6268 6269 /** 6270 * Create the component's DOM element 6271 * 6272 * @return {Element} 6273 * The element that was created. 6274 */ 6275 TimeDivider.prototype.createEl = function createEl() { 6276 return _Component.prototype.createEl.call(this, 'div', { 6277 className: 'vjs-time-control vjs-time-divider', 6278 innerHTML: '<div><span>/</span></div>' 6279 }); 6280 }; 6281 6282 return TimeDivider; 6283}(_component2['default']); 6284 6285_component2['default'].registerComponent('TimeDivider', TimeDivider); 6286exports['default'] = TimeDivider; 6287 6288},{"5":5}],36:[function(_dereq_,module,exports){ 6289'use strict'; 6290 6291exports.__esModule = true; 6292 6293var _menuButton = _dereq_(47); 6294 6295var _menuButton2 = _interopRequireDefault(_menuButton); 6296 6297var _component = _dereq_(5); 6298 6299var _component2 = _interopRequireDefault(_component); 6300 6301var _fn = _dereq_(83); 6302 6303var Fn = _interopRequireWildcard(_fn); 6304 6305function _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; } } 6306 6307function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6308 6309function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6310 6311function _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; } 6312 6313function _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; } /** 6314 * @file track-button.js 6315 */ 6316 6317 6318/** 6319 * The base class for buttons that toggle specific track types (e.g. subtitles). 6320 * 6321 * @extends MenuButton 6322 */ 6323var TrackButton = function (_MenuButton) { 6324 _inherits(TrackButton, _MenuButton); 6325 6326 /** 6327 * Creates an instance of this class. 6328 * 6329 * @param {Player} player 6330 * The `Player` that this class should be attached to. 6331 * 6332 * @param {Object} [options] 6333 * The key/value store of player options. 6334 */ 6335 function TrackButton(player, options) { 6336 _classCallCheck(this, TrackButton); 6337 6338 var tracks = options.tracks; 6339 6340 var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options)); 6341 6342 if (_this.items.length <= 1) { 6343 _this.hide(); 6344 } 6345 6346 if (!tracks) { 6347 return _possibleConstructorReturn(_this); 6348 } 6349 6350 var updateHandler = Fn.bind(_this, _this.update); 6351 6352 tracks.addEventListener('removetrack', updateHandler); 6353 tracks.addEventListener('addtrack', updateHandler); 6354 6355 _this.player_.on('dispose', function () { 6356 tracks.removeEventListener('removetrack', updateHandler); 6357 tracks.removeEventListener('addtrack', updateHandler); 6358 }); 6359 return _this; 6360 } 6361 6362 return TrackButton; 6363}(_menuButton2['default']); 6364 6365_component2['default'].registerComponent('TrackButton', TrackButton); 6366exports['default'] = TrackButton; 6367 6368},{"47":47,"5":5,"83":83}],37:[function(_dereq_,module,exports){ 6369'use strict'; 6370 6371exports.__esModule = true; 6372 6373var _slider = _dereq_(57); 6374 6375var _slider2 = _interopRequireDefault(_slider); 6376 6377var _component = _dereq_(5); 6378 6379var _component2 = _interopRequireDefault(_component); 6380 6381var _fn = _dereq_(83); 6382 6383var Fn = _interopRequireWildcard(_fn); 6384 6385_dereq_(39); 6386 6387function _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; } } 6388 6389function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6390 6391function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6392 6393function _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; } 6394 6395function _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
6395onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6396 * @file volume-bar.js 6397 */ 6398 6399 6400// Required children 6401 6402 6403/** 6404 * The bar that contains the volume level and can be clicked on to adjust the level 6405 * 6406 * @extends Slider 6407 */ 6408var VolumeBar = function (_Slider) { 6409 _inherits(VolumeBar, _Slider); 6410 6411 /** 6412 * Creates an instance of this class. 6413 * 6414 * @param {Player} player 6415 * The `Player` that this class should be attached to. 6416 * 6417 * @param {Object} [options] 6418 * The key/value store of player options. 6419 */ 6420 function VolumeBar(player, options) { 6421 _classCallCheck(this, VolumeBar); 6422 6423 var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options)); 6424 6425 _this.on(player, 'volumechange', _this.updateARIAAttributes); 6426 player.ready(Fn.bind(_this, _this.updateARIAAttributes)); 6427 return _this; 6428 } 6429 6430 /** 6431 * Create the `Component`'s DOM element 6432 * 6433 * @return {Element} 6434 * The element that was created. 6435 */ 6436 6437 6438 VolumeBar.prototype.createEl = function createEl() { 6439 return _Slider.prototype.createEl.call(this, 'div', { 6440 className: 'vjs-volume-bar vjs-slider-bar' 6441 }, { 6442 'aria-label': 'volume level' 6443 }); 6444 }; 6445 6446 /** 6447 * Handle movement events on the {@link VolumeMenuButton}. 6448 * 6449 * @param {EventTarget~Event} event 6450 * The event that caused this function to run. 6451 * 6452 * @listens mousemove 6453 */ 6454 6455 6456 VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) { 6457 this.checkMuted(); 6458 this.player_.volume(this.calculateDistance(event)); 6459 }; 6460 6461 /** 6462 * If the player is muted unmute it. 6463 */ 6464 6465 6466 VolumeBar.prototype.checkMuted = function checkMuted() { 6467 if (this.player_.muted()) { 6468 this.player_.muted(false); 6469 } 6470 }; 6471 6472 /** 6473 * Get percent of volume level 6474 * 6475 * @return {number} 6476 * Volume level percent as a decimal number. 6477 */ 6478 6479 6480 VolumeBar.prototype.getPercent = function getPercent() { 6481 if (this.player_.muted()) { 6482 return 0; 6483 } 6484 return this.player_.volume(); 6485 }; 6486 6487 /** 6488 * Increase volume level for keyboard users 6489 */ 6490 6491 6492 VolumeBar.prototype.stepForward = function stepForward() { 6493 this.checkMuted(); 6494 this.player_.volume(this.player_.volume() + 0.1); 6495 }; 6496 6497 /** 6498 * Decrease volume level for keyboard users 6499 */ 6500 6501 6502 VolumeBar.prototype.stepBack = function stepBack() { 6503 this.checkMuted(); 6504 this.player_.volume(this.player_.volume() - 0.1); 6505 }; 6506 6507 /** 6508 * Update ARIA accessibility attributes 6509 * 6510 * @param {EventTarget~Event} [event] 6511 * The `volumechange` event that caused this function to run. 6512 * 6513 * @listens Player#volumechange 6514 */ 6515 6516 6517 VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes(event) { 6518 // Current value of volume bar as a percentage 6519 var volume = (this.player_.volume() * 100).toFixed(2); 6520 6521 this.el_.setAttribute('aria-valuenow', volume); 6522 this.el_.setAttribute('aria-valuetext', volume + '%'); 6523 }; 6524 6525 return VolumeBar; 6526}(_slider2['default']); 6527 6528/** 6529 * Default options for the `VolumeBar` 6530 * 6531 * @type {Object} 6532 * @private 6533 */ 6534 6535 6536VolumeBar.prototype.options_ = { 6537 children: ['volumeLevel'], 6538 barName: 'volumeLevel' 6539}; 6540 6541/** 6542 * Call the update event for this Slider when this event happens on the player. 6543 * 6544 * @type {string} 6545 */ 6546VolumeBar.prototype.playerEvent = 'volumechange'; 6547 6548_component2['default'].registerComponent('VolumeBar', VolumeBar); 6549exports['default'] = VolumeBar; 6550 6551},{"39":39,"5":5,"57":57,"83":83}],38:[function(_dereq_,module,exports){ 6552'use strict'; 6553 6554exports.__esModule = true; 6555 6556var _component = _dereq_(5); 6557 6558var _component2 = _interopRequireDefault(_component); 6559 6560_dereq_(37); 6561 6562function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6563 6564function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6565 6566function _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; } 6567 6568function _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
6568onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6569 * @file volume-control.js 6570 */ 6571 6572 6573// Required children 6574 6575 6576/** 6577 * The component for controlling the volume level 6578 * 6579 * @extends Component 6580 */ 6581var VolumeControl = function (_Component) { 6582 _inherits(VolumeControl, _Component); 6583 6584 /** 6585 * Creates an instance of this class. 6586 * 6587 * @param {Player} player 6588 * The `Player` that this class should be attached to. 6589 * 6590 * @param {Object} [options={}] 6591 * The key/value store of player options. 6592 */ 6593 function VolumeControl(player, options) { 6594 _classCallCheck(this, VolumeControl); 6595 6596 // hide volume controls when they're not supported by the current tech 6597 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 6598 6599 if (player.tech_ && player.tech_.featuresVolumeControl === false) { 6600 _this.addClass('vjs-hidden'); 6601 } 6602 _this.on(player, 'loadstart', function () { 6603 if (player.tech_.featuresVolumeControl === false) { 6604 this.addClass('vjs-hidden'); 6605 } else { 6606 this.removeClass('vjs-hidden'); 6607 } 6608 }); 6609 return _this; 6610 } 6611 6612 /** 6613 * Create the `Component`'s DOM element 6614 * 6615 * @return {Element} 6616 * The element that was created. 6617 */ 6618 6619 6620 VolumeControl.prototype.createEl = function createEl() { 6621 return _Component.prototype.createEl.call(this, 'div', { 6622 className: 'vjs-volume-control vjs-control' 6623 }); 6624 }; 6625 6626 return VolumeControl; 6627}(_component2['default']); 6628 6629/** 6630 * Default options for the `VolumeControl` 6631 * 6632 * @type {Object} 6633 * @private 6634 */ 6635 6636 6637VolumeControl.prototype.options_ = { 6638 children: ['volumeBar'] 6639}; 6640 6641_component2['default'].registerComponent('VolumeControl', VolumeControl); 6642exports['default'] = VolumeControl; 6643 6644},{"37":37,"5":5}],39:[function(_dereq_,module,exports){ 6645'use strict'; 6646 6647exports.__esModule = true; 6648 6649var _component = _dereq_(5); 6650 6651var _component2 = _interopRequireDefault(_component); 6652 6653function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6654 6655function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6656 6657function _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; } 6658 6659function _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; } /** 6660 * @file volume-level.js 6661 */ 6662 6663 6664/** 6665 * Shows volume level 6666 * 6667 * @extends Component 6668 */ 6669var VolumeLevel = function (_Component) { 6670 _inherits(VolumeLevel, _Component); 6671 6672 function VolumeLevel() { 6673 _classCallCheck(this, VolumeLevel); 6674 6675 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 6676 } 6677 6678 /** 6679 * Create the `Component`'s DOM element 6680 * 6681 * @return {Element} 6682 * The element that was created. 6683 */ 6684 VolumeLevel.prototype.createEl = function createEl() { 6685 return _Component.prototype.createEl.call(this, 'div', { 6686 className: 'vjs-volume-level', 6687 innerHTML: '<span class="vjs-control-text"></span>' 6688 }); 6689 }; 6690 6691 return VolumeLevel; 6692}(_component2['default']); 6693 6694_component2['default'].registerComponent('VolumeLevel', VolumeLevel); 6695exports['default'] = VolumeLevel; 6696 6697},{"5":5}],40:[function(_dereq_,module,exports){ 6698'use strict'; 6699 6700exports.__esModule = true; 6701 6702var _fn = _dereq_(83); 6703 6704var Fn = _interopRequireWildcard(_fn); 6705 6706var _component = _dereq_(5); 6707 6708var _component2 = _interopRequireDefault(_component); 6709 6710var _popup = _dereq_(54); 6711 6712var _popup2 = _interopRequireDefault(_popup); 6713 6714var _popupButton = _dereq_(53); 6715 6716var _popupButton2 = _interopRequireDefault(_popupButton); 6717 6718var _muteToggle = _dereq_(11); 6719 6720var _muteToggle2 = _interopRequireDefault(_muteToggle); 6721 6722var _volumeBar = _dereq_(37); 6723 6724var _volumeBar2 = _interopRequireDefault(_volumeBar); 6725 6726function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6727 6728function _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; } } 6729 6730function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6731 6732function _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; } 6733 6734function _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
6734onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6735 * @file volume-menu-button.js 6736 */ 6737 6738 6739/** 6740 * Button for volume popup 6741 * 6742 * @extends PopupButton 6743 */ 6744var VolumeMenuButton = function (_PopupButton) { 6745 _inherits(VolumeMenuButton, _PopupButton); 6746 6747 /** 6748 * Creates an instance of this class. 6749 * 6750 * @param {Player} player 6751 * The `Player` that this class should be attached to. 6752 * 6753 * @param {Object} [options={}] 6754 * The key/value store of player options. 6755 */ 6756 function VolumeMenuButton(player) { 6757 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 6758 6759 _classCallCheck(this, VolumeMenuButton); 6760 6761 // Default to inline 6762 if (options.inline === undefined) { 6763 options.inline = true; 6764 } 6765 6766 // If the vertical option isn't passed at all, default to true. 6767 if (options.vertical === undefined) { 6768 // If an inline volumeMenuButton is used, we should default to using 6769 // a horizontal slider for obvious reasons. 6770 if (options.inline) { 6771 options.vertical = false;
6772 } else { 6773 options.vertical = true; 6774 } 6775 } 6776 6777 // The vertical option needs to be set on the volumeBar as well, 6778 // since that will need to be passed along to the VolumeBar constructor 6779 options.volumeBar = options.volumeBar || {}; 6780 options.volumeBar.vertical = !!options.vertical; 6781 6782 // Same listeners as MuteToggle 6783 var _this = _possibleConstructorReturn(this, _PopupButton.call(this, player, options)); 6784 6785 _this.on(player, 'volumechange', _this.volumeUpdate); 6786 _this.on(player, 'loadstart', _this.volumeUpdate); 6787 6788 // hide mute toggle if the current tech doesn't support volume control 6789 function updateVisibility() { 6790 if (player.tech_ && player.tech_.featuresVolumeControl === false) { 6791 this.addClass('vjs-hidden'); 6792 } else { 6793 this.removeClass('vjs-hidden'); 6794 } 6795 } 6796 6797 updateVisibility.call(_this); 6798 _this.on(player, 'loadstart', updateVisibility); 6799 6800 _this.on(_this.volumeBar, ['slideractive', 'focus'], function () { 6801 this.addClass('vjs-slider-active'); 6802 }); 6803 6804 _this.on(_this.volumeBar, ['sliderinactive', 'blur'], function () { 6805 this.removeClass('vjs-slider-active'); 6806 }); 6807 6808 _this.on(_this.volumeBar, ['focus'], function () { 6809 this.addClass('vjs-lock-showing'); 6810 }); 6811 6812 _this.on(_this.volumeBar, ['blur'], function () { 6813 this.removeClass('vjs-lock-showing'); 6814 }); 6815 return _this; 6816 } 6817 6818 /** 6819 * Builds the default DOM `className`. 6820 * 6821 * @return {string} 6822 * The DOM `className` for this object. 6823 */ 6824 6825 6826 VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() { 6827 var orientationClass = ''; 6828 6829 if (this.options_.vertical) { 6830 orientationClass = 'vjs-volume-menu-button-vertical'; 6831 } else { 6832 orientationClass = 'vjs-volume-menu-button-horizontal'; 6833 } 6834 6835 return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass; 6836 }; 6837 6838 /** 6839 * Create the VolumeMenuButton popup 6840 * 6841 * @return {Popup} 6842 * The popup that was created 6843 */ 6844 6845 6846 VolumeMenuButton.prototype.createPopup = function createPopup() { 6847 var popup = new _popup2['default'](this.player_, { 6848 contentElType: 'div' 6849 }); 6850 6851 var vb = new _volumeBar2['default'](this.player_, this.options_.volumeBar); 6852 6853 popup.addChild(vb); 6854 6855 this.menuContent = popup; 6856 this.volumeBar = vb; 6857 6858 this.attachVolumeBarEvents(); 6859 6860 return popup; 6861 }; 6862 6863 /** 6864 * This gets called when an `VolumeMenuButton` is "clicked". See 6865 * {@link ClickableComponent} for more detailed information on what a click can be. 6866 * 6867 * @param {EventTarget~Event} [event] 6868 * The `keydown`, `tap`, or `click` event that caused this function to be 6869 * called. 6870 * 6871 * @listens tap 6872 * @listens click 6873 */ 6874 6875 6876 VolumeMenuButton.prototype.handleClick = function handleClick(event) { 6877 _muteToggle2['default'].prototype.handleClick.call(this); 6878 _PopupButton.prototype.handleClick.call(this); 6879 }; 6880 6881 /** 6882 * Add events listeners to the created `VolumeBar`. 6883 */ 6884 6885 6886 VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() { 6887 this.menuContent.on(['mousedown', 'touchdown'], Fn.bind(this, this.handleMouseDown)); 6888 }; 6889 6890 /** 6891 * Handle the `mousedown` and `touchdown` events on the `VolumeBar` 6892 * 6893 * @param {EventTarget~Event} [event] 6894 * The `mousedown` or `touchdown` event that caused this to run. 6895 * 6896 * @listens mousedown 6897 * @listens touchdown 6898 */ 6899 6900 6901 VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) { 6902 this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove)); 6903 this.on(this.el_.ownerDocument, ['mouseup', 'touchend'], this.handleMouseUp); 6904 }; 6905 6906 /** 6907 * Handle the `mouseup` and `touchend` events on the `VolumeBar` 6908 * 6909 * @param {EventTarget~Event} [event] 6910 * The `mouseup` or `touchend` event that caused this to run. 6911 * 6912 * @listens mouseup 6913 * @listens touchend 6914 */ 6915 6916 6917 VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) { 6918 this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove)); 6919 }; 6920 6921 return VolumeMenuButton; 6922}(_popupButton2['default']); 6923 6924/** 6925 * @borrows MuteToggle#update as VolumeMenuButton#volumeUpdate 6926 */ 6927 6928 6929VolumeMenuButton.prototype.volumeUpdate = _muteToggle2['default'].prototype.update; 6930 6931/** 6932 * The text that should display over the `VolumeMenuButton`s controls. Added for localization. 6933 * 6934 * @type {string} 6935 * @private 6936 */ 6937VolumeMenuButton.prototype.controlText_ = 'Mute'; 6938 6939_component2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton); 6940exports['default'] = VolumeMenuButton; 6941 6942},{"11":11,"37":37,"5":5,"53":53,"54":54,"83":83}],41:[function(_dereq_,module,exports){ 6943'use strict'; 6944 6945exports.__esModule = true; 6946 6947var _component = _dereq_(5); 6948 6949var _component2 = _interopRequireDefault(_component); 6950 6951var _modalDialog = _dereq_(50); 6952 6953var _modalDialog2 = _interopRequireDefault(_modalDialog); 6954 6955var _mergeOptions = _dereq_(87); 6956 6957var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 6958 6959function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6960 6961function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6962 6963function _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; } 6964 6965function _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
6965onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 6966 * @file error-display.js 6967 */ 6968 6969 6970/** 6971 * A display that indicates an error has occurred. This means that the video 6972 * is unplayable. 6973 * 6974 * @extends ModalDialog 6975 */ 6976var ErrorDisplay = function (_ModalDialog) { 6977 _inherits(ErrorDisplay, _ModalDialog); 6978 6979 /** 6980 * Creates an instance of this class. 6981 * 6982 * @param {Player} player 6983 * The `Player` that this class should be attached to. 6984 * 6985 * @param {Object} [options] 6986 * The key/value store of player options. 6987 */ 6988 function ErrorDisplay(player, options) { 6989 _classCallCheck(this, ErrorDisplay); 6990 6991 var _this = _possibleConstructorReturn(this, _ModalDialog.call(this, player, options)); 6992 6993 _this.on(player, 'error', _this.open); 6994 return _this; 6995 } 6996 6997 /** 6998 * Builds the default DOM `className`. 6999 * 7000 * @return {string} 7001 * The DOM `className` for this object. 7002 * 7003 * @deprecated Since version 5. 7004 */ 7005 7006 7007 ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() { 7008 return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this); 7009 }; 7010 7011 /** 7012 * Gets the localized error message based on the `Player`s error. 7013 * 7014 * @return {string} 7015 * The `Player`s error message localized or an empty string. 7016 */ 7017 7018 7019 ErrorDisplay.prototype.content = function content() { 7020 var error = this.player().error(); 7021 7022 return error ? this.localize(error.message) : ''; 7023 }; 7024 7025 return ErrorDisplay; 7026}(_modalDialog2['default']); 7027 7028/** 7029 * The default options for an `ErrorDisplay`. 7030 * 7031 * @private 7032 */ 7033 7034 7035ErrorDisplay.prototype.options_ = (0, _mergeOptions2['default'])(_modalDialog2['default'].prototype.options_, { 7036 fillAlways: true, 7037 temporary: false, 7038 uncloseable: true 7039}); 7040 7041_component2['default'].registerComponent('ErrorDisplay', ErrorDisplay); 7042exports['default'] = ErrorDisplay; 7043 7044},{"5":5,"50":50,"87":87}],42:[function(_dereq_,module,exports){ 7045'use strict'; 7046 7047exports.__esModule = true; 7048 7049var _events = _dereq_(82); 7050 7051var Events = _interopRequireWildcard(_events); 7052 7053function _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; } } 7054 7055/** 7056 * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It 7057 * adds shorthand functions that wrap around lengthy functions. For example: 7058 * the `on` function is a wrapper around `addEventListener`. 7059 * 7060 * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget} 7061 * @class EventTarget 7062 */ 7063var EventTarget = function EventTarget() {}; 7064 7065/** 7066 * A Custom DOM event. 7067 * 7068 * @typedef {Object} EventTarget~Event 7069 * @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent} 7070 */ 7071 7072/** 7073 * All event listeners should follow the following format. 7074 * 7075 * @callback EventTarget~EventListener 7076 * @this {EventTarget} 7077 * 7078 * @param {EventTarget~Event} event 7079 * the event that triggered this function 7080 * 7081 * @param {Object} [hash] 7082 * hash of data sent during the event 7083 */ 7084 7085/**
7086 * An object containing event names as keys and booleans as values. 7087 * 7088 * > NOTE: If an event name is set to a true value here {@link EventTarget#trigger} 7089 * will have extra functionality. See that function for more information. 7090 * 7091 * @property EventTarget.prototype.allowedEvents_ 7092 * @private 7093 */ 7094/** 7095 * @file src/js/event-target.js 7096 */ 7097EventTarget.prototype.allowedEvents_ = {}; 7098 7099/** 7100 * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a 7101 * function that will get called when an event with a certain name gets triggered. 7102 * 7103 * @param {string|string[]} type 7104 * An event name or an array of event names. 7105 * 7106 * @param {EventTarget~EventListener} fn 7107 * The function to call with `EventTarget`s 7108 */ 7109EventTarget.prototype.on = function (type, fn) { 7110 // Remove the addEventListener alias before calling Events.on 7111 // so we don't get into an infinite type loop 7112 var ael = this.addEventListener; 7113 7114 this.addEventListener = function () {}; 7115 Events.on(this, type, fn); 7116 this.addEventListener = ael; 7117}; 7118 7119/** 7120 * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic 7121 * the standard DOM API. 7122 * 7123 * @function 7124 * @see {@link EventTarget#on} 7125 */ 7126EventTarget.prototype.addEventListener = EventTarget.prototype.on; 7127 7128/** 7129 * Removes an `event listener` for a specific event from an instance of `EventTarget`. 7130 * This makes it so that the `event listener` will no longer get called when the 7131 * named event happens. 7132 * 7133 * @param {string|string[]} type 7134 * An event name or an array of event names. 7135 * 7136 * @param {EventTarget~EventListener} fn 7137 * The function to remove. 7138 */ 7139EventTarget.prototype.off = function (type, fn) { 7140 Events.off(this, type, fn); 7141}; 7142 7143/** 7144 * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic 7145 * the standard DOM API. 7146 * 7147 * @function 7148 * @see {@link EventTarget#off} 7149 */ 7150EventTarget.prototype.removeEventListener = EventTarget.prototype.off; 7151 7152/** 7153 * This function will add an `event listener` that gets triggered only once. After the 7154 * first trigger it will get removed. This is like adding an `event listener` 7155 * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself. 7156 * 7157 * @param {string|string[]} type 7158 * An event name or an array of event names. 7159 * 7160 * @param {EventTarget~EventListener} fn 7161 * The function to be called once for each event name. 7162 */ 7163EventTarget.prototype.one = function (type, fn) { 7164 // Remove the addEventListener alialing Events.on 7165 // so we don't get into an infinite type loop 7166 var ael = this.addEventListener; 7167 7168 this.addEventListener = function () {}; 7169 Events.one(this, type, fn); 7170 this.addEventListener = ael; 7171}; 7172 7173/** 7174 * This function causes an event to happen. This will then cause any `event listeners` 7175 * that are waiting for that event, to get called. If there are no `event listeners` 7176 * for an event then nothing will happen. 7177 * 7178 * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`. 7179 * Trigger will also call the `on` + `uppercaseEventName` function. 7180 * 7181 * Example: 7182 * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call 7183 * `onClick` if it exists. 7184 * 7185 * @param {string|EventTarget~Event|Object} event 7186 * The name of the event, an `Event`, or an object with a key of type set to 7187 * an event name. 7188 */ 7189EventTarget.prototype.trigger = function (event) { 7190 var type = event.type || event; 7191 7192 if (typeof event === 'string') { 7193 event = { type: type }; 7194 } 7195 event = Events.fixEvent(event); 7196 7197 if (this.allowedEvents_[type] && this['on' + type]) { 7198 this['on' + type](event); 7199 } 7200 7201 Events.trigger(this, event); 7202}; 7203 7204/** 7205 * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic 7206 * the standard DOM API. 7207 * 7208 * @function 7209 * @see {@link EventTarget#trigger} 7210 */ 7211EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger; 7212 7213exports['default'] = EventTarget; 7214 7215},{"82":82}],43:[function(_dereq_,module,exports){ 7216'use strict'; 7217 7218exports.__esModule = true; 7219 7220var _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; }; 7221 7222var _log = _dereq_(86); 7223 7224var _log2 = _interopRequireDefault(_log); 7225 7226var _obj = _dereq_(88); 7227 7228function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7229 7230/** 7231 * @file extend.js 7232 * @module extend 7233 */ 7234
7235/** 7236 * A combination of node inherits and babel's inherits (after transpile). 7237 * Both work the same but node adds `super_` to the subClass 7238 * and Bable adds the superClass as __proto__. Both seem useful. 7239 * 7240 * @param {Object} subClass 7241 * The class to inherit to 7242 * 7243 * @param {Object} superClass 7244 * The class to inherit from 7245 * 7246 * @private 7247 */ 7248var _inherits = function _inherits(subClass, superClass) { 7249 if (typeof superClass !== 'function' && superClass !== null) { 7250 throw new TypeError('Super expression must either be null or a function, not ' + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass))); 7251 } 7252 7253 subClass.prototype = Object.create(superClass && superClass.prototype, { 7254 constructor: { 7255 value: subClass, 7256 enumerable: false, 7257 writable: true, 7258 configurable: true 7259 } 7260 }); 7261 7262 if (superClass) { 7263 // node 7264 subClass.super_ = superClass; 7265 } 7266}; 7267 7268/** 7269 * Function for subclassing using the same inheritance that 7270 * videojs uses internally 7271 * 7272 * @param {Object} superClass 7273 * The class to inherit from 7274 * 7275 * @param {Object} [subClassMethods={}] 7276 * The class to inherit to 7277 * 7278 * @return {Object} 7279 * The new object with subClassMethods that inherited superClass. 7280 */ 7281var extendFn = function extendFn(superClass) { 7282 var subClassMethods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 7283 7284 var subClass = function subClass() { 7285 superClass.apply(this, arguments); 7286 }; 7287 7288 var methods = {}; 7289 7290 if ((0, _obj.isObject)(subClassMethods)) { 7291 if (typeof subClassMethods.init === 'function') { 7292 _log2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.'); 7293 subClassMethods.constructor = subClassMethods.init; 7294 } 7295 if (subClassMethods.constructor !== Object.prototype.constructor) { 7296 subClass = subClassMethods.constructor; 7297 } 7298 methods = subClassMethods; 7299 } else if (typeof subClassMethods === 'function') { 7300 subClass = subClassMethods; 7301 } 7302 7303 _inherits(subClass, superClass); 7304 7305 // Extend subObj's prototype with functions and other properties from props 7306 for (var name in methods) { 7307 if (methods.hasOwnProperty(name)) { 7308 subClass.prototype[name] = methods[name]; 7309 } 7310 } 7311 7312 return subClass; 7313}; 7314 7315exports['default'] = extendFn; 7316 7317},{"86":86,"88":88}],44:[function(_dereq_,module,exports){ 7318'use strict'; 7319 7320exports.__esModule = true; 7321 7322var _document = _dereq_(94); 7323 7324var _document2 = _interopRequireDefault(_document); 7325 7326function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7327 7328/** 7329 * Store the browser-specific methods for the fullscreen API. 7330 * 7331 * @type {Object} 7332 * @see [Specification]{@link https://fullscreen.spec.whatwg.org} 7333 * @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js} 7334 */ 7335var FullscreenApi = {}; 7336 7337// browser API methods 7338/** 7339 * @file fullscreen-api.js 7340 * @module fullscreen-api 7341 * @private 7342 */ 7343var apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'], 7344// WebKit 7345['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'], 7346// Old WebKit (Safari 5.1) 7347['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'], 7348// Mozilla 7349['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'], 7350// Microsoft 7351['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']]; 7352 7353var specApi = apiMap[0]; 7354var browserApi = void 0; 7355 7356// determine the supported set of functions 7357for (var i = 0; i < apiMap.length; i++) { 7358 // check for exitFullscreen function 7359 if (apiMap[i][1] in _document2['default']) { 7360 browserApi = apiMap[i]; 7361 break; 7362 } 7363} 7364 7365// map the browser API names to the spec API names 7366if (browserApi) { 7367 for (var _i = 0; _i < browserApi.length; _i++) { 7368 FullscreenApi[specApi[_i]] = browserApi[_i]; 7369 } 7370} 7371 7372exports['default'] = FullscreenApi; 7373 7374},{"94":94}],45:[function(_dereq_,module,exports){ 7375'use strict'; 7376 7377exports.__esModule = true; 7378 7379var _component = _dereq_(5); 7380 7381var _component2 = _interopRequireDefault(_component); 7382 7383function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7384 7385function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 7386 7387function _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; } 7388 7389function _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
7389onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 7390 * @file loading-spinner.js 7391 */ 7392 7393 7394/** 7395 * A loading spinner for use during waiting/loading events. 7396 * 7397 * @extends Component 7398 */ 7399var LoadingSpinner = function (_Component) { 7400 _inherits(LoadingSpinner, _Component); 7401 7402 function LoadingSpinner() { 7403 _classCallCheck(this, LoadingSpinner); 7404 7405 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 7406 } 7407 7408 /** 7409 * Create the `LoadingSpinner`s DOM element. 7410 * 7411 * @return {Element} 7412 * The dom element that gets created. 7413 */ 7414 LoadingSpinner.prototype.createEl = function createEl() { 7415 return _Component.prototype.createEl.call(this, 'div', { 7416 className: 'vjs-loading-spinner', 7417 dir: 'ltr' 7418 }); 7419 }; 7420 7421 return LoadingSpinner; 7422}(_component2['default']); 7423 7424_component2['default'].registerComponent('LoadingSpinner', LoadingSpinner); 7425exports['default'] = LoadingSpinner; 7426 7427},{"5":5}],46:[function(_dereq_,module,exports){ 7428'use strict'; 7429 7430exports.__esModule = true; 7431 7432var _obj = _dereq_(88); 7433 7434/** 7435 * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class. 7436 * 7437 * @param {number|string|Object|MediaError} value 7438 * This can be of multiple types: 7439 * - number: should be a standard error code 7440 * - string: an error message (the code will be 0) 7441 * - Object: arbitrary properties 7442 * - `MediaError` (native): used to populate a video.js `MediaError` object 7443 * - `MediaError` (video.js): will return itself if it's already a 7444 * video.js `MediaError` object. 7445 * 7446 * @see [MediaError Spec]{@link https://dev.w3.org/html5/spec-author-view/video.html#mediaerror} 7447 * @see [Encrypted MediaError Spec]{@link https://www.w3.org/TR/2013/WD-encrypted-media-20130510/#error-codes} 7448 * 7449 * @class MediaError 7450 */ 7451function MediaError(value) { 7452 7453 // Allow redundant calls to this constructor to avoid having `instanceof` 7454 // checks peppered around the code. 7455 if (value instanceof MediaError) { 7456 return value; 7457 } 7458 7459 if (typeof value === 'number') { 7460 this.code = value; 7461 } else if (typeof value === 'string') {
7462 // default code is zero, so this is a custom error 7463 this.message = value; 7464 } else if ((0, _obj.isObject)(value)) { 7465 7466 // We assign the `code` property manually because native `MediaError` objects 7467 // do not expose it as an own/enumerable property of the object. 7468 if (typeof value.code === 'number') { 7469 this.code = value.code; 7470 } 7471 7472 (0, _obj.assign)(this, value); 7473 } 7474 7475 if (!this.message) { 7476 this.message = MediaError.defaultMessages[this.code] || ''; 7477 } 7478} 7479 7480/** 7481 * The error code that refers two one of the defined `MediaError` types 7482 * 7483 * @type {Number} 7484 */ 7485/** 7486 * @file media-error.js 7487 */ 7488MediaError.prototype.code = 0; 7489 7490/** 7491 * An optional message that to show with the error. Message is not part of the HTML5 7492 * video spec but allows for more informative custom errors. 7493 * 7494 * @type {String} 7495 */ 7496MediaError.prototype.message = ''; 7497 7498/** 7499 * An optional status code that can be set by plugins to allow even more detail about 7500 * the error. For example a plugin might provide a specific HTTP status code and an 7501 * error message for that code. Then when the plugin gets that error this class will 7502 * know how to display an error message for it. This allows a custom message to show 7503 * up on the `Player` error overlay. 7504 * 7505 * @type {Array} 7506 */ 7507MediaError.prototype.status = null; 7508 7509/** 7510 * Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the 7511 * specification listed under {@link MediaError} for more information. 7512 * 7513 * @enum {array} 7514 * @readonly 7515 * @property {string} 0 - MEDIA_ERR_CUSTOM 7516 * @property {string} 1 - MEDIA_ERR_CUSTOM 7517 * @property {string} 2 - MEDIA_ERR_ABORTED 7518 * @property {string} 3 - MEDIA_ERR_NETWORK 7519 * @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED 7520 * @property {string} 5 - MEDIA_ERR_ENCRYPTED 7521 */ 7522MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED']; 7523 7524/** 7525 * The default `MediaError` messages based on the {@link MediaError.errorTypes}. 7526 * 7527 * @type {Array} 7528 * @constant 7529 */ 7530MediaError.defaultMessages = { 7531 1: 'You aborted the media playback', 7532 2: 'A network error caused the media download to fail part-way.', 7533 3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.', 7534 4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.', 7535 5: 'The media is encrypted and we do not have the keys to decrypt it.' 7536}; 7537 7538// Add types as properties on MediaError 7539// e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4; 7540for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) { 7541 MediaError[MediaError.errorTypes[errNum]] = errNum; 7542 // values should be accessible on both the class and instance 7543 MediaError.prototype[MediaError.errorTypes[errNum]] = errNum; 7544} 7545 7546// jsdocs for instance/static members added above 7547// instance methods use `#` and static methods use `.` 7548/** 7549 * W3C error code for any custom error. 7550 * 7551 * @member MediaError#MEDIA_ERR_CUSTOM 7552 * @constant {number} 7553 * @default 0 7554 */ 7555/** 7556 * W3C error code for any custom error. 7557 * 7558 * @member MediaError.MEDIA_ERR_CUSTOM 7559 * @constant {number} 7560 * @default 0 7561 */ 7562 7563/** 7564 * W3C error code for media error aborted. 7565 * 7566 * @member MediaError#MEDIA_ERR_ABORTED 7567 * @constant {number} 7568 * @default 1 7569 */ 7570/** 7571 * W3C error code for media error aborted. 7572 * 7573 * @member MediaError.MEDIA_ERR_ABORTED 7574 * @constant {number} 7575 * @default 1 7576 */ 7577 7578/** 7579 * W3C error code for any network error. 7580 * 7581 * @member MediaError#MEDIA_ERR_NETWORK 7582 * @constant {number} 7583 * @default 2 7584 */ 7585/** 7586 * W3C error code for any network error. 7587 * 7588 * @member MediaError.MEDIA_ERR_NETWORK 7589 * @constant {number} 7590 * @default 2 7591 */ 7592 7593/** 7594 * W3C error code for any decoding error. 7595 * 7596 * @member MediaError#MEDIA_ERR_DECODE 7597 * @constant {number} 7598 * @default 3 7599 */ 7600/** 7601 * W3C error code for any decoding error. 7602 * 7603 * @member MediaError.MEDIA_ERR_DECODE 7604 * @constant {number} 7605 * @default 3 7606 */ 7607 7608/** 7609 * W3C error code for any time that a source is not supported. 7610 * 7611 * @member MediaError#MEDIA_ERR_SRC_NOT_SUPPORTED 7612 * @constant {number} 7613 * @default 4 7614 */ 7615/** 7616 * W3C error code for any time that a source is not supported. 7617 * 7618 * @member MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED 7619 * @constant {number} 7620 * @default 4 7621 */ 7622 7623/** 7624 * W3C error code for any time that a source is encrypted. 7625 * 7626 * @member MediaError#MEDIA_ERR_ENCRYPTED 7627 * @constant {number} 7628 * @default 5 7629 */ 7630/** 7631 * W3C error code for any time that a source is encrypted. 7632 * 7633 * @member MediaError.MEDIA_ERR_ENCRYPTED 7634 * @constant {number} 7635 * @default 5 7636 */ 7637 7638exports['default'] = MediaError; 7639 7640},{"88":88}],47:[function(_dereq_,module,exports){ 7641'use strict'; 7642 7643exports.__esModule = true; 7644 7645var _clickableComponent = _dereq_(3); 7646 7647var _clickableComponent2 = _interopRequireDefault(_clickableComponent); 7648 7649var _component = _dereq_(5); 7650 7651var _component2 = _interopRequireDefault(_component); 7652 7653var _menu = _dereq_(49); 7654 7655var _menu2 = _interopRequireDefault(_menu); 7656 7657var _dom = _dereq_(81); 7658 7659var Dom = _interopRequireWildcard(_dom); 7660 7661var _fn = _dereq_(83); 7662 7663var Fn = _interopRequireWildcard(_fn); 7664 7665var _toTitleCase = _dereq_(91); 7666 7667var _toTitleCase2 = _interopRequireDefault(_toTitleCase); 7668 7669function _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; } } 7670 7671function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7672 7673function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 7674 7675function _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; } 7676 7677function _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,792 bytes, lines 7677-7830
7677onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 7678 * @file menu-button.js 7679 */ 7680 7681 7682/** 7683 * A `MenuButton` class for any popup {@link Menu}. 7684 * 7685 * @extends ClickableComponent 7686 */ 7687var MenuButton = function (_ClickableComponent) { 7688 _inherits(MenuButton, _ClickableComponent); 7689 7690 /** 7691 * Creates an instance of this class. 7692 * 7693 * @param {Player} player 7694 * The `Player` that this class should be attached to. 7695 * 7696 * @param {Object} [options={}] 7697 * The key/value store of player options. 7698 */ 7699 function MenuButton(player) { 7700 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 7701 7702 _classCallCheck(this, MenuButton); 7703 7704 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options)); 7705 7706 _this.update(); 7707 7708 _this.enabled_ = true; 7709 7710 _this.el_.setAttribute('aria-haspopup', 'true'); 7711 _this.el_.setAttribute('role', 'menuitem'); 7712 _this.on('keydown', _this.handleSubmenuKeyPress); 7713 return _this; 7714 } 7715 7716 /** 7717 * Update the menu based on the current state of its items. 7718 */ 7719 7720 7721 MenuButton.prototype.update = function update() { 7722 var menu = this.createMenu(); 7723 7724 if (this.menu) { 7725 this.removeChild(this.menu); 7726 } 7727 7728 this.menu = menu; 7729 this.addChild(menu); 7730 7731 /** 7732 * Track the state of the menu button 7733 * 7734 * @type {Boolean} 7735 * @private 7736 */ 7737 this.buttonPressed_ = false; 7738 this.el_.setAttribute('aria-expanded', 'false'); 7739 7740 if (this.items && this.items.length === 0) { 7741 this.hide(); 7742 } else if (this.items && this.items.length > 1) { 7743 this.show(); 7744 } 7745 }; 7746 7747 /** 7748 * Create the menu and add all items to it. 7749 * 7750 * @return {Menu} 7751 * The constructed menu 7752 */ 7753 7754 7755 MenuButton.prototype.createMenu = function createMenu() { 7756 var menu = new _menu2['default'](this.player_); 7757 7758 // Add a title list item to the top 7759 if (this.options_.title) { 7760 var title = Dom.createEl('li', { 7761 className: 'vjs-menu-title', 7762 innerHTML: (0, _toTitleCase2['default'])(this.options_.title), 7763 tabIndex: -1 7764 }); 7765 7766 menu.children_.unshift(title); 7767 Dom.insertElFirst(title, menu.contentEl()); 7768 } 7769 7770 this.items = this.createItems(); 7771 7772 if (this.items) { 7773 // Add menu items to the menu 7774 for (var i = 0; i < this.items.length; i++) { 7775 menu.addItem(this.items[i]); 7776 } 7777 } 7778 7779 return menu; 7780 }; 7781 7782 /** 7783 * Create the list of menu items. Specific to each subclass. 7784 * 7785 * @abstract 7786 */ 7787 7788 7789 MenuButton.prototype.createItems = function createItems() {}; 7790 7791 /** 7792 * Create the `MenuButtons`s DOM element. 7793 * 7794 * @return {Element} 7795 * The element that gets created. 7796 */ 7797 7798 7799 MenuButton.prototype.createEl = function createEl() { 7800 return _ClickableComponent.prototype.createEl.call(this, 'div', { 7801 className: this.buildCSSClass() 7802 }); 7803 }; 7804 7805 /** 7806 * Builds the default DOM `className`. 7807 * 7808 * @return {string} 7809 * The DOM `className` for this object. 7810 */ 7811 7812 7813 MenuButton.prototype.buildCSSClass = function buildCSSClass() { 7814 var menuButtonClass = 'vjs-menu-button'; 7815 7816 // If the inline option is passed, we want to use different styles altogether. 7817 if (this.options_.inline === true) { 7818 menuButtonClass += '-inline'; 7819 } else { 7820 menuButtonClass += '-popup'; 7821 } 7822 7823 return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this); 7824 }; 7825 7826 /** 7827 * Handle a click on a `MenuButton`. 7828 * See {@link ClickableComponent#handleClick} for instances where this is called. 7829 * 7830 * @param {EventTarget~Event} event
7831 * The `keydown`, `tap`, or `click` event that caused this function to be 7832 * called. 7833 * 7834 * @listens tap 7835 * @listens click 7836 */ 7837 7838 7839 MenuButton.prototype.handleClick = function handleClick(event) { 7840 // When you click the button it adds focus, which will show the menu. 7841 // So we'll remove focus when the mouse leaves the button. Focus is needed 7842 // for tab navigation. 7843 7844 this.one(this.menu.contentEl(), 'mouseleave', Fn.bind(this, function (e) { 7845 this.unpressButton(); 7846 this.el_.blur(); 7847 })); 7848 if (this.buttonPressed_) { 7849 this.unpressButton(); 7850 } else { 7851 this.pressButton(); 7852 } 7853 }; 7854 7855 /** 7856 * Handle tab, escape, down arrow, and up arrow keys for `MenuButton`. See 7857 * {@link ClickableComponent#handleKeyPress} for instances where this is called. 7858 * 7859 * @param {EventTarget~Event} event 7860 * The `keydown` event that caused this function to be called. 7861 * 7862 * @listens keydown 7863 */ 7864 7865 7866 MenuButton.prototype.handleKeyPress = function handleKeyPress(event) { 7867 7868 // Escape (27) key or Tab (9) key unpress the 'button' 7869 if (event.which === 27 || event.which === 9) { 7870 if (this.buttonPressed_) { 7871 this.unpressButton(); 7872 } 7873 // Don't preventDefault for Tab key - we still want to lose focus 7874 if (event.which !== 9) { 7875 event.preventDefault(); 7876 } 7877 // Up (38) key or Down (40) key press the 'button' 7878 } else if (event.which === 38 || event.which === 40) { 7879 if (!this.buttonPressed_) { 7880 this.pressButton(); 7881 event.preventDefault(); 7882 } 7883 } else { 7884 _ClickableComponent.prototype.handleKeyPress.call(this, event); 7885 } 7886 }; 7887 7888 /** 7889 * Handle a `keydown` event on a sub-menu. The listener for this is added in 7890 * the constructor. 7891 * 7892 * @param {EventTarget~Event} event 7893 * Key press event 7894 * 7895 * @listens keydown 7896 */ 7897 7898 7899 MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) { 7900 7901 // Escape (27) key or Tab (9) key unpress the 'button' 7902 if (event.which === 27 || event.which === 9) { 7903 if (this.buttonPressed_) { 7904 this.unpressButton(); 7905 } 7906 // Don't preventDefault for Tab key - we still want to lose focus 7907 if (event.which !== 9) { 7908 event.preventDefault(); 7909 } 7910 } 7911 }; 7912 7913 /** 7914 * Put the current `MenuButton` into a pressed state. 7915 */ 7916 7917 7918 MenuButton.prototype.pressButton = function pressButton() { 7919 if (this.enabled_) { 7920 this.buttonPressed_ = true; 7921 this.menu.lockShowing(); 7922 this.el_.setAttribute('aria-expanded', 'true'); 7923 // set the focus into the submenu 7924 this.menu.focus(); 7925 } 7926 }; 7927 7928 /** 7929 * Take the current `MenuButton` out of a pressed state. 7930 */ 7931 7932 7933 MenuButton.prototype.unpressButton = function unpressButton() { 7934 if (this.enabled_) { 7935 this.buttonPressed_ = false; 7936 this.menu.unlockShowing(); 7937 this.el_.setAttribute('aria-expanded', 'false'); 7938 // Set focus back to this menu button 7939 this.el_.focus(); 7940 } 7941 }; 7942 7943 /** 7944 * Disable the `MenuButton`. Don't allow it to be clicked. 7945 * 7946 * @return {MenuButton} 7947 * Returns itself; method can be chained. 7948 */ 7949 7950 7951 MenuButton.prototype.disable = function disable() { 7952 // Unpress, but don't force focus on this button 7953 this.buttonPressed_ = false; 7954 this.menu.unlockShowing(); 7955 this.el_.setAttribute('aria-expanded', 'false'); 7956 7957 this.enabled_ = false; 7958 7959 return _ClickableComponent.prototype.disable.call(this); 7960 }; 7961 7962 /** 7963 * Enable the `MenuButton`. Allow it to be clicked. 7964 * 7965 * @return {MenuButton} 7966 * Returns itself; method can be chained. 7967 */ 7968 7969 7970 MenuButton.prototype.enable = function enable() { 7971 this.enabled_ = true; 7972 7973 return _ClickableComponent.prototype.enable.call(this); 7974 }; 7975 7976 return MenuButton; 7977}(_clickableComponent2['default']); 7978 7979_component2['default'].registerComponent('MenuButton', MenuButton); 7980exports['default'] = MenuButton; 7981 7982},{"3":3,"49":49,"5":5,"81":81,"83":83,"91":91}],48:[function(_dereq_,module,exports){ 7983'use strict'; 7984 7985exports.__esModule = true; 7986 7987var _clickableComponent = _dereq_(3); 7988 7989var _clickableComponent2 = _interopRequireDefault(_clickableComponent); 7990 7991var _component = _dereq_(5); 7992 7993var _component2 = _interopRequireDefault(_component); 7994 7995var _obj = _dereq_(88); 7996 7997function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7998 7999function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 8000 8001function _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; } 8002 8003function _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 8003-8115
8003onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 8004 * @file menu-item.js 8005 */ 8006 8007 8008/** 8009 * The component for a menu item. `<li>` 8010 * 8011 * @extends ClickableComponent 8012 */ 8013var MenuItem = function (_ClickableComponent) { 8014 _inherits(MenuItem, _ClickableComponent); 8015 8016 /** 8017 * Creates an instance of the this class. 8018 * 8019 * @param {Player} player 8020 * The `Player` that this class should be attached to. 8021 * 8022 * @param {Object} [options={}] 8023 * The key/value store of player options. 8024 * 8025 */ 8026 function MenuItem(player, options) { 8027 _classCallCheck(this, MenuItem); 8028 8029 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options)); 8030 8031 _this.selectable = options.selectable; 8032 8033 _this.selected(options.selected); 8034 8035 if (_this.selectable) { 8036 // TODO: May need to be either menuitemcheckbox or menuitemradio, 8037 // and may need logical grouping of menu items. 8038 _this.el_.setAttribute('role', 'menuitemcheckbox'); 8039 } else { 8040 _this.el_.setAttribute('role', 'menuitem'); 8041 } 8042 return _this; 8043 } 8044 8045 /** 8046 * Create the `MenuItem's DOM element 8047 * 8048 * @param {string} [type=li] 8049 * Element's node type, not actually used, always set to `li`. 8050 * 8051 * @param {Object} [props={}] 8052 * An object of properties that should be set on the element 8053 * 8054 * @param {Object} [attrs={}] 8055 * An object of attributes that should be set on the element 8056 * 8057 * @return {Element} 8058 * The element that gets created. 8059 */ 8060 8061 8062 MenuItem.prototype.createEl = function createEl(type, props, attrs) { 8063 // The control is textual, not just an icon 8064 this.nonIconControl = true; 8065 8066 return _ClickableComponent.prototype.createEl.call(this, 'li', (0, _obj.assign)({ 8067 className: 'vjs-menu-item', 8068 innerHTML: this.localize(this.options_.label), 8069 tabIndex: -1 8070 }, props), attrs); 8071 }; 8072 8073 /** 8074 * Any click on a `MenuItem` puts int into the selected state. 8075 * See {@link ClickableComponent#handleClick} for instances where this is called. 8076 * 8077 * @param {EventTarget~Event} event 8078 * The `keydown`, `tap`, or `click` event that caused this function to be 8079 * called. 8080 * 8081 * @listens tap 8082 * @listens click 8083 */ 8084 8085 8086 MenuItem.prototype.handleClick = function handleClick(event) { 8087 this.selected(true); 8088 }; 8089 8090 /** 8091 * Set the state for this menu item as selected or not. 8092 * 8093 * @param {boolean} selected 8094 * if the menu item is selected or not 8095 */ 8096 8097 8098 MenuItem.prototype.selected = function selected(_selected) { 8099 if (this.selectable) { 8100 if (_selected) { 8101 this.addClass('vjs-selected'); 8102 this.el_.setAttribute('aria-checked', 'true'); 8103 // aria-checked isn't fully supported by browsers/screen readers, 8104 // so indicate selected state to screen reader in the control text. 8105 this.controlText(', selected'); 8106 } else { 8107 this.removeClass('vjs-selected'); 8108 this.el_.setAttribute('aria-checked', 'false'); 8109 // Indicate un-selected state to screen reader 8110 // Note that a space clears out the selected state text 8111 this.controlText(' '); 8112 } 8113 } 8114 }; 8115
8116 return MenuItem; 8117}(_clickableComponent2['default']); 8118 8119_component2['default'].registerComponent('MenuItem', MenuItem); 8120exports['default'] = MenuItem; 8121 8122},{"3":3,"5":5,"88":88}],49:[function(_dereq_,module,exports){ 8123'use strict'; 8124 8125exports.__esModule = true; 8126 8127var _component = _dereq_(5); 8128 8129var _component2 = _interopRequireDefault(_component); 8130 8131var _dom = _dereq_(81); 8132 8133var Dom = _interopRequireWildcard(_dom); 8134 8135var _fn = _dereq_(83); 8136 8137var Fn = _interopRequireWildcard(_fn); 8138 8139var _events = _dereq_(82); 8140 8141var Events = _interopRequireWildcard(_events); 8142 8143function _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; } } 8144 8145function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8146 8147function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 8148 8149function _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; } 8150 8151function _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; } /** 8152 * @file menu.js 8153 */ 8154 8155 8156/** 8157 * The Menu component is used to build popup menus, including subtitle and 8158 * captions selection menus. 8159 * 8160 * @extends Component 8161 */ 8162var Menu = function (_Component) { 8163 _inherits(Menu, _Component); 8164 8165 /** 8166 * Create an instance of this class. 8167 * 8168 * @param {Player} player 8169 * the player that this component should attach to 8170 * 8171 * @param {Object} [options] 8172 * Object of option names and values 8173 * 8174 */ 8175 function Menu(player, options) { 8176 _classCallCheck(this, Menu); 8177 8178 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 8179 8180 _this.focusedChild_ = -1; 8181 8182 _this.on('keydown', _this.handleKeyPress); 8183 return _this; 8184 } 8185 8186 /** 8187 * Add a {@link MenuItem} to the menu. 8188 * 8189 * @param {Object|string} component 8190 * The name or instance of the `MenuItem` to add. 8191 * 8192 */ 8193 8194 8195 Menu.prototype.addItem = function addItem(component) { 8196 this.addChild(component); 8197 component.on('click', Fn.bind(this, function (event) { 8198 this.unlockShowing(); 8199 // TODO: Need to set keyboard focus back to the menuButton 8200 })); 8201 }; 8202 8203 /** 8204 * Create the `Menu`s DOM element. 8205 * 8206 * @return {Element} 8207 * the element that was created 8208 */ 8209 8210 8211 Menu.prototype.createEl = function createEl() { 8212 var contentElType = this.options_.contentElType || 'ul'; 8213 8214 this.contentEl_ = Dom.createEl(contentElType, { 8215 className: 'vjs-menu-content' 8216 }); 8217 8218 this.contentEl_.setAttribute('role', 'menu'); 8219 8220 var el = _Component.prototype.createEl.call(this, 'div', { 8221 append: this.contentEl_, 8222 className: 'vjs-menu' 8223 }); 8224 8225 el.setAttribute('role', 'presentation'); 8226 el.appendChild(this.contentEl_); 8227 8228 // Prevent clicks from bubbling up. Needed for Menu Buttons, 8229 // where a click on the parent is significant 8230 Events.on(el, 'click', function (event) { 8231 event.preventDefault(); 8232 event.stopImmediatePropagation(); 8233 }); 8234 8235 return el; 8236 }; 8237 8238 /** 8239 * Handle a `keydown` event on this menu. This listener is added in the constructor. 8240 * 8241 * @param {EventTarget~Event} event 8242 * A `keydown` event that happened on the menu. 8243 * 8244 * @listens keydown 8245 */ 8246 8247 8248 Menu.prototype.handleKeyPress = function handleKeyPress(event) { 8249 // Left and Down Arrows 8250 if (event.which === 37 || event.which === 40) { 8251 event.preventDefault(); 8252 this.stepForward(); 8253 8254 // Up and Right Arrows 8255 } else if (event.which === 38 || event.which === 39) { 8256 event.preventDefault(); 8257 this.stepBack(); 8258 } 8259 }; 8260 8261 /** 8262 * Move to next (lower) menu item for keyboard users. 8263 */ 8264 8265 8266 Menu.prototype.stepForward = function stepForward() {
8267 var stepChild = 0; 8268 8269 if (this.focusedChild_ !== undefined) { 8270 stepChild = this.focusedChild_ + 1; 8271 } 8272 this.focus(stepChild); 8273 }; 8274 8275 /** 8276 * Move to previous (higher) menu item for keyboard users. 8277 */ 8278 8279 8280 Menu.prototype.stepBack = function stepBack() { 8281 var stepChild = 0; 8282 8283 if (this.focusedChild_ !== undefined) { 8284 stepChild = this.focusedChild_ - 1; 8285 } 8286 this.focus(stepChild); 8287 }; 8288 8289 /** 8290 * Set focus on a {@link MenuItem} in the `Menu`. 8291 * 8292 * @param {Object|string} [item=0] 8293 * Index of child item set focus on. 8294 */ 8295 8296 8297 Menu.prototype.focus = function focus() { 8298 var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 8299 8300 var children = this.children().slice(); 8301 var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className); 8302 8303 if (haveTitle) { 8304 children.shift(); 8305 } 8306 8307 if (children.length > 0) { 8308 if (item < 0) { 8309 item = 0; 8310 } else if (item >= children.length) { 8311 item = children.length - 1; 8312 } 8313 8314 this.focusedChild_ = item; 8315 8316 children[item].el_.focus(); 8317 } 8318 }; 8319 8320 return Menu; 8321}(_component2['default']); 8322 8323_component2['default'].registerComponent('Menu', Menu); 8324exports['default'] = Menu; 8325 8326},{"5":5,"81":81,"82":82,"83":83}],50:[function(_dereq_,module,exports){ 8327'use strict'; 8328 8329exports.__esModule = true; 8330 8331var _dom = _dereq_(81); 8332 8333var Dom = _interopRequireWildcard(_dom); 8334 8335var _fn = _dereq_(83); 8336 8337var Fn = _interopRequireWildcard(_fn); 8338 8339var _component = _dereq_(5); 8340 8341var _component2 = _interopRequireDefault(_component); 8342 8343function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8344 8345function _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; } } 8346 8347function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 8348 8349function _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; } 8350 8351function _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; } /** 8352 * @file modal-dialog.js 8353 */ 8354 8355 8356var MODAL_CLASS_NAME = 'vjs-modal-dialog'; 8357var ESC = 27; 8358 8359/** 8360 * The `ModalDialog` displays over the video and its controls, which blocks 8361 * interaction with the player until it is closed. 8362 * 8363 * Modal dialogs include a "Close" button and will close when that button 8364 * is activated - or when ESC is pressed anywhere. 8365 * 8366 * @extends Component 8367 */ 8368 8369var ModalDialog = function (_Component) { 8370 _inherits(ModalDialog, _Component); 8371 8372 /** 8373 * Create an instance of this class. 8374 * 8375 * @param {Player} player 8376 * The `Player` that this class should be attached to. 8377 * 8378 * @param {Object} [options] 8379 * The key/value store of player options. 8380 * 8381 * @param {Mixed} [options.content=undefined] 8382 * Provide customized content for this modal. 8383 * 8384 * @param {string} [options.description] 8385 * A text description for the modal, primarily for accessibility. 8386 * 8387 * @param {boolean} [options.fillAlways=false] 8388 * Normally, modals are automatically filled only the first time 8389 * they open. This tells the modal to refresh its content 8390 * every time it opens. 8391 * 8392 * @param {string} [options.label] 8393 * A text label for the modal, primarily for accessibility. 8394 * 8395 * @param {boolean} [options.temporary=true] 8396 * If `true`, the modal can only be opened once; it will be 8397 * disposed as soon as it's closed. 8398 * 8399 * @param {boolean} [options.uncloseable=false] 8400 * If `true`, the user will not be able to close the modal 8401 * through the UI in the normal ways. Programmatic closing is 8402 * still possible. 8403 */ 8404 function ModalDialog(player, options) { 8405 _classCallCheck(this, ModalDialog); 8406 8407 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 8408 8409 _this.opened_ = _this.hasBeenOpened_ = _this.hasBeenFilled_ = false;
vendor: 5,049 bytes, lines 8410-8607
8410 8411 _this.closeable(!_this.options_.uncloseable); 8412 _this.content(_this.options_.content); 8413 8414 // Make sure the contentEl is defined AFTER any children are initialized 8415 // because we only want the contents of the modal in the contentEl 8416 // (not the UI elements like the close button). 8417 _this.contentEl_ = Dom.createEl('div', { 8418 className: MODAL_CLASS_NAME + '-content' 8419 }, { 8420 role: 'document' 8421 }); 8422 8423 _this.descEl_ = Dom.createEl('p', { 8424 className: MODAL_CLASS_NAME + '-description vjs-offscreen', 8425 id: _this.el().getAttribute('aria-describedby') 8426 }); 8427 8428 Dom.textContent(_this.descEl_, _this.description()); 8429 _this.el_.appendChild(_this.descEl_); 8430 _this.el_.appendChild(_this.contentEl_); 8431 return _this; 8432 } 8433 8434 /** 8435 * Create the `ModalDialog`'s DOM element 8436 * 8437 * @return {Element} 8438 * The DOM element that gets created. 8439 */ 8440 8441 8442 ModalDialog.prototype.createEl = function createEl() { 8443 return _Component.prototype.createEl.call(this, 'div', { 8444 className: this.buildCSSClass(), 8445 tabIndex: -1 8446 }, { 8447 'aria-describedby': this.id() + '_description', 8448 'aria-hidden': 'true', 8449 'aria-label': this.label(), 8450 'role': 'dialog' 8451 }); 8452 }; 8453 8454 /** 8455 * Builds the default DOM `className`. 8456 * 8457 * @return {string} 8458 * The DOM `className` for this object. 8459 */ 8460 8461 8462 ModalDialog.prototype.buildCSSClass = function buildCSSClass() { 8463 return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this); 8464 }; 8465 8466 /** 8467 * Handles `keydown` events on the document, looking for ESC, which closes 8468 * the modal. 8469 * 8470 * @param {EventTarget~Event} e 8471 * The keypress that triggered this event. 8472 * 8473 * @listens keydown 8474 */ 8475 8476 8477 ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) { 8478 if (e.which === ESC && this.closeable()) { 8479 this.close(); 8480 } 8481 }; 8482 8483 /** 8484 * Returns the label string for this modal. Primarily used for accessibility. 8485 * 8486 * @return {string} 8487 * the localized or raw label of this modal. 8488 */ 8489 8490 8491 ModalDialog.prototype.label = function label() { 8492 return this.options_.label || this.localize('Modal Window'); 8493 }; 8494 8495 /** 8496 * Returns the description string for this modal. Primarily used for 8497 * accessibility. 8498 * 8499 * @return {string} 8500 * The localized or raw description of this modal. 8501 */ 8502 8503 8504 ModalDialog.prototype.description = function description() { 8505 var desc = this.options_.description || this.localize('This is a modal window.'); 8506 8507 // Append a universal closeability message if the modal is closeable. 8508 if (this.closeable()) { 8509 desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.'); 8510 } 8511 8512 return desc; 8513 }; 8514 8515 /** 8516 * Opens the modal. 8517 * 8518 * @fires ModalDialog#beforemodalopen 8519 * @fires ModalDialog#modalopen 8520 * 8521 * @return {ModalDialog} 8522 * Returns itself; method can be chained. 8523 */ 8524 8525 8526 ModalDialog.prototype.open = function open() { 8527 if (!this.opened_) { 8528 var player = this.player(); 8529 8530 /** 8531 * Fired just before a `ModalDialog` is opened. 8532 * 8533 * @event ModalDialog#beforemodalopen 8534 * @type {EventTarget~Event} 8535 */ 8536 this.trigger('beforemodalopen'); 8537 this.opened_ = true; 8538 8539 // Fill content if the modal has never opened before and 8540 // never been filled. 8541 if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) { 8542 this.fill(); 8543 } 8544 8545 // If the player was playing, pause it and take note of its previously 8546 // playing state. 8547 this.wasPlaying_ = !player.paused(); 8548 8549 if (this.wasPlaying_) { 8550 player.pause(); 8551 } 8552 8553 if (this.closeable()) { 8554 this.on(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress)); 8555 } 8556 8557 player.controls(false); 8558 this.show(); 8559 this.el().setAttribute('aria-hidden', 'false'); 8560 8561 /** 8562 * Fired just after a `ModalDialog` is opened. 8563 * 8564 * @event ModalDialog#modalopen 8565 * @type {EventTarget~Event} 8566 */ 8567 this.trigger('modalopen'); 8568 this.hasBeenOpened_ = true; 8569 } 8570 return this; 8571 }; 8572 8573 /** 8574 * If the `ModalDialog` is currently open or closed. 8575 * 8576 * @param {boolean} [value] 8577 * If given, it will open (`true`) or close (`false`) the modal. 8578 * 8579 * @return {boolean} 8580 * the current open state of the modaldialog 8581 */ 8582 8583 8584 ModalDialog.prototype.opened = function opened(value) { 8585 if (typeof value === 'boolean') { 8586 this[value ? 'open' : 'close'](); 8587 } 8588 return this.opened_; 8589 }; 8590 8591 /** 8592 * Closes the modal, does nothing if the `ModalDialog` is 8593 * not open. 8594 * 8595 * @fires ModalDialog#beforemodalclose 8596 * @fires ModalDialog#modalclose 8597 * 8598 * @return {ModalDialog} 8599 * Returns itself; method can be chained. 8600 */ 8601 8602 8603 ModalDialog.prototype.close = function close() { 8604 if (this.opened_) { 8605 var player = this.player(); 8606 8607 /**
8608 * Fired just before a `ModalDialog` is closed. 8609 * 8610 * @event ModalDialog#beforemodalclose 8611 * @type {EventTarget~Event} 8612 */ 8613 this.trigger('beforemodalclose'); 8614 this.opened_ = false; 8615 8616 if (this.wasPlaying_) { 8617 player.play(); 8618 } 8619 8620 if (this.closeable()) { 8621 this.off(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress)); 8622 } 8623 8624 player.controls(true); 8625 this.hide(); 8626 this.el().setAttribute('aria-hidden', 'true'); 8627 8628 /** 8629 * Fired just after a `ModalDialog` is closed. 8630 * 8631 * @event ModalDialog#modalclose 8632 * @type {EventTarget~Event} 8633 */ 8634 this.trigger('modalclose'); 8635 8636 if (this.options_.temporary) { 8637 this.dispose(); 8638 } 8639 } 8640 return this; 8641 }; 8642 8643 /** 8644 * Check to see if the `ModalDialog` is closeable via the UI. 8645 * 8646 * @param {boolean} [value] 8647 * If given as a boolean, it will set the `closeable` option. 8648 * 8649 * @return {boolean} 8650 * Returns the final value of the closable option. 8651 */ 8652 8653 8654 ModalDialog.prototype.closeable = function closeable(value) { 8655 if (typeof value === 'boolean') { 8656 var closeable = this.closeable_ = !!value; 8657 var close = this.getChild('closeButton'); 8658 8659 // If this is being made closeable and has no close button, add one. 8660 if (closeable && !close) { 8661 8662 // The close button should be a child of the modal - not its 8663 // content element, so temporarily change the content element. 8664 var temp = this.contentEl_; 8665 8666 this.contentEl_ = this.el_; 8667 close = this.addChild('closeButton', { controlText: 'Close Modal Dialog' }); 8668 this.contentEl_ = temp; 8669 this.on(close, 'close', this.close); 8670 } 8671 8672 // If this is being made uncloseable and has a close button, remove it. 8673 if (!closeable && close) { 8674 this.off(close, 'close', this.close); 8675 this.removeChild(close); 8676 close.dispose(); 8677 } 8678 } 8679 return this.closeable_; 8680 }; 8681 8682 /**
8683 * Fill the modal's content element with the modal's "content" option. 8684 * The content element will be emptied before this change takes place. 8685 * 8686 * @return {ModalDialog} 8687 * Returns itself; method can be chained. 8688 */ 8689 8690 8691 ModalDialog.prototype.fill = function fill() { 8692 return this.fillWith(this.content()); 8693 }; 8694 8695 /** 8696 * Fill the modal's content element with arbitrary content. 8697 * The content element will be emptied before this change takes place. 8698 * 8699 * @fires ModalDialog#beforemodalfill 8700 * @fires ModalDialog#modalfill 8701 * 8702 * @param {Mixed} [content] 8703 * The same rules apply to this as apply to the `content` option. 8704 * 8705 * @return {ModalDialog} 8706 * Returns itself; method can be chained. 8707 */ 8708 8709 8710 ModalDialog.prototype.fillWith = function fillWith(content) { 8711 var contentEl = this.contentEl(); 8712 var parentEl = contentEl.parentNode; 8713 var nextSiblingEl = contentEl.nextSibling; 8714 8715 /** 8716 * Fired just before a `ModalDialog` is filled with content. 8717 * 8718 * @event ModalDialog#beforemodalfill 8719 * @type {EventTarget~Event} 8720 */ 8721 this.trigger('beforemodalfill'); 8722 this.hasBeenFilled_ = true; 8723 8724 // Detach the content element from the DOM before performing 8725 // manipulation to avoid modifying the live DOM multiple times. 8726 parentEl.removeChild(contentEl); 8727 this.empty(); 8728 Dom.insertContent(contentEl, content); 8729 /** 8730 * Fired just after a `ModalDialog` is filled with content. 8731 * 8732 * @event ModalDialog#modalfill 8733 * @type {EventTarget~Event} 8734 */ 8735 this.trigger('modalfill'); 8736 8737 // Re-inject the re-filled content element. 8738 if (nextSiblingEl) { 8739 parentEl.insertBefore(contentEl, nextSiblingEl); 8740 } else { 8741 parentEl.appendChild(contentEl); 8742 } 8743 8744 return this; 8745 }; 8746 8747 /** 8748 * Empties the content element. This happens anytime the modal is filled. 8749 * 8750 * @fires ModalDialog#beforemodalempty 8751 * @fires ModalDialog#modalempty 8752 * 8753 * @return {ModalDialog} 8754 * Returns itself; method can be chained. 8755 */ 8756 8757 8758 ModalDialog.prototype.empty = function empty() { 8759 /** 8760 * Fired just before a `ModalDialog` is emptied. 8761 * 8762 * @event ModalDialog#beforemodalempty 8763 * @type {EventTarget~Event} 8764 */ 8765 this.trigger('beforemodalempty'); 8766 Dom.emptyEl(this.contentEl()); 8767 8768 /** 8769 * Fired just after a `ModalDialog` is emptied. 8770 * 8771 * @event ModalDialog#modalempty 8772 * @type {EventTarget~Event} 8773 */ 8774 this.trigger('modalempty'); 8775 return this; 8776 }; 8777 8778 /** 8779 * Gets or sets the modal content, which gets normalized before being 8780 * rendered into the DOM. 8781 * 8782 * This does not update the DOM or fill the modal, but it is called during 8783 * that process. 8784 * 8785 * @param {Mixed} [value] 8786 * If defined, sets the internal content value to be used on the 8787 * next call(s) to `fill`. This value is normalized before being 8788 * inserted. To "clear" the internal content value, pass `null`. 8789 * 8790 * @return {Mixed} 8791 * The current content of the modal dialog 8792 */ 8793 8794 8795 ModalDialog.prototype.content = function content(value) { 8796 if (typeof value !== 'undefined') { 8797 this.content_ = value; 8798 } 8799 return this.content_; 8800 }; 8801 8802 return ModalDialog; 8803}(_component2['default']); 8804 8805/** 8806 * Default options for `ModalDialog` default options. 8807 * 8808 * @type {Object} 8809 * @private 8810 */ 8811 8812 8813ModalDialog.prototype.options_ = { 8814 temporary: true 8815}; 8816 8817_component2['default'].registerComponent('ModalDialog', ModalDialog); 8818exports['default'] = ModalDialog; 8819 8820},{"5":5,"81":81,"83":83}],51:[function(_dereq_,module,exports){ 8821'use strict'; 8822 8823exports.__esModule = true; 8824 8825var _component = _dereq_(5); 8826 8827var _component2 = _interopRequireDefault(_component); 8828 8829var _document = _dereq_(94); 8830 8831var _document2 = _interopRequireDefault(_document); 8832 8833var _window = _dereq_(95); 8834 8835var _window2 = _interopRequireDefault(_window); 8836 8837var _events = _dereq_(82); 8838 8839var Events = _interopRequireWildcard(_events); 8840 8841var _dom = _dereq_(81); 8842 8843var Dom = _interopRequireWildcard(_dom); 8844 8845var _fn = _dereq_(83); 8846 8847var Fn = _interopRequireWildcard(_fn); 8848 8849var _guid = _dereq_(85); 8850 8851var Guid = _interopRequireWildcard(_guid); 8852 8853var _browser = _dereq_(78); 8854 8855var browser = _interopRequireWildcard(_browser); 8856 8857var _log = _dereq_(86); 8858 8859var _log2 = _interopRequireDefault(_log); 8860 8861var _toTitleCase = _dereq_(91); 8862 8863var _toTitleCase2 = _interopRequireDefault(_toTitleCase); 8864 8865var _timeRanges = _dereq_(90); 8866 8867var _buffer = _dereq_(79); 8868 8869var _stylesheet = _dereq_(89); 8870 8871var stylesheet = _interopRequireWildcard(_stylesheet); 8872 8873var _fullscreenApi = _dereq_(44); 8874 8875var _fullscreenApi2 = _interopRequireDefault(_fullscreenApi); 8876 8877var _mediaError = _dereq_(46); 8878 8879var _mediaError2 = _interopRequireDefault(_mediaError); 8880 8881var _tuple = _dereq_(97); 8882 8883var _tuple2 = _interopRequireDefault(_tuple); 8884 8885var _obj = _dereq_(88); 8886 8887var _mergeOptions = _dereq_(87); 8888 8889var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 8890 8891var _textTrackListConverter = _dereq_(69); 8892 8893var _textTrackListConverter2 = _interopRequireDefault(_textTrackListConverter); 8894 8895var _modalDialog = _dereq_(50); 8896 8897var _modalDialog2 = _interopRequireDefault(_modalDialog); 8898 8899var _tech = _dereq_(62); 8900 8901var _tech2 = _interopRequireDefault(_tech); 8902 8903var _audioTrackList = _dereq_(63); 8904 8905var _audioTrackList2 = _interopRequireDefault(_audioTrackList); 8906 8907var _videoTrackList = _dereq_(76); 8908 8909var _videoTrackList2 = _interopRequireDefault(_videoTrackList); 8910 8911_dereq_(61); 8912 8913_dereq_(59); 8914 8915_dereq_(55); 8916 8917_dereq_(68); 8918 8919_dereq_(45); 8920 8921_dereq_(1); 8922 8923_dereq_(4); 8924 8925_dereq_(8); 8926 8927_dereq_(41); 8928 8929_dereq_(71); 8930 8931_dereq_(60); 8932 8933function _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; } } 8934 8935function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8936 8937function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 8938 8939function _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; } 8940 8941function _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
8941onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 8942 * @file player.js 8943 */ 8944// Subclasses Component 8945 8946 8947// The following imports are used only to ensure that the corresponding modules 8948// are always included in the video.js package. Importing the modules will 8949// execute them and they will register themselves with video.js. 8950 8951 8952// Import Html5 tech, at least for disposing the original video tag. 8953 8954 8955// The following tech events are simply re-triggered 8956// on the player when they happen 8957var TECH_EVENTS_RETRIGGER = [ 8958/** 8959 * Fired while the user agent is downloading media data. 8960 * 8961 * @event Player#progress 8962 * @type {EventTarget~Event} 8963 */ 8964/** 8965 * Retrigger the `progress` event that was triggered by the {@link Tech}. 8966 * 8967 * @private 8968 * @method Player#handleTechProgress_ 8969 * @fires Player#progress 8970 * @listens Tech#progress 8971 */ 8972'progress', 8973 8974/** 8975 * Fires when the loading of an audio/video is aborted. 8976 * 8977 * @event Player#abort 8978 * @type {EventTarget~Event} 8979 */ 8980/** 8981 * Retrigger the `abort` event that was triggered by the {@link Tech}. 8982 * 8983 * @private 8984 * @method Player#handleTechAbort_ 8985 * @fires Player#abort 8986 * @listens Tech#abort 8987 */ 8988'abort', 8989 8990/** 8991 * Fires when the browser is intentionally not getting media data. 8992 * 8993 * @event Player#suspend 8994 * @type {EventTarget~Event} 8995 */ 8996/** 8997 * Retrigger the `suspend` event that was triggered by the {@link Tech}. 8998 * 8999 * @private 9000 * @method Player#handleTechSuspend_ 9001 * @fires Player#suspend 9002 * @listens Tech#suspend 9003 */ 9004'suspend', 9005 9006/** 9007 * Fires when the current playlist is empty. 9008 * 9009 * @event Player#emptied 9010 * @type {EventTarget~Event} 9011 */ 9012/** 9013 * Retrigger the `emptied` event that was triggered by the {@link Tech}. 9014 * 9015 * @private 9016 * @method Player#handleTechEmptied_ 9017 * @fires Player#emptied 9018 * @listens Tech#emptied 9019 */ 9020'emptied', 9021/** 9022 * Fires when the browser is trying to get media data, but data is not available. 9023 * 9024 * @event Player#stalled 9025 * @type {EventTarget~Event} 9026 */ 9027/** 9028 * Retrigger the `stalled` event that was triggered by the {@link Tech}. 9029 * 9030 * @private 9031 * @method Player#handleTechStalled_ 9032 * @fires Player#stalled 9033 * @listens Tech#stalled 9034 */ 9035'stalled', 9036 9037/** 9038 * Fires when the browser has loaded meta data for the audio/video. 9039 * 9040 * @event Player#loadedmetadata 9041 * @type {EventTarget~Event} 9042 */ 9043/** 9044 * Retrigger the `stalled` event that was triggered by the {@link Tech}. 9045 * 9046 * @private 9047 * @method Player#handleTechLoadedmetadata_ 9048 * @fires Player#loadedmetadata 9049 * @listens Tech#loadedmetadata 9050 */ 9051'loadedmetadata', 9052 9053/** 9054 * Fires when the browser has loaded the current frame of the audio/video. 9055 * 9056 * @event player#loadeddata 9057 * @type {event} 9058 */ 9059/** 9060 * Retrigger the `loadeddata` event that was triggered by the {@link Tech}. 9061 * 9062 * @private 9063 * @method Player#handleTechLoaddeddata_ 9064 * @fires Player#loadeddata 9065 * @listens Tech#loadeddata 9066 */ 9067'loadeddata', 9068 9069/** 9070 * Fires when the current playback position has changed. 9071 * 9072 * @event player#timeupdate 9073 * @type {event} 9074 */ 9075/** 9076 * Retrigger the `timeupdate` event that was triggered by the {@link Tech}. 9077 * 9078 * @private 9079 * @method Player#handleTechTimeUpdate_ 9080 * @fires Player#timeupdate 9081 * @listens Tech#timeupdate 9082 */ 9083'timeupdate', 9084 9085/** 9086 * Fires when the playing speed of the audio/video is changed 9087 * 9088 * @event player#ratechange 9089 * @type {event} 9090 */ 9091/** 9092 * Retrigger the `ratechange` event that was triggered by the {@link Tech}. 9093 * 9094 * @private 9095 * @method Player#handleTechRatechange_ 9096 * @fires Player#ratechange 9097 * @listens Tech#ratechange 9098 */ 9099'ratechange', 9100 9101/** 9102 * Fires when the volume has been changed 9103 * 9104 * @event player#volumechange 9105 * @type {event} 9106 */ 9107/** 9108 * Retrigger the `volumechange` event that was triggered by the {@link Tech}. 9109 * 9110 * @private 9111 * @method Player#handleTechVolumechange_ 9112 * @fires Player#volumechange 9113 * @listens Tech#volumechange 9114 */ 9115'volumechange', 9116 9117/** 9118 * Fires when the text track has been changed 9119 * 9120 * @event player#texttrackchange 9121 * @type {event} 9122 */ 9123/** 9124 * Retrigger the `texttrackchange` event that was triggered by the {@link Tech}. 9125 * 9126 * @private 9127 * @method Player#handleTechTexttrackchange_ 9128 * @fires Player#texttrackchange 9129 * @listens Tech#texttrackchange 9130 */ 9131'texttrackchange']; 9132 9133/** 9134 * An instance of the `Player` class is created when any of the Video.js setup methods 9135 * are used to initialize a video. 9136 * 9137 * After an instance has been created it can be accessed globally in two ways: 9138 * 1. By calling `videojs('example_video_1');` 9139 * 2. By using it directly via `videojs.players.example_video_1;` 9140 * 9141 * @extends Component 9142 */ 9143 9144var Player = function (_Component) { 9145 _inherits(Player, _Component); 9146 9147 /** 9148 * Create an instance of this class. 9149 * 9150 * @param {Element} tag
9151 * The original video DOM element used for configuring options. 9152 * 9153 * @param {Object} [options] 9154 * Object of option names and values. 9155 * 9156 * @param {Component~ReadyCallback} [ready] 9157 * Ready callback function. 9158 */ 9159 function Player(tag, options, ready) { 9160 _classCallCheck(this, Player); 9161 9162 // Make sure tag ID exists 9163 tag.id = tag.id || 'vjs_video_' + Guid.newGUID(); 9164 9165 // Set Options 9166 // The options argument overrides options set in the video tag 9167 // which overrides globally set options. 9168 // This latter part coincides with the load order 9169 // (tag must exist before Player) 9170 options = (0, _obj.assign)(Player.getTagSettings(tag), options); 9171 9172 // Delay the initialization of children because we need to set up 9173 // player properties first, and can't use `this` before `super()` 9174 options.initChildren = false; 9175 9176 // Same with creating the element 9177 options.createEl = false; 9178 9179 // we don't want the player to report touch activity on itself 9180 // see enableTouchActivity in Component 9181 options.reportTouchActivity = false; 9182 9183 // If language is not set, get the closest lang attribute 9184 if (!options.language) { 9185 if (typeof tag.closest === 'function') { 9186 var closest = tag.closest('[lang]'); 9187 9188 if (closest) { 9189 options.language = closest.getAttribute('lang'); 9190 } 9191 } else { 9192 var element = tag; 9193 9194 while (element && element.nodeType === 1) { 9195 if (Dom.getElAttributes(element).hasOwnProperty('lang')) { 9196 options.language = element.getAttribute('lang'); 9197 break; 9198 } 9199 element = element.parentNode; 9200 } 9201 } 9202 } 9203 9204 // Run base component initializing with new options 9205 9206 // if the global option object was accidentally blown away by 9207 // someone, bail early with an informative error 9208 var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready)); 9209 9210 if (!_this.options_ || !_this.options_.techOrder || !_this.options_.techOrder.length) { 9211 throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?'); 9212 } 9213 9214 // Store the original tag used to set options 9215 _this.tag = tag; 9216 9217 // Store the tag attributes used to restore html5 element 9218 _this.tagAttributes = tag && Dom.getElAttributes(tag); 9219 9220 // Update current language 9221 _this.language(_this.options_.language); 9222 9223 // Update Supported Languages 9224 if (options.languages) { 9225 (function () { 9226 // Normalise player option languages to lowercase 9227 var languagesToLower = {}; 9228 9229 Object.getOwnPropertyNames(options.languages).forEach(function (name) { 9230 languagesToLower[name.toLowerCase()] = options.languages[name]; 9231 }); 9232 _this.languages_ = languagesToLower; 9233 })(); 9234 } else { 9235 _this.languages_ = Player.prototype.options_.languages; 9236 } 9237 9238 // Cache for video property values. 9239 _this.cache_ = {}; 9240 9241 // Set poster 9242 _this.poster_ = options.poster || ''; 9243 9244 // Set controls 9245 _this.controls_ = !!options.controls; 9246 9247 // Original tag settings stored in options 9248 // now remove immediately so native controls don't flash. 9249 // May be turned back on by HTML5 tech if nativeControlsForTouch is true 9250 tag.controls = false; 9251 9252 /* 9253 * Store the internal state of scrubbing 9254 * 9255 * @private 9256 * @return {Boolean} True if the user is scrubbing 9257 */ 9258 _this.scrubbing_ = false; 9259 9260 _this.el_ = _this.createEl(); 9261 9262 // We also want to pass the original player options to each component and plugin 9263 // as well so they don't need to reach back into the player for options later. 9264 // We also need to do another copy of this.options_ so we don't end up with 9265 // an infinite loop. 9266 var playerOptionsCopy = (0, _mergeOptions2['default'])(_this.options_); 9267 9268 // Load plugins 9269 if (options.plugins) { 9270 (function () { 9271 var plugins = options.plugins; 9272 9273 Object.getOwnPropertyNames(plugins).forEach(function (name) { 9274 if (typeof this[name] === 'function') { 9275 this[name](plugins[name]); 9276 } else { 9277 _log2['default'].error('Unable to find plugin:', name); 9278 } 9279 }, _this); 9280 })(); 9281 } 9282 9283 _this.options_.playerOptions = playerOptionsCopy; 9284 9285 _this.initChildren(); 9286 9287 // Set isAudio based on whether or not an audio tag was used 9288 _this.isAudio(tag.nodeName.toLowerCase() === 'audio'); 9289 9290 // Update controls className. Can't do this when the controls are initially 9291 // set because the element doesn't exist yet. 9292 if (_this.controls()) { 9293 _this.addClass('vjs-controls-enabled'); 9294 } else { 9295 _this.addClass('vjs-controls-disabled'); 9296 } 9297 9298 // Set ARIA label and region role depending on player type 9299 _this.el_.setAttribute('role', 'region'); 9300 if (_this.isAudio()) { 9301 _this.el_.setAttribute('aria-label', 'audio player'); 9302 } else { 9303 _this.el_.setAttribute('aria-label', 'video player'); 9304 } 9305 9306 if (_this.isAudio()) { 9307 _this.addClass('vjs-audio'); 9308 } 9309 9310 if (_this.flexNotSupported_()) { 9311 _this.addClass('vjs-no-flex'); 9312 } 9313 9314 // TODO: Make this smarter. Toggle user state between touching/mousing 9315 // using events, since devices can have both touch and mouse events. 9316 // if (browser.TOUCH_ENABLED) { 9317 // this.addClass('vjs-touch-enabled'); 9318 // } 9319 9320 // iOS Safari has broken hover handling 9321 if (!browser.IS_IOS) { 9322 _this.addClass('vjs-workinghover'); 9323 } 9324 9325 // Make player easily findable by ID 9326 Player.players[_this.id_] = _this; 9327 9328 // When the player is first initialized, trigger activity so components 9329 // like the control bar show themselves if needed 9330 _this.userActive(true); 9331 _this.reportUserActivity(); 9332 _this.listenForUserActivity_(); 9333 9334 _this.on('fullscreenchange', _this.handleFullscreenChange_); 9335 _this.on('stageclick', _this.handleStageClick_); 9336 return _this; 9337 } 9338 9339 /** 9340 * Destroys the video player and does any necessary cleanup. 9341 * 9342 * This is especially helpful if you are dynamically adding and removing videos 9343 * to/from the DOM. 9344 * 9345 * @fires Player#dispose 9346 */ 9347 9348 9349 Player.prototype.dispose = function dispose() { 9350 /** 9351 * Called when the player is being disposed of. 9352 * 9353 * @event Player#dispose 9354 * @type {EventTarget~Event} 9355 */ 9356 this.trigger('dispose'); 9357 // prevent dispose from being called twice 9358 this.off('dispose'); 9359 9360 if (this.styleEl_ && this.styleEl_.parentNode) { 9361 this.styleEl_.parentNode.removeChild(this.styleEl_); 9362 } 9363 9364 // Kill reference to this player 9365 Player.players[this.id_] = null; 9366 9367 if (this.tag && this.tag.player) { 9368 this.tag.player = null; 9369 } 9370 9371 if (this.el_ && this.el_.player) { 9372 this.el_.player = null; 9373 } 9374 9375 if (this.tech_) { 9376 this.tech_.dispose(); 9377 } 9378 9379 _Component.prototype.dispose.call(this); 9380 }; 9381 9382 /** 9383 * Create the `Player`'s DOM element. 9384 * 9385 * @return {Element} 9386 * The DOM element that gets created. 9387 */ 9388 9389 9390 Player.prototype.createEl = function createEl() { 9391 var tag = this.tag; 9392 var el = void 0; 9393 var playerElIngest = this.playerElIngest_ = tag.parentNode && tag.parentNode.hasAttribute && tag.parentNode.hasAttribute('data-vjs-player'); 9394 9395 if (playerElIngest) { 9396 el = this.el_ = tag.parentNode; 9397 } else { 9398 el = this.el_ = _Component.prototype.createEl.call(this, 'div'); 9399 } 9400 9401 // Remove width/height attrs from tag so CSS can make it 100% width/height 9402 tag.removeAttribute('width'); 9403 tag.removeAttribute('height'); 9404 9405 // Copy over all the attributes from the tag, including ID and class 9406 // ID will now reference player box, not the video tag 9407 var attrs = Dom.getElAttributes(tag); 9408
vendor: 6,769 bytes, lines 9409-9640
9409 Object.getOwnPropertyNames(attrs).forEach(function (attr) { 9410 // workaround so we don't totally break IE7 9411 // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7 9412 if (attr === 'class') { 9413 el.className += ' ' + attrs[attr]; 9414 } else { 9415 el.setAttribute(attr, attrs[attr]); 9416 } 9417 }); 9418 9419 // Update tag id/class for use as HTML5 playback tech 9420 // Might think we should do this after embedding in container so .vjs-tech class 9421 // doesn't flash 100% width/height, but class only applies with .video-js parent 9422 tag.playerId = tag.id; 9423 tag.id += '_html5_api'; 9424 tag.className = 'vjs-tech'; 9425 9426 // Make player findable on elements 9427 tag.player = el.player = this; 9428 // Default state of video is paused 9429 this.addClass('vjs-paused'); 9430 9431 // Add a style element in the player that we'll use to set the width/height 9432 // of the player in a way that's still overrideable by CSS, just like the 9433 // video element 9434 if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) { 9435 this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions'); 9436 var defaultsStyleEl = Dom.$('.vjs-styles-defaults'); 9437 var head = Dom.$('head'); 9438 9439 head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild); 9440 } 9441 9442 // Pass in the width/height/aspectRatio options which will update the style el 9443 this.width(this.options_.width); 9444 this.height(this.options_.height); 9445 this.fluid(this.options_.fluid); 9446 this.aspectRatio(this.options_.aspectRatio); 9447 9448 // Hide any links within the video/audio tag, because IE doesn't hide them completely. 9449 var links = tag.getElementsByTagName('a'); 9450 9451 for (var i = 0; i < links.length; i++) { 9452 var linkEl = links.item(i); 9453 9454 Dom.addElClass(linkEl, 'vjs-hidden'); 9455 linkEl.setAttribute('hidden', 'hidden'); 9456 } 9457 9458 // insertElFirst seems to cause the networkState to flicker from 3 to 2, so 9459 // keep track of the original for later so we can know if the source originally failed 9460 tag.initNetworkState_ = tag.networkState; 9461 9462 // Wrap video tag in div (el/box) container 9463 if (tag.parentNode && !playerElIngest) { 9464 tag.parentNode.insertBefore(el, tag); 9465 } 9466 9467 // insert the tag as the first child of the player element 9468 // then manually add it to the children array so that this.addChild 9469 // will work properly for other components 9470 // 9471 // Breaks iPhone, fixed in HTML5 setup. 9472 Dom.insertElFirst(tag, el); 9473 this.children_.unshift(tag); 9474 9475 this.el_ = el; 9476 9477 return el; 9478 }; 9479 9480 /** 9481 * A getter/setter for the `Player`'s width. 9482 * 9483 * @param {number} [value] 9484 * The value to set the `Player's width to. 9485 * 9486 * @return {number} 9487 * The current width of the `Player`. 9488 */ 9489 9490 9491 Player.prototype.width = function width(value) { 9492 return this.dimension('width', value); 9493 }; 9494 9495 /** 9496 * A getter/setter for the `Player`'s height. 9497 * 9498 * @param {number} [value] 9499 * The value to set the `Player's heigth to. 9500 * 9501 * @return {number} 9502 * The current heigth of the `Player`. 9503 */ 9504 9505 9506 Player.prototype.height = function height(value) { 9507 return this.dimension('height', value); 9508 }; 9509 9510 /** 9511 * A getter/setter for the `Player`'s width & height. 9512 * 9513 * @param {string} dimension 9514 * This string can be: 9515 * - 'width' 9516 * - 'height' 9517 * 9518 * @param {number} [value] 9519 * Value for dimension specified in the first argument. 9520 * 9521 * @return {Player|number} 9522 * - Returns itself when setting; method can be chained. 9523 * - The dimension arguments value when getting (width/height). 9524 */ 9525 9526 9527 Player.prototype.dimension = function dimension(_dimension, value) { 9528 var privDimension = _dimension + '_'; 9529 9530 if (value === undefined) { 9531 return this[privDimension] || 0; 9532 } 9533 9534 if (value === '') { 9535 // If an empty string is given, reset the dimension to be automatic 9536 this[privDimension] = undefined; 9537 } else { 9538 var parsedVal = parseFloat(value); 9539 9540 if (isNaN(parsedVal)) { 9541 _log2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension); 9542 return this; 9543 } 9544 9545 this[privDimension] = parsedVal; 9546 } 9547 9548 this.updateStyleEl_(); 9549 return this; 9550 }; 9551 9552 /** 9553 * A getter/setter/toggler for the vjs-fluid `className` on the `Player`. 9554 * 9555 * @param {boolean} [bool] 9556 * - A value of true adds the class. 9557 * - A value of false removes the class. 9558 * - No value will toggle the fluid class. 9559 * 9560 * @return {boolean|undefined} 9561 * - The value of fluid when getting. 9562 * - `undefined` when setting. 9563 */ 9564 9565 9566 Player.prototype.fluid = function fluid(bool) { 9567 if (bool === undefined) { 9568 return !!this.fluid_; 9569 } 9570 9571 this.fluid_ = !!bool; 9572 9573 if (bool) { 9574 this.addClass('vjs-fluid'); 9575 } else { 9576 this.removeClass('vjs-fluid'); 9577 } 9578 9579 this.updateStyleEl_(); 9580 }; 9581 9582 /** 9583 * Get/Set the aspect ratio 9584 * 9585 * @param {string} [ratio] 9586 * Aspect ratio for player 9587 * 9588 * @return {string|undefined} 9589 * returns the current aspect ratio when getting 9590 */ 9591 9592 /** 9593 * A getter/setter for the `Player`'s aspect ratio. 9594 * 9595 * @param {string} [ratio] 9596 * The value to set the `Player's aspect ratio to. 9597 * 9598 * @return {string|undefined} 9599 * - The current aspect ratio of the `Player` when getting. 9600 * - undefined when setting 9601 */ 9602 9603 9604 Player.prototype.aspectRatio = function aspectRatio(ratio) { 9605 if (ratio === undefined) { 9606 return this.aspectRatio_; 9607 } 9608 9609 // Check for width:height format 9610 if (!/^\d+\:\d+$/.test(ratio)) { 9611 throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.'); 9612 } 9613 this.aspectRatio_ = ratio; 9614 9615 // We're assuming if you set an aspect ratio you want fluid mode, 9616 // because in fixed mode you could calculate width and height yourself. 9617 this.fluid(true); 9618 9619 this.updateStyleEl_(); 9620 }; 9621 9622 /** 9623 * Update styles of the `Player` element (height, width and aspect ratio). 9624 * 9625 * @private 9626 * @listens Tech#loadedmetadata 9627 */ 9628 9629 9630 Player.prototype.updateStyleEl_ = function updateStyleEl_() { 9631 if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE === true) { 9632 var _width = typeof this.width_ === 'number' ? this.width_ : this.options_.width; 9633 var _height = typeof this.height_ === 'number' ? this.height_ : this.options_.height; 9634 var techEl = this.tech_ && this.tech_.el(); 9635 9636 if (techEl) { 9637 if (_width >= 0) { 9638 techEl.width = _width; 9639 } 9640 if (_height >= 0) {
9641 techEl.height = _height; 9642 } 9643 } 9644 9645 return; 9646 } 9647 9648 var width = void 0; 9649 var height = void 0; 9650 var aspectRatio = void 0; 9651 var idClass = void 0; 9652 9653 // The aspect ratio is either used directly or to calculate width and height. 9654 if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') { 9655 // Use any aspectRatio that's been specifically set 9656 aspectRatio = this.aspectRatio_; 9657 } else if (this.videoWidth() > 0) { 9658 // Otherwise try to get the aspect ratio from the video metadata 9659 aspectRatio = this.videoWidth() + ':' + this.videoHeight(); 9660 } else { 9661 // Or use a default. The video element's is 2:1, but 16:9 is more common. 9662 aspectRatio = '16:9'; 9663 } 9664 9665 // Get the ratio as a decimal we can use to calculate dimensions 9666 var ratioParts = aspectRatio.split(':'); 9667 var ratioMultiplier = ratioParts[1] / ratioParts[0]; 9668 9669 if (this.width_ !== undefined) { 9670 // Use any width that's been specifically set 9671 width = this.width_; 9672 } else if (this.height_ !== undefined) { 9673 // Or calulate the width from the aspect ratio if a height has been set 9674 width = this.height_ / ratioMultiplier; 9675 } else { 9676 // Or use the video's metadata, or use the video el's default of 300 9677 width = this.videoWidth() || 300; 9678 } 9679 9680 if (this.height_ !== undefined) { 9681 // Use any height that's been specifically set 9682 height = this.height_; 9683 } else { 9684 // Otherwise calculate the height from the ratio and the width 9685 height = width * ratioMultiplier; 9686 } 9687 9688 // Ensure the CSS class is valid by starting with an alpha character 9689 if (/^[^a-zA-Z]/.test(this.id())) { 9690 idClass = 'dimensions-' + this.id(); 9691 } else { 9692 idClass = this.id() + '-dimensions'; 9693 } 9694 9695 // Ensure the right class is still on the player for the style element 9696 this.addClass(idClass); 9697 9698 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 '); 9699 }; 9700 9701 /** 9702 * Load/Create an instance of playback {@link Tech} including element 9703 * and API methods. Then append the `Tech` element in `Player` as a child. 9704 * 9705 * @param {string} techName 9706 * name of the playback technology 9707 * 9708 * @param {string} source 9709 * video source 9710 * 9711 * @private 9712 */ 9713 9714 9715 Player.prototype.loadTech_ = function loadTech_(techName, source) { 9716 var _this2 = this; 9717 9718 // Pause and remove current playback technology 9719 if (this.tech_) { 9720 this.unloadTech_(); 9721 } 9722 9723 // get rid of the HTML5 video tag as soon as we are using another tech 9724 if (techName !== 'Html5' && this.tag) { 9725 _tech2['default'].getTech('Html5').disposeMediaElement(this.tag); 9726 this.tag.player = null; 9727 this.tag = null; 9728 } 9729 9730 this.techName_ = techName; 9731 9732 // Turn off API access because we're loading a new tech that might load asynchronously 9733 this.isReady_ = false; 9734 9735 // Grab tech-specific options from player options and add source and parent element to use. 9736 var techOptions = (0, _obj.assign)({ 9737 source: source, 9738 'nativeControlsForTouch': this.options_.nativeControlsForTouch, 9739 'playerId': this.id(), 9740 'techId': this.id() + '_' + techName + '_api', 9741 'videoTracks': this.videoTracks_, 9742 'textTracks': this.textTracks_, 9743 'audioTracks': this.audioTracks_, 9744 'autoplay': this.options_.autoplay, 9745 'preload': this.options_.preload, 9746 'loop': this.options_.loop, 9747 'muted': this.options_.muted, 9748 'poster': this.poster(), 9749 'language': this.language(), 9750 'playerElIngest': this.playerElIngest_ || false, 9751 'vtt.js': this.options_['vtt.js'] 9752 }, this.options_[techName.toLowerCase()]); 9753 9754 if (this.tag) { 9755 techOptions.tag = this.tag; 9756 } 9757 9758 if (source) { 9759 this.currentType_ = source.type; 9760 9761 if (source.src === this.cache_.src && this.cache_.currentTime > 0) { 9762 techOptions.startTime = this.cache_.currentTime; 9763 } 9764 9765 this.cache_.sources = null; 9766 this.cache_.source = source; 9767 this.cache_.src = source.src; 9768 } 9769 9770 // Initialize tech instance 9771 var TechComponent = _tech2['default'].getTech(techName); 9772
9773 // Support old behavior of techs being registered as components. 9774 // Remove once that deprecated behavior is removed. 9775 if (!TechComponent) { 9776 TechComponent = _component2['default'].getComponent(techName); 9777 } 9778 this.tech_ = new TechComponent(techOptions); 9779 9780 // player.triggerReady is always async, so don't need this to be async 9781 this.tech_.ready(Fn.bind(this, this.handleTechReady_), true); 9782 9783 _textTrackListConverter2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_); 9784 9785 // Listen to all HTML5-defined events and trigger them on the player 9786 TECH_EVENTS_RETRIGGER.forEach(function (event) { 9787 _this2.on(_this2.tech_, event, _this2['handleTech' + (0, _toTitleCase2['default'])(event) + '_']); 9788 }); 9789 this.on(this.tech_, 'loadstart', this.handleTechLoadStart_); 9790 this.on(this.tech_, 'waiting', this.handleTechWaiting_); 9791 this.on(this.tech_, 'canplay', this.handleTechCanPlay_); 9792 this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_); 9793 this.on(this.tech_, 'playing', this.handleTechPlaying_); 9794 this.on(this.tech_, 'ended', this.handleTechEnded_); 9795 this.on(this.tech_, 'seeking', this.handleTechSeeking_); 9796 this.on(this.tech_, 'seeked', this.handleTechSeeked_); 9797 this.on(this.tech_, 'play', this.handleTechPlay_); 9798 this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_); 9799 this.on(this.tech_, 'pause', this.handleTechPause_); 9800 this.on(this.tech_, 'durationchange', this.handleTechDurationChange_); 9801 this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_); 9802 this.on(this.tech_, 'error', this.handleTechError_); 9803 this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_); 9804 this.on(this.tech_, 'posterchange', this.handleTechPosterChange_); 9805 this.on(this.tech_, 'textdata', this.handleTechTextData_); 9806 9807 this.usingNativeControls(this.techGet_('controls')); 9808 9809 if (this.controls() && !this.usingNativeControls()) { 9810 this.addTechControlsListeners_(); 9811 } 9812 9813 // Add the tech element in the DOM if it was not already there 9814 // Make sure to not insert the original video element if using Html5 9815 if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) { 9816 Dom.insertElFirst(this.tech_.el(), this.el()); 9817 } 9818 9819 // Get rid of the original video tag reference after the first tech is loaded 9820 if (this.tag) { 9821 this.tag.player = null; 9822 this.tag = null; 9823 } 9824 }; 9825 9826 /** 9827 * Unload and dispose of the current playback {@link Tech}. 9828 * 9829 * @private 9830 */ 9831 9832 9833 Player.prototype.unloadTech_ = function unloadTech_() { 9834 // Save the current text tracks so that we can reuse the same text tracks with the next tech 9835 this.videoTracks_ = this.videoTracks(); 9836 this.textTracks_ = this.textTracks(); 9837 this.audioTracks_ = this.audioTracks(); 9838 this.textTracksJson_ = _textTrackListConverter2['default'].textTracksToJson(this.tech_); 9839 9840 this.isReady_ = false; 9841 9842 this.tech_.dispose(); 9843 9844 this.tech_ = false;
9845 }; 9846 9847 /** 9848 * Return a reference to the current {@link Tech}, but only if given an object with the 9849 * `IWillNotUseThisInPlugins` property having a true value. This is try and prevent misuse 9850 * of techs by plugins. 9851 * 9852 * @param {Object} safety 9853 * An object that must contain `{IWillNotUseThisInPlugins: true}` 9854 * 9855 * @param {boolean} safety.IWillNotUseThisInPlugins 9856 * Must be set to true or else this function will throw an error. 9857 * 9858 * @return {Tech} 9859 * The Tech 9860 */ 9861 9862 9863 Player.prototype.tech = function tech(safety) { 9864 if (safety && safety.IWillNotUseThisInPlugins) { 9865 return this.tech_; 9866 } 9867 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 '; 9868 9869 _window2['default'].alert(errorText); 9870 throw new Error(errorText); 9871 }; 9872 9873 /** 9874 * Set up click and touch listeners for the playback element 9875 * 9876 * - On desktops: a click on the video itself will toggle playback 9877 * - On mobile devices: a click on the video toggles controls 9878 * which is done by toggling the user state between active and 9879 * inactive 9880 * - A tap can signal that a user has become active or has become inactive 9881 * e.g. a quick tap on an iPhone movie should reveal the controls. Another 9882 * quick tap should hide them again (signaling the user is in an inactive 9883 * viewing state) 9884 * - In addition to this, we still want the user to be considered inactive after 9885 * a few seconds of inactivity. 9886 * 9887 * > Note: the only part of iOS interaction we can't mimic with this setup 9888 * is a touch and hold on the video element counting as activity in order to 9889 * keep the controls showing, but that shouldn't be an issue. A touch and hold 9890 * on any controls will still keep the user active 9891 * 9892 * @private 9893 */ 9894 9895 9896 Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() { 9897 // Make sure to remove all the previous listeners in case we are called multiple times. 9898 this.removeTechControlsListeners_(); 9899 9900 // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do 9901 // trigger mousedown/up. 9902 // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object 9903 // Any touch events are set to block the mousedown event from happening 9904 this.on(this.tech_, 'mousedown', this.handleTechClick_); 9905 9906 // If the controls were hidden we don't want that to change without a tap event 9907 // so we'll check if the controls were already showing before reporting user 9908 // activity 9909 this.on(this.tech_, 'touchstart', this.handleTechTouchStart_); 9910 this.on(this.tech_, 'touchmove', this.handleTechTouchMove_); 9911 this.on(this.tech_, 'touchend', this.handleTechTouchEnd_); 9912 9913 // The tap listener needs to come after the touchend listener because the tap 9914 // listener cancels out any reportedUserActivity when setting userActive(false) 9915 this.on(this.tech_, 'tap', this.handleTechTap_); 9916 }; 9917 9918 /** 9919 * Remove the listeners used for click and tap controls. This is needed for 9920 * toggling to controls disabled, where a tap/touch should do nothing. 9921 * 9922 * @private 9923 */ 9924 9925 9926 Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() { 9927 // We don't want to just use `this.off()` because there might be other needed 9928 // listeners added by techs that extend this. 9929 this.off(this.tech_, 'tap', this.handleTechTap_); 9930 this.off(this.tech_, 'touchstart', this.handleTechTouchStart_); 9931 this.off(this.tech_, 'touchmove', this.handleTechTouchMove_); 9932 this.off(this.tech_, 'touchend', this.handleTechTouchEnd_); 9933 this.off(this.tech_, 'mousedown', this.handleTechClick_); 9934 }; 9935 9936 /** 9937 * Player waits for the tech to be ready 9938 * 9939 * @private 9940 */ 9941 9942 9943 Player.prototype.handleTechReady_ = function handleTechReady_() { 9944 this.triggerReady(); 9945 9946 // Keep the same volume as before 9947 if (this.cache_.volume) { 9948 this.techCall_('setVolume', this.cache_.volume); 9949 } 9950 9951 // Look if the tech found a higher resolution poster while loading 9952 this.handleTechPosterChange_(); 9953 9954 // Update the duration if available 9955 this.handleTechDurationChange_(); 9956 9957 // Chrome and Safari both have issues with autoplay. 9958 // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work. 9959 // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays) 9960 // This fixes both issues. Need to wait for API, so it updates displays correctly 9961 if ((this.src() || this.currentSrc()) && this.tag && this.options_.autoplay && this.paused()) {
vendor: 13,008 bytes, lines 9962-10502
9962 try { 9963 // Chrome Fix. Fixed in Chrome v16. 9964 delete this.tag.poster; 9965 } catch (e) { 9966 (0, _log2['default'])('deleting tag.poster throws in some browsers', e); 9967 } 9968 this.play(); 9969 } 9970 }; 9971 9972 /** 9973 * Retrigger the `loadstart` event that was triggered by the {@link Tech}. This 9974 * function will also trigger {@link Player#firstplay} if it is the first loadstart 9975 * for a video. 9976 * 9977 * @fires Player#loadstart 9978 * @fires Player#firstplay 9979 * @listens Tech#loadstart 9980 * @private 9981 */ 9982 9983 9984 Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() { 9985 // TODO: Update to use `emptied` event instead. See #1277. 9986 9987 this.removeClass('vjs-ended'); 9988 this.removeClass('vjs-seeking'); 9989 9990 // reset the error state 9991 this.error(null); 9992 9993 // If it's already playing we want to trigger a firstplay event now. 9994 // The firstplay event relies on both the play and loadstart events 9995 // which can happen in any order for a new source 9996 if (!this.paused()) { 9997 /** 9998 * Fired when the user agent begins looking for media data 9999 * 10000 * @event Player#loadstart 10001 * @type {EventTarget~Event} 10002 */ 10003 this.trigger('loadstart'); 10004 this.trigger('firstplay'); 10005 } else { 10006 // reset the hasStarted state 10007 this.hasStarted(false); 10008 this.trigger('loadstart'); 10009 } 10010 }; 10011 10012 /** 10013 * Add/remove the vjs-has-started class 10014 * 10015 * @fires Player#firstplay 10016 * 10017 * @param {boolean} hasStarted 10018 * - true: adds the class 10019 * - false: remove the class 10020 * 10021 * @return {boolean} 10022 * the boolean value of hasStarted 10023 */ 10024 10025 10026 Player.prototype.hasStarted = function hasStarted(_hasStarted) { 10027 if (_hasStarted !== undefined) { 10028 // only update if this is a new value 10029 if (this.hasStarted_ !== _hasStarted) { 10030 this.hasStarted_ = _hasStarted; 10031 if (_hasStarted) { 10032 this.addClass('vjs-has-started'); 10033 // trigger the firstplay event if this newly has played 10034 this.trigger('firstplay'); 10035 } else { 10036 this.removeClass('vjs-has-started'); 10037 } 10038 } 10039 return this; 10040 } 10041 return !!this.hasStarted_; 10042 }; 10043 10044 /** 10045 * Fired whenever the media begins or resumes playback 10046 * 10047 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play} 10048 * @fires Player#play 10049 * @listens Tech#play 10050 * @private 10051 */ 10052 10053 10054 Player.prototype.handleTechPlay_ = function handleTechPlay_() { 10055 this.removeClass('vjs-ended'); 10056 this.removeClass('vjs-paused'); 10057 this.addClass('vjs-playing'); 10058 10059 // hide the poster when the user hits play 10060 this.hasStarted(true); 10061 /** 10062 * Triggered whenever an {@link Tech#play} event happens. Indicates that 10063 * playback has started or resumed. 10064 * 10065 * @event Player#play 10066 * @type {EventTarget~Event} 10067 */ 10068 this.trigger('play'); 10069 }; 10070 10071 /** 10072 * Retrigger the `waiting` event that was triggered by the {@link Tech}. 10073 * 10074 * @fires Player#waiting 10075 * @listens Tech#waiting 10076 * @private 10077 */ 10078 10079 10080 Player.prototype.handleTechWaiting_ = function handleTechWaiting_() { 10081 var _this3 = this; 10082 10083 this.addClass('vjs-waiting'); 10084 /** 10085 * A readyState change on the DOM element has caused playback to stop. 10086 * 10087 * @event Player#waiting 10088 * @type {EventTarget~Event} 10089 */ 10090 this.trigger('waiting'); 10091 this.one('timeupdate', function () { 10092 return _this3.removeClass('vjs-waiting'); 10093 }); 10094 }; 10095 10096 /** 10097 * Retrigger the `canplay` event that was triggered by the {@link Tech}. 10098 * > Note: This is not consistent between browsers. See #1351 10099 * 10100 * @fires Player#canplay 10101 * @listens Tech#canplay 10102 * @private 10103 */ 10104 10105 10106 Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() { 10107 this.removeClass('vjs-waiting'); 10108 /** 10109 * The media has a readyState of HAVE_FUTURE_DATA or greater. 10110 * 10111 * @event Player#canplay 10112 * @type {EventTarget~Event} 10113 */ 10114 this.trigger('canplay'); 10115 }; 10116 10117 /** 10118 * Retrigger the `canplaythrough` event that was triggered by the {@link Tech}. 10119 * 10120 * @fires Player#canplaythrough 10121 * @listens Tech#canplaythrough 10122 * @private 10123 */ 10124 10125 10126 Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() { 10127 this.removeClass('vjs-waiting'); 10128 /** 10129 * The media has a readyState of HAVE_ENOUGH_DATA or greater. This means that the 10130 * entire media file can be played without buffering. 10131 * 10132 * @event Player#canplaythrough 10133 * @type {EventTarget~Event} 10134 */ 10135 this.trigger('canplaythrough'); 10136 }; 10137 10138 /** 10139 * Retrigger the `playing` event that was triggered by the {@link Tech}. 10140 * 10141 * @fires Player#playing 10142 * @listens Tech#playing 10143 * @private 10144 */ 10145 10146 10147 Player.prototype.handleTechPlaying_ = function handleTechPlaying_() { 10148 this.removeClass('vjs-waiting'); 10149 /** 10150 * The media is no longer blocked from playback, and has started playing. 10151 * 10152 * @event Player#playing 10153 * @type {EventTarget~Event} 10154 */ 10155 this.trigger('playing'); 10156 }; 10157 10158 /** 10159 * Retrigger the `seeking` event that was triggered by the {@link Tech}. 10160 * 10161 * @fires Player#seeking 10162 * @listens Tech#seeking 10163 * @private 10164 */ 10165 10166 10167 Player.prototype.handleTechSeeking_ = function handleTechSeeking_() { 10168 this.addClass('vjs-seeking'); 10169 /** 10170 * Fired whenever the player is jumping to a new time 10171 * 10172 * @event Player#seeking 10173 * @type {EventTarget~Event} 10174 */ 10175 this.trigger('seeking'); 10176 }; 10177 10178 /** 10179 * Retrigger the `seeked` event that was triggered by the {@link Tech}. 10180 * 10181 * @fires Player#seeked 10182 * @listens Tech#seeked 10183 * @private 10184 */ 10185 10186 10187 Player.prototype.handleTechSeeked_ = function handleTechSeeked_() { 10188 this.removeClass('vjs-seeking'); 10189 /** 10190 * Fired when the player has finished jumping to a new time 10191 * 10192 * @event Player#seeked 10193 * @type {EventTarget~Event} 10194 */ 10195 this.trigger('seeked'); 10196 }; 10197 10198 /** 10199 * Retrigger the `firstplay` event that was triggered by the {@link Tech}. 10200 * 10201 * @fires Player#firstplay 10202 * @listens Tech#firstplay 10203 * @deprecated As of 6.0 passing the `starttime` option to the player will be deprecated 10204 * @private 10205 */ 10206 10207 10208 Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() { 10209 // If the first starttime attribute is specified 10210 // then we will start at the given offset in seconds 10211 if (this.options_.starttime) { 10212 _log2['default'].warn('Passing the `starttime` option to the player will be deprecated in 6.0'); 10213 this.currentTime(this.options_.starttime); 10214 } 10215 10216 this.addClass('vjs-has-started'); 10217 /** 10218 * Fired the first time a video is played. Not part of the HLS spec, and this is 10219 * probably not the best implementation yet, so use sparingly. If you don't have a 10220 * reason to prevent playback, use `myPlayer.one('play');` instead. 10221 * 10222 * @event Player#firstplay 10223 * @type {EventTarget~Event} 10224 */ 10225 this.trigger('firstplay'); 10226 }; 10227 10228 /** 10229 * Retrigger the `pause` event that was triggered by the {@link Tech}. 10230 * 10231 * @fires Player#pause 10232 * @listens Tech#pause 10233 * @private 10234 */ 10235 10236 10237 Player.prototype.handleTechPause_ = function handleTechPause_() { 10238 this.removeClass('vjs-playing'); 10239 this.addClass('vjs-paused'); 10240 /** 10241 * Fired whenever the media has been paused 10242 * 10243 * @event Player#pause 10244 * @type {EventTarget~Event} 10245 */ 10246 this.trigger('pause'); 10247 }; 10248 10249 /** 10250 * Retrigger the `ended` event that was triggered by the {@link Tech}. 10251 * 10252 * @fires Player#ended 10253 * @listens Tech#ended 10254 * @private 10255 */ 10256 10257 10258 Player.prototype.handleTechEnded_ = function handleTechEnded_() { 10259 this.addClass('vjs-ended'); 10260 if (this.options_.loop) { 10261 this.currentTime(0); 10262 this.play(); 10263 } else if (!this.paused()) { 10264 this.pause(); 10265 } 10266 10267 /** 10268 * Fired when the end of the media resource is reached (currentTime == duration) 10269 * 10270 * @event Player#ended 10271 * @type {EventTarget~Event} 10272 */ 10273 this.trigger('ended'); 10274 }; 10275 10276 /** 10277 * Fired when the duration of the media resource is first known or changed 10278 * 10279 * @listens Tech#durationchange 10280 * @private 10281 */ 10282 10283 10284 Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() { 10285 this.duration(this.techGet_('duration')); 10286 }; 10287 10288 /** 10289 * Handle a click on the media element to play/pause 10290 * 10291 * @param {EventTarget~Event} event 10292 * the event that caused this function to trigger 10293 * 10294 * @listens Tech#mousedown 10295 * @private 10296 */ 10297 10298 10299 Player.prototype.handleTechClick_ = function handleTechClick_(event) { 10300 // We're using mousedown to detect clicks thanks to Flash, but mousedown 10301 // will also be triggered with right-clicks, so we need to prevent that 10302 if (event.button !== 0) { 10303 return; 10304 } 10305 10306 // When controls are disabled a click should not toggle playback because 10307 // the click is considered a control 10308 if (this.controls()) { 10309 if (this.paused()) { 10310 this.play(); 10311 } else { 10312 this.pause(); 10313 } 10314 } 10315 }; 10316 10317 /** 10318 * Handle a tap on the media element. It will toggle the user 10319 * activity state, which hides and shows the controls. 10320 * 10321 * @listens Tech#tap 10322 * @private 10323 */ 10324 10325 10326 Player.prototype.handleTechTap_ = function handleTechTap_() { 10327 this.userActive(!this.userActive()); 10328 }; 10329 10330 /** 10331 * Handle touch to start 10332 * 10333 * @listens Tech#touchstart 10334 * @private 10335 */ 10336 10337 10338 Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() { 10339 this.userWasActive = this.userActive(); 10340 }; 10341 10342 /** 10343 * Handle touch to move 10344 * 10345 * @listens Tech#touchmove 10346 * @private 10347 */ 10348 10349 10350 Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() { 10351 if (this.userWasActive) { 10352 this.reportUserActivity(); 10353 } 10354 }; 10355 10356 /** 10357 * Handle touch to end 10358 * 10359 * @param {EventTarget~Event} event 10360 * the touchend event that triggered 10361 * this function 10362 * 10363 * @listens Tech#touchend 10364 * @private 10365 */ 10366 10367 10368 Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) { 10369 // Stop the mouse events from also happening 10370 event.preventDefault(); 10371 }; 10372 10373 /** 10374 * Fired when the player switches in or out of fullscreen mode 10375 * 10376 * @private 10377 * @listens Player#fullscreenchange 10378 */ 10379 10380 10381 Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() { 10382 if (this.isFullscreen()) { 10383 this.addClass('vjs-fullscreen'); 10384 } else { 10385 this.removeClass('vjs-fullscreen'); 10386 } 10387 }; 10388 10389 /** 10390 * native click events on the SWF aren't triggered on IE11, Win8.1RT 10391 * use stageclick events triggered from inside the SWF instead 10392 * 10393 * @private 10394 * @listens stageclick 10395 */ 10396 10397 10398 Player.prototype.handleStageClick_ = function handleStageClick_() { 10399 this.reportUserActivity(); 10400 }; 10401 10402 /** 10403 * Handle Tech Fullscreen Change 10404 * 10405 * @param {EventTarget~Event} event 10406 * the fullscreenchange event that triggered this function 10407 * 10408 * @param {Object} data 10409 * the data that was sent with the event 10410 * 10411 * @private 10412 * @listens Tech#fullscreenchange 10413 * @fires Player#fullscreenchange 10414 */ 10415 10416 10417 Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) { 10418 if (data) { 10419 this.isFullscreen(data.isFullscreen); 10420 } 10421 /** 10422 * Fired when going in and out of fullscreen. 10423 * 10424 * @event Player#fullscreenchange 10425 * @type {EventTarget~Event} 10426 */ 10427 this.trigger('fullscreenchange'); 10428 }; 10429 10430 /** 10431 * Fires when an error occurred during the loading of an audio/video. 10432 * 10433 * @private 10434 * @listens Tech#error 10435 */ 10436 10437 10438 Player.prototype.handleTechError_ = function handleTechError_() { 10439 var error = this.tech_.error(); 10440 10441 this.error(error); 10442 }; 10443 10444 /** 10445 * Retrigger the `textdata` event that was triggered by the {@link Tech}. 10446 * 10447 * @fires Player#textdata 10448 * @listens Tech#textdata 10449 * @private 10450 */ 10451 10452 10453 Player.prototype.handleTechTextData_ = function handleTechTextData_() { 10454 var data = null; 10455 10456 if (arguments.length > 1) { 10457 data = arguments[1]; 10458 } 10459 10460 /** 10461 * Fires when we get a textdata event from tech 10462 * 10463 * @event Player#textdata 10464 * @type {EventTarget~Event} 10465 */ 10466 this.trigger('textdata', data); 10467 }; 10468 10469 /** 10470 * Get object for cached values. 10471 * 10472 * @return {Object} 10473 * get the current object cache 10474 */ 10475 10476 10477 Player.prototype.getCache = function getCache() { 10478 return this.cache_; 10479 }; 10480 10481 /** 10482 * Pass values to the playback tech 10483 * 10484 * @param {string} [method] 10485 * the method to call 10486 * 10487 * @param {Object} arg 10488 * the argument to pass 10489 * 10490 * @private 10491 */ 10492 10493 10494 Player.prototype.techCall_ = function techCall_(method, arg) { 10495 // If it's not ready yet, call method when it is 10496 if (this.tech_ && !this.tech_.isReady_) { 10497 this.tech_.ready(function () { 10498 this[method](arg); 10499 }, true); 10500 10501 // Otherwise call method now 10502 } else {
10503 try { 10504 if (this.tech_) { 10505 this.tech_[method](arg); 10506 } 10507 } catch (e) { 10508 (0, _log2['default'])(e); 10509 throw e; 10510 } 10511 } 10512 }; 10513 10514 /** 10515 * Get calls can't wait for the tech, and sometimes don't need to. 10516 * 10517 * @param {string} method 10518 * Tech method 10519 * 10520 * @return {Function|undefined} 10521 * the method or undefined 10522 * 10523 * @private 10524 */ 10525 10526 10527 Player.prototype.techGet_ = function techGet_(method) { 10528 if (this.tech_ && this.tech_.isReady_) { 10529 10530 // Flash likes to die and reload when you hide or reposition it. 10531 // In these cases the object methods go away and we get errors. 10532 // When that happens we'll catch the errors and inform tech that it's not ready any more. 10533 try { 10534 return this.tech_[method](); 10535 } catch (e) { 10536 // When building additional tech libs, an expected method may not be defined yet 10537 if (this.tech_[method] === undefined) { 10538 (0, _log2['default'])('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e); 10539 10540 // When a method isn't available on the object it throws a TypeError 10541 } else if (e.name === 'TypeError') { 10542 (0, _log2['default'])('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e); 10543 this.tech_.isReady_ = false; 10544 } else { 10545 (0, _log2['default'])(e); 10546 } 10547 throw e; 10548 } 10549 } 10550 10551 return; 10552 }; 10553 10554 /** 10555 * start media playback 10556 * 10557 * @return {Player} 10558 * A reference to the player object this function was called on 10559 */ 10560 10561 10562 Player.prototype.play = function play() { 10563 // Only calls the tech's play if we already have a src loaded 10564 if (this.src() || this.currentSrc()) { 10565 this.techCall_('play'); 10566 } else { 10567 this.tech_.one('loadstart', function () { 10568 this.play(); 10569 }); 10570 } 10571 10572 return this; 10573 }; 10574 10575 /** 10576 * Pause the video playback 10577 * 10578 * @return {Player} 10579 * A reference to the player object this function was called on 10580 */ 10581 10582 10583 Player.prototype.pause = function pause() { 10584 this.techCall_('pause'); 10585 return this; 10586 }; 10587 10588 /** 10589 * Check if the player is paused or has yet to play 10590 * 10591 * @return {boolean} 10592 * - false: if the media is currently playing 10593 * - true: if media is not currently playing 10594 */ 10595 10596 10597 Player.prototype.paused = function paused() { 10598 // The initial state of paused should be true (in Safari it's actually false) 10599 return this.techGet_('paused') === false ? false : true; 10600 }; 10601 10602 /** 10603 * Returns whether or not the user is "scrubbing". Scrubbing is 10604 * when the user has clicked the progress bar handle and is 10605 * dragging it along the progress bar. 10606 * 10607 * @param {boolean} [isScrubbing] 10608 * wether the user is or is not scrubbing 10609 * 10610 * @return {boolean|Player} 10611 * A instance of the player that called this function when setting, 10612 * and the value of scrubbing when getting 10613 */ 10614 10615 10616 Player.prototype.scrubbing = function scrubbing(isScrubbing) { 10617 if (isScrubbing !== undefined) { 10618 this.scrubbing_ = !!isScrubbing; 10619 10620 if (isScrubbing) { 10621 this.addClass('vjs-scrubbing'); 10622 } else { 10623 this.removeClass('vjs-scrubbing'); 10624 } 10625 10626 return this; 10627 } 10628 10629 return this.scrubbing_; 10630 }; 10631 10632 /** 10633 * Get or set the current time (in seconds) 10634 * 10635 * @param {number|string} [seconds] 10636 * The time to seek to in seconds 10637 * 10638 * @return {Player|number} 10639 * - the current time in seconds when getting 10640 * - a reference to the current player object when setting 10641 */ 10642 10643 10644 Player.prototype.currentTime = function currentTime(seconds) { 10645 if (seconds !== undefined) { 10646 10647 this.techCall_('setCurrentTime', seconds); 10648 10649 return this; 10650 } 10651 10652 // cache last currentTime and return. default to 0 seconds 10653 // 10654 // Caching the currentTime is meant to prevent a massive amount of reads on the tech's 10655 // currentTime when scrubbing, but may not provide much performance benefit afterall. 10656 // Should be tested. Also something has to read the actual current time or the cache will 10657 // never get updated. 10658 this.cache_.currentTime = this.techGet_('currentTime') || 0; 10659 return this.cache_.currentTime; 10660 }; 10661 10662 /** 10663 * Normally gets the length in time of the video in seconds; 10664 * in all but the rarest use cases an argument will NOT be passed to the method 10665 * 10666 * > **NOTE**: The video must have started loading before the duration can be 10667 * known, and in the case of Flash, may not be known until the video starts 10668 * playing. 10669 * 10670 * @fires Player#durationchange 10671 * 10672 * @param {number} [seconds] 10673 * The duration of the video to set in seconds 10674 * 10675 * @return {number|Player} 10676 * - The duration of the video in seconds when getting 10677 * - A reference to the player that called this function 10678 * when setting 10679 */ 10680 10681 10682 Player.prototype.duration = function duration(seconds) { 10683 if (seconds === undefined) { 10684 return this.cache_.duration || 0; 10685 } 10686 10687 seconds = parseFloat(seconds) || 0; 10688 10689 // Standardize on Inifity for signaling video is live 10690 if (seconds < 0) { 10691 seconds = Infinity; 10692 } 10693 10694 if (seconds !== this.cache_.duration) { 10695 // Cache the last set value for optimized scrubbing (esp. Flash) 10696 this.cache_.duration = seconds; 10697 10698 if (seconds === Infinity) { 10699 this.addClass('vjs-live'); 10700 } else { 10701 this.removeClass('vjs-live'); 10702 } 10703 /** 10704 * @event Player#durationchange 10705 * @type {EventTarget~Event} 10706 */ 10707 this.trigger('durationchange'); 10708 } 10709 10710 return this; 10711 }; 10712 10713 /** 10714 * Calculates how much time is left in the video. Not part 10715 * of the native video API. 10716 * 10717 * @return {number} 10718 * The time remaining in seconds 10719 */ 10720 10721 10722 Player.prototype.remainingTime = function remainingTime() { 10723 return this.duration() - this.currentTime(); 10724 }; 10725 10726 // 10727 // Kind of like an array of portions of the video that have been downloaded.
10728 10729 /** 10730 * Get a TimeRange object with an array of the times of the video 10731 * that have been downloaded. If you just want the percent of the 10732 * video that's been downloaded, use bufferedPercent. 10733 * 10734 * @see [Buffered Spec]{@link http://dev.w3.org/html5/spec/video.html#dom-media-buffered} 10735 * 10736 * @return {TimeRange} 10737 * A mock TimeRange object (following HTML spec) 10738 */ 10739 10740 10741 Player.prototype.buffered = function buffered() { 10742 var buffered = this.techGet_('buffered'); 10743 10744 if (!buffered || !buffered.length) { 10745 buffered = (0, _timeRanges.createTimeRange)(0, 0); 10746 } 10747 10748 return buffered; 10749 }; 10750 10751 /** 10752 * Get the percent (as a decimal) of the video that's been downloaded. 10753 * This method is not a part of the native HTML video API. 10754 * 10755 * @return {number} 10756 * A decimal between 0 and 1 representing the percent 10757 * that is bufferred 0 being 0% and 1 being 100% 10758 */ 10759 10760 10761 Player.prototype.bufferedPercent = function bufferedPercent() { 10762 return (0, _buffer.bufferedPercent)(this.buffered(), this.duration()); 10763 }; 10764 10765 /** 10766 * Get the ending time of the last buffered time range 10767 * This is used in the progress bar to encapsulate all time ranges. 10768 * 10769 * @return {number} 10770 * The end of the last buffered time range 10771 */ 10772 10773 10774 Player.prototype.bufferedEnd = function bufferedEnd() { 10775 var buffered = this.buffered(); 10776 var duration = this.duration(); 10777 var end = buffered.end(buffered.length - 1); 10778 10779 if (end > duration) { 10780 end = duration; 10781 } 10782 10783 return end; 10784 }; 10785 10786 /** 10787 * Get or set the current volume of the media 10788 * 10789 * @param {number} [percentAsDecimal] 10790 * The new volume as a decimal percent: 10791 * - 0 is muted/0%/off 10792 * - 1.0 is 100%/full 10793 * - 0.5 is half volume or 50% 10794 * 10795 * @return {Player|number} 10796 * a reference to the calling player when setting and the 10797 * current volume as a percent when getting 10798 */ 10799 10800 10801 Player.prototype.volume = function volume(percentAsDecimal) { 10802 var vol = void 0; 10803 10804 if (percentAsDecimal !== undefined) { 10805 // Force value to between 0 and 1 10806 vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); 10807 this.cache_.volume = vol; 10808 this.techCall_('setVolume', vol); 10809 10810 return this; 10811 } 10812 10813 // Default to 1 when returning current volume. 10814 vol = parseFloat(this.techGet_('volume')); 10815 return isNaN(vol) ? 1 : vol; 10816 }; 10817 10818 /** 10819 * Get the current muted state, or turn mute on or off 10820 * 10821 * @param {boolean} [muted] 10822 * - true to mute 10823 * - false to unmute 10824 * 10825 * @return {boolean|Player} 10826 * - true if mute is on and getting 10827 * - false if mute is off and getting 10828 * - A reference to the current player when setting 10829 */ 10830 10831 10832 Player.prototype.muted = function muted(_muted) { 10833 if (_muted !== undefined) { 10834 this.techCall_('setMuted', _muted); 10835 return this; 10836 } 10837 return this.techGet_('muted') || false; 10838 }; 10839 10840 /** 10841 * Check if current tech can support native fullscreen 10842 * (e.g. with built in controls like iOS, so not our flash swf) 10843 * 10844 * @return {boolean} 10845 * if native fullscreen is supported 10846 */ 10847 10848 10849 Player.prototype.supportsFullScreen = function supportsFullScreen() { 10850 return this.techGet_('supportsFullScreen') || false; 10851 }; 10852 10853 /** 10854 * Check if the player is in fullscreen mode or tell the player that it 10855 * is or is not in fullscreen mode. 10856 * 10857 * > NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official 10858 * property and instead document.fullscreenElement is used. But isFullscreen is 10859 * still a valuable property for internal player workings. 10860 * 10861 * @param {boolean} [isFS] 10862 * Set the players current fullscreen state 10863 * 10864 * @return {boolean|Player} 10865 * - true if fullscreen is on and getting 10866 * - false if fullscreen is off and getting 10867 * - A reference to the current player when setting 10868 */ 10869 10870 10871 Player.prototype.isFullscreen = function isFullscreen(isFS) { 10872 if (isFS !== undefined) { 10873 this.isFullscreen_ = !!isFS; 10874 return this; 10875 } 10876 return !!this.isFullscreen_; 10877 }; 10878 10879 /** 10880 * Increase the size of the video to full screen 10881 * In some browsers, full screen is not supported natively, so it enters 10882 * "full window mode", where the video fills the browser window. 10883 * In browsers and devices that support native full screen, sometimes the 10884 * browser's default controls will be shown, and not the Video.js custom skin. 10885 * This includes most mobile devices (iOS, Android) and older versions of 10886 * Safari. 10887 * 10888 * @fires Player#fullscreenchange 10889 * @return {Player} 10890 * A reference to the current player 10891 */ 10892 10893 10894 Player.prototype.requestFullscreen = function requestFullscreen() { 10895 var fsApi = _fullscreenApi2['default']; 10896 10897 this.isFullscreen(true); 10898 10899 if (fsApi.requestFullscreen) { 10900 // the browser supports going fullscreen at the element level so we can 10901 // take the controls fullscreen as well as the video 10902 10903 // Trigger fullscreenchange event after change 10904 // We have to specifically add this each time, and remove 10905 // when canceling fullscreen. Otherwise if there's multiple 10906 // players on a page, they would all be reacting to the same fullscreen 10907 // events 10908 Events.on(_document2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) { 10909 this.isFullscreen(_document2['default'][fsApi.fullscreenElement]); 10910 10911 // If cancelling fullscreen, remove event listener. 10912 if (this.isFullscreen() === false) { 10913 Events.off(_document2['default'], fsApi.fullscreenchange, documentFullscreenChange); 10914 } 10915 /** 10916 * @event Player#fullscreenchange 10917 * @type {EventTarget~Event} 10918 */ 10919 this.trigger('fullscreenchange'); 10920 })); 10921 10922 this.el_[fsApi.requestFullscreen](); 10923 } else if (this.tech_.supportsFullScreen()) { 10924 // we can't take the video.js controls fullscreen but we can go fullscreen 10925 // with native controls 10926 this.techCall_('enterFullScreen'); 10927 } else { 10928 // fullscreen isn't supported so we'll just stretch the video element to 10929 // fill the viewport 10930 this.enterFullWindow(); 10931 /** 10932 * @event Player#fullscreenchange 10933 * @type {EventTarget~Event} 10934 */ 10935 this.trigger('fullscreenchange'); 10936 } 10937 10938 return this; 10939 }; 10940 10941 /** 10942 * Return the video to its normal size after having been in full screen mode 10943 * 10944 * @fires Player#fullscreenchange 10945 * 10946 * @return {Player} 10947 * A reference to the current player 10948 */ 10949 10950 10951 Player.prototype.exitFullscreen = function exitFullscreen() { 10952 var fsApi = _fullscreenApi2['default']; 10953 10954 this.isFullscreen(false); 10955 10956 // Check for browser element fullscreen support 10957 if (fsApi.requestFullscreen) { 10958 _document2['default'][fsApi.exitFullscreen](); 10959 } else if (this.tech_.supportsFullScreen()) { 10960 this.techCall_('exitFullScreen'); 10961 } else { 10962 this.exitFullWindow(); 10963 /** 10964 * @event Player#fullscreenchange 10965 * @type {EventTarget~Event} 10966 */ 10967 this.trigger('fullscreenchange'); 10968 } 10969 10970 return this; 10971 }; 10972 10973 /** 10974 * When fullscreen isn't supported we can stretch the 10975 * video container to as wide as the browser will let us. 10976 * 10977 * @fires Player#enterFullWindow 10978 */ 10979 10980 10981 Player.prototype.enterFullWindow = function enterFullWindow() { 10982 this.isFullWindow = true; 10983 10984 // Storing original doc overflow value to return to when fullscreen is off 10985 this.docOrigOverflow = _document2['default'].documentElement.style.overflow; 10986 10987 // Add listener for esc key to exit fullscreen 10988 Events.on(_document2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey)); 10989 10990 // Hide any scroll bars 10991 _document2['default'].documentElement.style.overflow = 'hidden'; 10992 10993 // Apply fullscreen styles 10994 Dom.addElClass(_document2['default'].body, 'vjs-full-window'); 10995 10996 /** 10997 * @event Player#enterFullWindow 10998 * @type {EventTarget~Event} 10999 */ 11000 this.trigger('enterFullWindow'); 11001 }; 11002 11003 /** 11004 * Check for call to either exit full window or 11005 * full screen on ESC key 11006 * 11007 * @param {string} event 11008 * Event to check for key press 11009 */ 11010 11011 11012 Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) { 11013 if (event.keyCode === 27) { 11014 if (this.isFullscreen() === true) { 11015 this.exitFullscreen(); 11016 } else { 11017 this.exitFullWindow(); 11018 } 11019 } 11020 }; 11021 11022 /** 11023 * Exit full window 11024 * 11025 * @fires Player#exitFullWindow 11026 */ 11027 11028 11029 Player.prototype.exitFullWindow = function exitFullWindow() { 11030 this.isFullWindow = false;
11031 Events.off(_document2['default'], 'keydown', this.fullWindowOnEscKey); 11032 11033 // Unhide scroll bars. 11034 _document2['default'].documentElement.style.overflow = this.docOrigOverflow; 11035 11036 // Remove fullscreen styles 11037 Dom.removeElClass(_document2['default'].body, 'vjs-full-window'); 11038 11039 // Resize the box, controller, and poster to original sizes 11040 // this.positionAll(); 11041 /** 11042 * @event Player#exitFullWindow 11043 * @type {EventTarget~Event} 11044 */ 11045 this.trigger('exitFullWindow'); 11046 }; 11047 11048 /** 11049 * Check whether the player can play a given mimetype 11050 * 11051 * @see https://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-navigator-canplaytype 11052 * 11053 * @param {string} type 11054 * The mimetype to check 11055 * 11056 * @return {string} 11057 * 'probably', 'maybe', or '' (empty string) 11058 */ 11059 11060 11061 Player.prototype.canPlayType = function canPlayType(type) { 11062 var can = void 0; 11063 11064 // Loop through each playback technology in the options order 11065 for (var i = 0, j = this.options_.techOrder; i < j.length; i++) { 11066 var techName = (0, _toTitleCase2['default'])(j[i]); 11067 var tech = _tech2['default'].getTech(techName); 11068 11069 // Support old behavior of techs being registered as components. 11070 // Remove once that deprecated behavior is removed. 11071 if (!tech) { 11072 tech = _component2['default'].getComponent(techName); 11073 } 11074 11075 // Check if the current tech is defined before continuing 11076 if (!tech) { 11077 _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.'); 11078 continue; 11079 } 11080 11081 // Check if the browser supports this technology 11082 if (tech.isSupported()) { 11083 can = tech.canPlayType(type); 11084 11085 if (can) { 11086 return can; 11087 } 11088 } 11089 } 11090 11091 return ''; 11092 }; 11093 11094 /** 11095 * Select source based on tech-order or source-order 11096 * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise, 11097 * defaults to tech-order selection 11098 * 11099 * @param {Array} sources 11100 * The sources for a media asset 11101 * 11102 * @return {Object|boolean} 11103 * Object of source and tech order or false 11104 */ 11105 11106 11107 Player.prototype.selectSource = function selectSource(sources) { 11108 var _this4 = this; 11109 11110 // Get only the techs specified in `techOrder` that exist and are supported by the 11111 // current platform 11112 var techs = this.options_.techOrder.map(_toTitleCase2['default']).map(function (techName) { 11113 // `Component.getComponent(...)` is for support of old behavior of techs 11114 // being registered as components. 11115 // Remove once that deprecated behavior is removed. 11116 return [techName, _tech2['default'].getTech(techName) || _component2['default'].getComponent(techName)]; 11117 }).filter(function (_ref) { 11118 var techName = _ref[0], 11119 tech = _ref[1]; 11120 11121 // Check if the current tech is defined before continuing 11122 if (tech) { 11123 // Check if the browser supports this technology 11124 return tech.isSupported(); 11125 } 11126 11127 _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.'); 11128 return false; 11129 }); 11130 11131 // Iterate over each `innerArray` element once per `outerArray` element and execute 11132 // `tester` with both. If `tester` returns a non-falsy value, exit early and return 11133 // that value. 11134 var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) { 11135 var found = void 0; 11136 11137 outerArray.some(function (outerChoice) { 11138 return innerArray.some(function (innerChoice) { 11139 found = tester(outerChoice, innerChoice); 11140 11141 if (found) { 11142 return true; 11143 } 11144 }); 11145 }); 11146 11147 return found; 11148 }; 11149 11150 var foundSourceAndTech = void 0; 11151 var flip = function flip(fn) { 11152 return function (a, b) { 11153 return fn(b, a); 11154 }; 11155 }; 11156 var finder = function finder(_ref2, source) { 11157 var techName = _ref2[0], 11158 tech = _ref2[1]; 11159 11160 if (tech.canPlaySource(source, _this4.options_[techName.toLowerCase()])) { 11161 return { source: source, tech: techName }; 11162 } 11163 }; 11164 11165 // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources 11166 // to select from them based on their priority. 11167 if (this.options_.sourceOrder) { 11168 // Source-first ordering 11169 foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder)); 11170 } else { 11171 // Tech-first ordering 11172 foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder); 11173 } 11174 11175 return foundSourceAndTech || false; 11176 }; 11177 11178 /** 11179 * The source function updates the video source 11180 * There are three types of variables you can pass as the argument. 11181 * **URL string**: A URL to the the video file. Use this method if you are sure 11182 * the current playback technology (HTML5/Flash) can support the source you 11183 * provide. Currently only MP4 files can be used in both HTML5 and Flash. 11184 * 11185 * @param {Tech~SourceObject|Tech~SourceObject[]} [source] 11186 * One SourceObject or an array of SourceObjects 11187 * 11188 * @return {string|Player} 11189 * - The current video source when getting 11190 * - The player when setting 11191 */ 11192 11193 11194 Player.prototype.src = function src(source) { 11195 if (source === undefined) { 11196 return this.techGet_('src'); 11197 } 11198 11199 var currentTech = _tech2['default'].getTech(this.techName_); 11200
11201 // Support old behavior of techs being registered as components. 11202 // Remove once that deprecated behavior is removed. 11203 if (!currentTech) { 11204 currentTech = _component2['default'].getComponent(this.techName_); 11205 } 11206 11207 // case: Array of source objects to choose from and pick the best to play 11208 if (Array.isArray(source)) { 11209 this.sourceList_(source); 11210 11211 // case: URL String (http://myvideo...) 11212 } else if (typeof source === 'string') { 11213 // create a source object from the string 11214 this.src({ src: source }); 11215 11216 // case: Source object { src: '', type: '' ... } 11217 } else if (source instanceof Object) { 11218 // check if the source has a type and the loaded tech cannot play the source 11219 // if there's no type we'll just try the current tech 11220 if (source.type && !currentTech.canPlaySource(source, this.options_[this.techName_.toLowerCase()])) { 11221 // create a source list with the current source and send through 11222 // the tech loop to check for a compatible technology 11223 this.sourceList_([source]); 11224 } else { 11225 this.cache_.sources = null; 11226 this.cache_.source = source; 11227 this.cache_.src = source.src; 11228 11229 this.currentType_ = source.type || ''; 11230 11231 // wait until the tech is ready to set the source 11232 this.ready(function () { 11233 11234 // The setSource tech method was added with source handlers 11235 // so older techs won't support it 11236 // We need to check the direct prototype for the case where subclasses 11237 // of the tech do not support source handlers 11238 if (currentTech.prototype.hasOwnProperty('setSource')) { 11239 this.techCall_('setSource', source); 11240 } else { 11241 this.techCall_('src', source.src); 11242 } 11243 11244 if (this.options_.preload === 'auto') { 11245 this.load(); 11246 } 11247 11248 if (this.options_.autoplay) { 11249 this.play(); 11250 } 11251 11252 // Set the source synchronously if possible (#2326) 11253 }, true); 11254 } 11255 } 11256 11257 return this; 11258 }; 11259 11260 /** 11261 * Handle an array of source objects 11262 * 11263 * @param {Tech~SourceObject[]} sources 11264 * Array of source objects 11265 * 11266 * @private 11267 */ 11268 11269 11270 Player.prototype.sourceList_ = function sourceList_(sources) { 11271 var sourceTech = this.selectSource(sources); 11272 11273 if (sourceTech) { 11274 if (sourceTech.tech === this.techName_) { 11275 // if this technology is already loaded, set the source 11276 this.src(sourceTech.source); 11277 } else { 11278 // load this technology with the chosen source 11279 this.loadTech_(sourceTech.tech, sourceTech.source); 11280 } 11281 11282 this.cache_.sources = sources; 11283 } else { 11284 // We need to wrap this in a timeout to give folks a chance to add error event handlers 11285 this.setTimeout(function () { 11286 this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) }); 11287 }, 0); 11288 11289 // we could not find an appropriate tech, but let's still notify the delegate that this is it 11290 // this needs a better comment about why this is needed 11291 this.triggerReady(); 11292 } 11293 }; 11294 11295 /** 11296 * Begin loading the src data. 11297 * 11298 * @return {Player} 11299 * A reference to the player 11300 */ 11301 11302 11303 Player.prototype.load = function load() { 11304 this.techCall_('load'); 11305 return this; 11306 }; 11307 11308 /** 11309 * Reset the player. Loads the first tech in the techOrder, 11310 * and calls `reset` on the tech`. 11311 * 11312 * @return {Player} 11313 * A reference to the player 11314 */ 11315 11316 11317 Player.prototype.reset = function reset() { 11318 this.loadTech_((0, _toTitleCase2['default'])(this.options_.techOrder[0]), null); 11319 this.techCall_('reset'); 11320 return this; 11321 }; 11322 11323 /** 11324 * Returns all of the current source objects. 11325 * 11326 * @return {Tech~SourceObject[]} 11327 * The current source objects 11328 */ 11329 11330 11331 Player.prototype.currentSources = function currentSources() { 11332 var source = this.currentSource(); 11333 var sources = []; 11334 11335 // assume `{}` or `{ src }` 11336 if (Object.keys(source).length !== 0) { 11337 sources.push(source); 11338 } 11339 11340 return this.cache_.sources || sources; 11341 }; 11342 11343 /** 11344 * Returns the current source object. 11345 * 11346 * @return {Tech~SourceObject} 11347 * The current source object 11348 */ 11349 11350 11351 Player.prototype.currentSource = function currentSource() { 11352 var source = {}; 11353 var src = this.currentSrc(); 11354 11355 if (src) { 11356 source.src = src; 11357 } 11358 11359 return this.cache_.source || source; 11360 }; 11361 11362 /** 11363 * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4 11364 * Can be used in conjuction with `currentType` to assist in rebuilding the current source object. 11365 * 11366 * @return {string} 11367 * The current source 11368 */ 11369 11370 11371 Player.prototype.currentSrc = function currentSrc() { 11372 return this.techGet_('currentSrc') || this.cache_.src || ''; 11373 }; 11374 11375 /** 11376 * Get the current source type e.g. video/mp4 11377 * This can allow you rebuild the current source object so that you could load the same 11378 * source and tech later 11379 * 11380 * @return {string} 11381 * The source MIME type 11382 */ 11383 11384 11385 Player.prototype.currentType = function currentType() { 11386 return this.currentType_ || ''; 11387 }; 11388 11389 /** 11390 * Get or set the preload attribute 11391 * 11392 * @param {boolean} [value] 11393 * - true means that we should preload 11394 * - false maens that we should not preload 11395 * 11396 * @return {string|Player} 11397 * - the preload attribute value when getting 11398 * - the player when setting 11399 */ 11400 11401 11402 Player.prototype.preload = function preload(value) { 11403 if (value !== undefined) { 11404 this.techCall_('setPreload', value); 11405 this.options_.preload = value; 11406 return this; 11407 } 11408 return this.techGet_('preload'); 11409 }; 11410 11411 /** 11412 * Get or set the autoplay attribute. 11413 * 11414 * @param {boolean} [value] 11415 * - true means that we should autoplay 11416 * - false maens that we should not autoplay 11417 * 11418 * @return {string|Player} 11419 * - the current value of autoplay 11420 * - the player when setting 11421 */ 11422 11423 11424 Player.prototype.autoplay = function autoplay(value) { 11425 if (value !== undefined) { 11426 this.techCall_('setAutoplay', value); 11427 this.options_.autoplay = value; 11428 return this; 11429 } 11430 return this.techGet_('autoplay', value); 11431 }; 11432 11433 /** 11434 * Get or set the loop attribute on the video element. 11435 * 11436 * @param {boolean} [value] 11437 * - true means that we should loop the video 11438 * - false means that we should not loop the video 11439 * 11440 * @return {string|Player} 11441 * - the current value of loop when getting 11442 * - the player when setting 11443 */ 11444 11445 11446 Player.prototype.loop = function loop(value) { 11447 if (value !== undefined) { 11448 this.techCall_('setLoop', value); 11449 this.options_.loop = value; 11450 return this; 11451 } 11452 return this.techGet_('loop'); 11453 }; 11454 11455 /** 11456 * Get or set the poster image source url 11457 * 11458 * @fires Player#posterchange 11459 * 11460 * @param {string} [src] 11461 * Poster image source URL 11462 * 11463 * @return {string|Player} 11464 * - the current value of poster when getting 11465 * - the player when setting 11466 */ 11467 11468 11469 Player.prototype.poster = function poster(src) { 11470 if (src === undefined) { 11471 return this.poster_; 11472 } 11473 11474 // The correct way to remove a poster is to set as an empty string 11475 // other falsey values will throw errors 11476 if (!src) { 11477 src = ''; 11478 } 11479 11480 // update the internal poster variable 11481 this.poster_ = src; 11482 11483 // update the tech's poster 11484 this.techCall_('setPoster', src); 11485 11486 // alert components that the poster has been set 11487 /** 11488 * This event fires when the poster image is changed on the player. 11489 * 11490 * @event Player#posterchange 11491 * @type {EventTarget~Event} 11492 */ 11493 this.trigger('posterchange'); 11494 11495 return this; 11496 }; 11497 11498 /** 11499 * Some techs (e.g. YouTube) can provide a poster source in an 11500 * asynchronous way. We want the poster component to use this 11501 * poster source so that it covers up the tech's controls. 11502 * (YouTube's play button). However we only want to use this 11503 * soruce if the player user hasn't set a poster through 11504 * the normal APIs. 11505 * 11506 * @fires Player#posterchange 11507 * @listens Tech#posterchange 11508 * @private 11509 */ 11510 11511 11512 Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() { 11513 if (!this.poster_ && this.tech_ && this.tech_.poster) { 11514 this.poster_ = this.tech_.poster() || ''; 11515 11516 // Let components know the poster has changed 11517 this.trigger('posterchange'); 11518 } 11519 }; 11520 11521 /** 11522 * Get or set whether or not the controls are showing. 11523 * 11524 * @fires Player#controlsenabled 11525 * 11526 * @param {boolean} [bool] 11527 * - true to turn controls on 11528 * - false to turn controls off 11529 * 11530 * @return {boolean|Player} 11531 * - the current value of controls when getting 11532 * - the player when setting 11533 */ 11534 11535 11536 Player.prototype.controls = function controls(bool) { 11537 if (bool !== undefined) { 11538 bool = !!bool; 11539 11540 // Don't trigger a change event unless it actually changed 11541 if (this.controls_ !== bool) { 11542 this.controls_ = bool; 11543 11544 if (this.usingNativeControls()) { 11545 this.techCall_('setControls', bool); 11546 } 11547 11548 if (bool) { 11549 this.removeClass('vjs-controls-disabled'); 11550 this.addClass('vjs-controls-enabled'); 11551 /** 11552 * @event Player#controlsenabled 11553 * @type {EventTarget~Event} 11554 */ 11555 this.trigger('controlsenabled'); 11556 11557 if (!this.usingNativeControls()) {
11558 this.addTechControlsListeners_(); 11559 } 11560 } else { 11561 this.removeClass('vjs-controls-enabled'); 11562 this.addClass('vjs-controls-disabled'); 11563 /** 11564 * @event Player#controlsdisabled 11565 * @type {EventTarget~Event} 11566 */ 11567 this.trigger('controlsdisabled'); 11568 11569 if (!this.usingNativeControls()) { 11570 this.removeTechControlsListeners_(); 11571 } 11572 } 11573 } 11574 return this; 11575 } 11576 return !!this.controls_; 11577 }; 11578 11579 /** 11580 * Toggle native controls on/off. Native controls are the controls built into 11581 * devices (e.g. default iPhone controls), Flash, or other techs 11582 * (e.g. Vimeo Controls) 11583 * **This should only be set by the current tech, because only the tech knows 11584 * if it can support native controls** 11585 * 11586 * @fires Player#usingnativecontrols 11587 * @fires Player#usingcustomcontrols 11588 * 11589 * @param {boolean} [bool] 11590 * - true to turn native controls on 11591 * - false to turn native controls off 11592 * 11593 * @return {boolean|Player} 11594 * - the current value of native controls when getting 11595 * - the player when setting 11596 */ 11597 11598 11599 Player.prototype.usingNativeControls = function usingNativeControls(bool) { 11600 if (bool !== undefined) { 11601 bool = !!bool; 11602 11603 // Don't trigger a change event unless it actually changed 11604 if (this.usingNativeControls_ !== bool) { 11605 this.usingNativeControls_ = bool; 11606 if (bool) { 11607 this.addClass('vjs-using-native-controls'); 11608 11609 /** 11610 * player is using the native device controls 11611 * 11612 * @event Player#usingnativecontrols 11613 * @type {EventTarget~Event} 11614 */ 11615 this.trigger('usingnativecontrols'); 11616 } else { 11617 this.removeClass('vjs-using-native-controls'); 11618 11619 /** 11620 * player is using the custom HTML controls 11621 * 11622 * @event Player#usingcustomcontrols 11623 * @type {EventTarget~Event} 11624 */ 11625 this.trigger('usingcustomcontrols'); 11626 } 11627 } 11628 return this; 11629 } 11630 return !!this.usingNativeControls_; 11631 }; 11632 11633 /** 11634 * Set or get the current MediaError 11635 * 11636 * @fires Player#error 11637 * 11638 * @param {MediaError|string|number} [err] 11639 * A MediaError or a string/number to be turned 11640 * into a MediaError 11641 * 11642 * @return {MediaError|null|Player} 11643 * - The current MediaError when getting (or null) 11644 * - The player when setting 11645 */ 11646 11647 11648 Player.prototype.error = function error(err) { 11649 if (err === undefined) { 11650 return this.error_ || null; 11651 } 11652 11653 // restoring to default 11654 if (err === null) { 11655 this.error_ = err; 11656 this.removeClass('vjs-error'); 11657 if (this.errorDisplay) { 11658 this.errorDisplay.close(); 11659 } 11660 return this; 11661 } 11662 11663 this.error_ = new _mediaError2['default'](err); 11664 11665 // add the vjs-error classname to the player 11666 this.addClass('vjs-error'); 11667 11668 // log the name of the error type and any message 11669 // ie8 just logs "[object object]" if you just log the error object 11670 _log2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaError2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_); 11671 11672 /** 11673 * @event Player#error 11674 * @type {EventTarget~Event} 11675 */ 11676 this.trigger('error'); 11677 11678 return this; 11679 }; 11680 11681 /** 11682 * Report user activity 11683 * 11684 * @param {Object} event 11685 * Event object 11686 */ 11687 11688 11689 Player.prototype.reportUserActivity = function reportUserActivity(event) { 11690 this.userActivity_ = true; 11691 }; 11692 11693 /** 11694 * Get/set if user is active 11695 * 11696 * @fires Player#useractive 11697 * @fires Player#userinactive 11698 * 11699 * @param {boolean} [bool] 11700 * - true if the user is active 11701 * - false if the user is inactive 11702 * @return {boolean|Player} 11703 * - the current value of userActive when getting 11704 * - the player when setting 11705 */ 11706 11707 11708 Player.prototype.userActive = function userActive(bool) { 11709 if (bool !== undefined) { 11710 bool = !!bool; 11711 if (bool !== this.userActive_) { 11712 this.userActive_ = bool; 11713 if (bool) { 11714 // If the user was inactive and is now active we want to reset the 11715 // inactivity timer 11716 this.userActivity_ = true; 11717 this.removeClass('vjs-user-inactive'); 11718 this.addClass('vjs-user-active'); 11719 /** 11720 * @event Player#useractive 11721 * @type {EventTarget~Event} 11722 */ 11723 this.trigger('useractive'); 11724 } else { 11725 // We're switching the state to inactive manually, so erase any other 11726 // activity 11727 this.userActivity_ = false;
vendor: 3,493 bytes, lines 11728-11820
11728 11729 // Chrome/Safari/IE have bugs where when you change the cursor it can 11730 // trigger a mousemove event. This causes an issue when you're hiding 11731 // the cursor when the user is inactive, and a mousemove signals user 11732 // activity. Making it impossible to go into inactive mode. Specifically 11733 // this happens in fullscreen when we really need to hide the cursor. 11734 // 11735 // When this gets resolved in ALL browsers it can be removed 11736 // https://code.google.com/p/chromium/issues/detail?id=103041 11737 if (this.tech_) { 11738 this.tech_.one('mousemove', function (e) { 11739 e.stopPropagation(); 11740 e.preventDefault(); 11741 }); 11742 } 11743 11744 this.removeClass('vjs-user-active'); 11745 this.addClass('vjs-user-inactive'); 11746 /** 11747 * @event Player#userinactive 11748 * @type {EventTarget~Event} 11749 */ 11750 this.trigger('userinactive'); 11751 } 11752 } 11753 return this; 11754 } 11755 return this.userActive_; 11756 }; 11757 11758 /** 11759 * Listen for user activity based on timeout value 11760 * 11761 * @private 11762 */ 11763 11764 11765 Player.prototype.listenForUserActivity_ = function listenForUserActivity_() { 11766 var mouseInProgress = void 0; 11767 var lastMoveX = void 0; 11768 var lastMoveY = void 0; 11769 var handleActivity = Fn.bind(this, this.reportUserActivity); 11770 11771 var handleMouseMove = function handleMouseMove(e) { 11772 // #1068 - Prevent mousemove spamming 11773 // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970 11774 if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) { 11775 lastMoveX = e.screenX; 11776 lastMoveY = e.screenY; 11777 handleActivity(); 11778 } 11779 }; 11780 11781 var handleMouseDown = function handleMouseDown() { 11782 handleActivity(); 11783 // For as long as the they are touching the device or have their mouse down, 11784 // we consider them active even if they're not moving their finger or mouse. 11785 // So we want to continue to update that they are active 11786 this.clearInterval(mouseInProgress); 11787 // Setting userActivity=true now and setting the interval to the same time 11788 // as the activityCheck interval (250) should ensure we never miss the 11789 // next activityCheck 11790 mouseInProgress = this.setInterval(handleActivity, 250); 11791 }; 11792 11793 var handleMouseUp = function handleMouseUp(event) { 11794 handleActivity(); 11795 // Stop the interval that maintains activity if the mouse/touch is down 11796 this.clearInterval(mouseInProgress); 11797 }; 11798 11799 // Any mouse movement will be considered user activity 11800 this.on('mousedown', handleMouseDown); 11801 this.on('mousemove', handleMouseMove); 11802 this.on('mouseup', handleMouseUp); 11803 11804 // Listen for keyboard navigation 11805 // Shouldn't need to use inProgress interval because of key repeat 11806 this.on('keydown', handleActivity); 11807 this.on('keyup', handleActivity); 11808 11809 // Run an interval every 250 milliseconds instead of stuffing everything into 11810 // the mousemove/touchmove function itself, to prevent performance degradation. 11811 // `this.reportUserActivity` simply sets this.userActivity_ to true, which 11812 // then gets picked up by this loop 11813 // http://ejohn.org/blog/learning-from-twitter/ 11814 var inactivityTimeout = void 0; 11815 11816 this.setInterval(function () { 11817 // Check to see if mouse/touch activity has happened 11818 if (this.userActivity_) { 11819 // Reset the activity tracker 11820 this.userActivity_ = false;
11821 11822 // If the user state was inactive, set the state to active 11823 this.userActive(true); 11824 11825 // Clear any existing inactivity timeout to start the timer over 11826 this.clearTimeout(inactivityTimeout); 11827 11828 var timeout = this.options_.inactivityTimeout; 11829 11830 if (timeout > 0) { 11831 // In <timeout> milliseconds, if no more activity has occurred the 11832 // user will be considered inactive 11833 inactivityTimeout = this.setTimeout(function () { 11834 // Protect against the case where the inactivityTimeout can trigger just 11835 // before the next user activity is picked up by the activity check loop 11836 // causing a flicker 11837 if (!this.userActivity_) { 11838 this.userActive(false); 11839 } 11840 }, timeout); 11841 } 11842 } 11843 }, 250); 11844 }; 11845 11846 /** 11847 * Gets or sets the current playback rate. A playback rate of 11848 * 1.0 represents normal speed and 0.5 would indicate half-speed 11849 * playback, for instance. 11850 * 11851 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate 11852 * 11853 * @param {number} [rate] 11854 * New playback rate to set. 11855 * 11856 * @return {number|Player} 11857 * - The current playback rate when getting or 1.0 11858 * - the player when setting 11859 */ 11860 11861 11862 Player.prototype.playbackRate = function playbackRate(rate) { 11863 if (rate !== undefined) { 11864 this.techCall_('setPlaybackRate', rate); 11865 return this; 11866 } 11867 11868 if (this.tech_ && this.tech_.featuresPlaybackRate) { 11869 return this.techGet_('playbackRate'); 11870 } 11871 return 1.0; 11872 }; 11873 11874 /** 11875 * Gets or sets the audio flag 11876 * 11877 * @param {boolean} bool 11878 * - true signals that this is an audio player 11879 * - false signals that this is not an audio player 11880 * 11881 * @return {Player|boolean} 11882 * - the current value of isAudio when getting 11883 * - the player if setting 11884 */ 11885 11886 11887 Player.prototype.isAudio = function isAudio(bool) { 11888 if (bool !== undefined) { 11889 this.isAudio_ = !!bool; 11890 return this; 11891 } 11892 11893 return !!this.isAudio_; 11894 }; 11895 11896 /** 11897 * Get the {@link VideoTrackList} 11898 * 11899 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist 11900 * 11901 * @return {VideoTrackList} 11902 * the current video track list 11903 */ 11904 11905 11906 Player.prototype.videoTracks = function videoTracks() { 11907 // if we have not yet loadTech_, we create videoTracks_ 11908 // these will be passed to the tech during loading 11909 if (!this.tech_) { 11910 this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default'](); 11911 return this.videoTracks_; 11912 } 11913 11914 return this.tech_.videoTracks(); 11915 }; 11916 11917 /** 11918 * Get the {@link AudioTrackList} 11919 * 11920 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist 11921 * 11922 * @return {AudioTrackList} 11923 * the current audio track list 11924 */ 11925 11926 11927 Player.prototype.audioTracks = function audioTracks() { 11928 // if we have not yet loadTech_, we create videoTracks_ 11929 // these will be passed to the tech during loading 11930 if (!this.tech_) { 11931 this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default'](); 11932 return this.audioTracks_; 11933 } 11934 11935 return this.tech_.audioTracks(); 11936 }; 11937 11938 /** 11939 * Get the {@link TextTrackList} 11940 * 11941 * Text tracks are tracks of timed text events. 11942 * - Captions: text displayed over the video 11943 * for the hearing impaired 11944 * - Subtitles: text displayed over the video for 11945 * those who don't understand language in the video 11946 * - Chapters: text displayed in a menu allowing the user to jump 11947 * to particular points (chapters) in the video 11948 * - Descriptions: (not yet implemented) audio descriptions that are read back to 11949 * the user by a screen reading device 11950 * 11951 * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks 11952 * 11953 * @return {TextTrackList|undefined} 11954 * The current TextTrackList or undefined if 11955 * or undefined if we don't have a tech 11956 */ 11957 11958 11959 Player.prototype.textTracks = function textTracks() { 11960 // cannot use techGet_ directly because it checks to see whether the tech is ready. 11961 // Flash is unlikely to be ready in time but textTracks should still work. 11962 if (this.tech_) { 11963 return this.tech_.textTracks(); 11964 } 11965 }; 11966 11967 /** 11968 * Get the "remote" {@link TextTrackList}. Remote Text Tracks 11969 * are tracks that were added to the HTML video element and can 11970 * be removed, whereas normal texttracks cannot be removed. 11971 * 11972 * 11973 * @return {TextTrackList|undefined} 11974 * The current remote text track list or undefined 11975 * if we don't have a tech 11976 */ 11977 11978 11979 Player.prototype.remoteTextTracks = function remoteTextTracks() { 11980 if (this.tech_) { 11981 return this.tech_.remoteTextTracks(); 11982 } 11983 }; 11984 11985 /** 11986 * Get the "remote" {@link HTMLTrackElementList}. 11987 * This gives the user all of the DOM elements that match up 11988 * with the remote {@link TextTrackList}. 11989 * 11990 * @return {HTMLTrackElementList} 11991 * The current remote text track list elements 11992 * or undefined if we don't have a tech 11993 */ 11994 11995 11996 Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() { 11997 if (this.tech_) { 11998 return this.tech_.remoteTextTrackEls(); 11999 } 12000 }; 12001 12002 /** 12003 * A helper method for adding a {@link TextTrack} to our 12004 * {@link TextTrackList}. 12005 * 12006 * In addition to the W3C settings we allow adding additional info through options. 12007 * 12008 * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack 12009 * 12010 * @param {string} [kind] 12011 * the kind of TextTrack you are adding 12012 * 12013 * @param {string} [label] 12014 * the label to give the TextTrack label 12015 * 12016 * @param {string} [language] 12017 * the language to set on the TextTrack 12018 * 12019 * @return {TextTrack|undefined} 12020 * the TextTrack that was added or undefined 12021 * if there is no tech 12022 */ 12023 12024 12025 Player.prototype.addTextTrack = function addTextTrack(kind, label, language) { 12026 if (this.tech_) { 12027 return this.tech_.addTextTrack(kind, label, language); 12028 } 12029 }; 12030 12031 /** 12032 * Create a remote {@link TextTrack} and an {@link HTMLTrackElement}. It will 12033 * automatically removed from the video element whenever the source changes, unless 12034 * manualCleanup is set to false. 12035 * 12036 * @param {Object} options 12037 * Options to pass to {@link HTMLTrackElement} during creation. See 12038 * {@link HTMLTrackElement} for object properties that you should use. 12039 * 12040 * @param {boolean} [manualCleanup=true] if set to false, the TextTrack will be 12041 * 12042 * @return {HTMLTrackElement} 12043 * the HTMLTrackElement that was created and added 12044 * to the HTMLTrackElementList and the remote 12045 * TextTrackList 12046 * 12047 * @deprecated The default value of the "manualCleanup" parameter will default
12048 * to "false" in upcoming versions of Video.js 12049 */ 12050 12051 12052 Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) { 12053 if (this.tech_) { 12054 return this.tech_.addRemoteTextTrack(options, manualCleanup); 12055 } 12056 }; 12057 12058 /** 12059 * Remove a remote {@link TextTrack} from the respective 12060 * {@link TextTrackList} and {@link HTMLTrackElementList}. 12061 * 12062 * @param {Object} track 12063 * Remote {@link TextTrack} to remove 12064 * 12065 * @return {undefined} 12066 * does not return anything 12067 */ 12068 12069 12070 Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack() { 12071 var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, 12072 _ref3$track = _ref3.track, 12073 track = _ref3$track === undefined ? arguments[0] : _ref3$track; 12074 12075 // destructure the input into an object with a track argument, defaulting to arguments[0] 12076 // default the whole argument to an empty object if nothing was passed in 12077 12078 if (this.tech_) { 12079 return this.tech_.removeRemoteTextTrack(track); 12080 } 12081 }; 12082 12083 /** 12084 * Get video width 12085 * 12086 * @return {number} 12087 * current video width 12088 */ 12089 12090 12091 Player.prototype.videoWidth = function videoWidth() { 12092 return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0; 12093 }; 12094 12095 /** 12096 * Get video height 12097 * 12098 * @return {number} 12099 * current video height 12100 */ 12101 12102 12103 Player.prototype.videoHeight = function videoHeight() { 12104 return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0; 12105 }; 12106 12107 // Methods to add support for 12108 // initialTime: function() { return this.techCall_('initialTime'); }, 12109 // startOffsetTime: function() { return this.techCall_('startOffsetTime'); }, 12110 // played: function() { return this.techCall_('played'); }, 12111 // defaultPlaybackRate: function() { return this.techCall_('defaultPlaybackRate'); }, 12112 // defaultMuted: function() { return this.techCall_('defaultMuted'); } 12113 12114 /** 12115 * The player's language code 12116 * NOTE: The language should be set in the player options if you want the 12117 * the controls to be built with a specific language. Changing the lanugage 12118 * later will not update controls text. 12119 * 12120 * @param {string} [code] 12121 * the language code to set the player to 12122 * 12123 * @return {string|Player} 12124 * - The current language code when getting 12125 * - A reference to the player when setting 12126 */ 12127 12128 12129 Player.prototype.language = function language(code) { 12130 if (code === undefined) { 12131 return this.language_; 12132 } 12133 12134 this.language_ = String(code).toLowerCase(); 12135 return this; 12136 }; 12137 12138 /** 12139 * Get the player's language dictionary 12140 * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time 12141 * Languages specified directly in the player options have precedence 12142 * 12143 * @return {Array} 12144 * An array of of supported languages 12145 */ 12146 12147 12148 Player.prototype.languages = function languages() { 12149 return (0, _mergeOptions2['default'])(Player.prototype.options_.languages, this.languages_); 12150 }; 12151 12152 /** 12153 * returns a JavaScript object reperesenting the current track 12154 * information. **DOES not return it as JSON** 12155 * 12156 * @return {Object} 12157 * Object representing the current of track info 12158 */ 12159 12160 12161 Player.prototype.toJSON = function toJSON() { 12162 var options = (0, _mergeOptions2['default'])(this.options_); 12163 var tracks = options.tracks; 12164 12165 options.tracks = []; 12166 12167 for (var i = 0; i < tracks.length; i++) { 12168 var track = tracks[i]; 12169 12170 // deep merge tracks and null out player so no circular references 12171 track = (0, _mergeOptions2['default'])(track); 12172 track.player = undefined; 12173 options.tracks[i] = track; 12174 } 12175 12176 return options; 12177 }; 12178 12179 /** 12180 * Creates a simple modal dialog (an instance of the {@link ModalDialog} 12181 * component) that immediately overlays the player with arbitrary 12182 * content and removes itself when closed. 12183 * 12184 * @param {string|Function|Element|Array|null} content 12185 * Same as {@link ModalDialog#content}'s param of the same name. 12186 * The most straight-forward usage is to provide a string or DOM 12187 * element. 12188 * 12189 * @param {Object} [options] 12190 * Extra options which will be passed on to the {@link ModalDialog}. 12191 * 12192 * @return {ModalDialog} 12193 * the {@link ModalDialog} that was created 12194 */ 12195 12196 12197 Player.prototype.createModal = function createModal(content, options) { 12198 var _this5 = this; 12199 12200 options = options || {}; 12201 options.content = content || ''; 12202 12203 var modal = new _modalDialog2['default'](this, options); 12204 12205 this.addChild(modal); 12206 modal.on('dispose', function () { 12207 _this5.removeChild(modal); 12208 }); 12209 12210 return modal.open(); 12211 }; 12212 12213 /** 12214 * Gets tag settings 12215 * 12216 * @param {Element} tag 12217 * The player tag 12218 * 12219 * @return {Object}
12220 * An object containing all of the settings 12221 * for a player tag 12222 */ 12223 12224 12225 Player.getTagSettings = function getTagSettings(tag) { 12226 var baseOptions = { 12227 sources: [], 12228 tracks: [] 12229 }; 12230 12231 var tagOptions = Dom.getElAttributes(tag); 12232 var dataSetup = tagOptions['data-setup']; 12233 12234 if (Dom.hasElClass(tag, 'vjs-fluid')) { 12235 tagOptions.fluid = true; 12236 } 12237 12238 // Check if data-setup attr exists. 12239 if (dataSetup !== null) { 12240 // Parse options JSON 12241 // If empty string, make it a parsable json object. 12242 var _safeParseTuple = (0, _tuple2['default'])(dataSetup || '{}'), 12243 err = _safeParseTuple[0], 12244 data = _safeParseTuple[1]; 12245 12246 if (err) { 12247 _log2['default'].error(err); 12248 } 12249 (0, _obj.assign)(tagOptions, data); 12250 } 12251 12252 (0, _obj.assign)(baseOptions, tagOptions); 12253 12254 // Get tag children settings 12255 if (tag.hasChildNodes()) { 12256 var children = tag.childNodes; 12257 12258 for (var i = 0, j = children.length; i < j; i++) { 12259 var child = children[i]; 12260 // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/ 12261 var childName = child.nodeName.toLowerCase(); 12262 12263 if (childName === 'source') { 12264 baseOptions.sources.push(Dom.getElAttributes(child)); 12265 } else if (childName === 'track') { 12266 baseOptions.tracks.push(Dom.getElAttributes(child)); 12267 } 12268 } 12269 } 12270 12271 return baseOptions; 12272 }; 12273 12274 /** 12275 * Determine wether or not flexbox is supported 12276 * 12277 * @return {boolean} 12278 * - true if flexbox is supported 12279 * - false if flexbox is not supported 12280 */ 12281 12282 12283 Player.prototype.flexNotSupported_ = function flexNotSupported_() { 12284 var elem = _document2['default'].createElement('i'); 12285 12286 // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more 12287 // common flex features that we can rely on when checking for flex support. 12288 return !('flexBasis' in elem.style || 'webkitFlexBasis' in elem.style || 'mozFlexBasis' in elem.style || 'msFlexBasis' in elem.style || 12289 // IE10-specific (2012 flex spec) 12290 'msFlexOrder' in elem.style); 12291 }; 12292 12293 return Player; 12294}(_component2['default']); 12295 12296/** 12297 * Global player list 12298 * 12299 * @type {Object} 12300 */ 12301 12302 12303Player.players = {}; 12304 12305var navigator = _window2['default'].navigator; 12306 12307/* 12308 * Player instance options, surfaced using options 12309 * options = Player.prototype.options_ 12310 * Make changes in options, not here. 12311 * 12312 * @type {Object} 12313 * @private 12314 */ 12315Player.prototype.options_ = { 12316 // Default order of fallback technology 12317 techOrder: ['html5', 'flash'], 12318 // techOrder: ['flash','html5'], 12319 12320 html5: {}, 12321 flash: {}, 12322 12323 // defaultVolume: 0.85, 12324 defaultVolume: 0.00, 12325 12326 // default inactivity timeout 12327 inactivityTimeout: 2000, 12328 12329 // default playback rates 12330 playbackRates: [], 12331 // Add playback rate selection by adding rates 12332 // 'playbackRates': [0.5, 1, 1.5, 2], 12333 12334 // Included control sets 12335 children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'], 12336 12337 language: navigator && (navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language) || 'en', 12338 12339 // locales and their language translations 12340 languages: {}, 12341 12342 // Default message to show when a video cannot be played. 12343 notSupportedMessage: 'No compatible source was found for this media.' 12344}; 12345 12346[ 12347/** 12348 * Returns whether or not the player is in the "ended" state. 12349 * 12350 * @return {Boolean} True if the player is in the ended state, false if not. 12351 * @method Player#ended 12352 */ 12353'ended', 12354/** 12355 * Returns whether or not the player is in the "seeking" state. 12356 * 12357 * @return {Boolean} True if the player is in the seeking state, false if not. 12358 * @method Player#seeking 12359 */ 12360'seeking', 12361/** 12362 * Returns the TimeRanges of the media that are currently available 12363 * for seeking to. 12364 * 12365 * @return {TimeRanges} the seekable intervals of the media timeline 12366 * @method Player#seekable 12367 */ 12368'seekable', 12369/** 12370 * Returns the current state of network activity for the element, from 12371 * the codes in the list below. 12372 * - NETWORK_EMPTY (numeric value 0) 12373 * The element has not yet been initialised. All attributes are in 12374 * their initial states. 12375 * - NETWORK_IDLE (numeric value 1) 12376 * The element's resource selection algorithm is active and has 12377 * selected a resource, but it is not actually using the network at 12378 * this time. 12379 * - NETWORK_LOADING (numeric value 2) 12380 * The user agent is actively trying to download data. 12381 * - NETWORK_NO_SOURCE (numeric value 3) 12382 * The element's resource selection algorithm is active, but it has 12383 * not yet found a resource to use. 12384 * 12385 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states 12386 * @return {number} the current network activity state 12387 * @method Player#networkState 12388 */ 12389'networkState', 12390/** 12391 * Returns a value that expresses the current state of the element 12392 * with respect to rendering the current playback position, from the 12393 * codes in the list below.
12394 * - HAVE_NOTHING (numeric value 0) 12395 * No information regarding the media resource is available. 12396 * - HAVE_METADATA (numeric value 1) 12397 * Enough of the resource has been obtained that the duration of the 12398 * resource is available. 12399 * - HAVE_CURRENT_DATA (numeric value 2) 12400 * Data for the immediate current playback position is available. 12401 * - HAVE_FUTURE_DATA (numeric value 3) 12402 * Data for the immediate current playback position is available, as 12403 * well as enough data for the user agent to advance the current 12404 * playback position in the direction of playback. 12405 * - HAVE_ENOUGH_DATA (numeric value 4) 12406 * The user agent estimates that enough data is available for 12407 * playback to proceed uninterrupted. 12408 * 12409 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate 12410 * @return {number} the current playback rendering state 12411 * @method Player#readyState 12412 */ 12413'readyState'].forEach(function (fn) { 12414 Player.prototype[fn] = function () { 12415 return this.techGet_(fn); 12416 }; 12417}); 12418 12419TECH_EVENTS_RETRIGGER.forEach(function (event) { 12420 Player.prototype['handleTech' + (0, _toTitleCase2['default'])(event) + '_'] = function () { 12421 return this.trigger(event); 12422 }; 12423}); 12424 12425/** 12426 * Fired when the player has initial duration and dimension information 12427 * 12428 * @event Player#loadedmetadata 12429 * @type {EventTarget~Event} 12430 */ 12431 12432/** 12433 * Fired when the player has downloaded data at the current playback position 12434 * 12435 * @event Player#loadeddata 12436 * @type {EventTarget~Event} 12437 */ 12438 12439/** 12440 * Fired when the current playback position has changed * 12441 * During playback this is fired every 15-250 milliseconds, depending on the 12442 * playback technology in use. 12443 * 12444 * @event Player#timeupdate 12445 * @type {EventTarget~Event} 12446 */ 12447 12448/** 12449 * Fired when the volume changes 12450 * 12451 * @event Player#volumechange 12452 * @type {EventTarget~Event} 12453 */ 12454 12455_component2['default'].registerComponent('Player', Player); 12456exports['default'] = Player; 12457 12458},{"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){ 12459'use strict'; 12460 12461exports.__esModule = true; 12462 12463var _player = _dereq_(51); 12464 12465var _player2 = _interopRequireDefault(_player); 12466 12467function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12468 12469/** 12470 * The method for registering a video.js plugin. {@link videojs:videojs.registerPlugin]. 12471 * 12472 * @param {string} name 12473 * The name of the plugin that is being registered 12474 * 12475 * @param {plugins:PluginFn} init 12476 * The function that gets run when a `Player` initializes. 12477 */ 12478var plugin = function plugin(name, init) { 12479 _player2['default'].prototype[name] = init; 12480}; /** 12481 * @file plugins.js 12482 * @module plugins 12483 */ 12484exports['default'] = plugin; 12485 12486},{"51":51}],53:[function(_dereq_,module,exports){ 12487'use strict'; 12488 12489exports.__esModule = true; 12490 12491var _clickableComponent = _dereq_(3); 12492 12493var _clickableComponent2 = _interopRequireDefault(_clickableComponent); 12494 12495var _component = _dereq_(5); 12496 12497var _component2 = _interopRequireDefault(_component); 12498 12499function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12500 12501function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 12502 12503function _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; } 12504 12505function _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; } /** 12506 * @file popup-button.js 12507 */ 12508 12509 12510/** 12511 * A button class for use with {@link Popup} controls 12512 * 12513 * @extends ClickableComponent 12514 */ 12515var PopupButton = function (_ClickableComponent) { 12516 _inherits(PopupButton, _ClickableComponent); 12517 12518 /** 12519 * Create an instance of this class. 12520 * 12521 * @param {Player} player 12522 * The `Player` that this class should be attached to. 12523 * 12524 * @param {Object} [options] 12525 * The key/value store of player options. 12526 */ 12527 function PopupButton(player) { 12528 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 12529 12530 _classCallCheck(this, PopupButton); 12531 12532 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options)); 12533 12534 _this.update(); 12535 return _this; 12536 } 12537 12538 /** 12539 * Update the `Popup` that this button is attached to. 12540 */ 12541 12542
12543 PopupButton.prototype.update = function update() { 12544 var popup = this.createPopup(); 12545 12546 if (this.popup) { 12547 this.removeChild(this.popup); 12548 } 12549 12550 this.popup = popup; 12551 this.addChild(popup); 12552 12553 if (this.items && this.items.length === 0) { 12554 this.hide(); 12555 } else if (this.items && this.items.length > 1) { 12556 this.show(); 12557 } 12558 }; 12559 12560 /** 12561 * Create a `Popup`. - Override with specific functionality for component 12562 * 12563 * @abstract 12564 */ 12565 12566 12567 PopupButton.prototype.createPopup = function createPopup() {}; 12568 12569 /** 12570 * Create the `PopupButton`s DOM element. 12571 * 12572 * @return {Element} 12573 * The element that gets created. 12574 */ 12575 12576 12577 PopupButton.prototype.createEl = function createEl() { 12578 return _ClickableComponent.prototype.createEl.call(this, 'div', { 12579 className: this.buildCSSClass() 12580 }); 12581 }; 12582 12583 /** 12584 * Builds the default DOM `className`. 12585 * 12586 * @return {string} 12587 * The DOM `className` for this object. 12588 */ 12589 12590 12591 PopupButton.prototype.buildCSSClass = function buildCSSClass() { 12592 var menuButtonClass = 'vjs-menu-button'; 12593 12594 // If the inline option is passed, we want to use different styles altogether. 12595 if (this.options_.inline === true) { 12596 menuButtonClass += '-inline'; 12597 } else { 12598 menuButtonClass += '-popup'; 12599 } 12600 12601 return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this); 12602 }; 12603 12604 return PopupButton; 12605}(_clickableComponent2['default']); 12606 12607_component2['default'].registerComponent('PopupButton', PopupButton); 12608exports['default'] = PopupButton; 12609 12610},{"3":3,"5":5}],54:[function(_dereq_,module,exports){ 12611'use strict'; 12612 12613exports.__esModule = true; 12614 12615var _component = _dereq_(5); 12616 12617var _component2 = _interopRequireDefault(_component); 12618 12619var _dom = _dereq_(81); 12620 12621var Dom = _interopRequireWildcard(_dom); 12622 12623var _fn = _dereq_(83); 12624 12625var Fn = _interopRequireWildcard(_fn); 12626 12627var _events = _dereq_(82); 12628 12629var Events = _interopRequireWildcard(_events); 12630 12631function _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; } } 12632 12633function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12634 12635function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 12636 12637function _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; } 12638 12639function _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; } /** 12640 * @file popup.js 12641 */ 12642 12643 12644/** 12645 * The Popup component is used to build pop up controls. 12646 * 12647 * @extends Component 12648 */ 12649var Popup = function (_Component) { 12650 _inherits(Popup, _Component); 12651 12652 function Popup() { 12653 _classCallCheck(this, Popup); 12654 12655 return _possibleConstructorReturn(this, _Component.apply(this, arguments)); 12656 } 12657 12658 /**
12659 * Add a popup item to the popup 12660 * 12661 * @param {Object|string} component 12662 * Component or component type to add 12663 * 12664 */ 12665 Popup.prototype.addItem = function addItem(component) { 12666 this.addChild(component); 12667 component.on('click', Fn.bind(this, function () { 12668 this.unlockShowing(); 12669 })); 12670 }; 12671 12672 /** 12673 * Create the `PopupButton`s DOM element. 12674 * 12675 * @return {Element} 12676 * The element that gets created. 12677 */ 12678 12679 12680 Popup.prototype.createEl = function createEl() { 12681 var contentElType = this.options_.contentElType || 'ul'; 12682 12683 this.contentEl_ = Dom.createEl(contentElType, { 12684 className: 'vjs-menu-content' 12685 }); 12686 12687 var el = _Component.prototype.createEl.call(this, 'div', { 12688 append: this.contentEl_, 12689 className: 'vjs-menu' 12690 }); 12691 12692 el.appendChild(this.contentEl_); 12693 12694 // Prevent clicks from bubbling up. Needed for Popup Buttons, 12695 // where a click on the parent is significant 12696 Events.on(el, 'click', function (event) { 12697 event.preventDefault(); 12698 event.stopImmediatePropagation(); 12699 }); 12700 12701 return el; 12702 }; 12703 12704 return Popup; 12705}(_component2['default']); 12706 12707_component2['default'].registerComponent('Popup', Popup); 12708exports['default'] = Popup; 12709 12710},{"5":5,"81":81,"82":82,"83":83}],55:[function(_dereq_,module,exports){ 12711'use strict'; 12712 12713exports.__esModule = true; 12714 12715var _clickableComponent = _dereq_(3); 12716 12717var _clickableComponent2 = _interopRequireDefault(_clickableComponent); 12718 12719var _component = _dereq_(5); 12720 12721var _component2 = _interopRequireDefault(_component); 12722 12723var _fn = _dereq_(83); 12724 12725var Fn = _interopRequireWildcard(_fn); 12726 12727var _dom = _dereq_(81); 12728 12729var Dom = _interopRequireWildcard(_dom); 12730 12731var _browser = _dereq_(78); 12732 12733var browser = _interopRequireWildcard(_browser); 12734 12735function _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; } } 12736 12737function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12738 12739function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 12740 12741function _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; } 12742 12743function _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; } /** 12744 * @file poster-image.js 12745 */ 12746 12747 12748/** 12749 * A `ClickableComponent` that handles showing the poster image for the player. 12750 * 12751 * @extends ClickableComponent 12752 */ 12753var PosterImage = function (_ClickableComponent) { 12754 _inherits(PosterImage, _ClickableComponent); 12755 12756 /** 12757 * Create an instance of this class. 12758 * 12759 * @param {Player} player 12760 * The `Player` that this class should attach to. 12761 * 12762 * @param {Object} [options] 12763 * The key/value store of player options. 12764 */ 12765 function PosterImage(player, options) { 12766 _classCallCheck(this, PosterImage); 12767 12768 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options)); 12769 12770 _this.update(); 12771 player.on('posterchange', Fn.bind(_this, _this.update)); 12772 return _this; 12773 } 12774 12775 /** 12776 * Clean up and dispose of the `PosterImage`. 12777 */ 12778 12779 12780 PosterImage.prototype.dispose = function dispose() { 12781 this.player().off('posterchange', this.update); 12782 _ClickableComponent.prototype.dispose.call(this); 12783 }; 12784 12785 /** 12786 * Create the `PosterImage`s DOM element. 12787 * 12788 * @return {Element} 12789 * The element that gets created. 12790 */ 12791 12792 12793 PosterImage.prototype.createEl = function createEl() { 12794 var el = Dom.createEl('div', { 12795 className: 'vjs-poster', 12796 12797 // Don't want poster to be tabbable. 12798 tabIndex: -1 12799 }); 12800 12801 // To ensure the poster image resizes while maintaining its original aspect 12802 // ratio, use a div with `background-size` when available. For browsers that 12803 // do not support `background-size` (e.g. IE8), fall back on using a regular
12804 // img element. 12805 if (!browser.BACKGROUND_SIZE_SUPPORTED) { 12806 this.fallbackImg_ = Dom.createEl('img'); 12807 el.appendChild(this.fallbackImg_); 12808 } 12809 12810 return el; 12811 }; 12812 12813 /** 12814 * An {@link EventTarget~EventListener} for {@link Player#posterchange} events. 12815 * 12816 * @listens Player#posterchange 12817 * 12818 * @param {EventTarget~Event} [event] 12819 * The `Player#posterchange` event that triggered this function. 12820 */ 12821 12822 12823 PosterImage.prototype.update = function update(event) { 12824 var url = this.player().poster(); 12825 12826 this.setSrc(url); 12827 12828 // If there's no poster source we should display:none on this component 12829 // so it's not still clickable or right-clickable 12830 if (url) { 12831 this.show(); 12832 } else { 12833 this.hide(); 12834 } 12835 }; 12836 12837 /** 12838 * Set the source of the `PosterImage` depending on the display method. 12839 * 12840 * @param {string} url 12841 * The URL to the source for the `PosterImage`. 12842 */ 12843 12844 12845 PosterImage.prototype.setSrc = function setSrc(url) { 12846 if (this.fallbackImg_) { 12847 this.fallbackImg_.src = url; 12848 } else { 12849 var backgroundImage = ''; 12850 12851 // Any falsey values should stay as an empty string, otherwise 12852 // this will throw an extra error 12853 if (url) { 12854 backgroundImage = 'url("' + url + '")'; 12855 } 12856 12857 this.el_.style.backgroundImage = backgroundImage; 12858 } 12859 }; 12860 12861 /** 12862 * An {@link EventTarget~EventListener} for clicks on the `PosterImage`. See 12863 * {@link ClickableComponent#handleClick} for instances where this will be triggered. 12864 * 12865 * @listens tap 12866 * @listens click 12867 * @listens keydown 12868 * 12869 * @param {EventTarget~Event} event 12870 + The `click`, `tap` or `keydown` event that caused this function to be called. 12871 */ 12872 12873 12874 PosterImage.prototype.handleClick = function handleClick(event) { 12875 // We don't want a click to trigger playback when controls are disabled 12876 if (!this.player_.controls()) { 12877 return; 12878 } 12879 12880 if (this.player_.paused()) { 12881 this.player_.play(); 12882 } else { 12883 this.player_.pause(); 12884 } 12885 }; 12886 12887 return PosterImage; 12888}(_clickableComponent2['default']); 12889 12890_component2['default'].registerComponent('PosterImage', PosterImage); 12891exports['default'] = PosterImage; 12892 12893},{"3":3,"5":5,"78":78,"81":81,"83":83}],56:[function(_dereq_,module,exports){ 12894'use strict'; 12895 12896exports.__esModule = true; 12897exports.hasLoaded = exports.autoSetupTimeout = exports.autoSetup = undefined; 12898 12899var _dom = _dereq_(81); 12900 12901var Dom = _interopRequireWildcard(_dom); 12902 12903var _events = _dereq_(82); 12904 12905var Events = _interopRequireWildcard(_events); 12906 12907var _document = _dereq_(94); 12908 12909var _document2 = _interopRequireDefault(_document); 12910 12911var _window = _dereq_(95); 12912 12913var _window2 = _interopRequireDefault(_window); 12914 12915function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12916 12917function _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; } } 12918 12919/** 12920 * @file setup.js - Functions for setting up a player without 12921 * user interaction based on the data-setup `attribute` of the video tag. 12922 * 12923 * @module setup 12924 */ 12925var _windowLoaded = false; 12926var videojs = void 0; 12927 12928/** 12929 * Set up any tags that have a data-setup `attribute` when the player is started. 12930 */ 12931var autoSetup = function autoSetup() { 12932 12933 // Protect against breakage in non-browser environments. 12934 if (!Dom.isReal()) { 12935 return; 12936 } 12937 12938 // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack* 12939 // var vids = Array.prototype.slice.call(document.getElementsByTagName('video')); 12940 // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio')); 12941 // var mediaEls = vids.concat(audios); 12942 12943 // Because IE8 doesn't support calling slice on a node list, we need to loop 12944 // through each list of elements to build up a new, combined list of elements. 12945 var vids = _document2['default'].getElementsByTagName('video'); 12946 var audios = _document2['default'].getElementsByTagName('audio'); 12947 var mediaEls = []; 12948 12949 if (vids && vids.length > 0) { 12950 for (var i = 0, e = vids.length; i < e; i++) { 12951 mediaEls.push(vids[i]); 12952 } 12953 } 12954 12955 if (audios && audios.length > 0) { 12956 for (var _i = 0, _e = audios.length; _i < _e; _i++) { 12957 mediaEls.push(audios[_i]); 12958 } 12959 } 12960 12961 // Check if any media elements exist 12962 if (mediaEls && mediaEls.length > 0) { 12963 12964 for (var _i2 = 0, _e2 = mediaEls.length; _i2 < _e2; _i2++) { 12965 var mediaEl = mediaEls[_i2]; 12966 12967 // Check if element exists, has getAttribute func. 12968 // IE seems to consider typeof el.getAttribute == 'object' instead of 12969 // 'function' like expected, at least when loading the player immediately. 12970 if (mediaEl && mediaEl.getAttribute) { 12971 12972 // Make sure this player hasn't already been set up. 12973 if (mediaEl.player === undefined) { 12974 var options = mediaEl.getAttribute('data-setup'); 12975 12976 // Check if data-setup attr exists. 12977 // We only auto-setup if they've added the data-setup attr. 12978 if (options !== null) { 12979 // Create new video.js instance. 12980 videojs(mediaEl); 12981 } 12982 } 12983 12984 // If getAttribute isn't defined, we need to wait for the DOM. 12985 } else { 12986 autoSetupTimeout(1); 12987 break; 12988 } 12989 } 12990 12991 // No videos were found, so keep looping unless page is finished loading. 12992 } else if (!_windowLoaded) { 12993 autoSetupTimeout(1); 12994 } 12995}; 12996 12997/** 12998 * Wait until the page is loaded before running autoSetup. This will be called in 12999 * autoSetup if `hasLoaded` returns false. 13000 * 13001 * @param {number} wait 13002 * How long to wait in ms 13003 * 13004 * @param {videojs} [vjs] 13005 * The videojs library function 13006 */ 13007function autoSetupTimeout(wait, vjs) { 13008 if (vjs) { 13009 videojs = vjs; 13010 } 13011 13012 _window2['default'].setTimeout(autoSetup, wait); 13013} 13014 13015if (Dom.isReal() && _document2['default'].readyState === 'complete') { 13016 _windowLoaded = true; 13017} else { 13018 /** 13019 * Listen for the load event on window, and set _windowLoaded to true. 13020 * 13021 * @listens load 13022 */ 13023 Events.one(_window2['default'], 'load', function () { 13024 _windowLoaded = true; 13025 }); 13026} 13027 13028/** 13029 * check if the document has been loaded 13030 */ 13031var hasLoaded = function hasLoaded() { 13032 return _windowLoaded; 13033}; 13034 13035exports.autoSetup = autoSetup; 13036exports.autoSetupTimeout = autoSetupTimeout; 13037exports.hasLoaded = hasLoaded; 13038 13039},{"81":81,"82":82,"94":94,"95":95}],57:[function(_dereq_,module,exports){ 13040'use strict'; 13041 13042exports.__esModule = true; 13043 13044var _component = _dereq_(5); 13045 13046var _component2 = _interopRequireDefault(_component); 13047 13048var _dom = _dereq_(81); 13049 13050var Dom = _interopRequireWildcard(_dom); 13051 13052var _obj = _dereq_(88); 13053 13054function _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; } } 13055 13056function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 13057 13058function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 13059 13060function _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; } 13061 13062function _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 13062-13235
13062onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 13063 * @file slider.js 13064 */ 13065 13066 13067/** 13068 * The base functionality for a slider. Can be vertical or horizontal. 13069 * For instance the volume bar or the seek bar on a video is a slider. 13070 * 13071 * @extends Component 13072 */ 13073var Slider = function (_Component) { 13074 _inherits(Slider, _Component); 13075 13076 /** 13077 * Create an instance of this class 13078 * 13079 * @param {Player} player 13080 * The `Player` that this class should be attached to. 13081 * 13082 * @param {Object} [options] 13083 * The key/value store of player options. 13084 */ 13085 function Slider(player, options) { 13086 _classCallCheck(this, Slider); 13087 13088 // Set property names to bar to match with the child Slider class is looking for 13089 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 13090 13091 _this.bar = _this.getChild(_this.options_.barName); 13092 13093 // Set a horizontal or vertical class on the slider depending on the slider type 13094 _this.vertical(!!_this.options_.vertical); 13095 13096 _this.on('mousedown', _this.handleMouseDown); 13097 _this.on('touchstart', _this.handleMouseDown); 13098 _this.on('focus', _this.handleFocus); 13099 _this.on('blur', _this.handleBlur); 13100 _this.on('click', _this.handleClick); 13101 13102 _this.on(player, 'controlsvisible', _this.update); 13103 _this.on(player, _this.playerEvent, _this.update); 13104 return _this; 13105 } 13106 13107 /** 13108 * Create the `Button`s DOM element. 13109 * 13110 * @param {string} type 13111 * Type of element to create. 13112 * 13113 * @param {Object} [props={}] 13114 * List of properties in Object form. 13115 * 13116 * @param {Object} [attributes={}] 13117 * list of attributes in Object form. 13118 * 13119 * @return {Element} 13120 * The element that gets created. 13121 */ 13122 13123 13124 Slider.prototype.createEl = function createEl(type) { 13125 var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 13126 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 13127 13128 // Add the slider element class to all sub classes 13129 props.className = props.className + ' vjs-slider'; 13130 props = (0, _obj.assign)({ 13131 tabIndex: 0 13132 }, props); 13133 13134 attributes = (0, _obj.assign)({ 13135 'role': 'slider', 13136 'aria-valuenow': 0, 13137 'aria-valuemin': 0, 13138 'aria-valuemax': 100, 13139 'tabIndex': 0 13140 }, attributes); 13141 13142 return _Component.prototype.createEl.call(this, type, props, attributes); 13143 }; 13144 13145 /** 13146 * Handle `mousedown` or `touchstart` events on the `Slider`. 13147 * 13148 * @param {EventTarget~Event} event 13149 * `mousedown` or `touchstart` event that triggered this function 13150 * 13151 * @listens mousedown 13152 * @listens touchstart 13153 * @fires Slider#slideractive 13154 */ 13155 13156 13157 Slider.prototype.handleMouseDown = function handleMouseDown(event) { 13158 var doc = this.bar.el_.ownerDocument; 13159 13160 event.preventDefault(); 13161 Dom.blockTextSelection(); 13162 13163 this.addClass('vjs-sliding'); 13164 /** 13165 * Triggered when the slider is in an active state 13166 * 13167 * @event Slider#slideractive 13168 * @type {EventTarget~Event} 13169 */ 13170 this.trigger('slideractive'); 13171 13172 this.on(doc, 'mousemove', this.handleMouseMove); 13173 this.on(doc, 'mouseup', this.handleMouseUp); 13174 this.on(doc, 'touchmove', this.handleMouseMove); 13175 this.on(doc, 'touchend', this.handleMouseUp); 13176 13177 this.handleMouseMove(event); 13178 }; 13179 13180 /** 13181 * Handle the `mousemove`, `touchmove`, and `mousedown` events on this `Slider`. 13182 * The `mousemove` and `touchmove` events will only only trigger this function during 13183 * `mousedown` and `touchstart`. This is due to {@link Slider#handleMouseDown} and 13184 * {@link Slider#handleMouseUp}. 13185 * 13186 * @param {EventTarget~Event} event 13187 * `mousedown`, `mousemove`, `touchstart`, or `touchmove` event that triggered 13188 * this function 13189 * 13190 * @listens mousemove 13191 * @listens touchmove 13192 */ 13193 13194 13195 Slider.prototype.handleMouseMove = function handleMouseMove(event) {}; 13196 13197 /** 13198 * Handle `mouseup` or `touchend` events on the `Slider`. 13199 * 13200 * @param {EventTarget~Event} event 13201 * `mouseup` or `touchend` event that triggered this function. 13202 * 13203 * @listens touchend 13204 * @listens mouseup 13205 * @fires Slider#sliderinactive 13206 */ 13207 13208 13209 Slider.prototype.handleMouseUp = function handleMouseUp() { 13210 var doc = this.bar.el_.ownerDocument; 13211 13212 Dom.unblockTextSelection(); 13213 13214 this.removeClass('vjs-sliding'); 13215 /** 13216 * Triggered when the slider is no longer in an active state. 13217 * 13218 * @event Slider#sliderinactive 13219 * @type {EventTarget~Event} 13220 */ 13221 this.trigger('sliderinactive'); 13222 13223 this.off(doc, 'mousemove', this.handleMouseMove); 13224 this.off(doc, 'mouseup', this.handleMouseUp); 13225 this.off(doc, 'touchmove', this.handleMouseMove); 13226 this.off(doc, 'touchend', this.handleMouseUp); 13227 13228 this.update(); 13229 }; 13230 13231 /** 13232 * Update the progress bar of the `Slider`. 13233 */ 13234 13235
13236 Slider.prototype.update = function update() { 13237 // In VolumeBar init we have a setTimeout for update that pops and update to the end of the 13238 // execution stack. The player is destroyed before then update will cause an error 13239 if (!this.el_) { 13240 return; 13241 } 13242 13243 // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse. 13244 // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later. 13245 // var progress = (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration(); 13246 var progress = this.getPercent(); 13247 var bar = this.bar; 13248 13249 // If there's no bar... 13250 if (!bar) { 13251 return; 13252 } 13253 13254 // Protect against no duration and other division issues 13255 if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) { 13256 progress = 0; 13257 } 13258 13259 // Convert to a percentage for setting 13260 var percentage = (progress * 100).toFixed(2) + '%'; 13261 13262 // Set the new bar width or height 13263 if (this.vertical()) { 13264 bar.el().style.height = percentage; 13265 } else { 13266 bar.el().style.width = percentage; 13267 } 13268 }; 13269 13270 /** 13271 * Calculate distance for slider 13272 * 13273 * @param {EventTarget~Event} event 13274 * The event that caused this function to run. 13275 * 13276 * @return {number} 13277 * The current position of the Slider. 13278 * - postition.x for vertical `Slider`s 13279 * - postition.y for horizontal `Slider`s 13280 */ 13281 13282 13283 Slider.prototype.calculateDistance = function calculateDistance(event) { 13284 var position = Dom.getPointerPosition(this.el_, event); 13285 13286 if (this.vertical()) { 13287 return position.y; 13288 } 13289 return position.x; 13290 }; 13291 13292 /** 13293 * Handle a `focus` event on this `Slider`. 13294 * 13295 * @param {EventTarget~Event} event 13296 * The `focus` event that caused this function to run. 13297 * 13298 * @listens focus 13299 */ 13300 13301 13302 Slider.prototype.handleFocus = function handleFocus() { 13303 this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress); 13304 }; 13305 13306 /** 13307 * Handle a `keydown` event on the `Slider`. Watches for left, rigth, up, and down 13308 * arrow keys. This function will only be called when the slider has focus. See 13309 * {@link Slider#handleFocus} and {@link Slider#handleBlur}. 13310 * 13311 * @param {EventTarget~Event} event 13312 * the `keydown` event that caused this function to run. 13313 * 13314 * @listens keydown 13315 */ 13316 13317 13318 Slider.prototype.handleKeyPress = function handleKeyPress(event) { 13319 // Left and Down Arrows 13320 if (event.which === 37 || event.which === 40) { 13321 event.preventDefault(); 13322 this.stepBack(); 13323 13324 // Up and Right Arrows 13325 } else if (event.which === 38 || event.which === 39) { 13326 event.preventDefault(); 13327 this.stepForward(); 13328 } 13329 }; 13330 13331 /** 13332 * Handle a `blur` event on this `Slider`. 13333 * 13334 * @param {EventTarget~Event} event 13335 * The `blur` event that caused this function to run. 13336 * 13337 * @listens blur 13338 */ 13339 13340 Slider.prototype.handleBlur = function handleBlur() { 13341 this.off(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress); 13342 }; 13343 13344 /** 13345 * Listener for click events on slider, used to prevent clicks 13346 * from bubbling up to parent elements like button menus. 13347 * 13348 * @param {Object} event 13349 * Event that caused this object to run 13350 */ 13351 13352 13353 Slider.prototype.handleClick = function handleClick(event) { 13354 event.stopImmediatePropagation(); 13355 event.preventDefault(); 13356 }; 13357 13358 /** 13359 * Get/set if slider is horizontal for vertical 13360 * 13361 * @param {boolean} [bool] 13362 * - true if slider is vertical, 13363 * - false is horizontal 13364 * 13365 * @return {boolean|Slider} 13366 * - true if slider is vertical, and getting 13367 * - false is horizontal, and getting 13368 * - a reference to this object when setting 13369 */ 13370 13371 13372 Slider.prototype.vertical = function vertical(bool) { 13373 if (bool === undefined) { 13374 return this.vertical_ || false; 13375 } 13376 13377 this.vertical_ = !!bool; 13378 13379 if (this.vertical_) { 13380 this.addClass('vjs-slider-vertical'); 13381 } else { 13382 this.addClass('vjs-slider-horizontal'); 13383 } 13384 13385 return this; 13386 }; 13387 13388 return Slider; 13389}(_component2['default']); 13390 13391_component2['default'].registerComponent('Slider', Slider); 13392exports['default'] = Slider; 13393 13394},{"5":5,"81":81,"88":88}],58:[function(_dereq_,module,exports){ 13395'use strict'; 13396 13397exports.__esModule = true; 13398/** 13399 * @file flash-rtmp.js 13400 * @module flash-rtmp 13401 */ 13402 13403/** 13404 * Add RTMP properties to the {@link Flash} Tech. 13405 *
vendor: 4,097 bytes, lines 13406-13576
13406 * @param {Flash} Flash 13407 * The flash tech class. 13408 * 13409 * @mixin FlashRtmpDecorator 13410 */ 13411function FlashRtmpDecorator(Flash) { 13412 Flash.streamingFormats = { 13413 'rtmp/mp4': 'MP4', 13414 'rtmp/flv': 'FLV' 13415 }; 13416 13417 /** 13418 * Join connection and stream with an ampersand. 13419 * 13420 * @param {string} connection 13421 * The connection string. 13422 * 13423 * @param {string} stream 13424 * The stream string. 13425 */ 13426 Flash.streamFromParts = function (connection, stream) { 13427 return connection + '&' + stream; 13428 }; 13429 13430 /** 13431 * The flash parts object that contains connection and stream info. 13432 * 13433 * @typedef {Object} Flash~PartsObject 13434 * 13435 * @property {string} connection 13436 * The connection string of a source, defaults to an empty string. 13437 * 13438 * @property {string} stream 13439 * The stream string of the source, defaults to an empty string. 13440 */ 13441 13442 /** 13443 * Convert a source url into a stream and connection parts. 13444 * 13445 * @param {string} src 13446 * the source url 13447 * 13448 * @return {Flash~PartsObject} 13449 * The parts object that contains a connection and a stream 13450 */ 13451 Flash.streamToParts = function (src) { 13452 var parts = { 13453 connection: '', 13454 stream: '' 13455 }; 13456 13457 if (!src) { 13458 return parts; 13459 } 13460 13461 // Look for the normal URL separator we expect, '&'. 13462 // If found, we split the URL into two pieces around the 13463 // first '&'. 13464 var connEnd = src.search(/&(?!\w+=)/); 13465 var streamBegin = void 0; 13466 13467 if (connEnd !== -1) { 13468 streamBegin = connEnd + 1; 13469 } else { 13470 // If there's not a '&', we use the last '/' as the delimiter. 13471 connEnd = streamBegin = src.lastIndexOf('/') + 1; 13472 if (connEnd === 0) { 13473 // really, there's not a '/'? 13474 connEnd = streamBegin = src.length; 13475 } 13476 } 13477 13478 parts.connection = src.substring(0, connEnd); 13479 parts.stream = src.substring(streamBegin, src.length); 13480 13481 return parts; 13482 }; 13483 13484 /** 13485 * Check if the source type is a streaming type. 13486 * 13487 * @param {string} srcType 13488 * The mime type to check. 13489 * 13490 * @return {boolean} 13491 * - True if the source type is a streaming type. 13492 * - False if the source type is not a streaming type. 13493 */ 13494 Flash.isStreamingType = function (srcType) { 13495 return srcType in Flash.streamingFormats; 13496 }; 13497 13498 // RTMP has four variations, any string starting 13499 // with one of these protocols should be valid 13500 13501 /** 13502 * Regular expression used to check if the source is an rtmp source. 13503 * 13504 * @property {RegExp} Flash.RTMP_RE 13505 */ 13506 Flash.RTMP_RE = /^rtmp[set]?:\/\//i; 13507 13508 /** 13509 * Check if the source itself is a streaming type. 13510 * 13511 * @param {string} src 13512 * The url to the source. 13513 * 13514 * @return {boolean} 13515 * - True if the source url indicates that the source is streaming. 13516 * - False if the shource url indicates that the source url is not streaming. 13517 */ 13518 Flash.isStreamingSrc = function (src) { 13519 return Flash.RTMP_RE.test(src); 13520 }; 13521 13522 /** 13523 * A source handler for RTMP urls 13524 * @type {Object} 13525 */ 13526 Flash.rtmpSourceHandler = {}; 13527 13528 /** 13529 * Check if Flash can play the given mime type. 13530 * 13531 * @param {string} type 13532 * The mime type to check 13533 * 13534 * @return {string} 13535 * 'maybe', or '' (empty string) 13536 */ 13537 Flash.rtmpSourceHandler.canPlayType = function (type) { 13538 if (Flash.isStreamingType(type)) { 13539 return 'maybe'; 13540 } 13541 13542 return ''; 13543 }; 13544 13545 /** 13546 * Check if Flash can handle the source natively 13547 * 13548 * @param {Object} source 13549 * The source object 13550 * 13551 * @param {Object} [options] 13552 * The options passed to the tech 13553 * 13554 * @return {string} 13555 * 'maybe', or '' (empty string) 13556 */ 13557 Flash.rtmpSourceHandler.canHandleSource = function (source, options) { 13558 var can = Flash.rtmpSourceHandler.canPlayType(source.type); 13559 13560 if (can) { 13561 return can; 13562 } 13563 13564 if (Flash.isStreamingSrc(source.src)) { 13565 return 'maybe'; 13566 } 13567 13568 return ''; 13569 }; 13570 13571 /** 13572 * Pass the source to the flash object. 13573 * 13574 * @param {Object} source 13575 * The source object 13576 *
13577 * @param {Flash} tech 13578 * The instance of the Flash tech 13579 * 13580 * @param {Object} [options] 13581 * The options to pass to the source 13582 */ 13583 Flash.rtmpSourceHandler.handleSource = function (source, tech, options) { 13584 var srcParts = Flash.streamToParts(source.src); 13585 13586 tech.setRtmpConnection(srcParts.connection); 13587 tech.setRtmpStream(srcParts.stream); 13588 }; 13589 13590 // Register the native source handler 13591 Flash.registerSourceHandler(Flash.rtmpSourceHandler); 13592 13593 return Flash; 13594} 13595 13596exports['default'] = FlashRtmpDecorator; 13597 13598},{}],59:[function(_dereq_,module,exports){ 13599'use strict'; 13600 13601exports.__esModule = true; 13602 13603var _tech = _dereq_(62); 13604 13605var _tech2 = _interopRequireDefault(_tech); 13606 13607var _dom = _dereq_(81); 13608 13609var Dom = _interopRequireWildcard(_dom); 13610 13611var _url = _dereq_(92); 13612 13613var Url = _interopRequireWildcard(_url); 13614 13615var _timeRanges = _dereq_(90); 13616 13617var _flashRtmp = _dereq_(58); 13618 13619var _flashRtmp2 = _interopRequireDefault(_flashRtmp); 13620 13621var _component = _dereq_(5); 13622 13623var _component2 = _interopRequireDefault(_component); 13624 13625var _window = _dereq_(95); 13626 13627var _window2 = _interopRequireDefault(_window); 13628 13629var _obj = _dereq_(88); 13630 13631function _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; } } 13632 13633function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 13634 13635function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 13636 13637function _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; } 13638 13639function _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; } /** 13640 * @file flash.js 13641 * VideoJS-SWF - Custom Flash Player with HTML5-ish API 13642 * https://github.com/zencoder/video-js-swf 13643 * Not using setupTriggers. Using global onEvent func to distribute events 13644 */ 13645 13646var navigator = _window2['default'].navigator; 13647 13648/** 13649 * Flash Media Controller - Wrapper for Flash Media API 13650 * 13651 * @mixes FlashRtmpDecorator 13652 * @mixes Tech~SouceHandlerAdditions 13653 * @extends Tech 13654 */ 13655 13656var Flash = function (_Tech) { 13657 _inherits(Flash, _Tech); 13658 13659 /** 13660 * Create an instance of this Tech. 13661 * 13662 * @param {Object} [options] 13663 * The key/value store of player options. 13664 * 13665 * @param {Component~ReadyCallback} ready 13666 * Callback function to call when the `Flash` Tech is ready. 13667 */ 13668 function Flash(options, ready) { 13669 _classCallCheck(this, Flash); 13670 13671 // Set the source when ready 13672 var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready)); 13673 13674 if (options.source) { 13675 _this.ready(function () { 13676 this.setSource(options.source); 13677 }, true); 13678 } 13679 13680 // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers 13681 // This allows resetting the playhead when we catch the reload 13682 if (options.startTime) { 13683 _this.ready(function () { 13684 this.load(); 13685 this.play(); 13686 this.currentTime(options.startTime); 13687 }, true); 13688 } 13689 13690 // Add global window functions that the swf expects 13691 // A 4.x workflow we weren't able to solve for in 5.0 13692 // because of the need to hard code these functions 13693 // into the swf for security reasons 13694 _window2['default'].videojs = _window2['default'].videojs || {}; 13695 _window2['default'].videojs.Flash = _window2['default'].videojs.Flash || {}; 13696 _window2['default'].videojs.Flash.onReady = Flash.onReady; 13697 _window2['default'].videojs.Flash.onEvent = Flash.onEvent; 13698 _window2['default'].videojs.Flash.onError = Flash.onError; 13699 13700 _this.on('seeked', function () { 13701 this.lastSeekTarget_ = undefined; 13702 }); 13703 13704 return _this; 13705 } 13706 13707 /** 13708 * Create the `Flash` Tech's DOM element. 13709 * 13710 * @return {Element} 13711 * The element that gets created. 13712 */ 13713 13714 13715 Flash.prototype.createEl = function createEl() { 13716 var options = this.options_; 13717 13718 // If video.js is hosted locally you should also set the location 13719 // for the hosted swf, which should be relative to the page (not video.js) 13720 // Otherwise this adds a CDN url. 13721 // The CDN also auto-adds a swf URL for that specific version. 13722 if (!options.swf) { 13723 var ver = '5.2.0'; 13724 13725 options.swf = '//vjs.zencdn.net/swf/' + ver + '/video-js.swf'; 13726 } 13727 13728 // Generate ID for swf object 13729 var objId = options.techId; 13730 13731 // Merge default flashvars with ones passed in to init 13732 var flashVars = (0, _obj.assign)({ 13733 13734 // SWF Callback Functions 13735 readyFunction: 'videojs.Flash.onReady', 13736 eventProxyFunction: 'videojs.Flash.onEvent', 13737 errorEventProxyFunction: 'videojs.Flash.onError', 13738 13739 // Player Settings 13740 autoplay: options.autoplay, 13741 preload: options.preload, 13742 loop: options.loop, 13743 muted: options.muted 13744 13745 }, options.flashVars); 13746 13747 // Merge default parames with ones passed in 13748 var params = (0, _obj.assign)({ 13749 // Opaque is needed to overlay controls, but can affect playback performance 13750 wmode: 'opaque', 13751 // Using bgcolor prevents a white flash when the object is loading 13752 bgcolor: '#000000' 13753 }, options.params); 13754 13755 // Merge default attributes with ones passed in 13756 var attributes = (0, _obj.assign)({ 13757 // Both ID and Name needed or swf to identify itself 13758 id: objId, 13759 name: objId, 13760 'class': 'vjs-tech' 13761 }, options.attributes); 13762 13763 this.el_ = Flash.embed(options.swf, flashVars, params, attributes); 13764 this.el_.tech = this; 13765 13766 return this.el_; 13767 }; 13768 13769 /** 13770 * Called by {@link Player#play} to play using the `Flash` `Tech`. 13771 */ 13772 13773 13774 Flash.prototype.play = function play() { 13775 if (this.ended()) { 13776 this.setCurrentTime(0); 13777 } 13778 this.el_.vjs_play(); 13779 }; 13780 13781 /** 13782 * Called by {@link Player#pause} to pause using the `Flash` `Tech`. 13783 */ 13784 13785 13786 Flash.prototype.pause = function pause() { 13787 this.el_.vjs_pause(); 13788 }; 13789 13790 /** 13791 * A getter/setter for the `Flash` Tech's source object. 13792 * > Note: Please use {@link Flash#setSource} 13793 * 13794 * @param {Tech~SourceObject} [src] 13795 * The source object you want to set on the `Flash` techs. 13796 * 13797 * @return {Tech~SourceObject|undefined} 13798 * - The current source object when a source is not passed in. 13799 * - undefined when setting 13800 * 13801 * @deprecated Since version 5. 13802 */ 13803 13804 13805 Flash.prototype.src = function src(_src) { 13806 if (_src === undefined) { 13807 return this.currentSrc(); 13808 } 13809 13810 // Setting src through `src` not `setSrc` will be deprecated 13811 return this.setSrc(_src); 13812 }; 13813 13814 /** 13815 * A getter/setter for the `Flash` Tech's source object. 13816 * 13817 * @param {Tech~SourceObject} [src] 13818 * The source object you want to set on the `Flash` techs. 13819 * 13820 * @return {Tech~SourceObject|undefined} 13821 * - The current source object when a source is not passed in. 13822 * - undefined when setting 13823 */ 13824 13825 13826 Flash.prototype.setSrc = function setSrc(src) { 13827 var _this2 = this; 13828 13829 // Make sure source URL is absolute. 13830 src = Url.getAbsoluteURL(src); 13831 this.el_.vjs_src(src); 13832 13833 // Currently the SWF doesn't autoplay if you load a source later. 13834 // e.g. Load player w/ no source, wait 2s, set src. 13835 if (this.autoplay()) { 13836 this.setTimeout(function () { 13837 return _this2.play(); 13838 }, 0); 13839 } 13840 }; 13841 13842 /** 13843 * Indicates whether the media is currently seeking to a new position or not. 13844 * 13845 * @return {boolean} 13846 * - True if seeking to a new position 13847 * - False otherwise 13848 */ 13849 13850 13851 Flash.prototype.seeking = function seeking() { 13852 return this.lastSeekTarget_ !== undefined; 13853 }; 13854 13855 /** 13856 * Returns the current time in seconds that the media is at in playback. 13857 * 13858 * @param {number} time 13859 * Current playtime of the media in seconds. 13860 */ 13861 13862 13863 Flash.prototype.setCurrentTime = function setCurrentTime(time) { 13864 var seekable = this.seekable(); 13865 13866 if (seekable.length) { 13867 // clamp to the current seekable range 13868 time = time > seekable.start(0) ? time : seekable.start(0); 13869 time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1); 13870 13871 this.lastSeekTarget_ = time; 13872 this.trigger('seeking'); 13873 this.el_.vjs_setProperty('currentTime', time); 13874 _Tech.prototype.setCurrentTime.call(this); 13875 } 13876 }; 13877 13878 /** 13879 * Get the current playback time in seconds 13880 * 13881 * @return {number} 13882 * The current time of playback in seconds. 13883 */ 13884 13885 13886 Flash.prototype.currentTime = function currentTime() { 13887 // when seeking make the reported time keep up with the requested time 13888 // by reading the time we're seeking to 13889 if (this.seeking()) { 13890 return this.lastSeekTarget_ || 0; 13891 } 13892 return this.el_.vjs_getProperty('currentTime'); 13893 }; 13894 13895 /** 13896 * Get the current source 13897 * 13898 * @method currentSrc 13899 * @return {Tech~SourceObject} 13900 * The current source 13901 */ 13902 13903 13904 Flash.prototype.currentSrc = function currentSrc() { 13905 if (this.currentSource_) { 13906 return this.currentSource_.src; 13907 } 13908 return this.el_.vjs_getProperty('currentSrc'); 13909 }; 13910 13911 /** 13912 * Get the total duration of the current media. 13913 * 13914 * @return {number} 13915 8 The total duration of the current media. 13916 */ 13917 13918 13919 Flash.prototype.duration = function duration() { 13920 if (this.readyState() === 0) { 13921 return NaN; 13922 } 13923 var duration = this.el_.vjs_getProperty('duration'); 13924 13925 return duration >= 0 ? duration : Infinity; 13926 }; 13927 13928 /** 13929 * Load media into Tech. 13930 */ 13931 13932 13933 Flash.prototype.load = function load() { 13934 this.el_.vjs_load(); 13935 }; 13936 13937 /** 13938 * Get the poster image that was set on the tech. 13939 */ 13940 13941 13942 Flash.prototype.poster = function poster() { 13943 this.el_.vjs_getProperty('poster'); 13944 }; 13945 13946 /** 13947 * Poster images are not handled by the Flash tech so make this is a no-op. 13948 */ 13949 13950 13951 Flash.prototype.setPoster = function setPoster() {}; 13952 13953 /** 13954 * Determine the time ranges that can be seeked to in the media. 13955 * 13956 * @return {TimeRange} 13957 * Returns the time ranges that can be seeked to. 13958 */ 13959 13960 13961 Flash.prototype.seekable = function seekable() { 13962 var duration = this.duration(); 13963 13964 if (duration === 0) { 13965 return (0, _timeRanges.createTimeRange)(); 13966 } 13967 return (0, _timeRanges.createTimeRange)(0, duration); 13968 }; 13969 13970 /** 13971 * Get and create a `TimeRange` object for buffering. 13972 * 13973 * @return {TimeRange} 13974 * The time range object that was created. 13975 */ 13976 13977 13978 Flash.prototype.buffered = function buffered() { 13979 var ranges = this.el_.vjs_getProperty('buffered'); 13980 13981 if (ranges.length === 0) { 13982 return (0, _timeRanges.createTimeRange)(); 13983 } 13984 return (0, _timeRanges.createTimeRange)(ranges[0][0], ranges[0][1]); 13985 }; 13986 13987 /** 13988 * Get fullscreen support - 13989 * 13990 * Flash does not allow fullscreen through javascript 13991 * so this always returns false. 13992 * 13993 * @return {boolean}
13994 * The Flash tech does not support fullscreen, so it will always return false. 13995 */ 13996 13997 13998 Flash.prototype.supportsFullScreen = function supportsFullScreen() { 13999 // Flash does not allow fullscreen through javascript 14000 return false; 14001 }; 14002 14003 /** 14004 * Flash does not allow fullscreen through javascript 14005 * so this always returns false. 14006 * 14007 * @return {boolean} 14008 * The Flash tech does not support fullscreen, so it will always return false. 14009 */ 14010 14011 14012 Flash.prototype.enterFullScreen = function enterFullScreen() { 14013 return false; 14014 }; 14015 14016 return Flash; 14017}(_tech2['default']); 14018 14019// Create setters and getters for attributes 14020 14021 14022var _api = Flash.prototype; 14023var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(','); 14024var _readOnly = 'networkState,readyState,initialTime,startOffsetTime,paused,ended,videoWidth,videoHeight'.split(','); 14025 14026function _createSetter(attr) { 14027 var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1); 14028 14029 _api['set' + attrUpper] = function (val) { 14030 return this.el_.vjs_setProperty(attr, val); 14031 }; 14032}
vendor: 12,234 bytes, lines 14033-14434
14033 14034function _createGetter(attr) { 14035 _api[attr] = function () { 14036 return this.el_.vjs_getProperty(attr); 14037 }; 14038} 14039 14040// Create getter and setters for all read/write attributes 14041for (var i = 0; i < _readWrite.length; i++) { 14042 _createGetter(_readWrite[i]); 14043 _createSetter(_readWrite[i]); 14044} 14045 14046// Create getters for read-only attributes 14047for (var _i = 0; _i < _readOnly.length; _i++) { 14048 _createGetter(_readOnly[_i]); 14049} 14050 14051/** ------------------------------ Getters ------------------------------ **/ 14052/** 14053 * Get the value of `rtmpConnection` from the swf. 14054 * 14055 * @method Flash#rtmpConnection 14056 * @return {string} 14057 * The current value of `rtmpConnection` on the swf. 14058 */ 14059 14060/** 14061 * Get the value of `rtmpStream` from the swf. 14062 * 14063 * @method Flash#rtmpStream 14064 * @return {string} 14065 * The current value of `rtmpStream` on the swf. 14066 */ 14067 14068/** 14069 * Get the value of `preload` from the swf. `preload` indicates 14070 * what should download before the media is interacted with. It can have the following 14071 * values: 14072 * - none: nothing should be downloaded 14073 * - metadata: poster and the first few frames of the media may be downloaded to get 14074 * media dimensions and other metadata 14075 * - auto: allow the media and metadata for the media to be downloaded before 14076 * interaction 14077 * 14078 * @method Flash#preload 14079 * @return {string} 14080 * The value of `preload` from the swf. Will be 'none', 'metadata', 14081 * or 'auto'. 14082 */ 14083 14084/** 14085 * Get the value of `defaultPlaybackRate` from the swf. 14086 * 14087 * @method Flash#defaultPlaybackRate 14088 * @return {number} 14089 * The current value of `defaultPlaybackRate` on the swf. 14090 */ 14091 14092/** 14093 * Get the value of `playbackRate` from the swf. `playbackRate` indicates 14094 * the rate at which the media is currently playing back. Examples: 14095 * - if playbackRate is set to 2, media will play twice as fast. 14096 * - if playbackRate is set to 0.5, media will play half as fast. 14097 * 14098 * @method Flash#playbackRate 14099 * @return {number} 14100 * The value of `playbackRate` from the swf. A number indicating 14101 * the current playback speed of the media, where 1 is normal speed. 14102 */ 14103 14104/** 14105 * Get the value of `autoplay` from the swf. `autoplay` indicates 14106 * that the media should start to play as soon as the page is ready. 14107 * 14108 * @method Flash#autoplay 14109 * @return {boolean} 14110 * - The value of `autoplay` from the swf. 14111 * - True indicates that the media ashould start as soon as the page loads. 14112 * - False indicates that the media should not start as soon as the page loads. 14113 */ 14114 14115/** 14116 * Get the value of `loop` from the swf. `loop` indicates 14117 * that the media should return to the start of the media and continue playing once 14118 * it reaches the end. 14119 * 14120 * @method Flash#loop 14121 * @return {boolean} 14122 * - The value of `loop` from the swf. 14123 * - True indicates that playback should seek back to start once 14124 * the end of a media is reached. 14125 * - False indicates that playback should not loop back to the start when the 14126 * end of the media is reached. 14127 */ 14128 14129/** 14130 * Get the value of `mediaGroup` from the swf. 14131 * 14132 * @method Flash#mediaGroup 14133 * @return {string} 14134 * The current value of `mediaGroup` on the swf. 14135 */ 14136 14137/** 14138 * Get the value of `controller` from the swf. 14139 * 14140 * @method Flash#controller 14141 * @return {string} 14142 * The current value of `controller` on the swf. 14143 */ 14144 14145/** 14146 * Get the value of `controls` from the swf. `controls` indicates 14147 * whether the native flash controls should be shown or hidden. 14148 * 14149 * @method Flash#controls 14150 * @return {boolean} 14151 * - The value of `controls` from the swf. 14152 * - True indicates that native controls should be showing. 14153 * - False indicates that native controls should be hidden. 14154 */ 14155 14156/** 14157 * Get the value of the `volume` from the swf. `volume` indicates the current 14158 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and 14159 * so on. 14160 * 14161 * @method Flash#volume 14162 * @return {number} 14163 * The volume percent as a decimal. Value will be between 0-1. 14164 */ 14165 14166/** 14167 * Get the value of the `muted` from the swf. `muted` indicates the current 14168 * audio level should be silent. 14169 * 14170 * @method Flash#muted 14171 * @return {boolean} 14172 * - True if the audio should be set to silent 14173 * - False otherwise 14174 */ 14175 14176/** 14177 * Get the value of `defaultMuted` from the swf. `defaultMuted` indicates 14178 * whether the media should start muted or not. Only changes the default state of the 14179 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the 14180 * current state. 14181 * 14182 * @method Flash#defaultMuted 14183 * @return {boolean} 14184 * - The value of `defaultMuted` from the swf. 14185 * - True indicates that the media should start muted. 14186 * - False indicates that the media should not start muted. 14187 */ 14188 14189/** 14190 * Get the value of `networkState` from the swf. `networkState` indicates 14191 * the current network state. It returns an enumeration from the following list: 14192 * - 0: NETWORK_EMPTY 14193 * - 1: NEWORK_IDLE 14194 * - 2: NETWORK_LOADING 14195 * - 3: NETWORK_NO_SOURCE 14196 * 14197 * @method Flash#networkState 14198 * @return {number} 14199 * The value of `networkState` from the swf. This will be a number 14200 * from the list in the description. 14201 */ 14202 14203/** 14204 * Get the value of `readyState` from the swf. `readyState` indicates 14205 * the current state of the media element. It returns an enumeration from the 14206 * following list: 14207 * - 0: HAVE_NOTHING 14208 * - 1: HAVE_METADATA 14209 * - 2: HAVE_CURRENT_DATA 14210 * - 3: HAVE_FUTURE_DATA 14211 * - 4: HAVE_ENOUGH_DATA 14212 * 14213 * @method Flash#readyState 14214 * @return {number} 14215 * The value of `readyState` from the swf. This will be a number 14216 * from the list in the description. 14217 */ 14218 14219/** 14220 * Get the value of `readyState` from the swf. `readyState` indicates 14221 * the current state of the media element. It returns an enumeration from the 14222 * following list: 14223 * - 0: HAVE_NOTHING 14224 * - 1: HAVE_METADATA 14225 * - 2: HAVE_CURRENT_DATA 14226 * - 3: HAVE_FUTURE_DATA 14227 * - 4: HAVE_ENOUGH_DATA 14228 * 14229 * @method Flash#readyState 14230 * @return {number} 14231 * The value of `readyState` from the swf. This will be a number 14232 * from the list in the description. 14233 */ 14234 14235/** 14236 * Get the value of `initialTime` from the swf. 14237 * 14238 * @method Flash#initialTime 14239 * @return {number} 14240 * The `initialTime` proprety on the swf. 14241 */ 14242 14243/** 14244 * Get the value of `startOffsetTime` from the swf. 14245 * 14246 * @method Flash#startOffsetTime 14247 * @return {number} 14248 * The `startOffsetTime` proprety on the swf. 14249 */ 14250 14251/** 14252 * Get the value of `paused` from the swf. `paused` indicates whether the swf 14253 * is current paused or not. 14254 * 14255 * @method Flash#paused 14256 * @return {boolean} 14257 * The value of `paused` from the swf. 14258 */ 14259 14260/** 14261 * Get the value of `ended` from the swf. `ended` indicates whether 14262 * the media has reached the end or not. 14263 * 14264 * @method Flash#ended 14265 * @return {boolean} 14266 * - True indicates that the media has ended. 14267 * - False indicates that the media has not ended. 14268 * 14269 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended} 14270 */ 14271 14272/** 14273 * Get the value of `videoWidth` from the swf. `videoWidth` indicates 14274 * the current width of the media in css pixels. 14275 * 14276 * @method Flash#videoWidth 14277 * @return {number} 14278 * The value of `videoWidth` from the swf. This will be a number 14279 * in css pixels. 14280 */ 14281 14282/** 14283 * Get the value of `videoHeight` from the swf. `videoHeigth` indicates 14284 * the current height of the media in css pixels. 14285 * 14286 * @method Flassh.prototype.videoHeight 14287 * @return {number} 14288 * The value of `videoHeight` from the swf. This will be a number 14289 * in css pixels. 14290 */ 14291/** ------------------------------ Setters ------------------------------ **/ 14292 14293/** 14294 * Set the value of `rtmpConnection` on the swf. 14295 * 14296 * @method Flash#setRtmpConnection 14297 * @param {string} rtmpConnection 14298 * New value to set the `rtmpConnection` property to. 14299 */ 14300 14301/** 14302 * Set the value of `rtmpStream` on the swf. 14303 * 14304 * @method Flash#setRtmpStream 14305 * @param {string} rtmpStream 14306 * New value to set the `rtmpStream` property to. 14307 */ 14308 14309/** 14310 * Set the value of `preload` on the swf. `preload` indicates 14311 * what should download before the media is interacted with. It can have the following 14312 * values: 14313 * - none: nothing should be downloaded 14314 * - metadata: poster and the first few frames of the media may be downloaded to get 14315 * media dimensions and other metadata 14316 * - auto: allow the media and metadata for the media to be downloaded before 14317 * interaction 14318 * 14319 * @method Flash#setPreload 14320 * @param {string} preload 14321 * The value of `preload` to set on the swf. Should be 'none', 'metadata', 14322 * or 'auto'. 14323 */ 14324 14325/** 14326 * Set the value of `defaultPlaybackRate` on the swf. 14327 * 14328 * @method Flash#setDefaultPlaybackRate 14329 * @param {number} defaultPlaybackRate 14330 * New value to set the `defaultPlaybackRate` property to. 14331 */ 14332 14333/** 14334 * Set the value of `playbackRate` on the swf. `playbackRate` indicates 14335 * the rate at which the media is currently playing back. Examples: 14336 * - if playbackRate is set to 2, media will play twice as fast. 14337 * - if playbackRate is set to 0.5, media will play half as fast. 14338 * 14339 * @method Flash#setPlaybackRate 14340 * @param {number} playbackRate 14341 * New value of `playbackRate` on the swf. A number indicating 14342 * the current playback speed of the media, where 1 is normal speed. 14343 */ 14344 14345/** 14346 * Set the value of `autoplay` on the swf. `autoplay` indicates 14347 * that the media should start to play as soon as the page is ready. 14348 * 14349 * @method Flash#setAutoplay 14350 * @param {boolean} autoplay 14351 * - The value of `autoplay` from the swf. 14352 * - True indicates that the media ashould start as soon as the page loads. 14353 * - False indicates that the media should not start as soon as the page loads. 14354 */ 14355 14356/** 14357 * Set the value of `loop` on the swf. `loop` indicates 14358 * that the media should return to the start of the media and continue playing once 14359 * it reaches the end. 14360 * 14361 * @method Flash#setLoop 14362 * @param {boolean} loop 14363 * - True indicates that playback should seek back to start once 14364 * the end of a media is reached. 14365 * - False indicates that playback should not loop back to the start when the 14366 * end of the media is reached. 14367 */ 14368 14369/** 14370 * Set the value of `mediaGroup` on the swf. 14371 * 14372 * @method Flash#setMediaGroup 14373 * @param {string} mediaGroup 14374 * New value of `mediaGroup` to set on the swf. 14375 */ 14376 14377/** 14378 * Set the value of `controller` on the swf. 14379 * 14380 * @method Flash#setController 14381 * @param {string} controller 14382 * New value the current value of `controller` on the swf. 14383 */ 14384 14385/** 14386 * Get the value of `controls` from the swf. `controls` indicates 14387 * whether the native flash controls should be shown or hidden. 14388 * 14389 * @method Flash#controls 14390 * @return {boolean} 14391 * - The value of `controls` from the swf. 14392 * - True indicates that native controls should be showing. 14393 * - False indicates that native controls should be hidden. 14394 */ 14395 14396/** 14397 * Set the value of the `volume` on the swf. `volume` indicates the current 14398 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and 14399 * so on. 14400 * 14401 * @method Flash#setVolume 14402 * @param {number} percentAsDecimal 14403 * The volume percent as a decimal. Value will be between 0-1. 14404 */ 14405 14406/** 14407 * Set the value of the `muted` on the swf. `muted` indicates that the current 14408 * audio level should be silent. 14409 * 14410 * @method Flash#setMuted 14411 * @param {boolean} muted 14412 * - True if the audio should be set to silent 14413 * - False otherwise 14414 */ 14415 14416/** 14417 * Set the value of `defaultMuted` on the swf. `defaultMuted` indicates 14418 * whether the media should start muted or not. Only changes the default state of the 14419 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the 14420 * current state. 14421 * 14422 * @method Flash#setDefaultMuted 14423 * @param {boolean} defaultMuted 14424 * - True indicates that the media should start muted. 14425 * - False indicates that the media should not start muted. 14426 */ 14427 14428/* Flash Support Testing -------------------------------------------------------- */ 14429 14430/** 14431 * Check if the Flash tech is currently supported. 14432 * 14433 * @return {boolean} 14434 * - True
vendor: 5,749 bytes, lines 14434-14668
14434if the flash tech is supported. 14435 * - False otherwise. 14436 */ 14437Flash.isSupported = function () { 14438 return Flash.version()[0] >= 10; 14439 // return swfobject.hasFlashPlayerVersion('10'); 14440}; 14441 14442// Add Source Handler pattern functions to this tech 14443_tech2['default'].withSourceHandlers(Flash); 14444 14445/* 14446 * Native source handler for flash, simply passes the source to the swf element. 14447 * 14448 * @property {Tech~SourceObject} source 14449 * The source object 14450 * 14451 * @property {Flash} tech 14452 * The instance of the Flash tech 14453 */ 14454Flash.nativeSourceHandler = {}; 14455 14456/** 14457 * Check if the Flash can play the given mime type. 14458 * 14459 * @param {string} type 14460 * The mimetype to check 14461 * 14462 * @return {string} 14463 * 'maybe', or '' (empty string) 14464 */ 14465Flash.nativeSourceHandler.canPlayType = function (type) { 14466 if (type in Flash.formats) { 14467 return 'maybe'; 14468 } 14469 14470 return ''; 14471}; 14472 14473/** 14474 * Check if the media element can handle a source natively. 14475 * 14476 * @param {Tech~SourceObject} source 14477 * The source object 14478 * 14479 * @param {Object} [options] 14480 * Options to be passed to the tech. 14481 * 14482 * @return {string} 14483 * 'maybe', or '' (empty string). 14484 */ 14485Flash.nativeSourceHandler.canHandleSource = function (source, options) { 14486 var type = void 0; 14487 14488 function guessMimeType(src) { 14489 var ext = Url.getFileExtension(src); 14490 14491 if (ext) { 14492 return 'video/' + ext; 14493 } 14494 return ''; 14495 } 14496 14497 if (!source.type) { 14498 type = guessMimeType(source.src); 14499 } else { 14500 // Strip code information from the type because we don't get that specific 14501 type = source.type.replace(/;.*/, '').toLowerCase(); 14502 } 14503 14504 return Flash.nativeSourceHandler.canPlayType(type); 14505}; 14506 14507/** 14508 * Pass the source to the swf. 14509 * 14510 * @param {Tech~SourceObject} source 14511 * The source object 14512 * 14513 * @param {Flash} tech 14514 * The instance of the Flash tech 14515 * 14516 * @param {Object} [options] 14517 * The options to pass to the source 14518 */ 14519Flash.nativeSourceHandler.handleSource = function (source, tech, options) { 14520 tech.setSrc(source.src); 14521}; 14522 14523/** 14524 * noop for native source handler dispose, as cleanup will happen automatically. 14525 */ 14526Flash.nativeSourceHandler.dispose = function () {}; 14527 14528// Register the native source handler 14529Flash.registerSourceHandler(Flash.nativeSourceHandler); 14530 14531/** 14532 * Flash supported mime types. 14533 * 14534 * @constant {Object} 14535 */ 14536Flash.formats = { 14537 'video/flv': 'FLV', 14538 'video/x-flv': 'FLV', 14539 'video/mp4': 'MP4', 14540 'video/m4v': 'MP4' 14541}; 14542 14543/** 14544 * Called when the the swf is "ready", and makes sure that the swf is really 14545 * ready using {@link Flash#checkReady} 14546 */ 14547Flash.onReady = function (currSwf) { 14548 var el = Dom.getEl(currSwf); 14549 var tech = el && el.tech; 14550 14551 // if there is no el then the tech has been disposed 14552 // and the tech element was removed from the player div 14553 if (tech && tech.el()) { 14554 // check that the flash object is really ready 14555 Flash.checkReady(tech); 14556 } 14557}; 14558 14559/** 14560 * The SWF isn't always ready when it says it is. Sometimes the API functions still 14561 * need to be added to the object. If it's not ready, we set a timeout to check again 14562 * shortly. 14563 * 14564 * @param {Flash} tech 14565 * The instance of the flash tech to check. 14566 */ 14567Flash.checkReady = function (tech) { 14568 // stop worrying if the tech has been disposed 14569 if (!tech.el()) { 14570 return; 14571 } 14572 14573 // check if API property exists 14574 if (tech.el().vjs_getProperty) { 14575 // tell tech it's ready 14576 tech.triggerReady(); 14577 } else { 14578 // wait longer 14579 this.setTimeout(function () { 14580 Flash.checkReady(tech); 14581 }, 50); 14582 } 14583}; 14584 14585/** 14586 * Trigger events from the swf on the Flash Tech. 14587 * 14588 * @param {number} swfID 14589 * The id of the swf that had the event 14590 * 14591 * @param {string} eventName 14592 * The name of the event to trigger 14593 */ 14594Flash.onEvent = function (swfID, eventName) { 14595 var tech = Dom.getEl(swfID).tech; 14596 var args = Array.prototype.slice.call(arguments, 2); 14597 14598 // dispatch Flash events asynchronously for two reasons: 14599 // - Flash swallows any exceptions generated by javascript it 14600 // invokes 14601 // - Flash is suspended until the javascript returns which may cause 14602 // playback performance issues 14603 tech.setTimeout(function () { 14604 tech.trigger(eventName, args); 14605 }, 1); 14606}; 14607 14608/** 14609 * Log errors from the swf on the Flash tech. 14610 * 14611 * @param {number} swfID 14612 * The id of the swf that had an error. 14613 * 14614 * @param {string} The error string 14615 * The error to set on the Flash Tech. 14616 * 14617 * @return {MediaError|undefined} 14618 * - Returns a MediaError when err is 'srcnotfound' 14619 * - Returns undefined otherwise. 14620 */ 14621Flash.onError = function (swfID, err) { 14622 var tech = Dom.getEl(swfID).tech; 14623 14624 // trigger MEDIA_ERR_SRC_NOT_SUPPORTED 14625 if (err === 'srcnotfound') { 14626 return tech.error(4); 14627 } 14628 14629 // trigger a custom error 14630 tech.error('FLASH: ' + err); 14631}; 14632 14633/** 14634 * Get the current version of Flash that is in use on the page. 14635 * 14636 * @return {Array} 14637 * an array of versions that are available. 14638 */ 14639Flash.version = function () { 14640 var version = '0,0,0'; 14641 14642 // IE 14643 try { 14644 version = new _window2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; 14645 14646 // other browsers 14647 } catch (e) { 14648 try { 14649 if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) { 14650 version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; 14651 } 14652 } catch (err) { 14653 // satisfy linter 14654 } 14655 } 14656 return version.split(','); 14657}; 14658 14659/** 14660 * Only use for non-iframe embeds. 14661 * 14662 * @param {Object} swf 14663 * The videojs-swf object. 14664 * 14665 * @param {Object} flashVars 14666 * Names and values to use as flash option variables. 14667 * 14668 * @param {Object} params
14669 * Style parameters to set on the object. 14670 * 14671 * @param {Object} attributes 14672 * Attributes to set on the element. 14673 * 14674 * @return {Element} 14675 * The embeded Flash DOM element. 14676 */ 14677Flash.embed = function (swf, flashVars, params, attributes) { 14678 var code = Flash.getEmbedCode(swf, flashVars, params, attributes); 14679 14680 // Get element by embedding code and retrieving created element 14681 var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0]; 14682 14683 return obj; 14684}; 14685 14686/** 14687 * Only use for non-iframe embeds. 14688 * 14689 * @param {Object} swf 14690 * The videojs-swf object. 14691 * 14692 * @param {Object} flashVars 14693 * Names and values to use as flash option variables. 14694 * 14695 * @param {Object} params 14696 * Style parameters to set on the object. 14697 * 14698 * @param {Object} attributes 14699 * Attributes to set on the element. 14700 * 14701 * @return {Element} 14702 * The embeded Flash DOM element. 14703 */ 14704Flash.getEmbedCode = function (swf, flashVars, params, attributes) { 14705 var objTag = '<object type="application/x-shockwave-flash" '; 14706 var flashVarsString = ''; 14707 var paramsString = ''; 14708 var attrsString = ''; 14709 14710 // Convert flash vars to string 14711 if (flashVars) { 14712 Object.getOwnPropertyNames(flashVars).forEach(function (key) { 14713 flashVarsString += key + '=' + flashVars[key] + '&'; 14714 }); 14715 } 14716 14717 // Add swf, flashVars, and other default params 14718 params = (0, _obj.assign)({ 14719 movie: swf, 14720 flashvars: flashVarsString, 14721 // Required to talk to swf 14722 allowScriptAccess: 'always', 14723 // All should be default, but having security issues. 14724 allowNetworking: 'all' 14725 }, params); 14726 14727 // Create param tags string 14728 Object.getOwnPropertyNames(params).forEach(function (key) { 14729 paramsString += '<param name="' + key + '" value="' + params[key] + '" />'; 14730 }); 14731 14732 attributes = (0, _obj.assign)({ 14733 // Add swf to attributes (need both for IE and Others to work) 14734 data: swf, 14735 14736 // Default to 100% width/height 14737 width: '100%', 14738 height: '100%' 14739 14740 }, attributes); 14741 14742 // Create Attributes string 14743 Object.getOwnPropertyNames(attributes).forEach(function (key) { 14744 attrsString += key + '="' + attributes[key] + '" '; 14745 }); 14746 14747 return '' + objTag + attrsString + '>' + paramsString + '</object>'; 14748}; 14749 14750// Run Flash through the RTMP decorator 14751(0, _flashRtmp2['default'])(Flash); 14752 14753_component2['default'].registerComponent('Flash', Flash); 14754_tech2['default'].registerTech('Flash', Flash); 14755exports['default'] = Flash; 14756 14757},{"5":5,"58":58,"62":62,"81":81,"88":88,"90":90,"92":92,"95":95}],60:[function(_dereq_,module,exports){ 14758'use strict'; 14759 14760exports.__esModule = true; 14761 14762var _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; }; 14763 14764var _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.']); 14765 14766var _tech = _dereq_(62); 14767 14768var _tech2 = _interopRequireDefault(_tech); 14769 14770var _component = _dereq_(5); 14771 14772var _component2 = _interopRequireDefault(_component); 14773 14774var _dom = _dereq_(81); 14775 14776var Dom = _interopRequireWildcard(_dom); 14777 14778var _url = _dereq_(92); 14779 14780var Url = _interopRequireWildcard(_url); 14781 14782var _fn = _dereq_(83); 14783 14784var Fn = _interopRequireWildcard(_fn); 14785 14786var _log = _dereq_(86); 14787 14788var _log2 = _interopRequireDefault(_log); 14789 14790var _tsml = _dereq_(98); 14791 14792var _tsml2 = _interopRequireDefault(_tsml); 14793 14794var _browser = _dereq_(78); 14795 14796var browser = _interopRequireWildcard(_browser); 14797 14798var _document = _dereq_(94); 14799 14800var _document2 = _interopRequireDefault(_document); 14801 14802var _window = _dereq_(95); 14803 14804var _window2 = _interopRequireDefault(_window); 14805 14806var _obj = _dereq_(88); 14807 14808var _mergeOptions = _dereq_(87); 14809 14810var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 14811 14812var _toTitleCase = _dereq_(91); 14813 14814var _toTitleCase2 = _interopRequireDefault(_toTitleCase); 14815 14816function _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; } } 14817 14818function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 14819 14820function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } 14821 14822function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 14823 14824function _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; } 14825 14826function _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: 2,264 bytes, lines 14826-14861
14826onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 14827 * @file html5.js 14828 */ 14829 14830 14831/** 14832 * HTML5 Media Controller - Wrapper for HTML5 Media API 14833 * 14834 * @mixes Tech~SouceHandlerAdditions 14835 * @extends Tech 14836 */ 14837var Html5 = function (_Tech) { 14838 _inherits(Html5, _Tech); 14839 14840 /** 14841 * Create an instance of this Tech. 14842 * 14843 * @param {Object} [options] 14844 * The key/value store of player options. 14845 * 14846 * @param {Component~ReadyCallback} ready 14847 * Callback function to call when the `HTML5` Tech is ready. 14848 */ 14849 function Html5(options, ready) { 14850 _classCallCheck(this, Html5); 14851 14852 var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready)); 14853 14854 var source = options.source; 14855 var crossoriginTracks = false; 14856 14857 // Set the source if one is provided 14858 // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted) 14859 // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source 14860 // anyway so the error gets fired. 14861 if (source && (_this.el_.currentSrc !== source.src || options.tag && options.tag.
14861initNetworkState_ === 3)) { 14862 _this.setSource(source); 14863 } else { 14864 _this.handleLateInit_(_this.el_); 14865 } 14866 14867 if (_this.el_.hasChildNodes()) { 14868 14869 var nodes = _this.el_.childNodes; 14870 var nodesLength = nodes.length; 14871 var removeNodes = []; 14872 14873 while (nodesLength--) { 14874 var node = nodes[nodesLength]; 14875 var nodeName = node.nodeName.toLowerCase(); 14876 14877 if (nodeName === 'track') { 14878 if (!_this.featuresNativeTextTracks) { 14879 // Empty video tag tracks so the built-in player doesn't use them also. 14880 // This may not be fast enough to stop HTML5 browsers from reading the tags 14881 // so we'll need to turn off any default tracks if we're manually doing 14882 // captions and subtitles. videoElement.textTracks 14883 removeNodes.push(node); 14884 } else { 14885 // store HTMLTrackElement and TextTrack to remote list 14886 _this.remoteTextTrackEls().addTrackElement_(node); 14887 _this.remoteTextTracks().addTrack_(node.track); 14888 if (!crossoriginTracks && !_this.el_.hasAttribute('crossorigin') && Url.isCrossOrigin(node.src)) { 14889 crossoriginTracks = true; 14890 } 14891 } 14892 } 14893 } 14894 14895 for (var i = 0; i < removeNodes.length; i++) { 14896 _this.el_.removeChild(removeNodes[i]); 14897 } 14898 } 14899 14900 // TODO: add text tracks into this list 14901 var trackTypes = ['audio', 'video']; 14902 14903 // ProxyNative Video/Audio Track 14904 trackTypes.forEach(function (type) { 14905 var elTracks = _this.el()[type + 'Tracks']; 14906 var techTracks = _this[type + 'Tracks'](); 14907 var capitalType = (0, _toTitleCase2['default'])(type); 14908 14909 if (!_this['featuresNative' + capitalType + 'Tracks'] || !elTracks || !elTracks.addEventListener) { 14910 return; 14911 } 14912 14913 _this['handle' + capitalType + 'TrackChange_'] = function (e) { 14914 techTracks.trigger({ 14915 type: 'change', 14916 target: techTracks, 14917 currentTarget: techTracks, 14918 srcElement: techTracks 14919 }); 14920 }; 14921 14922 _this['handle' + capitalType + 'TrackAdd_'] = function (e) { 14923 return techTracks.addTrack(e.track); 14924 }; 14925 _this['handle' + capitalType + 'TrackRemove_'] = function (e) { 14926 return techTracks.removeTrack(e.track); 14927 }; 14928 14929 elTracks.addEventListener('change', _this['handle' + capitalType + 'TrackChange_']); 14930 elTracks.addEventListener('addtrack', _this['handle' + capitalType + 'TrackAdd_']); 14931 elTracks.addEventListener('removetrack', _this['handle' + capitalType + 'TrackRemove_']); 14932 _this['removeOld' + capitalType + 'Tracks_'] = function (e) { 14933 return _this.removeOldTracks_(techTracks, elTracks); 14934 }; 14935 14936 // Remove (native) tracks that are not used anymore 14937 _this.on('loadstart', _this['removeOld' + capitalType + 'Tracks_']); 14938 }); 14939 14940 if (_this.featuresNativeTextTracks) { 14941 if (crossoriginTracks) { 14942 _log2['default'].warn((0, _tsml2['default'])(_templateObject)); 14943 } 14944 14945 _this.handleTextTrackChange_ = Fn.bind(_this, _this.handleTextTrackChange); 14946 _this.handleTextTrackAdd_ = Fn.bind(_this, _this.handleTextTrackAdd); 14947 _this.handleTextTrackRemove_ = Fn.bind(_this, _this.handleTextTrackRemove); 14948 _this.proxyNativeTextTracks_(); 14949 } 14950 14951 // Determine if native controls should be used 14952 // Our goal should be to get the custom controls on mobile solid everywhere 14953 // so we can remove this all together. Right now this will block custom 14954 // controls on touch enabled laptops like the Chrome Pixel 14955 if ((browser.TOUCH_ENABLED || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) && options.nativeControlsForTouch === true) { 14956 _this.setControls(true); 14957 } 14958 14959 // on iOS, we want to proxy `webkitbeginfullscreen` and `webkitendfullscreen` 14960 // into a `fullscreenchange` event 14961 _this.proxyWebkitFullscreen_(); 14962 14963 _this.triggerReady(); 14964 return _this; 14965 } 14966 14967 /** 14968 * Dispose of `HTML5` media element and remove all tracks. 14969 */ 14970 14971 14972 Html5.prototype.dispose = function dispose() { 14973 var _this2 = this; 14974 14975 // Un-ProxyNativeTracks 14976 ['audio', 'video', 'text'].forEach(function (type) { 14977 var capitalType = (0, _toTitleCase2['default'])(type); 14978 var tl = _this2.el_[type + 'Tracks']; 14979 14980 if (tl && tl.removeEventListener) { 14981 tl.removeEventListener('change', _this2['handle' + capitalType + 'TrackChange_']); 14982 tl.removeEventListener('addtrack', _this2['handle' + capitalType + 'TrackAdd_']); 14983 tl.removeEventListener('removetrack', _this2['handle' + capitalType + 'TrackRemove_']); 14984 } 14985 14986 // Stop removing old text tracks 14987 if (tl) { 14988 _this2.off('loadstart', _this2['removeOld' + capitalType + 'Tracks_']); 14989 } 14990 }); 14991 14992 Html5.disposeMediaElement(this.el_); 14993 // tech will handle clearing of the emulated track list 14994 _Tech.prototype.dispose.call(this); 14995 }; 14996 14997 /** 14998 * Create the `Html5` Tech's DOM element. 14999 * 15000 * @return {Element} 15001 * The element that gets created. 15002 */ 15003 15004 15005 Html5.prototype.createEl = function createEl() { 15006 var el = this.options_.tag; 15007 15008 // Check if this browser supports moving the element into the box. 15009 // On the iPhone video will break if you move the element, 15010 // So we have to create a brand new element. 15011 // If we ingested the player div, we do not need to move the media element. 15012 if (!el || !(this.options_.playerElIngest || this.movingMediaElementInDOM)) { 15013 15014 // If the original tag is still there, clone and remove it. 15015 if (el) { 15016 var clone = el.cloneNode(true); 15017 15018 if (el.parentNode) { 15019 el.parentNode.insertBefore(clone, el); 15020 } 15021 Html5.disposeMediaElement(el); 15022 el = clone; 15023 } else { 15024 el = _document2['default'].createElement('video'); 15025 15026 // determine if native controls should be used 15027 var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag); 15028 var attributes = (0, _mergeOptions2['default'])({}, tagAttributes); 15029 15030 if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) { 15031 delete attributes.controls; 15032 } 15033 15034 Dom.setElAttributes(el, (0, _obj.assign)(attributes, { 15035 id: this.options_.techId, 15036 'class': 'vjs-tech' 15037 })); 15038 } 15039 15040 el.playerId = this.options_.playerId; 15041 } 15042 15043 // Update specific tag settings, in case they were overridden 15044 var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted']; 15045 15046 for (var i = settingsAttrs.length - 1; i >= 0; i--) { 15047 var attr = settingsAttrs[i]; 15048 var overwriteAttrs = {}; 15049 15050 if (typeof this.options_[attr] !== 'undefined') { 15051 overwriteAttrs[attr] = this.options_[attr]; 15052 } 15053 Dom.setElAttributes(el, overwriteAttrs); 15054 } 15055 15056 return el; 15057 }; 15058 15059 /** 15060 * This will be triggered if the loadstart event has already fired, before videojs was 15061 * ready. Two known examples of when this can happen are: 15062 * 1. If we're loading the playback object after it has started loading 15063 * 2. The media is already playing the (often with autoplay on) then 15064 * 15065 * This function will fire another loadstart so that videojs can catchup. 15066 * 15067 * @fires Tech#loadstart 15068 * 15069 * @return {undefined} 15070 * returns nothing. 15071 */ 15072 15073 15074 Html5.prototype.handleLateInit_ = function handleLateInit_(el) { 15075 var _this3 = this; 15076 15077 if (el.networkState === 0 || el.networkState === 3) { 15078 // The video element hasn't started loading the source yet 15079 // or didn't find a source 15080 return; 15081 } 15082 15083 if (el.readyState === 0) { 15084 var _ret = function () { 15085 // NetworkState is set synchronously BUT loadstart is fired at the 15086 // end of the current stack, usually before setInterval(fn, 0). 15087 // So at this point we know loadstart may have already fired or is 15088 // about to fire, and either way the player hasn't seen it yet. 15089 // We don't want to fire loadstart prematurely here and cause a 15090 // double loadstart so we'll wait and see if it happens between now 15091 // and the next loop, and fire it if not. 15092 // HOWEVER, we also want to make sure it fires before loadedmetadata 15093 // which could also happen between now and the next loop, so we'll 15094 // watch for that also. 15095 var loadstartFired = false;
15096 var setLoadstartFired = function setLoadstartFired() { 15097 loadstartFired = true; 15098 }; 15099 15100 _this3.on('loadstart', setLoadstartFired); 15101 15102 var triggerLoadstart = function triggerLoadstart() { 15103 // We did miss the original loadstart. Make sure the player 15104 // sees loadstart before loadedmetadata 15105 if (!loadstartFired) { 15106 this.trigger('loadstart'); 15107 } 15108 }; 15109 15110 _this3.on('loadedmetadata', triggerLoadstart); 15111 15112 _this3.ready(function () { 15113 this.off('loadstart', setLoadstartFired); 15114 this.off('loadedmetadata', triggerLoadstart); 15115 15116 if (!loadstartFired) { 15117 // We did miss the original native loadstart. Fire it now. 15118 this.trigger('loadstart'); 15119 } 15120 }); 15121 15122 return { 15123 v: void 0 15124 }; 15125 }(); 15126 15127 if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; 15128 } 15129 15130 // From here on we know that loadstart already fired and we missed it. 15131 // The other readyState events aren't as much of a problem if we double 15132 // them, so not going to go to as much trouble as loadstart to prevent 15133 // that unless we find reason to. 15134 var eventsToTrigger = ['loadstart']; 15135 15136 // loadedmetadata: newly equal to HAVE_METADATA (1) or greater 15137 eventsToTrigger.push('loadedmetadata'); 15138 15139 // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater 15140 if (el.readyState >= 2) { 15141 eventsToTrigger.push('loadeddata'); 15142 } 15143 15144 // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater 15145 if (el.readyState >= 3) { 15146 eventsToTrigger.push('canplay'); 15147 } 15148 15149 // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4) 15150 if (el.readyState >= 4) { 15151 eventsToTrigger.push('canplaythrough'); 15152 } 15153 15154 // We still need to give the player time to add event listeners 15155 this.ready(function () { 15156 eventsToTrigger.forEach(function (type) { 15157 this.trigger(type); 15158 }, this); 15159 }); 15160 }; 15161 15162 /** 15163 * Add event listeners to native text track events. This adds the native text tracks 15164 * to our emulated {@link TextTrackList}. 15165 */ 15166 15167 15168 Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() { 15169 var tt = this.el().textTracks; 15170 15171 if (tt) { 15172 // Add tracks - if player is initialised after DOM loaded, textTracks 15173 // will not trigger addtrack 15174 for (var i = 0; i < tt.length; i++) { 15175 this.textTracks().addTrack_(tt[i]); 15176 } 15177 15178 if (tt.addEventListener) { 15179 tt.addEventListener('change', this.handleTextTrackChange_); 15180 tt.addEventListener('addtrack', this.handleTextTrackAdd_); 15181 tt.addEventListener('removetrack', this.handleTextTrackRemove_); 15182 } 15183 15184 // Remove (native) texttracks that are not used anymore 15185 this.on('loadstart', this.removeOldTextTracks_); 15186 } 15187 }; 15188 15189 /** 15190 * Handle any {@link TextTrackList} `change` event. 15191 * 15192 * @param {EventTarget~Event} e 15193 * The `change` event that caused this to run. 15194 * 15195 * @listens TextTrackList#change 15196 */ 15197 15198 15199 Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) { 15200 var tt = this.textTracks(); 15201 15202 this.textTracks().trigger({ 15203 type: 'change', 15204 target: tt, 15205 currentTarget: tt, 15206 srcElement: tt 15207 }); 15208 }; 15209 15210 /** 15211 * Handle any {@link TextTrackList} `addtrack` event. 15212 * 15213 * @param {EventTarget~Event} e 15214 * The `addtrack` event that caused this to run. 15215 * 15216 * @listens TextTrackList#addtrack 15217 */ 15218 15219 15220 Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) { 15221 this.textTracks().addTrack_(e.track); 15222 }; 15223 15224 /** 15225 * Handle any {@link TextTrackList} `removetrack` event. 15226 * 15227 * @param {EventTarget~Event} e 15228 * The `removetrack` event that caused this to run. 15229 * 15230 * @listens TextTrackList#removetrack 15231 */ 15232 15233 15234 Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) { 15235 this.textTracks().removeTrack_(e.track); 15236 }; 15237 15238 /** 15239 * This function removes any {@link AudioTrack}s, {@link VideoTrack}s, or 15240 * {@link TextTrack}s that are not in the media elements TrackList. 15241 * 15242 * @param {TrackList} techTracks 15243 * HTML5 Tech's TrackList to search through 15244 * 15245 * @param {TrackList} elTracks 15246 * HTML5 media elements TrackList to search trough. 15247 * 15248 * @private 15249 */ 15250 15251 15252 Html5.prototype.removeOldTracks_ = function removeOldTracks_(techTracks, elTracks) { 15253 // This will loop over the techTracks and check if they are still used by the HTML5 media element 15254 // If not, they will be removed from the emulated list 15255 var removeTracks = []; 15256 15257 if (!elTracks) { 15258 return; 15259 } 15260 15261 for (var i = 0; i < techTracks.length; i++) { 15262 var techTrack = techTracks[i]; 15263 var found = false;
15264 15265 for (var j = 0; j < elTracks.length; j++) { 15266 if (elTracks[j] === techTrack) { 15267 found = true; 15268 break; 15269 } 15270 } 15271 15272 if (!found) { 15273 removeTracks.push(techTrack); 15274 } 15275 } 15276 15277 for (var _i = 0; _i < removeTracks.length; _i++) { 15278 var track = removeTracks[_i]; 15279 15280 techTracks.removeTrack_(track); 15281 } 15282 }; 15283 15284 /** 15285 * Remove {@link TextTrack}s that dont exist in the native track list from our 15286 * emulated {@link TextTrackList}. 15287 * 15288 * @listens Tech#loadstart 15289 */ 15290 15291 15292 Html5.prototype.removeOldTextTracks_ = function removeOldTextTracks_(e) { 15293 var techTracks = this.textTracks(); 15294 var elTracks = this.el().textTracks; 15295 15296 this.removeOldTracks_(techTracks, elTracks); 15297 }; 15298 15299 /** 15300 * Called by {@link Player#play} to play using the `Html5` `Tech`. 15301 */ 15302 15303 15304 Html5.prototype.play = function play() { 15305 var playPromise = this.el_.play(); 15306 15307 // Catch/silence error when a pause interrupts a play request 15308 // on browsers which return a promise 15309 if (playPromise !== undefined && typeof playPromise.then === 'function') { 15310 playPromise.then(null, function (e) {}); 15311 } 15312 }; 15313 15314 /** 15315 * Set current time for the `HTML5` tech. 15316 * 15317 * @param {number} seconds 15318 * Set the current time of the media to this. 15319 */ 15320 15321 15322 Html5.prototype.setCurrentTime = function setCurrentTime(seconds) { 15323 try { 15324 this.el_.currentTime = seconds; 15325 } catch (e) { 15326 (0, _log2['default'])(e, 'Video is not ready. (Video.js)'); 15327 // this.warning(VideoJS.warnings.videoNotReady); 15328 } 15329 }; 15330 15331 /** 15332 * Get the current duration of the HTML5 media element. 15333 * 15334 * @return {number} 15335 * The duration of the media or 0 if there is no duration. 15336 */ 15337 15338 15339 Html5.prototype.duration = function duration() { 15340 var _this4 = this; 15341 15342 // Android Chrome will report duration as Infinity for VOD HLS until after 15343 // playback has started, which triggers the live display erroneously. 15344 // Return NaN if playback has not started and trigger a durationupdate once 15345 // the duration can be reliably known. 15346 if (this.el_.duration === Infinity && browser.IS_ANDROID && browser.IS_CHROME) { 15347 if (this.el_.currentTime === 0) { 15348 var _ret2 = function () { 15349 // Wait for the first `timeupdate` with currentTime > 0 - there may be 15350 // several with 0 15351 var checkProgress = function checkProgress() { 15352 if (_this4.el_.currentTime > 0) { 15353 // Trigger durationchange for genuinely live video 15354 if (_this4.el_.duration === Infinity) { 15355 _this4.trigger('durationchange'); 15356 } 15357 _this4.off('timeupdate', checkProgress); 15358 } 15359 }; 15360 15361 _this4.on('timeupdate', checkProgress); 15362 return { 15363 v: NaN 15364 }; 15365 }(); 15366 15367 if ((typeof _ret2 === 'undefined' ? 'undefined' : _typeof(_ret2)) === "object") return _ret2.v; 15368 } 15369 } 15370 return this.el_.duration || NaN; 15371 }; 15372 15373 /** 15374 * Get the current width of the HTML5 media element. 15375 * 15376 * @return {number} 15377 * The width of the HTML5 media element. 15378 */ 15379 15380 15381 Html5.prototype.width = function width() { 15382 return this.el_.offsetWidth; 15383 }; 15384 15385 /** 15386 * Get the current height of the HTML5 media element. 15387 * 15388 * @return {number} 15389 * The heigth of the HTML5 media element. 15390 */ 15391 15392 15393 Html5.prototype.height = function height() { 15394 return this.el_.offsetHeight; 15395 }; 15396 15397 /** 15398 * Proxy iOS `webkitbeginfullscreen` and `webkitendfullscreen` into 15399 * `fullscreenchange` event. 15400 * 15401 * @private 15402 * @fires fullscreenchange 15403 * @listens webkitendfullscreen 15404 * @listens webkitbeginfullscreen 15405 * @listens webkitbeginfullscreen 15406 */ 15407 15408 15409 Html5.prototype.proxyWebkitFullscreen_ = function proxyWebkitFullscreen_() { 15410 var _this5 = this; 15411 15412 if (!('webkitDisplayingFullscreen' in this.el_)) { 15413 return; 15414 } 15415 15416 var endFn = function endFn() { 15417 this.trigger('fullscreenchange', { isFullscreen: false }); 15418 }; 15419 15420 var beginFn = function beginFn() { 15421 this.one('webkitendfullscreen', endFn); 15422 15423 this.trigger('fullscreenchange', { isFullscreen: true }); 15424 }; 15425 15426 this.on('webkitbeginfullscreen', beginFn); 15427 this.on('dispose', function () { 15428 _this5.off('webkitbeginfullscreen', beginFn); 15429 _this5.off('webkitendfullscreen', endFn); 15430 }); 15431 }; 15432 15433 /** 15434 * Check if fullscreen is supported on the current playback device. 15435 * 15436 * @return {boolean} 15437 * - True if fullscreen is supported. 15438 * - False if fullscreen is not supported. 15439 */ 15440 15441 15442 Html5.prototype.supportsFullScreen = function supportsFullScreen() { 15443 if (typeof this.el_.webkitEnterFullScreen === 'function') { 15444 var userAgent = _window2['default'].navigator && _window2['default'].navigator.userAgent || ''; 15445 15446 // Seems to be broken in Chromium/Chrome && Safari in Leopard 15447 if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) { 15448 return true; 15449 } 15450 } 15451 return false;
vendor: 22,527 bytes, lines 15452-16202
15452 }; 15453 15454 /** 15455 * Request that the `HTML5` Tech enter fullscreen. 15456 */ 15457 15458 15459 Html5.prototype.enterFullScreen = function enterFullScreen() { 15460 var video = this.el_; 15461 15462 if (video.paused && video.networkState <= video.HAVE_METADATA) { 15463 // attempt to prime the video element for programmatic access 15464 // this isn't necessary on the desktop but shouldn't hurt 15465 this.el_.play(); 15466 15467 // playing and pausing synchronously during the transition to fullscreen 15468 // can get iOS ~6.1 devices into a play/pause loop 15469 this.setTimeout(function () { 15470 video.pause(); 15471 video.webkitEnterFullScreen(); 15472 }, 0); 15473 } else { 15474 video.webkitEnterFullScreen(); 15475 } 15476 }; 15477 15478 /** 15479 * Request that the `HTML5` Tech exit fullscreen. 15480 */ 15481 15482 15483 Html5.prototype.exitFullScreen = function exitFullScreen() { 15484 this.el_.webkitExitFullScreen(); 15485 }; 15486 15487 /** 15488 * A getter/setter for the `Html5` Tech's source object. 15489 * > Note: Please use {@link Html5#setSource} 15490 * 15491 * @param {Tech~SourceObject} [src] 15492 * The source object you want to set on the `HTML5` techs element. 15493 * 15494 * @return {Tech~SourceObject|undefined} 15495 * - The current source object when a source is not passed in. 15496 * - undefined when setting 15497 * 15498 * @deprecated Since version 5. 15499 */ 15500 15501 15502 Html5.prototype.src = function src(_src) { 15503 if (_src === undefined) { 15504 return this.el_.src; 15505 } 15506 15507 // Setting src through `src` instead of `setSrc` will be deprecated 15508 this.setSrc(_src); 15509 }; 15510 15511 /** 15512 * Reset the tech by removing all sources and then calling 15513 * {@link Html5.resetMediaElement}. 15514 */ 15515 15516 15517 Html5.prototype.reset = function reset() { 15518 Html5.resetMediaElement(this.el_); 15519 }; 15520 15521 /** 15522 * Get the current source on the `HTML5` Tech. Falls back to returning the source from 15523 * the HTML5 media element. 15524 * 15525 * @return {Tech~SourceObject} 15526 * The current source object from the HTML5 tech. With a fallback to the 15527 * elements source. 15528 */ 15529 15530 15531 Html5.prototype.currentSrc = function currentSrc() { 15532 if (this.currentSource_) { 15533 return this.currentSource_.src; 15534 } 15535 return this.el_.currentSrc; 15536 }; 15537 15538 /** 15539 * Set controls attribute for the HTML5 media Element. 15540 * 15541 * @param {string} val 15542 * Value to set the controls attribute to 15543 */ 15544 15545 15546 Html5.prototype.setControls = function setControls(val) { 15547 this.el_.controls = !!val; 15548 }; 15549 15550 /** 15551 * Create and returns a remote {@link TextTrack} object. 15552 * 15553 * @param {string} kind 15554 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata) 15555 * 15556 * @param {string} [label] 15557 * Label to identify the text track 15558 * 15559 * @param {string} [language] 15560 * Two letter language abbreviation 15561 * 15562 * @return {TextTrack} 15563 * The TextTrack that gets created. 15564 */ 15565 15566 15567 Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) { 15568 if (!this.featuresNativeTextTracks) { 15569 return _Tech.prototype.addTextTrack.call(this, kind, label, language); 15570 } 15571 15572 return this.el_.addTextTrack(kind, label, language); 15573 }; 15574 15575 /** 15576 * Creates either native TextTrack or an emulated TextTrack depending 15577 * on the value of `featuresNativeTextTracks` 15578 * 15579 * @param {Object} options 15580 * The object should contain the options to intialize the TextTrack with. 15581 * 15582 * @param {string} [options.kind] 15583 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata). 15584 * 15585 * @param {string} [options.label]. 15586 * Label to identify the text track 15587 * 15588 * @param {string} [options.language] 15589 * Two letter language abbreviation. 15590 * 15591 * @param {boolean} [options.default] 15592 * Default this track to on. 15593 * 15594 * @param {string} [options.id] 15595 * The internal id to assign this track. 15596 * 15597 * @param {string} [options.src] 15598 * A source url for the track. 15599 * 15600 * @return {HTMLTrackElement} 15601 * The track element that gets created. 15602 */ 15603 15604 15605 Html5.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) { 15606 if (!this.featuresNativeTextTracks) { 15607 return _Tech.prototype.createRemoteTextTrack.call(this, options); 15608 } 15609 var htmlTrackElement = _document2['default'].createElement('track'); 15610 15611 if (options.kind) { 15612 htmlTrackElement.kind = options.kind; 15613 } 15614 if (options.label) { 15615 htmlTrackElement.label = options.label; 15616 } 15617 if (options.language || options.srclang) { 15618 htmlTrackElement.srclang = options.language || options.srclang; 15619 } 15620 if (options['default']) { 15621 htmlTrackElement['default'] = options['default']; 15622 } 15623 if (options.id) { 15624 htmlTrackElement.id = options.id; 15625 } 15626 if (options.src) { 15627 htmlTrackElement.src = options.src; 15628 } 15629 15630 return htmlTrackElement; 15631 }; 15632 15633 /** 15634 * Creates a remote text track object and returns an html track element. 15635 * 15636 * @param {Object} options The object should contain values for 15637 * kind, language, label, and src (location of the WebVTT file) 15638 * @param {Boolean} [manualCleanup=true] if set to false, the TextTrack will be 15639 * automatically removed from the video element whenever the source changes 15640 * @return {HTMLTrackElement} An Html Track Element. 15641 * This can be an emulated {@link HTMLTrackElement} or a native one. 15642 * @deprecated The default value of the "manualCleanup" parameter will default 15643 * to "false" in upcoming versions of Video.js 15644 */ 15645 15646 15647 Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) { 15648 var htmlTrackElement = _Tech.prototype.addRemoteTextTrack.call(this, options, manualCleanup); 15649 15650 if (this.featuresNativeTextTracks) { 15651 this.el().appendChild(htmlTrackElement); 15652 } 15653 15654 return htmlTrackElement; 15655 }; 15656 15657 /** 15658 * Remove remote `TextTrack` from `TextTrackList` object 15659 * 15660 * @param {TextTrack} track 15661 * `TextTrack` object to remove 15662 */ 15663 15664 15665 Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) { 15666 _Tech.prototype.removeRemoteTextTrack.call(this, track); 15667 15668 if (this.featuresNativeTextTracks) { 15669 var tracks = this.$$('track'); 15670 15671 var i = tracks.length; 15672 15673 while (i--) { 15674 if (track === tracks[i] || track === tracks[i].track) { 15675 this.el().removeChild(tracks[i]); 15676 } 15677 } 15678 } 15679 }; 15680 15681 return Html5; 15682}(_tech2['default']); 15683 15684/* HTML5 Support Testing ---------------------------------------------------- */ 15685 15686if (Dom.isReal()) { 15687 15688 /** 15689 * Element for testing browser HTML5 media capabilities 15690 * 15691 * @type {Element} 15692 * @constant 15693 * @private 15694 */ 15695 Html5.TEST_VID = _document2['default'].createElement('video'); 15696 var track = _document2['default'].createElement('track'); 15697 15698 track.kind = 'captions'; 15699 track.srclang = 'en'; 15700 track.label = 'English'; 15701 Html5.TEST_VID.appendChild(track); 15702} 15703 15704/** 15705 * Check if HTML5 media is supported by this browser/device. 15706 * 15707 * @return {boolean} 15708 * - True if HTML5 media is supported. 15709 * - False if HTML5 media is not supported. 15710 */ 15711Html5.isSupported = function () { 15712 // IE9 with no Media Player is a LIAR! (#984) 15713 try { 15714 Html5.TEST_VID.volume = 0.5; 15715 } catch (e) { 15716 return false; 15717 } 15718 15719 return !!(Html5.TEST_VID && Html5.TEST_VID.canPlayType); 15720}; 15721 15722/** 15723 * Check if the volume can be changed in this browser/device. 15724 * Volume cannot be changed in a lot of mobile devices. 15725 * Specifically, it can't be changed from 1 on iOS. 15726 * 15727 * @return {boolean} 15728 * - True if volume can be controlled 15729 * - False otherwise 15730 */ 15731Html5.canControlVolume = function () { 15732 // IE will error if Windows Media Player not installed #3315 15733 try { 15734 var volume = Html5.TEST_VID.volume; 15735 15736 Html5.TEST_VID.volume = volume / 2 + 0.1; 15737 return volume !== Html5.TEST_VID.volume; 15738 } catch (e) { 15739 return false; 15740 } 15741}; 15742 15743/** 15744 * Check if the playback rate can be changed in this browser/device. 15745 * 15746 * @return {boolean} 15747 * - True if playback rate can be controlled 15748 * - False otherwise 15749 */ 15750Html5.canControlPlaybackRate = function () { 15751 // Playback rate API is implemented in Android Chrome, but doesn't do anything 15752 // https://github.com/videojs/video.js/issues/3180 15753 if (browser.IS_ANDROID && browser.IS_CHROME) { 15754 return false; 15755 } 15756 // IE will error if Windows Media Player not installed #3315 15757 try { 15758 var playbackRate = Html5.TEST_VID.playbackRate; 15759 15760 Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1; 15761 return playbackRate !== Html5.TEST_VID.playbackRate; 15762 } catch (e) { 15763 return false; 15764 } 15765}; 15766 15767/** 15768 * Check to see if native `TextTrack`s are supported by this browser/device. 15769 * 15770 * @return {boolean} 15771 * - True if native `TextTrack`s are supported. 15772 * - False otherwise 15773 */ 15774Html5.supportsNativeTextTracks = function () { 15775 return browser.IS_ANY_SAFARI; 15776}; 15777 15778/** 15779 * Check to see if native `VideoTrack`s are supported by this browser/device 15780 * 15781 * @return {boolean} 15782 * - True if native `VideoTrack`s are supported. 15783 * - False otherwise 15784 */ 15785Html5.supportsNativeVideoTracks = function () { 15786 return !!(Html5.TEST_VID && Html5.TEST_VID.videoTracks); 15787}; 15788 15789/** 15790 * Check to see if native `AudioTrack`s are supported by this browser/device 15791 * 15792 * @return {boolean} 15793 * - True if native `AudioTrack`s are supported. 15794 * - False otherwise 15795 */ 15796Html5.supportsNativeAudioTracks = function () { 15797 return !!(Html5.TEST_VID && Html5.TEST_VID.audioTracks); 15798}; 15799 15800/** 15801 * An array of events available on the Html5 tech. 15802 * 15803 * @private 15804 * @type {Array} 15805 */ 15806Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange']; 15807 15808/** 15809 * Boolean indicating whether the `Tech` supports volume control. 15810 * 15811 * @type {boolean} 15812 * @default {@link Html5.canControlVolume} 15813 */ 15814Html5.prototype.featuresVolumeControl = Html5.canControlVolume(); 15815 15816/** 15817 * Boolean indicating whether the `Tech` supports changing the speed at which the media 15818 * plays. Examples: 15819 * - Set player to play 2x (twice) as fast 15820 * - Set player to play 0.5x (half) as fast 15821 * 15822 * @type {boolean} 15823 * @default {@link Html5.canControlPlaybackRate} 15824 */ 15825Html5.prototype.featuresPlaybackRate = Html5.canControlPlaybackRate(); 15826 15827/** 15828 * Boolean indicating whether the `HTML5` tech currently supports the media element 15829 * moving in the DOM. iOS breaks if you move the media element, so this is set this to 15830 * false there. Everywhere else this should be true. 15831 * 15832 * @type {boolean} 15833 * @default 15834 */ 15835Html5.prototype.movingMediaElementInDOM = !browser.IS_IOS; 15836 15837// TODO: Previous comment: No longer appears to be used. Can probably be removed. 15838// Is this true? 15839/** 15840 * Boolean indicating whether the `HTML5` tech currently supports automatic media resize 15841 * when going into fullscreen. 15842 * 15843 * @type {boolean} 15844 * @default 15845 */ 15846Html5.prototype.featuresFullscreenResize = true; 15847 15848/** 15849 * Boolean indicating whether the `HTML5` tech currently supports the progress event. 15850 * If this is false, manual `progress` events will be triggred instead. 15851 * 15852 * @type {boolean} 15853 * @default 15854 */ 15855Html5.prototype.featuresProgressEvents = true; 15856 15857/** 15858 * Boolean indicating whether the `HTML5` tech currently supports the timeupdate event. 15859 * If this is false, manual `timeupdate` events will be triggred instead. 15860 * 15861 * @default 15862 */ 15863Html5.prototype.featuresTimeupdateEvents = true; 15864 15865/** 15866 * Boolean indicating whether the `HTML5` tech currently supports native `TextTrack`s. 15867 * 15868 * @type {boolean} 15869 * @default {@link Html5.supportsNativeTextTracks} 15870 */ 15871Html5.prototype.featuresNativeTextTracks = Html5.supportsNativeTextTracks(); 15872 15873/** 15874 * Boolean indicating whether the `HTML5` tech currently supports native `VideoTrack`s. 15875 * 15876 * @type {boolean} 15877 * @default {@link Html5.supportsNativeVideoTracks} 15878 */ 15879Html5.prototype.featuresNativeVideoTracks = Html5.supportsNativeVideoTracks(); 15880 15881/** 15882 * Boolean indicating whether the `HTML5` tech currently supports native `AudioTrack`s. 15883 * 15884 * @type {boolean} 15885 * @default {@link Html5.supportsNativeAudioTracks} 15886 */ 15887Html5.prototype.featuresNativeAudioTracks = Html5.supportsNativeAudioTracks(); 15888 15889// HTML5 Feature detection and Device Fixes --------------------------------- // 15890var canPlayType = Html5.TEST_VID && Html5.TEST_VID.constructor.prototype.canPlayType; 15891var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i; 15892var mp4RE = /^video\/mp4/i; 15893 15894Html5.patchCanPlayType = function () { 15895 15896 // Android 4.0 and above can play HLS to some extent but it reports being unable to do so 15897 if (browser.ANDROID_VERSION >= 4.0 && !browser.IS_FIREFOX) { 15898 Html5.TEST_VID.constructor.prototype.canPlayType = function (type) { 15899 if (type && mpegurlRE.test(type)) { 15900 return 'maybe'; 15901 } 15902 return canPlayType.call(this, type); 15903 }; 15904 15905 // Override Android 2.2 and less canPlayType method which is broken 15906 } else if (browser.IS_OLD_ANDROID) { 15907 Html5.TEST_VID.constructor.prototype.canPlayType = function (type) { 15908 if (type && mp4RE.test(type)) { 15909 return 'maybe'; 15910 } 15911 return canPlayType.call(this, type); 15912 }; 15913 } 15914}; 15915 15916Html5.unpatchCanPlayType = function () { 15917 var r = Html5.TEST_VID.constructor.prototype.canPlayType; 15918 15919 Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType; 15920 return r; 15921}; 15922 15923// by default, patch the media element 15924Html5.patchCanPlayType(); 15925 15926Html5.disposeMediaElement = function (el) { 15927 if (!el) { 15928 return; 15929 } 15930 15931 if (el.parentNode) { 15932 el.parentNode.removeChild(el); 15933 } 15934 15935 // remove any child track or source nodes to prevent their loading 15936 while (el.hasChildNodes()) { 15937 el.removeChild(el.firstChild); 15938 } 15939 15940 // remove any src reference. not setting `src=''` because that causes a warning 15941 // in firefox 15942 el.removeAttribute('src'); 15943 15944 // force the media element to update its loading state by calling load() 15945 // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793) 15946 if (typeof el.load === 'function') { 15947 // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473) 15948 (function () { 15949 try { 15950 el.load(); 15951 } catch (e) { 15952 // not supported 15953 } 15954 })(); 15955 } 15956}; 15957 15958Html5.resetMediaElement = function (el) { 15959 if (!el) { 15960 return; 15961 } 15962 15963 var sources = el.querySelectorAll('source'); 15964 var i = sources.length; 15965 15966 while (i--) { 15967 el.removeChild(sources[i]); 15968 } 15969 15970 // remove any src reference. 15971 // not setting `src=''` because that throws an error 15972 el.removeAttribute('src'); 15973 15974 if (typeof el.load === 'function') { 15975 // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473) 15976 (function () { 15977 try { 15978 el.load(); 15979 } catch (e) { 15980 // satisfy linter 15981 } 15982 })(); 15983 } 15984}; 15985 15986/* Native HTML5 element property wrapping ----------------------------------- */ 15987// Wrap native properties with a getter 15988[ 15989/** 15990 * Get the value of `paused` from the media element. `paused` indicates whether the media element 15991 * is currently paused or not. 15992 * 15993 * @method Html5#paused 15994 * @return {boolean} 15995 * The value of `paused` from the media element. 15996 * 15997 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-paused} 15998 */ 15999'paused', 16000 16001/** 16002 * Get the value of `currentTime` from the media element. `currentTime` indicates 16003 * the current second that the media is at in playback. 16004 * 16005 * @method Html5#currentTime 16006 * @return {number} 16007 * The value of `currentTime` from the media element. 16008 * 16009 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-currenttime} 16010 */ 16011'currentTime', 16012 16013/** 16014 * Get the value of `buffered` from the media element. `buffered` is a `TimeRange` 16015 * object that represents the parts of the media that are already downloaded and 16016 * available for playback. 16017 * 16018 * @method Html5#buffered 16019 * @return {TimeRange} 16020 * The value of `buffered` from the media element. 16021 * 16022 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-buffered} 16023 */ 16024'buffered', 16025 16026/** 16027 * Get the value of `volume` from the media element. `volume` indicates 16028 * the current playback volume of audio for a media. `volume` will be a value from 0 16029 * (silent) to 1 (loudest and default). 16030 * 16031 * @method Html5#volume 16032 * @return {number} 16033 * The value of `volume` from the media element. Value will be between 0-1. 16034 * 16035 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume} 16036 */ 16037'volume', 16038 16039/** 16040 * Get the value of `muted` from the media element. `muted` indicates 16041 * that the volume for the media should be set to silent. This does not actually change 16042 * the `volume` attribute. 16043 * 16044 * @method Html5#muted 16045 * @return {boolean} 16046 * - True if the value of `volume` should be ignored and the audio set to silent. 16047 * - False if the value of `volume` should be used. 16048 * 16049 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted} 16050 */ 16051'muted', 16052 16053/** 16054 * Get the value of `poster` from the media element. `poster` indicates 16055 * that the url of an image file that can/will be shown when no media data is available. 16056 * 16057 * @method Html5#poster 16058 * @return {string} 16059 * The value of `poster` from the media element. Value will be a url to an 16060 * image. 16061 * 16062 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-video-poster} 16063 */ 16064'poster', 16065 16066/** 16067 * Get the value of `preload` from the media element. `preload` indicates 16068 * what should download before the media is interacted with. It can have the following 16069 * values: 16070 * - none: nothing should be downloaded 16071 * - metadata: poster and the first few frames of the media may be downloaded to get 16072 * media dimensions and other metadata 16073 * - auto: allow the media and metadata for the media to be downloaded before 16074 * interaction 16075 * 16076 * @method Html5#preload 16077 * @return {string} 16078 * The value of `preload` from the media element. Will be 'none', 'metadata', 16079 * or 'auto'. 16080 * 16081 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload} 16082 */ 16083'preload', 16084 16085/** 16086 * Get the value of `autoplay` from the media element. `autoplay` indicates 16087 * that the media should start to play as soon as the page is ready. 16088 * 16089 * @method Html5#autoplay 16090 * @return {boolean} 16091 * - The value of `autoplay` from the media element. 16092 * - True indicates that the media should start as soon as the page loads. 16093 * - False indicates that the media should not start as soon as the page loads. 16094 * 16095 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay} 16096 */ 16097'autoplay', 16098 16099/** 16100 * Get the value of `controls` from the media element. `controls` indicates 16101 * whether the native media controls should be shown or hidden. 16102 * 16103 * @method Html5#controls 16104 * @return {boolean} 16105 * - The value of `controls` from the media element. 16106 * - True indicates that native controls should be showing. 16107 * - False indicates that native controls should be hidden. 16108 * 16109 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-controls} 16110 */ 16111'controls', 16112 16113/** 16114 * Get the value of `loop` from the media element. `loop` indicates 16115 * that the media should return to the start of the media and continue playing once 16116 * it reaches the end. 16117 * 16118 * @method Html5#loop 16119 * @return {boolean} 16120 * - The value of `loop` from the media element. 16121 * - True indicates that playback should seek back to start once 16122 * the end of a media is reached. 16123 * - False indicates that playback should not loop back to the start when the 16124 * end of the media is reached. 16125 * 16126 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop} 16127 */ 16128'loop', 16129 16130/** 16131 * Get the value of the `error` from the media element. `error` indicates any 16132 * MediaError that may have occured during playback. If error returns null there is no 16133 * current error. 16134 * 16135 * @method Html5#error 16136 * @return {MediaError|null} 16137 * The value of `error` from the media element. Will be `MediaError` if there 16138 * is a current error and null otherwise. 16139 * 16140 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-error} 16141 */ 16142'error', 16143 16144/** 16145 * Get the value of `seeking` from the media element. `seeking` indicates whether the 16146 * media is currently seeking to a new position or not. 16147 * 16148 * @method Html5#seeking 16149 * @return {boolean} 16150 * - The value of `seeking` from the media element. 16151 * - True indicates that the media is currently seeking to a new position. 16152 * - Flase indicates that the media is not seeking to a new position at this time. 16153 * 16154 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seeking} 16155 */ 16156'seeking', 16157 16158/** 16159 * Get the value of `seekable` from the media element. `seekable` returns a 16160 * `TimeRange` object indicating ranges of time that can currently be `seeked` to. 16161 * 16162 * @method Html5#seekable 16163 * @return {TimeRange} 16164 * The value of `seekable` from the media element. A `TimeRange` object 16165 * indicating the current ranges of time that can be seeked to. 16166 * 16167 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seekable} 16168 */ 16169'seekable', 16170 16171/** 16172 * Get the value of `ended` from the media element. `ended` indicates whether 16173 * the media has reached the end or not. 16174 * 16175 * @method Html5#ended 16176 * @return {boolean} 16177 * - The value of `ended` from the media element. 16178 * - True indicates that the media has ended. 16179 * - False indicates that the media has not ended. 16180 * 16181 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended} 16182 */ 16183'ended', 16184 16185/** 16186 * Get the value of `defaultMuted` from the media element. `defaultMuted` indicates 16187 * whether the media should start muted or not. Only changes the default state of the 16188 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the 16189 * current state. 16190 * 16191 * @method Html5#defaultMuted 16192 * @return {boolean} 16193 * - The value of `defaultMuted` from the media element. 16194 * - True indicates that the media should start muted. 16195 * - False indicates that the media should not start muted 16196 * 16197 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted} 16198 */ 16199'defaultMuted', 16200 16201/** 16202 * Get the value of `playbackRate` from the media element. `playbackRate` indicates
16203 * the rate at which the media is currently playing back. Examples: 16204 * - if playbackRate is set to 2, media will play twice as fast. 16205 * - if playbackRate is set to 0.5, media will play half as fast. 16206 * 16207 * @method Html5#playbackRate 16208 * @return {number} 16209 * The value of `playbackRate` from the media element. A number indicating 16210 * the current playback speed of the media, where 1 is normal speed. 16211 * 16212 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate} 16213 */ 16214'playbackRate', 16215 16216/** 16217 * Get the value of `played` from the media element. `played` returns a `TimeRange` 16218 * object representing points in the media timeline that have been played. 16219 * 16220 * @method Html5#played 16221 * @return {TimeRange} 16222 * The value of `played` from the media element. A `TimeRange` object indicating 16223 * the ranges of time that have been played. 16224 * 16225 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-played} 16226 */ 16227'played', 16228 16229/** 16230 * Get the value of `networkState` from the media element. `networkState` indicates 16231 * the current network state. It returns an enumeration from the following list: 16232 * - 0: NETWORK_EMPTY 16233 * - 1: NEWORK_IDLE 16234 * - 2: NETWORK_LOADING 16235 * - 3: NETWORK_NO_SOURCE 16236 * 16237 * @method Html5#networkState 16238 * @return {number} 16239 * The value of `networkState` from the media element. This will be a number 16240 * from the list in the description. 16241 * 16242 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-networkstate} 16243 */ 16244'networkState', 16245 16246/** 16247 * Get the value of `readyState` from the media element. `readyState` indicates 16248 * the current state of the media element. It returns an enumeration from the 16249 * following list: 16250 * - 0: HAVE_NOTHING 16251 * - 1: HAVE_METADATA 16252 * - 2: HAVE_CURRENT_DATA 16253 * - 3: HAVE_FUTURE_DATA 16254 * - 4: HAVE_ENOUGH_DATA 16255 * 16256 * @method Html5#readyState 16257 * @return {number} 16258 * The value of `readyState` from the media element. This will be a number 16259 * from the list in the description. 16260 * 16261 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#ready-states} 16262 */ 16263'readyState', 16264 16265/** 16266 * Get the value of `videoWidth` from the video element. `videoWidth` indicates 16267 * the current width of the video in css pixels. 16268 * 16269 * @method Html5#videoWidth 16270 * @return {number} 16271 * The value of `videoWidth` from the video element. This will be a number 16272 * in css pixels. 16273 * 16274 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth} 16275 */ 16276'videoWidth', 16277 16278/** 16279 * Get the value of `videoHeight` from the video element. `videoHeigth` indicates 16280 * the current height of the video in css pixels. 16281 * 16282 * @method Html5#videoHeight 16283 * @return {number} 16284 * The value of `videoHeight` from the video element. This will be a number 16285 * in css pixels. 16286 * 16287 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth} 16288 */ 16289'videoHeight'].forEach(function (prop) { 16290 Html5.prototype[prop] = function () { 16291 return this.el_[prop]; 16292 }; 16293}); 16294 16295// Wrap native properties with a setter in this format: 16296// set + toTitleCase(name) 16297[ 16298/** 16299 * Set the value of `volume` on the media element. `volume` indicates the current 16300 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and 16301 * so on. 16302 * 16303 * @method Html5#setVolume 16304 * @param {number} percentAsDecimal 16305 * The volume percent as a decimal. Valid range is from 0-1. 16306 * 16307 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume} 16308 */ 16309'volume', 16310 16311/** 16312 * Set the value of `muted` on the media element. `muted` indicates the current 16313 * audio level should be silent. 16314 * 16315 * @method Html5#setMuted 16316 * @param {boolean} muted 16317 * - True if the audio should be set to silent 16318 * - False otherwise 16319 * 16320 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted} 16321 */ 16322'muted', 16323 16324/** 16325 * Set the value of `src` on the media element. `src` indicates the current 16326 * {@link Tech~SourceObject} for the media. 16327 * 16328 * @method Html5#setSrc 16329 * @param {Tech~SourceObject} src 16330 * The source object to set as the current source. 16331 * 16332 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-src} 16333 */ 16334'src', 16335 16336/** 16337 * Set the value of `poster` on the media element. `poster` is the url to 16338 * an image file that can/will be shown when no media data is available. 16339 * 16340 * @method Html5#setPoster 16341 * @param {string} poster 16342 * The url to an image that should be used as the `poster` for the media 16343 * element. 16344 * 16345 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-poster} 16346 */ 16347'poster', 16348 16349/** 16350 * Set the value of `preload` on the media element. `preload` indicates 16351 * what should download before the media is interacted with. It can have the following 16352 * values: 16353 * - none: nothing should be downloaded 16354 * - metadata: poster and the first few frames of the media may be downloaded to get 16355 * media dimensions and other metadata 16356 * - auto: allow the media and metadata for the media to be downloaded before 16357 * interaction 16358 * 16359 * @method Html5#setPreload 16360 * @param {string} preload 16361 * The value of `preload` to set on the media element. Must be 'none', 'metadata', 16362 * or 'auto'. 16363 * 16364 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload} 16365 */ 16366'preload', 16367 16368/** 16369 * Set the value of `autoplay` on the media element. `autoplay` indicates 16370 * that the media should start to play as soon as the page is ready. 16371 * 16372 * @method Html5#setAutoplay 16373 * @param {boolean} autoplay 16374 * - True indicates that the media should start as soon as the page loads. 16375 * - False indicates that the media should not start as soon as the page loads. 16376 * 16377 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay} 16378 */ 16379'autoplay', 16380 16381/** 16382 * Set the value of `loop` on the media element. `loop` indicates 16383 * that the media should return to the start of the media and continue playing once 16384 * it reaches the end. 16385 * 16386 * @method Html5#setLoop 16387 * @param {boolean} loop 16388 * - True indicates that playback should seek back to start once 16389 * the end of a media is reached. 16390 * - False indicates that playback should not loop back to the start when the 16391 * end of the media is reached. 16392 * 16393 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop} 16394 */ 16395'loop', 16396 16397/** 16398 * Set the value of `playbackRate` on the media element. `playbackRate` indicates 16399 * the rate at which the media should play back. Examples: 16400 * - if playbackRate is set to 2, media will play twice as fast. 16401 * - if playbackRate is set to 0.5, media will play half as fast. 16402 * 16403 * @method Html5#setPlaybackRate 16404 * @return {number} 16405 * The value of `playbackRate` from the media element. A number indicating 16406 * the current playback speed of the media, where 1 is normal speed. 16407 * 16408 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate} 16409 */ 16410'playbackRate'].forEach(function (prop) { 16411 Html5.prototype['set' + (0, _toTitleCase2['default'])(prop)] = function (v) { 16412 this.el_[prop] = v; 16413 }; 16414}); 16415 16416// wrap native functions with a function 16417[ 16418/** 16419 * A wrapper around the media elements `pause` function. This will call the `HTML5` 16420 * media elements `pause` function. 16421 * 16422 * @method Html5#pause 16423 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-pause} 16424 */ 16425'pause', 16426 16427/** 16428 * A wrapper around the media elements `load` function. This will call the `HTML5`s 16429 * media element `load` function. 16430 * 16431 * @method Html5#load 16432 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-load} 16433 */ 16434'load'].forEach(function (prop) { 16435 Html5.prototype[prop] = function () { 16436 return this.el_[prop](); 16437 }; 16438}); 16439 16440_tech2['default'].withSourceHandlers(Html5); 16441 16442/** 16443 * Native source handler for Html5, simply passes the source to the media element. 16444 * 16445 * @proprety {Tech~SourceObject} source 16446 * The source object 16447 * 16448 * @proprety {Html5} tech 16449 * The instance of the HTML5 tech. 16450 */ 16451Html5.nativeSourceHandler = {}; 16452 16453/** 16454 * Check if the media element can play the given mime type. 16455 * 16456 * @param {string} type 16457 * The mimetype to check 16458 * 16459 * @return {string} 16460 * 'probably', 'maybe', or '' (empty string) 16461 */ 16462Html5.nativeSourceHandler.canPlayType = function (type) { 16463 // IE9 on Windows 7 without MediaPlayer throws an error here 16464 // https://github.com/videojs/video.js/issues/519 16465 try {
16466 return Html5.TEST_VID.canPlayType(type); 16467 } catch (e) { 16468 return ''; 16469 } 16470}; 16471 16472/** 16473 * Check if the media element can handle a source natively. 16474 * 16475 * @param {Tech~SourceObject} source 16476 * The source object 16477 * 16478 * @param {Object} [options] 16479 * Options to be passed to the tech. 16480 * 16481 * @return {string} 16482 * 'probably', 'maybe', or '' (empty string). 16483 */ 16484Html5.nativeSourceHandler.canHandleSource = function (source, options) { 16485 16486 // If a type was provided we should rely on that 16487 if (source.type) { 16488 return Html5.nativeSourceHandler.canPlayType(source.type); 16489 16490 // If no type, fall back to checking 'video/[EXTENSION]' 16491 } else if (source.src) { 16492 var ext = Url.getFileExtension(source.src); 16493 16494 return Html5.nativeSourceHandler.canPlayType('video/' + ext); 16495 } 16496 16497 return ''; 16498}; 16499 16500/** 16501 * Pass the source to the native media element. 16502 * 16503 * @param {Tech~SourceObject} source 16504 * The source object 16505 * 16506 * @param {Html5} tech 16507 * The instance of the Html5 tech 16508 * 16509 * @param {Object} [options] 16510 * The options to pass to the source 16511 */ 16512Html5.nativeSourceHandler.handleSource = function (source, tech, options) { 16513 tech.setSrc(source.src); 16514}; 16515 16516/** 16517 * A noop for the native dispose function, as cleanup is not needed. 16518 */ 16519Html5.nativeSourceHandler.dispose = function () {}; 16520 16521// Register the native source handler 16522Html5.registerSourceHandler(Html5.nativeSourceHandler); 16523 16524_component2['default'].registerComponent('Html5', Html5); 16525_tech2['default'].registerTech('Html5', Html5); 16526exports['default'] = Html5; 16527 16528},{"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){ 16529'use strict'; 16530 16531exports.__esModule = true; 16532 16533var _component = _dereq_(5); 16534 16535var _component2 = _interopRequireDefault(_component); 16536 16537var _tech = _dereq_(62); 16538 16539var _tech2 = _interopRequireDefault(_tech); 16540 16541var _toTitleCase = _dereq_(91); 16542 16543var _toTitleCase2 = _interopRequireDefault(_toTitleCase); 16544 16545function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16546 16547function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 16548 16549function _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; } 16550 16551function _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; } /** 16552 * @file loader.js 16553 */ 16554 16555 16556/** 16557 * The `MediaLoader` is the `Component` that decides which playback technology to load 16558 * when a player is initialized. 16559 * 16560 * @extends Component 16561 */ 16562var MediaLoader = function (_Component) { 16563 _inherits(MediaLoader, _Component); 16564 16565 /** 16566 * Create an instance of this class. 16567 * 16568 * @param {Player} player 16569 * The `Player` that this class should attach to. 16570 * 16571 * @param {Object} [options] 16572 * The key/value stroe of player options. 16573 * 16574 * @param {Component~ReadyCallback} [ready] 16575 * The function that is run when this component is ready. 16576 */ 16577 function MediaLoader(player, options, ready) { 16578 _classCallCheck(this, MediaLoader); 16579 16580 // If there are no sources when the player is initialized, 16581 // load the first supported playback technology. 16582 16583 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready)); 16584 16585 if (!options.playerOptions.sources || options.playerOptions.sources.length === 0) { 16586 for (var i = 0, j = options.playerOptions.techOrder; i < j.length; i++) { 16587 var techName = (0, _toTitleCase2['default'])(j[i]); 16588 var tech = _tech2['default'].getTech(techName); 16589
16590 // Support old behavior of techs being registered as components. 16591 // Remove once that deprecated behavior is removed. 16592 if (!techName) { 16593 tech = _component2['default'].getComponent(techName); 16594 } 16595 16596 // Check if the browser supports this technology 16597 if (tech && tech.isSupported()) { 16598 player.loadTech_(techName); 16599 break; 16600 } 16601 } 16602 } else { 16603 // Loop through playback technologies (HTML5, Flash) and check for support. 16604 // Then load the best source. 16605 // A few assumptions here: 16606 // All playback technologies respect preload false. 16607 player.src(options.playerOptions.sources); 16608 } 16609 return _this; 16610 } 16611 16612 return MediaLoader; 16613}(_component2['default']); 16614 16615_component2['default'].registerComponent('MediaLoader', MediaLoader); 16616exports['default'] = MediaLoader; 16617 16618},{"5":5,"62":62,"91":91}],62:[function(_dereq_,module,exports){ 16619'use strict'; 16620 16621exports.__esModule = true; 16622 16623var _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; }; 16624 16625var _component = _dereq_(5); 16626 16627var _component2 = _interopRequireDefault(_component); 16628 16629var _htmlTrackElement = _dereq_(66); 16630 16631var _htmlTrackElement2 = _interopRequireDefault(_htmlTrackElement); 16632
16633var _htmlTrackElementList = _dereq_(65); 16634 16635var _htmlTrackElementList2 = _interopRequireDefault(_htmlTrackElementList); 16636 16637var _mergeOptions = _dereq_(87); 16638 16639var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 16640 16641var _textTrack = _dereq_(72); 16642 16643var _textTrack2 = _interopRequireDefault(_textTrack); 16644 16645var _textTrackList = _dereq_(70); 16646 16647var _textTrackList2 = _interopRequireDefault(_textTrackList); 16648 16649var _videoTrackList = _dereq_(76); 16650 16651var _videoTrackList2 = _interopRequireDefault(_videoTrackList); 16652 16653var _audioTrackList = _dereq_(63); 16654 16655var _audioTrackList2 = _interopRequireDefault(_audioTrackList); 16656 16657var _fn = _dereq_(83); 16658 16659var Fn = _interopRequireWildcard(_fn); 16660 16661var _log = _dereq_(86); 16662 16663var _log2 = _interopRequireDefault(_log); 16664 16665var _timeRanges = _dereq_(90); 16666 16667var _buffer = _dereq_(79); 16668 16669var _mediaError = _dereq_(46); 16670 16671var _mediaError2 = _interopRequireDefault(_mediaError); 16672 16673var _window = _dereq_(95); 16674 16675var _window2 = _interopRequireDefault(_window); 16676 16677var _document = _dereq_(94); 16678 16679var _document2 = _interopRequireDefault(_document); 16680 16681var _obj = _dereq_(88); 16682 16683function _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; } } 16684 16685function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16686 16687function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 16688 16689function _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; } 16690 16691function _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; } /** 16692 * @file tech.js 16693 */ 16694 16695/** 16696 * An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string 16697 * that just contains the src url alone. 16698 * * `var SourceObject = {src: 'http://ex.com/video.mp4', type: 'video/mp4'};` 16699 * `var SourceString = 'http://example.com/some-video.mp4';` 16700 * 16701 * @typedef {Object|string} Tech~SourceObject 16702 * 16703 * @property {string} src 16704 * The url to the source 16705 * 16706 * @property {string} type 16707 * The mime type of the source 16708 */ 16709 16710/** 16711 * A function used by {@link Tech} to create a new {@link TextTrack}. 16712 * 16713 * @param {Tech} self 16714 * An instance of the Tech class. 16715 * 16716 * @param {string} kind 16717 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata) 16718 * 16719 * @param {string} [label] 16720 * Label to identify the text track 16721 * 16722 * @param {string} [language] 16723 * Two letter language abbreviation 16724 * 16725 * @param {Object} [options={}] 16726 * An object with additional text track options 16727 * 16728 * @return {TextTrack} 16729 * The text track that was created. 16730 */ 16731function createTrackHelper(self, kind, label, language) { 16732 var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; 16733 16734 var tracks = self.textTracks(); 16735 16736 options.kind = kind; 16737 16738 if (label) { 16739 options.label = label; 16740 } 16741 if (language) { 16742 options.language = language; 16743 } 16744 options.tech = self; 16745 16746 var track = new _textTrack2['default'](options); 16747 16748 tracks.addTrack_(track); 16749 16750 return track; 16751} 16752 16753/** 16754 * This is the base class for media playback technology controllers, such as 16755 * {@link Flash} and {@link HTML5} 16756 * 16757 * @extends Component 16758 */ 16759 16760var Tech = function (_Component) { 16761 _inherits(Tech, _Component); 16762 16763 /** 16764 * Create an instance of this Tech. 16765 * 16766 * @param {Object} [options] 16767 * The key/value store of player options. 16768 * 16769 * @param {Component~ReadyCallback} ready 16770 * Callback function to call when the `HTML5` Tech is ready. 16771 */ 16772 function Tech() { 16773 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 16774 var ready = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; 16775 16776 _classCallCheck(this, Tech); 16777 16778 // we don't want the tech to report user activity automatically.
vendor: 5,704 bytes, lines 16779-16984
16779 // This is done manually in addControlsListeners 16780 options.reportTouchActivity = false; 16781 16782 // keep track of whether the current source has played at all to 16783 // implement a very limited played() 16784 var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready)); 16785 16786 _this.hasStarted_ = false; 16787 _this.on('playing', function () { 16788 this.hasStarted_ = true; 16789 }); 16790 _this.on('loadstart', function () { 16791 this.hasStarted_ = false; 16792 }); 16793 16794 _this.textTracks_ = options.textTracks; 16795 _this.videoTracks_ = options.videoTracks; 16796 _this.audioTracks_ = options.audioTracks; 16797 16798 // Manually track progress in cases where the browser/flash player doesn't report it. 16799 if (!_this.featuresProgressEvents) { 16800 _this.manualProgressOn(); 16801 } 16802 16803 // Manually track timeupdates in cases where the browser/flash player doesn't report it. 16804 if (!_this.featuresTimeupdateEvents) { 16805 _this.manualTimeUpdatesOn(); 16806 } 16807 16808 ['Text', 'Audio', 'Video'].forEach(function (track) { 16809 if (options['native' + track + 'Tracks'] === false) { 16810 _this['featuresNative' + track + 'Tracks'] = false; 16811 } 16812 }); 16813 16814 if (options.nativeCaptions === false) { 16815 _this.featuresNativeTextTracks = false; 16816 } 16817 16818 if (!_this.featuresNativeTextTracks) { 16819 _this.emulateTextTracks(); 16820 } 16821 16822 _this.autoRemoteTextTracks_ = new _textTrackList2['default'](); 16823 16824 _this.initTextTrackListeners(); 16825 _this.initTrackListeners(); 16826 16827 // Turn on component tap events only if not using native controls 16828 if (!options.nativeControlsForTouch) { 16829 _this.emitTapEvents(); 16830 } 16831 16832 if (_this.constructor) { 16833 _this.name_ = _this.constructor.name || 'Unknown Tech'; 16834 } 16835 return _this; 16836 } 16837 16838 /* Fallbacks for unsupported event types 16839 ================================================================================ */ 16840 16841 /** 16842 * Polyfill the `progress` event for browsers that don't support it natively. 16843 * 16844 * @see {@link Tech#trackProgress} 16845 */ 16846 16847 16848 Tech.prototype.manualProgressOn = function manualProgressOn() { 16849 this.on('durationchange', this.onDurationChange); 16850 16851 this.manualProgress = true; 16852 16853 // Trigger progress watching when a source begins loading 16854 this.one('ready', this.trackProgress); 16855 }; 16856 16857 /** 16858 * Turn off the polyfill for `progress` events that was created in 16859 * {@link Tech#manualProgressOn} 16860 */ 16861 16862 16863 Tech.prototype.manualProgressOff = function manualProgressOff() { 16864 this.manualProgress = false; 16865 this.stopTrackingProgress(); 16866 16867 this.off('durationchange', this.onDurationChange); 16868 }; 16869 16870 /** 16871 * This is used to trigger a `progress` event when the buffered percent changes. It 16872 * sets an interval function that will be called every 500 milliseconds to check if the 16873 * buffer end percent has changed. 16874 * 16875 * > This function is called by {@link Tech#manualProgressOn} 16876 * 16877 * @param {EventTarget~Event} event 16878 * The `ready` event that caused this to run. 16879 * 16880 * @listens Tech#ready 16881 * @fires Tech#progress 16882 */ 16883 16884 16885 Tech.prototype.trackProgress = function trackProgress(event) { 16886 this.stopTrackingProgress(); 16887 this.progressInterval = this.setInterval(Fn.bind(this, function () { 16888 // Don't trigger unless buffered amount is greater than last time 16889 16890 var numBufferedPercent = this.bufferedPercent(); 16891 16892 if (this.bufferedPercent_ !== numBufferedPercent) { 16893 /** 16894 * See {@link Player#progress} 16895 * 16896 * @event Tech#progress 16897 * @type {EventTarget~Event} 16898 */ 16899 this.trigger('progress'); 16900 } 16901 16902 this.bufferedPercent_ = numBufferedPercent; 16903 16904 if (numBufferedPercent === 1) { 16905 this.stopTrackingProgress(); 16906 } 16907 }), 500); 16908 }; 16909 16910 /** 16911 * Update our internal duration on a `durationchange` event by calling 16912 * {@link Tech#duration}. 16913 * 16914 * @param {EventTarget~Event} event 16915 * The `durationchange` event that caused this to run. 16916 * 16917 * @listens Tech#durationchange 16918 */ 16919 16920 16921 Tech.prototype.onDurationChange = function onDurationChange(event) { 16922 this.duration_ = this.duration(); 16923 }; 16924 16925 /** 16926 * Get and create a `TimeRange` object for buffering. 16927 * 16928 * @return {TimeRange} 16929 * The time range object that was created. 16930 */ 16931 16932 16933 Tech.prototype.buffered = function buffered() { 16934 return (0, _timeRanges.createTimeRange)(0, 0); 16935 }; 16936 16937 /** 16938 * Get the percentage of the current video that is currently buffered. 16939 * 16940 * @return {number} 16941 * A number from 0 to 1 that represents the decimal percentage of the 16942 * video that is buffered. 16943 * 16944 */ 16945 16946 16947 Tech.prototype.bufferedPercent = function bufferedPercent() { 16948 return (0, _buffer.bufferedPercent)(this.buffered(), this.duration_); 16949 }; 16950 16951 /** 16952 * Turn off the polyfill for `progress` events that was created in 16953 * {@link Tech#manualProgressOn} 16954 * Stop manually tracking progress events by clearing the interval that was set in 16955 * {@link Tech#trackProgress}. 16956 */ 16957 16958 16959 Tech.prototype.stopTrackingProgress = function stopTrackingProgress() { 16960 this.clearInterval(this.progressInterval); 16961 }; 16962 16963 /** 16964 * Polyfill the `timeupdate` event for browsers that don't support it. 16965 * 16966 * @see {@link Tech#trackCurrentTime} 16967 */ 16968 16969 16970 Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() { 16971 this.manualTimeUpdates = true; 16972 16973 this.on('play', this.trackCurrentTime); 16974 this.on('pause', this.stopTrackingCurrentTime); 16975 }; 16976 16977 /** 16978 * Turn off the polyfill for `timeupdate` events that was created in 16979 * {@link Tech#manualTimeUpdatesOn} 16980 */ 16981 16982 16983 Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() { 16984 this.manualTimeUpdates = false;
16985 this.stopTrackingCurrentTime(); 16986 this.off('play', this.trackCurrentTime); 16987 this.off('pause', this.stopTrackingCurrentTime); 16988 }; 16989 16990 /** 16991 * Sets up an interval function to track current time and trigger `timeupdate` every 16992 * 250 milliseconds. 16993 * 16994 * @listens Tech#play 16995 * @triggers Tech#timeupdate 16996 */ 16997 16998 16999 Tech.prototype.trackCurrentTime = function trackCurrentTime() { 17000 if (this.currentTimeInterval) { 17001 this.stopTrackingCurrentTime(); 17002 } 17003 this.currentTimeInterval = this.setInterval(function () { 17004 /** 17005 * Triggered at an interval of 250ms to indicated that time is passing in the video. 17006 * 17007 * @event Tech#timeupdate 17008 * @type {EventTarget~Event} 17009 */ 17010 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); 17011 17012 // 42 = 24 fps // 250 is what Webkit uses // FF uses 15 17013 }, 250); 17014 }; 17015 17016 /** 17017 * Stop the interval function created in {@link Tech#trackCurrentTime} so that the 17018 * `timeupdate` event is no longer triggered. 17019 * 17020 * @listens {Tech#pause} 17021 */ 17022 17023 17024 Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() { 17025 this.clearInterval(this.currentTimeInterval); 17026 17027 // #1002 - if the video ends right before the next timeupdate would happen, 17028 // the progress bar won't make it all the way to the end 17029 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); 17030 }; 17031 17032 /** 17033 * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList}, 17034 * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech. 17035 * 17036 * @fires Component#dispose 17037 */ 17038 17039 17040 Tech.prototype.dispose = function dispose() { 17041 17042 // clear out all tracks because we can't reuse them between techs 17043 this.clearTracks(['audio', 'video', 'text']); 17044 17045 // Turn off any manual progress or timeupdate tracking 17046 if (this.manualProgress) { 17047 this.manualProgressOff(); 17048 } 17049 17050 if (this.manualTimeUpdates) { 17051 this.manualTimeUpdatesOff(); 17052 } 17053 17054 _Component.prototype.dispose.call(this); 17055 }; 17056 17057 /** 17058 * Clear out a single `TrackList` or an array of `TrackLists` given their names. 17059 * 17060 * > Note: Techs without source handlers should call this between sources for `video` 17061 * & `audio` tracks. You don't want to use them between tracks! 17062 * 17063 * @param {string[]|string} types 17064 * TrackList names to clear, valid names are `video`, `audio`, and 17065 * `text`. 17066 */ 17067 17068 17069 Tech.prototype.clearTracks = function clearTracks(types) { 17070 var _this2 = this; 17071 17072 types = [].concat(types); 17073 // clear out all tracks because we can't reuse them between techs 17074 types.forEach(function (type) { 17075 var list = _this2[type + 'Tracks']() || []; 17076 var i = list.length; 17077 17078 while (i--) { 17079 var track = list[i]; 17080 17081 if (type === 'text') { 17082 _this2.removeRemoteTextTrack(track); 17083 } 17084 list.removeTrack_(track); 17085 } 17086 }); 17087 }; 17088 17089 /** 17090 * Remove any TextTracks added via addRemoteTextTrack that are 17091 * flagged for automatic garbage collection 17092 */ 17093 17094 17095 Tech.prototype.cleanupAutoTextTracks = function cleanupAutoTextTracks() { 17096 var list = this.autoRemoteTextTracks_ || []; 17097 var i = list.length; 17098 17099 while (i--) { 17100 var track = list[i]; 17101 17102 this.removeRemoteTextTrack(track); 17103 } 17104 }; 17105 17106 /** 17107 * Reset the tech, which will removes all sources and reset the internal readyState. 17108 * 17109 * @abstract 17110 */ 17111 17112 17113 Tech.prototype.reset = function reset() {}; 17114 17115 /** 17116 * Get or set an error on the Tech. 17117 * 17118 * @param {MediaError} [err] 17119 * Error to set on the Tech 17120 * 17121 * @return {MediaError|null} 17122 * The current error object on the tech, or null if there isn't one. 17123 */ 17124 17125 17126 Tech.prototype.error = function error(err) { 17127 if (err !== undefined) { 17128 this.error_ = new _mediaError2['default'](err); 17129 this.trigger('error'); 17130 } 17131 return this.error_; 17132 }; 17133 17134 /** 17135 * Returns the `TimeRange`s that have been played through for the current source. 17136 * 17137 * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`. 17138 * It only checks wether the source has played at all or not. 17139 * 17140 * @return {TimeRange} 17141 * - A single time range if this video has played 17142 * - An empty set of ranges if not. 17143 */ 17144 17145 17146 Tech.prototype.played = function played() { 17147 if (this.hasStarted_) { 17148 return (0, _timeRanges.createTimeRange)(0, 0); 17149 } 17150 return (0, _timeRanges.createTimeRange)(); 17151 }; 17152 17153 /** 17154 * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was 17155 * previously called. 17156 * 17157 * @fires Tech#timeupdate 17158 */ 17159 17160 17161 Tech.prototype.setCurrentTime = function setCurrentTime() { 17162 // improve the accuracy of manual timeupdates 17163 if (this.manualTimeUpdates) { 17164 /** 17165 * A manual `timeupdate` event. 17166 * 17167 * @event Tech#timeupdate 17168 * @type {EventTarget~Event} 17169 */ 17170 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); 17171 } 17172 }; 17173 17174 /** 17175 * Turn on listeners for {@link TextTrackList} events. This adds 17176 * {@link EventTarget~EventListeners} for `texttrackchange`, `addtrack` and 17177 * `removetrack`. 17178 * 17179 * @fires Tech#texttrackchange 17180 */ 17181 17182 17183 Tech.prototype.initTextTrackListeners = function initTextTrackListeners() { 17184 var textTrackListChanges = Fn.bind(this, function () { 17185 /** 17186 * Triggered when tracks are added or removed on the Tech {@link TextTrackList} 17187 * 17188 * @event Tech#texttrackchange 17189 * @type {EventTarget~Event} 17190 */ 17191 this.trigger('texttrackchange'); 17192 }); 17193 17194 var tracks = this.textTracks(); 17195 17196 if (!tracks) { 17197 return; 17198 } 17199 17200 tracks.addEventListener('removetrack', textTrackListChanges); 17201 tracks.addEventListener('addtrack', textTrackListChanges); 17202 17203 this.on('dispose', Fn.bind(this, function () { 17204 tracks.removeEventListener('removetrack', textTrackListChanges); 17205 tracks.removeEventListener('addtrack', textTrackListChanges); 17206 })); 17207 }; 17208 17209 /** 17210 * Turn on listeners for {@link VideoTrackList} and {@link {AudioTrackList} events. 17211 * This adds {@link EventTarget~EventListeners} for `addtrack`, and `removetrack`. 17212 * 17213 * @fires Tech#audiotrackchange 17214 * @fires Tech#videotrackchange 17215 */ 17216 17217 17218 Tech.prototype.initTrackListeners = function initTrackListeners() { 17219 var _this3 = this; 17220 17221 var trackTypes = ['video', 'audio']; 17222
17223 trackTypes.forEach(function (type) { 17224 /** 17225 * Triggered when tracks are added or removed on the Tech {@link AudioTrackList} 17226 * 17227 * @event Tech#audiotrackchange 17228 * @type {EventTarget~Event} 17229 */ 17230 17231 /** 17232 * Triggered when tracks are added or removed on the Tech {@link VideoTrackList} 17233 * 17234 * @event Tech#videotrackchange 17235 * @type {EventTarget~Event} 17236 */ 17237 var trackListChanges = function trackListChanges() { 17238 _this3.trigger(type + 'trackchange'); 17239 }; 17240 17241 var tracks = _this3[type + 'Tracks'](); 17242 17243 tracks.addEventListener('removetrack', trackListChanges); 17244 tracks.addEventListener('addtrack', trackListChanges); 17245 17246 _this3.on('dispose', function () { 17247 tracks.removeEventListener('removetrack', trackListChanges); 17248 tracks.removeEventListener('addtrack', trackListChanges); 17249 }); 17250 }); 17251 }; 17252 17253 /** 17254 * Emulate TextTracks using vtt.js if necessary 17255 * 17256 * @fires Tech#vttjsloaded 17257 * @fires Tech#vttjserror 17258 */ 17259 17260 17261 Tech.prototype.addWebVttScript_ = function addWebVttScript_() { 17262 var _this4 = this; 17263 17264 if (!_window2['default'].WebVTT && this.el().parentNode !== null && this.el().parentNode !== undefined) { 17265 var _ret = function () { 17266 var vtt = _dereq_(99); 17267 17268 // load via require if available and vtt.js script location was not passed in 17269 // as an option. novtt builds will turn the above require call into an empty object 17270 // which will cause this if check to always fail. 17271 if (!_this4.options_['vtt.js'] && (0, _obj.isPlain)(vtt) && Object.keys(vtt).length > 0) { 17272 Object.keys(vtt).forEach(function (k) { 17273 _window2['default'][k] = vtt[k]; 17274 }); 17275 _this4.trigger('vttjsloaded'); 17276 return { 17277 v: void 0 17278 }; 17279 } 17280 17281 // load vtt.js via the script location option or the cdn of no location was 17282 // passed in 17283 var script = _document2['default'].createElement('script'); 17284 17285 script.src = _this4.options_['vtt.js'] || 'https://cdn.rawgit.com/gkatsev/vtt.js/vjs-v0.12.1/dist/vtt.min.js'; 17286 script.onload = function () { 17287 /** 17288 * Fired when vtt.js is loaded. 17289 * 17290 * @event Tech#vttjsloaded 17291 * @type {EventTarget~Event} 17292 */ 17293 _this4.trigger('vttjsloaded'); 17294 }; 17295 script.onerror = function () { 17296 /** 17297 * Fired when vtt.js was not loaded due to an error 17298 * 17299 * @event Tech#vttjsloaded 17300 * @type {EventTarget~Event} 17301 */ 17302 _this4.trigger('vttjserror'); 17303 }; 17304 _this4.on('dispose', function () { 17305 script.onload = null; 17306 script.onerror = null; 17307 }); 17308 // but have not loaded yet and we set it to true before the inject so that 17309 // we don't overwrite the injected window.WebVTT if it loads right away 17310 _window2['default'].WebVTT = true; 17311 _this4.el().parentNode.appendChild(script); 17312 }(); 17313 17314 if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; 17315 } 17316 }; 17317 17318 /** 17319 * Emulate texttracks 17320 * 17321 * @method emulateTextTracks 17322 */ 17323 17324 17325 Tech.prototype.emulateTextTracks = function emulateTextTracks() { 17326 var _this5 = this; 17327 17328 var tracks = this.textTracks(); 17329 17330 if (!tracks) { 17331 return; 17332 } 17333 17334 var remoteTracks = this.remoteTextTracks(); 17335 var handleAddTrack = function handleAddTrack(e) { 17336 return tracks.addTrack_(e.track); 17337 }; 17338 var handleRemoveTrack = function handleRemoveTrack(e) { 17339 return tracks.removeTrack_(e.track); 17340 }; 17341 17342 remoteTracks.on('addtrack', handleAddTrack); 17343 remoteTracks.on('removetrack', handleRemoveTrack); 17344 17345 // Initially, Tech.el_ is a child of a dummy-div wait until the Component system 17346 // signals that the Tech is ready at which point Tech.el_ is part of the DOM 17347 // before inserting the WebVTT script 17348 this.on('ready', this.addWebVttScript_); 17349 17350 var updateDisplay = function updateDisplay() { 17351 return _this5.trigger('texttrackchange'); 17352 }; 17353 17354 var textTracksChanges = function textTracksChanges() { 17355 updateDisplay(); 17356 17357 for (var i = 0; i < tracks.length; i++) { 17358 var track = tracks[i]; 17359 17360 track.removeEventListener('cuechange', updateDisplay); 17361 if (track.mode === 'showing') { 17362 track.addEventListener('cuechange', updateDisplay); 17363 } 17364 } 17365 }; 17366 17367 textTracksChanges(); 17368 tracks.addEventListener('change', textTracksChanges); 17369 17370 this.on('dispose', function () { 17371 remoteTracks.off('addtrack', handleAddTrack); 17372 remoteTracks.off('removetrack', handleRemoveTrack); 17373 tracks.removeEventListener('change', textTracksChanges); 17374 17375 for (var i = 0; i < tracks.length; i++) { 17376 var track = tracks[i]; 17377 17378 track.removeEventListener('cuechange', updateDisplay); 17379 } 17380 }); 17381 }; 17382 17383 /** 17384 * Get the `Tech`s {@link VideoTrackList}. 17385 * 17386 * @return {VideoTrackList} 17387 * The video track list that the Tech is currently using. 17388 */ 17389 17390 17391 Tech.prototype.videoTracks = function videoTracks() { 17392 this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default'](); 17393 return this.videoTracks_; 17394 }; 17395 17396 /** 17397 * Get the `Tech`s {@link AudioTrackList}. 17398 * 17399 * @return {AudioTrackList} 17400 * The audio track list that the Tech is currently using. 17401 */ 17402 17403 17404 Tech.prototype.audioTracks = function audioTracks() { 17405 this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default'](); 17406 return this.audioTracks_; 17407 }; 17408 17409 /** 17410 * Get the `Tech`s {@link TextTrackList}. 17411 * 17412 * @return {TextTrackList} 17413 * The text track list that the Tech is currently using. 17414 */ 17415 17416 17417 Tech.prototype.textTracks = function textTracks() { 17418 this.textTracks_ = this.textTracks_ || new _textTrackList2['default'](); 17419 return this.textTracks_; 17420 }; 17421 17422 /** 17423 * Get the `Tech`s remote {@link TextTrackList}, which is created from elements 17424 * that were added to the DOM. 17425 * 17426 * @return {TextTrackList} 17427 * The remote text track list that the Tech is currently using. 17428 */ 17429 17430 17431 Tech.prototype.remoteTextTracks = function remoteTextTracks() { 17432 this.remoteTextTracks_ = this.remoteTextTracks_ || new _textTrackList2['default'](); 17433 return this.remoteTextTracks_; 17434 }; 17435 17436 /** 17437 * Get The `Tech`s {HTMLTrackElementList}, which are the elements in the DOM that are 17438 * being used as TextTracks. 17439 * 17440 * @return {HTMLTrackElementList} 17441 * The current HTML track elements that exist for the tech. 17442 */ 17443 17444 17445 Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() { 17446 this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _htmlTrackElementList2['default'](); 17447 return this.remoteTextTrackEls_;
vendor: 5,927 bytes, lines 17448-17653
17448 }; 17449 17450 /** 17451 * Create and returns a remote {@link TextTrack} object. 17452 * 17453 * @param {string} kind 17454 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata) 17455 * 17456 * @param {string} [label] 17457 * Label to identify the text track 17458 * 17459 * @param {string} [language] 17460 * Two letter language abbreviation 17461 * 17462 * @return {TextTrack} 17463 * The TextTrack that gets created. 17464 */ 17465 17466 17467 Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) { 17468 if (!kind) { 17469 throw new Error('TextTrack kind is required but was not provided'); 17470 } 17471 17472 return createTrackHelper(this, kind, label, language); 17473 }; 17474 17475 /** 17476 * Create an emulated TextTrack for use by addRemoteTextTrack 17477 * 17478 * This is intended to be overridden by classes that inherit from 17479 * Tech in order to create native or custom TextTracks. 17480 * 17481 * @param {Object} options 17482 * The object should contain the options to initialize the TextTrack with. 17483 * 17484 * @param {string} [options.kind] 17485 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata). 17486 * 17487 * @param {string} [options.label]. 17488 * Label to identify the text track 17489 * 17490 * @param {string} [options.language] 17491 * Two letter language abbreviation. 17492 * 17493 * @return {HTMLTrackElement} 17494 * The track element that gets created. 17495 */ 17496 17497 17498 Tech.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) { 17499 var track = (0, _mergeOptions2['default'])(options, { 17500 tech: this 17501 }); 17502 17503 return new _htmlTrackElement2['default'](track); 17504 }; 17505 17506 /** 17507 * Creates a remote text track object and returns an html track element. 17508 * 17509 * > Note: This can be an emulated {@link HTMLTrackElement} or a native one. 17510 * 17511 * @param {Object} options 17512 * See {@link Tech#createRemoteTextTrack} for more detailed properties. 17513 * 17514 * @param {boolean} [manualCleanup=true] 17515 * - When false: the TextTrack will be automatically removed from the video 17516 * element whenever the source changes 17517 * - When True: The TextTrack will have to be cleaned up manually 17518 * 17519 * @return {HTMLTrackElement} 17520 * An Html Track Element. 17521 * 17522 * @deprecated The default functionality for this function will be equivalent 17523 * to "manualCleanup=false" in the future. The manualCleanup parameter will 17524 * also be removed. 17525 */ 17526 17527 17528 Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack() { 17529 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 17530 var manualCleanup = arguments[1]; 17531 17532 var htmlTrackElement = this.createRemoteTextTrack(options); 17533 17534 if (manualCleanup !== true && manualCleanup !== false) { 17535 // deprecation warning 17536 _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'); 17537 manualCleanup = true; 17538 } 17539 17540 // store HTMLTrackElement and TextTrack to remote list 17541 this.remoteTextTrackEls().addTrackElement_(htmlTrackElement); 17542 this.remoteTextTracks().addTrack_(htmlTrackElement.track); 17543 17544 if (manualCleanup !== true) { 17545 // create the TextTrackList if it doesn't exist 17546 this.autoRemoteTextTracks_.addTrack_(htmlTrackElement.track); 17547 } 17548 17549 return htmlTrackElement; 17550 }; 17551 17552 /** 17553 * Remove a remote text track from the remote `TextTrackList`. 17554 * 17555 * @param {TextTrack} track 17556 * `TextTrack` to remove from the `TextTrackList` 17557 */ 17558 17559 17560 Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) { 17561 var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track); 17562 17563 // remove HTMLTrackElement and TextTrack from remote list 17564 this.remoteTextTrackEls().removeTrackElement_(trackElement); 17565 this.remoteTextTracks().removeTrack_(track); 17566 this.autoRemoteTextTracks_.removeTrack_(track); 17567 }; 17568 17569 /** 17570 * A method to set a poster from a `Tech`. 17571 * 17572 * @abstract 17573 */ 17574 17575 17576 Tech.prototype.setPoster = function setPoster() {}; 17577 17578 /* 17579 * Check if the tech can support the given mime-type. 17580 * 17581 * The base tech does not support any type, but source handlers might 17582 * overwrite this. 17583 * 17584 * @param {string} type 17585 * The mimetype to check for support 17586 * 17587 * @return {string} 17588 * 'probably', 'maybe', or empty string 17589 * 17590 * @see [Spec]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType} 17591 * 17592 * @abstract 17593 */ 17594 17595 17596 Tech.prototype.canPlayType = function canPlayType() { 17597 return ''; 17598 }; 17599 17600 /* 17601 * Return whether the argument is a Tech or not. 17602 * Can be passed either a Class like `Html5` or a instance like `player.tech_` 17603 * 17604 * @param {Object} component 17605 * The item to check 17606 * 17607 * @return {boolean} 17608 * Whether it is a tech or not 17609 * - True if it is a tech 17610 * - False if it is not 17611 */ 17612 17613 17614 Tech.isTech = function isTech(component) { 17615 return component.prototype instanceof Tech || component instanceof Tech || component === Tech; 17616 }; 17617 17618 /** 17619 * Registers a `Tech` into a shared list for videojs. 17620 * 17621 * @param {string} name 17622 * Name of the `Tech` to register. 17623 * 17624 * @param {Object} tech 17625 * The `Tech` class to register. 17626 */ 17627 17628 17629 Tech.registerTech = function registerTech(name, tech) { 17630 if (!Tech.techs_) { 17631 Tech.techs_ = {}; 17632 } 17633 17634 if (!Tech.isTech(tech)) { 17635 throw new Error('Tech ' + name + ' must be a Tech'); 17636 } 17637 17638 Tech.techs_[name] = tech; 17639 return tech; 17640 }; 17641 17642 /** 17643 * Get a `Tech` from the shared list by name. 17644 * 17645 * @param {string} name 17646 * Name of the component to get 17647 * 17648 * @return {Tech|undefined} 17649 * The `Tech` or undefined if there was no tech with the name requsted. 17650 */ 17651 17652 17653 Tech.getTech = function getTech(name) {
17654 if (Tech.techs_ && Tech.techs_[name]) { 17655 return Tech.techs_[name]; 17656 } 17657 17658 if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) { 17659 _log2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)'); 17660 return _window2['default'].videojs[name]; 17661 } 17662 }; 17663 17664 return Tech; 17665}(_component2['default']); 17666 17667/** 17668 * List of associated text tracks. 17669 * 17670 * @type {TextTrackList} 17671 * @private 17672 */ 17673 17674 17675Tech.prototype.textTracks_; // eslint-disable-line 17676 17677/** 17678 * List of associated audio tracks. 17679 * 17680 * @type {AudioTrackList} 17681 * @private 17682 */ 17683Tech.prototype.audioTracks_; // eslint-disable-line 17684 17685/** 17686 * List of associated video tracks. 17687 * 17688 * @type {VideoTrackList} 17689 * @private 17690 */ 17691Tech.prototype.videoTracks_; // eslint-disable-line 17692 17693/** 17694 * Boolean indicating wether the `Tech` supports volume control. 17695 * 17696 * @type {boolean} 17697 * @default 17698 */ 17699Tech.prototype.featuresVolumeControl = true; 17700 17701/** 17702 * Boolean indicating wether the `Tech` support fullscreen resize control. 17703 * Resizing plugins using request fullscreen reloads the plugin 17704 * 17705 * @type {boolean} 17706 * @default 17707 */ 17708Tech.prototype.featuresFullscreenResize = false; 17709 17710/** 17711 * Boolean indicating wether the `Tech` supports changing the speed at which the video 17712 * plays. Examples: 17713 * - Set player to play 2x (twice) as fast 17714 * - Set player to play 0.5x (half) as fast 17715 * 17716 * @type {boolean} 17717 * @default 17718 */ 17719Tech.prototype.featuresPlaybackRate = false; 17720 17721/** 17722 * Boolean indicating wether the `Tech` supports the `progress` event. This is currently 17723 * not triggered by video-js-swf. This will be used to determine if 17724 * {@link Tech#manualProgressOn} should be called. 17725 * 17726 * @type {boolean} 17727 * @default 17728 */ 17729Tech.prototype.featuresProgressEvents = false; 17730 17731/** 17732 * Boolean indicating wether the `Tech` supports the `timeupdate` event. This is currently 17733 * not triggered by video-js-swf. This will be used to determine if 17734 * {@link Tech#manualTimeUpdates} should be called. 17735 * 17736 * @type {boolean} 17737 * @default 17738 */ 17739Tech.prototype.featuresTimeupdateEvents = false; 17740 17741/** 17742 * Boolean indicating wether the `Tech` supports the native `TextTrack`s. 17743 * This will help us integrate with native `TextTrack`s if the browser supports them. 17744 * 17745 * @type {boolean} 17746 * @default 17747 */ 17748Tech.prototype.featuresNativeTextTracks = false; 17749 17750/** 17751 * A functional mixin for techs that want to use the Source Handler pattern. 17752 * Source handlers are scripts for handling specific formats. 17753 * The source handler pattern is used for adaptive formats (HLS, DASH) that 17754 * manually load video data and feed it into a Source Buffer (Media Source Extensions) 17755 * Example: `Tech.withSourceHandlers.call(MyTech);` 17756 * 17757 * @param {Tech} _Tech 17758 * The tech to add source handler functions to. 17759 * 17760 * @mixes Tech~SourceHandlerAdditions 17761 */ 17762Tech.withSourceHandlers = function (_Tech) { 17763 17764 /** 17765 * Register a source handler 17766 * 17767 * @param {Function} handler 17768 * The source handler class 17769 * 17770 * @param {number} [index] 17771 * Register it at the following index 17772 */ 17773 _Tech.registerSourceHandler = function (handler, index) { 17774 var handlers = _Tech.sourceHandlers; 17775 17776 if (!handlers) { 17777 handlers = _Tech.sourceHandlers = []; 17778 } 17779 17780 if (index === undefined) { 17781 // add to the end of the list 17782 index = handlers.length; 17783 } 17784 17785 handlers.splice(index, 0, handler); 17786 }; 17787 17788 /** 17789 * Check if the tech can support the given type. Also checks the 17790 * Techs sourceHandlers. 17791 * 17792 * @param {string} type 17793 * The mimetype to check. 17794 * 17795 * @return {string} 17796 * 'probably', 'maybe', or '' (empty string) 17797 */ 17798 _Tech.canPlayType = function (type) { 17799 var handlers = _Tech.sourceHandlers || []; 17800 var can = void 0; 17801 17802 for (var i = 0; i < handlers.length; i++) { 17803 can = handlers[i].canPlayType(type); 17804 17805 if (can) { 17806 return can; 17807 } 17808 } 17809 17810 return ''; 17811 }; 17812 17813 /** 17814 * Returns the first source handler that supports the source. 17815 * 17816 * TODO: Answer question: should 'probably' be prioritized over 'maybe' 17817 * 17818 * @param {Tech~SourceObject} source 17819 * The source object 17820 * 17821 * @param {Object} options 17822 * The options passed to the tech 17823 * 17824 * @return {SourceHandler|null} 17825 * The first source handler that supports the source or null if 17826 * no SourceHandler supports the source 17827 */ 17828 _Tech.selectSourceHandler = function (source, options) { 17829 var handlers = _Tech.sourceHandlers || []; 17830 var can = void 0; 17831 17832 for (var i = 0; i < handlers.length; i++) { 17833 can = handlers[i].canHandleSource(source, options); 17834 17835 if (can) { 17836 return handlers[i]; 17837 } 17838 } 17839 17840 return null; 17841 }; 17842 17843 /** 17844 * Check if the tech can support the given source. 17845 * 17846 * @param {Tech~SourceObject} srcObj 17847 * The source object 17848 * 17849 * @param {Object} options 17850 * The options passed to the tech 17851 * 17852 * @return {string} 17853 * 'probably', 'maybe', or '' (empty string) 17854 */ 17855 _Tech.canPlaySource = function (srcObj, options) { 17856 var sh = _Tech.selectSourceHandler(srcObj, options); 17857 17858 if (sh) { 17859 return sh.canHandleSource(srcObj, options); 17860 } 17861 17862 return ''; 17863 }; 17864 17865 /** 17866 * When using a source handler, prefer its implementation of 17867 * any function normally provided by the tech. 17868 */ 17869 var deferrable = ['seekable', 'duration']; 17870 17871 /** 17872 * A wrapper around {@link Tech#seekable} that will call a `SourceHandler`s seekable 17873 * function if it exists, with a fallback to the Techs seekable function. 17874 * 17875 * @method _Tech.seekable 17876 */ 17877 17878 /** 17879 * A wrapper around {@link Tech#duration} that will call a `SourceHandler`s duration 17880 * function if it exists, otherwise it will fallback to the techs duration function. 17881 * 17882 * @method _Tech.duration 17883 */ 17884 17885 deferrable.forEach(function (fnName) { 17886 var originalFn = this[fnName]; 17887 17888 if (typeof originalFn !== 'function') { 17889 return; 17890 } 17891 17892 this[fnName] = function () { 17893 if (this.sourceHandler_ && this.sourceHandler_[fnName]) { 17894 return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments); 17895 } 17896 return originalFn.apply(this, arguments); 17897 }; 17898 }, _Tech.prototype); 17899 17900 /** 17901 * Create a function for setting the source using a source object 17902 * and source handlers. 17903 * Should never be called unless a source handler was found. 17904 * 17905 * @param {Tech~SourceObject} source 17906 * A source object with src and type keys 17907 * 17908 * @return {Tech} 17909 * Returns itself; this method is chainable 17910 */ 17911 _Tech.prototype.setSource = function (source) { 17912 var sh = _Tech.selectSourceHandler(source, this.options_); 17913 17914 if (!sh) { 17915 // Fall back to a native source hander when unsupported sources are 17916 // deliberately set 17917 if (_Tech.nativeSourceHandler) { 17918 sh = _Tech.nativeSourceHandler; 17919 } else { 17920 _log2['default'].error('No source hander found for the current source.'); 17921 } 17922 } 17923 17924 // Dispose any existing source handler 17925 this.disposeSourceHandler(); 17926 this.off('dispose', this.disposeSourceHandler); 17927 17928 if (sh !== _Tech.nativeSourceHandler) { 17929 this.currentSource_ = source; 17930 17931 // Catch if someone replaced the src without calling setSource. 17932 // If they do, set currentSource_ to null and dispose our source handler. 17933 this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_); 17934 this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); 17935 this.one(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_); 17936 } 17937 17938 this.sourceHandler_ = sh.handleSource(source, this, this.options_); 17939 this.on('dispose', this.disposeSourceHandler); 17940 17941 return this; 17942 }; 17943 17944 /** 17945 * Called once for the first loadstart of a video. 17946 * 17947 * @listens Tech#loadstart 17948 */ 17949 _Tech.prototype.firstLoadStartListener_ = function () { 17950 this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); 17951 }; 17952 17953 // On successive loadstarts when setSource has not been called again 17954 /** 17955 * Called after the first loadstart for a video occurs. 17956 * 17957 * @listens Tech#loadstart 17958 */ 17959 _Tech.prototype.successiveLoadStartListener_ = function () { 17960 this.disposeSourceHandler(); 17961 this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); 17962 }; 17963 17964 /** 17965 * Clean up any existing SourceHandlers and listeners when the Tech is disposed. 17966 * 17967 * @listens Tech#dispose 17968 */ 17969 _Tech.prototype.disposeSourceHandler = function () { 17970 // if we have a source and get another one 17971 // then we are loading something new 17972 // than clear all of our current tracks 17973 if (this.currentSource_) { 17974 this.clearTracks(['audio', 'video']); 17975 this.currentSource_ = null; 17976 } 17977 17978 // always clean up auto-text tracks 17979 this.cleanupAutoTextTracks(); 17980 17981 if (this.sourceHandler_) { 17982 this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_); 17983 this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); 17984 17985 if (this.sourceHandler_.dispose) { 17986 this.sourceHandler_.dispose(); 17987 } 17988 17989 this.sourceHandler_ = null; 17990 } 17991 }; 17992}; 17993 17994_component2['default'].registerComponent('Tech', Tech); 17995// Old name for Tech 17996// @deprecated 17997_component2['default'].registerComponent('MediaTechController', Tech);
17998Tech.registerTech('Tech', Tech); 17999exports['default'] = Tech; 18000 18001},{"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,"99":99}],63:[function(_dereq_,module,exports){ 18002'use strict'; 18003 18004exports.__esModule = true; 18005 18006var _trackList = _dereq_(74); 18007 18008var _trackList2 = _interopRequireDefault(_trackList); 18009 18010var _browser = _dereq_(78); 18011 18012var browser = _interopRequireWildcard(_browser); 18013 18014var _document = _dereq_(94); 18015 18016var _document2 = _interopRequireDefault(_document); 18017 18018function _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; } } 18019 18020function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18021 18022function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 18023 18024function _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; } 18025 18026function _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; } /** 18027 * @file audio-track-list.js 18028 */ 18029 18030 18031/** 18032 * Anywhere we call this function we diverge from the spec 18033 * as we only support one enabled audiotrack at a time 18034 * 18035 * @param {AudioTrackList} list 18036 * list to work on 18037 * 18038 * @param {AudioTrack} track 18039 * The track to skip 18040 * 18041 * @private 18042 */ 18043var disableOthers = function disableOthers(list, track) { 18044 for (var i = 0; i < list.length; i++) { 18045 if (track.id === list[i].id) { 18046 continue; 18047 } 18048 // another audio track is enabled, disable it 18049 list[i].enabled = false; 18050 } 18051}; 18052 18053/** 18054 * The current list of {@link AudioTrack} for a media file. 18055 * 18056 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist} 18057 * @extends TrackList 18058 */ 18059 18060var AudioTrackList = function (_TrackList) { 18061 _inherits(AudioTrackList, _TrackList); 18062 18063 /** 18064 * Create an instance of this class. 18065 * 18066 * @param {AudioTrack[]} [tracks=[]] 18067 * A list of `AudioTrack` to instantiate the list with. 18068 */ 18069 function AudioTrackList() { 18070 var _this, _ret; 18071 18072 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 18073 18074 _classCallCheck(this, AudioTrackList); 18075 18076 var list = void 0; 18077 18078 // make sure only 1 track is enabled 18079 // sorted from last index to first index 18080 for (var i = tracks.length - 1; i >= 0; i--) { 18081 if (tracks[i].enabled) { 18082 disableOthers(tracks, tracks[i]); 18083 break; 18084 } 18085 } 18086 18087 // IE8 forces us to implement inheritance ourselves 18088 // as it does not support Object.defineProperty properly 18089 if (browser.IS_IE8) { 18090 list = _document2['default'].createElement('custom'); 18091 for (var prop in _trackList2['default'].prototype) { 18092 if (prop !== 'constructor') { 18093 list[prop] = _trackList2['default'].prototype[prop]; 18094 } 18095 } 18096 for (var _prop in AudioTrackList.prototype) { 18097 if (_prop !== 'constructor') { 18098 list[_prop] = AudioTrackList.prototype[_prop]; 18099 } 18100 } 18101 } 18102
18103 list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this); 18104 list.changing_ = false; 18105 18106 return _ret = list, _possibleConstructorReturn(_this, _ret); 18107 } 18108 18109 /** 18110 * Add an {@link AudioTrack} to the `AudioTrackList`. 18111 * 18112 * @param {AudioTrack} track 18113 * The AudioTrack to add to the list 18114 * 18115 * @fires Track#addtrack 18116 * @private 18117 */ 18118 18119 18120 AudioTrackList.prototype.addTrack_ = function addTrack_(track) { 18121 var _this2 = this; 18122 18123 if (track.enabled) { 18124 disableOthers(this, track); 18125 } 18126 18127 _TrackList.prototype.addTrack_.call(this, track); 18128 // native tracks don't have this 18129 if (!track.addEventListener) { 18130 return; 18131 } 18132 18133 /** 18134 * @listens AudioTrack#enabledchange 18135 * @fires TrackList#change 18136 */ 18137 track.addEventListener('enabledchange', function () { 18138 // when we are disabling other tracks (since we don't support 18139 // more than one track at a time) we will set changing_ 18140 // to true so that we don't trigger additional change events 18141 if (_this2.changing_) { 18142 return; 18143 } 18144 _this2.changing_ = true; 18145 disableOthers(_this2, track); 18146 _this2.changing_ = false; 18147 _this2.trigger('change'); 18148 }); 18149 }; 18150 18151 /** 18152 * Add an {@link AudioTrack} to the `AudioTrackList`. 18153 * 18154 * @param {AudioTrack} track 18155 * The AudioTrack to add to the list 18156 * 18157 * @fires Track#addtrack 18158 */ 18159 18160 18161 AudioTrackList.prototype.addTrack = function addTrack(track) { 18162 this.addTrack_(track); 18163 }; 18164 18165 /** 18166 * Remove an {@link AudioTrack} from the `AudioTrackList`. 18167 * 18168 * @param {AudioTrack} track 18169 * The AudioTrack to remove from the list 18170 * 18171 * @fires Track#removetrack 18172 */ 18173 18174 18175 AudioTrackList.prototype.removeTrack = function removeTrack(track) { 18176 _TrackList.prototype.removeTrack_.call(this, track); 18177 }; 18178 18179 return AudioTrackList; 18180}(_trackList2['default']); 18181 18182exports['default'] = AudioTrackList; 18183 18184},{"74":74,"78":78,"94":94}],64:[function(_dereq_,module,exports){ 18185'use strict'; 18186 18187exports.__esModule = true; 18188 18189var _trackEnums = _dereq_(73); 18190 18191var _track = _dereq_(75); 18192 18193var _track2 = _interopRequireDefault(_track); 18194 18195var _mergeOptions = _dereq_(87); 18196 18197var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 18198 18199var _browser = _dereq_(78); 18200 18201var browser = _interopRequireWildcard(_browser); 18202 18203function _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; } } 18204 18205function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18206 18207function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 18208 18209function _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; } 18210 18211function _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; } 18212 18213/** 18214 * A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList} 18215 * only one `AudioTrack` in the list will be enabled at a time. 18216 * 18217 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack} 18218 * @extends Track 18219 */ 18220var AudioTrack = function (_Track) { 18221 _inherits(AudioTrack, _Track); 18222 18223 /** 18224 * Create an instance of this class. 18225 * 18226 * @param {Object} [options={}] 18227 * Object of option names and values 18228 * 18229 * @param {AudioTrack~Kind} [options.kind=''] 18230 * A valid audio track kind 18231 * 18232 * @param {string} [options.id='vjs_track_' + Guid.newGUID()] 18233 * A unique id for this AudioTrack. 18234 * 18235 * @param {string} [options.label=''] 18236 * The menu label for this track. 18237 * 18238 * @param {string} [options.language=''] 18239 * A valid two character language code. 18240 * 18241 * @param {boolean} [options.enabled] 18242 * If this track is the one that is currently playing. If this track is part of 18243 * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled. 18244 */ 18245 function AudioTrack() { 18246 var _this, _ret; 18247 18248 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 18249 18250 _classCallCheck(this, AudioTrack); 18251 18252 var settings = (0, _mergeOptions2['default'])(options, { 18253 kind: _trackEnums.AudioTrackKind[options.kind] || '' 18254 }); 18255 // on IE8 this will be a document element 18256 // for every other browser this will be a normal object
18257 var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this); 18258 var enabled = false; 18259 18260 if (browser.IS_IE8) { 18261 for (var prop in AudioTrack.prototype) { 18262 if (prop !== 'constructor') { 18263 track[prop] = AudioTrack.prototype[prop]; 18264 } 18265 } 18266 } 18267 /** 18268 * @member {boolean} enabled 18269 * If this `AudioTrack` is enabled or not. When setting this will 18270 * fire {@link AudioTrack#enabledchange} if the state of enabled is changed. 18271 * 18272 * @fires VideoTrack#selectedchange 18273 */ 18274 Object.defineProperty(track, 'enabled', { 18275 get: function get() { 18276 return enabled; 18277 }, 18278 set: function set(newEnabled) { 18279 // an invalid or unchanged value 18280 if (typeof newEnabled !== 'boolean' || newEnabled === enabled) { 18281 return; 18282 } 18283 enabled = newEnabled; 18284 18285 /** 18286 * An event that fires when enabled changes on this track. This allows 18287 * the AudioTrackList that holds this track to act accordingly. 18288 * 18289 * > Note: This is not part of the spec! Native tracks will do 18290 * this internally without an event. 18291 * 18292 * @event AudioTrack#enabledchange 18293 * @type {EventTarget~Event} 18294 */ 18295 this.trigger('enabledchange'); 18296 } 18297 }); 18298 18299 // if the user sets this track to selected then 18300 // set selected to that true value otherwise 18301 // we keep it false 18302 if (settings.enabled) { 18303 track.enabled = settings.enabled; 18304 } 18305 track.loaded_ = true; 18306 18307 return _ret = track, _possibleConstructorReturn(_this, _ret); 18308 } 18309 18310 return AudioTrack; 18311}(_track2['default']); 18312 18313exports['default'] = AudioTrack; 18314 18315},{"73":73,"75":75,"78":78,"87":87}],65:[function(_dereq_,module,exports){ 18316'use strict'; 18317 18318exports.__esModule = true; 18319 18320var _browser = _dereq_(78); 18321 18322var browser = _interopRequireWildcard(_browser); 18323 18324var _document = _dereq_(94); 18325 18326var _document2 = _interopRequireDefault(_document); 18327 18328function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18329 18330function _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; } } 18331 18332function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** 18333 * @file html-track-element-list.js 18334 */ 18335 18336/** 18337 * The current list of {@link HtmlTrackElement}s. 18338 */ 18339var HtmlTrackElementList = function () { 18340 18341 /** 18342 * Create an instance of this class. 18343 * 18344 * @param {HtmlTrackElement[]} [tracks=[]] 18345 * A list of `HtmlTrackElement` to instantiate the list with. 18346 */ 18347 function HtmlTrackElementList() { 18348 var trackElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 18349 18350 _classCallCheck(this, HtmlTrackElementList); 18351 18352 var list = this; // eslint-disable-line 18353 18354 if (browser.IS_IE8) { 18355 list = _document2['default'].createElement('custom'); 18356 18357 for (var prop in HtmlTrackElementList.prototype) { 18358 if (prop !== 'constructor') { 18359 list[prop] = HtmlTrackElementList.prototype[prop]; 18360 } 18361 } 18362 } 18363 18364 list.trackElements_ = []; 18365 18366 /** 18367 * @member {number} length 18368 * The current number of `Track`s in the this Trackist. 18369 */ 18370 Object.defineProperty(list, 'length', { 18371 get: function get() { 18372 return this.trackElements_.length; 18373 } 18374 }); 18375 18376 for (var i = 0, length = trackElements.length; i < length; i++) { 18377 list.addTrackElement_(trackElements[i]); 18378 } 18379 18380 if (browser.IS_IE8) { 18381 return list; 18382 } 18383 } 18384 18385 /** 18386 * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList` 18387 * 18388 * @param {HtmlTrackElement} trackElement 18389 * The track element to add to the list. 18390 * 18391 * @private 18392 */ 18393 18394 18395 HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) { 18396 var index = this.trackElements_.length; 18397 18398 if (!('' + index in this)) { 18399 Object.defineProperty(this, index, { 18400 get: function get() { 18401 return this.trackElements_[index]; 18402 } 18403 }); 18404 } 18405
18406 // Do not add duplicate elements 18407 if (this.trackElements_.indexOf(trackElement) === -1) { 18408 this.trackElements_.push(trackElement); 18409 } 18410 }; 18411 18412 /** 18413 * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an 18414 * {@link TextTrack}. 18415 * 18416 * @param {TextTrack} track 18417 * The track associated with a track element. 18418 * 18419 * @return {HtmlTrackElement|undefined} 18420 * The track element that was found or undefined. 18421 * 18422 * @private 18423 */ 18424 18425 18426 HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) { 18427 var trackElement_ = void 0; 18428 18429 for (var i = 0, length = this.trackElements_.length; i < length; i++) { 18430 if (track === this.trackElements_[i].track) { 18431 trackElement_ = this.trackElements_[i]; 18432 18433 break; 18434 } 18435 } 18436 18437 return trackElement_; 18438 }; 18439 18440 /** 18441 * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList` 18442 * 18443 * @param {HtmlTrackElement} trackElement 18444 * The track element to remove from the list. 18445 * 18446 * @private 18447 */ 18448 18449 18450 HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) { 18451 for (var i = 0, length = this.trackElements_.length; i < length; i++) { 18452 if (trackElement === this.trackElements_[i]) { 18453 this.trackElements_.splice(i, 1); 18454 18455 break; 18456 } 18457 } 18458 }; 18459 18460 return HtmlTrackElementList; 18461}(); 18462 18463exports['default'] = HtmlTrackElementList; 18464 18465},{"78":78,"94":94}],66:[function(_dereq_,module,exports){ 18466'use strict'; 18467 18468exports.__esModule = true; 18469 18470var _browser = _dereq_(78); 18471 18472var browser = _interopRequireWildcard(_browser); 18473 18474var _document = _dereq_(94); 18475 18476var _document2 = _interopRequireDefault(_document); 18477 18478var _eventTarget = _dereq_(42); 18479 18480var _eventTarget2 = _interopRequireDefault(_eventTarget); 18481 18482var _textTrack = _dereq_(72); 18483 18484var _textTrack2 = _interopRequireDefault(_textTrack); 18485 18486function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18487 18488function _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; } } 18489 18490function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 18491 18492function _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; } 18493 18494function _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; } /** 18495 * @file html-track-element.js 18496 */ 18497 18498/** 18499 * @typedef {HTMLTrackElement~ReadyState} 18500 * @enum {number} 18501 */ 18502var NONE = 0; 18503var LOADING = 1; 18504var LOADED = 2; 18505var ERROR = 3; 18506 18507/** 18508 * A single track represented in the DOM. 18509 * 18510 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement}
18511 * @extends EventTarget 18512 */ 18513 18514var HTMLTrackElement = function (_EventTarget) { 18515 _inherits(HTMLTrackElement, _EventTarget); 18516 18517 /** 18518 * Create an instance of this class. 18519 * 18520 * @param {Object} options={} 18521 * Object of option names and values 18522 * 18523 * @param {Tech} options.tech 18524 * A reference to the tech that owns this HTMLTrackElement. 18525 * 18526 * @param {TextTrack~Kind} [options.kind='subtitles'] 18527 * A valid text track kind. 18528 * 18529 * @param {TextTrack~Mode} [options.mode='disabled'] 18530 * A valid text track mode. 18531 * 18532 * @param {string} [options.id='vjs_track_' + Guid.newGUID()] 18533 * A unique id for this TextTrack. 18534 * 18535 * @param {string} [options.label=''] 18536 * The menu label for this track. 18537 * 18538 * @param {string} [options.language=''] 18539 * A valid two character language code. 18540 * 18541 * @param {string} [options.srclang=''] 18542 * A valid two character language code. An alternative, but deprioritized 18543 * vesion of `options.language` 18544 * 18545 * @param {string} [options.src] 18546 * A url to TextTrack cues. 18547 * 18548 * @param {boolean} [options.default] 18549 * If this track should default to on or off. 18550 */ 18551 function HTMLTrackElement() { 18552 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 18553 18554 _classCallCheck(this, HTMLTrackElement); 18555 18556 var _this = _possibleConstructorReturn(this, _EventTarget.call(this)); 18557 18558 var readyState = void 0; 18559 var trackElement = _this; // eslint-disable-line 18560 18561 if (browser.IS_IE8) { 18562 trackElement = _document2['default'].createElement('custom'); 18563 18564 for (var prop in HTMLTrackElement.prototype) { 18565 if (prop !== 'constructor') { 18566 trackElement[prop] = HTMLTrackElement.prototype[prop]; 18567 } 18568 } 18569 } 18570 18571 var track = new _textTrack2['default'](options); 18572 18573 trackElement.kind = track.kind; 18574 trackElement.src = track.src; 18575 trackElement.srclang = track.language; 18576 trackElement.label = track.label; 18577 trackElement['default'] = track['default']; 18578 18579 /** 18580 * @member {HTMLTrackElement~ReadyState} readyState 18581 * The current ready state of the track element. 18582 */ 18583 Object.defineProperty(trackElement, 'readyState', { 18584 get: function get() { 18585 return readyState; 18586 } 18587 }); 18588 18589 /** 18590 * @member {TextTrack} track 18591 * The underlying TextTrack object. 18592 */ 18593 Object.defineProperty(trackElement, 'track', { 18594 get: function get() { 18595 return track; 18596 } 18597 }); 18598 18599 readyState = NONE; 18600 18601 /** 18602 * @listens TextTrack#loadeddata 18603 * @fires HTMLTrackElement#load 18604 */ 18605 track.addEventListener('loadeddata', function () { 18606 readyState = LOADED; 18607 18608 trackElement.trigger({ 18609 type: 'load', 18610 target: trackElement 18611 }); 18612 }); 18613 18614 if (browser.IS_IE8) { 18615 var _ret; 18616 18617 return _ret = trackElement, _possibleConstructorReturn(_this, _ret); 18618 } 18619 return _this; 18620 } 18621 18622 return HTMLTrackElement; 18623}(_eventTarget2['default']); 18624 18625HTMLTrackElement.prototype.allowedEvents_ = { 18626 load: 'load' 18627}; 18628 18629HTMLTrackElement.NONE = NONE; 18630HTMLTrackElement.LOADING = LOADING; 18631HTMLTrackElement.LOADED = LOADED; 18632HTMLTrackElement.ERROR = ERROR; 18633 18634exports['default'] = HTMLTrackElement; 18635 18636},{"42":42,"72":72,"78":78,"94":94}],67:[function(_dereq_,module,exports){ 18637'use strict'; 18638 18639exports.__esModule = true; 18640 18641var _browser = _dereq_(78); 18642 18643var browser = _interopRequireWildcard(_browser); 18644 18645var _document = _dereq_(94); 18646 18647var _document2 = _interopRequireDefault(_document); 18648 18649function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18650 18651function _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; } } 18652 18653function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** 18654 * @file text-track-cue-list.js 18655 */ 18656 18657 18658/** 18659 * @typedef {Object} TextTrackCue 18660 * 18661 * @property {string} id 18662 * The unique id for this text track cue 18663 * 18664 * @property {number} startTime 18665 * The start time for this text track cue 18666 * 18667 * @property {number} endTime 18668 * The end time for this text track cue 18669 * 18670 * @property {boolean} pauseOnExit 18671 * Pause when the end time is reached if true. 18672 * 18673 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue} 18674 */ 18675 18676/** 18677 * A List of TextTrackCues. 18678 * 18679 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist} 18680 */ 18681var TextTrackCueList = function () { 18682 18683 /** 18684 * Create an instance of this class.. 18685 * 18686 * @param {Array} cues 18687 * A list of cues to be initialized with 18688 */ 18689 function TextTrackCueList(cues) { 18690 _classCallCheck(this, TextTrackCueList); 18691 18692 var list = this; // eslint-disable-line 18693 18694 if (browser.IS_IE8) { 18695 list = _document2['default'].createElement('custom'); 18696 18697 for (var prop in TextTrackCueList.prototype) { 18698 if (prop !== 'constructor') { 18699 list[prop] = TextTrackCueList.prototype[prop]; 18700 } 18701 } 18702 } 18703 18704 TextTrackCueList.prototype.setCues_.call(list, cues); 18705 18706 /** 18707 * @member {number} length 18708 * The current number of `TextTrackCue`s in the TextTrackCueList. 18709 */ 18710 Object.defineProperty(list, 'length', { 18711 get: function get() { 18712 return this.length_; 18713 } 18714 }); 18715 18716 if (browser.IS_IE8) { 18717 return list; 18718 } 18719 } 18720 18721 /** 18722 * A setter for cues in this list. Creates getters 18723 * an an index for the cues. 18724 * 18725 * @param {Array} cues 18726 * An array of cues to set 18727 * 18728 * @private 18729 */ 18730 18731 18732 TextTrackCueList.prototype.setCues_ = function setCues_(cues) { 18733 var oldLength = this.length || 0; 18734 var i = 0; 18735 var l = cues.length; 18736 18737 this.cues_ = cues; 18738 this.length_ = cues.length; 18739 18740 var defineProp = function defineProp(index) { 18741 if (!('' + index in this)) { 18742 Object.defineProperty(this, '' + index, { 18743 get: function get() { 18744 return this.cues_[index]; 18745 } 18746 }); 18747 } 18748 }; 18749 18750 if (oldLength < l) { 18751 i = oldLength; 18752 18753 for (; i < l; i++) { 18754 defineProp.call(this, i); 18755 } 18756 } 18757 }; 18758 18759 /** 18760 * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id. 18761 * 18762 * @param {string} id 18763 * The id of the cue that should be searched for. 18764 * 18765 * @return {TextTrackCue|null} 18766 * A single cue or null if none was found. 18767 */ 18768 18769 18770 TextTrackCueList.prototype.getCueById = function getCueById(id) { 18771 var result = null; 18772 18773 for (var i = 0, l = this.length; i < l; i++) { 18774 var cue = this[i]; 18775 18776 if (cue.id === id) { 18777 result = cue; 18778 break; 18779 } 18780 } 18781 18782 return result; 18783 }; 18784 18785 return TextTrackCueList; 18786}(); 18787 18788exports['default'] = TextTrackCueList; 18789 18790},{"78":78,"94":94}],68:[function(_dereq_,module,exports){ 18791'use strict'; 18792 18793exports.__esModule = true; 18794 18795var _component = _dereq_(5); 18796 18797var _component2 = _interopRequireDefault(_component); 18798 18799var _fn = _dereq_(83); 18800 18801var Fn = _interopRequireWildcard(_fn); 18802 18803var _window = _dereq_(95); 18804 18805var _window2 = _interopRequireDefault(_window); 18806 18807function _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; } } 18808 18809function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18810 18811function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 18812 18813function _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; } 18814 18815function _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: 6,058 bytes, lines 18815-18986
18815onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 18816 * @file text-track-display.js 18817 */ 18818 18819 18820var darkGray = '#222'; 18821var lightGray = '#ccc'; 18822var fontMap = { 18823 monospace: 'monospace', 18824 sansSerif: 'sans-serif', 18825 serif: 'serif', 18826 monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace', 18827 monospaceSerif: '"Courier New", monospace', 18828 proportionalSansSerif: 'sans-serif', 18829 proportionalSerif: 'serif', 18830 casual: '"Comic Sans MS", Impact, fantasy', 18831 script: '"Monotype Corsiva", cursive', 18832 smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif' 18833}; 18834 18835/** 18836 * Construct an rgba color from a given hex color code. 18837 * 18838 * @param {number} color 18839 * Hex number for color, like #f0e. 18840 * 18841 * @param {number} opacity 18842 * Value for opacity, 0.0 - 1.0. 18843 * 18844 * @return {string} 18845 * The rgba color that was created, like 'rgba(255, 0, 0, 0.3)'. 18846 * 18847 * @private 18848 */ 18849function constructColor(color, opacity) { 18850 return 'rgba(' + 18851 // color looks like "#f0e" 18852 parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')'; 18853} 18854 18855/** 18856 * Try to update the style of a DOM element. Some style changes will throw an error, 18857 * particularly in IE8. Those should be noops. 18858 * 18859 * @param {Element} el 18860 * The DOM element to be styled. 18861 * 18862 * @param {string} style 18863 * The CSS property on the element that should be styled. 18864 * 18865 * @param {string} rule 18866 * The style rule that should be applied to the property. 18867 */ 18868function tryUpdateStyle(el, style, rule) { 18869 try { 18870 el.style[style] = rule; 18871 } catch (e) { 18872 18873 // Satisfies linter. 18874 return; 18875 } 18876} 18877 18878/** 18879 * The component for displaying text track cues. 18880 * 18881 * @extends Component 18882 */ 18883 18884var TextTrackDisplay = function (_Component) { 18885 _inherits(TextTrackDisplay, _Component); 18886 18887 /** 18888 * Creates an instance of this class. 18889 * 18890 * @param {Player} player 18891 * The `Player` that this class should be attached to. 18892 * 18893 * @param {Object} [options] 18894 * The key/value store of player options. 18895 * 18896 * @param {Component~ReadyCallback} [ready] 18897 * The function to call when `TextTrackDisplay` is ready. 18898 */ 18899 function TextTrackDisplay(player, options, ready) { 18900 _classCallCheck(this, TextTrackDisplay); 18901 18902 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready)); 18903 18904 player.on('loadstart', Fn.bind(_this, _this.toggleDisplay)); 18905 player.on('texttrackchange', Fn.bind(_this, _this.updateDisplay)); 18906 18907 // This used to be called during player init, but was causing an error 18908 // if a track should show by default and the display hadn't loaded yet. 18909 // Should probably be moved to an external track loader when we support 18910 // tracks that don't need a display. 18911 player.ready(Fn.bind(_this, function () { 18912 if (player.tech_ && player.tech_.featuresNativeTextTracks) { 18913 this.hide(); 18914 return; 18915 } 18916 18917 player.on('fullscreenchange', Fn.bind(this, this.updateDisplay)); 18918 18919 var tracks = this.options_.playerOptions.tracks || []; 18920 18921 for (var i = 0; i < tracks.length; i++) { 18922 this.player_.addRemoteTextTrack(tracks[i], true); 18923 } 18924 18925 var modes = { captions: 1, subtitles: 1 }; 18926 var trackList = this.player_.textTracks(); 18927 var firstDesc = void 0; 18928 var firstCaptions = void 0; 18929 18930 if (trackList) { 18931 for (var _i = 0; _i < trackList.length; _i++) { 18932 var track = trackList[_i]; 18933 18934 if (track['default']) { 18935 if (track.kind === 'descriptions' && !firstDesc) { 18936 firstDesc = track; 18937 } else if (track.kind in modes && !firstCaptions) { 18938 firstCaptions = track; 18939 } 18940 } 18941 } 18942 18943 // We want to show the first default track but captions and subtitles 18944 // take precedence over descriptions. 18945 // So, display the first default captions or subtitles track 18946 // and otherwise the first default descriptions track. 18947 if (firstCaptions) { 18948 firstCaptions.mode = 'showing'; 18949 } else if (firstDesc) { 18950 firstDesc.mode = 'showing'; 18951 } 18952 } 18953 })); 18954 return _this; 18955 } 18956 18957 /** 18958 * Turn display of {@link TextTrack}'s from the current state into the other state. 18959 * There are only two states: 18960 * - 'shown' 18961 * - 'hidden' 18962 * 18963 * @listens Player#loadstart 18964 */ 18965 18966 18967 TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() { 18968 if (this.player_.tech_ && this.player_.tech_.featuresNativeTextTracks) { 18969 this.hide(); 18970 } else { 18971 this.show(); 18972 } 18973 }; 18974 18975 /** 18976 * Create the {@link Component}'s DOM element. 18977 * 18978 * @return {Element} 18979 * The element that was created. 18980 */ 18981 18982 18983 TextTrackDisplay.prototype.createEl = function createEl() { 18984 return _Component.prototype.createEl.call(this, 'div', { 18985 className: 'vjs-text-track-display' 18986 }, {
18987 'aria-live': 'off', 18988 'aria-atomic': 'true' 18989 }); 18990 }; 18991 18992 /** 18993 * Clear all displayed {@link TextTrack}s. 18994 */ 18995 18996 18997 TextTrackDisplay.prototype.clearDisplay = function clearDisplay() { 18998 if (typeof _window2['default'].WebVTT === 'function') { 18999 _window2['default'].WebVTT.processCues(_window2['default'], [], this.el_); 19000 } 19001 }; 19002 19003 /** 19004 * Update the displayed TextTrack when a either a {@link Player#texttrackchange} or 19005 * a {@link Player#fullscreenchange} is fired. 19006 * 19007 * @listens Player#texttrackchange 19008 * @listens Player#fullscreenchange 19009 */ 19010 19011 19012 TextTrackDisplay.prototype.updateDisplay = function updateDisplay() { 19013 var tracks = this.player_.textTracks(); 19014 19015 this.clearDisplay(); 19016 19017 if (!tracks) { 19018 return; 19019 } 19020 19021 // Track display prioritization model: if multiple tracks are 'showing', 19022 // display the first 'subtitles' or 'captions' track which is 'showing', 19023 // otherwise display the first 'descriptions' track which is 'showing' 19024 19025 var descriptionsTrack = null; 19026 var captionsSubtitlesTrack = null; 19027 19028 var i = tracks.length; 19029 19030 while (i--) { 19031 var track = tracks[i]; 19032 19033 if (track.mode === 'showing') { 19034 if (track.kind === 'descriptions') { 19035 descriptionsTrack = track; 19036 } else { 19037 captionsSubtitlesTrack = track; 19038 } 19039 } 19040 } 19041 19042 if (captionsSubtitlesTrack) { 19043 if (this.getAttribute('aria-live') !== 'off') { 19044 this.setAttribute('aria-live', 'off'); 19045 } 19046 this.updateForTrack(captionsSubtitlesTrack); 19047 } else if (descriptionsTrack) { 19048 if (this.getAttribute('aria-live') !== 'assertive') { 19049 this.setAttribute('aria-live', 'assertive'); 19050 } 19051 this.updateForTrack(descriptionsTrack); 19052 } 19053 }; 19054 19055 /** 19056 * Add an {@link Texttrack} to to the {@link Tech}s {@link TextTrackList}. 19057 * 19058 * @param {TextTrack} track 19059 * Text track object to be added to the list. 19060 */ 19061 19062 19063 TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) { 19064 if (typeof _window2['default'].WebVTT !== 'function' || !track.activeCues) { 19065 return; 19066 } 19067 19068 var overrides = this.player_.textTrackSettings.getValues(); 19069 var cues = []; 19070 19071 for (var _i2 = 0; _i2 < track.activeCues.length; _i2++) { 19072 cues.push(track.activeCues[_i2]); 19073 } 19074 19075 _window2['default'].WebVTT.processCues(_window2['default'], cues, this.el_); 19076 19077 var i = cues.length; 19078 19079 while (i--) { 19080 var cue = cues[i]; 19081 19082 if (!cue) { 19083 continue; 19084 } 19085 19086 var cueDiv = cue.displayState; 19087 19088 if (overrides.color) { 19089 cueDiv.firstChild.style.color = overrides.color; 19090 } 19091 if (overrides.textOpacity) { 19092 tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity)); 19093 } 19094 if (overrides.backgroundColor) { 19095 cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor; 19096 } 19097 if (overrides.backgroundOpacity) { 19098 tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity)); 19099 } 19100 if (overrides.windowColor) { 19101 if (overrides.windowOpacity) { 19102 tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity)); 19103 } else { 19104 cueDiv.style.backgroundColor = overrides.windowColor; 19105 } 19106 } 19107 if (overrides.edgeStyle) { 19108 if (overrides.edgeStyle === 'dropshadow') { 19109 cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray; 19110 } else if (overrides.edgeStyle === 'raised') { 19111 cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray; 19112 } else if (overrides.edgeStyle === 'depressed') { 19113 cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray; 19114 } else if (overrides.edgeStyle === 'uniform') { 19115 cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray; 19116 } 19117 } 19118 if (overrides.fontPercent && overrides.fontPercent !== 1) { 19119 var fontSize = _window2['default'].parseFloat(cueDiv.style.fontSize); 19120 19121 cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px'; 19122 cueDiv.style.height = 'auto'; 19123 cueDiv.style.top = 'auto'; 19124 cueDiv.style.bottom = '2px'; 19125 } 19126 if (overrides.fontFamily && overrides.fontFamily !== 'default') { 19127 if (overrides.fontFamily === 'small-caps') { 19128 cueDiv.firstChild.style.fontVariant = 'small-caps'; 19129 } else { 19130 cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily]; 19131 } 19132 } 19133 } 19134 }; 19135 19136 return TextTrackDisplay; 19137}(_component2['default']); 19138 19139_component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay); 19140exports['default'] = TextTrackDisplay; 19141 19142},{"5":5,"83":83,"95":95}],69:[function(_dereq_,module,exports){ 19143'use strict'; 19144 19145exports.__esModule = true; 19146/** 19147 * @file text-track-list-converter.js Utilities for capturing text track state and 19148 * re-creating tracks based on a capture. 19149 * 19150 * @module text-track-list-converter 19151 */ 19152 19153/**
19154 * Examine a single {@link TextTrack} and return a JSON-compatible javascript object that 19155 * represents the {@link TextTrack}'s state. 19156 * 19157 * @param {TextTrack} track 19158 * The text track to query. 19159 * 19160 * @return {Object} 19161 * A serializable javascript representation of the TextTrack. 19162 * @private 19163 */ 19164var trackToJson_ = function trackToJson_(track) { 19165 var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) { 19166 19167 if (track[prop]) { 19168 acc[prop] = track[prop]; 19169 } 19170 19171 return acc; 19172 }, { 19173 cues: track.cues && Array.prototype.map.call(track.cues, function (cue) { 19174 return { 19175 startTime: cue.startTime, 19176 endTime: cue.endTime, 19177 text: cue.text, 19178 id: cue.id 19179 }; 19180 }) 19181 }); 19182 19183 return ret; 19184}; 19185 19186/** 19187 * Examine a {@link Tech} and return a JSON-compatible javascript array that represents the 19188 * state of all {@link TextTrack}s currently configured. The return array is compatible with 19189 * {@link text-track-list-converter:jsonToTextTracks}. 19190 * 19191 * @param {Tech} tech 19192 * The tech object to query 19193 * 19194 * @return {Array} 19195 * A serializable javascript representation of the {@link Tech}s 19196 * {@link TextTrackList}. 19197 */ 19198var textTracksToJson = function textTracksToJson(tech) { 19199 19200 var trackEls = tech.$$('track'); 19201 19202 var trackObjs = Array.prototype.map.call(trackEls, function (t) { 19203 return t.track; 19204 }); 19205 var tracks = Array.prototype.map.call(trackEls, function (trackEl) { 19206 var json = trackToJson_(trackEl.track); 19207 19208 if (trackEl.src) { 19209 json.src = trackEl.src; 19210 } 19211 return json; 19212 }); 19213 19214 return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) { 19215 return trackObjs.indexOf(track) === -1; 19216 }).map(trackToJson_)); 19217}; 19218 19219/** 19220 * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript 19221 * object {@link TextTrack} representations. 19222 * 19223 * @param {Array} json 19224 * An array of `TextTrack` representation objects, like those that would be 19225 * produced by `textTracksToJson`. 19226 * 19227 * @param {Tech} tech 19228 * The `Tech` to create the `TextTrack`s on. 19229 */ 19230var jsonToTextTracks = function jsonToTextTracks(json, tech) { 19231 json.forEach(function (track) { 19232 var addedTrack = tech.addRemoteTextTrack(track).track; 19233 19234 if (!track.src && track.cues) { 19235 track.cues.forEach(function (cue) { 19236 return addedTrack.addCue(cue); 19237 }); 19238 } 19239 }); 19240 19241 return tech.textTracks(); 19242}; 19243 19244exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ }; 19245 19246},{}],70:[function(_dereq_,module,exports){ 19247'use strict'; 19248 19249exports.__esModule = true; 19250 19251var _trackList = _dereq_(74); 19252 19253var _trackList2 = _interopRequireDefault(_trackList); 19254 19255var _fn = _dereq_(83); 19256 19257var Fn = _interopRequireWildcard(_fn); 19258 19259var _browser = _dereq_(78); 19260 19261var browser = _interopRequireWildcard(_browser); 19262 19263var _document = _dereq_(94); 19264 19265var _document2 = _interopRequireDefault(_document); 19266 19267function _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; } } 19268 19269function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19270 19271function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 19272 19273function _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; } 19274 19275function _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; } /** 19276 * @file text-track-list.js 19277 */ 19278 19279 19280/** 19281 * The current list of {@link TextTrack} for a media file. 19282 * 19283 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist} 19284 * @extends TrackList 19285 */ 19286var TextTrackList = function (_TrackList) { 19287 _inherits(TextTrackList, _TrackList); 19288 19289 /** 19290 * Create an instance of this class. 19291 * 19292 * @param {TextTrack[]} [tracks=[]] 19293 * A list of `TextTrack` to instantiate the list with. 19294 */ 19295 function TextTrackList() { 19296 var _this, _ret; 19297 19298 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 19299 19300 _classCallCheck(this, TextTrackList); 19301 19302 var list = void 0; 19303 19304 // IE8 forces us to implement inheritance ourselves 19305 // as it does not support Object.defineProperty properly 19306 if (browser.IS_IE8) { 19307 list = _document2['default'].createElement('custom'); 19308 for (var prop in _trackList2['default'].prototype) { 19309 if (prop !== 'constructor') { 19310 list[prop] = _trackList2['default'].prototype[prop]; 19311 } 19312 } 19313 for (var _prop in TextTrackList.prototype) { 19314 if (_prop !== 'constructor') { 19315 list[_prop] = TextTrackList.prototype[_prop]; 19316 } 19317 } 19318 } 19319
19320 list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this); 19321 return _ret = list, _possibleConstructorReturn(_this, _ret); 19322 } 19323 19324 /** 19325 * Add a {@link TextTrack} to the `TextTrackList` 19326 * 19327 * @param {TextTrack} track 19328 * The text track to add to the list. 19329 * 19330 * @fires TrackList#addtrack 19331 * @private 19332 */ 19333 19334 19335 TextTrackList.prototype.addTrack_ = function addTrack_(track) { 19336 _TrackList.prototype.addTrack_.call(this, track); 19337 19338 /** 19339 * @listens TextTrack#modechange 19340 * @fires TrackList#change 19341 */ 19342 track.addEventListener('modechange', Fn.bind(this, function () { 19343 this.trigger('change'); 19344 })); 19345 }; 19346 19347 return TextTrackList; 19348}(_trackList2['default']); 19349 19350exports['default'] = TextTrackList; 19351 19352},{"74":74,"78":78,"83":83,"94":94}],71:[function(_dereq_,module,exports){ 19353'use strict'; 19354 19355exports.__esModule = true; 19356 19357var _window = _dereq_(95); 19358 19359var _window2 = _interopRequireDefault(_window); 19360 19361var _component = _dereq_(5); 19362 19363var _component2 = _interopRequireDefault(_component); 19364 19365var _dom = _dereq_(81); 19366 19367var _fn = _dereq_(83); 19368 19369var Fn = _interopRequireWildcard(_fn); 19370 19371var _obj = _dereq_(88); 19372 19373var Obj = _interopRequireWildcard(_obj); 19374 19375var _log = _dereq_(86); 19376 19377var _log2 = _interopRequireDefault(_log); 19378 19379function _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; } } 19380 19381function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19382 19383function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 19384 19385function _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; } 19386 19387function _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; } /** 19388 * @file text-track-settings.js 19389 */ 19390 19391 19392var LOCAL_STORAGE_KEY = 'vjs-text-track-settings'; 19393 19394var COLOR_BLACK = ['#000', 'Black']; 19395var COLOR_BLUE = ['#00F', 'Blue']; 19396var COLOR_CYAN = ['#0FF', 'Cyan']; 19397var COLOR_GREEN = ['#0F0', 'Green']; 19398var COLOR_MAGENTA = ['#F0F', 'Magenta']; 19399var COLOR_RED = ['#F00', 'Red']; 19400var COLOR_WHITE = ['#FFF', 'White']; 19401var COLOR_YELLOW = ['#FF0', 'Yellow']; 19402 19403var OPACITY_OPAQUE = ['1', 'Opaque']; 19404var OPACITY_SEMI = ['0.5', 'Semi-Transparent']; 19405var OPACITY_TRANS = ['0', 'Transparent']; 19406 19407// Configuration for the various <select> elements in the DOM of this component. 19408// 19409// Possible keys include: 19410// 19411// `default`: 19412// The default option index. Only needs to be provided if not zero. 19413// `parser`: 19414// A function which is used to parse the value from the selected option in 19415// a customized way. 19416// `selector`: 19417// The selector used to find the associated <select> element. 19418var selectConfigs = { 19419 backgroundColor: { 19420 selector: '.vjs-bg-color > select', 19421 id: 'captions-background-color-%s', 19422 label: 'Color', 19423 options: [COLOR_BLACK, COLOR_WHITE, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN] 19424 }, 19425 19426 backgroundOpacity: { 19427 selector: '.vjs-bg-opacity > select', 19428 id: 'captions-background-opacity-%s', 19429 label: 'Transparency', 19430 options: [OPACITY_OPAQUE, OPACITY_SEMI, OPACITY_TRANS] 19431 }, 19432 19433 color: { 19434 selector: '.vjs-fg-color > select', 19435 id: 'captions-foreground-color-%s', 19436 label: 'Color', 19437 options: [COLOR_WHITE, COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN] 19438 }, 19439 19440 edgeStyle: { 19441 selector: '.vjs-edge-style > select', 19442 id: '%s', 19443 label: 'Text Edge Style', 19444 options: [['none', 'None'], ['raised', 'Raised'], ['depressed', 'Depressed'], ['uniform', 'Uniform'], ['dropshadow', 'Dropshadow']] 19445 }, 19446 19447 fontFamily: { 19448 selector: '.vjs-font-family > select', 19449 id: 'captions-font-family-%s', 19450 label: 'Font Family', 19451 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 19451-19640
19451Small Caps']] 19452 }, 19453 19454 fontPercent: { 19455 selector: '.vjs-font-percent > select', 19456 id: 'captions-font-size-%s', 19457 label: 'Font Size', 19458 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%']], 19459 'default': 2, 19460 parser: function parser(v) { 19461 return v === '1.00' ? null : Number(v); 19462 } 19463 }, 19464 19465 textOpacity: { 19466 selector: '.vjs-text-opacity > select', 19467 id: 'captions-foreground-opacity-%s', 19468 label: 'Transparency', 19469 options: [OPACITY_OPAQUE, OPACITY_SEMI] 19470 }, 19471 19472 // Options for this object are defined below. 19473 windowColor: { 19474 selector: '.vjs-window-color > select', 19475 id: 'captions-window-color-%s', 19476 label: 'Color' 19477 }, 19478 19479 // Options for this object are defined below. 19480 windowOpacity: { 19481 selector: '.vjs-window-opacity > select', 19482 id: 'captions-window-opacity-%s', 19483 label: 'Transparency', 19484 options: [OPACITY_TRANS, OPACITY_SEMI, OPACITY_OPAQUE] 19485 } 19486}; 19487 19488selectConfigs.windowColor.options = selectConfigs.backgroundColor.options; 19489 19490/** 19491 * Get the actual value of an option. 19492 * 19493 * @param {string} value 19494 * The value to get 19495 * 19496 * @param {Function} [parser] 19497 * Optional function to adjust the value. 19498 * 19499 * @return {Mixed} 19500 * - Will be `undefined` if no value exists 19501 * - Will be `undefined` if the given value is "none". 19502 * - Will be the actual value otherwise. 19503 * 19504 * @private 19505 */ 19506function parseOptionValue(value, parser) { 19507 if (parser) { 19508 value = parser(value); 19509 } 19510 19511 if (value && value !== 'none') { 19512 return value; 19513 } 19514} 19515 19516/** 19517 * Gets the value of the selected <option> element within a <select> element. 19518 * 19519 * @param {Element} el 19520 * the element to look in 19521 * 19522 * @param {Function} [parser] 19523 * Optional function to adjust the value. 19524 * 19525 * @return {Mixed} 19526 * - Will be `undefined` if no value exists 19527 * - Will be `undefined` if the given value is "none". 19528 * - Will be the actual value otherwise. 19529 * 19530 * @private 19531 */ 19532function getSelectedOptionValue(el, parser) { 19533 var value = el.options[el.options.selectedIndex].value; 19534 19535 return parseOptionValue(value, parser); 19536} 19537 19538/** 19539 * Sets the selected <option> element within a <select> element based on a 19540 * given value. 19541 * 19542 * @param {Element} el 19543 * The element to look in. 19544 * 19545 * @param {string} value 19546 * the property to look on. 19547 * 19548 * @param {Function} [parser] 19549 * Optional function to adjust the value before comparing. 19550 * 19551 * @private 19552 */ 19553function setSelectedOption(el, value, parser) { 19554 if (!value) { 19555 return; 19556 } 19557 19558 for (var i = 0; i < el.options.length; i++) { 19559 if (parseOptionValue(el.options[i].value, parser) === value) { 19560 el.selectedIndex = i; 19561 break; 19562 } 19563 } 19564} 19565 19566/** 19567 * Manipulate Text Tracks settings. 19568 * 19569 * @extends Component 19570 */ 19571 19572var TextTrackSettings = function (_Component) { 19573 _inherits(TextTrackSettings, _Component); 19574 19575 /** 19576 * Creates an instance of this class. 19577 * 19578 * @param {Player} player 19579 * The `Player` that this class should be attached to. 19580 * 19581 * @param {Object} [options] 19582 * The key/value store of player options. 19583 */ 19584 function TextTrackSettings(player, options) { 19585 _classCallCheck(this, TextTrackSettings); 19586 19587 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); 19588 19589 _this.setDefaults(); 19590 _this.hide(); 19591 19592 _this.updateDisplay = Fn.bind(_this, _this.updateDisplay); 19593 19594 // Grab `persistTextTrackSettings` from the player options if not passed in child options 19595 if (options.persistTextTrackSettings === undefined) { 19596 _this.options_.persistTextTrackSettings = _this.options_.playerOptions.persistTextTrackSettings; 19597 } 19598 19599 _this.on(_this.$('.vjs-done-button'), 'click', function () { 19600 _this.saveSettings(); 19601 _this.hide(); 19602 }); 19603 19604 _this.on(_this.$('.vjs-default-button'), 'click', function () { 19605 _this.setDefaults(); 19606 _this.updateDisplay(); 19607 }); 19608 19609 Obj.each(selectConfigs, function (config) { 19610 _this.on(_this.$(config.selector), 'change', _this.updateDisplay); 19611 }); 19612 19613 if (_this.options_.persistTextTrackSettings) { 19614 _this.restoreSettings(); 19615 } 19616 return _this; 19617 } 19618 19619 /** 19620 * Create a <select> element with configured options. 19621 * 19622 * @param {string} key 19623 * Configuration key to use during creation. 19624 * 19625 * @return {Element} 19626 * The DOM element that gets created. 19627 * @private 19628 */ 19629 19630 19631 TextTrackSettings.prototype.createElSelect_ = function createElSelect_(key) { 19632 var _this2 = this; 19633 19634 var config = selectConfigs[key]; 19635 var id = config.id.replace('%s', this.id_); 19636 19637 return [(0, _dom.createEl)('label', { 19638 className: 'vjs-label', 19639 textContent: config.label 19640 }, {
19641 'for': id 19642 }), (0, _dom.createEl)('select', { id: id }, undefined, config.options.map(function (o) { 19643 return (0, _dom.createEl)('option', { 19644 textContent: _this2.localize(o[1]), 19645 value: o[0] 19646 }); 19647 }))]; 19648 }; 19649 19650 /** 19651 * Create foreground color element for the component 19652 * 19653 * @return {Element} 19654 * The element that was created. 19655 * 19656 * @private 19657 */ 19658 19659 19660 TextTrackSettings.prototype.createElFgColor_ = function createElFgColor_() { 19661 var legend = (0, _dom.createEl)('legend', { 19662 textContent: this.localize('Text') 19663 }); 19664 19665 var select = this.createElSelect_('color'); 19666 19667 var opacity = (0, _dom.createEl)('span', { 19668 className: 'vjs-text-opacity vjs-opacity' 19669 }, undefined, this.createElSelect_('textOpacity')); 19670 19671 return (0, _dom.createEl)('fieldset', { 19672 className: 'vjs-fg-color vjs-tracksetting' 19673 }, undefined, [legend].concat(select, opacity)); 19674 }; 19675 19676 /** 19677 * Create background color element for the component 19678 * 19679 * @return {Element} 19680 * The element that was created 19681 * 19682 * @private 19683 */ 19684 19685 19686 TextTrackSettings.prototype.createElBgColor_ = function createElBgColor_() { 19687 var legend = (0, _dom.createEl)('legend', { 19688 textContent: this.localize('Background') 19689 }); 19690 19691 var select = this.createElSelect_('backgroundColor'); 19692 19693 var opacity = (0, _dom.createEl)('span', { 19694 className: 'vjs-bg-opacity vjs-opacity' 19695 }, undefined, this.createElSelect_('backgroundOpacity')); 19696 19697 return (0, _dom.createEl)('fieldset', { 19698 className: 'vjs-bg-color vjs-tracksetting' 19699 }, undefined, [legend].concat(select, opacity)); 19700 }; 19701 19702 /** 19703 * Create window color element for the component 19704 * 19705 * @return {Element} 19706 * The element that was created 19707 * 19708 * @private 19709 */ 19710 19711 19712 TextTrackSettings.prototype.createElWinColor_ = function createElWinColor_() { 19713 var legend = (0, _dom.createEl)('legend', { 19714 textContent: this.localize('Window') 19715 }); 19716 19717 var select = this.createElSelect_('windowColor'); 19718 19719 var opacity = (0, _dom.createEl)('span', { 19720 className: 'vjs-window-opacity vjs-opacity' 19721 }, undefined, this.createElSelect_('windowOpacity')); 19722 19723 return (0, _dom.createEl)('fieldset', { 19724 className: 'vjs-window-color vjs-tracksetting' 19725 }, undefined, [legend].concat(select, opacity)); 19726 }; 19727 19728 /** 19729 * Create color elements for the component 19730 * 19731 * @return {Element} 19732 * The element that was created 19733 * 19734 * @private 19735 */ 19736 19737 19738 TextTrackSettings.prototype.createElColors_ = function createElColors_() { 19739 return (0, _dom.createEl)('div', { 19740 className: 'vjs-tracksettings-colors' 19741 }, undefined, [this.createElFgColor_(), this.createElBgColor_(), this.createElWinColor_()]); 19742 }; 19743 19744 /** 19745 * Create font elements for the component 19746 * 19747 * @return {Element} 19748 * The element that was created. 19749 * 19750 * @private 19751 */ 19752 19753 19754 TextTrackSettings.prototype.createElFont_ = function createElFont_() { 19755 var fontPercent = (0, _dom.createEl)('div', { 19756 className: 'vjs-font-percent vjs-tracksetting' 19757 }, undefined, this.createElSelect_('fontPercent')); 19758 19759 var edgeStyle = (0, _dom.createEl)('div', { 19760 className: 'vjs-edge-style vjs-tracksetting' 19761 }, undefined, this.createElSelect_('edgeStyle')); 19762 19763 var fontFamily = (0, _dom.createEl)('div', { 19764 className: 'vjs-font-family vjs-tracksetting' 19765 }, undefined, this.createElSelect_('fontFamily')); 19766 19767 return (0, _dom.createEl)('div', { 19768 className: 'vjs-tracksettings-font' 19769 }, undefined, [fontPercent, edgeStyle, fontFamily]); 19770 }; 19771 19772 /** 19773 * Create controls for the component 19774 * 19775 * @return {Element} 19776 * The element that was created. 19777 * 19778 * @private 19779 */ 19780 19781 19782 TextTrackSettings.prototype.createElControls_ = function createElControls_() { 19783 var defaultsButton = (0, _dom.createEl)('button', { 19784 className: 'vjs-default-button', 19785 textContent: this.localize('Defaults') 19786 }); 19787 19788 var doneButton = (0, _dom.createEl)('button', { 19789 className: 'vjs-done-button', 19790 textContent: 'Done' 19791 }); 19792 19793 return (0, _dom.createEl)('div', { 19794 className: 'vjs-tracksettings-controls' 19795 }, undefined, [defaultsButton, doneButton]); 19796 }; 19797 19798 /** 19799 * Create the component's DOM element 19800 * 19801 * @return {Element} 19802 * The element that was created. 19803 */ 19804 19805 19806 TextTrackSettings.prototype.createEl = function createEl() { 19807 var settings = (0, _dom.createEl)('div', { 19808 className: 'vjs-tracksettings' 19809 }, undefined, [this.createElColors_(), this.createElFont_(), this.createElControls_()]); 19810 19811 var heading = (0, _dom.createEl)('div', { 19812 className: 'vjs-control-text', 19813 id: 'TTsettingsDialogLabel-' + this.id_, 19814 textContent: 'Caption Settings Dialog' 19815 }, {
19816 'aria-level': '1', 19817 'role': 'heading' 19818 }); 19819 19820 var description = (0, _dom.createEl)('div', { 19821 className: 'vjs-control-text', 19822 id: 'TTsettingsDialogDescription-' + this.id_, 19823 textContent: 'Beginning of dialog window. Escape will cancel and close the window.' 19824 }); 19825 19826 var doc = (0, _dom.createEl)('div', undefined, { 19827 role: 'document' 19828 }, [heading, description, settings]); 19829 19830 return (0, _dom.createEl)('div', { 19831 className: 'vjs-caption-settings vjs-modal-overlay', 19832 tabIndex: -1 19833 }, { 19834 'role': 'dialog', 19835 'aria-labelledby': heading.id, 19836 'aria-describedby': description.id 19837 }, doc); 19838 }; 19839 19840 /** 19841 * Gets an object of text track settings (or null). 19842 * 19843 * @return {Object} 19844 * An object with config values parsed from the DOM or localStorage. 19845 */ 19846 19847 19848 TextTrackSettings.prototype.getValues = function getValues() { 19849 var _this3 = this; 19850 19851 return Obj.reduce(selectConfigs, function (accum, config, key) { 19852 var value = getSelectedOptionValue(_this3.$(config.selector), config.parser); 19853 19854 if (value !== undefined) { 19855 accum[key] = value; 19856 } 19857 19858 return accum; 19859 }, {}); 19860 }; 19861 19862 /** 19863 * Sets text track settings from an object of values. 19864 * 19865 * @param {Object} values 19866 * An object with config values parsed from the DOM or localStorage. 19867 */ 19868 19869 19870 TextTrackSettings.prototype.setValues = function setValues(values) { 19871 var _this4 = this; 19872 19873 Obj.each(selectConfigs, function (config, key) { 19874 setSelectedOption(_this4.$(config.selector), values[key], config.parser); 19875 }); 19876 }; 19877 19878 /** 19879 * Sets all <select> elements to their default values. 19880 */ 19881 19882 19883 TextTrackSettings.prototype.setDefaults = function setDefaults() { 19884 var _this5 = this; 19885 19886 Obj.each(selectConfigs, function (config) { 19887 var index = config.hasOwnProperty('default') ? config['default'] : 0; 19888 19889 _this5.$(config.selector).selectedIndex = index; 19890 }); 19891 }; 19892 19893 /** 19894 * Restore texttrack settings from localStorage 19895 */ 19896 19897 19898 TextTrackSettings.prototype.restoreSettings = function restoreSettings() { 19899 var values = void 0; 19900 19901 try { 19902 values = JSON.parse(_window2['default'].localStorage.getItem(LOCAL_STORAGE_KEY)); 19903 } catch (err) { 19904 _log2['default'].warn(err); 19905 } 19906 19907 if (values) { 19908 this.setValues(values); 19909 } 19910 }; 19911 19912 /** 19913 * Save text track settings to localStorage 19914 */ 19915 19916 19917 TextTrackSettings.prototype.saveSettings = function saveSettings() { 19918 if (!this.options_.persistTextTrackSettings) { 19919 return; 19920 } 19921 19922 var values = this.getValues(); 19923 19924 try { 19925 if (Object.keys(values).length) { 19926 _window2['default'].localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values)); 19927 } else { 19928 _window2['default'].localStorage.removeItem(LOCAL_STORAGE_KEY); 19929 } 19930 } catch (err) { 19931 _log2['default'].warn(err); 19932 } 19933 }; 19934 19935 /** 19936 * Update display of text track settings 19937 */ 19938 19939 19940 TextTrackSettings.prototype.updateDisplay = function updateDisplay() { 19941 var ttDisplay = this.player_.getChild('textTrackDisplay'); 19942 19943 if (ttDisplay) { 19944 ttDisplay.updateDisplay(); 19945 } 19946 }; 19947 19948 return TextTrackSettings; 19949}(_component2['default']); 19950 19951_component2['default'].registerComponent('TextTrackSettings', TextTrackSettings); 19952 19953exports['default'] = TextTrackSettings; 19954 19955},{"5":5,"81":81,"83":83,"86":86,"88":88,"95":95}],72:[function(_dereq_,module,exports){ 19956'use strict'; 19957 19958exports.__esModule = true; 19959 19960var _textTrackCueList = _dereq_(67); 19961 19962var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList); 19963 19964var _fn = _dereq_(83); 19965 19966var Fn = _interopRequireWildcard(_fn); 19967 19968var _trackEnums = _dereq_(73); 19969 19970var _log = _dereq_(86); 19971 19972var _log2 = _interopRequireDefault(_log); 19973 19974var _window = _dereq_(95); 19975 19976var _window2 = _interopRequireDefault(_window); 19977 19978var _track = _dereq_(75); 19979 19980var _track2 = _interopRequireDefault(_track); 19981 19982var _url = _dereq_(92); 19983 19984var _xhr = _dereq_(105); 19985 19986var _xhr2 = _interopRequireDefault(_xhr); 19987 19988var _mergeOptions = _dereq_(87); 19989 19990var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 19991 19992var _browser = _dereq_(78); 19993 19994var browser = _interopRequireWildcard(_browser); 19995 19996function _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; } } 19997 19998function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19999 20000function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 20001 20002function _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; } 20003 20004function _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
20004onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 20005 * @file text-track.js 20006 */ 20007 20008 20009/** 20010 * Takes a webvtt file contents and parses it into cues 20011 * 20012 * @param {string} srcContent 20013 * webVTT file contents 20014 * 20015 * @param {TextTrack} track 20016 * TextTrack to add cues to. Cues come from the srcContent. 20017 * 20018 * @private 20019 */ 20020var parseCues = function parseCues(srcContent, track) { 20021 var parser = new _window2['default'].WebVTT.Parser(_window2['default'], _window2['default'].vttjs, _window2['default'].WebVTT.StringDecoder()); 20022 var errors = []; 20023 20024 parser.oncue = function (cue) { 20025 track.addCue(cue); 20026 }; 20027 20028 parser.onparsingerror = function (error) { 20029 errors.push(error); 20030 }; 20031 20032 parser.onflush = function () { 20033 track.trigger({ 20034 type: 'loadeddata', 20035 target: track 20036 }); 20037 }; 20038 20039 parser.parse(srcContent); 20040 if (errors.length > 0) { 20041 if (_window2['default'].console && _window2['default'].console.groupCollapsed) { 20042 _window2['default'].console.groupCollapsed('Text Track parsing errors for ' + track.src); 20043 } 20044 errors.forEach(function (error) { 20045 return _log2['default'].error(error); 20046 }); 20047 if (_window2['default'].console && _window2['default'].console.groupEnd) { 20048 _window2['default'].console.groupEnd(); 20049 } 20050 } 20051 20052 parser.flush(); 20053}; 20054 20055/** 20056 * Load a `TextTrack` from a specifed url. 20057 * 20058 * @param {string} src 20059 * Url to load track from. 20060 * 20061 * @param {TextTrack} track 20062 * Track to add cues to. Comes from the content at the end of `url`. 20063 * 20064 * @private 20065 */ 20066var loadTrack = function loadTrack(src, track) { 20067 var opts = { 20068 uri: src 20069 }; 20070 var crossOrigin = (0, _url.isCrossOrigin)(src); 20071 20072 if (crossOrigin) { 20073 opts.cors = crossOrigin; 20074 } 20075 20076 (0, _xhr2['default'])(opts, Fn.bind(this, function (err, response, responseBody) { 20077 if (err) { 20078 return _log2['default'].error(err, response); 20079 } 20080 20081 track.loaded_ = true; 20082 20083 // Make sure that vttjs has loaded, otherwise, wait till it finished loading 20084 // NOTE: this is only used for the alt/video.novtt.js build 20085 if (typeof _window2['default'].WebVTT !== 'function') { 20086 if (track.tech_) { 20087 (function () { 20088 var loadHandler = function loadHandler() { 20089 return parseCues(responseBody, track); 20090 }; 20091 20092 track.tech_.on('vttjsloaded', loadHandler); 20093 track.tech_.on('vttjserror', function () { 20094 _log2['default'].error('vttjs failed to load, stopping trying to process ' + track.src); 20095 track.tech_.off('vttjsloaded', loadHandler); 20096 }); 20097 })(); 20098 } 20099 } else { 20100 parseCues(responseBody, track); 20101 } 20102 })); 20103}; 20104 20105/** 20106 * A representation of a single `TextTrack`. 20107 * 20108 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack} 20109 * @extends Track 20110 */ 20111 20112var TextTrack = function (_Track) { 20113 _inherits(TextTrack, _Track); 20114 20115 /** 20116 * Create an instance of this class. 20117 * 20118 * @param {Object} options={} 20119 * Object of option names and values 20120 * 20121 * @param {Tech} options.tech 20122 * A reference to the tech that owns this TextTrack. 20123 * 20124 * @param {TextTrack~Kind} [options.kind='subtitles'] 20125 * A valid text track kind. 20126 * 20127 * @param {TextTrack~Mode} [options.mode='disabled'] 20128 * A valid text track mode. 20129 * 20130 * @param {string} [options.id='vjs_track_' + Guid.newGUID()] 20131 * A unique id for this TextTrack. 20132 * 20133 * @param {string} [options.label=''] 20134 * The menu label for this track. 20135 * 20136 * @param {string} [options.language=''] 20137 * A valid two character language code. 20138 * 20139 * @param {string} [options.srclang=''] 20140 * A valid two character language code. An alternative, but deprioritized 20141 * vesion of `options.language` 20142 * 20143 * @param {string} [options.src] 20144 * A url to TextTrack cues. 20145 * 20146 * @param {boolean} [options.default] 20147 * If this track should default to on or off. 20148 */ 20149 function TextTrack() { 20150 var _this, _ret2; 20151 20152 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 20153 20154 _classCallCheck(this, TextTrack); 20155 20156 if (!options.tech) {
20157 throw new Error('A tech was not provided.'); 20158 } 20159 20160 var settings = (0, _mergeOptions2['default'])(options, { 20161 kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles', 20162 language: options.language || options.srclang || '' 20163 }); 20164 var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled'; 20165 var default_ = settings['default']; 20166 20167 if (settings.kind === 'metadata' || settings.kind === 'chapters') { 20168 mode = 'hidden'; 20169 } 20170 // on IE8 this will be a document element 20171 // for every other browser this will be a normal object 20172 var tt = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this); 20173 20174 tt.tech_ = settings.tech; 20175 20176 if (browser.IS_IE8) { 20177 for (var prop in TextTrack.prototype) { 20178 if (prop !== 'constructor') { 20179 tt[prop] = TextTrack.prototype[prop]; 20180 } 20181 } 20182 } 20183 20184 tt.cues_ = []; 20185 tt.activeCues_ = []; 20186 20187 var cues = new _textTrackCueList2['default'](tt.cues_); 20188 var activeCues = new _textTrackCueList2['default'](tt.activeCues_); 20189 var changed = false; 20190 var timeupdateHandler = Fn.bind(tt, function () { 20191 20192 // Accessing this.activeCues for the side-effects of updating itself 20193 // due to it's nature as a getter function. Do not remove or cues will 20194 // stop updating! 20195 /* eslint-disable no-unused-expressions */ 20196 this.activeCues; 20197 /* eslint-enable no-unused-expressions */ 20198 if (changed) { 20199 this.trigger('cuechange'); 20200 changed = false; 20201 } 20202 }); 20203 20204 if (mode !== 'disabled') { 20205 tt.tech_.on('timeupdate', timeupdateHandler); 20206 } 20207 20208 /** 20209 * @member {boolean} default 20210 * If this track was set to be on or off by default. Cannot be changed after 20211 * creation. 20212 * 20213 * @readonly 20214 */ 20215 Object.defineProperty(tt, 'default', { 20216 get: function get() { 20217 return default_; 20218 }, 20219 set: function set() {} 20220 }); 20221 20222 /** 20223 * @member {string} mode 20224 * Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will 20225 * not be set if setting to an invalid mode. 20226 * 20227 * @fires TextTrack#modechange 20228 */ 20229 Object.defineProperty(tt, 'mode', { 20230 get: function get() { 20231 return mode; 20232 }, 20233 set: function set(newMode) { 20234 if (!_trackEnums.TextTrackMode[newMode]) { 20235 return; 20236 } 20237 mode = newMode; 20238 if (mode === 'showing') { 20239 this.tech_.on('timeupdate', timeupdateHandler); 20240 } 20241 /** 20242 * An event that fires when mode changes on this track. This allows 20243 * the TextTrackList that holds this track to act accordingly. 20244 * 20245 * > Note: This is not part of the spec! 20246 * 20247 * @event TextTrack#modechange 20248 * @type {EventTarget~Event} 20249 */ 20250 this.trigger('modechange'); 20251 } 20252 }); 20253 20254 /** 20255 * @member {TextTrackCueList} cues 20256 * The text track cue list for this TextTrack. 20257 */ 20258 Object.defineProperty(tt, 'cues', { 20259 get: function get() { 20260 if (!this.loaded_) { 20261 return null; 20262 } 20263 20264 return cues; 20265 }, 20266 set: function set() {} 20267 }); 20268 20269 /** 20270 * @member {TextTrackCueList} activeCues 20271 * The list text track cues that are currently active for this TextTrack. 20272 */ 20273 Object.defineProperty(tt, 'activeCues', { 20274 get: function get() { 20275 if (!this.loaded_) { 20276 return null; 20277 } 20278 20279 // nothing to do 20280 if (this.cues.length === 0) { 20281 return activeCues; 20282 } 20283 20284 var ct = this.tech_.currentTime(); 20285 var active = []; 20286 20287 for (var i = 0, l = this.cues.length; i < l; i++) { 20288 var cue = this.cues[i]; 20289 20290 if (cue.startTime <= ct && cue.endTime >= ct) { 20291 active.push(cue); 20292 } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) { 20293 active.push(cue); 20294 } 20295 } 20296 20297 changed = false; 20298 20299 if (active.length !== this.activeCues_.length) { 20300 changed = true; 20301 } else { 20302 for (var _i = 0; _i < active.length; _i++) { 20303 if (this.activeCues_.indexOf(active[_i]) === -1) { 20304 changed = true; 20305 } 20306 } 20307 } 20308 20309 this.activeCues_ = active; 20310 activeCues.setCues_(this.activeCues_); 20311 20312 return activeCues; 20313 }, 20314 set: function set() {} 20315 }); 20316 20317 if (settings.src) { 20318 tt.src = settings.src; 20319 loadTrack(settings.src, tt); 20320 } else { 20321 tt.loaded_ = true; 20322 } 20323 20324 return _ret2 = tt, _possibleConstructorReturn(_this, _ret2); 20325 } 20326 20327 /** 20328 * Add a cue to the internal list of cues. 20329 * 20330 * @param {TextTrack~Cue} cue 20331 * The cue to add to our internal list 20332 */ 20333 20334 20335 TextTrack.prototype.addCue = function addCue(cue) { 20336 var tracks = this.tech_.textTracks(); 20337 20338 if (tracks) { 20339 for (var i = 0; i < tracks.length; i++) { 20340 if (tracks[i] !== this) { 20341 tracks[i].removeCue(cue); 20342 } 20343 } 20344 } 20345 20346 this.cues_.push(cue); 20347 this.cues.setCues_(this.cues_); 20348 }; 20349 20350 /** 20351 * Remove a cue from our internal list 20352 * 20353 * @param {TextTrack~Cue} removeCue 20354 * The cue to remove from our internal list 20355 */ 20356 20357 20358 TextTrack.prototype.removeCue = function removeCue(_removeCue) { 20359 var removed = false;
20360 20361 for (var i = 0, l = this.cues_.length; i < l; i++) { 20362 var cue = this.cues_[i]; 20363 20364 if (cue === _removeCue) { 20365 this.cues_.splice(i, 1); 20366 removed = true; 20367 } 20368 } 20369 20370 if (removed) { 20371 this.cues.setCues_(this.cues_); 20372 } 20373 }; 20374 20375 return TextTrack; 20376}(_track2['default']); 20377 20378/** 20379 * cuechange - One or more cues in the track have become active or stopped being active. 20380 */ 20381 20382 20383TextTrack.prototype.allowedEvents_ = { 20384 cuechange: 'cuechange' 20385}; 20386 20387exports['default'] = TextTrack; 20388 20389},{"105":105,"67":67,"73":73,"75":75,"78":78,"83":83,"86":86,"87":87,"92":92,"95":95}],73:[function(_dereq_,module,exports){ 20390'use strict'; 20391 20392exports.__esModule = true; 20393/** 20394 * @file track-kinds.js 20395 */ 20396 20397/** 20398 * All possible `VideoTrackKind`s 20399 * 20400 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind 20401 * @typedef VideoTrack~Kind 20402 * @enum 20403 */ 20404var VideoTrackKind = exports.VideoTrackKind = { 20405 alternative: 'alternative', 20406 captions: 'captions', 20407 main: 'main', 20408 sign: 'sign', 20409 subtitles: 'subtitles', 20410 commentary: 'commentary' 20411}; 20412 20413/** 20414 * All possible `AudioTrackKind`s 20415 * 20416 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind 20417 * @typedef AudioTrack~Kind 20418 * @enum 20419 */ 20420var AudioTrackKind = exports.AudioTrackKind = { 20421 'alternative': 'alternative', 20422 'descriptions': 'descriptions', 20423 'main': 'main', 20424 'main-desc': 'main-desc', 20425 'translation': 'translation', 20426 'commentary': 'commentary' 20427}; 20428 20429/** 20430 * All possible `TextTrackKind`s 20431 * 20432 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-texttrack-kind 20433 * @typedef TextTrack~Kind 20434 * @enum 20435 */ 20436var TextTrackKind = exports.TextTrackKind = { 20437 subtitles: 'subtitles', 20438 captions: 'captions', 20439 descriptions: 'descriptions', 20440 chapters: 'chapters', 20441 metadata: 'metadata' 20442}; 20443 20444/** 20445 * All possible `TextTrackMode`s 20446 * 20447 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode 20448 * @typedef TextTrack~Mode 20449 * @enum 20450 */ 20451var TextTrackMode = exports.TextTrackMode = { 20452 disabled: 'disabled', 20453 hidden: 'hidden', 20454 showing: 'showing' 20455}; 20456 20457},{}],74:[function(_dereq_,module,exports){ 20458'use strict'; 20459 20460exports.__esModule = true; 20461 20462var _eventTarget = _dereq_(42); 20463 20464var _eventTarget2 = _interopRequireDefault(_eventTarget); 20465 20466var _browser = _dereq_(78); 20467 20468var browser = _interopRequireWildcard(_browser); 20469 20470var _document = _dereq_(94); 20471 20472var _document2 = _interopRequireDefault(_document); 20473 20474function _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; } } 20475 20476function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20477 20478function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 20479 20480function _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; } 20481 20482function _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; } /** 20483 * @file track-list.js 20484 */ 20485 20486 20487/** 20488 * Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and 20489 * {@link VideoTrackList} 20490 *
20491 * @extends EventTarget 20492 */ 20493var TrackList = function (_EventTarget) { 20494 _inherits(TrackList, _EventTarget); 20495 20496 /** 20497 * Create an instance of this class 20498 * 20499 * @param {Track[]} tracks 20500 * A list of tracks to initialize the list with. 20501 * 20502 * @param {Object} [list] 20503 * The child object with inheritance done manually for ie8. 20504 * 20505 * @abstract 20506 */ 20507 function TrackList() { 20508 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 20509 20510 var _ret; 20511 20512 var list = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 20513 20514 _classCallCheck(this, TrackList); 20515 20516 var _this = _possibleConstructorReturn(this, _EventTarget.call(this)); 20517 20518 if (!list) { 20519 list = _this; // eslint-disable-line 20520 if (browser.IS_IE8) { 20521 list = _document2['default'].createElement('custom'); 20522 for (var prop in TrackList.prototype) { 20523 if (prop !== 'constructor') { 20524 list[prop] = TrackList.prototype[prop]; 20525 } 20526 } 20527 } 20528 } 20529 20530 list.tracks_ = []; 20531 20532 /** 20533 * @member {number} length 20534 * The current number of `Track`s in the this Trackist. 20535 */ 20536 Object.defineProperty(list, 'length', { 20537 get: function get() { 20538 return this.tracks_.length; 20539 } 20540 }); 20541 20542 for (var i = 0; i < tracks.length; i++) { 20543 list.addTrack_(tracks[i]); 20544 } 20545 20546 // must return the object, as for ie8 it will not be this 20547 // but a reference to a document object 20548 return _ret = list, _possibleConstructorReturn(_this, _ret); 20549 } 20550 20551 /** 20552 * Add a {@link Track} to the `TrackList` 20553 * 20554 * @param {Track} track 20555 * The audio, video, or text track to add to the list. 20556 * 20557 * @fires TrackList#addtrack 20558 * @private 20559 */ 20560 20561 20562 TrackList.prototype.addTrack_ = function addTrack_(track) { 20563 var index = this.tracks_.length; 20564 20565 if (!('' + index in this)) { 20566 Object.defineProperty(this, index, { 20567 get: function get() { 20568 return this.tracks_[index]; 20569 } 20570 }); 20571 } 20572 20573 // Do not add duplicate tracks 20574 if (this.tracks_.indexOf(track) === -1) { 20575 this.tracks_.push(track); 20576 /** 20577 * Triggered when a track is added to a track list. 20578 * 20579 * @event TrackList#addtrack 20580 * @type {EventTarget~Event} 20581 * @property {Track} track 20582 * A reference to track that was added. 20583 */ 20584 this.trigger({ 20585 track: track, 20586 type: 'addtrack' 20587 }); 20588 } 20589 }; 20590 20591 /** 20592 * Remove a {@link Track} from the `TrackList` 20593 * 20594 * @param {Track} track 20595 * The audio, video, or text track to remove from the list. 20596 * 20597 * @fires TrackList#removetrack 20598 * @private 20599 */ 20600 20601 20602 TrackList.prototype.removeTrack_ = function removeTrack_(rtrack) { 20603 var track = void 0; 20604 20605 for (var i = 0, l = this.length; i < l; i++) { 20606 if (this[i] === rtrack) { 20607 track = this[i]; 20608 if (track.off) { 20609 track.off(); 20610 } 20611 20612 this.tracks_.splice(i, 1); 20613 20614 break; 20615 } 20616 } 20617 20618 if (!track) { 20619 return; 20620 } 20621 20622 /** 20623 * Triggered when a track is removed from track list. 20624 * 20625 * @event TrackList#removetrack 20626 * @type {EventTarget~Event} 20627 * @property {Track} track 20628 * A reference to track that was removed. 20629 */ 20630 this.trigger({ 20631 track: track, 20632 type: 'removetrack' 20633 }); 20634 }; 20635 20636 /** 20637 * Get a Track from the TrackList by a tracks id 20638 * 20639 * @param {String} id - the id of the track to get 20640 * @method getTrackById 20641 * @return {Track} 20642 * @private 20643 */ 20644 20645 20646 TrackList.prototype.getTrackById = function getTrackById(id) { 20647 var result = null; 20648 20649 for (var i = 0, l = this.length; i < l; i++) { 20650 var track = this[i]; 20651 20652 if (track.id === id) { 20653 result = track; 20654 break; 20655 } 20656 } 20657 20658 return result; 20659 }; 20660 20661 return TrackList; 20662}(_eventTarget2['default']); 20663 20664/** 20665 * Triggered when a different track is selected/enabled. 20666 * 20667 * @event TrackList#change 20668 * @type {EventTarget~Event} 20669 */ 20670 20671/** 20672 * Events that can be called with on + eventName. See {@link EventHandler}. 20673 * 20674 * @property {Object} TrackList#allowedEvents_ 20675 * @private 20676 */ 20677 20678 20679TrackList.prototype.allowedEvents_ = { 20680 change: 'change', 20681 addtrack: 'addtrack', 20682 removetrack: 'removetrack' 20683}; 20684 20685// emulate attribute EventHandler support to allow for feature detection 20686for (var event in TrackList.prototype.allowedEvents_) { 20687 TrackList.prototype['on' + event] = null; 20688} 20689 20690exports['default'] = TrackList; 20691 20692},{"42":42,"78":78,"94":94}],75:[function(_dereq_,module,exports){ 20693'use strict'; 20694 20695exports.__esModule = true; 20696 20697var _browser = _dereq_(78); 20698 20699var browser = _interopRequireWildcard(_browser); 20700 20701var _document = _dereq_(94); 20702 20703var _document2 = _interopRequireDefault(_document); 20704 20705var _guid = _dereq_(85); 20706 20707var Guid = _interopRequireWildcard(_guid); 20708 20709var _eventTarget = _dereq_(42); 20710 20711var _eventTarget2 = _interopRequireDefault(_eventTarget); 20712 20713function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20714 20715function _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; } } 20716 20717function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 20718 20719function _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; } 20720 20721function _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
20721onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 20722 * @file track.js 20723 */ 20724 20725 20726/** 20727 * A Track class that contains all of the common functionality for {@link AudioTrack}, 20728 * {@link VideoTrack}, and {@link TextTrack}. 20729 * 20730 * > Note: This class should not be used directly 20731 * 20732 * @see {@link https://html.spec.whatwg.org/multipage/embedded-content.html} 20733 * @extends EventTarget 20734 * @abstract 20735 */ 20736var Track = function (_EventTarget) { 20737 _inherits(Track, _EventTarget); 20738 20739 /** 20740 * Create an instance of this class. 20741 * 20742 * @param {Object} [options={}] 20743 * Object of option names and values 20744 * 20745 * @param {string} [options.kind=''] 20746 * A valid kind for the track type you are creating. 20747 * 20748 * @param {string} [options.id='vjs_track_' + Guid.newGUID()] 20749 * A unique id for this AudioTrack. 20750 * 20751 * @param {string} [options.label=''] 20752 * The menu label for this track. 20753 * 20754 * @param {string} [options.language=''] 20755 * A valid two character language code. 20756 * 20757 * @abstract 20758 */ 20759 function Track() { 20760 var _ret; 20761 20762 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 20763 20764 _classCallCheck(this, Track); 20765 20766 var _this = _possibleConstructorReturn(this, _EventTarget.call(this)); 20767 20768 var track = _this; // eslint-disable-line 20769 20770 if (browser.IS_IE8) { 20771 track = _document2['default'].createElement('custom'); 20772 for (var prop in Track.prototype) { 20773 if (prop !== 'constructor') { 20774 track[prop] = Track.prototype[prop]; 20775 } 20776 } 20777 } 20778 20779 var trackProps = { 20780 id: options.id || 'vjs_track_' + Guid.newGUID(), 20781 kind: options.kind || '', 20782 label: options.label || '', 20783 language: options.language || '' 20784 }; 20785 20786 /** 20787 * @member {string} id 20788 * The id of this track. Cannot be changed after creation. 20789 * 20790 * @readonly 20791 */ 20792 20793 /** 20794 * @member {string} kind 20795 * The kind of track that this is. Cannot be changed after creation. 20796 * 20797 * @readonly 20798 */ 20799 20800 /** 20801 * @member {string} label 20802 * The label of this track. Cannot be changed after creation. 20803 * 20804 * @readonly 20805 */ 20806 20807 /** 20808 * @member {string} language 20809 * The two letter language code for this track. Cannot be changed after 20810 * creation. 20811 * 20812 * @readonly 20813 */ 20814 20815 var _loop = function _loop(key) { 20816 Object.defineProperty(track, key, { 20817 get: function get() { 20818 return trackProps[key]; 20819 }, 20820 set: function set() {} 20821 }); 20822 }; 20823 20824 for (var key in trackProps) { 20825 _loop(key); 20826 } 20827 20828 return _ret = track, _possibleConstructorReturn(_this, _ret); 20829 } 20830 20831 return Track; 20832}(_eventTarget2['default']); 20833 20834exports['default'] = Track; 20835 20836},{"42":42,"78":78,"85":85,"94":94}],76:[function(_dereq_,module,exports){ 20837'use strict'; 20838 20839exports.__esModule = true; 20840 20841var _trackList = _dereq_(74); 20842 20843var _trackList2 = _interopRequireDefault(_trackList); 20844 20845var _browser = _dereq_(78); 20846 20847var browser = _interopRequireWildcard(_browser); 20848 20849var _document = _dereq_(94); 20850 20851var _document2 = _interopRequireDefault(_document); 20852 20853function _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; } } 20854 20855function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20856 20857function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 20858 20859function _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; } 20860 20861function _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
20861onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** 20862 * @file video-track-list.js 20863 */ 20864 20865 20866/** 20867 * Un-select all other {@link VideoTrack}s that are selected. 20868 * 20869 * @param {VideoTrackList} list 20870 * list to work on 20871 * 20872 * @param {VideoTrack} track 20873 * The track to skip 20874 * 20875 * @private 20876 */ 20877var disableOthers = function disableOthers(list, track) { 20878 for (var i = 0; i < list.length; i++) { 20879 if (track.id === list[i].id) { 20880 continue; 20881 } 20882 // another video track is enabled, disable it 20883 list[i].selected = false; 20884 } 20885}; 20886 20887/** 20888 * The current list of {@link VideoTrack} for a video. 20889 * 20890 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist} 20891 * @extends TrackList 20892 */ 20893 20894var VideoTrackList = function (_TrackList) { 20895 _inherits(VideoTrackList, _TrackList); 20896 20897 /** 20898 * Create an instance of this class. 20899 * 20900 * @param {VideoTrack[]} [tracks=[]] 20901 * A list of `VideoTrack` to instantiate the list with. 20902 */ 20903 function VideoTrackList() { 20904 var _this, _ret; 20905 20906 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 20907 20908 _classCallCheck(this, VideoTrackList); 20909 20910 var list = void 0; 20911 20912 // make sure only 1 track is enabled 20913 // sorted from last index to first index 20914 for (var i = tracks.length - 1; i >= 0; i--) { 20915 if (tracks[i].selected) { 20916 disableOthers(tracks, tracks[i]); 20917 break; 20918 } 20919 } 20920 20921 // IE8 forces us to implement inheritance ourselves 20922 // as it does not support Object.defineProperty properly 20923 if (browser.IS_IE8) { 20924 list = _document2['default'].createElement('custom'); 20925 for (var prop in _trackList2['default'].prototype) { 20926 if (prop !== 'constructor') { 20927 list[prop] = _trackList2['default'].prototype[prop]; 20928 } 20929 } 20930 for (var _prop in VideoTrackList.prototype) { 20931 if (_prop !== 'constructor') { 20932 list[_prop] = VideoTrackList.prototype[_prop]; 20933 } 20934 } 20935 } 20936
20937 list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this); 20938 list.changing_ = false; 20939 20940 /** 20941 * @member {number} VideoTrackList#selectedIndex 20942 * The current index of the selected {@link VideoTrack`}. 20943 */ 20944 Object.defineProperty(list, 'selectedIndex', { 20945 get: function get() { 20946 for (var _i = 0; _i < this.length; _i++) { 20947 if (this[_i].selected) { 20948 return _i; 20949 } 20950 } 20951 return -1; 20952 }, 20953 set: function set() {} 20954 }); 20955 20956 return _ret = list, _possibleConstructorReturn(_this, _ret); 20957 } 20958 20959 /** 20960 * Add a {@link VideoTrack} to the `VideoTrackList`. 20961 * 20962 * @param {VideoTrack} track 20963 * The VideoTrack to add to the list 20964 * 20965 * @fires TrackList#addtrack 20966 * @private 20967 */ 20968 20969 20970 VideoTrackList.prototype.addTrack_ = function addTrack_(track) { 20971 var _this2 = this; 20972 20973 if (track.selected) { 20974 disableOthers(this, track); 20975 } 20976 20977 _TrackList.prototype.addTrack_.call(this, track); 20978 // native tracks don't have this 20979 if (!track.addEventListener) { 20980 return; 20981 } 20982 20983 /** 20984 * @listens VideoTrack#selectedchange 20985 * @fires TrackList#change 20986 */ 20987 track.addEventListener('selectedchange', function () { 20988 if (_this2.changing_) { 20989 return; 20990 } 20991 _this2.changing_ = true; 20992 disableOthers(_this2, track); 20993 _this2.changing_ = false; 20994 _this2.trigger('change'); 20995 }); 20996 }; 20997 20998 /** 20999 * Add a {@link VideoTrack} to the `VideoTrackList`. 21000 * 21001 * @param {VideoTrack} track 21002 * The VideoTrack to add to the list 21003 * 21004 * @fires TrackList#addtrack 21005 */ 21006 21007 21008 VideoTrackList.prototype.addTrack = function addTrack(track) { 21009 this.addTrack_(track); 21010 }; 21011 21012 /** 21013 * Remove a {@link VideoTrack} to the `VideoTrackList`. 21014 * 21015 * @param {VideoTrack} track 21016 * The VideoTrack to remove from the list. 21017 * 21018 * @fires TrackList#removetrack 21019 */ 21020 21021 21022 VideoTrackList.prototype.removeTrack = function removeTrack(track) { 21023 _TrackList.prototype.removeTrack_.call(this, track); 21024 }; 21025 21026 return VideoTrackList; 21027}(_trackList2['default']); 21028 21029exports['default'] = VideoTrackList; 21030 21031},{"74":74,"78":78,"94":94}],77:[function(_dereq_,module,exports){ 21032'use strict'; 21033 21034exports.__esModule = true; 21035 21036var _trackEnums = _dereq_(73); 21037 21038var _track = _dereq_(75); 21039 21040var _track2 = _interopRequireDefault(_track); 21041 21042var _mergeOptions = _dereq_(87); 21043 21044var _mergeOptions2 = _interopRequireDefault(_mergeOptions); 21045 21046var _browser = _dereq_(78); 21047 21048var browser = _interopRequireWildcard(_browser); 21049 21050function _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; } } 21051 21052function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21053 21054function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 21055 21056function _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; } 21057 21058function _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; } 21059 21060/** 21061 * A representation of a single `VideoTrack`. 21062 * 21063 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack} 21064 * @extends Track 21065 */ 21066var VideoTrack = function (_Track) { 21067 _inherits(VideoTrack, _Track); 21068 21069 /** 21070 * Create an instance of this class. 21071 * 21072 * @param {Object} [options={}] 21073 * Object of option names and values 21074 * 21075 * @param {string} [options.kind=''] 21076 * A valid {@link VideoTrack~Kind} 21077 * 21078 * @param {string} [options.id='vjs_track_' + Guid.newGUID()] 21079 * A unique id for this AudioTrack. 21080 * 21081 * @param {string} [options.label=''] 21082 * The menu label for this track. 21083 * 21084 * @param {string} [options.language=''] 21085 * A valid two character language code. 21086 * 21087 * @param {boolean} [options.selected] 21088 * If this track is the one that is currently playing. 21089 */ 21090 function VideoTrack() { 21091 var _this, _ret; 21092 21093 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 21094 21095 _classCallCheck(this, VideoTrack); 21096 21097 var settings = (0, _mergeOptions2['default'])(options, { 21098 kind: _trackEnums.VideoTrackKind[options.kind] || '' 21099 }); 21100 21101 // on IE8 this will be a document element 21102 // for every other browser this will be a normal object
21103 var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this); 21104 var selected = false; 21105 21106 if (browser.IS_IE8) { 21107 for (var prop in VideoTrack.prototype) { 21108 if (prop !== 'constructor') { 21109 track[prop] = VideoTrack.prototype[prop]; 21110 } 21111 } 21112 } 21113 21114 /** 21115 * @member {boolean} selected 21116 * If this `VideoTrack` is selected or not. When setting this will 21117 * fire {@link VideoTrack#selectedchange} if the state of selected changed. 21118 * 21119 * @fires VideoTrack#selectedchange 21120 */ 21121 Object.defineProperty(track, 'selected', { 21122 get: function get() { 21123 return selected; 21124 }, 21125 set: function set(newSelected) { 21126 // an invalid or unchanged value 21127 if (typeof newSelected !== 'boolean' || newSelected === selected) { 21128 return; 21129 } 21130 selected = newSelected; 21131 21132 /** 21133 * An event that fires when selected changes on this track. This allows 21134 * the VideoTrackList that holds this track to act accordingly. 21135 * 21136 * > Note: This is not part of the spec! Native tracks will do 21137 * this internally without an event. 21138 * 21139 * @event VideoTrack#selectedchange 21140 * @type {EventTarget~Event} 21141 */ 21142 this.trigger('selectedchange'); 21143 } 21144 }); 21145 21146 // if the user sets this track to selected then 21147 // set selected to that true value otherwise 21148 // we keep it false 21149 if (settings.selected) { 21150 track.selected = settings.selected; 21151 } 21152 21153 return _ret = track, _possibleConstructorReturn(_this, _ret); 21154 } 21155 21156 return VideoTrack; 21157}(_track2['default']); 21158 21159exports['default'] = VideoTrack; 21160 21161},{"73":73,"75":75,"78":78,"87":87}],78:[function(_dereq_,module,exports){ 21162'use strict'; 21163 21164exports.__esModule = true; 21165exports.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
21165orts.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; 21166 21167var _dom = _dereq_(81); 21168 21169var Dom = _interopRequireWildcard(_dom); 21170 21171var _window = _dereq_(95); 21172 21173var _window2 = _interopRequireDefault(_window); 21174 21175function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21176 21177function _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; } } 21178 21179/** 21180 * @file browser.js 21181 * @module browser 21182 */ 21183var USER_AGENT = _window2['default'].navigator && _window2['default'].navigator.userAgent || ''; 21184var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT); 21185var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null; 21186 21187/* 21188 * Device is an iPhone 21189 * 21190 * @type {Boolean} 21191 * @constant 21192 * @private 21193 */ 21194var IS_IPAD = exports.IS_IPAD = /iPad/i.test(USER_AGENT); 21195 21196// The Facebook app's UIWebView identifies as both an iPhone and iPad, so 21197// to identify iPhones, we need to exclude iPads. 21198// http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/ 21199var IS_IPHONE = exports.IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD; 21200var IS_IPOD = exports.IS_IPOD = /iPod/i.test(USER_AGENT); 21201var IS_IOS = exports.IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD; 21202 21203var IOS_VERSION = exports.IOS_VERSION = function () { 21204 var match = USER_AGENT.match(/OS (\d+)_/i); 21205 21206 if (match && match[1]) { 21207 return match[1]; 21208 } 21209 return null; 21210}(); 21211
21212var IS_ANDROID = exports.IS_ANDROID = /Android/i.test(USER_AGENT); 21213var ANDROID_VERSION = exports.ANDROID_VERSION = function () { 21214 // This matches Android Major.Minor.Patch versions 21215 // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned 21216 var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i); 21217 21218 if (!match) { 21219 return null; 21220 } 21221 21222 var major = match[1] && parseFloat(match[1]); 21223 var minor = match[2] && parseFloat(match[2]); 21224 21225 if (major && minor) { 21226 return parseFloat(match[1] + '.' + match[2]); 21227 } else if (major) { 21228 return major; 21229 } 21230 return null; 21231}(); 21232 21233// Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser 21234var IS_OLD_ANDROID = exports.IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3; 21235var IS_NATIVE_ANDROID = exports.IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537; 21236 21237var IS_FIREFOX = exports.IS_FIREFOX = /Firefox/i.test(USER_AGENT); 21238var IS_EDGE = exports.IS_EDGE = /Edge/i.test(USER_AGENT); 21239var IS_CHROME = exports.IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT); 21240var IS_IE8 = exports.IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT); 21241var IE_VERSION = exports.IE_VERSION = function (result) { 21242 return result && parseFloat(result[1]); 21243}(/MSIE\s(\d+)\.\d/.exec(USER_AGENT)); 21244 21245var IS_SAFARI = exports.IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE; 21246var IS_ANY_SAFARI = exports.IS_ANY_SAFARI = IS_SAFARI || IS_IOS; 21247 21248var TOUCH_ENABLED = exports.TOUCH_ENABLED = Dom.isReal() && ('ontouchstart' in _window2['default'] || _window2['default'].DocumentTouch && _window2['default'].document instanceof _window2['default'].DocumentTouch); 21249 21250var BACKGROUND_SIZE_SUPPORTED = exports.BACKGROUND_SIZE_SUPPORTED = Dom.isReal() && 'backgroundSize' in _window2['default'].document.createElement('video').style; 21251 21252},{"81":81,"95":95}],79:[function(_dereq_,module,exports){ 21253'use strict'; 21254 21255exports.__esModule = true; 21256exports.bufferedPercent = bufferedPercent; 21257 21258var _timeRanges = _dereq_(90); 21259 21260/** 21261 * Compute the percentage of the media that has been buffered. 21262 * 21263 * @param {TimeRange} buffered 21264 * The current `TimeRange` object representing buffered time ranges 21265 * 21266 * @param {number} duration 21267 * Total duration of the media 21268 * 21269 * @return {number} 21270 * Percent buffered of the total duration in decimal form. 21271 */ 21272function bufferedPercent(buffered, duration) { 21273 var bufferedDuration = 0; 21274 var start = void 0; 21275 var end = void 0; 21276 21277 if (!duration) { 21278 return 0; 21279 } 21280 21281 if (!buffered || !buffered.length) { 21282 buffered = (0, _timeRanges.createTimeRange)(0, 0); 21283 } 21284 21285 for (var i = 0; i < buffered.length; i++) { 21286 start = buffered.start(i); 21287 end = buffered.end(i); 21288 21289 // buffered end can be bigger than duration by a very small fraction 21290 if (end > duration) { 21291 end = duration; 21292 } 21293 21294 bufferedDuration += end - start; 21295 } 21296 21297 return bufferedDuration / duration; 21298} /** 21299 * @file buffer.js 21300 * @module buffer 21301 */ 21302 21303},{"90":90}],80:[function(_dereq_,module,exports){ 21304'use strict'; 21305 21306exports.__esModule = true; 21307exports['default'] = computedStyle; 21308 21309var _window = _dereq_(95); 21310 21311var _window2 = _interopRequireDefault(_window); 21312 21313function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21314 21315/** 21316 * A safe getComputedStyle with an IE8 fallback. 21317 * 21318 * This is needed because in Firefox, if the player is loaded in an iframe with 21319 * `display:none`, then `getComputedStyle` returns `null`, so, we do a null-check to 21320 * make sure that the player doesn't break in these cases. 21321 * 21322 * @param {Element} el 21323 * The element you want the computed style of 21324 * 21325 * @param {string} prop 21326 * The property name you want 21327 * 21328 * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397 21329 */ 21330function computedStyle(el, prop) { 21331 if (!el || !prop) { 21332 return ''; 21333 } 21334 21335 if (typeof _window2['default'].getComputedStyle === 'function') { 21336 var cs = _window2['default'].getComputedStyle(el); 21337 21338 return cs ? cs[prop] : ''; 21339 } 21340 21341 return el.currentStyle[prop] || ''; 21342} /** 21343 * @file computed-style.js 21344 * @module computed-style 21345 */ 21346 21347},{"95":95}],81:[function(_dereq_,module,exports){ 21348'use strict'; 21349 21350exports.__esModule = true; 21351exports.$$ = exports.$ = undefined; 21352
21353var _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 ', '.']); 21354 21355exports.isReal = isReal; 21356exports.isEl = isEl; 21357exports.getEl = getEl; 21358exports.createEl = createEl; 21359exports.textContent = textContent; 21360exports.insertElFirst = insertElFirst; 21361exports.getElData = getElData; 21362exports.hasElData = hasElData; 21363exports.removeElData = removeElData; 21364exports.hasElClass = hasElClass; 21365exports.addElClass = addElClass; 21366exports.removeElClass = removeElClass; 21367exports.toggleElClass = toggleElClass; 21368exports.setElAttributes = setElAttributes; 21369exports.getElAttributes = getElAttributes; 21370exports.getAttribute = getAttribute; 21371exports.setAttribute = setAttribute; 21372exports.removeAttribute = removeAttribute; 21373exports.blockTextSelection = blockTextSelection; 21374exports.unblockTextSelection = unblockTextSelection; 21375exports.findElPosition = findElPosition; 21376exports.getPointerPosition = getPointerPosition; 21377exports.isTextNode = isTextNode; 21378exports.emptyEl = emptyEl; 21379exports.normalizeContent = normalizeContent; 21380exports.appendContent = appendContent; 21381exports.insertContent = insertContent; 21382 21383var _document = _dereq_(94); 21384 21385var _document2 = _interopRequireDefault(_document); 21386 21387var _window = _dereq_(95); 21388 21389var _window2 = _interopRequireDefault(_window); 21390 21391var _guid = _dereq_(85); 21392 21393var Guid = _interopRequireWildcard(_guid); 21394 21395var _log = _dereq_(86); 21396 21397var _log2 = _interopRequireDefault(_log); 21398 21399var _tsml = _dereq_(98); 21400 21401var _tsml2 = _interopRequireDefault(_tsml); 21402 21403var _obj = _dereq_(88); 21404 21405function _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; } } 21406 21407function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21408 21409function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } /** 21410 * @file dom.js 21411 * @module dom 21412 */ 21413 21414 21415/** 21416 * Detect if a value is a string with any non-whitespace characters. 21417 * 21418 * @param {string} str 21419 * The string to check 21420 * 21421 * @return {boolean} 21422 * - True if the string is non-blank 21423 * - False otherwise 21424 * 21425 */ 21426function isNonBlankString(str) { 21427 return typeof str === 'string' && /\S/.test(str); 21428} 21429 21430/** 21431 * Throws an error if the passed string has whitespace. This is used by 21432 * class methods to be relatively consistent with the classList API. 21433 * 21434 * @param {string} str 21435 * The string to check for whitespace. 21436 * 21437 * @throws {Error} 21438 * Throws an error if there is whitespace in the string. 21439 * 21440 */ 21441function throwIfWhitespace(str) { 21442 if (/\s/.test(str)) { 21443 throw new Error('class has illegal whitespace characters'); 21444 } 21445} 21446 21447/** 21448 * Produce a regular expression for matching a className within an elements className. 21449 * 21450 * @param {string} className 21451 * The className to generate the RegExp for. 21452 * 21453 * @return {RegExp} 21454 * The RegExp that will check for a specific `className` in an elements 21455 * className. 21456 */ 21457function classRegExp(className) { 21458 return new RegExp('(^|\\s)' + className + '($|\\s)'); 21459} 21460 21461/** 21462 * Whether the current DOM interface appears to be real. 21463 * 21464 * @return {Boolean} 21465 */ 21466function isReal() { 21467 return ( 21468 21469 // Both document and window will never be undefined thanks to `global`. 21470 _document2['default'] === _window2['default'].document && 21471 21472 // In IE < 9, DOM methods return "object" as their type, so all we can 21473 // confidently check is that it exists. 21474 typeof _document2['default'].createElement !== 'undefined' 21475 ); 21476} 21477 21478/** 21479 * Determines, via duck typing, whether or not a value is a DOM element. 21480 * 21481 * @param {Mixed} value 21482 * The thing to check 21483 * 21484 * @return {boolean} 21485 * - True if it is a DOM element 21486 * - False otherwise 21487 */ 21488function isEl(value) { 21489 return (0, _obj.isObject)(value) && value.nodeType === 1; 21490} 21491 21492/** 21493 * Creates functions to query the DOM using a given method. 21494 * 21495 * @param {string} method 21496 * The method to create the query with. 21497 * 21498 * @return {Function} 21499 * The query method 21500 */ 21501function createQuerier(method) { 21502 return function (selector, context) { 21503 if (!isNonBlankString(selector)) { 21504 return _document2['default'][method](null); 21505 } 21506 if (isNonBlankString(context)) { 21507 context = _document2['default'].querySelector(context); 21508 } 21509 21510 var ctx = isEl(context) ? context : _document2['default']; 21511 21512 return ctx[method] && ctx[method](selector); 21513 }; 21514} 21515 21516/** 21517 * Shorthand for document.getElementById() 21518 * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs. 21519 * 21520 * @param {string} id 21521 * The id of the element to get 21522 * 21523 * @return {Element|null} 21524 * Element with supplied ID or null if there wasn't one. 21525 */ 21526function getEl(id) { 21527 if (id.indexOf('#') === 0) { 21528 id = id.slice(1); 21529 } 21530 21531 return _document2['default'].getElementById(id); 21532} 21533 21534/** 21535 * Creates an element and applies properties. 21536 * 21537 * @param {string} [tagName='div'] 21538 * Name of tag to be created. 21539 * 21540 * @param {Object} [properties={}] 21541 * Element properties to be applied. 21542 * 21543 * @param {Object} [attributes={}] 21544 * Element attributes to be applied. 21545 * 21546 * @param {String|Element|TextNode|Array|Function} [content] 21547 * Contents for the element (see: {@link dom:normalizeContent}) 21548 * 21549 * @return {Element} 21550 * The element that was created. 21551 */ 21552function createEl() { 21553 var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div'; 21554 var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 21555 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 21556 var content = arguments[3]; 21557 21558 var el = _document2['default'].createElement(tagName); 21559
vendor: 8,890 bytes, lines 21560-21907
21560 Object.getOwnPropertyNames(properties).forEach(function (propName) { 21561 var val = properties[propName]; 21562 21563 // See #2176 21564 // We originally were accepting both properties and attributes in the 21565 // same object, but that doesn't work so well. 21566 if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') { 21567 _log2['default'].warn((0, _tsml2['default'])(_templateObject, propName, val)); 21568 el.setAttribute(propName, val); 21569 21570 // Handle textContent since it's not supported everywhere and we have a 21571 // method for it. 21572 } else if (propName === 'textContent') { 21573 textContent(el, val); 21574 } else { 21575 el[propName] = val; 21576 } 21577 }); 21578 21579 Object.getOwnPropertyNames(attributes).forEach(function (attrName) { 21580 el.setAttribute(attrName, attributes[attrName]); 21581 }); 21582 21583 if (content) { 21584 appendContent(el, content); 21585 } 21586 21587 return el; 21588} 21589 21590/** 21591 * Injects text into an element, replacing any existing contents entirely. 21592 * 21593 * @param {Element} el 21594 * The element to add text content into 21595 * 21596 * @param {string} text 21597 * The text content to add. 21598 * 21599 * @return {Element} 21600 * The element with added text content. 21601 */ 21602function textContent(el, text) { 21603 if (typeof el.textContent === 'undefined') { 21604 el.innerText = text; 21605 } else { 21606 el.textContent = text; 21607 } 21608 return el; 21609} 21610 21611/** 21612 * Insert an element as the first child node of another 21613 * 21614 * @param {Element} child 21615 * Element to insert 21616 * 21617 * @param {Element} parent 21618 * Element to insert child into 21619 * 21620 */ 21621function insertElFirst(child, parent) { 21622 if (parent.firstChild) { 21623 parent.insertBefore(child, parent.firstChild); 21624 } else { 21625 parent.appendChild(child); 21626 } 21627} 21628 21629/** 21630 * Element Data Store. Allows for binding data to an element without putting it directly on the element. 21631 * Ex. Event listeners are stored here. 21632 * (also from jsninja.com, slightly modified and updated for closure compiler) 21633 * 21634 * @type {Object} 21635 * @private 21636 */ 21637var elData = {}; 21638 21639/* 21640 * Unique attribute name to store an element's guid in 21641 * 21642 * @type {string} 21643 * @constant 21644 * @private 21645 */ 21646var elIdAttr = 'vdata' + new Date().getTime(); 21647 21648/** 21649 * Returns the cache object where data for an element is stored 21650 * 21651 * @param {Element} el 21652 * Element to store data for. 21653 * 21654 * @return {Object} 21655 * The cache object for that el that was passed in. 21656 */ 21657function getElData(el) { 21658 var id = el[elIdAttr]; 21659 21660 if (!id) { 21661 id = el[elIdAttr] = Guid.newGUID(); 21662 } 21663 21664 if (!elData[id]) { 21665 elData[id] = {}; 21666 } 21667 21668 return elData[id]; 21669} 21670 21671/** 21672 * Returns whether or not an element has cached data 21673 * 21674 * @param {Element} el 21675 * Check if this element has cached data. 21676 * 21677 * @return {boolean} 21678 * - True if the DOM element has cached data. 21679 * - False otherwise. 21680 */ 21681function hasElData(el) { 21682 var id = el[elIdAttr]; 21683 21684 if (!id) { 21685 return false; 21686 } 21687 21688 return !!Object.getOwnPropertyNames(elData[id]).length; 21689} 21690 21691/** 21692 * Delete data for the element from the cache and the guid attr from getElementById 21693 * 21694 * @param {Element} el 21695 * Remove cached data for this element. 21696 */ 21697function removeElData(el) { 21698 var id = el[elIdAttr]; 21699 21700 if (!id) { 21701 return; 21702 } 21703 21704 // Remove all stored data 21705 delete elData[id]; 21706 21707 // Remove the elIdAttr property from the DOM node 21708 try { 21709 delete el[elIdAttr]; 21710 } catch (e) { 21711 if (el.removeAttribute) { 21712 el.removeAttribute(elIdAttr); 21713 } else { 21714 // IE doesn't appear to support removeAttribute on the document element 21715 el[elIdAttr] = null; 21716 } 21717 } 21718} 21719 21720/** 21721 * Check if an element has a CSS class 21722 * 21723 * @param {Element} element 21724 * Element to check 21725 * 21726 * @param {string} classToCheck 21727 * Class name to check for 21728 * 21729 * @return {boolean} 21730 * - True if the element had the class 21731 * - False otherwise. 21732 * 21733 * @throws {Error} 21734 * Throws an error if `classToCheck` has white space. 21735 */ 21736function hasElClass(element, classToCheck) { 21737 throwIfWhitespace(classToCheck); 21738 if (element.classList) { 21739 return element.classList.contains(classToCheck); 21740 } 21741 return classRegExp(classToCheck).test(element.className); 21742} 21743 21744/** 21745 * Add a CSS class name to an element 21746 * 21747 * @param {Element} element 21748 * Element to add class name to. 21749 * 21750 * @param {string} classToAdd 21751 * Class name to add. 21752 * 21753 * @return {Element} 21754 * The dom element with the added class name. 21755 */ 21756function addElClass(element, classToAdd) { 21757 if (element.classList) { 21758 element.classList.add(classToAdd); 21759 21760 // Don't need to `throwIfWhitespace` here because `hasElClass` will do it 21761 // in the case of classList not being supported. 21762 } else if (!hasElClass(element, classToAdd)) { 21763 element.className = (element.className + ' ' + classToAdd).trim(); 21764 } 21765 21766 return element; 21767} 21768 21769/** 21770 * Remove a CSS class name from an element 21771 * 21772 * @param {Element} element 21773 * Element to remove a class name from. 21774 * 21775 * @param {string} classToRemove 21776 * Class name to remove 21777 * 21778 * @return {Element} 21779 * The dom element with class name removed. 21780 */ 21781function removeElClass(element, classToRemove) { 21782 if (element.classList) { 21783 element.classList.remove(classToRemove); 21784 } else { 21785 throwIfWhitespace(classToRemove); 21786 element.className = element.className.split(/\s+/).filter(function (c) { 21787 return c !== classToRemove; 21788 }).join(' '); 21789 } 21790 21791 return element; 21792} 21793 21794/** 21795 * The callback definition for toggleElClass. 21796 * 21797 * @callback Dom~PredicateCallback 21798 * @param {Element} element 21799 * The DOM element of the Component. 21800 * 21801 * @param {string} classToToggle 21802 * The `className` that wants to be toggled 21803 * 21804 * @return {boolean|undefined} 21805 * - If true the `classToToggle` will get added to `element`. 21806 * - If false the `classToToggle` will get removed from `element`. 21807 * - If undefined this callback will be ignored 21808 */ 21809 21810/** 21811 * Adds or removes a CSS class name on an element depending on an optional 21812 * condition or the presence/absence of the class name. 21813 * 21814 * @param {Element} element 21815 * The element to toggle a class name on. 21816 * 21817 * @param {string} classToToggle 21818 * The class that should be toggled 21819 * 21820 * @param {boolean|PredicateCallback} [predicate] 21821 * See the return value for {@link Dom~PredicateCallback} 21822 * 21823 * @return {Element} 21824 * The element with a class that has been toggled. 21825 */ 21826function toggleElClass(element, classToToggle, predicate) { 21827 21828 // This CANNOT use `classList` internally because IE does not support the 21829 // second parameter to the `classList.toggle()` method! Which is fine because 21830 // `classList` will be used by the add/remove functions. 21831 var has = hasElClass(element, classToToggle); 21832 21833 if (typeof predicate === 'function') { 21834 predicate = predicate(element, classToToggle); 21835 } 21836 21837 if (typeof predicate !== 'boolean') { 21838 predicate = !has; 21839 } 21840 21841 // If the necessary class operation matches the current state of the 21842 // element, no action is required. 21843 if (predicate === has) { 21844 return; 21845 } 21846 21847 if (predicate) { 21848 addElClass(element, classToToggle); 21849 } else { 21850 removeElClass(element, classToToggle); 21851 } 21852 21853 return element; 21854} 21855 21856/** 21857 * Apply attributes to an HTML element. 21858 * 21859 * @param {Element} el 21860 * Element to add attributes to. 21861 * 21862 * @param {Object} [attributes] 21863 * Attributes to be applied. 21864 */ 21865function setElAttributes(el, attributes) { 21866 Object.getOwnPropertyNames(attributes).forEach(function (attrName) { 21867 var attrValue = attributes[attrName]; 21868 21869 if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) { 21870 el.removeAttribute(attrName); 21871 } else { 21872 el.setAttribute(attrName, attrValue === true ? '' : attrValue); 21873 } 21874 }); 21875} 21876 21877/** 21878 * Get an element's attribute values, as defined on the HTML tag 21879 * Attributes are not the same as properties. They're defined on the tag 21880 * or with setAttribute (which shouldn't be used with HTML) 21881 * This will return true or false for boolean attributes. 21882 * 21883 * @param {Element} tag 21884 * Element from which to get tag attributes. 21885 * 21886 * @return {Object} 21887 * All attributes of the element. 21888 */ 21889function getElAttributes(tag) { 21890 var obj = {}; 21891 21892 // known boolean attributes 21893 // we can check for matching boolean properties, but older browsers 21894 // won't know about HTML5 boolean attributes that we still read from 21895 var knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ','; 21896 21897 if (tag && tag.attributes && tag.attributes.length > 0) { 21898 var attrs = tag.attributes; 21899 21900 for (var i = attrs.length - 1; i >= 0; i--) { 21901 var attrName = attrs[i].name; 21902 var attrVal = attrs[i].value; 21903 21904 // check for known booleans 21905 // the matching element property will return a value for typeof 21906 if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) { 21907 // the value of an included boolean attribute is typically an empty
21908 // string ('') which would equal false if we just check for a false value. 21909 // we also don't want support bad code like autoplay='false' 21910 attrVal = attrVal !== null ? true : false; 21911 } 21912 21913 obj[attrName] = attrVal; 21914 } 21915 } 21916 21917 return obj; 21918} 21919 21920/** 21921 * Get the value of an element's attribute 21922 * 21923 * @param {Element} el 21924 * A DOM element 21925 * 21926 * @param {string} attribute 21927 * Attribute to get the value of 21928 * 21929 * @return {string} 21930 * value of the attribute 21931 */ 21932function getAttribute(el, attribute) { 21933 return el.getAttribute(attribute); 21934} 21935 21936/** 21937 * Set the value of an element's attribute 21938 * 21939 * @param {Element} el 21940 * A DOM element 21941 * 21942 * @param {string} attribute 21943 * Attribute to set 21944 * 21945 * @param {string} value 21946 * Value to set the attribute to 21947 */ 21948function setAttribute(el, attribute, value) { 21949 el.setAttribute(attribute, value); 21950} 21951 21952/** 21953 * Remove an element's attribute 21954 * 21955 * @param {Element} el 21956 * A DOM element 21957 * 21958 * @param {string} attribute 21959 * Attribute to remove 21960 */ 21961function removeAttribute(el, attribute) { 21962 el.removeAttribute(attribute); 21963} 21964 21965/** 21966 * Attempt to block the ability to select text while dragging controls 21967 */ 21968function blockTextSelection() { 21969 _document2['default'].body.focus(); 21970 _document2['default'].onselectstart = function () { 21971 return false; 21972 }; 21973} 21974 21975/** 21976 * Turn off text selection blocking 21977 */ 21978function unblockTextSelection() { 21979 _document2['default'].onselectstart = function () { 21980 return true; 21981 }; 21982} 21983 21984/** 21985 * The postion of a DOM element on the page. 21986 * 21987 * @typedef {Object} Dom~Position 21988 * 21989 * @property {number} left 21990 * Pixels to the left 21991 * 21992 * @property {number} top 21993 * Pixels on top 21994 */ 21995 21996/** 21997 * Offset Left. 21998 * getBoundingClientRect technique from 21999 * John Resig 22000 * 22001 * @see http://ejohn.org/blog/getboundingclientrect-is-awesome/ 22002 * 22003 * @param {Element} el 22004 * Element from which to get offset 22005 * 22006 * @return {Dom~Position} 22007 * The position of the element that was passed in. 22008 */ 22009function findElPosition(el) { 22010 var box = void 0; 22011 22012 if (el.getBoundingClientRect && el.parentNode) { 22013 box = el.getBoundingClientRect(); 22014 } 22015 22016 if (!box) { 22017 return { 22018 left: 0, 22019 top: 0 22020 }; 22021 } 22022 22023 var docEl = _document2['default'].documentElement; 22024 var body = _document2['default'].body; 22025 22026 var clientLeft = docEl.clientLeft || body.clientLeft || 0; 22027 var scrollLeft = _window2['default'].pageXOffset || body.scrollLeft; 22028 var left = box.left + scrollLeft - clientLeft; 22029 22030 var clientTop = docEl.clientTop || body.clientTop || 0; 22031 var scrollTop = _window2['default'].pageYOffset || body.scrollTop; 22032 var top = box.top + scrollTop - clientTop; 22033 22034 // Android sometimes returns slightly off decimal values, so need to round 22035 return { 22036 left: Math.round(left), 22037 top: Math.round(top) 22038 }; 22039} 22040 22041/** 22042 * x and y coordinates for a dom element or mouse pointer 22043 * 22044 * @typedef {Object} Dom~Coordinates 22045 * 22046 * @property {number} x 22047 * x coordinate in pixels 22048 * 22049 * @property {number} y 22050 * y coordinate in pixels 22051 */ 22052 22053/** 22054 * Get pointer position in element 22055 * Returns an object with x and y coordinates. 22056 * The base on the coordinates are the bottom left of the element. 22057 * 22058 * @param {Element} el 22059 * Element on which to get the pointer position on 22060 * 22061 * @param {EventTarget~Event} event 22062 * Event object 22063 * 22064 * @return {Dom~Coordinates} 22065 * A Coordinates object corresponding to the mouse position. 22066 * 22067 */ 22068function getPointerPosition(el, event) { 22069 var position = {}; 22070 var box = findElPosition(el); 22071 var boxW = el.offsetWidth; 22072 var boxH = el.offsetHeight; 22073 22074 var boxY = box.top; 22075 var boxX = box.left; 22076 var pageY = event.pageY; 22077 var pageX = event.pageX; 22078 22079 if (event.changedTouches) { 22080 pageX = event.changedTouches[0].pageX; 22081 pageY = event.changedTouches[0].pageY; 22082 } 22083 22084 position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH)); 22085 position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW)); 22086 22087 return position; 22088} 22089 22090/** 22091 * Determines, via duck typing, whether or not a value is a text node. 22092 * 22093 * @param {Mixed} value 22094 * Check if this value is a text node. 22095 * 22096 * @return {boolean} 22097 * - True if it is a text node 22098 * - False otherwise 22099 */ 22100function isTextNode(value) { 22101 return (0, _obj.isObject)(value) && value.nodeType === 3; 22102} 22103
vendor: 4,080 bytes, lines 22104-22235
22104/** 22105 * Empties the contents of an element. 22106 * 22107 * @param {Element} el 22108 * The element to empty children from 22109 * 22110 * @return {Element} 22111 * The element with no children 22112 */ 22113function emptyEl(el) { 22114 while (el.firstChild) { 22115 el.removeChild(el.firstChild); 22116 } 22117 return el; 22118} 22119 22120/** 22121 * Normalizes content for eventual insertion into the DOM. 22122 * 22123 * This allows a wide range of content definition methods, but protects 22124 * from falling into the trap of simply writing to `innerHTML`, which is 22125 * an XSS concern. 22126 * 22127 * The content for an element can be passed in multiple types and 22128 * combinations, whose behavior is as follows: 22129 * 22130 * @param {String|Element|TextNode|Array|Function} content 22131 * - String: Normalized into a text node. 22132 * - Element/TextNode: Passed through. 22133 * - Array: A one-dimensional array of strings, elements, nodes, or functions 22134 * (which return single strings, elements, or nodes). 22135 * - Function: If the sole argument, is expected to produce a string, element, 22136 * node, or array as defined above. 22137 * 22138 * @return {Array} 22139 * All of the content that was passed in normalized. 22140 */ 22141function normalizeContent(content) { 22142 22143 // First, invoke content if it is a function. If it produces an array, 22144 // that needs to happen before normalization. 22145 if (typeof content === 'function') { 22146 content = content(); 22147 } 22148 22149 // Next up, normalize to an array, so one or many items can be normalized, 22150 // filtered, and returned. 22151 return (Array.isArray(content) ? content : [content]).map(function (value) { 22152 22153 // First, invoke value if it is a function to produce a new value, 22154 // which will be subsequently normalized to a Node of some kind. 22155 if (typeof value === 'function') { 22156 value = value(); 22157 } 22158 22159 if (isEl(value) || isTextNode(value)) { 22160 return value; 22161 } 22162 22163 if (typeof value === 'string' && /\S/.test(value)) { 22164 return _document2['default'].createTextNode(value); 22165 } 22166 }).filter(function (value) { 22167 return value; 22168 }); 22169} 22170 22171/** 22172 * Normalizes and appends content to an element. 22173 * 22174 * @param {Element} el 22175 * Element to append normalized content to. 22176 * 22177 * 22178 * @param {String|Element|TextNode|Array|Function} content 22179 * See the `content` argument of {@link dom:normalizeContent} 22180 * 22181 * @return {Element} 22182 * The element with appended normalized content. 22183 */ 22184function appendContent(el, content) { 22185 normalizeContent(content).forEach(function (node) { 22186 return el.appendChild(node); 22187 }); 22188 return el; 22189} 22190 22191/** 22192 * Normalizes and inserts content into an element; this is identical to 22193 * `appendContent()`, except it empties the element first. 22194 * 22195 * @param {Element} el 22196 * Element to insert normalized content into. 22197 * 22198 * @param {String|Element|TextNode|Array|Function} content 22199 * See the `content` argument of {@link dom:normalizeContent} 22200 * 22201 * @return {Element} 22202 * The element with inserted normalized content. 22203 * 22204 */ 22205function insertContent(el, content) { 22206 return appendContent(emptyEl(el), content); 22207} 22208 22209/** 22210 * Finds a single DOM element matching `selector` within the optional 22211 * `context` of another DOM element (defaulting to `document`). 22212 * 22213 * @param {string} selector 22214 * A valid CSS selector, which will be passed to `querySelector`. 22215 * 22216 * @param {Element|String} [context=document] 22217 * A DOM element within which to query. Can also be a selector 22218 * string in which case the first matching element will be used 22219 * as context. If missing (or no element matches selector), falls 22220 * back to `document`. 22221 * 22222 * @return {Element|null} 22223 * The element that was found or null. 22224 */ 22225var $ = exports.$ = createQuerier('querySelector'); 22226 22227/** 22228 * Finds a all DOM elements matching `selector` within the optional 22229 * `context` of another DOM element (defaulting to `document`). 22230 * 22231 * @param {string} selector 22232 * A valid CSS selector, which will be passed to `querySelectorAll`. 22233 * 22234 * @param {Element|String} [context=document] 22235 * A DOM element within which to query. Can also be a selector
22236 * string in which case the first matching element will be used 22237 * as context. If missing (or no element matches selector), falls 22238 * back to `document`. 22239 * 22240 * @return {NodeList} 22241 * A element list of elements that were found. Will be empty if none were found. 22242 * 22243 */ 22244var $$ = exports.$$ = createQuerier('querySelectorAll'); 22245 22246},{"85":85,"86":86,"88":88,"94":94,"95":95,"98":98}],82:[function(_dereq_,module,exports){ 22247'use strict'; 22248 22249exports.__esModule = true; 22250exports.fixEvent = fixEvent; 22251exports.on = on; 22252exports.off = off; 22253exports.trigger = trigger; 22254exports.one = one; 22255 22256var _dom = _dereq_(81); 22257 22258var Dom = _interopRequireWildcard(_dom); 22259 22260var _guid = _dereq_(85); 22261 22262var Guid = _interopRequireWildcard(_guid); 22263 22264var _log = _dereq_(86); 22265 22266var _log2 = _interopRequireDefault(_log); 22267 22268var _window = _dereq_(95); 22269 22270var _window2 = _interopRequireDefault(_window); 22271 22272var _document = _dereq_(94); 22273 22274var _document2 = _interopRequireDefault(_document); 22275 22276function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 22277 22278function _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; } } 22279 22280/** 22281 * Clean up the listener cache and dispatchers 22282 * 22283 * @param {Element|Object} elem 22284 * Element to clean up 22285 * 22286 * @param {string} type 22287 * Type of event to clean up 22288 */ 22289function _cleanUpEvents(elem, type) { 22290 var data = Dom.getElData(elem); 22291 22292 // Remove the events of a particular type if there are none left 22293 if (data.handlers[type].length === 0) { 22294 delete data.handlers[type]; 22295 // data.handlers[type] = null; 22296 // Setting to null was causing an error with data.handlers 22297 22298 // Remove the meta-handler from the element 22299 if (elem.removeEventListener) { 22300 elem.removeEventListener(type, data.dispatcher, false); 22301 } else if (elem.detachEvent) { 22302 elem.detachEvent('on' + type, data.dispatcher); 22303 } 22304 } 22305 22306 // Remove the events object if there are no types left 22307 if (Object.getOwnPropertyNames(data.handlers).length <= 0) { 22308 delete data.handlers; 22309 delete data.dispatcher; 22310 delete data.disabled; 22311 } 22312 22313 // Finally remove the element data if there is no data left 22314 if (Object.getOwnPropertyNames(data).length === 0) { 22315 Dom.removeElData(elem); 22316 } 22317} 22318 22319/** 22320 * Loops through an array of event types and calls the requested method for each type. 22321 * 22322 * @param {Function} fn 22323 * The event method we want to use. 22324 * 22325 * @param {Element|Object} elem 22326 * Element or object to bind listeners to 22327 * 22328 * @param {string} type 22329 * Type of event to bind to. 22330 * 22331 * @param {EventTarget~EventListener} callback 22332 * Event listener. 22333 */ 22334/** 22335 * @file events.js. An Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/) 22336 * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible) 22337 * This should work very similarly to jQuery's events, however it's based off the book version which isn't as 22338 * robust as jquery's, so there's probably some differences. 22339 * 22340 * @module events 22341 */ 22342 22343function _handleMultipleEvents(fn, elem, types, callback) { 22344 types.forEach(function (type) { 22345 // Call the event method for each one of the types 22346 fn(elem, type, callback); 22347 }); 22348} 22349 22350/** 22351 * Fix a native event to have standard property values 22352 * 22353 * @param {Object} event 22354 * Event object to fix. 22355 * 22356 * @return {Object} 22357 * Fixed event object. 22358 */ 22359function fixEvent(event) { 22360 22361 function returnTrue() { 22362 return true; 22363 } 22364 22365 function returnFalse() { 22366 return false; 22367 } 22368 22369 // Test if fixing up is needed 22370 // Used to check if !event.stopPropagation instead of isPropagationStopped 22371 // But native events return true for stopPropagation, but don't have 22372 // other expected methods like isPropagationStopped. Seems to be a problem 22373 // with the Javascript Ninja code. So we're just overriding all events now. 22374 if (!event || !event.isPropagationStopped) { 22375 (function () { 22376 var old = event || _window2['default'].event; 22377 22378 event = {}; 22379 // Clone the old object so that we can modify the values event = {}; 22380 // IE8 Doesn't like when you mess with native event properties 22381 // Firefox returns false for event.hasOwnProperty('type') and other props 22382 // which makes copying more difficult. 22383 // TODO: Probably best to create a whitelist of event props 22384 for (var key in old) {
vendor: 4,950 bytes, lines 22385-22551
22385 // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y 22386 // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation 22387 // and webkitMovementX/Y 22388 if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') { 22389 // Chrome 32+ warns if you try to copy deprecated returnValue, but 22390 // we still want to if preventDefault isn't supported (IE8). 22391 if (!(key === 'returnValue' && old.preventDefault)) { 22392 event[key] = old[key]; 22393 } 22394 } 22395 } 22396 22397 // The event occurred on this element 22398 if (!event.target) { 22399 event.target = event.srcElement || _document2['default']; 22400 } 22401 22402 // Handle which other element the event is related to 22403 if (!event.relatedTarget) { 22404 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; 22405 } 22406 22407 // Stop the default browser action 22408 event.preventDefault = function () { 22409 if (old.preventDefault) { 22410 old.preventDefault(); 22411 } 22412 event.returnValue = false; 22413 old.returnValue = false; 22414 event.defaultPrevented = true; 22415 }; 22416 22417 event.defaultPrevented = false; 22418 22419 // Stop the event from bubbling 22420 event.stopPropagation = function () { 22421 if (old.stopPropagation) { 22422 old.stopPropagation(); 22423 } 22424 event.cancelBubble = true; 22425 old.cancelBubble = true; 22426 event.isPropagationStopped = returnTrue; 22427 }; 22428 22429 event.isPropagationStopped = returnFalse; 22430 22431 // Stop the event from bubbling and executing other handlers 22432 event.stopImmediatePropagation = function () { 22433 if (old.stopImmediatePropagation) { 22434 old.stopImmediatePropagation(); 22435 } 22436 event.isImmediatePropagationStopped = returnTrue; 22437 event.stopPropagation(); 22438 }; 22439 22440 event.isImmediatePropagationStopped = returnFalse; 22441 22442 // Handle mouse position 22443 if (event.clientX !== null && event.clientX !== undefined) { 22444 var doc = _document2['default'].documentElement; 22445 var body = _document2['default'].body; 22446 22447 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); 22448 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); 22449 } 22450 22451 // Handle key presses 22452 event.which = event.charCode || event.keyCode; 22453 22454 // Fix button for mouse clicks: 22455 // 0 == left; 1 == middle; 2 == right 22456 if (event.button !== null && event.button !== undefined) { 22457 22458 // The following is disabled because it does not pass videojs-standard 22459 // and... yikes. 22460 /* eslint-disable */ 22461 event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0; 22462 /* eslint-enable */ 22463 } 22464 })(); 22465 } 22466 22467 // Returns fixed-up instance 22468 return event; 22469} 22470 22471/** 22472 * Add an event listener to element 22473 * It stores the handler function in a separate cache object 22474 * and adds a generic handler to the element's event, 22475 * along with a unique id (guid) to the element. 22476 * 22477 * @param {Element|Object} elem 22478 * Element or object to bind listeners to 22479 * 22480 * @param {string|string[]} type 22481 * Type of event to bind to. 22482 * 22483 * @param {EventTarget~EventListener} fn 22484 * Event listener. 22485 */ 22486function on(elem, type, fn) { 22487 if (Array.isArray(type)) { 22488 return _handleMultipleEvents(on, elem, type, fn); 22489 } 22490 22491 var data = Dom.getElData(elem); 22492 22493 // We need a place to store all our handler data 22494 if (!data.handlers) { 22495 data.handlers = {}; 22496 } 22497 22498 if (!data.handlers[type]) { 22499 data.handlers[type] = []; 22500 } 22501 22502 if (!fn.guid) { 22503 fn.guid = Guid.newGUID(); 22504 } 22505 22506 data.handlers[type].push(fn); 22507 22508 if (!data.dispatcher) { 22509 data.disabled = false; 22510 22511 data.dispatcher = function (event, hash) { 22512 22513 if (data.disabled) { 22514 return; 22515 } 22516 22517 event = fixEvent(event); 22518 22519 var handlers = data.handlers[event.type]; 22520 22521 if (handlers) { 22522 // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off. 22523 var handlersCopy = handlers.slice(0); 22524 22525 for (var m = 0, n = handlersCopy.length; m < n; m++) { 22526 if (event.isImmediatePropagationStopped()) { 22527 break; 22528 } else { 22529 try { 22530 handlersCopy[m].call(elem, event, hash); 22531 } catch (e) { 22532 _log2['default'].error(e); 22533 } 22534 } 22535 } 22536 } 22537 }; 22538 } 22539 22540 if (data.handlers[type].length === 1) { 22541 if (elem.addEventListener) { 22542 elem.addEventListener(type, data.dispatcher, false); 22543 } else if (elem.attachEvent) { 22544 elem.attachEvent('on' + type, data.dispatcher); 22545 } 22546 } 22547} 22548 22549/** 22550 * Removes event listeners from an element 22551 *
22552 * @param {Element|Object} elem 22553 * Object to remove listeners from. 22554 * 22555 * @param {string|string[]} [type] 22556 * Type of listener to remove. Don't include to remove all events from element. 22557 * 22558 * @param {EventTarget~EventListener} [fn] 22559 * Specific listener to remove. Don't include to remove listeners for an event 22560 * type. 22561 */ 22562function off(elem, type, fn) { 22563 // Don't want to add a cache object through getElData if not needed 22564 if (!Dom.hasElData(elem)) { 22565 return; 22566 } 22567 22568 var data = Dom.getElData(elem); 22569 22570 // If no events exist, nothing to unbind 22571 if (!data.handlers) { 22572 return; 22573 } 22574 22575 if (Array.isArray(type)) { 22576 return _handleMultipleEvents(off, elem, type, fn); 22577 } 22578 22579 // Utility function 22580 var removeType = function removeType(t) { 22581 data.handlers[t] = []; 22582 _cleanUpEvents(elem, t); 22583 }; 22584 22585 // Are we removing all bound events? 22586 if (!type) { 22587 for (var t in data.handlers) { 22588 removeType(t); 22589 } 22590 return; 22591 } 22592 22593 var handlers = data.handlers[type]; 22594 22595 // If no handlers exist, nothing to unbind 22596 if (!handlers) { 22597 return; 22598 } 22599 22600 // If no listener was provided, remove all listeners for type 22601 if (!fn) { 22602 removeType(type); 22603 return; 22604 } 22605 22606 // We're only removing a single handler 22607 if (fn.guid) { 22608 for (var n = 0; n < handlers.length; n++) { 22609 if (handlers[n].guid === fn.guid) { 22610 handlers.splice(n--, 1); 22611 } 22612 } 22613 } 22614 22615 _cleanUpEvents(elem, type); 22616} 22617 22618/** 22619 * Trigger an event for an element 22620 * 22621 * @param {Element|Object} elem 22622 * Element to trigger an event on 22623 * 22624 * @param {EventTarget~Event|string} event 22625 * A string (the type) or an event object with a type attribute 22626 * 22627 * @param {Object} [hash] 22628 * data hash to pass along with the event 22629 * 22630 * @return {boolean|undefined} 22631 * - Returns the opposite of `defaultPrevented` if default was prevented 22632 * - Otherwise returns undefined 22633 */ 22634function trigger(elem, event, hash) { 22635 // Fetches element data and a reference to the parent (for bubbling). 22636 // Don't want to add a data object to cache for every parent, 22637 // so checking hasElData first. 22638 var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {}; 22639 var parent = elem.parentNode || elem.ownerDocument; 22640 // type = event.type || event, 22641 // handler; 22642 22643 // If an event name was passed as a string, creates an event out of it 22644 if (typeof event === 'string') { 22645 event = { type: event, target: elem }; 22646 } 22647 // Normalizes the event properties. 22648 event = fixEvent(event); 22649 22650 // If the passed element has a dispatcher, executes the established handlers. 22651 if (elemData.dispatcher) { 22652 elemData.dispatcher.call(elem, event, hash); 22653 } 22654 22655 // Unless explicitly stopped or the event does not bubble (e.g. media events) 22656 // recursively calls this function to bubble the event up the DOM. 22657 if (parent && !event.isPropagationStopped() && event.bubbles === true) { 22658 trigger.call(null, parent, event, hash); 22659 22660 // If at the top of the DOM, triggers the default action unless disabled. 22661 } else if (!parent && !event.defaultPrevented) { 22662 var targetData = Dom.getElData(event.target); 22663 22664 // Checks if the target has a default action for this event. 22665 if (event.target[event.type]) { 22666 // Temporarily disables event dispatching on the target as we have already executed the handler. 22667 targetData.disabled = true; 22668 // Executes the default action. 22669 if (typeof event.target[event.type] === 'function') { 22670 event.target[event.type](); 22671 } 22672 // Re-enables event dispatching. 22673 targetData.disabled = false; 22674 } 22675 } 22676 22677 // Inform the triggerer if the default was prevented by returning false 22678 return !event.defaultPrevented; 22679} 22680 22681/** 22682 * Trigger a listener only once for an event 22683 * 22684 * @param {Element|Object} elem 22685 * Element or object to bind to. 22686 * 22687 * @param {string|string[]} type 22688 * Name/type of event 22689 * 22690 * @param {Event~EventListener} fn 22691 * Event Listener function 22692 */ 22693function one(elem, type, fn) { 22694 if (Array.isArray(type)) { 22695 return _handleMultipleEvents(one, elem, type, fn); 22696 } 22697 var func = function func() { 22698 off(elem, type, func); 22699 fn.apply(this, arguments); 22700 }; 22701 22702 // copy the guid to the new function so it can removed using the original function's ID 22703 func.guid = fn.guid = fn.guid || Guid.newGUID(); 22704 on(elem, type, func); 22705} 22706 22707},{"81":81,"85":85,"86":86,"94":94,"95":95}],83:[function(_dereq_,module,exports){ 22708'use strict'; 22709 22710exports.__esModule = true; 22711exports.throttle = exports.bind = undefined; 22712 22713var _guid = _dereq_(85); 22714 22715/**
22716 * Bind (a.k.a proxy or Context). A simple method for changing the context of a function 22717 * It also stores a unique id on the function so it can be easily removed from events. 22718 * 22719 * @param {Mixed} context 22720 * The object to bind as scope. 22721 * 22722 * @param {Function} fn 22723 * The function to be bound to a scope. 22724 * 22725 * @param {number} [uid] 22726 * An optional unique ID for the function to be set 22727 * 22728 * @return {Function} 22729 * The new function that will be bound into the context given 22730 */ 22731var bind = exports.bind = function bind(context, fn, uid) { 22732 // Make sure the function has a unique ID 22733 if (!fn.guid) { 22734 fn.guid = (0, _guid.newGUID)(); 22735 } 22736 22737 // Create the new function that changes the context 22738 var bound = function bound() { 22739 return fn.apply(context, arguments); 22740 }; 22741 22742 // Allow for the ability to individualize this function 22743 // Needed in the case where multiple objects might share the same prototype 22744 // IF both items add an event listener with the same function, then you try to remove just one 22745 // it will remove both because they both have the same guid. 22746 // when using this, you need to use the bind method when you remove the listener as well. 22747 // currently used in text tracks 22748 bound.guid = uid ? uid + '_' + fn.guid : fn.guid; 22749 22750 return bound; 22751}; 22752 22753/** 22754 * Wraps the given function, `fn`, with a new function that only invokes `fn` 22755 * at most once per every `wait` milliseconds. 22756 * 22757 * @param {Function} fn 22758 * The function to be throttled. 22759 * 22760 * @param {Number} wait 22761 * The number of milliseconds by which to throttle. 22762 * 22763 * @return {Function} 22764 */ 22765/** 22766 * @file fn.js 22767 * @module fn 22768 */ 22769var throttle = exports.throttle = function throttle(fn, wait) { 22770 var last = Date.now(); 22771 22772 var throttled = function throttled() { 22773 var now = Date.now(); 22774 22775 if (now - last >= wait) { 22776 fn.apply(undefined, arguments); 22777 last = now; 22778 } 22779 }; 22780 22781 return throttled; 22782}; 22783 22784},{"85":85}],84:[function(_dereq_,module,exports){ 22785'use strict'; 22786 22787exports.__esModule = true; 22788/** 22789 * @file format-time.js 22790 * @module Format-time 22791 */ 22792 22793/** 22794 * Format seconds as a time string, H:MM:SS or M:SS. Supplying a guide (in seconds) 22795 * will force a number of leading zeros to cover the length of the guide. 22796 * 22797 * @param {number} seconds 22798 * Number of seconds to be turned into a string 22799 * 22800 * @param {number} guide 22801 * Number (in seconds) to model the string after 22802 * 22803 * @return {string} 22804 * Time formatted as H:MM:SS or M:SS 22805 */ 22806function formatTime(seconds) { 22807 var guide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : seconds; 22808 22809 seconds = seconds < 0 ? 0 : seconds; 22810 var s = Math.floor(seconds % 60); 22811 var m = Math.floor(seconds / 60 % 60); 22812 var h = Math.floor(seconds / 3600); 22813 var gm = Math.floor(guide / 60 % 60); 22814 var gh = Math.floor(guide / 3600); 22815 22816 // handle invalid times 22817 if (isNaN(seconds) || seconds === Infinity) { 22818 // '-' is false for all relational operators (e.g. <, >=) so this setting 22819 // will add the minimum number of fields specified by the guide 22820 h = m = s = '-'; 22821 } 22822 22823 // Check if we need to show hours 22824 h = h > 0 || gh > 0 ? h + ':' : ''; 22825 22826 // If hours are showing, we may need to add a leading zero. 22827 // Always show at least one digit of minutes. 22828 m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':'; 22829 22830 // Check if leading zero is need for seconds 22831 s = s < 10 ? '0' + s : s; 22832 22833 return h + m + s; 22834} 22835 22836exports['default'] = formatTime; 22837 22838},{}],85:[function(_dereq_,module,exports){ 22839"use strict"; 22840 22841exports.__esModule = true; 22842exports.newGUID = newGUID; 22843/** 22844 * @file guid.js 22845 * @module guid 22846 */ 22847 22848/** 22849 * Unique ID for an element or function 22850 * @type {Number} 22851 */ 22852var _guid = 1; 22853 22854/** 22855 * Get a unique auto-incrementing ID by number that has not been returned before. 22856 * 22857 * @return {number} 22858 * A new unique ID. 22859 */ 22860function newGUID() { 22861 return _guid++; 22862} 22863 22864},{}],86:[function(_dereq_,module,exports){ 22865'use strict'; 22866 22867exports.__esModule = true; 22868exports.logByType = undefined; 22869 22870var _window = _dereq_(95); 22871 22872var _window2 = _interopRequireDefault(_window); 22873 22874var _browser = _dereq_(78); 22875 22876var _obj = _dereq_(88); 22877 22878function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 22879 22880var log = void 0; 22881 22882/** 22883 * Log messages to the console and history based on the type of message 22884 * 22885 * @param {string} type 22886 * The name of the console method to use. 22887 * 22888 * @param {Array} args 22889 * The arguments to be passed to the matching console method. 22890 * 22891 * @param {boolean} [stringify] 22892 * By default, only old IEs should get console argument stringification, 22893 * but this is exposed as a parameter to facilitate testing. 22894 */ 22895/** 22896 * @file log.js 22897 * @module log 22898 */ 22899var logByType = exports.logByType = function logByType(type, args) { 22900 var stringify = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : !!_browser.IE_VERSION && _browser.IE_VERSION < 11; 22901 22902 22903 if (type !== 'log') { 22904 22905 // add the type to the front of the message when it's not "log" 22906 args.unshift(type.toUpperCase() + ':'); 22907 } 22908 22909 // add to history 22910 log.history.push(args); 22911 22912 // add console prefix after adding to history 22913 args.unshift('VIDEOJS:'); 22914 22915 // If there's no console then don't try to output messages, but they will 22916 // still be stored in `log.history`. 22917 // 22918 // Was setting these once outside of this function, but containing them 22919 // in the function makes it easier to test cases where console doesn't exist 22920 // when the module is executed. 22921 var fn = _window2['default'].console && _window2['default'].console[type]; 22922 22923 // Bail out if there's no console. 22924 if (!fn) { 22925 return; 22926 } 22927 22928 // IEs previous to 11 log objects uselessly as "[object Object]"; so, JSONify 22929 // objects and arrays for those less-capable browsers. 22930 if (stringify) { 22931 args = args.map(function (a) { 22932 if ((0, _obj.isObject)(a) || Array.isArray(a)) { 22933 try { 22934 return JSON.stringify(a); 22935 } catch (x) { 22936 return String(a); 22937 } 22938 } 22939 22940 // Cast to string before joining, so we get null and undefined explicitly 22941 // included in output (as we would in a modern console). 22942 return String(a); 22943 }).join(' '); 22944 } 22945 22946 // Old IE versions do not allow .apply() for console methods (they are 22947 // reported as objects rather than functions). 22948 if (!fn.apply) { 22949 fn(args); 22950 } else { 22951 fn[Array.isArray(args) ? 'apply' : 'call'](_window2['default'].console, args); 22952 } 22953}; 22954 22955/** 22956 * Log plain debug messages 22957 * 22958 * @param {Mixed[]} args 22959 * One or more messages or objects that should be logged. 22960 */ 22961log = function log() { 22962 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { 22963 args[_key] = arguments[_key]; 22964 } 22965 22966 logByType('log', args); 22967}; 22968 22969/** 22970 * Keep a history of log messages 22971 * 22972 * @type {Array} 22973 */ 22974log.history = []; 22975 22976/** 22977 * Log error messages 22978 * 22979 * @param {Mixed[]} args 22980 * One or more messages or objects that should be logged as an error 22981 */ 22982log.error = function () { 22983 for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 22984 args[_key2] = arguments[_key2]; 22985 } 22986 22987 return logByType('error', args); 22988}; 22989 22990/** 22991 * Log warning messages 22992 * 22993 * @param {Mixed[]} args 22994 * One or more messages or objects that should be logged as a warning. 22995 */ 22996log.warn = function () { 22997 for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { 22998 args[_key3] = arguments[_key3]; 22999 } 23000 23001 return logByType('warn', args); 23002}; 23003 23004exports['default'] = log; 23005 23006},{"78":78,"88":88,"95":95}],87:[function(_dereq_,module,exports){ 23007'use strict'; 23008 23009exports.__esModule = true; 23010exports['default'] = mergeOptions; 23011 23012var _obj = _dereq_(88); 23013 23014/** 23015 * Deep-merge one or more options objects, recursively merging **only** plain 23016 * object properties. 23017 * 23018 * @param {Object[]} sources
23019 * One or more objects to merge into a new object. 23020 * 23021 * @returns {Object} 23022 * A new object that is the merged result of all sources. 23023 */ 23024function mergeOptions() { 23025 var result = {}; 23026 23027 for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) { 23028 sources[_key] = arguments[_key]; 23029 } 23030 23031 sources.forEach(function (source) { 23032 if (!source) { 23033 return; 23034 } 23035 23036 (0, _obj.each)(source, function (value, key) { 23037 if (!(0, _obj.isPlain)(value)) { 23038 result[key] = value; 23039 return; 23040 } 23041 23042 if (!(0, _obj.isPlain)(result[key])) { 23043 result[key] = {}; 23044 } 23045 23046 result[key] = mergeOptions(result[key], value); 23047 }); 23048 }); 23049 23050 return result; 23051} /** 23052 * @file merge-options.js 23053 * @module merge-options 23054 */ 23055 23056},{"88":88}],88:[function(_dereq_,module,exports){ 23057'use strict'; 23058 23059exports.__esModule = true; 23060 23061var _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; }; 23062 23063exports.each = each; 23064exports.reduce = reduce; 23065exports.assign = assign; 23066exports.isObject = isObject; 23067exports.isPlain = isPlain; 23068/** 23069 * @file obj.js 23070 * @module obj 23071 */ 23072 23073/** 23074 * @callback obj:EachCallback 23075 * 23076 * @param {Mixed} value 23077 * The current key for the object that is being iterated over. 23078 * 23079 * @param {string} key 23080 * The current key-value for object that is being iterated over 23081 */ 23082 23083/** 23084 * @callback obj:ReduceCallback 23085 * 23086 * @param {Mixed} accum 23087 * The value that is accumulating over the reduce loop. 23088 * 23089 * @param {Mixed} value 23090 * The current key for the object that is being iterated over. 23091 * 23092 * @param {string} key 23093 * The current key-value for object that is being iterated over 23094 * 23095 * @return {Mixed} 23096 * The new accumulated value. 23097 */ 23098var toString = Object.prototype.toString; 23099 23100/** 23101 * Array-like iteration for objects. 23102 * 23103 * @param {Object} object 23104 * The object to iterate over 23105 * 23106 * @param {obj:EachCallback} fn 23107 * The callback function which is called for each key in the object. 23108 */ 23109function each(object, fn) { 23110 Object.keys(object).forEach(function (key) { 23111 return fn(object[key], key); 23112 }); 23113} 23114 23115/** 23116 * Array-like reduce for objects. 23117 * 23118 * @param {Object} object 23119 * The Object that you want to reduce. 23120 * 23121 * @param {Function} fn 23122 * A callback function which is called for each key in the object. It 23123 * receives the accumulated value and the per-iteration value and key 23124 * as arguments. 23125 * 23126 * @param {Mixed} [initial = 0] 23127 * Starting value 23128 * 23129 * @return {Mixed} 23130 * The final accumulated value. 23131 */ 23132function reduce(object, fn) { 23133 var initial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; 23134 23135 return Object.keys(object).reduce(function (accum, key) { 23136 return fn(accum, object[key], key); 23137 }, initial); 23138} 23139 23140/** 23141 * Object.assign-style object shallow merge/extend. 23142 * 23143 * @param {Object} target 23144 * @param {Object} ...sources 23145 * @return {Object} 23146 */ 23147function assign(target) { 23148 for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 23149 sources[_key - 1] = arguments[_key]; 23150 } 23151 23152 if (Object.assign) { 23153 return Object.assign.apply(Object, [target].concat(sources)); 23154 } 23155 23156 sources.forEach(function (source) { 23157 if (!source) { 23158 return; 23159 } 23160 23161 each(source, function (value, key) { 23162 target[key] = value; 23163 }); 23164 }); 23165 23166 return target; 23167} 23168 23169/** 23170 * Returns whether a value is an object of any kind - including DOM nodes, 23171 * arrays, regular expressions, etc. Not functions, though. 23172 * 23173 * This avoids the gotcha where using `typeof` on a `null` value 23174 * results in `'object'`. 23175 * 23176 * @param {Object} value 23177 * @return {Boolean} 23178 */ 23179function isObject(value) { 23180 return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object'; 23181} 23182 23183/** 23184 * Returns whether an object appears to be a "plain" object - that is, a
23185 * direct instance of `Object`. 23186 * 23187 * @param {Object} value 23188 * @return {Boolean} 23189 */ 23190function isPlain(value) { 23191 return isObject(value) && toString.call(value) === '[object Object]' && value.constructor === Object; 23192} 23193 23194},{}],89:[function(_dereq_,module,exports){ 23195'use strict'; 23196 23197exports.__esModule = true; 23198exports.setTextContent = exports.createStyleElement = undefined; 23199 23200var _document = _dereq_(94); 23201 23202var _document2 = _interopRequireDefault(_document); 23203 23204function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 23205 23206/** 23207 * Create a DOM syle element given a className for it. 23208 * 23209 * @param {string} className 23210 * The className to add to the created style element. 23211 * 23212 * @return {Element} 23213 * The element that was created. 23214 */ 23215var createStyleElement = exports.createStyleElement = function createStyleElement(className) { 23216 var style = _document2['default'].createElement('style'); 23217 23218 style.className = className; 23219 23220 return style; 23221}; 23222 23223/** 23224 * Add text to a DOM element. 23225 * 23226 * @param {Element} el 23227 * The Element to add text content to. 23228 * 23229 * @param {string} content 23230 * The text to add to the element. 23231 */ 23232/** 23233 * @file stylesheet.js 23234 * @module stylesheet 23235 */ 23236var setTextContent = exports.setTextContent = function setTextContent(el, content) { 23237 if (el.styleSheet) { 23238 el.styleSheet.cssText = content; 23239 } else { 23240 el.textContent = content; 23241 } 23242}; 23243 23244},{"94":94}],90:[function(_dereq_,module,exports){ 23245'use strict'; 23246 23247exports.__esModule = true; 23248exports.createTimeRange = undefined; 23249exports.createTimeRanges = createTimeRanges; 23250 23251var _log = _dereq_(86); 23252 23253var _log2 = _interopRequireDefault(_log); 23254 23255function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 23256 23257/** 23258 * Returns the time for the specified index at the start or end 23259 * of a TimeRange object. 23260 * 23261 * @function time-ranges:indexFunction 23262 * 23263 * @param {number} [index=0] 23264 * The range number to return the time for. 23265 * 23266 * @return {number} 23267 * The time that offset at the specified index. 23268 * 23269 * @depricated index must be set to a value, in the future this will throw an error. 23270 */ 23271 23272/** 23273 * An object that contains ranges of time for various reasons. 23274 * 23275 * @typedef {Object} TimeRange 23276 * 23277 * @property {number} length 23278 * The number of time ranges represented by this Object 23279 * 23280 * @property {time-ranges:indexFunction} start 23281 * Returns the time offset at which a specified time range begins. 23282 * 23283 * @property {time-ranges:indexFunction} end 23284 * Returns the time offset at which a specified time range begins. 23285 * 23286 * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges 23287 */ 23288 23289/** 23290 * Check if any of the time ranges are over the maximum index. 23291 * 23292 * @param {string} fnName 23293 * The function name to use for logging 23294 * 23295 * @param {number} index 23296 * The index to check 23297 * 23298 * @param {number} maxIndex 23299 * The maximum possible index 23300 * 23301 * @throws {Error} if the timeRanges provided are over the maxIndex 23302 */ 23303function rangeCheck(fnName, index, maxIndex) { 23304 if (index < 0 || index > maxIndex) { 23305 throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').'); 23306 } 23307} 23308 23309/** 23310 * Check if any of the time ranges are over the maximum index. 23311 * 23312 * @param {string} fnName 23313 * The function name to use for logging 23314 * 23315 * @param {string} valueIndex 23316 * The proprety that should be used to get the time. should be 'start' or 'end' 23317 * 23318 * @param {Array} ranges 23319 * An array of time ranges 23320 * 23321 * @param {Array} [rangeIndex=0] 23322 * The index to start the search at 23323 * 23324 * @return {number} 23325 * The time that offset at the specified index. 23326 * 23327 * 23328 * @depricated rangeIndex must be set to a value, in the future this will throw an error. 23329 * @throws {Error} if rangeIndex is more than the length of ranges 23330 */ 23331/** 23332 * @file time-ranges.js 23333 * @module time-ranges 23334 */ 23335function getRange(fnName, valueIndex, ranges, rangeIndex) { 23336 if (rangeIndex === undefined) { 23337 _log2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.'); 23338 rangeIndex = 0; 23339 } 23340 rangeCheck(fnName, rangeIndex, ranges.length - 1); 23341 return ranges[rangeIndex][valueIndex]; 23342} 23343 23344/** 23345 * Create a time range object givent ranges of time. 23346 * 23347 * @param {Array} [ranges] 23348 * An array of time ranges. 23349 */ 23350function createTimeRangesObj(ranges) { 23351 if (ranges === undefined || ranges.length === 0) { 23352 return { 23353 length: 0, 23354 start: function start() { 23355 throw new Error('This TimeRanges object is empty'); 23356 }, 23357 end: function end() { 23358 throw new Error('This TimeRanges object is empty'); 23359 } 23360 }; 23361 } 23362 return { 23363 length: ranges.length, 23364 start: getRange.bind(null, 'start', 0, ranges), 23365 end: getRange.bind(null, 'end', 1, ranges) 23366 }; 23367} 23368 23369/** 23370 * Should create a fake `TimeRange` object which mimics an HTML5 time range instance. 23371 * 23372 * @param {number|Array} start 23373 * The start of a single range or an array of ranges 23374 * 23375 * @param {number} end 23376 * The end of a single range. 23377 * 23378 * @private 23379 */ 23380function createTimeRanges(start, end) { 23381 if (Array.isArray(start)) { 23382 return createTimeRangesObj(start); 23383 } else if (start === undefined || end === undefined) { 23384 return createTimeRangesObj(); 23385 } 23386 return createTimeRangesObj([[start, end]]); 23387} 23388 23389exports.createTimeRange = createTimeRanges; 23390 23391},{"86":86}],91:[function(_dereq_,module,exports){ 23392'use strict'; 23393 23394exports.__esModule = true; 23395/** 23396 * @file to-title-case.js 23397 * @module to-title-case 23398 */ 23399 23400/** 23401 * Uppercase the first letter of a string. 23402 * 23403 * @param {string} string 23404 * String to be uppercased 23405 * 23406 * @return {string} 23407 * The string with an uppercased first letter 23408 */ 23409function toTitleCase(string) { 23410 if (typeof string !== 'string') { 23411 return string; 23412 } 23413 23414 return string.charAt(0).toUpperCase() + string.slice(1); 23415} 23416 23417exports['default'] = toTitleCase; 23418 23419},{}],92:[function(_dereq_,module,exports){ 23420'use strict'; 23421 23422exports.__esModule = true; 23423exports.isCrossOrigin = exports.getFileExtension = exports.getAbsoluteURL = exports.parseUrl = undefined; 23424 23425var _document = _dereq_(94); 23426 23427var _document2 = _interopRequireDefault(_document); 23428 23429var _window = _dereq_(95); 23430 23431var _window2 = _interopRequireDefault(_window); 23432 23433function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 23434 23435/** 23436 * @typedef {Object} url:URLObject 23437 * 23438 * @property {string} protocol 23439 * The protocol of the url that was parsed. 23440 * 23441 * @property {string} hostname 23442 * The hostname of the url that was parsed. 23443 * 23444 * @property {string} port 23445 * The port of the url that was parsed. 23446 * 23447 * @property {string} pathname 23448 * The pathname of the url that was parsed. 23449 * 23450 * @property {string} search 23451 * The search query of the url that was parsed. 23452 * 23453 * @property {string} hash 23454 * The hash of the url that was parsed. 23455 * 23456 * @property {string} host 23457 * The host of the url that was parsed. 23458 */ 23459 23460/** 23461 * Resolve and parse the elements of a URL. 23462 * 23463 * @param {String} url 23464 * The url to parse 23465 * 23466 * @return {url:URLObject} 23467 * An object of url details 23468 */ 23469/** 23470 * @file url.js 23471 * @module url 23472 */ 23473var parseUrl = exports.parseUrl = function parseUrl(url) { 23474 var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host']; 23475 23476 // add the url to an anchor and let the browser parse the URL 23477 var a = _document2['default'].createElement('a'); 23478 23479 a.href = url; 23480 23481 // IE8 (and 9?) Fix
23482 // ie8 doesn't parse the URL correctly until the anchor is actually 23483 // added to the body, and an innerHTML is needed to trigger the parsing 23484 var addToBody = a.host === '' && a.protocol !== 'file:'; 23485 var div = void 0; 23486 23487 if (addToBody) { 23488 div = _document2['default'].createElement('div'); 23489 div.innerHTML = '<a href="' + url + '"></a>'; 23490 a = div.firstChild; 23491 // prevent the div from affecting layout 23492 div.setAttribute('style', 'display:none; position:absolute;'); 23493 _document2['default'].body.appendChild(div); 23494 } 23495 23496 // Copy the specific URL properties to a new object 23497 // This is also needed for IE8 because the anchor loses its 23498 // properties when it's removed from the dom 23499 var details = {}; 23500 23501 for (var i = 0; i < props.length; i++) { 23502 details[props[i]] = a[props[i]]; 23503 } 23504 23505 // IE9 adds the port to the host property unlike everyone else. If 23506 // a port identifier is added for standard ports, strip it. 23507 if (details.protocol === 'http:') { 23508 details.host = details.host.replace(/:80$/, ''); 23509 } 23510 23511 if (details.protocol === 'https:') { 23512 details.host = details.host.replace(/:443$/, ''); 23513 } 23514 23515 if (addToBody) { 23516 _document2['default'].body.removeChild(div); 23517 } 23518 23519 return details; 23520}; 23521 23522/** 23523 * Get absolute version of relative URL. Used to tell flash correct URL. 23524 * 23525 * 23526 * @param {string} url 23527 * URL to make absolute 23528 * 23529 * @return {string} 23530 * Absolute URL 23531 * 23532 * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue 23533 */ 23534var getAbsoluteURL = exports.getAbsoluteURL = function getAbsoluteURL(url) { 23535 // Check if absolute URL 23536 if (!url.match(/^https?:\/\//)) { 23537 // Convert to absolute URL. Flash hosted off-site needs an absolute URL. 23538 var div = _document2['default'].createElement('div'); 23539 23540 div.innerHTML = '<a href="' + url + '">x</a>'; 23541 url = div.firstChild.href; 23542 } 23543 23544 return url; 23545}; 23546 23547/** 23548 * Returns the extension of the passed file name. It will return an empty string 23549 * if passed an invalid path. 23550 * 23551 * @param {string} path 23552 * The fileName path like '/path/to/file.mp4' 23553 * 23554 * @returns {string} 23555 * The extension in lower case or an empty string if no 23556 * extension could be found. 23557 */ 23558var getFileExtension = exports.getFileExtension = function getFileExtension(path) { 23559 if (typeof path === 'string') { 23560 var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i; 23561 var pathParts = splitPathRe.exec(path); 23562 23563 if (pathParts) { 23564 return pathParts.pop().toLowerCase(); 23565 } 23566 } 23567 23568 return ''; 23569}; 23570 23571/** 23572 * Returns whether the url passed is a cross domain request or not. 23573 * 23574 * @param {string} url 23575 * The url to check. 23576 * 23577 * @return {boolean} 23578 * Whether it is a cross domain request or not. 23579 */ 23580var isCrossOrigin = exports.isCrossOrigin = function isCrossOrigin(url) { 23581 var winLoc = _window2['default'].location; 23582 var urlInfo = parseUrl(url); 23583 23584 // IE8 protocol relative urls will return ':' for protocol 23585 var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol; 23586 23587 // Check if url is for another domain/origin 23588 // IE8 doesn't know location.origin, so we won't rely on it here 23589 var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host; 23590 23591 return crossOrigin; 23592}; 23593 23594},{"94":94,"95":95}],93:[function(_dereq_,module,exports){ 23595'use strict'; 23596 23597exports.__esModule = true; 23598 23599var _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; }; /** 23600 * @file video.js 23601 * @module videojs 23602 */ 23603 23604/* global define */ 23605 23606// Include the built-in techs 23607 23608 23609var _window = _dereq_(95); 23610 23611var _window2 = _interopRequireDefault(_window); 23612 23613var _document = _dereq_(94); 23614 23615var _document2 = _interopRequireDefault(_document); 23616 23617var _setup = _dereq_(56); 23618 23619var setup = _interopRequireWildcard(_setup); 23620 23621var _stylesheet = _dereq_(89); 23622 23623var stylesheet = _interopRequireWildcard(_stylesheet); 23624 23625var _component = _dereq_(5); 23626 23627var _component2 = _interopRequireDefault(_component); 23628 23629var _eventTarget = _dereq_(42); 23630 23631var _eventTarget2 = _interopRequireDefault(_eventTarget); 23632 23633var _events = _dereq_(82); 23634 23635var Events = _interopRequireWildcard(_events); 23636 23637var _player = _dereq_(51); 23638 23639var _player2 = _interopRequireDefault(_player); 23640 23641var _plugins = _dereq_(52); 23642 23643var _plugins2 = _interopRequireDefault(_plugins); 23644 23645var _mergeOptions2 = _dereq_(87); 23646 23647var _mergeOptions3 = _interopRequireDefault(_mergeOptions2); 23648 23649var _fn = _dereq_(83); 23650 23651var Fn = _interopRequireWildcard(_fn); 23652 23653var _textTrack = _dereq_(72); 23654 23655var _textTrack2 = _interopRequireDefault(_textTrack); 23656 23657var _audioTrack = _dereq_(64); 23658 23659var _audioTrack2 = _interopRequireDefault(_audioTrack); 23660 23661var _videoTrack = _dereq_(77); 23662 23663var _videoTrack2 = _interopRequireDefault(_videoTrack); 23664 23665var _timeRanges = _dereq_(90); 23666 23667var _formatTime = _dereq_(84); 23668 23669var _formatTime2 = _interopRequireDefault(_formatTime); 23670 23671var _log = _dereq_(86); 23672 23673var _log2 = _interopRequireDefault(_log); 23674 23675var _dom = _dereq_(81); 23676 23677var Dom = _interopRequireWildcard(_dom); 23678 23679var _browser = _dereq_(78); 23680 23681var browser = _interopRequireWildcard(_browser); 23682 23683var _url = _dereq_(92); 23684 23685var Url = _interopRequireWildcard(_url); 23686 23687var _obj = _dereq_(88); 23688 23689var _computedStyle = _dereq_(80); 23690 23691var _computedStyle2 = _interopRequireDefault(_computedStyle); 23692 23693var _extend = _dereq_(43); 23694 23695var _extend2 = _interopRequireDefault(_extend); 23696 23697var _xhr = _dereq_(105); 23698
23699var _xhr2 = _interopRequireDefault(_xhr); 23700 23701var _tech = _dereq_(62); 23702 23703var _tech2 = _interopRequireDefault(_tech); 23704 23705function _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; } } 23706 23707function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 23708 23709// HTML5 Element Shim for IE8 23710if (typeof HTMLVideoElement === 'undefined' && Dom.isReal()) { 23711 _document2['default'].createElement('video'); 23712 _document2['default'].createElement('audio'); 23713 _document2['default'].createElement('track'); 23714} 23715 23716/** 23717 * Doubles as the main function for users to create a player instance and also 23718 * the main library object. 23719 * The `videojs` function can be used to initialize or retrieve a player. 23720 * 23721 * @param {string|Element} id 23722 * Video element or video element ID 23723 * 23724 * @param {Object} [options] 23725 * Optional options object for config/settings 23726 * 23727 * @param {Component~ReadyCallback} [ready] 23728 * Optional ready callback 23729 * 23730 * @return {Player} 23731 * A player instance 23732 * 23733 * @mixes videojs 23734 */ 23735function videojs(id, options, ready) { 23736 var tag = void 0; 23737 23738 // Allow for element or ID to be passed in 23739 // String ID 23740 if (typeof id === 'string') { 23741 23742 // Adjust for jQuery ID syntax 23743 if (id.indexOf('#') === 0) { 23744 id = id.slice(1); 23745 } 23746 23747 // If a player instance has already been created for this ID return it. 23748 if (videojs.getPlayers()[id]) { 23749 23750 // If options or ready funtion are passed, warn 23751 if (options) { 23752 _log2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.'); 23753 } 23754 23755 if (ready) { 23756 videojs.getPlayers()[id].ready(ready); 23757 } 23758 23759 return videojs.getPlayers()[id]; 23760 } 23761 23762 // Otherwise get element for ID 23763 tag = Dom.getEl(id); 23764 23765 // ID is a media element 23766 } else { 23767 tag = id; 23768 } 23769 23770 // Check for a useable element 23771 // re: nodeName, could be a box div also 23772 if (!tag || !tag.nodeName) { 23773 throw new TypeError('The element or ID supplied is not valid. (videojs)'); 23774 } 23775 23776 // Element may have a player attr referring to an already created player instance. 23777 // If so return that otherwise set up a new player below 23778 if (tag.player || _player2['default'].players[tag.playerId]) { 23779 return tag.player || _player2['default'].players[tag.playerId]; 23780 } 23781 23782 options = options || {}; 23783 23784 videojs.hooks('beforesetup').forEach(function (hookFunction) { 23785 var opts = hookFunction(tag, (0, _mergeOptions3['default'])(options)); 23786 23787 if (!(0, _obj.isObject)(opts) || Array.isArray(opts)) { 23788 _log2['default'].error('please return an object in beforesetup hooks'); 23789 return; 23790 } 23791 23792 options = (0, _mergeOptions3['default'])(options, opts); 23793 }); 23794 23795 var PlayerComponent = _component2['default'].getComponent('Player'); 23796 // If not, set up a new player 23797 var player = new PlayerComponent(tag, options, ready); 23798 23799 videojs.hooks('setup').forEach(function (hookFunction) { 23800 return hookFunction(player); 23801 }); 23802 23803 return player; 23804} 23805 23806/** 23807 * An Object that contains lifecycle hooks as keys which point to an array 23808 * of functions that are run when a lifecycle is triggered 23809 */ 23810videojs.hooks_ = {}; 23811 23812/** 23813 * Get a list of hooks for a specific lifecycle 23814 * 23815 * @param {string} type 23816 * the lifecyle to get hooks from 23817 * 23818 * @param {Function} [fn] 23819 * Optionally add a hook to the lifecycle that your are getting. 23820 * 23821 * @return {Array} 23822 * an array of hooks, or an empty array if there are none. 23823 */ 23824videojs.hooks = function (type, fn) { 23825 videojs.hooks_[type] = videojs.hooks_[type] || []; 23826 if (fn) { 23827 videojs.hooks_[type] = videojs.hooks_[type].concat(fn); 23828 } 23829 return videojs.hooks_[type]; 23830}; 23831 23832/** 23833 * Add a function hook to a specific videojs lifecycle. 23834 * 23835 * @param {string} type 23836 * the lifecycle to hook the function to. 23837 * 23838 * @param {Function|Function[]} 23839 * The function or array of functions to attach. 23840 */
23841videojs.hook = function (type, fn) { 23842 videojs.hooks(type, fn); 23843}; 23844 23845/** 23846 * Remove a hook from a specific videojs lifecycle. 23847 * 23848 * @param {string} type 23849 * the lifecycle that the function hooked to 23850 * 23851 * @param {Function} fn 23852 * The hooked function to remove 23853 * 23854 * @return {boolean} 23855 * The function that was removed or undef 23856 */ 23857videojs.removeHook = function (type, fn) { 23858 var index = videojs.hooks(type).indexOf(fn); 23859 23860 if (index <= -1) { 23861 return false; 23862 } 23863 23864 videojs.hooks_[type] = videojs.hooks_[type].slice(); 23865 videojs.hooks_[type].splice(index, 1); 23866 23867 return true; 23868}; 23869 23870// Add default styles 23871if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true && Dom.isReal()) { 23872 var style = Dom.$('.vjs-styles-defaults'); 23873 23874 if (!style) { 23875 style = stylesheet.createStyleElement('vjs-styles-defaults'); 23876 var head = Dom.$('head'); 23877 23878 if (head) { 23879 head.insertBefore(style, head.firstChild); 23880 } 23881 stylesheet.setTextContent(style, '\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n '); 23882 } 23883} 23884 23885// Run Auto-load players 23886// You have to wait at least once in case this script is loaded after your 23887// video in the DOM (weird behavior only with minified version) 23888setup.autoSetupTimeout(1, videojs); 23889 23890/** 23891 * Current software version. Follows semver. 23892 * 23893 * @type {string} 23894 */ 23895videojs.VERSION = '5.17.0'; 23896 23897/** 23898 * The global options object. These are the settings that take effect 23899 * if no overrides are specified when the player is created. 23900 * 23901 * @type {Object} 23902 */ 23903videojs.options = _player2['default'].prototype.options_; 23904 23905/** 23906 * Get an object with the currently created players, keyed by player ID 23907 * 23908 * @return {Object} 23909 * The created players 23910 */ 23911videojs.getPlayers = function () { 23912 return _player2['default'].players; 23913}; 23914 23915/** 23916 * Expose players object. 23917 * 23918 * @memberOf videojs 23919 * @property {Object} players 23920 */ 23921videojs.players = _player2['default'].players; 23922 23923/** 23924 * Get a component class object by name 23925 * 23926 * @borrows Component.getComponent as videojs.getComponent 23927 */ 23928videojs.getComponent = _component2['default'].getComponent; 23929 23930/** 23931 * Register a component so it can referred to by name. Used when adding to other 23932 * components, either through addChild `component.addChild('myComponent')` or through 23933 * default children options `{ children: ['myComponent'] }`. 23934 * 23935 * > NOTE: You could also just initialize the component before adding. 23936 * `component.addChild(new MyComponent());` 23937 * 23938 * @param {string} name 23939 * The class name of the component 23940 * 23941 * @param {Component} comp 23942 * The component class 23943 * 23944 * @return {Component} 23945 * The newly registered component 23946 */ 23947videojs.registerComponent = function (name, comp) { 23948 if (_tech2['default'].isTech(comp)) { 23949 _log2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)'); 23950 } 23951 23952 _component2['default'].registerComponent.call(_component2['default'], name, comp); 23953}; 23954 23955/** 23956 * Get a Tech class object by name 23957 * 23958 * @borrows Tech.getTech as videojs.getTech 23959 */ 23960videojs.getTech = _tech2['default'].getTech; 23961 23962/** 23963 * Register a Tech so it can referred to by name. 23964 * This is used in the tech order for the player. 23965 * 23966 * @borrows Tech.registerTech as videojs.registerTech 23967 */ 23968videojs.registerTech = _tech2['default'].registerTech; 23969 23970/** 23971 * A suite of browser and device tests from {@link browser}. 23972 * 23973 * @type {Object} 23974 * @private 23975 */ 23976videojs.browser = browser; 23977 23978/** 23979 * Whether or not the browser supports touch events. Included for backward 23980 * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED` 23981 * instead going forward. 23982 * 23983 * @deprecated since version 5.0 23984 * @type {boolean} 23985 */ 23986videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED; 23987 23988/** 23989 * Subclass an existing class 23990 * Mimics ES6 subclassing with the `extend` keyword 23991 * 23992 * @borrows extend:extendFn as videojs.extend 23993 */ 23994videojs.extend = _extend2['default']; 23995 23996/** 23997 * Merge two options objects recursively 23998 * Performs a deep merge like lodash.merge but **only merges plain objects** 23999 * (not arrays, elements, anything else) 24000 * Other values will be copied directly from the second object. 24001 * 24002 * @borrows merge-options:mergeOptions as videojs.mergeOptions 24003 */ 24004videojs.mergeOptions = _mergeOptions3['default']; 24005 24006/** 24007 * Change the context (this) of a function 24008 * 24009 * > NOTE: as of v5.0 we require an ES5 shim, so you should use the native 24010 * `function() {}.bind(newContext);` instead of this. 24011 * 24012 * @borrows fn:bind as videojs.bind 24013 */ 24014videojs.bind = Fn.bind; 24015 24016/** 24017 * Create a Video.js player plugin. 24018 * Plugins are only initialized when options for the plugin are included 24019 * in the player options, or the plugin function on the player instance is 24020 * called. 24021 * 24022 * @borrows plugin:plugin as videojs.plugin 24023 */ 24024videojs.plugin = _plugins2['default']; 24025 24026/** 24027 * Adding languages so that they're available to all players. 24028 * Example: `videojs.addLanguage('es', { 'Hello': 'Hola' });` 24029 * 24030 * @param {string} code 24031 * The language code or dictionary property 24032 * 24033 * @param {Object} data 24034 * The data values to be translated 24035 * 24036 * @return {Object} 24037 * The resulting language dictionary object 24038 */ 24039videojs.addLanguage = function (code, data) { 24040 var _mergeOptions; 24041 24042 code = ('' + code).toLowerCase(); 24043 24044 videojs.options.languages = (0, _mergeOptions3['default'])(videojs.options.languages, (_mergeOptions = {}, _mergeOptions[code] = data, _mergeOptions)); 24045 24046 return videojs.options.languages[code]; 24047}; 24048 24049/** 24050 * Log messages 24051 * 24052 * @borrows log:log as videojs.log 24053 */ 24054videojs.log = _log2['default']; 24055 24056/** 24057 * Creates an emulated TimeRange object. 24058 * 24059 * @borrows time-ranges:createTimeRanges as videojs.createTimeRange 24060 */ 24061/** 24062 * @borrows time-ranges:createTimeRanges as videojs.createTimeRanges 24063 */ 24064videojs.createTimeRange = videojs.createTimeRanges = _timeRanges.createTimeRanges; 24065 24066/** 24067 * Format seconds as a time string, H:MM:SS or M:SS 24068 * Supplying a guide (in seconds) will force a number of leading zeros 24069 * to cover the length of the guide 24070 * 24071 * @borrows format-time:formatTime as videojs.formatTime 24072 */ 24073videojs.formatTime = _formatTime2['default']; 24074 24075/** 24076 * Resolve and parse the elements of a URL 24077 * 24078 * @borrows url:parseUrl as videojs.parseUrl 24079 */ 24080videojs.parseUrl = Url.parseUrl; 24081 24082/** 24083 * Returns whether the url passed is a cross domain request or not. 24084 * 24085 * @borrows url:isCrossOrigin as videojs.isCrossOrigin 24086 */
24087videojs.isCrossOrigin = Url.isCrossOrigin; 24088 24089/** 24090 * Event target class. 24091 * 24092 * @borrows EventTarget as videojs.EventTarget 24093 */ 24094videojs.EventTarget = _eventTarget2['default']; 24095 24096/** 24097 * Add an event listener to element 24098 * It stores the handler function in a separate cache object 24099 * and adds a generic handler to the element's event, 24100 * along with a unique id (guid) to the element. 24101 * 24102 * @borrows events:on as videojs.on 24103 */ 24104videojs.on = Events.on; 24105 24106/** 24107 * Trigger a listener only once for an event 24108 * 24109 * @borrows events:one as videojs.one 24110 */ 24111videojs.one = Events.one; 24112 24113/** 24114 * Removes event listeners from an element 24115 * 24116 * @borrows events:off as videojs.off 24117 */ 24118videojs.off = Events.off; 24119 24120/** 24121 * Trigger an event for an element 24122 * 24123 * @borrows events:trigger as videojs.trigger 24124 */ 24125videojs.trigger = Events.trigger; 24126 24127/** 24128 * A cross-browser XMLHttpRequest wrapper. Here's a simple example: 24129 * 24130 * @param {Object} options 24131 * settings for the request. 24132 * 24133 * @return {XMLHttpRequest|XDomainRequest} 24134 * The request object. 24135 * 24136 * @see https://github.com/Raynos/xhr 24137 */ 24138videojs.xhr = _xhr2['default']; 24139 24140/** 24141 * TextTrack class 24142 * 24143 * @borrows TextTrack as videojs.TextTrack 24144 */ 24145videojs.TextTrack = _textTrack2['default']; 24146 24147/** 24148 * export the AudioTrack class so that source handlers can create 24149 * AudioTracks and then add them to the players AudioTrackList 24150 * 24151 * @borrows AudioTrack as videojs.AudioTrack 24152 */ 24153videojs.AudioTrack = _audioTrack2['default']; 24154 24155/** 24156 * export the VideoTrack class so that source handlers can create 24157 * VideoTracks and then add them to the players VideoTrackList 24158 * 24159 * @borrows VideoTrack as videojs.VideoTrack 24160 */ 24161videojs.VideoTrack = _videoTrack2['default']; 24162 24163/** 24164 * Determines, via duck typing, whether or not a value is a DOM element. 24165 * 24166 * @borrows dom:isEl as videojs.isEl 24167 */ 24168videojs.isEl = Dom.isEl; 24169 24170/** 24171 * Determines, via duck typing, whether or not a value is a text node. 24172 * 24173 * @borrows dom:isTextNode as videojs.isTextNode 24174 */ 24175videojs.isTextNode = Dom.isTextNode; 24176 24177/** 24178 * Creates an element and applies properties. 24179 * 24180 * @borrows dom:createEl as videojs.createEl 24181 */ 24182videojs.createEl = Dom.createEl; 24183 24184/** 24185 * Check if an element has a CSS class 24186 * 24187 * @borrows dom:hasElClass as videojs.hasClass 24188 */ 24189videojs.hasClass = Dom.hasElClass; 24190 24191/** 24192 * Add a CSS class name to an element 24193 * 24194 * @borrows dom:addElClass as videojs.addClass 24195 */ 24196videojs.addClass = Dom.addElClass; 24197 24198/** 24199 * Remove a CSS class name from an element 24200 * 24201 * @borrows dom:removeElClass as videojs.removeClass 24202 */ 24203videojs.removeClass = Dom.removeElClass; 24204 24205/** 24206 * Adds or removes a CSS class name on an element depending on an optional 24207 * condition or the presence/absence of the class name. 24208 * 24209 * @borrows dom:toggleElClass as videojs.toggleClass 24210 */ 24211videojs.toggleClass = Dom.toggleElClass; 24212 24213/** 24214 * Apply attributes to an HTML element. 24215 * 24216 * @borrows dom:setElAttributes as videojs.setAttribute 24217 */ 24218videojs.setAttributes = Dom.setElAttributes; 24219 24220/** 24221 * Get an element's attribute values, as defined on the HTML tag 24222 * Attributes are not the same as properties. They're defined on the tag 24223 * or with setAttribute (which shouldn't be used with HTML) 24224 * This will return true or false for boolean attributes. 24225 * 24226 * @borrows dom:getElAttributes as videojs.getAttributes 24227 */ 24228videojs.getAttributes = Dom.getElAttributes; 24229 24230/** 24231 * Empties the contents of an element. 24232 * 24233 * @borrows dom:emptyEl as videojs.emptyEl 24234 */ 24235videojs.emptyEl = Dom.emptyEl; 24236 24237/** 24238 * Normalizes and appends content to an element. 24239 * 24240 * The content for an element can be passed in multiple types and 24241 * combinations, whose behavior is as follows: 24242 * 24243 * - String 24244 * Normalized into a text node. 24245 * 24246 * - Element, TextNode 24247 * Passed through. 24248 * 24249 * - Array 24250 * A one-dimensional array of strings, elements, nodes, or functions (which 24251 * return single strings, elements, or nodes). 24252 * 24253 * - Function 24254 * If the sole argument, is expected to produce a string, element, 24255 * node, or array. 24256 * 24257 * @borrows dom:appendContents as videojs.appendContet 24258 */ 24259videojs.appendContent = Dom.appendContent; 24260 24261/** 24262 * Normalizes and inserts content into an element; this is identical to 24263 * `appendContent()`, except it empties the element first. 24264 * 24265 * The content for an element can be passed in multiple types and 24266 * combinations, whose behavior is as follows: 24267 * 24268 * - String 24269 * Normalized into a text node. 24270 * 24271 * - Element, TextNode 24272 * Passed through. 24273 * 24274 * - Array
24275 * A one-dimensional array of strings, elements, nodes, or functions (which 24276 * return single strings, elements, or nodes). 24277 * 24278 * - Function 24279 * If the sole argument, is expected to produce a string, element, 24280 * node, or array. 24281 * 24282 * @borrows dom:insertContent as videojs.insertContent 24283 */ 24284videojs.insertContent = Dom.insertContent; 24285 24286/** 24287 * A safe getComputedStyle with an IE8 fallback. 24288 * 24289 * This is because in Firefox, if the player is loaded in an iframe with `display:none`, 24290 * then `getComputedStyle` returns `null`, so, we do a null-check to make sure 24291 * that the player doesn't break in these cases. 24292 * See https://bugzilla.mozilla.org/show_bug.cgi?id=548397 for more details. 24293 * 24294 * @borrows computed-style:computedStyle as videojs.computedStyle 24295 */ 24296videojs.computedStyle = _computedStyle2['default']; 24297 24298/* 24299 * Custom Universal Module Definition (UMD) 24300 * 24301 * Video.js will never be a non-browser lib so we can simplify UMD a bunch and 24302 * still support requirejs and browserify. This also needs to be closure 24303 * compiler compatible, so string keys are used. 24304 */ 24305if (typeof define === 'function' && define.amd) { 24306 define('videojs', [], function () { 24307 return videojs; 24308 }); 24309 24310 // checking that module is an object too because of umdjs/umd#35 24311} else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && (typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') { 24312 module.exports = videojs; 24313} 24314 24315exports['default'] = videojs; 24316 24317},{"105":105,"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}],94:[function(_dereq_,module,exports){ 24318(function (global){ 24319var topLevel = typeof global !== 'undefined' ? global : 24320 typeof window !== 'undefined' ? window : {} 24321var minDoc = _dereq_(96); 24322 24323if (typeof document !== 'undefined') { 24324 module.exports = document; 24325} else { 24326 var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4']; 24327 24328 if (!doccy) { 24329 doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc; 24330 } 24331 24332 module.exports = doccy; 24333} 24334 24335}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 24336},{"96":96}],95:[function(_dereq_,module,exports){ 24337(function (global){ 24338if (typeof window !== "undefined") { 24339 module.exports = window; 24340} else if (typeof global !== "undefined") { 24341 module.exports = global; 24342} else if (typeof self !== "undefined"){ 24343 module.exports = self; 24344} else { 24345 module.exports = {}; 24346} 24347 24348}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 24349},{}],96:[function(_dereq_,module,exports){ 24350 24351},{}],97:[function(_dereq_,module,exports){ 24352module.exports = SafeParseTuple 24353 24354function SafeParseTuple(obj, reviver) { 24355 var json 24356 var error = null 24357 24358 try { 24359 json = JSON.parse(obj, reviver) 24360 } catch (err) { 24361 error = err 24362 } 24363 24364 return [error, json] 24365} 24366 24367},{}],98:[function(_dereq_,module,exports){ 24368function clean (s) { 24369 return s.replace(/\n\r?\s*/g, '') 24370} 24371 24372 24373module.exports = function tsml (sa) { 24374 var s = '' 24375 , i = 0 24376 24377 for (; i < arguments.length; i++) 24378 s += clean(sa[i]) + (arguments[i + 1] || '') 24379 24380 return s 24381} 24382},{}],99:[function(_dereq_,module,exports){ 24383/** 24384 * Copyright 2013 vtt.js Contributors 24385 * 24386 * Licensed under the Apache License, Version 2.0 (the "License"); 24387 * you may not use this file except in compliance with the License. 24388 * You may obtain a copy of the License at 24389 * 24390 * http://www.apache.org/licenses/LICENSE-2.0 24391 * 24392 * Unless required by applicable law or agreed to in writing, software 24393 * distributed under the License is distributed on an "AS IS" BASIS, 24394 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24395 * See the License for the specific language governing permissions and 24396 * limitations under the License. 24397 */ 24398 24399// Default exports for Node. Export the extended versions of VTTCue and 24400// VTTRegion in Node since we likely want the capability to convert back and 24401// forth between JSON. If we don't then it's not that big of a deal since we're 24402// off browser. 24403module.exports = { 24404 WebVTT: _dereq_(100).WebVTT, 24405 VTTCue: _dereq_(101).VTTCue, 24406 VTTRegion: _dereq_(103).VTTRegion 24407}; 24408 24409},{"100":100,"101":101,"103":103}],100:[function(_dereq_,module,exports){ 24410/** 24411 * Copyright 2013 vtt.js Contributors 24412 * 24413 * Licensed under the Apache License, Version 2.0 (the "License");
vendor: 14,276 bytes, lines 24414-24839
24414 * you may not use this file except in compliance with the License. 24415 * You may obtain a copy of the License at 24416 * 24417 * http://www.apache.org/licenses/LICENSE-2.0 24418 * 24419 * Unless required by applicable law or agreed to in writing, software 24420 * distributed under the License is distributed on an "AS IS" BASIS, 24421 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24422 * See the License for the specific language governing permissions and 24423 * limitations under the License. 24424 */ 24425 24426/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 24427/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 24428 24429(function(global) { 24430 24431 var _objCreate = Object.create || (function() { 24432 function F() {} 24433 return function(o) { 24434 if (arguments.length !== 1) { 24435 throw new Error('Object.create shim only accepts one parameter.'); 24436 } 24437 F.prototype = o; 24438 return new F(); 24439 }; 24440 })(); 24441 24442 // Creates a new ParserError object from an errorData object. The errorData 24443 // object should have default code and message properties. The default message 24444 // property can be overriden by passing in a message parameter. 24445 // See ParsingError.Errors below for acceptable errors. 24446 function ParsingError(errorData, message) { 24447 this.name = "ParsingError"; 24448 this.code = errorData.code; 24449 this.message = message || errorData.message; 24450 } 24451 ParsingError.prototype = _objCreate(Error.prototype); 24452 ParsingError.prototype.constructor = ParsingError; 24453 24454 // ParsingError metadata for acceptable ParsingErrors. 24455 ParsingError.Errors = { 24456 BadSignature: { 24457 code: 0, 24458 message: "Malformed WebVTT signature." 24459 }, 24460 BadTimeStamp: { 24461 code: 1, 24462 message: "Malformed time stamp." 24463 } 24464 }; 24465 24466 // Try to parse input as a time stamp. 24467 function parseTimeStamp(input) { 24468 24469 function computeSeconds(h, m, s, f) { 24470 return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000; 24471 } 24472 24473 var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/); 24474 if (!m) { 24475 return null; 24476 } 24477 24478 if (m[3]) { 24479 // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds] 24480 return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]); 24481 } else if (m[1] > 59) { 24482 // Timestamp takes the form of [hours]:[minutes].[milliseconds] 24483 // First position is hours as it's over 59. 24484 return computeSeconds(m[1], m[2], 0, m[4]); 24485 } else { 24486 // Timestamp takes the form of [minutes]:[seconds].[milliseconds] 24487 return computeSeconds(0, m[1], m[2], m[4]); 24488 } 24489 } 24490 24491 // A settings object holds key/value pairs and will ignore anything but the first 24492 // assignment to a specific key. 24493 function Settings() { 24494 this.values = _objCreate(null); 24495 } 24496 24497 Settings.prototype = { 24498 // Only accept the first assignment to any key. 24499 set: function(k, v) { 24500 if (!this.get(k) && v !== "") { 24501 this.values[k] = v; 24502 } 24503 }, 24504 // Return the value for a key, or a default value. 24505 // If 'defaultKey' is passed then 'dflt' is assumed to be an object with 24506 // a number of possible default values as properties where 'defaultKey' is 24507 // the key of the property that will be chosen; otherwise it's assumed to be 24508 // a single value. 24509 get: function(k, dflt, defaultKey) { 24510 if (defaultKey) { 24511 return this.has(k) ? this.values[k] : dflt[defaultKey]; 24512 } 24513 return this.has(k) ? this.values[k] : dflt; 24514 }, 24515 // Check whether we have a value for a key. 24516 has: function(k) { 24517 return k in this.values; 24518 }, 24519 // Accept a setting if its one of the given alternatives. 24520 alt: function(k, v, a) { 24521 for (var n = 0; n < a.length; ++n) { 24522 if (v === a[n]) { 24523 this.set(k, v); 24524 break; 24525 } 24526 } 24527 }, 24528 // Accept a setting if its a valid (signed) integer. 24529 integer: function(k, v) { 24530 if (/^-?\d+$/.test(v)) { // integer 24531 this.set(k, parseInt(v, 10)); 24532 } 24533 }, 24534 // Accept a setting if its a valid percentage. 24535 percent: function(k, v) { 24536 var m; 24537 if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) { 24538 v = parseFloat(v); 24539 if (v >= 0 && v <= 100) { 24540 this.set(k, v); 24541 return true; 24542 } 24543 } 24544 return false; 24545 } 24546 }; 24547 24548 // Helper function to parse input into groups separated by 'groupDelim', and 24549 // interprete each group as a key/value pair separated by 'keyValueDelim'. 24550 function parseOptions(input, callback, keyValueDelim, groupDelim) { 24551 var groups = groupDelim ? input.split(groupDelim) : [input]; 24552 for (var i in groups) { 24553 if (typeof groups[i] !== "string") { 24554 continue; 24555 } 24556 var kv = groups[i].split(keyValueDelim); 24557 if (kv.length !== 2) { 24558 continue; 24559 } 24560 var k = kv[0]; 24561 var v = kv[1]; 24562 callback(k, v); 24563 } 24564 } 24565 24566 function parseCue(input, cue, regionList) { 24567 // Remember the original input if we need to throw an error. 24568 var oInput = input; 24569 // 4.1 WebVTT timestamp 24570 function consumeTimeStamp() { 24571 var ts = parseTimeStamp(input); 24572 if (ts === null) { 24573 throw new ParsingError(ParsingError.Errors.BadTimeStamp, 24574 "Malformed timestamp: " + oInput); 24575 } 24576 // Remove time stamp from input. 24577 input = input.replace(/^[^\sa-zA-Z-]+/, ""); 24578 return ts; 24579 } 24580 24581 // 4.4.2 WebVTT cue settings 24582 function consumeCueSettings(input, cue) { 24583 var settings = new Settings(); 24584 24585 parseOptions(input, function (k, v) { 24586 switch (k) { 24587 case "region": 24588 // Find the last region we parsed with the same region id. 24589 for (var i = regionList.length - 1; i >= 0; i--) { 24590 if (regionList[i].id === v) { 24591 settings.set(k, regionList[i].region); 24592 break; 24593 } 24594 } 24595 break; 24596 case "vertical": 24597 settings.alt(k, v, ["rl", "lr"]); 24598 break; 24599 case "line": 24600 var vals = v.split(","), 24601 vals0 = vals[0]; 24602 settings.integer(k, vals0); 24603 settings.percent(k, vals0) ? settings.set("snapToLines", false) : null; 24604 settings.alt(k, vals0, ["auto"]); 24605 if (vals.length === 2) { 24606 settings.alt("lineAlign", vals[1], ["start", "middle", "end"]); 24607 } 24608 break; 24609 case "position": 24610 vals = v.split(","); 24611 settings.percent(k, vals[0]); 24612 if (vals.length === 2) { 24613 settings.alt("positionAlign", vals[1], ["start", "middle", "end"]); 24614 } 24615 break; 24616 case "size": 24617 settings.percent(k, v); 24618 break; 24619 case "align": 24620 settings.alt(k, v, ["start", "middle", "end", "left", "right"]); 24621 break; 24622 } 24623 }, /:/, /\s/); 24624 24625 // Apply default values for any missing fields. 24626 cue.region = settings.get("region", null); 24627 cue.vertical = settings.get("vertical", ""); 24628 cue.line = settings.get("line", "auto"); 24629 cue.lineAlign = settings.get("lineAlign", "start"); 24630 cue.snapToLines = settings.get("snapToLines", true); 24631 cue.size = settings.get("size", 100); 24632 cue.align = settings.get("align", "middle"); 24633 cue.position = settings.get("position", { 24634 start: 0, 24635 left: 0, 24636 middle: 50, 24637 end: 100, 24638 right: 100 24639 }, cue.align); 24640 cue.positionAlign = settings.get("positionAlign", { 24641 start: "start", 24642 left: "start", 24643 middle: "middle", 24644 end: "end", 24645 right: "end" 24646 }, cue.align); 24647 } 24648 24649 function skipWhitespace() { 24650 input = input.replace(/^\s+/, ""); 24651 } 24652 24653 // 4.1 WebVTT cue timings. 24654 skipWhitespace(); 24655 cue.startTime = consumeTimeStamp(); // (1) collect cue start time 24656 skipWhitespace(); 24657 if (input.substr(0, 3) !== "-->") { // (3) next characters must match "-->" 24658 throw new ParsingError(ParsingError.Errors.BadTimeStamp, 24659 "Malformed time stamp (time stamps must be separated by '-->'): " + 24660 oInput); 24661 } 24662 input = input.substr(3); 24663 skipWhitespace(); 24664 cue.endTime = consumeTimeStamp(); // (5) collect cue end time 24665 24666 // 4.1 WebVTT cue settings list. 24667 skipWhitespace(); 24668 consumeCueSettings(input, cue); 24669 } 24670 24671 var ESCAPE = { 24672 "&": "&", 24673 "<": "<", 24674 ">": ">", 24675 "‎": "\u200e", 24676 "‏": "\u200f", 24677 " ": "\u00a0" 24678 }; 24679 24680 var TAG_NAME = { 24681 c: "span", 24682 i: "i", 24683 b: "b", 24684 u: "u", 24685 ruby: "ruby", 24686 rt: "rt", 24687 v: "span", 24688 lang: "span" 24689 }; 24690 24691 var TAG_ANNOTATION = { 24692 v: "title", 24693 lang: "lang" 24694 }; 24695 24696 var NEEDS_PARENT = { 24697 rt: "ruby" 24698 }; 24699 24700 // Parse content into a document fragment. 24701 function parseContent(window, input) { 24702 function nextToken() { 24703 // Check for end-of-string. 24704 if (!input) { 24705 return null; 24706 } 24707 24708 // Consume 'n' characters from the input. 24709 function consume(result) { 24710 input = input.substr(result.length); 24711 return result; 24712 } 24713 24714 var m = input.match(/^([^<]*)(<[^>]+>?)?/); 24715 // If there is some text before the next tag, return it, otherwise return 24716 // the tag. 24717 return consume(m[1] ? m[1] : m[2]); 24718 } 24719 24720 // Unescape a string 's'. 24721 function unescape1(e) { 24722 return ESCAPE[e]; 24723 } 24724 function unescape(s) { 24725 while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) { 24726 s = s.replace(m[0], unescape1); 24727 } 24728 return s; 24729 } 24730 24731 function shouldAdd(current, element) { 24732 return !NEEDS_PARENT[element.localName] || 24733 NEEDS_PARENT[element.localName] === current.localName; 24734 } 24735 24736 // Create an element for this tag. 24737 function createElement(type, annotation) { 24738 var tagName = TAG_NAME[type]; 24739 if (!tagName) { 24740 return null; 24741 } 24742 var element = window.document.createElement(tagName); 24743 element.localName = tagName; 24744 var name = TAG_ANNOTATION[type]; 24745 if (name && annotation) { 24746 element[name] = annotation.trim(); 24747 } 24748 return element; 24749 } 24750 24751 var rootDiv = window.document.createElement("div"), 24752 current = rootDiv, 24753 t, 24754 tagStack = []; 24755 24756 while ((t = nextToken()) !== null) { 24757 if (t[0] === '<') { 24758 if (t[1] === "/") { 24759 // If the closing tag matches, move back up to the parent node. 24760 if (tagStack.length && 24761 tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) { 24762 tagStack.pop(); 24763 current = current.parentNode; 24764 } 24765 // Otherwise just ignore the end tag. 24766 continue; 24767 } 24768 var ts = parseTimeStamp(t.substr(1, t.length - 2)); 24769 var node; 24770 if (ts) { 24771 // Timestamps are lead nodes as well. 24772 node = window.document.createProcessingInstruction("timestamp", ts); 24773 current.appendChild(node); 24774 continue; 24775 } 24776 var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/); 24777 // If we can't parse the tag, skip to the next tag. 24778 if (!m) { 24779 continue; 24780 } 24781 // Try to construct an element, and ignore the tag if we couldn't. 24782 node = createElement(m[1], m[3]); 24783 if (!node) { 24784 continue; 24785 } 24786 // Determine if the tag should be added based on the context of where it 24787 // is placed in the cuetext. 24788 if (!shouldAdd(current, node)) { 24789 continue; 24790 } 24791 // Set the class list (as a list of classes, separated by space). 24792 if (m[2]) { 24793 node.className = m[2].substr(1).replace('.', ' '); 24794 } 24795 // Append the node to the current node, and enter the scope of the new 24796 // node. 24797 tagStack.push(m[1]); 24798 current.appendChild(node); 24799 current = node; 24800 continue; 24801 } 24802 24803 // Text nodes are leaf nodes. 24804 current.appendChild(window.document.createTextNode(unescape(t))); 24805 } 24806 24807 return rootDiv; 24808 } 24809 24810 // This is a list of all the Unicode characters that have a strong 24811 // right-to-left category. What this means is that these characters are 24812 // written right-to-left for sure. It was generated by pulling all the strong 24813 // right-to-left characters out of the Unicode data table. That table can 24814 // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt 24815 var strongRTLChars = [0x05BE, 0x05C0, 0x05C3, 0x05C6, 0x05D0, 0x05D1, 24816 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 24817 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 24818 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x05F0, 0x05F1, 24819 0x05F2, 0x05F3, 0x05F4, 0x0608, 0x060B, 0x060D, 0x061B, 0x061E, 0x061F, 24820 0x0620, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 24821 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 24822 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 24823 0x063B, 0x063C, 0x063D, 0x063E, 0x063F, 0x0640, 0x0641, 0x0642, 0x0643, 24824 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x066D, 0x066E, 24825 0x066F, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0x0677, 0x0678, 24826 0x0679, 0x067A, 0x067B, 0x067C, 0x067D, 0x067E, 0x067F, 0x0680, 0x0681, 24827 0x0682, 0x0683, 0x0684, 0x0685, 0x0686, 0x0687, 0x0688, 0x0689, 0x068A, 24828 0x068B, 0x068C, 0x068D, 0x068E, 0x068F, 0x0690, 0x0691, 0x0692, 0x0693, 24829 0x0694, 0x0695, 0x0696, 0x0697, 0x0698, 0x0699, 0x069A, 0x069B, 0x069C, 24830 0x069D, 0x069E, 0x069F, 0x06A0, 0x06A1, 0x06A2, 0x06A3, 0x06A4, 0x06A5, 24831 0x06A6, 0x06A7, 0x06A8, 0x06A9, 0x06AA, 0x06AB, 0x06AC, 0x06AD, 0x06AE, 24832 0x06AF, 0x06B0, 0x06B1, 0x06B2, 0x06B3, 0x06B4, 0x06B5, 0x06B6, 0x06B7, 24833 0x06B8, 0x06B9, 0x06BA, 0x06BB, 0x06BC, 0x06BD, 0x06BE, 0x06BF, 0x06C0, 24834 0x06C1, 0x06C2, 0x06C3, 0x06C4, 0x06C5, 0x06C6, 0x06C7, 0x06C8, 0x06C9, 24835 0x06CA, 0x06CB, 0x06CC, 0x06CD, 0x06CE, 0x06CF, 0x06D0, 0x06D1, 0x06D2, 24836 0x06D3, 0x06D4, 0x06D5, 0x06E5, 0x06E6, 0x06EE, 0x06EF, 0x06FA, 0x06FB, 24837 0x06FC, 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, 0x0703, 0x0704, 24838 0x0705, 0x0706, 0x0707, 0x0708, 0x0709, 0x070A, 0x070B, 0x070C, 0x070D, 24839 0x070F, 0x0710, 0x0712, 0x0713, 0x0714, 0x0715, 0x0716, 0x0717, 0x0718,
24840 0x0719, 0x071A, 0x071B, 0x071C, 0x071D, 0x071E, 0x071F, 0x0720, 0x0721, 24841 0x0722, 0x0723, 0x0724, 0x0725, 0x0726, 0x0727, 0x0728, 0x0729, 0x072A, 24842 0x072B, 0x072C, 0x072D, 0x072E, 0x072F, 0x074D, 0x074E, 0x074F, 0x0750, 24843 0x0751, 0x0752, 0x0753, 0x0754, 0x0755, 0x0756, 0x0757, 0x0758, 0x0759, 24844 0x075A, 0x075B, 0x075C, 0x075D, 0x075E, 0x075F, 0x0760, 0x0761, 0x0762, 24845 0x0763, 0x0764, 0x0765, 0x0766, 0x0767, 0x0768, 0x0769, 0x076A, 0x076B, 24846 0x076C, 0x076D, 0x076E, 0x076F, 0x0770, 0x0771, 0x0772, 0x0773, 0x0774, 24847 0x0775, 0x0776, 0x0777, 0x0778, 0x0779, 0x077A, 0x077B, 0x077C, 0x077D, 24848 0x077E, 0x077F, 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0786, 24849 0x0787, 0x0788, 0x0789, 0x078A, 0x078B, 0x078C, 0x078D, 0x078E, 0x078F, 24850 0x0790, 0x0791, 0x0792, 0x0793, 0x0794, 0x0795, 0x0796, 0x0797, 0x0798, 24851 0x0799, 0x079A, 0x079B, 0x079C, 0x079D, 0x079E, 0x079F, 0x07A0, 0x07A1, 24852 0x07A2, 0x07A3, 0x07A4, 0x07A5, 0x07B1, 0x07C0, 0x07C1, 0x07C2, 0x07C3, 24853 0x07C4, 0x07C5, 0x07C6, 0x07C7, 0x07C8, 0x07C9, 0x07CA, 0x07CB, 0x07CC, 24854 0x07CD, 0x07CE, 0x07CF, 0x07D0, 0x07D1, 0x07D2, 0x07D3, 0x07D4, 0x07D5, 24855 0x07D6, 0x07D7, 0x07D8, 0x07D9, 0x07DA, 0x07DB, 0x07DC, 0x07DD, 0x07DE, 24856 0x07DF, 0x07E0, 0x07E1, 0x07E2, 0x07E3, 0x07E4, 0x07E5, 0x07E6, 0x07E7, 24857 0x07E8, 0x07E9, 0x07EA, 0x07F4, 0x07F5, 0x07FA, 0x0800, 0x0801, 0x0802, 24858 0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809, 0x080A, 0x080B, 24859 0x080C, 0x080D, 0x080E, 0x080F, 0x0810, 0x0811, 0x0812, 0x0813, 0x0814, 24860 0x0815, 0x081A, 0x0824, 0x0828, 0x0830, 0x0831, 0x0832, 0x0833, 0x0834, 24861 0x0835, 0x0836, 0x0837, 0x0838, 0x0839, 0x083A, 0x083B, 0x083C, 0x083D, 24862 0x083E, 0x0840, 0x0841, 0x0842, 0x0843, 0x0844, 0x0845, 0x0846, 0x0847, 24863 0x0848, 0x0849, 0x084A, 0x084B, 0x084C, 0x084D, 0x084E, 0x084F, 0x0850, 24864 0x0851, 0x0852, 0x0853, 0x0854, 0x0855, 0x0856, 0x0857, 0x0858, 0x085E, 24865 0x08A0, 0x08A2, 0x08A3, 0x08A4, 0x08A5, 0x08A6, 0x08A7, 0x08A8, 0x08A9, 24866 0x08AA, 0x08AB, 0x08AC, 0x200F, 0xFB1D, 0xFB1F, 0xFB20, 0xFB21, 0xFB22, 24867 0xFB23, 0xFB24, 0xFB25, 0xFB26, 0xFB27, 0xFB28, 0xFB2A, 0xFB2B, 0xFB2C, 24868 0xFB2D, 0xFB2E, 0xFB2F, 0xFB30, 0xFB31, 0xFB32, 0xFB33, 0xFB34, 0xFB35, 24869 0xFB36, 0xFB38, 0xFB39, 0xFB3A, 0xFB3B, 0xFB3C, 0xFB3E, 0xFB40, 0xFB41, 24870 0xFB43, 0xFB44, 0xFB46, 0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C, 24871 0xFB4D, 0xFB4E, 0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54, 0xFB55,
24872 0xFB56, 0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B, 0xFB5C, 0xFB5D, 0xFB5E, 24873 0xFB5F, 0xFB60, 0xFB61, 0xFB62, 0xFB63, 0xFB64, 0xFB65, 0xFB66, 0xFB67, 24874 0xFB68, 0xFB69, 0xFB6A, 0xFB6B, 0xFB6C, 0xFB6D, 0xFB6E, 0xFB6F, 0xFB70, 24875 0xFB71, 0xFB72, 0xFB73, 0xFB74, 0xFB75, 0xFB76, 0xFB77, 0xFB78, 0xFB79, 24876 0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D, 0xFB7E, 0xFB7F, 0xFB80, 0xFB81, 0xFB82, 24877 0xFB83, 0xFB84, 0xFB85, 0xFB86, 0xFB87, 0xFB88, 0xFB89, 0xFB8A, 0xFB8B, 24878 0xFB8C, 0xFB8D, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91, 0xFB92, 0xFB93, 0xFB94, 24879 0xFB95, 0xFB96, 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B, 0xFB9C, 0xFB9D, 24880 0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3, 0xFBA4, 0xFBA5, 0xFBA6, 24881 0xFBA7, 0xFBA8, 0xFBA9, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD, 0xFBAE, 0xFBAF, 24882 0xFBB0, 0xFBB1, 0xFBB2, 0xFBB3, 0xFBB4, 0xFBB5, 0xFBB6, 0xFBB7, 0xFBB8, 24883 0xFBB9, 0xFBBA, 0xFBBB, 0xFBBC, 0xFBBD, 0xFBBE, 0xFBBF, 0xFBC0, 0xFBC1, 24884 0xFBD3, 0xFBD4, 0xFBD5, 0xFBD6, 0xFBD7, 0xFBD8, 0xFBD9, 0xFBDA, 0xFBDB, 24885 0xFBDC, 0xFBDD, 0xFBDE, 0xFBDF, 0xFBE0, 0xFBE1, 0xFBE2, 0xFBE3, 0xFBE4, 24886 0xFBE5, 0xFBE6, 0xFBE7, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEB, 0xFBEC, 0xFBED, 24887 0xFBEE, 0xFBEF, 0xFBF0, 0xFBF1, 0xFBF2, 0xFBF3, 0xFBF4, 0xFBF5, 0xFBF6, 24888 0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF, 24889 0xFC00, 0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08, 24890 0xFC09, 0xFC0A, 0xFC0B, 0xFC0C, 0xFC0D, 0xFC0E, 0xFC0F, 0xFC10, 0xFC11, 24891 0xFC12, 0xFC13, 0xFC14, 0xFC15, 0xFC16, 0xFC17, 0xFC18, 0xFC19, 0xFC1A, 24892 0xFC1B, 0xFC1C, 0xFC1D, 0xFC1E, 0xFC1F, 0xFC20, 0xFC21, 0xFC22, 0xFC23, 24893 0xFC24, 0xFC25, 0xFC26, 0xFC27, 0xFC28, 0xFC29, 0xFC2A, 0xFC2B, 0xFC2C, 24894 0xFC2D, 0xFC2E, 0xFC2F, 0xFC30, 0xFC31, 0xFC32, 0xFC33, 0xFC34, 0xFC35, 24895 0xFC36, 0xFC37, 0xFC38, 0xFC39, 0xFC3A, 0xFC3B, 0xFC3C, 0xFC3D, 0xFC3E, 24896 0xFC3F, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44, 0xFC45, 0xFC46, 0xFC47, 24897 0xFC48, 0xFC49, 0xFC4A, 0xFC4B, 0xFC4C, 0xFC4D, 0xFC4E, 0xFC4F, 0xFC50,
24898 0xFC51, 0xFC52, 0xFC53, 0xFC54, 0xFC55, 0xFC56, 0xFC57, 0xFC58, 0xFC59, 24899 0xFC5A, 0xFC5B, 0xFC5C, 0xFC5D, 0xFC5E, 0xFC5F, 0xFC60, 0xFC61, 0xFC62, 24900 0xFC63, 0xFC64, 0xFC65, 0xFC66, 0xFC67, 0xFC68, 0xFC69, 0xFC6A, 0xFC6B, 24901 0xFC6C, 0xFC6D, 0xFC6E, 0xFC6F, 0xFC70, 0xFC71, 0xFC72, 0xFC73, 0xFC74, 24902 0xFC75, 0xFC76, 0xFC77, 0xFC78, 0xFC79, 0xFC7A, 0xFC7B, 0xFC7C, 0xFC7D, 24903 0xFC7E, 0xFC7F, 0xFC80, 0xFC81, 0xFC82, 0xFC83, 0xFC84, 0xFC85, 0xFC86, 24904 0xFC87, 0xFC88, 0xFC89, 0xFC8A, 0xFC8B, 0xFC8C, 0xFC8D, 0xFC8E, 0xFC8F, 24905 0xFC90, 0xFC91, 0xFC92, 0xFC93, 0xFC94, 0xFC95, 0xFC96, 0xFC97, 0xFC98, 24906 0xFC99, 0xFC9A, 0xFC9B, 0xFC9C, 0xFC9D, 0xFC9E, 0xFC9F, 0xFCA0, 0xFCA1, 24907 0xFCA2, 0xFCA3, 0xFCA4, 0xFCA5, 0xFCA6, 0xFCA7, 0xFCA8, 0xFCA9, 0xFCAA, 24908 0xFCAB, 0xFCAC, 0xFCAD, 0xFCAE, 0xFCAF, 0xFCB0, 0xFCB1, 0xFCB2, 0xFCB3, 24909 0xFCB4, 0xFCB5, 0xFCB6, 0xFCB7, 0xFCB8, 0xFCB9, 0xFCBA, 0xFCBB, 0xFCBC, 24910 0xFCBD, 0xFCBE, 0xFCBF, 0xFCC0, 0xFCC1, 0xFCC2, 0xFCC3, 0xFCC4, 0xFCC5, 24911 0xFCC6, 0xFCC7, 0xFCC8, 0xFCC9, 0xFCCA, 0xFCCB, 0xFCCC, 0xFCCD, 0xFCCE, 24912 0xFCCF, 0xFCD0, 0xFCD1, 0xFCD2, 0xFCD3, 0xFCD4, 0xFCD5, 0xFCD6, 0xFCD7, 24913 0xFCD8, 0xFCD9, 0xFCDA, 0xFCDB, 0xFCDC, 0xFCDD, 0xFCDE, 0xFCDF, 0xFCE0, 24914 0xFCE1, 0xFCE2, 0xFCE3, 0xFCE4, 0xFCE5, 0xFCE6, 0xFCE7, 0xFCE8, 0xFCE9, 24915 0xFCEA, 0xFCEB, 0xFCEC, 0xFCED, 0xFCEE, 0xFCEF, 0xFCF0, 0xFCF1, 0xFCF2, 24916 0xFCF3, 0xFCF4, 0xFCF5, 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, 0xFCFA, 0xFCFB, 24917 0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04, 24918 0xFD05, 0xFD06, 0xFD07, 0xFD08, 0xFD09, 0xFD0A, 0xFD0B, 0xFD0C, 0xFD0D, 24919 0xFD0E, 0xFD0F, 0xFD10, 0xFD11, 0xFD12, 0xFD13, 0xFD14, 0xFD15, 0xFD16, 24920 0xFD17, 0xFD18, 0xFD19, 0xFD1A, 0xFD1B, 0xFD1C, 0xFD1D, 0xFD1E, 0xFD1F, 24921 0xFD20, 0xFD21, 0xFD22, 0xFD23, 0xFD24, 0xFD25, 0xFD26, 0xFD27, 0xFD28, 24922 0xFD29, 0xFD2A, 0xFD2B, 0xFD2C, 0xFD2D, 0xFD2E, 0xFD2F, 0xFD30, 0xFD31, 24923 0xFD32, 0xFD33, 0xFD34, 0xFD35, 0xFD36, 0xFD37, 0xFD38, 0xFD39, 0xFD3A, 24924 0xFD3B, 0xFD3C, 0xFD3D, 0xFD50, 0xFD51, 0xFD52, 0xFD53, 0xFD54, 0xFD55, 24925 0xFD56, 0xFD57, 0xFD58, 0xFD59, 0xFD5A, 0xFD5B, 0xFD5C, 0xFD5D, 0xFD5E, 24926 0xFD5F, 0xFD60, 0xFD61, 0xFD62, 0xFD63, 0xFD64, 0xFD65, 0xFD66, 0xFD67, 24927 0xFD68, 0xFD69, 0xFD6A, 0xFD6B, 0xFD6C, 0xFD6D, 0xFD6E, 0xFD6F, 0xFD70, 24928 0xFD71, 0xFD72, 0xFD73, 0xFD74, 0xFD75, 0xFD76, 0xFD77, 0xFD78, 0xFD79, 24929 0xFD7A, 0xFD7B, 0xFD7C, 0xFD7D, 0xFD7E, 0xFD7F, 0xFD80, 0xFD81, 0xFD82, 24930 0xFD83, 0xFD84, 0xFD85, 0xFD86, 0xFD87, 0xFD88, 0xFD89, 0xFD8A, 0xFD8B, 24931 0xFD8C, 0xFD8D, 0xFD8E, 0xFD8F, 0xFD92, 0xFD93, 0xFD94, 0xFD95, 0xFD96, 24932 0xFD97, 0xFD98, 0xFD99, 0xFD9A, 0xFD9B, 0xFD9C, 0xFD9D, 0xFD9E, 0xFD9F, 24933 0xFDA0, 0xFDA1, 0xFDA2, 0xFDA3, 0xFDA4, 0xFDA5, 0xFDA6, 0xFDA7, 0xFDA8, 24934 0xFDA9, 0xFDAA, 0xFDAB, 0xFDAC, 0xFDAD, 0xFDAE, 0xFDAF, 0xFDB0, 0xFDB1, 24935 0xFDB2, 0xFDB3, 0xFDB4, 0xFDB5, 0xFDB6, 0xFDB7, 0xFDB8, 0xFDB9, 0xFDBA, 24936 0xFDBB, 0xFDBC, 0xFDBD, 0xFDBE, 0xFDBF, 0xFDC0, 0xFDC1, 0xFDC2, 0xFDC3, 24937 0xFDC4, 0xFDC5, 0xFDC6, 0xFDC7, 0xFDF0, 0xFDF1, 0xFDF2, 0xFDF3, 0xFDF4, 24938 0xFDF5, 0xFDF6, 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, 0xFE70, 24939 0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE76, 0xFE77, 0xFE78, 0xFE79, 0xFE7A, 24940 0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F, 0xFE80, 0xFE81, 0xFE82, 0xFE83, 24941 0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C, 24942 0xFE8D, 0xFE8E, 0xFE8F, 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95, 24943 0xFE96, 0xFE97, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E, 24944 0xFE9F, 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7, 24945 0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF, 0xFEB0, 24946 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9, 24947 0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0, 0xFEC1, 0xFEC2, 24948 0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9, 0xFECA, 0xFECB, 24949 0xFECC, 0xFECD, 0xFECE, 0xFECF, 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4, 24950 0xFED5, 0xFED6, 0xFED7, 0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD, 24951 0xFEDE, 0xFEDF, 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6,
24952 0xFEE7, 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF, 24953 0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8, 24954 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0x10800, 0x10801, 0x10802, 0x10803, 24955 0x10804, 0x10805, 0x10808, 0x1080A, 0x1080B, 0x1080C, 0x1080D, 0x1080E, 24956 0x1080F, 0x10810, 0x10811, 0x10812, 0x10813, 0x10814, 0x10815, 0x10816, 24957 0x10817, 0x10818, 0x10819, 0x1081A, 0x1081B, 0x1081C, 0x1081D, 0x1081E, 24958 0x1081F, 0x10820, 0x10821, 0x10822, 0x10823, 0x10824, 0x10825, 0x10826, 24959 0x10827, 0x10828, 0x10829, 0x1082A, 0x1082B, 0x1082C, 0x1082D, 0x1082E, 24960 0x1082F, 0x10830, 0x10831, 0x10832, 0x10833, 0x10834, 0x10835, 0x10837, 24961 0x10838, 0x1083C, 0x1083F, 0x10840, 0x10841, 0x10842, 0x10843, 0x10844, 24962 0x10845, 0x10846, 0x10847, 0x10848, 0x10849, 0x1084A, 0x1084B, 0x1084C, 24963 0x1084D, 0x1084E, 0x1084F, 0x10850, 0x10851, 0x10852, 0x10853, 0x10854, 24964 0x10855, 0x10857, 0x10858, 0x10859, 0x1085A, 0x1085B, 0x1085C, 0x1085D, 24965 0x1085E, 0x1085F, 0x10900, 0x10901, 0x10902, 0x10903, 0x10904, 0x10905, 24966 0x10906, 0x10907, 0x10908, 0x10909, 0x1090A, 0x1090B, 0x1090C, 0x1090D, 24967 0x1090E, 0x1090F, 0x10910, 0x10911, 0x10912, 0x10913, 0x10914, 0x10915, 24968 0x10916, 0x10917, 0x10918, 0x10919, 0x1091A, 0x1091B, 0x10920, 0x10921, 24969 0x10922, 0x10923, 0x10924, 0x10925, 0x10926, 0x10927, 0x10928, 0x10929, 24970 0x1092A, 0x1092B, 0x1092C, 0x1092D, 0x1092E, 0x1092F, 0x10930, 0x10931, 24971 0x10932, 0x10933, 0x10934, 0x10935, 0x10936, 0x10937, 0x10938, 0x10939, 24972 0x1093F, 0x10980, 0x10981, 0x10982, 0x10983, 0x10984, 0x10985, 0x10986, 24973 0x10987, 0x10988, 0x10989, 0x1098A, 0x1098B, 0x1098C, 0x1098D, 0x1098E, 24974 0x1098F, 0x10990, 0x10991, 0x10992, 0x10993, 0x10994, 0x10995, 0x10996, 24975 0x10997, 0x10998, 0x10999, 0x1099A, 0x1099B, 0x1099C, 0x1099D, 0x1099E, 24976 0x1099F, 0x109A0, 0x109A1, 0x109A2, 0x109A3, 0x109A4, 0x109A5, 0x109A6, 24977 0x109A7, 0x109A8, 0x109A9, 0x109AA, 0x109AB, 0x109AC, 0x109AD, 0x109AE, 24978 0x109AF, 0x109B0, 0x109B1, 0x109B2, 0x109B3, 0x109B4, 0x109B5, 0x109B6, 24979 0x109B7, 0x109BE, 0x109BF, 0x10A00, 0x10A10, 0x10A11, 0x10A12, 0x10A13, 24980 0x10A15, 0x10A16, 0x10A17, 0x10A19, 0x10A1A, 0x10A1B, 0x10A1C, 0x10A1D, 24981 0x10A1E, 0x10A1F, 0x10A20, 0x10A21, 0x10A22, 0x10A23, 0x10A24, 0x10A25, 24982 0x10A26, 0x10A27, 0x10A28, 0x10A29, 0x10A2A, 0x10A2B, 0x10A2C, 0x10A2D, 24983 0x10A2E, 0x10A2F, 0x10A30, 0x10A31, 0x10A32, 0x10A33, 0x10A40, 0x10A41, 24984 0x10A42, 0x10A43, 0x10A44, 0x10A45, 0x10A46, 0x10A47, 0x10A50, 0x10A51, 24985 0x10A52, 0x10A53, 0x10A54, 0x10A55, 0x10A56, 0x10A57, 0x10A58, 0x10A60, 24986 0x10A61, 0x10A62, 0x10A63, 0x10A64, 0x10A65, 0x10A66, 0x10A67, 0x10A68, 24987 0x10A69, 0x10A6A, 0x10A6B, 0x10A6C, 0x10A6D, 0x10A6E, 0x10A6F, 0x10A70, 24988 0x10A71, 0x10A72, 0x10A73, 0x10A74, 0x10A75, 0x10A76, 0x10A77, 0x10A78, 24989 0x10A79, 0x10A7A, 0x10A7B, 0x10A7C, 0x10A7D, 0x10A7E, 0x10A7F, 0x10B00, 24990 0x10B01, 0x10B02, 0x10B03, 0x10B04, 0x10B05, 0x10B06, 0x10B07, 0x10B08, 24991 0x10B09, 0x10B0A, 0x10B0B, 0x10B0C, 0x10B0D, 0x10B0E, 0x10B0F, 0x10B10, 24992 0x10B11, 0x10B12, 0x10B13, 0x10B14, 0x10B15, 0x10B16, 0x10B17, 0x10B18, 24993 0x10B19, 0x10B1A, 0x10B1B, 0x10B1C, 0x10B1D, 0x10B1E, 0x10B1F, 0x10B20, 24994 0x10B21, 0x10B22, 0x10B23, 0x10B24, 0x10B25, 0x10B26, 0x10B27, 0x10B28, 24995 0x10B29, 0x10B2A, 0x10B2B, 0x10B2C, 0x10B2D, 0x10B2E, 0x10B2F, 0x10B30, 24996 0x10B31, 0x10B32, 0x10B33, 0x10B34, 0x10B35, 0x10B40, 0x10B41, 0x10B42, 24997 0x10B43, 0x10B44, 0x10B45, 0x10B46, 0x10B47, 0x10B48, 0x10B49, 0x10B4A, 24998 0x10B4B, 0x10B4C, 0x10B4D, 0x10B4E, 0x10B4F, 0x10B50, 0x10B51, 0x10B52, 24999 0x10B53, 0x10B54, 0x10B55, 0x10B58, 0x10B59, 0x10B5A, 0x10B5B, 0x10B5C, 25000 0x10B5D, 0x10B5E, 0x10B5F, 0x10B60, 0x10B61, 0x10B62, 0x10B63, 0x10B64, 25001 0x10B65, 0x10B66, 0x10B67, 0x10B68, 0x10B69, 0x10B6A, 0x10B6B, 0x10B6C, 25002 0x10B6D, 0x10B6E, 0x10B6F, 0x10B70, 0x10B71, 0x10B72, 0x10B78, 0x10B79, 25003 0x10B7A, 0x10B7B, 0x10B7C, 0x10B7D, 0x10B7E, 0x10B7F, 0x10C00, 0x10C01, 25004 0x10C02, 0x10C03, 0x10C04, 0x10C05, 0x10C06, 0x10C07, 0x10C08, 0x10C09, 25005 0x10C0A, 0x10C0B, 0x10C0C, 0x10C0D, 0x10C0E, 0x10C0F, 0x10C10, 0x10C11, 25006 0x10C12, 0x10C13, 0x10C14, 0x10C15, 0x10C16, 0x10C17, 0x10C18, 0x10C19, 25007 0x10C1A, 0x10C1B, 0x10C1C, 0x10C1D, 0x10C1E, 0x10C1F, 0x10C20, 0x10C21, 25008 0x10C22, 0x10C23, 0x10C24, 0x10C25, 0x10C26, 0x10C27, 0x10C28, 0x10C29, 25009 0x10C2A, 0x10C2B, 0x10C2C, 0x10C2D, 0x10C2E, 0x10C2F, 0x10C30, 0x10C31, 25010 0x10C32, 0x10C33, 0x10C34, 0x10C35, 0x10C36, 0x10C37, 0x10C38, 0x10C39, 25011 0x10C3A, 0x10C3B, 0x10C3C, 0x10C3D, 0x10C3E, 0x10C3F, 0x10C40, 0x10C41, 25012 0x10C42, 0x10C43, 0x10C44, 0x10C45, 0x10C46, 0x10C47, 0x10C48, 0x1EE00, 25013 0x1EE01, 0x1EE02, 0x1EE03, 0x1EE05, 0x1EE06, 0x1EE07, 0x1EE08, 0x1EE09, 25014 0x1EE0A, 0x1EE0B, 0x1EE0C, 0x1EE0D, 0x1EE0E, 0x1EE0F, 0x1EE10, 0x1EE11, 25015 0x1EE12, 0x1EE13, 0x1EE14, 0x1EE15, 0x1EE16, 0x1EE17, 0x1EE18, 0x1EE19, 25016 0x1EE1A, 0x1EE1B, 0x1EE1C, 0x1EE1D, 0x1EE1E, 0x1EE1F, 0x1EE21, 0x1EE22, 25017 0x1EE24, 0x1EE27, 0x1EE29, 0x1EE2A, 0x1EE2B, 0x1EE2C, 0x1EE2D, 0x1EE2E, 25018 0x1EE2F, 0x1EE30, 0x1EE31, 0x1EE32, 0x1EE34, 0x1EE35, 0x1EE36, 0x1EE37, 25019 0x1EE39, 0x1EE3B, 0x1EE42, 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE4D, 0x1EE4E, 25020 0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE57, 0x1EE59, 0x1EE5B, 0x1EE5D, 25021 0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE67, 0x1EE68, 0x1EE69, 0x1EE6A, 25022 0x1EE6C, 0x1EE6D, 0x1EE6E, 0x1EE6F, 0x1EE70, 0x1EE71, 0x1EE72, 0x1EE74, 25023 0x1EE75, 0x1EE76, 0x1EE77, 0x1EE79, 0x1EE7A, 0x1EE7B, 0x1EE7C, 0x1EE7E, 25024 0x1EE80, 0x1EE81, 0x1EE82, 0x1EE83, 0x1EE84, 0x1EE85, 0x1EE86, 0x1EE87, 25025 0x1EE88, 0x1EE89, 0x1EE8B, 0x1EE8C, 0x1EE8D, 0x1EE8E, 0x1EE8F, 0x1EE90, 25026 0x1EE91, 0x1EE92, 0x1EE93, 0x1EE94, 0x1EE95, 0x1EE96, 0x1EE97, 0x1EE98, 25027 0x1EE99, 0x1EE9A, 0x1EE9B, 0x1EEA1, 0x1EEA2, 0x1EEA3, 0x1EEA5, 0x1EEA6, 25028 0x1EEA7, 0x1EEA8, 0x1EEA9, 0x1EEAB, 0x1EEAC, 0x1EEAD, 0x1EEAE, 0x1EEAF, 25029 0x1EEB0, 0x1EEB1, 0x1EEB2, 0x1EEB3, 0x1EEB4, 0x1EEB5, 0x1EEB6, 0x1EEB7, 25030 0x1EEB8, 0x1EEB9, 0x1EEBA, 0x1EEBB, 0x10FFFD]; 25031 25032 function determineBidi(cueDiv) { 25033 var nodeStack = [], 25034 text = "",
vendor: 27,517 bytes, lines 25035-25866
25035 charCode; 25036 25037 if (!cueDiv || !cueDiv.childNodes) { 25038 return "ltr"; 25039 } 25040 25041 function pushNodes(nodeStack, node) { 25042 for (var i = node.childNodes.length - 1; i >= 0; i--) { 25043 nodeStack.push(node.childNodes[i]); 25044 } 25045 } 25046 25047 function nextTextNode(nodeStack) { 25048 if (!nodeStack || !nodeStack.length) { 25049 return null; 25050 } 25051 25052 var node = nodeStack.pop(), 25053 text = node.textContent || node.innerText; 25054 if (text) { 25055 // TODO: This should match all unicode type B characters (paragraph 25056 // separator characters). See issue #115. 25057 var m = text.match(/^.*(\n|\r)/); 25058 if (m) { 25059 nodeStack.length = 0; 25060 return m[0]; 25061 } 25062 return text; 25063 } 25064 if (node.tagName === "ruby") { 25065 return nextTextNode(nodeStack); 25066 } 25067 if (node.childNodes) { 25068 pushNodes(nodeStack, node); 25069 return nextTextNode(nodeStack); 25070 } 25071 } 25072 25073 pushNodes(nodeStack, cueDiv); 25074 while ((text = nextTextNode(nodeStack))) { 25075 for (var i = 0; i < text.length; i++) { 25076 charCode = text.charCodeAt(i); 25077 for (var j = 0; j < strongRTLChars.length; j++) { 25078 if (strongRTLChars[j] === charCode) { 25079 return "rtl"; 25080 } 25081 } 25082 } 25083 } 25084 return "ltr"; 25085 } 25086 25087 function computeLinePos(cue) { 25088 if (typeof cue.line === "number" && 25089 (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) { 25090 return cue.line; 25091 } 25092 if (!cue.track || !cue.track.textTrackList || 25093 !cue.track.textTrackList.mediaElement) { 25094 return -1; 25095 } 25096 var track = cue.track, 25097 trackList = track.textTrackList, 25098 count = 0; 25099 for (var i = 0; i < trackList.length && trackList[i] !== track; i++) { 25100 if (trackList[i].mode === "showing") { 25101 count++; 25102 } 25103 } 25104 return ++count * -1; 25105 } 25106 25107 function StyleBox() { 25108 } 25109 25110 // Apply styles to a div. If there is no div passed then it defaults to the 25111 // div on 'this'. 25112 StyleBox.prototype.applyStyles = function(styles, div) { 25113 div = div || this.div; 25114 for (var prop in styles) { 25115 if (styles.hasOwnProperty(prop)) { 25116 div.style[prop] = styles[prop]; 25117 } 25118 } 25119 }; 25120 25121 StyleBox.prototype.formatStyle = function(val, unit) { 25122 return val === 0 ? 0 : val + unit; 25123 }; 25124 25125 // Constructs the computed display state of the cue (a div). Places the div 25126 // into the overlay which should be a block level element (usually a div). 25127 function CueStyleBox(window, cue, styleOptions) { 25128 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); 25129 var color = "rgba(255, 255, 255, 1)"; 25130 var backgroundColor = "rgba(0, 0, 0, 0.8)"; 25131 25132 if (isIE8) { 25133 color = "rgb(255, 255, 255)"; 25134 backgroundColor = "rgb(0, 0, 0)"; 25135 } 25136 25137 StyleBox.call(this); 25138 this.cue = cue; 25139 25140 // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will 25141 // have inline positioning and will function as the cue background box. 25142 this.cueDiv = parseContent(window, cue.text); 25143 var styles = { 25144 color: color, 25145 backgroundColor: backgroundColor, 25146 position: "relative", 25147 left: 0, 25148 right: 0, 25149 top: 0, 25150 bottom: 0, 25151 display: "inline" 25152 }; 25153 25154 if (!isIE8) { 25155 styles.writingMode = cue.vertical === "" ? "horizontal-tb" 25156 : cue.vertical === "lr" ? "vertical-lr" 25157 : "vertical-rl"; 25158 styles.unicodeBidi = "plaintext"; 25159 } 25160 this.applyStyles(styles, this.cueDiv); 25161 25162 // Create an absolutely positioned div that will be used to position the cue 25163 // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS 25164 // mirrors of them except "middle" which is "center" in CSS. 25165 this.div = window.document.createElement("div"); 25166 styles = { 25167 textAlign: cue.align === "middle" ? "center" : cue.align, 25168 font: styleOptions.font, 25169 whiteSpace: "pre-line", 25170 position: "absolute" 25171 }; 25172 25173 if (!isIE8) { 25174 styles.direction = determineBidi(this.cueDiv); 25175 styles.writingMode = cue.vertical === "" ? "horizontal-tb" 25176 : cue.vertical === "lr" ? "vertical-lr" 25177 : "vertical-rl". 25178 stylesunicodeBidi = "plaintext"; 25179 } 25180 25181 this.applyStyles(styles); 25182 25183 this.div.appendChild(this.cueDiv); 25184 25185 // Calculate the distance from the reference edge of the viewport to the text 25186 // position of the cue box. The reference edge will be resolved later when 25187 // the box orientation styles are applied. 25188 var textPos = 0; 25189 switch (cue.positionAlign) { 25190 case "start": 25191 textPos = cue.position; 25192 break; 25193 case "middle": 25194 textPos = cue.position - (cue.size / 2); 25195 break; 25196 case "end": 25197 textPos = cue.position - cue.size; 25198 break; 25199 } 25200 25201 // Horizontal box orientation; textPos is the distance from the left edge of the 25202 // area to the left edge of the box and cue.size is the distance extending to 25203 // the right from there. 25204 if (cue.vertical === "") { 25205 this.applyStyles({ 25206 left: this.formatStyle(textPos, "%"), 25207 width: this.formatStyle(cue.size, "%") 25208 }); 25209 // Vertical box orientation; textPos is the distance from the top edge of the 25210 // area to the top edge of the box and cue.size is the height extending 25211 // downwards from there. 25212 } else { 25213 this.applyStyles({ 25214 top: this.formatStyle(textPos, "%"), 25215 height: this.formatStyle(cue.size, "%") 25216 }); 25217 } 25218 25219 this.move = function(box) { 25220 this.applyStyles({ 25221 top: this.formatStyle(box.top, "px"), 25222 bottom: this.formatStyle(box.bottom, "px"), 25223 left: this.formatStyle(box.left, "px"), 25224 right: this.formatStyle(box.right, "px"), 25225 height: this.formatStyle(box.height, "px"), 25226 width: this.formatStyle(box.width, "px") 25227 }); 25228 }; 25229 } 25230 CueStyleBox.prototype = _objCreate(StyleBox.prototype); 25231 CueStyleBox.prototype.constructor = CueStyleBox; 25232 25233 // Represents the co-ordinates of an Element in a way that we can easily 25234 // compute things with such as if it overlaps or intersects with another Element. 25235 // Can initialize it with either a StyleBox or another BoxPosition. 25236 function BoxPosition(obj) { 25237 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); 25238 25239 // Either a BoxPosition was passed in and we need to copy it, or a StyleBox 25240 // was passed in and we need to copy the results of 'getBoundingClientRect' 25241 // as the object returned is readonly. All co-ordinate values are in reference 25242 // to the viewport origin (top left). 25243 var lh, height, width, top; 25244 if (obj.div) { 25245 height = obj.div.offsetHeight; 25246 width = obj.div.offsetWidth; 25247 top = obj.div.offsetTop; 25248 25249 var rects = (rects = obj.div.childNodes) && (rects = rects[0]) && 25250 rects.getClientRects && rects.getClientRects(); 25251 obj = obj.div.getBoundingClientRect(); 25252 // In certain cases the outter div will be slightly larger then the sum of 25253 // the inner div's lines. This could be due to bold text, etc, on some platforms. 25254 // In this case we should get the average line height and use that. This will 25255 // result in the desired behaviour. 25256 lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length) 25257 : 0; 25258 25259 } 25260 this.left = obj.left; 25261 this.right = obj.right; 25262 this.top = obj.top || top; 25263 this.height = obj.height || height; 25264 this.bottom = obj.bottom || (top + (obj.height || height)); 25265 this.width = obj.width || width; 25266 this.lineHeight = lh !== undefined ? lh : obj.lineHeight; 25267 25268 if (isIE8 && !this.lineHeight) { 25269 this.lineHeight = 13; 25270 } 25271 } 25272 25273 // Move the box along a particular axis. Optionally pass in an amount to move 25274 // the box. If no amount is passed then the default is the line height of the 25275 // box. 25276 BoxPosition.prototype.move = function(axis, toMove) { 25277 toMove = toMove !== undefined ? toMove : this.lineHeight; 25278 switch (axis) { 25279 case "+x": 25280 this.left += toMove; 25281 this.right += toMove; 25282 break; 25283 case "-x": 25284 this.left -= toMove; 25285 this.right -= toMove; 25286 break; 25287 case "+y": 25288 this.top += toMove; 25289 this.bottom += toMove; 25290 break; 25291 case "-y": 25292 this.top -= toMove; 25293 this.bottom -= toMove; 25294 break; 25295 } 25296 }; 25297 25298 // Check if this box overlaps another box, b2. 25299 BoxPosition.prototype.overlaps = function(b2) { 25300 return this.left < b2.right && 25301 this.right > b2.left && 25302 this.top < b2.bottom && 25303 this.bottom > b2.top; 25304 }; 25305 25306 // Check if this box overlaps any other boxes in boxes. 25307 BoxPosition.prototype.overlapsAny = function(boxes) { 25308 for (var i = 0; i < boxes.length; i++) { 25309 if (this.overlaps(boxes[i])) { 25310 return true; 25311 } 25312 } 25313 return false; 25314 }; 25315 25316 // Check if this box is within another box. 25317 BoxPosition.prototype.within = function(container) { 25318 return this.top >= container.top && 25319 this.bottom <= container.bottom && 25320 this.left >= container.left && 25321 this.right <= container.right; 25322 }; 25323 25324 // Check if this box is entirely within the container or it is overlapping 25325 // on the edge opposite of the axis direction passed. For example, if "+x" is 25326 // passed and the box is overlapping on the left edge of the container, then 25327 // return true. 25328 BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) { 25329 switch (axis) { 25330 case "+x": 25331 return this.left < container.left; 25332 case "-x": 25333 return this.right > container.right; 25334 case "+y": 25335 return this.top < container.top; 25336 case "-y": 25337 return this.bottom > container.bottom; 25338 } 25339 }; 25340 25341 // Find the percentage of the area that this box is overlapping with another 25342 // box. 25343 BoxPosition.prototype.intersectPercentage = function(b2) { 25344 var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)), 25345 y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)), 25346 intersectArea = x * y; 25347 return intersectArea / (this.height * this.width); 25348 }; 25349 25350 // Convert the positions from this box to CSS compatible positions using 25351 // the reference container's positions. This has to be done because this 25352 // box's positions are in reference to the viewport origin, whereas, CSS 25353 // values are in referecne to their respective edges. 25354 BoxPosition.prototype.toCSSCompatValues = function(reference) { 25355 return { 25356 top: this.top - reference.top, 25357 bottom: reference.bottom - this.bottom, 25358 left: this.left - reference.left, 25359 right: reference.right - this.right, 25360 height: this.height, 25361 width: this.width 25362 }; 25363 }; 25364 25365 // Get an object that represents the box's position without anything extra. 25366 // Can pass a StyleBox, HTMLElement, or another BoxPositon. 25367 BoxPosition.getSimpleBoxPosition = function(obj) { 25368 var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0; 25369 var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0; 25370 var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0; 25371 25372 obj = obj.div ? obj.div.getBoundingClientRect() : 25373 obj.tagName ? obj.getBoundingClientRect() : obj; 25374 var ret = { 25375 left: obj.left, 25376 right: obj.right, 25377 top: obj.top || top, 25378 height: obj.height || height, 25379 bottom: obj.bottom || (top + (obj.height || height)), 25380 width: obj.width || width 25381 }; 25382 return ret; 25383 }; 25384 25385 // Move a StyleBox to its specified, or next best, position. The containerBox 25386 // is the box that contains the StyleBox, such as a div. boxPositions are 25387 // a list of other boxes that the styleBox can't overlap with. 25388 function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) { 25389 25390 // Find the best position for a cue box, b, on the video. The axis parameter 25391 // is a list of axis, the order of which, it will move the box along. For example: 25392 // Passing ["+x", "-x"] will move the box first along the x axis in the positive 25393 // direction. If it doesn't find a good position for it there it will then move 25394 // it along the x axis in the negative direction. 25395 function findBestPosition(b, axis) { 25396 var bestPosition, 25397 specifiedPosition = new BoxPosition(b), 25398 percentage = 1; // Highest possible so the first thing we get is better. 25399 25400 for (var i = 0; i < axis.length; i++) { 25401 while (b.overlapsOppositeAxis(containerBox, axis[i]) || 25402 (b.within(containerBox) && b.overlapsAny(boxPositions))) { 25403 b.move(axis[i]); 25404 } 25405 // We found a spot where we aren't overlapping anything. This is our 25406 // best position. 25407 if (b.within(containerBox)) { 25408 return b; 25409 } 25410 var p = b.intersectPercentage(containerBox); 25411 // If we're outside the container box less then we were on our last try 25412 // then remember this position as the best position. 25413 if (percentage > p) { 25414 bestPosition = new BoxPosition(b); 25415 percentage = p; 25416 } 25417 // Reset the box position to the specified position. 25418 b = new BoxPosition(specifiedPosition); 25419 } 25420 return bestPosition || specifiedPosition; 25421 } 25422 25423 var boxPosition = new BoxPosition(styleBox), 25424 cue = styleBox.cue, 25425 linePos = computeLinePos(cue), 25426 axis = []; 25427 25428 // If we have a line number to align the cue to. 25429 if (cue.snapToLines) { 25430 var size; 25431 switch (cue.vertical) { 25432 case "": 25433 axis = [ "+y", "-y" ]; 25434 size = "height"; 25435 break; 25436 case "rl": 25437 axis = [ "+x", "-x" ]; 25438 size = "width"; 25439 break; 25440 case "lr": 25441 axis = [ "-x", "+x" ]; 25442 size = "width"; 25443 break; 25444 } 25445 25446 var step = boxPosition.lineHeight, 25447 position = step * Math.round(linePos), 25448 maxPosition = containerBox[size] + step, 25449 initialAxis = axis[0]; 25450 25451 // If the specified intial position is greater then the max position then 25452 // clamp the box to the amount of steps it would take for the box to 25453 // reach the max position. 25454 if (Math.abs(position) > maxPosition) { 25455 position = position < 0 ? -1 : 1; 25456 position *= Math.ceil(maxPosition / step) * step; 25457 } 25458 25459 // If computed line position returns negative then line numbers are 25460 // relative to the bottom of the video instead of the top. Therefore, we 25461 // need to increase our initial position by the length or width of the 25462 // video, depending on the writing direction, and reverse our axis directions. 25463 if (linePos < 0) { 25464 position += cue.vertical === "" ? containerBox.height : containerBox.width; 25465 axis = axis.reverse(); 25466 } 25467 25468 // Move the box to the specified position. This may not be its best 25469 // position. 25470 boxPosition.move(initialAxis, position); 25471 25472 } else { 25473 // If we have a percentage line value for the cue. 25474 var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100; 25475 25476 switch (cue.lineAlign) { 25477 case "middle": 25478 linePos -= (calculatedPercentage / 2); 25479 break; 25480 case "end": 25481 linePos -= calculatedPercentage; 25482 break; 25483 } 25484 25485 // Apply initial line position to the cue box. 25486 switch (cue.vertical) { 25487 case "": 25488 styleBox.applyStyles({ 25489 top: styleBox.formatStyle(linePos, "%") 25490 }); 25491 break; 25492 case "rl": 25493 styleBox.applyStyles({ 25494 left: styleBox.formatStyle(linePos, "%") 25495 }); 25496 break; 25497 case "lr": 25498 styleBox.applyStyles({ 25499 right: styleBox.formatStyle(linePos, "%") 25500 }); 25501 break; 25502 } 25503 25504 axis = [ "+y", "-x", "+x", "-y" ]; 25505 25506 // Get the box position again after we've applied the specified positioning 25507 // to it. 25508 boxPosition = new BoxPosition(styleBox); 25509 } 25510 25511 var bestPosition = findBestPosition(boxPosition, axis); 25512 styleBox.move(bestPosition.toCSSCompatValues(containerBox)); 25513 } 25514 25515 function WebVTT() { 25516 // Nothing 25517 } 25518 25519 // Helper to allow strings to be decoded instead of the default binary utf8 data. 25520 WebVTT.StringDecoder = function() { 25521 return { 25522 decode: function(data) { 25523 if (!data) { 25524 return ""; 25525 } 25526 if (typeof data !== "string") { 25527 throw new Error("Error - expected string data."); 25528 } 25529 return decodeURIComponent(encodeURIComponent(data)); 25530 } 25531 }; 25532 }; 25533 25534 WebVTT.convertCueToDOMTree = function(window, cuetext) { 25535 if (!window || !cuetext) { 25536 return null; 25537 } 25538 return parseContent(window, cuetext); 25539 }; 25540 25541 var FONT_SIZE_PERCENT = 0.05; 25542 var FONT_STYLE = "sans-serif"; 25543 var CUE_BACKGROUND_PADDING = "1.5%"; 25544 25545 // Runs the processing model over the cues and regions passed to it. 25546 // @param overlay A block level element (usually a div) that the computed cues 25547 // and regions will be placed into. 25548 WebVTT.processCues = function(window, cues, overlay) { 25549 if (!window || !cues || !overlay) { 25550 return null; 25551 } 25552 25553 // Remove all previous children. 25554 while (overlay.firstChild) { 25555 overlay.removeChild(overlay.firstChild); 25556 } 25557 25558 var paddedOverlay = window.document.createElement("div"); 25559 paddedOverlay.style.position = "absolute"; 25560 paddedOverlay.style.left = "0"; 25561 paddedOverlay.style.right = "0"; 25562 paddedOverlay.style.top = "0"; 25563 paddedOverlay.style.bottom = "0"; 25564 paddedOverlay.style.margin = CUE_BACKGROUND_PADDING; 25565 overlay.appendChild(paddedOverlay); 25566 25567 // Determine if we need to compute the display states of the cues. This could 25568 // be the case if a cue's state has been changed since the last computation or 25569 // if it has not been computed yet. 25570 function shouldCompute(cues) { 25571 for (var i = 0; i < cues.length; i++) { 25572 if (cues[i].hasBeenReset || !cues[i].displayState) { 25573 return true; 25574 } 25575 } 25576 return false; 25577 } 25578 25579 // We don't need to recompute the cues' display states. Just reuse them. 25580 if (!shouldCompute(cues)) { 25581 for (var i = 0; i < cues.length; i++) { 25582 paddedOverlay.appendChild(cues[i].displayState); 25583 } 25584 return; 25585 } 25586 25587 var boxPositions = [], 25588 containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay), 25589 fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100; 25590 var styleOptions = { 25591 font: fontSize + "px " + FONT_STYLE 25592 }; 25593 25594 (function() { 25595 var styleBox, cue; 25596 25597 for (var i = 0; i < cues.length; i++) { 25598 cue = cues[i]; 25599 25600 // Compute the intial position and styles of the cue div. 25601 styleBox = new CueStyleBox(window, cue, styleOptions); 25602 paddedOverlay.appendChild(styleBox.div); 25603 25604 // Move the cue div to it's correct line position. 25605 moveBoxToLinePosition(window, styleBox, containerBox, boxPositions); 25606 25607 // Remember the computed div so that we don't have to recompute it later 25608 // if we don't have too. 25609 cue.displayState = styleBox.div; 25610 25611 boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox)); 25612 } 25613 })(); 25614 }; 25615 25616 WebVTT.Parser = function(window, vttjs, decoder) { 25617 if (!decoder) { 25618 decoder = vttjs; 25619 vttjs = {}; 25620 } 25621 if (!vttjs) { 25622 vttjs = {}; 25623 } 25624 25625 this.window = window; 25626 this.vttjs = vttjs; 25627 this.state = "INITIAL"; 25628 this.buffer = ""; 25629 this.decoder = decoder || new TextDecoder("utf8"); 25630 this.regionList = []; 25631 }; 25632 25633 WebVTT.Parser.prototype = { 25634 // If the error is a ParsingError then report it to the consumer if 25635 // possible. If it's not a ParsingError then throw it like normal. 25636 reportOrThrowError: function(e) { 25637 if (e instanceof ParsingError) { 25638 this.onparsingerror && this.onparsingerror(e); 25639 } else { 25640 throw e; 25641 } 25642 }, 25643 parse: function (data) { 25644 var self = this; 25645 25646 // If there is no data then we won't decode it, but will just try to parse 25647 // whatever is in buffer already. This may occur in circumstances, for 25648 // example when flush() is called. 25649 if (data) { 25650 // Try to decode the data that we received. 25651 self.buffer += self.decoder.decode(data, {stream: true}); 25652 } 25653 25654 function collectNextLine() { 25655 var buffer = self.buffer; 25656 var pos = 0; 25657 while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') { 25658 ++pos; 25659 } 25660 var line = buffer.substr(0, pos); 25661 // Advance the buffer early in case we fail below. 25662 if (buffer[pos] === '\r') { 25663 ++pos; 25664 } 25665 if (buffer[pos] === '\n') { 25666 ++pos; 25667 } 25668 self.buffer = buffer.substr(pos); 25669 return line; 25670 } 25671 25672 // 3.4 WebVTT region and WebVTT region settings syntax 25673 function parseRegion(input) { 25674 var settings = new Settings(); 25675 25676 parseOptions(input, function (k, v) { 25677 switch (k) { 25678 case "id": 25679 settings.set(k, v); 25680 break; 25681 case "width": 25682 settings.percent(k, v); 25683 break; 25684 case "lines": 25685 settings.integer(k, v); 25686 break; 25687 case "regionanchor": 25688 case "viewportanchor": 25689 var xy = v.split(','); 25690 if (xy.length !== 2) { 25691 break; 25692 } 25693 // We have to make sure both x and y parse, so use a temporary 25694 // settings object here. 25695 var anchor = new Settings(); 25696 anchor.percent("x", xy[0]); 25697 anchor.percent("y", xy[1]); 25698 if (!anchor.has("x") || !anchor.has("y")) { 25699 break; 25700 } 25701 settings.set(k + "X", anchor.get("x")); 25702 settings.set(k + "Y", anchor.get("y")); 25703 break; 25704 case "scroll": 25705 settings.alt(k, v, ["up"]); 25706 break; 25707 } 25708 }, /=/, /\s/); 25709 25710 // Create the region, using default values for any values that were not 25711 // specified. 25712 if (settings.has("id")) { 25713 var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)(); 25714 region.width = settings.get("width", 100); 25715 region.lines = settings.get("lines", 3); 25716 region.regionAnchorX = settings.get("regionanchorX", 0); 25717 region.regionAnchorY = settings.get("regionanchorY", 100); 25718 region.viewportAnchorX = settings.get("viewportanchorX", 0); 25719 region.viewportAnchorY = settings.get("viewportanchorY", 100); 25720 region.scroll = settings.get("scroll", ""); 25721 // Register the region. 25722 self.onregion && self.onregion(region); 25723 // Remember the VTTRegion for later in case we parse any VTTCues that 25724 // reference it. 25725 self.regionList.push({ 25726 id: settings.get("id"), 25727 region: region 25728 }); 25729 } 25730 } 25731 25732 // 3.2 WebVTT metadata header syntax 25733 function parseHeader(input) { 25734 parseOptions(input, function (k, v) { 25735 switch (k) { 25736 case "Region": 25737 // 3.3 WebVTT region metadata header syntax 25738 parseRegion(v); 25739 break; 25740 } 25741 }, /:/); 25742 } 25743 25744 // 5.1 WebVTT file parsing. 25745 try { 25746 var line; 25747 if (self.state === "INITIAL") { 25748 // We can't start parsing until we have the first line. 25749 if (!/\r\n|\n/.test(self.buffer)) { 25750 return this; 25751 } 25752 25753 line = collectNextLine(); 25754 25755 var m = line.match(/^WEBVTT([ \t].*)?$/); 25756 if (!m || !m[0]) { 25757 throw new ParsingError(ParsingError.Errors.BadSignature); 25758 } 25759 25760 self.state = "HEADER"; 25761 } 25762 25763 var alreadyCollectedLine = false; 25764 while (self.buffer) { 25765 // We can't parse a line until we have the full line. 25766 if (!/\r\n|\n/.test(self.buffer)) { 25767 return this; 25768 } 25769 25770 if (!alreadyCollectedLine) { 25771 line = collectNextLine(); 25772 } else { 25773 alreadyCollectedLine = false; 25774 } 25775 25776 switch (self.state) { 25777 case "HEADER": 25778 // 13-18 - Allow a header (metadata) under the WEBVTT line. 25779 if (/:/.test(line)) { 25780 parseHeader(line); 25781 } else if (!line) { 25782 // An empty line terminates the header and starts the body (cues). 25783 self.state = "ID"; 25784 } 25785 continue; 25786 case "NOTE": 25787 // Ignore NOTE blocks. 25788 if (!line) { 25789 self.state = "ID"; 25790 } 25791 continue; 25792 case "ID": 25793 // Check for the start of NOTE blocks. 25794 if (/^NOTE($|[ \t])/.test(line)) { 25795 self.state = "NOTE"; 25796 break; 25797 } 25798 // 19-29 - Allow any number of line terminators, then initialize new cue values. 25799 if (!line) { 25800 continue; 25801 } 25802 self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, ""); 25803 self.state = "CUE"; 25804 // 30-39 - Check if self line contains an optional identifier or timing data. 25805 if (line.indexOf("-->") === -1) { 25806 self.cue.id = line; 25807 continue; 25808 } 25809 // Process line as start of a cue. 25810 /*falls through*/ 25811 case "CUE": 25812 // 40 - Collect cue timings and settings. 25813 try { 25814 parseCue(line, self.cue, self.regionList); 25815 } catch (e) { 25816 self.reportOrThrowError(e); 25817 // In case of an error ignore rest of the cue. 25818 self.cue = null; 25819 self.state = "BADCUE"; 25820 continue; 25821 } 25822 self.state = "CUETEXT"; 25823 continue; 25824 case "CUETEXT": 25825 var hasSubstring = line.indexOf("-->") !== -1; 25826 // 34 - If we have an empty line then report the cue. 25827 // 35 - If we have the special substring '-->' then report the cue, 25828 // but do not collect the line as we need to process the current 25829 // one as a new cue. 25830 if (!line || hasSubstring && (alreadyCollectedLine = true)) { 25831 // We are done parsing self cue. 25832 self.oncue && self.oncue(self.cue); 25833 self.cue = null; 25834 self.state = "ID"; 25835 continue; 25836 } 25837 if (self.cue.text) { 25838 self.cue.text += "\n"; 25839 } 25840 self.cue.text += line; 25841 continue; 25842 case "BADCUE": // BADCUE 25843 // 54-62 - Collect and discard the remaining cue. 25844 if (!line) { 25845 self.state = "ID"; 25846 } 25847 continue; 25848 } 25849 } 25850 } catch (e) { 25851 self.reportOrThrowError(e); 25852 25853 // If we are currently parsing a cue, report what we have. 25854 if (self.state === "CUETEXT" && self.cue && self.oncue) { 25855 self.oncue(self.cue); 25856 } 25857 self.cue = null; 25858 // Enter BADWEBVTT state if header was not parsed correctly otherwise 25859 // another exception occurred so enter BADCUE state. 25860 self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE"; 25861 } 25862 return this; 25863 }, 25864 flush: function () { 25865 var self = this; 25866 try {
25867 // Finish decoding the stream. 25868 self.buffer += self.decoder.decode(); 25869 // Synthesize the end of the current cue or region. 25870 if (self.cue || self.state === "HEADER") { 25871 self.buffer += "\n\n"; 25872 self.parse(); 25873 } 25874 // If we've flushed, parsed, and we're still on the INITIAL state then 25875 // that means we don't have enough of the stream to parse the first 25876 // line. 25877 if (self.state === "INITIAL") { 25878 throw new ParsingError(ParsingError.Errors.BadSignature); 25879 } 25880 } catch(e) { 25881 self.reportOrThrowError(e); 25882 } 25883 self.onflush && self.onflush(); 25884 return this; 25885 } 25886 }; 25887 25888 global.WebVTT = WebVTT; 25889 25890}(this, (this.vttjs || {}))); 25891 25892},{}],101:[function(_dereq_,module,exports){ 25893/** 25894 * Copyright 2013 vtt.js Contributors 25895 * 25896 * Licensed under the Apache License, Version 2.0 (the "License"); 25897 * you may not use this file except in compliance with the License. 25898 * You may obtain a copy of the License at 25899 * 25900 * http://www.apache.org/licenses/LICENSE-2.0 25901 * 25902 * Unless required by applicable law or agreed to in writing, software 25903 * distributed under the License is distributed on an "AS IS" BASIS, 25904 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25905 * See the License for the specific language governing permissions and 25906 * limitations under the License. 25907 */ 25908 25909// If we're in Node.js then require VTTCue so we can extend it, otherwise assume 25910// VTTCue is on the global. 25911if (typeof module !== "undefined" && module.exports) { 25912 this.VTTCue = this.VTTCue || _dereq_(102).VTTCue; 25913} 25914 25915// Extend VTTCue with methods to convert to JSON, from JSON, and construct a 25916// VTTCue from an options object. The primary purpose of this is for use in the 25917// vtt.js test suite (for testing only properties that we care about). It's also 25918// useful if you need to work with VTTCues in JSON format. 25919(function(root) { 25920 25921 root.VTTCue.prototype.toJSON = function() { 25922 var cue = {}, 25923 self = this; 25924 // Filter out getCueAsHTML as it's a function and hasBeenReset and displayState as 25925 // they're only used when running the processing model algorithm. 25926 Object.keys(this).forEach(function(key) { 25927 if (key !== "getCueAsHTML" && key !== "hasBeenReset" && key !== "displayState") { 25928 cue[key] = self[key]; 25929 } 25930 }); 25931 return cue; 25932 }; 25933 25934 root.VTTCue.create = function(options) { 25935 if (!options.hasOwnProperty("startTime") || !options.hasOwnProperty("endTime") || 25936 !options.hasOwnProperty("text")) { 25937 throw new Error("You must at least have start time, end time, and text."); 25938 } 25939 var cue = new root.VTTCue(options.startTime, options.endTime, options.text); 25940 for (var key in options) { 25941 if (cue.hasOwnProperty(key)) { 25942 cue[key] = options[key]; 25943 } 25944 } 25945 return cue; 25946 }; 25947 25948 root.VTTCue.fromJSON = function(json) { 25949 return this.create(JSON.parse(json)); 25950 }; 25951 25952}(this)); 25953 25954},{"102":102}],102:[function(_dereq_,module,exports){ 25955/** 25956 * Copyright 2013 vtt.js Contributors 25957 * 25958 * Licensed under the Apache License, Version 2.0 (the "License"); 25959 * you may not use this file except in compliance with the License. 25960 * You may obtain a copy of the License at 25961 * 25962 * http://www.apache.org/licenses/LICENSE-2.0 25963 * 25964 * Unless required by applicable law or agreed to in writing, software 25965 * distributed under the License is distributed on an "AS IS" BASIS, 25966 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25967 * See the License for the specific language governing permissions and 25968 * limitations under the License. 25969 */ 25970 25971(function(root, vttjs) { 25972 25973 var autoKeyword = "auto"; 25974 var directionSetting = { 25975 "": true, 25976 "lr": true, 25977 "rl": true 25978 }; 25979 var alignSetting = { 25980 "start": true, 25981 "middle": true, 25982 "end": true, 25983 "left": true, 25984 "right": true 25985 }; 25986 25987 function findDirectionSetting(value) { 25988 if (typeof value !== "string") { 25989 return false; 25990 } 25991 var dir = directionSetting[value.toLowerCase()]; 25992 return dir ? value.toLowerCase() : false; 25993 } 25994 25995 function findAlignSetting(value) { 25996 if (typeof value !== "string") { 25997 return false;
vendor: 4,425 bytes, lines 25998-26172
25998 } 25999 var align = alignSetting[value.toLowerCase()]; 26000 return align ? value.toLowerCase() : false; 26001 } 26002 26003 function extend(obj) { 26004 var i = 1; 26005 for (; i < arguments.length; i++) { 26006 var cobj = arguments[i]; 26007 for (var p in cobj) { 26008 obj[p] = cobj[p]; 26009 } 26010 } 26011 26012 return obj; 26013 } 26014 26015 function VTTCue(startTime, endTime, text) { 26016 var cue = this; 26017 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); 26018 var baseObj = {}; 26019 26020 if (isIE8) { 26021 cue = document.createElement('custom'); 26022 } else { 26023 baseObj.enumerable = true; 26024 } 26025 26026 /** 26027 * Shim implementation specific properties. These properties are not in 26028 * the spec. 26029 */ 26030 26031 // Lets us know when the VTTCue's data has changed in such a way that we need 26032 // to recompute its display state. This lets us compute its display state 26033 // lazily. 26034 cue.hasBeenReset = false; 26035 26036 /** 26037 * VTTCue and TextTrackCue properties 26038 * http://dev.w3.org/html5/webvtt/#vttcue-interface 26039 */ 26040 26041 var _id = ""; 26042 var _pauseOnExit = false; 26043 var _startTime = startTime; 26044 var _endTime = endTime; 26045 var _text = text; 26046 var _region = null; 26047 var _vertical = ""; 26048 var _snapToLines = true; 26049 var _line = "auto"; 26050 var _lineAlign = "start"; 26051 var _position = 50; 26052 var _positionAlign = "middle"; 26053 var _size = 50; 26054 var _align = "middle"; 26055 26056 Object.defineProperty(cue, 26057 "id", extend({}, baseObj, { 26058 get: function() { 26059 return _id; 26060 }, 26061 set: function(value) { 26062 _id = "" + value; 26063 } 26064 })); 26065 26066 Object.defineProperty(cue, 26067 "pauseOnExit", extend({}, baseObj, { 26068 get: function() { 26069 return _pauseOnExit; 26070 }, 26071 set: function(value) { 26072 _pauseOnExit = !!value; 26073 } 26074 })); 26075 26076 Object.defineProperty(cue, 26077 "startTime", extend({}, baseObj, { 26078 get: function() { 26079 return _startTime; 26080 }, 26081 set: function(value) { 26082 if (typeof value !== "number") { 26083 throw new TypeError("Start time must be set to a number."); 26084 } 26085 _startTime = value; 26086 this.hasBeenReset = true; 26087 } 26088 })); 26089 26090 Object.defineProperty(cue, 26091 "endTime", extend({}, baseObj, { 26092 get: function() { 26093 return _endTime; 26094 }, 26095 set: function(value) { 26096 if (typeof value !== "number") { 26097 throw new TypeError("End time must be set to a number."); 26098 } 26099 _endTime = value; 26100 this.hasBeenReset = true; 26101 } 26102 })); 26103 26104 Object.defineProperty(cue, 26105 "text", extend({}, baseObj, { 26106 get: function() { 26107 return _text; 26108 }, 26109 set: function(value) { 26110 _text = "" + value; 26111 this.hasBeenReset = true; 26112 } 26113 })); 26114 26115 Object.defineProperty(cue, 26116 "region", extend({}, baseObj, { 26117 get: function() { 26118 return _region; 26119 }, 26120 set: function(value) { 26121 _region = value; 26122 this.hasBeenReset = true; 26123 } 26124 })); 26125 26126 Object.defineProperty(cue, 26127 "vertical", extend({}, baseObj, { 26128 get: function() { 26129 return _vertical; 26130 }, 26131 set: function(value) { 26132 var setting = findDirectionSetting(value); 26133 // Have to check for false because the setting an be an empty string. 26134 if (setting === false) { 26135 throw new SyntaxError("An invalid or illegal string was specified."); 26136 } 26137 _vertical = setting; 26138 this.hasBeenReset = true; 26139 } 26140 })); 26141 26142 Object.defineProperty(cue, 26143 "snapToLines", extend({}, baseObj, { 26144 get: function() { 26145 return _snapToLines; 26146 }, 26147 set: function(value) { 26148 _snapToLines = !!value; 26149 this.hasBeenReset = true; 26150 } 26151 })); 26152 26153 Object.defineProperty(cue, 26154 "line", extend({}, baseObj, { 26155 get: function() { 26156 return _line; 26157 }, 26158 set: function(value) { 26159 if (typeof value !== "number" && value !== autoKeyword) { 26160 throw new SyntaxError("An invalid number or illegal string was specified."); 26161 } 26162 _line = value; 26163 this.hasBeenReset = true; 26164 } 26165 })); 26166 26167 Object.defineProperty(cue, 26168 "lineAlign", extend({}, baseObj, { 26169 get: function() { 26170 return _lineAlign; 26171 }, 26172 set: function(value) {
26173 var setting = findAlignSetting(value); 26174 if (!setting) { 26175 throw new SyntaxError("An invalid or illegal string was specified."); 26176 } 26177 _lineAlign = setting; 26178 this.hasBeenReset = true; 26179 } 26180 })); 26181 26182 Object.defineProperty(cue, 26183 "position", extend({}, baseObj, { 26184 get: function() { 26185 return _position; 26186 }, 26187 set: function(value) { 26188 if (value < 0 || value > 100) { 26189 throw new Error("Position must be between 0 and 100."); 26190 } 26191 _position = value; 26192 this.hasBeenReset = true; 26193 } 26194 })); 26195 26196 Object.defineProperty(cue, 26197 "positionAlign", extend({}, baseObj, { 26198 get: function() { 26199 return _positionAlign; 26200 }, 26201 set: function(value) { 26202 var setting = findAlignSetting(value); 26203 if (!setting) { 26204 throw new SyntaxError("An invalid or illegal string was specified."); 26205 } 26206 _positionAlign = setting; 26207 this.hasBeenReset = true; 26208 } 26209 })); 26210 26211 Object.defineProperty(cue, 26212 "size", extend({}, baseObj, { 26213 get: function() { 26214 return _size; 26215 }, 26216 set: function(value) { 26217 if (value < 0 || value > 100) { 26218 throw new Error("Size must be between 0 and 100."); 26219 } 26220 _size = value; 26221 this.hasBeenReset = true; 26222 } 26223 })); 26224 26225 Object.defineProperty(cue, 26226 "align", extend({}, baseObj, { 26227 get: function() { 26228 return _align; 26229 }, 26230 set: function(value) { 26231 var setting = findAlignSetting(value); 26232 if (!setting) { 26233 throw new SyntaxError("An invalid or illegal string was specified."); 26234 } 26235 _align = setting; 26236 this.hasBeenReset = true; 26237 } 26238 })); 26239 26240 /** 26241 * Other <track> spec defined properties 26242 */ 26243 26244 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state 26245 cue.displayState = undefined; 26246 26247 if (isIE8) { 26248 return cue; 26249 } 26250 } 26251 26252 /** 26253 * VTTCue methods 26254 */ 26255 26256 VTTCue.prototype.getCueAsHTML = function() { 26257 // Assume WebVTT.convertCueToDOMTree is on the global. 26258 return WebVTT.convertCueToDOMTree(window, this.text); 26259 }; 26260 26261 root.VTTCue = root.VTTCue || VTTCue; 26262 vttjs.VTTCue = VTTCue; 26263}(this, (this.vttjs || {}))); 26264 26265},{}],103:[function(_dereq_,module,exports){ 26266/** 26267 * Copyright 2013 vtt.js Contributors 26268 * 26269 * Licensed under the Apache License, Version 2.0 (the "License"); 26270 * you may not use this file except in compliance with the License. 26271 * You may obtain a copy of the License at 26272 * 26273 * http://www.apache.org/licenses/LICENSE-2.0 26274 * 26275 * Unless required by applicable law or agreed to in writing, software 26276 * distributed under the License is distributed on an "AS IS" BASIS, 26277 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26278 * See the License for the specific language governing permissions and 26279 * limitations under the License. 26280 */ 26281 26282// If we're in Node.js then require VTTRegion so we can extend it, otherwise assume 26283// VTTRegion is on the global. 26284if (typeof module !== "undefined" && module.exports) { 26285 this.VTTRegion = _dereq_(104).VTTRegion; 26286} 26287 26288// Extend VTTRegion with methods to convert to JSON, from JSON, and construct a 26289// VTTRegion from an options object. The primary purpose of this is for use in the 26290// vtt.js test suite. It's also useful if you need to work with VTTRegions in 26291// JSON format. 26292(function(root) { 26293 26294 root.VTTRegion.create = function(options) { 26295 var region = new root.VTTRegion(); 26296 for (var key in options) { 26297 if (region.hasOwnProperty(key)) { 26298 region[key] = options[key]; 26299 } 26300 } 26301 return region; 26302 }; 26303 26304 root.VTTRegion.fromJSON = function(json) { 26305 return this.create(JSON.parse(json)); 26306 }; 26307 26308}(this)); 26309 26310},{"104":104}],104:[function(_dereq_,module,exports){ 26311/** 26312 * Copyright 2013 vtt.js Contributors 26313 * 26314 * Licensed under the Apache License, Version 2.0 (the "License"); 26315 * you may not use this file except in compliance with the License. 26316 * You may obtain a copy of the License at 26317 * 26318 * http://www.apache.org/licenses/LICENSE-2.0 26319 * 26320 * Unless required by applicable law or agreed to in writing, softw
vendor: 11,653 bytes, lines 26320-26727
26320are 26321 * distributed under the License is distributed on an "AS IS" BASIS, 26322 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26323 * See the License for the specific language governing permissions and 26324 * limitations under the License. 26325 */ 26326 26327(function(root, vttjs) { 26328 26329 var scrollSetting = { 26330 "": true, 26331 "up": true 26332 }; 26333 26334 function findScrollSetting(value) { 26335 if (typeof value !== "string") { 26336 return false; 26337 } 26338 var scroll = scrollSetting[value.toLowerCase()]; 26339 return scroll ? value.toLowerCase() : false; 26340 } 26341 26342 function isValidPercentValue(value) { 26343 return typeof value === "number" && (value >= 0 && value <= 100); 26344 } 26345 26346 // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface 26347 function VTTRegion() { 26348 var _width = 100; 26349 var _lines = 3; 26350 var _regionAnchorX = 0; 26351 var _regionAnchorY = 100; 26352 var _viewportAnchorX = 0; 26353 var _viewportAnchorY = 100; 26354 var _scroll = ""; 26355 26356 Object.defineProperties(this, { 26357 "width": { 26358 enumerable: true, 26359 get: function() { 26360 return _width; 26361 }, 26362 set: function(value) { 26363 if (!isValidPercentValue(value)) { 26364 throw new Error("Width must be between 0 and 100."); 26365 } 26366 _width = value; 26367 } 26368 }, 26369 "lines": { 26370 enumerable: true, 26371 get: function() { 26372 return _lines; 26373 }, 26374 set: function(value) { 26375 if (typeof value !== "number") { 26376 throw new TypeError("Lines must be set to a number."); 26377 } 26378 _lines = value; 26379 } 26380 }, 26381 "regionAnchorY": { 26382 enumerable: true, 26383 get: function() { 26384 return _regionAnchorY; 26385 }, 26386 set: function(value) { 26387 if (!isValidPercentValue(value)) { 26388 throw new Error("RegionAnchorX must be between 0 and 100."); 26389 } 26390 _regionAnchorY = value; 26391 } 26392 }, 26393 "regionAnchorX": { 26394 enumerable: true, 26395 get: function() { 26396 return _regionAnchorX; 26397 }, 26398 set: function(value) { 26399 if(!isValidPercentValue(value)) { 26400 throw new Error("RegionAnchorY must be between 0 and 100."); 26401 } 26402 _regionAnchorX = value; 26403 } 26404 }, 26405 "viewportAnchorY": { 26406 enumerable: true, 26407 get: function() { 26408 return _viewportAnchorY; 26409 }, 26410 set: function(value) { 26411 if (!isValidPercentValue(value)) { 26412 throw new Error("ViewportAnchorY must be between 0 and 100."); 26413 } 26414 _viewportAnchorY = value; 26415 } 26416 }, 26417 "viewportAnchorX": { 26418 enumerable: true, 26419 get: function() { 26420 return _viewportAnchorX; 26421 }, 26422 set: function(value) { 26423 if (!isValidPercentValue(value)) { 26424 throw new Error("ViewportAnchorX must be between 0 and 100."); 26425 } 26426 _viewportAnchorX = value; 26427 } 26428 }, 26429 "scroll": { 26430 enumerable: true, 26431 get: function() { 26432 return _scroll; 26433 }, 26434 set: function(value) { 26435 var setting = findScrollSetting(value); 26436 // Have to check for false as an empty string is a legal value. 26437 if (setting === false) { 26438 throw new SyntaxError("An invalid or illegal string was specified."); 26439 } 26440 _scroll = setting; 26441 } 26442 } 26443 }); 26444 } 26445 26446 root.VTTRegion = root.VTTRegion || VTTRegion; 26447 vttjs.VTTRegion = VTTRegion; 26448}(this, (this.vttjs || {}))); 26449 26450},{}],105:[function(_dereq_,module,exports){ 26451"use strict"; 26452var window = _dereq_(95) 26453var isFunction = _dereq_(106) 26454var parseHeaders = _dereq_(109) 26455var xtend = _dereq_(110) 26456 26457module.exports = createXHR 26458createXHR.XMLHttpRequest = window.XMLHttpRequest || noop 26459createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest 26460 26461forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) { 26462 createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) { 26463 options = initParams(uri, options, callback) 26464 options.method = method.toUpperCase() 26465 return _createXHR(options) 26466 } 26467}) 26468 26469function forEachArray(array, iterator) { 26470 for (var i = 0; i < array.length; i++) { 26471 iterator(array[i]) 26472 } 26473} 26474 26475function isEmpty(obj){ 26476 for(var i in obj){ 26477 if(obj.hasOwnProperty(i)) return false 26478 } 26479 return true 26480} 26481 26482function initParams(uri, options, callback) { 26483 var params = uri 26484 26485 if (isFunction(options)) { 26486 callback = options 26487 if (typeof uri === "string") { 26488 params = {uri:uri} 26489 } 26490 } else { 26491 params = xtend(options, {uri: uri}) 26492 } 26493 26494 params.callback = callback 26495 return params 26496} 26497 26498function createXHR(uri, options, callback) { 26499 options = initParams(uri, options, callback) 26500 return _createXHR(options) 26501} 26502 26503function _createXHR(options) { 26504 if(typeof options.callback === "undefined"){ 26505 throw new Error("callback argument missing") 26506 } 26507 26508 var called = false 26509 var callback = function cbOnce(err, response, body){ 26510 if(!called){ 26511 called = true 26512 options.callback(err, response, body) 26513 } 26514 } 26515 26516 function readystatechange() { 26517 if (xhr.readyState === 4) { 26518 loadFunc() 26519 } 26520 } 26521 26522 function getBody() { 26523 // Chrome with requestType=blob throws errors arround when even testing access to responseText 26524 var body = undefined 26525 26526 if (xhr.response) { 26527 body = xhr.response 26528 } else { 26529 body = xhr.responseText || getXml(xhr) 26530 } 26531 26532 if (isJson) { 26533 try { 26534 body = JSON.parse(body) 26535 } catch (e) {} 26536 } 26537 26538 return body 26539 } 26540 26541 function errorFunc(evt) { 26542 clearTimeout(timeoutTimer) 26543 if(!(evt instanceof Error)){ 26544 evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") ) 26545 } 26546 evt.statusCode = 0 26547 return callback(evt, failureResponse) 26548 } 26549 26550 // will load the data & process the response in a special response object 26551 function loadFunc() { 26552 if (aborted) return 26553 var status 26554 clearTimeout(timeoutTimer) 26555 if(options.useXDR && xhr.status===undefined) { 26556 //IE8 CORS GET successful response doesn't have a status field, but body is fine 26557 status = 200 26558 } else { 26559 status = (xhr.status === 1223 ? 204 : xhr.status) 26560 } 26561 var response = failureResponse 26562 var err = null 26563 26564 if (status !== 0){ 26565 response = { 26566 body: getBody(), 26567 statusCode: status, 26568 method: method, 26569 headers: {}, 26570 url: uri, 26571 rawRequest: xhr 26572 } 26573 if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE 26574 response.headers = parseHeaders(xhr.getAllResponseHeaders()) 26575 } 26576 } else { 26577 err = new Error("Internal XMLHttpRequest Error") 26578 } 26579 return callback(err, response, response.body) 26580 } 26581 26582 var xhr = options.xhr || null 26583 26584 if (!xhr) { 26585 if (options.cors || options.useXDR) { 26586 xhr = new createXHR.XDomainRequest() 26587 }else{ 26588 xhr = new createXHR.XMLHttpRequest() 26589 } 26590 } 26591 26592 var key 26593 var aborted 26594 var uri = xhr.url = options.uri || options.url 26595 var method = xhr.method = options.method || "GET" 26596 var body = options.body || options.data 26597 var headers = xhr.headers = options.headers || {} 26598 var sync = !!options.sync 26599 var isJson = false 26600 var timeoutTimer 26601 var failureResponse = { 26602 body: undefined, 26603 headers: {}, 26604 statusCode: 0, 26605 method: method, 26606 url: uri, 26607 rawRequest: xhr 26608 } 26609 26610 if ("json" in options && options.json !== false) { 26611 isJson = true 26612 headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user 26613 if (method !== "GET" && method !== "HEAD") { 26614 headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user 26615 body = JSON.stringify(options.json === true ? body : options.json) 26616 } 26617 } 26618 26619 xhr.onreadystatechange = readystatechange 26620 xhr.onload = loadFunc 26621 xhr.onerror = errorFunc 26622 // IE9 must have onprogress be set to a unique function. 26623 xhr.onprogress = function () { 26624 // IE must die 26625 } 26626 xhr.onabort = function(){ 26627 aborted = true; 26628 } 26629 xhr.ontimeout = errorFunc 26630 xhr.open(method, uri, !sync, options.username, options.password) 26631 //has to be after open 26632 if(!sync) { 26633 xhr.withCredentials = !!options.withCredentials 26634 } 26635 // Cannot set timeout with sync request 26636 // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly 26637 // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent 26638 if (!sync && options.timeout > 0 ) { 26639 timeoutTimer = setTimeout(function(){ 26640 if (aborted) return 26641 aborted = true//IE9 may still call readystatechange 26642 xhr.abort("timeout") 26643 var e = new Error("XMLHttpRequest timeout") 26644 e.code = "ETIMEDOUT" 26645 errorFunc(e) 26646 }, options.timeout ) 26647 } 26648 26649 if (xhr.setRequestHeader) { 26650 for(key in headers){ 26651 if(headers.hasOwnProperty(key)){ 26652 xhr.setRequestHeader(key, headers[key]) 26653 } 26654 } 26655 } else if (options.headers && !isEmpty(options.headers)) { 26656 throw new Error("Headers cannot be set on an XDomainRequest object") 26657 } 26658 26659 if ("responseType" in options) { 26660 xhr.responseType = options.responseType 26661 } 26662 26663 if ("beforeSend" in options && 26664 typeof options.beforeSend === "function" 26665 ) { 26666 options.beforeSend(xhr) 26667 } 26668 26669 // Microsoft Edge browser sends "undefined" when send is called with undefined value. 26670 // XMLHttpRequest spec says to pass null as body to indicate no body 26671 // See https://github.com/naugtur/xhr/issues/100. 26672 xhr.send(body || null) 26673 26674 return xhr 26675 26676 26677} 26678 26679function getXml(xhr) { 26680 if (xhr.responseType === "document") { 26681 return xhr.responseXML 26682 } 26683 var firefoxBugTakenEffect = xhr.status === 204 && xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror" 26684 if (xhr.responseType === "" && !firefoxBugTakenEffect) { 26685 return xhr.responseXML 26686 } 26687 26688 return null 26689} 26690 26691function noop() {} 26692 26693},{"106":106,"109":109,"110":110,"95":95}],106:[function(_dereq_,module,exports){ 26694module.exports = isFunction 26695 26696var toString = Object.prototype.toString 26697 26698function isFunction (fn) { 26699 var string = toString.call(fn) 26700 return string === '[object Function]' || 26701 (typeof fn === 'function' && string !== '[object RegExp]') || 26702 (typeof window !== 'undefined' && 26703 // IE8 and below 26704 (fn === window.setTimeout || 26705 fn === window.alert || 26706 fn === window.confirm || 26707 fn === window.prompt)) 26708}; 26709 26710},{}],107:[function(_dereq_,module,exports){ 26711var isFunction = _dereq_(106) 26712 26713module.exports = forEach 26714 26715var toString = Object.prototype.toString 26716var hasOwnProperty = Object.prototype.hasOwnProperty 26717 26718function forEach(list, iterator, context) { 26719 if (!isFunction(iterator)) { 26720 throw new TypeError('iterator must be a function') 26721 } 26722 26723 if (arguments.length < 3) { 26724 context = this 26725 } 26726 26727 if (toString.call(list) === '[object Array]')
26728 forEachArray(list, iterator, context) 26729 else if (typeof list === 'string') 26730 forEachString(list, iterator, context) 26731 else 26732 forEachObject(list, iterator, context) 26733} 26734 26735function forEachArray(array, iterator, context) { 26736 for (var i = 0, len = array.length; i < len; i++) { 26737 if (hasOwnProperty.call(array, i)) { 26738 iterator.call(context, array[i], i, array) 26739 } 26740 } 26741} 26742 26743function forEachString(string, iterator, context) { 26744 for (var i = 0, len = string.length; i < len; i++) { 26745 // no such thing as a sparse string. 26746 iterator.call(context, string.charAt(i), i, string) 26747 } 26748} 26749 26750function forEachObject(object, iterator, context) { 26751 for (var k in object) { 26752 if (hasOwnProperty.call(object, k)) { 26753 iterator.call(context, object[k], k, object) 26754 } 26755 } 26756} 26757 26758},{"106":106}],108:[function(_dereq_,module,exports){ 26759 26760exports = module.exports = trim; 26761 26762function trim(str){ 26763 return str.replace(/^\s*|\s*$/g, ''); 26764} 26765 26766exports.left = function(str){ 26767 return str.replace(/^\s*/, ''); 26768}; 26769 26770exports.right = function(str){ 26771 return str.replace(/\s*$/, ''); 26772}; 26773 26774},{}],109:[function(_dereq_,module,exports){ 26775var trim = _dereq_(108) 26776 , forEach = _dereq_(107) 26777 , isArray = function(arg) { 26778 return Object.prototype.toString.call(arg) === '[object Array]'; 26779 } 26780 26781module.exports = function (headers) { 26782 if (!headers) 26783 return {} 26784 26785 var result = {} 26786 26787 forEach( 26788 trim(headers).split('\n') 26789 , function (row) { 26790 var index = row.indexOf(':') 26791 , key = trim(row.slice(0, index)).toLowerCase() 26792 , value = trim(row.slice(index + 1)) 26793 26794 if (typeof(result[key]) === 'undefined') { 26795 result[key] = value 26796 } else if (isArray(result[key])) { 26797 result[key].push(value) 26798 } else { 26799 result[key] = [ result[key], value ] 26800 } 26801 } 26802 ) 26803 26804 return result 26805} 26806},{"107":107,"108":108}],110:[function(_dereq_,module,exports){ 26807module.exports = extend 26808 26809var hasOwnProperty = Object.prototype.hasOwnProperty; 26810 26811function extend() { 26812 var target = {} 26813 26814 for (var i = 0; i < arguments.length; i++) { 26815 var source = arguments[i] 26816 26817 for (var key in source) { 26818 if (hasOwnProperty.call(source, key)) { 26819 target[key] = source[key] 26820 } 26821 } 26822 } 26823 26824 return target 26825} 26826 26827},{}]},{},[93])(93) 26828}); 26829!function(){!function(a){var b=a&&a.videojs;if(b){b.CDN_VERSION="5.17.0";var c="https:"===a.location.protocol?"https://":"http://";b.options.flash.swf=c+"vjs.zencdn.net/swf/5.2.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.availWidth+"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.