1/** 2 * @license 3 * Video.js 5.10.5 <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(function (global){ 15var topLevel = typeof global !== 'undefined' ? global : 16 typeof window !== 'undefined' ? window : {} 17var minDoc = _dereq_('min-document'); 18 19if (typeof document !== 'undefined') { 20 module.exports = document; 21} else { 22 var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4']; 23 24 if (!doccy) { 25 doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc; 26 } 27 28 module.exports = doccy; 29} 30 31}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 32//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9nbG9iYWwvZG9jdW1lbnQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgdG9wTGV2ZWwgPSB0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbCA6XG4gICAgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB7fVxudmFyIG1pbkRvYyA9IHJlcXVpcmUoJ21pbi1kb2N1bWVudCcpO1xuXG5pZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZG9jdW1lbnQ7XG59IGVsc2Uge1xuICAgIHZhciBkb2NjeSA9IHRvcExldmVsWydfX0dMT0JBTF9ET0NVTUVOVF9DQUNIRUA0J107XG5cbiAgICBpZiAoIWRvY2N5KSB7XG4gICAgICAgIGRvY2N5ID0gdG9wTGV2ZWxbJ19fR0xPQkFMX0RPQ1VNRU5UX0NBQ0hFQDQnXSA9IG1pbkRvYztcbiAgICB9XG5cbiAgICBtb2R1bGUuZXhwb3J0cyA9IGRvY2N5O1xufVxuIl19 33},{"min-document":3}],2:[function(_dereq_,module,exports){ 34(function (global){ 35if (typeof window !== "undefined") { 36 module.exports = window; 37} else if (typeof global !== "undefined") { 38 module.exports = global; 39} else if (typeof self !== "undefined"){ 40 module.exports = self; 41} else { 42 module.exports = {}; 43} 44 45}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 46//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9nbG9iYWwvd2luZG93LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHdpbmRvdztcbn0gZWxzZSBpZiAodHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZ2xvYmFsO1xufSBlbHNlIGlmICh0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIil7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBzZWxmO1xufSBlbHNlIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHt9O1xufVxuIl19 47},{}],3:[function(_dereq_,module,exports){ 48 49},{}],4:[function(_dereq_,module,exports){ 50var getNative = _dereq_('../internal/getNative'); 51 52/* Native method references for those with the same name as other `lodash` methods. */ 53var nativeNow = getNative(Date, 'now'); 54 55/** 56 * Gets the number of milliseconds that have elapsed since the Unix epoch 57 * (1 January 1970 00:00:00 UTC). 58 * 59 * @static 60 * @memberOf _ 61 * @category Date 62 * @example 63 * 64 * _.defer(function(stamp) { 65 * console.log(_.now() - stamp); 66 * }, _.now()); 67 * // => logs the number of milliseconds it took for the deferred function to be invoked 68 */ 69var now = nativeNow || function() { 70 return new Date().getTime(); 71}; 72 73module.exports = now; 74 75},{"../internal/getNative":20}],5:[function(_dereq_,module,exports){ 76var isObject = _dereq_('../lang/isObject'), 77 now = _dereq_('../date/now'); 78 79/** Used as the `TypeError` message for "Functions" methods. */
vendor: 16,886 bytes, lines 80-600
80var FUNC_ERROR_TEXT = 'Expected a function'; 81 82/* Native method references for those with the same name as other `lodash` methods. */ 83var nativeMax = Math.max; 84 85/** 86 * Creates a debounced function that delays invoking `func` until after `wait` 87 * milliseconds have elapsed since the last time the debounced function was 88 * invoked. The debounced function comes with a `cancel` method to cancel 89 * delayed invocations. Provide an options object to indicate that `func` 90 * should be invoked on the leading and/or trailing edge of the `wait` timeout. 91 * Subsequent calls to the debounced function return the result of the last 92 * `func` invocation. 93 * 94 * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked 95 * on the trailing edge of the timeout only if the the debounced function is 96 * invoked more than once during the `wait` timeout. 97 * 98 * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) 99 * for details over the differences between `_.debounce` and `_.throttle`. 100 * 101 * @static 102 * @memberOf _ 103 * @category Function 104 * @param {Function} func The function to debounce. 105 * @param {number} [wait=0] The number of milliseconds to delay. 106 * @param {Object} [options] The options object. 107 * @param {boolean} [options.leading=false] Specify invoking on the leading 108 * edge of the timeout. 109 * @param {number} [options.maxWait] The maximum time `func` is allowed to be 110 * delayed before it's invoked. 111 * @param {boolean} [options.trailing=true] Specify invoking on the trailing 112 * edge of the timeout. 113 * @returns {Function} Returns the new debounced function. 114 * @example 115 * 116 * // avoid costly calculations while the window size is in flux 117 * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); 118 * 119 * // invoke `sendMail` when the click event is fired, debouncing subsequent calls 120 * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { 121 * 'leading': true, 122 * 'trailing': false 123 * })); 124 * 125 * // ensure `batchLog` is invoked once after 1 second of debounced calls 126 * var source = new EventSource('/stream'); 127 * jQuery(source).on('message', _.debounce(batchLog, 250, { 128 * 'maxWait': 1000 129 * })); 130 * 131 * // cancel a debounced call 132 * var todoChanges = _.debounce(batchLog, 1000); 133 * Object.observe(models.todo, todoChanges); 134 * 135 * Object.observe(models, function(changes) { 136 * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { 137 * todoChanges.cancel(); 138 * } 139 * }, ['delete']); 140 * 141 * // ...at some point `models.todo` is changed 142 * models.todo.completed = true; 143 * 144 * // ...before 1 second has passed `models.todo` is deleted 145 * // which cancels the debounced `todoChanges` call 146 * delete models.todo; 147 */ 148function debounce(func, wait, options) { 149 var args, 150 maxTimeoutId, 151 result, 152 stamp, 153 thisArg, 154 timeoutId, 155 trailingCall, 156 lastCalled = 0, 157 maxWait = false, 158 trailing = true; 159 160 if (typeof func != 'function') { 161 throw new TypeError(FUNC_ERROR_TEXT); 162 } 163 wait = wait < 0 ? 0 : (+wait || 0); 164 if (options === true) { 165 var leading = true; 166 trailing = false; 167 } else if (isObject(options)) { 168 leading = !!options.leading; 169 maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); 170 trailing = 'trailing' in options ? !!options.trailing : trailing; 171 } 172 173 function cancel() { 174 if (timeoutId) { 175 clearTimeout(timeoutId); 176 } 177 if (maxTimeoutId) { 178 clearTimeout(maxTimeoutId); 179 } 180 lastCalled = 0; 181 maxTimeoutId = timeoutId = trailingCall = undefined; 182 } 183 184 function complete(isCalled, id) { 185 if (id) { 186 clearTimeout(id); 187 } 188 maxTimeoutId = timeoutId = trailingCall = undefined; 189 if (isCalled) { 190 lastCalled = now(); 191 result = func.apply(thisArg, args); 192 if (!timeoutId && !maxTimeoutId) { 193 args = thisArg = undefined; 194 } 195 } 196 } 197 198 function delayed() { 199 var remaining = wait - (now() - stamp); 200 if (remaining <= 0 || remaining > wait) { 201 complete(trailingCall, maxTimeoutId); 202 } else { 203 timeoutId = setTimeout(delayed, remaining); 204 } 205 } 206 207 function maxDelayed() { 208 complete(trailing, timeoutId); 209 } 210 211 function debounced() { 212 args = arguments; 213 stamp = now(); 214 thisArg = this; 215 trailingCall = trailing && (timeoutId || !leading); 216 217 if (maxWait === false) { 218 var leadingCall = leading && !timeoutId; 219 } else { 220 if (!maxTimeoutId && !leading) { 221 lastCalled = stamp; 222 } 223 var remaining = maxWait - (stamp - lastCalled), 224 isCalled = remaining <= 0 || remaining > maxWait; 225 226 if (isCalled) { 227 if (maxTimeoutId) { 228 maxTimeoutId = clearTimeout(maxTimeoutId); 229 } 230 lastCalled = stamp; 231 result = func.apply(thisArg, args); 232 } 233 else if (!maxTimeoutId) { 234 maxTimeoutId = setTimeout(maxDelayed, remaining); 235 } 236 } 237 if (isCalled && timeoutId) { 238 timeoutId = clearTimeout(timeoutId); 239 } 240 else if (!timeoutId && wait !== maxWait) { 241 timeoutId = setTimeout(delayed, wait); 242 } 243 if (leadingCall) { 244 isCalled = true; 245 result = func.apply(thisArg, args); 246 } 247 if (isCalled && !timeoutId && !maxTimeoutId) { 248 args = thisArg = undefined; 249 } 250 return result; 251 } 252 debounced.cancel = cancel; 253 return debounced; 254} 255 256module.exports = debounce; 257 258},{"../date/now":4,"../lang/isObject":33}],6:[function(_dereq_,module,exports){ 259/** Used as the `TypeError` message for "Functions" methods. */ 260var FUNC_ERROR_TEXT = 'Expected a function'; 261 262/* Native method references for those with the same name as other `lodash` methods. */ 263var nativeMax = Math.max; 264 265/** 266 * Creates a function that invokes `func` with the `this` binding of the 267 * created function and arguments from `start` and beyond provided as an array. 268 * 269 * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters). 270 * 271 * @static 272 * @memberOf _ 273 * @category Function 274 * @param {Function} func The function to apply a rest parameter to. 275 * @param {number} [start=func.length-1] The start position of the rest parameter. 276 * @returns {Function} Returns the new function. 277 * @example 278 * 279 * var say = _.restParam(function(what, names) { 280 * return what + ' ' + _.initial(names).join(', ') + 281 * (_.size(names) > 1 ? ', & ' : '') + _.last(names); 282 * }); 283 * 284 * say('hello', 'fred', 'barney', 'pebbles'); 285 * // => 'hello fred, barney, & pebbles' 286 */ 287function restParam(func, start) { 288 if (typeof func != 'function') { 289 throw new TypeError(FUNC_ERROR_TEXT); 290 } 291 start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); 292 return function() { 293 var args = arguments, 294 index = -1, 295 length = nativeMax(args.length - start, 0), 296 rest = Array(length); 297 298 while (++index < length) { 299 rest[index] = args[start + index]; 300 } 301 switch (start) { 302 case 0: return func.call(this, rest); 303 case 1: return func.call(this, args[0], rest); 304 case 2: return func.call(this, args[0], args[1], rest); 305 } 306 var otherArgs = Array(start + 1); 307 index = -1; 308 while (++index < start) { 309 otherArgs[index] = args[index]; 310 } 311 otherArgs[start] = rest; 312 return func.apply(this, otherArgs); 313 }; 314} 315 316module.exports = restParam; 317 318},{}],7:[function(_dereq_,module,exports){ 319var debounce = _dereq_('./debounce'), 320 isObject = _dereq_('../lang/isObject'); 321 322/** Used as the `TypeError` message for "Functions" methods. */ 323var FUNC_ERROR_TEXT = 'Expected a function'; 324 325/** 326 * Creates a throttled function that only invokes `func` at most once per 327 * every `wait` milliseconds. The throttled function comes with a `cancel` 328 * method to cancel delayed invocations. Provide an options object to indicate 329 * that `func` should be invoked on the leading and/or trailing edge of the 330 * `wait` timeout. Subsequent calls to the throttled function return the 331 * result of the last `func` call. 332 * 333 * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked 334 * on the trailing edge of the timeout only if the the throttled function is 335 * invoked more than once during the `wait` timeout. 336 * 337 * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) 338 * for details over the differences between `_.throttle` and `_.debounce`. 339 * 340 * @static 341 * @memberOf _ 342 * @category Function 343 * @param {Function} func The function to throttle. 344 * @param {number} [wait=0] The number of milliseconds to throttle invocations to. 345 * @param {Object} [options] The options object. 346 * @param {boolean} [options.leading=true] Specify invoking on the leading 347 * edge of the timeout. 348 * @param {boolean} [options.trailing=true] Specify invoking on the trailing 349 * edge of the timeout. 350 * @returns {Function} Returns the new throttled function. 351 * @example 352 * 353 * // avoid excessively updating the position while scrolling 354 * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); 355 * 356 * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes 357 * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { 358 * 'trailing': false 359 * })); 360 * 361 * // cancel a trailing throttled call 362 * jQuery(window).on('popstate', throttled.cancel); 363 */ 364function throttle(func, wait, options) { 365 var leading = true, 366 trailing = true; 367 368 if (typeof func != 'function') { 369 throw new TypeError(FUNC_ERROR_TEXT); 370 } 371 if (options === false) { 372 leading = false; 373 } else if (isObject(options)) { 374 leading = 'leading' in options ? !!options.leading : leading; 375 trailing = 'trailing' in options ? !!options.trailing : trailing; 376 } 377 return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); 378} 379 380module.exports = throttle; 381 382},{"../lang/isObject":33,"./debounce":5}],8:[function(_dereq_,module,exports){ 383/** 384 * Copies the values of `source` to `array`. 385 * 386 * @private 387 * @param {Array} source The array to copy values from. 388 * @param {Array} [array=[]] The array to copy values to. 389 * @returns {Array} Returns `array`. 390 */ 391function arrayCopy(source, array) { 392 var index = -1, 393 length = source.length; 394 395 array || (array = Array(length)); 396 while (++index < length) { 397 array[index] = source[index]; 398 } 399 return array; 400} 401 402module.exports = arrayCopy; 403 404},{}],9:[function(_dereq_,module,exports){ 405/** 406 * A specialized version of `_.forEach` for arrays without support for callback 407 * shorthands and `this` binding. 408 * 409 * @private 410 * @param {Array} array The array to iterate over. 411 * @param {Function} iteratee The function invoked per iteration. 412 * @returns {Array} Returns `array`. 413 */ 414function arrayEach(array, iteratee) { 415 var index = -1, 416 length = array.length; 417 418 while (++index < length) { 419 if (iteratee(array[index], index, array) === false) { 420 break; 421 } 422 } 423 return array; 424} 425 426module.exports = arrayEach; 427 428},{}],10:[function(_dereq_,module,exports){ 429/** 430 * Copies properties of `source` to `object`. 431 * 432 * @private 433 * @param {Object} source The object to copy properties from. 434 * @param {Array} props The property names to copy. 435 * @param {Object} [object={}] The object to copy properties to. 436 * @returns {Object} Returns `object`. 437 */ 438function baseCopy(source, props, object) { 439 object || (object = {}); 440 441 var index = -1, 442 length = props.length; 443 444 while (++index < length) { 445 var key = props[index]; 446 object[key] = source[key]; 447 } 448 return object; 449} 450 451module.exports = baseCopy; 452 453},{}],11:[function(_dereq_,module,exports){ 454var createBaseFor = _dereq_('./createBaseFor'); 455 456/** 457 * The base implementation of `baseForIn` and `baseForOwn` which iterates 458 * over `object` properties returned by `keysFunc` invoking `iteratee` for 459 * each property. Iteratee functions may exit iteration early by explicitly 460 * returning `false`. 461 * 462 * @private 463 * @param {Object} object The object to iterate over. 464 * @param {Function} iteratee The function invoked per iteration. 465 * @param {Function} keysFunc The function to get the keys of `object`. 466 * @returns {Object} Returns `object`. 467 */ 468var baseFor = createBaseFor(); 469 470module.exports = baseFor; 471 472},{"./createBaseFor":18}],12:[function(_dereq_,module,exports){ 473var baseFor = _dereq_('./baseFor'), 474 keysIn = _dereq_('../object/keysIn'); 475 476/** 477 * The base implementation of `_.forIn` without support for callback 478 * shorthands and `this` binding. 479 * 480 * @private 481 * @param {Object} object The object to iterate over. 482 * @param {Function} iteratee The function invoked per iteration. 483 * @returns {Object} Returns `object`. 484 */ 485function baseForIn(object, iteratee) { 486 return baseFor(object, iteratee, keysIn); 487} 488 489module.exports = baseForIn; 490 491},{"../object/keysIn":39,"./baseFor":11}],13:[function(_dereq_,module,exports){ 492var arrayEach = _dereq_('./arrayEach'), 493 baseMergeDeep = _dereq_('./baseMergeDeep'), 494 isArray = _dereq_('../lang/isArray'), 495 isArrayLike = _dereq_('./isArrayLike'), 496 isObject = _dereq_('../lang/isObject'), 497 isObjectLike = _dereq_('./isObjectLike'), 498 isTypedArray = _dereq_('../lang/isTypedArray'), 499 keys = _dereq_('../object/keys'); 500 501/** 502 * The base implementation of `_.merge` without support for argument juggling, 503 * multiple sources, and `this` binding `customizer` functions. 504 * 505 * @private 506 * @param {Object} object The destination object. 507 * @param {Object} source The source object. 508 * @param {Function} [customizer] The function to customize merged values. 509 * @param {Array} [stackA=[]] Tracks traversed source objects. 510 * @param {Array} [stackB=[]] Associates values with source counterparts. 511 * @returns {Object} Returns `object`. 512 */ 513function baseMerge(object, source, customizer, stackA, stackB) { 514 if (!isObject(object)) { 515 return object; 516 } 517 var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), 518 props = isSrcArr ? undefined : keys(source); 519 520 arrayEach(props || source, function(srcValue, key) { 521 if (props) { 522 key = srcValue; 523 srcValue = source[key]; 524 } 525 if (isObjectLike(srcValue)) { 526 stackA || (stackA = []); 527 stackB || (stackB = []); 528 baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); 529 } 530 else { 531 var value = object[key], 532 result = customizer ? customizer(value, srcValue, key, object, source) : undefined, 533 isCommon = result === undefined; 534 535 if (isCommon) { 536 result = srcValue; 537 } 538 if ((result !== undefined || (isSrcArr && !(key in object))) && 539 (isCommon || (result === result ? (result !== value) : (value === value)))) { 540 object[key] = result; 541 } 542 } 543 }); 544 return object; 545} 546 547module.exports = baseMerge; 548 549},{"../lang/isArray":30,"../lang/isObject":33,"../lang/isTypedArray":36,"../object/keys":38,"./arrayEach":9,"./baseMergeDeep":14,"./isArrayLike":21,"./isObjectLike":26}],14:[function(_dereq_,module,exports){ 550var arrayCopy = _dereq_('./arrayCopy'), 551 isArguments = _dereq_('../lang/isArguments'), 552 isArray = _dereq_('../lang/isArray'), 553 isArrayLike = _dereq_('./isArrayLike'), 554 isPlainObject = _dereq_('../lang/isPlainObject'), 555 isTypedArray = _dereq_('../lang/isTypedArray'), 556 toPlainObject = _dereq_('../lang/toPlainObject'); 557 558/** 559 * A specialized version of `baseMerge` for arrays and objects which performs 560 * deep merges and tracks traversed objects enabling objects with circular 561 * references to be merged. 562 * 563 * @private 564 * @param {Object} object The destination object. 565 * @param {Object} source The source object. 566 * @param {string} key The key of the value to merge. 567 * @param {Function} mergeFunc The function to merge values. 568 * @param {Function} [customizer] The function to customize merged values. 569 * @param {Array} [stackA=[]] Tracks traversed source objects. 570 * @param {Array} [stackB=[]] Associates values with source counterparts. 571 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. 572 */ 573function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { 574 var length = stackA.length, 575 srcValue = source[key]; 576 577 while (length--) { 578 if (stackA[length] == srcValue) { 579 object[key] = stackB[length]; 580 return; 581 } 582 } 583 var value = object[key], 584 result = customizer ? customizer(value, srcValue, key, object, source) : undefined, 585 isCommon = result === undefined; 586 587 if (isCommon) { 588 result = srcValue; 589 if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) { 590 result = isArray(value) 591 ? value 592 : (isArrayLike(value) ? arrayCopy(value) : []); 593 } 594 else if (isPlainObject(srcValue) || isArguments(srcValue)) { 595 result = isArguments(value) 596 ? toPlainObject(value) 597 : (isPlainObject(value) ? value : {}); 598 } 599 else { 600 isCommon = false;
vendor: 8,163 bytes, lines 601-866
601 } 602 } 603 // Add the source value to the stack of traversed objects and associate 604 // it with its merged value. 605 stackA.push(srcValue); 606 stackB.push(result); 607 608 if (isCommon) { 609 // Recursively merge objects and arrays (susceptible to call stack limits). 610 object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); 611 } else if (result === result ? (result !== value) : (value === value)) { 612 object[key] = result; 613 } 614} 615 616module.exports = baseMergeDeep; 617 618},{"../lang/isArguments":29,"../lang/isArray":30,"../lang/isPlainObject":34,"../lang/isTypedArray":36,"../lang/toPlainObject":37,"./arrayCopy":8,"./isArrayLike":21}],15:[function(_dereq_,module,exports){ 619var toObject = _dereq_('./toObject'); 620 621/** 622 * The base implementation of `_.property` without support for deep paths. 623 * 624 * @private 625 * @param {string} key The key of the property to get. 626 * @returns {Function} Returns the new function. 627 */ 628function baseProperty(key) { 629 return function(object) { 630 return object == null ? undefined : toObject(object)[key]; 631 }; 632} 633 634module.exports = baseProperty; 635 636},{"./toObject":28}],16:[function(_dereq_,module,exports){ 637var identity = _dereq_('../utility/identity'); 638 639/** 640 * A specialized version of `baseCallback` which only supports `this` binding 641 * and specifying the number of arguments to provide to `func`. 642 * 643 * @private 644 * @param {Function} func The function to bind. 645 * @param {*} thisArg The `this` binding of `func`. 646 * @param {number} [argCount] The number of arguments to provide to `func`. 647 * @returns {Function} Returns the callback. 648 */ 649function bindCallback(func, thisArg, argCount) { 650 if (typeof func != 'function') { 651 return identity; 652 } 653 if (thisArg === undefined) { 654 return func; 655 } 656 switch (argCount) { 657 case 1: return function(value) { 658 return func.call(thisArg, value); 659 }; 660 case 3: return function(value, index, collection) { 661 return func.call(thisArg, value, index, collection); 662 }; 663 case 4: return function(accumulator, value, index, collection) { 664 return func.call(thisArg, accumulator, value, index, collection); 665 }; 666 case 5: return function(value, other, key, object, source) { 667 return func.call(thisArg, value, other, key, object, source); 668 }; 669 } 670 return function() { 671 return func.apply(thisArg, arguments); 672 }; 673} 674 675module.exports = bindCallback; 676 677},{"../utility/identity":42}],17:[function(_dereq_,module,exports){ 678var bindCallback = _dereq_('./bindCallback'), 679 isIterateeCall = _dereq_('./isIterateeCall'), 680 restParam = _dereq_('../function/restParam'); 681 682/** 683 * Creates a `_.assign`, `_.defaults`, or `_.merge` function. 684 * 685 * @private 686 * @param {Function} assigner The function to assign values. 687 * @returns {Function} Returns the new assigner function. 688 */ 689function createAssigner(assigner) { 690 return restParam(function(object, sources) { 691 var index = -1, 692 length = object == null ? 0 : sources.length, 693 customizer = length > 2 ? sources[length - 2] : undefined, 694 guard = length > 2 ? sources[2] : undefined, 695 thisArg = length > 1 ? sources[length - 1] : undefined; 696 697 if (typeof customizer == 'function') { 698 customizer = bindCallback(customizer, thisArg, 5); 699 length -= 2; 700 } else { 701 customizer = typeof thisArg == 'function' ? thisArg : undefined; 702 length -= (customizer ? 1 : 0); 703 } 704 if (guard && isIterateeCall(sources[0], sources[1], guard)) { 705 customizer = length < 3 ? undefined : customizer; 706 length = 1; 707 } 708 while (++index < length) { 709 var source = sources[index]; 710 if (source) { 711 assigner(object, source, customizer); 712 } 713 } 714 return object; 715 }); 716} 717 718module.exports = createAssigner; 719 720},{"../function/restParam":6,"./bindCallback":16,"./isIterateeCall":24}],18:[function(_dereq_,module,exports){ 721var toObject = _dereq_('./toObject'); 722 723/** 724 * Creates a base function for `_.forIn` or `_.forInRight`. 725 * 726 * @private 727 * @param {boolean} [fromRight] Specify iterating from right to left. 728 * @returns {Function} Returns the new base function. 729 */ 730function createBaseFor(fromRight) { 731 return function(object, iteratee, keysFunc) { 732 var iterable = toObject(object), 733 props = keysFunc(object), 734 length = props.length, 735 index = fromRight ? length : -1; 736 737 while ((fromRight ? index-- : ++index < length)) { 738 var key = props[index]; 739 if (iteratee(iterable[key], key, iterable) === false) { 740 break; 741 } 742 } 743 return object; 744 }; 745} 746 747module.exports = createBaseFor; 748 749},{"./toObject":28}],19:[function(_dereq_,module,exports){ 750var baseProperty = _dereq_('./baseProperty'); 751 752/** 753 * Gets the "length" property value of `object`. 754 * 755 * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) 756 * that affects Safari on at least iOS 8.1-8.3 ARM64. 757 * 758 * @private 759 * @param {Object} object The object to query. 760 * @returns {*} Returns the "length" value. 761 */ 762var getLength = baseProperty('length'); 763 764module.exports = getLength; 765 766},{"./baseProperty":15}],20:[function(_dereq_,module,exports){ 767var isNative = _dereq_('../lang/isNative'); 768 769/** 770 * Gets the native function at `key` of `object`. 771 * 772 * @private 773 * @param {Object} object The object to query. 774 * @param {string} key The key of the method to get. 775 * @returns {*} Returns the function if it's native, else `undefined`. 776 */ 777function getNative(object, key) { 778 var value = object == null ? undefined : object[key]; 779 return isNative(value) ? value : undefined; 780} 781 782module.exports = getNative; 783 784},{"../lang/isNative":32}],21:[function(_dereq_,module,exports){ 785var getLength = _dereq_('./getLength'), 786 isLength = _dereq_('./isLength'); 787 788/** 789 * Checks if `value` is array-like. 790 * 791 * @private 792 * @param {*} value The value to check. 793 * @returns {boolean} Returns `true` if `value` is array-like, else `false`. 794 */ 795function isArrayLike(value) { 796 return value != null && isLength(getLength(value)); 797} 798 799module.exports = isArrayLike; 800 801},{"./getLength":19,"./isLength":25}],22:[function(_dereq_,module,exports){ 802/** 803 * Checks if `value` is a host object in IE < 9. 804 * 805 * @private 806 * @param {*} value The value to check. 807 * @returns {boolean} Returns `true` if `value` is a host object, else `false`. 808 */ 809var isHostObject = (function() { 810 try { 811 Object({ 'toString': 0 } + ''); 812 } catch(e) { 813 return function() { return false; }; 814 } 815 return function(value) { 816 // IE < 9 presents many host objects as `Object` objects that can coerce 817 // to strings despite having improperly defined `toString` methods. 818 return typeof value.toString != 'function' && typeof (value + '') == 'string'; 819 }; 820}()); 821 822module.exports = isHostObject; 823 824},{}],23:[function(_dereq_,module,exports){ 825/** Used to detect unsigned integer values. */ 826var reIsUint = /^\d+$/; 827 828/** 829 * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) 830 * of an array-like value. 831 */ 832var MAX_SAFE_INTEGER = 9007199254740991; 833 834/** 835 * Checks if `value` is a valid array-like index. 836 * 837 * @private 838 * @param {*} value The value to check. 839 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. 840 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. 841 */ 842function isIndex(value, length) { 843 value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; 844 length = length == null ? MAX_SAFE_INTEGER : length; 845 return value > -1 && value % 1 == 0 && value < length; 846} 847 848module.exports = isIndex; 849 850},{}],24:[function(_dereq_,module,exports){ 851var isArrayLike = _dereq_('./isArrayLike'), 852 isIndex = _dereq_('./isIndex'), 853 isObject = _dereq_('../lang/isObject'); 854 855/** 856 * Checks if the provided arguments are from an iteratee call. 857 * 858 * @private 859 * @param {*} value The potential iteratee value argument. 860 * @param {*} index The potential iteratee index or key argument. 861 * @param {*} object The potential iteratee object argument. 862 * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. 863 */ 864function isIterateeCall(value, index, object) { 865 if (!isObject(object)) { 866 return false;
867 } 868 var type = typeof index; 869 if (type == 'number' 870 ? (isArrayLike(object) && isIndex(index, object.length)) 871 : (type == 'string' && index in object)) { 872 var other = object[index]; 873 return value === value ? (value === other) : (other !== other); 874 } 875 return false; 876} 877 878module.exports = isIterateeCall; 879 880},{"../lang/isObject":33,"./isArrayLike":21,"./isIndex":23}],25:[function(_dereq_,module,exports){ 881/** 882 * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) 883 * of an array-like value. 884 */ 885var MAX_SAFE_INTEGER = 9007199254740991; 886 887/** 888 * Checks if `value` is a valid array-like length. 889 * 890 * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). 891 * 892 * @private 893 * @param {*} value The value to check. 894 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. 895 */ 896function isLength(value) { 897 return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; 898} 899 900module.exports = isLength; 901 902},{}],26:[function(_dereq_,module,exports){ 903/** 904 * Checks if `value` is object-like. 905 * 906 * @private 907 * @param {*} value The value to check. 908 * @returns {boolean} Returns `true` if `value` is object-like, else `false`. 909 */ 910function isObjectLike(value) { 911 return !!value && typeof value == 'object'; 912} 913 914module.exports = isObjectLike; 915 916},{}],27:[function(_dereq_,module,exports){ 917var isArguments = _dereq_('../lang/isArguments'), 918 isArray = _dereq_('../lang/isArray'), 919 isIndex = _dereq_('./isIndex'), 920 isLength = _dereq_('./isLength'), 921 isString = _dereq_('../lang/isString'), 922 keysIn = _dereq_('../object/keysIn'); 923 924/** Used for native method references. */ 925var objectProto = Object.prototype; 926 927/** Used to check objects for own properties. */ 928var hasOwnProperty = objectProto.hasOwnProperty; 929 930/** 931 * A fallback implementation of `Object.keys` which creates an array of the 932 * own enumerable property names of `object`. 933 * 934 * @private 935 * @param {Object} object The object to query. 936 * @returns {Array} Returns the array of property names. 937 */ 938function shimKeys(object) { 939 var props = keysIn(object), 940 propsLength = props.length, 941 length = propsLength && object.length; 942 943 var allowIndexes = !!length && isLength(length) && 944 (isArray(object) || isArguments(object) || isString(object)); 945 946 var index = -1, 947 result = []; 948 949 while (++index < propsLength) { 950 var key = props[index]; 951 if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { 952 result.push(key); 953 } 954 } 955 return result; 956} 957 958module.exports = shimKeys; 959 960},{"../lang/isArguments":29,"../lang/isArray":30,"../lang/isString":35,"../object/keysIn":39,"./isIndex":23,"./isLength":25}],28:[function(_dereq_,module,exports){ 961var isObject = _dereq_('../lang/isObject'), 962 isString = _dereq_('../lang/isString'), 963 support = _dereq_('../support'); 964 965/** 966 * Converts `value` to an object if it's not one. 967 * 968 * @private 969 * @param {*} value The value to process. 970 * @returns {Object} Returns the object. 971 */ 972function toObject(value) { 973 if (support.unindexedChars && isString(value)) { 974 var index = -1, 975 length = value.length, 976 result = Object(value); 977 978 while (++index < length) { 979 result[index] = value.charAt(index); 980 } 981 return result; 982 } 983 return isObject(value) ? value : Object(value); 984} 985 986module.exports = toObject; 987 988},{"../lang/isObject":33,"../lang/isString":35,"../support":41}],29:[function(_dereq_,module,exports){ 989var isArrayLike = _dereq_('../internal/isArrayLike'), 990 isObjectLike = _dereq_('../internal/isObjectLike'); 991 992/** Used for native method references. */ 993var objectProto = Object.prototype; 994 995/** Used to check objects for own properties. */ 996var hasOwnProperty = objectProto.hasOwnProperty; 997 998/** Native method references. */ 999var propertyIsEnumerable = objectProto.propertyIsEnumerable; 1000 1001/** 1002 * Checks if `value` is classified as an `arguments` object. 1003 * 1004 * @static 1005 * @memberOf _ 1006 * @category Lang 1007 * @param {*} value The value to check. 1008 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. 1009 * @example 1010 * 1011 * _.isArguments(function() { return arguments; }()); 1012 * // => true 1013 * 1014 * _.isArguments([1, 2, 3]); 1015 * // => false 1016 */ 1017function isArguments(value) { 1018 return isObjectLike(value) && isArrayLike(value) && 1019 hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); 1020} 1021 1022module.exports = isArguments; 1023 1024},{"../internal/isArrayLike":21,"../internal/isObjectLike":26}],30:[function(_dereq_,module,exports){ 1025var getNative = _dereq_('../internal/getNative'), 1026 isLength = _dereq_('../internal/isLength'), 1027 isObjectLike = _dereq_('../internal/isObjectLike'); 1028 1029/** `Object#toString` result references. */ 1030var arrayTag = '[object Array]'; 1031 1032/** Used for native method references. */ 1033var objectProto = Object.prototype; 1034 1035/** 1036 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) 1037 * of values. 1038 */ 1039var objToString = objectProto.toString; 1040 1041/* Native method references for those with the same name as other `lodash` methods. */ 1042var nativeIsArray = getNative(Array, 'isArray'); 1043 1044/** 1045 * Checks if `value` is classified as an `Array` object. 1046 * 1047 * @static 1048 * @memberOf _ 1049 * @category Lang 1050 * @param {*} value The value to check. 1051 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. 1052 * @example 1053 * 1054 * _.isArray([1, 2, 3]); 1055 * // => true 1056 * 1057 * _.isArray(function() { return arguments; }()); 1058 * // => false 1059 */ 1060var isArray = nativeIsArray || function(value) { 1061 return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; 1062}; 1063 1064module.exports = isArray; 1065 1066},{"../internal/getNative":20,"../internal/isLength":25,"../internal/isObjectLike":26}],31:[function(_dereq_,module,exports){ 1067var isObject = _dereq_('./isObject'); 1068 1069/** `Object#toString` result references. */ 1070var funcTag = '[object Function]'; 1071 1072/** Used for native method references. */ 1073var objectProto = Object.prototype; 1074 1075/** 1076 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) 1077 * of values. 1078 */ 1079var objToString = objectProto.toString; 1080 1081/** 1082 * Checks if `value` is classified as a `Function` object. 1083 * 1084 * @static 1085 * @memberOf _ 1086 * @category Lang 1087 * @param {*} value The value to check. 1088 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. 1089 * @example 1090 * 1091 * _.isFunction(_); 1092 * // => true 1093 * 1094 * _.isFunction(/abc/); 1095 * // => false 1096 */ 1097function isFunction(value) {
vendor: 8,376 bytes, lines 1098-1361
1098 // The use of `Object#toString` avoids issues with the `typeof` operator 1099 // in older versions of Chrome and Safari which return 'function' for regexes 1100 // and Safari 8 which returns 'object' for typed array constructors. 1101 return isObject(value) && objToString.call(value) == funcTag; 1102} 1103 1104module.exports = isFunction; 1105 1106},{"./isObject":33}],32:[function(_dereq_,module,exports){ 1107var isFunction = _dereq_('./isFunction'), 1108 isHostObject = _dereq_('../internal/isHostObject'), 1109 isObjectLike = _dereq_('../internal/isObjectLike'); 1110 1111/** Used to detect host constructors (Safari > 5). */ 1112var reIsHostCtor = /^\[object .+?Constructor\]$/; 1113 1114/** Used for native method references. */ 1115var objectProto = Object.prototype; 1116 1117/** Used to resolve the decompiled source of functions. */ 1118var fnToString = Function.prototype.toString; 1119 1120/** Used to check objects for own properties. */ 1121var hasOwnProperty = objectProto.hasOwnProperty; 1122 1123/** Used to detect if a method is native. */ 1124var reIsNative = RegExp('^' + 1125 fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') 1126 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' 1127); 1128 1129/** 1130 * Checks if `value` is a native function. 1131 * 1132 * @static 1133 * @memberOf _ 1134 * @category Lang 1135 * @param {*} value The value to check. 1136 * @returns {boolean} Returns `true` if `value` is a native function, else `false`. 1137 * @example 1138 * 1139 * _.isNative(Array.prototype.push); 1140 * // => true 1141 * 1142 * _.isNative(_); 1143 * // => false 1144 */ 1145function isNative(value) { 1146 if (value == null) { 1147 return false; 1148 } 1149 if (isFunction(value)) { 1150 return reIsNative.test(fnToString.call(value)); 1151 } 1152 return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value); 1153} 1154 1155module.exports = isNative; 1156 1157},{"../internal/isHostObject":22,"../internal/isObjectLike":26,"./isFunction":31}],33:[function(_dereq_,module,exports){ 1158/** 1159 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. 1160 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) 1161 * 1162 * @static 1163 * @memberOf _ 1164 * @category Lang 1165 * @param {*} value The value to check. 1166 * @returns {boolean} Returns `true` if `value` is an object, else `false`. 1167 * @example 1168 * 1169 * _.isObject({}); 1170 * // => true 1171 * 1172 * _.isObject([1, 2, 3]); 1173 * // => true 1174 * 1175 * _.isObject(1); 1176 * // => false 1177 */ 1178function isObject(value) { 1179 // Avoid a V8 JIT bug in Chrome 19-20. 1180 // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. 1181 var type = typeof value; 1182 return !!value && (type == 'object' || type == 'function'); 1183} 1184 1185module.exports = isObject; 1186 1187},{}],34:[function(_dereq_,module,exports){ 1188var baseForIn = _dereq_('../internal/baseForIn'), 1189 isArguments = _dereq_('./isArguments'), 1190 isHostObject = _dereq_('../internal/isHostObject'), 1191 isObjectLike = _dereq_('../internal/isObjectLike'), 1192 support = _dereq_('../support'); 1193 1194/** `Object#toString` result references. */ 1195var objectTag = '[object Object]'; 1196 1197/** Used for native method references. */ 1198var objectProto = Object.prototype; 1199 1200/** Used to check objects for own properties. */ 1201var hasOwnProperty = objectProto.hasOwnProperty; 1202 1203/** 1204 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) 1205 * of values. 1206 */ 1207var objToString = objectProto.toString; 1208 1209/** 1210 * Checks if `value` is a plain object, that is, an object created by the 1211 * `Object` constructor or one with a `[[Prototype]]` of `null`. 1212 * 1213 * **Note:** This method assumes objects created by the `Object` constructor 1214 * have no inherited enumerable properties. 1215 * 1216 * @static 1217 * @memberOf _ 1218 * @category Lang 1219 * @param {*} value The value to check. 1220 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. 1221 * @example 1222 * 1223 * function Foo() { 1224 * this.a = 1; 1225 * } 1226 * 1227 * _.isPlainObject(new Foo); 1228 * // => false 1229 * 1230 * _.isPlainObject([1, 2, 3]); 1231 * // => false 1232 * 1233 * _.isPlainObject({ 'x': 0, 'y': 0 }); 1234 * // => true 1235 * 1236 * _.isPlainObject(Object.create(null)); 1237 * // => true 1238 */ 1239function isPlainObject(value) { 1240 var Ctor; 1241 1242 // Exit early for non `Object` objects. 1243 if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) || 1244 (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { 1245 return false; 1246 } 1247 // IE < 9 iterates inherited properties before own properties. If the first 1248 // iterated property is an object's own property then there are no inherited 1249 // enumerable properties. 1250 var result; 1251 if (support.ownLast) { 1252 baseForIn(value, function(subValue, key, object) { 1253 result = hasOwnProperty.call(object, key); 1254 return false; 1255 }); 1256 return result !== false; 1257 } 1258 // In most environments an object's own properties are iterated before 1259 // its inherited properties. If the last iterated property is an object's 1260 // own property then there are no inherited enumerable properties. 1261 baseForIn(value, function(subValue, key) { 1262 result = key; 1263 }); 1264 return result === undefined || hasOwnProperty.call(value, result); 1265} 1266 1267module.exports = isPlainObject; 1268 1269},{"../internal/baseForIn":12,"../internal/isHostObject":22,"../internal/isObjectLike":26,"../support":41,"./isArguments":29}],35:[function(_dereq_,module,exports){ 1270var isObjectLike = _dereq_('../internal/isObjectLike'); 1271 1272/** `Object#toString` result references. */ 1273var stringTag = '[object String]'; 1274 1275/** Used for native method references. */ 1276var objectProto = Object.prototype; 1277 1278/** 1279 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) 1280 * of values. 1281 */ 1282var objToString = objectProto.toString; 1283 1284/** 1285 * Checks if `value` is classified as a `String` primitive or object. 1286 * 1287 * @static 1288 * @memberOf _ 1289 * @category Lang 1290 * @param {*} value The value to check. 1291 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. 1292 * @example 1293 * 1294 * _.isString('abc'); 1295 * // => true 1296 * 1297 * _.isString(1); 1298 * // => false 1299 */ 1300function isString(value) { 1301 return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); 1302} 1303 1304module.exports = isString; 1305 1306},{"../internal/isObjectLike":26}],36:[function(_dereq_,module,exports){ 1307var isLength = _dereq_('../internal/isLength'), 1308 isObjectLike = _dereq_('../internal/isObjectLike'); 1309 1310/** `Object#toString` result references. */ 1311var argsTag = '[object Arguments]', 1312 arrayTag = '[object Array]', 1313 boolTag = '[object Boolean]', 1314 dateTag = '[object Date]', 1315 errorTag = '[object Error]', 1316 funcTag = '[object Function]', 1317 mapTag = '[object Map]', 1318 numberTag = '[object Number]', 1319 objectTag = '[object Object]', 1320 regexpTag = '[object RegExp]', 1321 setTag = '[object Set]', 1322 stringTag = '[object String]', 1323 weakMapTag = '[object WeakMap]'; 1324 1325var arrayBufferTag = '[object ArrayBuffer]', 1326 float32Tag = '[object Float32Array]', 1327 float64Tag = '[object Float64Array]', 1328 int8Tag = '[object Int8Array]', 1329 int16Tag = '[object Int16Array]', 1330 int32Tag = '[object Int32Array]', 1331 uint8Tag = '[object Uint8Array]', 1332 uint8ClampedTag = '[object Uint8ClampedArray]', 1333 uint16Tag = '[object Uint16Array]', 1334 uint32Tag = '[object Uint32Array]'; 1335 1336/** Used to identify `toStringTag` values of typed arrays. */ 1337var typedArrayTags = {}; 1338typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = 1339typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = 1340typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = 1341typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = 1342typedArrayTags[uint32Tag] = true; 1343typedArrayTags[argsTag] = typedArrayTags[arrayTag] = 1344typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = 1345typedArrayTags[dateTag] = typedArrayTags[errorTag] = 1346typedArrayTags[funcTag] = typedArrayTags[mapTag] = 1347typedArrayTags[numberTag] = typedArrayTags[objectTag] = 1348typedArrayTags[regexpTag] = typedArrayTags[setTag] = 1349typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; 1350 1351/** Used for native method references. */ 1352var objectProto = Object.prototype; 1353 1354/** 1355 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) 1356 * of values. 1357 */ 1358var objToString = objectProto.toString; 1359 1360/** 1361 * Checks if `value` is classified as a typed array.
1362 * 1363 * @static 1364 * @memberOf _ 1365 * @category Lang 1366 * @param {*} value The value to check. 1367 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. 1368 * @example 1369 * 1370 * _.isTypedArray(new Uint8Array); 1371 * // => true 1372 * 1373 * _.isTypedArray([]); 1374 * // => false 1375 */ 1376function isTypedArray(value) { 1377 return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; 1378} 1379 1380module.exports = isTypedArray; 1381 1382},{"../internal/isLength":25,"../internal/isObjectLike":26}],37:[function(_dereq_,module,exports){ 1383var baseCopy = _dereq_('../internal/baseCopy'), 1384 keysIn = _dereq_('../object/keysIn'); 1385 1386/** 1387 * Converts `value` to a plain object flattening inherited enumerable 1388 * properties of `value` to own properties of the plain object. 1389 * 1390 * @static 1391 * @memberOf _ 1392 * @category Lang 1393 * @param {*} value The value to convert. 1394 * @returns {Object} Returns the converted plain object. 1395 * @example 1396 * 1397 * function Foo() { 1398 * this.b = 2; 1399 * } 1400 * 1401 * Foo.prototype.c = 3; 1402 * 1403 * _.assign({ 'a': 1 }, new Foo); 1404 * // => { 'a': 1, 'b': 2 } 1405 * 1406 * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); 1407 * // => { 'a': 1, 'b': 2, 'c': 3 } 1408 */ 1409function toPlainObject(value) { 1410 return baseCopy(value, keysIn(value)); 1411} 1412 1413module.exports = toPlainObject; 1414 1415},{"../internal/baseCopy":10,"../object/keysIn":39}],38:[function(_dereq_,module,exports){ 1416var getNative = _dereq_('../internal/getNative'), 1417 isArrayLike = _dereq_('../internal/isArrayLike'), 1418 isObject = _dereq_('../lang/isObject'), 1419 shimKeys = _dereq_('../internal/shimKeys'), 1420 support = _dereq_('../support'); 1421 1422/* Native method references for those with the same name as other `lodash` methods. */ 1423var nativeKeys = getNative(Object, 'keys'); 1424 1425/** 1426 * Creates an array of the own enumerable property names of `object`. 1427 * 1428 * **Note:** Non-object values are coerced to objects. See the 1429 * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) 1430 * for more details. 1431 * 1432 * @static 1433 * @memberOf _ 1434 * @category Object 1435 * @param {Object} object The object to query. 1436 * @returns {Array} Returns the array of property names. 1437 * @example 1438 * 1439 * function Foo() { 1440 * this.a = 1; 1441 * this.b = 2; 1442 * } 1443 * 1444 * Foo.prototype.c = 3; 1445 * 1446 * _.keys(new Foo); 1447 * // => ['a', 'b'] (iteration order is not guaranteed) 1448 * 1449 * _.keys('hi'); 1450 * // => ['0', '1'] 1451 */ 1452var keys = !nativeKeys ? shimKeys : function(object) { 1453 var Ctor = object == null ? undefined : object.constructor; 1454 if ((typeof Ctor == 'function' && Ctor.prototype === object) || 1455 (typeof object == 'function' ? support.enumPrototypes : isArrayLike(object))) { 1456 return shimKeys(object); 1457 } 1458 return isObject(object) ? nativeKeys(object) : []; 1459}; 1460 1461module.exports = keys; 1462 1463},{"../internal/getNative":20,"../internal/isArrayLike":21,"../internal/shimKeys":27,"../lang/isObject":33,"../support":41}],39:[function(_dereq_,module,exports){ 1464var arrayEach = _dereq_('../internal/arrayEach'), 1465 isArguments = _dereq_('../lang/isArguments'), 1466 isArray = _dereq_('../lang/isArray'), 1467 isFunction = _dereq_('../lang/isFunction'), 1468 isIndex = _dereq_('../internal/isIndex'), 1469 isLength = _dereq_('../internal/isLength'), 1470 isObject = _dereq_('../lang/isObject'), 1471 isString = _dereq_('../lang/isString'), 1472 support = _dereq_('../support'); 1473 1474/** `Object#toString` result references. */ 1475var arrayTag = '[object Array]', 1476 boolTag = '[object Boolean]', 1477 dateTag = '[object Date]', 1478 errorTag = '[object Error]', 1479 funcTag = '[object Function]', 1480 numberTag = '[object Number]', 1481 objectTag = '[object Object]', 1482 regexpTag = '[object RegExp]', 1483 stringTag = '[object String]'; 1484 1485/** Used to fix the JScript `[[DontEnum]]` bug. */ 1486var shadowProps = [ 1487 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 1488 'toLocaleString', 'toString', 'valueOf' 1489]; 1490 1491/** Used for native method references. */ 1492var errorProto = Error.prototype, 1493 objectProto = Object.prototype, 1494 stringProto = String.prototype; 1495 1496/** Used to check objects for own properties. */ 1497var hasOwnProperty = objectProto.hasOwnProperty; 1498 1499/** 1500 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) 1501 * of values. 1502 */ 1503var objToString = objectProto.toString; 1504 1505/** Used to avoid iterating over non-enumerable properties in IE < 9. */ 1506var nonEnumProps = {}; 1507nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleStr
1507ing': true, 'toString': true, 'valueOf': true }; 1508nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true }; 1509nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true }; 1510nonEnumProps[objectTag] = { 'constructor': true }; 1511 1512arrayEach(shadowProps, function(key) { 1513 for (var tag in nonEnumProps) { 1514 if (hasOwnProperty.call(nonEnumProps, tag)) { 1515 var props = nonEnumProps[tag]; 1516 props[key] = hasOwnProperty.call(props, key); 1517 } 1518 } 1519}); 1520 1521/** 1522 * Creates an array of the own and inherited enumerable property names of `object`. 1523 * 1524 * **Note:** Non-object values are coerced to objects. 1525 * 1526 * @static 1527 * @memberOf _ 1528 * @category Object 1529 * @param {Object} object The object to query. 1530 * @returns {Array} Returns the array of property names. 1531 * @example 1532 * 1533 * function Foo() { 1534 * this.a = 1; 1535 * this.b = 2; 1536 * } 1537 * 1538 * Foo.prototype.c = 3; 1539 * 1540 * _.keysIn(new Foo); 1541 * // => ['a', 'b', 'c'] (iteration order is not guaranteed) 1542 */ 1543function keysIn(object) { 1544 if (object == null) { 1545 return []; 1546 } 1547 if (!isObject(object)) { 1548 object = Object(object); 1549 } 1550 var length = object.length; 1551 1552 length = (length && isLength(length) && 1553 (isArray(object) || isArguments(object) || isString(object)) && length) || 0; 1554 1555 var Ctor = object.constructor, 1556 index = -1, 1557 proto = (isFunction(Ctor) && Ctor.prototype) || objectProto, 1558 isProto = proto === object, 1559 result = Array(length), 1560 skipIndexes = length > 0, 1561 skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error), 1562 skipProto = support.enumPrototypes && isFunction(object); 1563 1564 while (++index < length) { 1565 result[index] = (index + ''); 1566 } 1567 // lodash skips the `constructor` property when it infers it's iterating 1568 // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]` 1569 // attribute of an existing property and the `constructor` property of a 1570 // prototype defaults to non-enumerable. 1571 for (var key in object) { 1572 if (!(skipProto && key == 'prototype') && 1573 !(skipErrorProps && (key == 'message' || key == 'name')) && 1574 !(skipIndexes && isIndex(key, length)) && 1575 !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { 1576 result.push(key); 1577 } 1578 } 1579 if (support.nonEnumShadows && object !== objectProto) { 1580 var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)), 1581 nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag]; 1582 1583 if (tag == objectTag) { 1584 proto = objectProto; 1585 } 1586 length = shadowProps.length; 1587 while (length--) { 1588 key = shadowProps[length]; 1589 var nonEnum = nonEnums[key]; 1590 if (!(isProto && nonEnum) && 1591 (nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) { 1592 result.push(key); 1593 } 1594 } 1595 } 1596 return result; 1597} 1598 1599module.exports = keysIn; 1600 1601},{"../internal/arrayEach":9,"../internal/isIndex":23,"../internal/isLength":25,"../lang/isArguments":29,"../lang/isArray":30,"../lang/isFunction":31,"../lang/isObject":33,"../lang/isString":35,"../support":41}],40:[function(_dereq_,module,exports){ 1602var baseMerge = _dereq_('../internal/baseMerge'), 1603 createAssigner = _dereq_('../internal/createAssigner'); 1604 1605/** 1606 * Recursively merges own enumerable properties of the source object(s), that 1607 * don't resolve to `undefined` into the destination object. Subsequent sources 1608 * overwrite property assignments of previous sources. If `customizer` is 1609 * provided it's invoked to produce the merged values of the destination and 1610 * source properties. If `customizer` returns `undefined` merging is handled 1611 * by the method instead. The `customizer` is bound to `thisArg` and invoked 1612 * with five arguments: (objectValue, sourceValue, key, object, source). 1613 * 1614 * @static 1615 * @memberOf _ 1616 * @category Object 1617 * @param {Object} object The destination object. 1618 * @param {...Object} [sources] The source objects. 1619 * @param {Function} [customizer] The function to customize assigned values. 1620 * @param {*} [thisArg] The `this` binding of `customizer`. 1621 * @returns {Object} Returns `object`. 1622 * @example 1623 * 1624 * var users = { 1625 * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] 1626 * }; 1627 * 1628 * var ages = { 1629 * 'data': [{ 'age': 36 }, { 'age': 40 }] 1630 * }; 1631 * 1632 * _.merge(users, ages); 1633 * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } 1634 * 1635 * // using a customizer callback 1636 * var object = { 1637 * 'fruits': ['apple'], 1638 * 'vegetables': ['beet'] 1639 * }; 1640 * 1641 * var other = { 1642 * 'fruits': ['banana'], 1643 * 'vegetables': ['carrot'] 1644 * }; 1645 * 1646 * _.merge(object, other, function(a, b) { 1647 * if (_.isArray(a)) { 1648 * return a.concat(b); 1649 * } 1650 * }); 1651 * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } 1652 */ 1653var merge = createAssigner(baseMerge); 1654 1655module.exports = merge; 1656 1657},{"../internal/baseMerge":13,"../internal/createAssigner":17}],41:[function(_dereq_,module,exports){ 1658/** Used for native method references. */ 1659var arrayProto = Array.prototype, 1660 errorProto = Error.prototype, 1661 objectProto = Object.prototype; 1662
1663/** Native method references. */ 1664var propertyIsEnumerable = objectProto.propertyIsEnumerable, 1665 splice = arrayProto.splice; 1666 1667/** 1668 * An object environment feature flags. 1669 * 1670 * @static 1671 * @memberOf _ 1672 * @type Object 1673 */ 1674var support = {}; 1675 1676(function(x) { 1677 var Ctor = function() { this.x = x; }, 1678 object = { '0': x, 'length': x }, 1679 props = []; 1680 1681 Ctor.prototype = { 'valueOf': x, 'y': x }; 1682 for (var key in new Ctor) { props.push(key); } 1683 1684 /** 1685 * Detect if `name` or `message` properties of `Error.prototype` are 1686 * enumerable by default (IE < 9, Safari < 5.1). 1687 * 1688 * @memberOf _.support 1689 * @type boolean 1690 */ 1691 support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || 1692 propertyIsEnumerable.call(errorProto, 'name'); 1693 1694 /** 1695 * Detect if `prototype` properties are enumerable by default. 1696 * 1697 * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 1698 * (if the prototype or a property on the prototype has been set) 1699 * incorrectly set the `[[Enumerable]]` value of a function's `prototype` 1700 * property to `true`. 1701 * 1702 * @memberOf _.support 1703 * @type boolean 1704 */ 1705 support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype'); 1706 1707 /** 1708 * Detect if properties shadowing those on `Object.prototype` are non-enumerable. 1709 * 1710 * In IE < 9 an object's own properties, shadowing non-enumerable ones, 1711 * are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug). 1712 * 1713 * @memberOf _.support 1714 * @type boolean 1715 */ 1716 support.nonEnumShadows = !/valueOf/.test(props); 1717 1718 /** 1719 * Detect if own properties are iterated after inherited properties (IE < 9). 1720 * 1721 * @memberOf _.support 1722 * @type boolean 1723 */ 1724 support.ownLast = props[0] != 'x'; 1725 1726 /** 1727 * Detect if `Array#shift` and `Array#splice` augment array-like objects 1728 * correctly. 1729 * 1730 * Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array 1731 * `shift()` and `splice()` functions that fail to remove the last element, 1732 * `value[0]`, of array-like objects even though the "length" property is 1733 * set to `0`. The `shift()` method is buggy in compatibility modes of IE 8, 1734 * while `splice()` is buggy regardless of mode in IE < 9. 1735 * 1736 * @memberOf _.support 1737 * @type boolean 1738 */ 1739 support.spliceObjects = (splice.call(object, 0, 1), !object[0]); 1740 1741 /** 1742 * Detect lack of support for accessing string characters by index. 1743 * 1744 * IE < 8 can't access characters by index. IE 8 can only access characters 1745 * by index on string literals, not string objects. 1746 * 1747 * @memberOf _.support 1748 * @type boolean 1749 */ 1750 support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; 1751}(1, 0)); 1752 1753module.exports = support; 1754 1755},{}],42:[function(_dereq_,module,exports){ 1756/** 1757 * This method returns the first argument provided to it. 1758 * 1759 * @static 1760 * @memberOf _ 1761 * @category Utility 1762 * @param {*} value Any value. 1763 * @returns {*} Returns `value`. 1764 * @example 1765 * 1766 * var object = { 'user': 'fred' }; 1767 * 1768 * _.identity(object) === object; 1769 * // => true 1770 */ 1771function identity(value) { 1772 return value; 1773} 1774 1775module.exports = identity; 1776 1777},{}],43:[function(_dereq_,module,exports){ 1778'use strict'; 1779 1780var keys = _dereq_('object-keys'); 1781 1782module.exports = function hasSymbols() { 1783 if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; } 1784 if (typeof Symbol.iterator === 'symbol') { return true; } 1785 1786 var obj = {}; 1787 var sym = Symbol('test'); 1788 if (typeof sym === 'string') { return false; } 1789 1790 // temp disabled per https://github.com/ljharb/object.assign/issues/17 1791 // if (sym instanceof Symbol) { return false; } 1792 // temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4 1793 // if (!(Object(sym) instanceof Symbol)) { return false; } 1794 1795 var symVal = 42; 1796 obj[sym] = symVal; 1797 for (sym in obj) { return false; } 1798 if (keys(obj).length !== 0) { return false; } 1799 if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; } 1800 1801 if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; } 1802 1803 var syms = Object.getOwnPropertySymbols(obj); 1804 if (syms.length !== 1 || syms[0] !== sym) { return false; } 1805 1806 if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; } 1807 1808 if (typeof Object.getOwnPropertyDescriptor === 'function') { 1809 var descriptor = Object.getOwnPropertyDescriptor(obj, sym); 1810 if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; } 1811 } 1812 1813 return true; 1814}; 1815 1816},{"object-keys":50}],44:[function(_dereq_,module,exports){ 1817'use strict'; 1818 1819// modified from https://github.com/es-shims/es6-shim 1820var keys = _dereq_('object-keys'); 1821var bind = _dereq_('function-bind'); 1822var canBeObject = function (obj) { 1823 return typeof obj !== 'undefined' && obj !== null; 1824}; 1825var hasSymbols = _dereq_('./hasSymbols')(); 1826var toObject = Object; 1827var push = bind.call(Function.call, Array.prototype.push); 1828var propIsEnumerable = bind.call(Function.call, Object.prototype.propertyIsEnumerable); 1829 1830module.exports = function assign(target, source1) { 1831 if (!canBeObject(target)) { throw new TypeError('target must be an object'); } 1832 var objTarget = toObject(target); 1833 var s, source, i, props, syms, value, key; 1834 for (s = 1; s < arguments.length; ++s) { 1835 source = toObject(arguments[s]); 1836 props = keys(source); 1837 if (hasSymbols && Object.getOwnPropertySymbols) { 1838 syms = Object.getOwnPropertySymbols(source); 1839 for (i = 0; i < syms.length; ++i) { 1840 key = syms[i]; 1841 if (propIsEnumerable(source, key)) { 1842 push(props, key); 1843 } 1844 } 1845 } 1846 for (i = 0; i < props.length; ++i) { 1847 key = props[i]; 1848 value = source[key]; 1849 if (propIsEnumerable(source, key)) { 1850 objTarget[key] = value; 1851 } 1852 } 1853 } 1854 return objTarget; 1855}; 1856 1857},{"./hasSymbols":43,"function-bind":49,"object-keys":50}],45:[function(_dereq_,module,exports){ 1858'use strict'; 1859 1860var defineProperties = _dereq_('define-properties'); 1861 1862var implementation = _dereq_('./implementation'); 1863var getPolyfill = _dereq_('./polyfill'); 1864var shim = _dereq_('./shim'); 1865 1866defineProperties(implementation, { 1867 implementation: implementation, 1868 getPolyfill: getPolyfill, 1869 shim: shim 1870}); 1871 1872module.exports = implementation; 1873 1874},{"./implementation":44,"./polyfill":52,"./shim":53,"define-properties":46}],46:[function(_dereq_,module,exports){ 1875'use strict'; 1876 1877var keys = _dereq_('object-keys'); 1878var foreach = _dereq_('foreach'); 1879var hasSymbols = typeof Symbol === 'function' && typeof Symbol() === 'symbol'; 1880 1881var toStr = Object.prototype.toString; 1882 1883var isFunction = function (fn) { 1884 return typeof fn === 'function' && toStr.call(fn) === '[object Function]'; 1885}; 1886 1887var arePropertyDescriptorsSupported = function () { 1888 var obj = {}; 1889 try { 1890 Object.defineProperty(obj, 'x', { enumerable: false, value: obj }); 1891 /* eslint-disable no-unused-vars, no-restricted-syntax */ 1892 for (var _ in obj) { return false; } 1893 /* eslint-enable no-unused-vars, no-restricted-syntax */ 1894 return obj.x === obj; 1895 } catch (e) { /* this is IE 8. */ 1896 return false;
1897 } 1898}; 1899var supportsDescriptors = Object.defineProperty && arePropertyDescriptorsSupported(); 1900 1901var defineProperty = function (object, name, value, predicate) { 1902 if (name in object && (!isFunction(predicate) || !predicate())) { 1903 return; 1904 } 1905 if (supportsDescriptors) { 1906 Object.defineProperty(object, name, { 1907 configurable: true, 1908 enumerable: false, 1909 value: value, 1910 writable: true 1911 }); 1912 } else { 1913 object[name] = value; 1914 } 1915}; 1916 1917var defineProperties = function (object, map) { 1918 var predicates = arguments.length > 2 ? arguments[2] : {}; 1919 var props = keys(map); 1920 if (hasSymbols) { 1921 props = props.concat(Object.getOwnPropertySymbols(map)); 1922 } 1923 foreach(props, function (name) { 1924 defineProperty(object, name, map[name], predicates[name]); 1925 }); 1926}; 1927 1928defineProperties.supportsDescriptors = !!supportsDescriptors; 1929 1930module.exports = defineProperties; 1931 1932},{"foreach":47,"object-keys":50}],47:[function(_dereq_,module,exports){ 1933 1934var hasOwn = Object.prototype.hasOwnProperty; 1935var toString = Object.prototype.toString; 1936 1937module.exports = function forEach (obj, fn, ctx) { 1938 if (toString.call(fn) !== '[object Function]') { 1939 throw new TypeError('iterator must be a function'); 1940 } 1941 var l = obj.length; 1942 if (l === +l) { 1943 for (var i = 0; i < l; i++) { 1944 fn.call(ctx, obj[i], i, obj); 1945 } 1946 } else { 1947 for (var k in obj) { 1948 if (hasOwn.call(obj, k)) { 1949 fn.call(ctx, obj[k], k, obj); 1950 } 1951 } 1952 } 1953}; 1954 1955 1956},{}],48:[function(_dereq_,module,exports){ 1957var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible '; 1958var slice = Array.prototype.slice; 1959var toStr = Object.prototype.toString; 1960var funcType = '[object Function]'; 1961 1962module.exports = function bind(that) { 1963 var target = this; 1964 if (typeof target !== 'function' || toStr.call(target) !== funcType) { 1965 throw new TypeError(ERROR_MESSAGE + target); 1966 } 1967 var args = slice.call(arguments, 1); 1968 1969 var bound; 1970 var binder = function () { 1971 if (this instanceof bound) { 1972 var result = target.apply( 1973 this, 1974 args.concat(slice.call(arguments)) 1975 ); 1976 if (Object(result) === result) { 1977 return result; 1978 } 1979 return this; 1980 } else { 1981 return target.apply( 1982 that, 1983 args.concat(slice.call(arguments)) 1984 ); 1985 } 1986 }; 1987 1988 var boundLength = Math.max(0, target.length - args.length); 1989 var boundArgs = []; 1990 for (var i = 0; i < boundLength; i++) { 1991 boundArgs.push('$' + i); 1992 } 1993 1994 bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder); 1995 1996 if (target.prototype) { 1997 var Empty = function Empty() {}; 1998 Empty.prototype = target.prototype; 1999 bound.prototype = new Empty(); 2000 Empty.prototype = null; 2001 } 2002 2003 return bound; 2004}; 2005 2006},{}],49:[function(_dereq_,module,exports){ 2007var implementation = _dereq_('./implementation'); 2008 2009module.exports = Function.prototype.bind || implementation; 2010 2011},{"./implementation":48}],50:[function(_dereq_,module,exports){ 2012'use strict'; 2013 2014// modified from https://github.com/es-shims/es5-shim 2015var has = Object.prototype.hasOwnProperty; 2016var toStr = Object.prototype.toString; 2017var slice = Array.prototype.slice; 2018var isArgs = _dereq_('./isArguments'); 2019var hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'); 2020var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype'); 2021var dontEnums = [ 2022 'toString', 2023 'toLocaleString', 2024 'valueOf', 2025 'hasOwnProperty', 2026 'isPrototypeOf', 2027 'propertyIsEnumerable', 2028 'constructor' 2029]; 2030var equalsConstructorPrototype = function (o) { 2031 var ctor = o.constructor; 2032 return ctor && ctor.prototype === o; 2033}; 2034var blacklistedKeys = { 2035 $console: true, 2036 $frame: true, 2037 $frameElement: true, 2038 $frames: true, 2039 $parent: true, 2040 $self: true, 2041 $webkitIndexedDB: true, 2042 $webkitStorageInfo: true, 2043 $window: true 2044}; 2045var hasAutomationEqualityBug = (function () { 2046 /* global window */ 2047 if (typeof window === 'undefined') { return false; } 2048 for (var k in window) { 2049 try { 2050 if (!blacklistedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') { 2051 try { 2052 equalsConstructorPrototype(window[k]); 2053 } catch (e) { 2054 return true; 2055 } 2056 } 2057 } catch (e) { 2058 return true; 2059 } 2060 } 2061 return false;
2062}()); 2063var equalsConstructorPrototypeIfNotBuggy = function (o) { 2064 /* global window */ 2065 if (typeof window === 'undefined' || !hasAutomationEqualityBug) { 2066 return equalsConstructorPrototype(o); 2067 } 2068 try { 2069 return equalsConstructorPrototype(o); 2070 } catch (e) { 2071 return false; 2072 } 2073}; 2074 2075var keysShim = function keys(object) { 2076 var isObject = object !== null && typeof object === 'object'; 2077 var isFunction = toStr.call(object) === '[object Function]'; 2078 var isArguments = isArgs(object); 2079 var isString = isObject && toStr.call(object) === '[object String]'; 2080 var theKeys = []; 2081 2082 if (!isObject && !isFunction && !isArguments) { 2083 throw new TypeError('Object.keys called on a non-object'); 2084 } 2085 2086 var skipProto = hasProtoEnumBug && isFunction; 2087 if (isString && object.length > 0 && !has.call(object, 0)) { 2088 for (var i = 0; i < object.length; ++i) { 2089 theKeys.push(String(i)); 2090 } 2091 } 2092 2093 if (isArguments && object.length > 0) { 2094 for (var j = 0; j < object.length; ++j) { 2095 theKeys.push(String(j)); 2096 } 2097 } else { 2098 for (var name in object) { 2099 if (!(skipProto && name === 'prototype') && has.call(object, name)) { 2100 theKeys.push(String(name)); 2101 } 2102 } 2103 } 2104 2105 if (hasDontEnumBug) { 2106 var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object); 2107 2108 for (var k = 0; k < dontEnums.length; ++k) { 2109 if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) { 2110 theKeys.push(dontEnums[k]); 2111 } 2112 } 2113 } 2114 return theKeys; 2115}; 2116 2117keysShim.shim = function shimObjectKeys() { 2118 if (Object.keys) { 2119 var keysWorksWithArguments = (function () { 2120 // Safari 5.0 bug 2121 return (Object.keys(arguments) || '').length === 2; 2122 }(1, 2)); 2123 if (!keysWorksWithArguments) { 2124 var originalKeys = Object.keys; 2125 Object.keys = function keys(object) { 2126 if (isArgs(object)) { 2127 return originalKeys(slice.call(object)); 2128 } else { 2129 return originalKeys(object); 2130 } 2131 }; 2132 } 2133 } else { 2134 Object.keys = keysShim; 2135 } 2136 return Object.keys || keysShim; 2137}; 2138 2139module.exports = keysShim; 2140 2141},{"./isArguments":51}],51:[function(_dereq_,module,exports){ 2142'use strict'; 2143 2144var toStr = Object.prototype.toString; 2145 2146module.exports = function isArguments(value) { 2147 var str = toStr.call(value); 2148 var isArgs = str === '[object Arguments]'; 2149 if (!isArgs) { 2150 isArgs = str !== '[object Array]' && 2151 value !== null && 2152 typeof value === 'object' && 2153 typeof value.length === 'number' && 2154 value.length >= 0 && 2155 toStr.call(value.callee) === '[object Function]'; 2156 } 2157 return isArgs; 2158}; 2159 2160},{}],52:[function(_dereq_,module,exports){ 2161'use strict'; 2162 2163var implementation = _dereq_('./implementation'); 2164 2165var lacksProperEnumerationOrder = function () { 2166 if (!Object.assign) { 2167 return false; 2168 } 2169 // v8, specifically in node 4.x, has a bug with incorrect property enumeration order 2170 // note: this does not detect the bug unless there's 20 characters 2171 var str = 'abcdefghijklmnopqrst'; 2172 var letters = str.split(''); 2173 var map = {}; 2174 for (var i = 0; i < letters.length; ++i) { 2175 map[letters[i]] = letters[i]; 2176 } 2177 var obj = Object.assign({}, map); 2178 var actual = ''; 2179 for (var k in obj) { 2180 actual += k; 2181 } 2182 return str !== actual; 2183}; 2184 2185var assignHasPendingExceptions = function () { 2186 if (!Object.assign || !Object.preventExtensions) { 2187 return false; 2188 } 2189 // Firefox 37 still has "pending exception" logic in its Object.assign implementation, 2190 // which is 72% slower than our shim, and Firefox 40's native implementation. 2191 var thrower = Object.preventExtensions({ 1: 2 }); 2192 try { 2193 Object.assign(thrower, 'xy'); 2194 } catch (e) { 2195 return thrower[1] === 'y'; 2196 } 2197}; 2198 2199module.exports = function getPolyfill() { 2200 if (!Object.assign) { 2201 return implementation; 2202 } 2203 if (lacksProperEnumerationOrder()) { 2204 return implementation; 2205 } 2206 if (assignHasPendingExceptions()) { 2207 return implementation; 2208 } 2209 return Object.assign; 2210}; 2211 2212},{"./implementation":44}],53:[function(_dereq_,module,exports){ 2213'use strict'; 2214 2215var define = _dereq_('define-properties'); 2216var getPolyfill = _dereq_('./polyfill'); 2217 2218module.exports = function shimAssign() { 2219 var polyfill = getPolyfill(); 2220 define( 2221 Object, 2222 { assign: polyfill }, 2223 { assign: function () { return Object.assign !== polyfill; } } 2224 ); 2225 return polyfill; 2226}; 2227 2228},{"./polyfill":52,"define-properties":46}],54:[function(_dereq_,module,exports){ 2229module.exports = SafeParseTuple 2230 2231function SafeParseTuple(obj, reviver) { 2232 var json 2233 var error = null 2234 2235 try { 2236 json = JSON.parse(obj, reviver) 2237 } catch (err) { 2238 error = err 2239 } 2240 2241 return [error, json] 2242} 2243 2244},{}],55:[function(_dereq_,module,exports){ 2245function clean (s) { 2246 return s.replace(/\n\r?\s*/g, '') 2247} 2248 2249 2250module.exports = function tsml (sa) { 2251 var s = '' 2252 , i = 0 2253 2254 for (; i < arguments.length; i++) 2255 s += clean(sa[i]) + (arguments[i + 1] || '') 2256 2257 return s 2258} 2259},{}],56:[function(_dereq_,module,exports){ 2260"use strict"; 2261var window = _dereq_("global/window") 2262var once = _dereq_("once") 2263var isFunction = _dereq_("is-function") 2264var parseHeaders = _dereq_("parse-headers") 2265var xtend = _dereq_("xtend") 2266 2267module.exports = createXHR 2268createXHR.XMLHttpRequest = window.XMLHttpRequest || noop 2269createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest 2270 2271forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) { 2272 createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) { 2273 options = initParams(uri, options, callback) 2274 options.method = method.toUpperCase() 2275 return _createXHR(options) 2276 } 2277}) 2278 2279function forEachArray(array, iterator) { 2280 for (var i = 0; i < array.length; i++) { 2281 iterator(array[i]) 2282 } 2283} 2284 2285function isEmpty(obj){ 2286 for(var i in obj){ 2287 if(obj.hasOwnProperty(i)) return false 2288 } 2289 return true 2290} 2291 2292function initParams(uri, options, callback) { 2293 var params = uri 2294 2295 if (isFunction(options)) { 2296 callback = options 2297 if (typeof uri === "string") { 2298 params = {uri:uri} 2299 } 2300 } else { 2301 params = xtend(options, {uri: uri}) 2302 } 2303 2304 params.callback = callback 2305 return params 2306} 2307 2308function createXHR(uri, options, callback) { 2309 options = initParams(uri, options, callback) 2310 return _createXHR(options) 2311} 2312 2313function _createXHR(options) { 2314 var callback = options.callback 2315 if(typeof callback === "undefined"){ 2316 throw new Error("callback argument missing") 2317 } 2318 callback = once(callback) 2319 2320 function readystatechange() { 2321 if (xhr.readyState === 4) { 2322 loadFunc() 2323 } 2324 } 2325 2326 function getBody() { 2327 // Chrome with requestType=blob throws errors arround when even testing access to responseText 2328 var body = undefined 2329 2330 if (xhr.response) { 2331 body = xhr.response 2332 } else if (xhr.responseType === "text" || !xhr.responseType) { 2333 body = xhr.responseText || xhr.responseXML 2334 } 2335 2336 if (isJson) { 2337 try { 2338 body = JSON.parse(body) 2339 } catch (e) {} 2340 } 2341 2342 return body 2343 } 2344 2345 var failureResponse = { 2346 body: undefined, 2347 headers: {}, 2348 statusCode: 0, 2349 method: method,
2350 url: uri, 2351 rawRequest: xhr 2352 } 2353 2354 function errorFunc(evt) { 2355 clearTimeout(timeoutTimer) 2356 if(!(evt instanceof Error)){ 2357 evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") ) 2358 } 2359 evt.statusCode = 0 2360 callback(evt, failureResponse) 2361 } 2362 2363 // will load the data & process the response in a special response object 2364 function loadFunc() { 2365 if (aborted) return 2366 var status 2367 clearTimeout(timeoutTimer) 2368 if(options.useXDR && xhr.status===undefined) { 2369 //IE8 CORS GET successful response doesn't have a status field, but body is fine 2370 status = 200 2371 } else { 2372 status = (xhr.status === 1223 ? 204 : xhr.status) 2373 } 2374 var response = failureResponse 2375 var err = null 2376 2377 if (status !== 0){ 2378 response = { 2379 body: getBody(), 2380 statusCode: status, 2381 method: method, 2382 headers: {}, 2383 url: uri, 2384 rawRequest: xhr 2385 } 2386 if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE 2387 response.headers = parseHeaders(xhr.getAllResponseHeaders()) 2388 } 2389 } else { 2390 err = new Error("Internal XMLHttpRequest Error") 2391 } 2392 callback(err, response, response.body) 2393 2394 } 2395 2396 var xhr = options.xhr || null 2397 2398 if (!xhr) { 2399 if (options.cors || options.useXDR) { 2400 xhr = new createXHR.XDomainRequest() 2401 }else{ 2402 xhr = new createXHR.XMLHttpRequest() 2403 } 2404 } 2405 2406 var key 2407 var aborted 2408 var uri = xhr.url = options.uri || options.url 2409 var method = xhr.method = options.method || "GET" 2410 var body = options.body || options.data || null 2411 var headers = xhr.headers = options.headers || {} 2412 var sync = !!options.sync 2413 var isJson = false 2414 var timeoutTimer 2415 2416 if ("json" in options) { 2417 isJson = true 2418 headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user 2419 if (method !== "GET" && method !== "HEAD") { 2420 headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user 2421 body = JSON.stringify(options.json) 2422 } 2423 } 2424 2425 xhr.onreadystatechange = readystatechange 2426 xhr.onload = loadFunc 2427 xhr.onerror = errorFunc 2428 // IE9 must have onprogress be set to a unique function. 2429 xhr.onprogress = function () { 2430 // IE must die 2431 } 2432 xhr.ontimeout = errorFunc 2433 xhr.open(method, uri, !sync, options.username, options.password) 2434 //has to be after open 2435 if(!sync) { 2436 xhr.withCredentials = !!options.withCredentials 2437 } 2438 // Cannot set timeout with sync request 2439 // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly 2440 // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent 2441 if (!sync && options.timeout > 0 ) { 2442 timeoutTimer = setTimeout(function(){ 2443 aborted=true//IE9 may still call readystatechange 2444 xhr.abort("timeout") 2445 var e = new Error("XMLHttpRequest timeout") 2446 e.code = "ETIMEDOUT" 2447 errorFunc(e) 2448 }, options.timeout ) 2449 } 2450 2451 if (xhr.setRequestHeader) { 2452 for(key in headers){ 2453 if(headers.hasOwnProperty(key)){ 2454 xhr.setRequestHeader(key, headers[key]) 2455 } 2456 } 2457 } else if (options.headers && !isEmpty(options.headers)) { 2458 throw new Error("Headers cannot be set on an XDomainRequest object") 2459 } 2460 2461 if ("responseType" in options) { 2462 xhr.responseType = options.responseType 2463 } 2464 2465 if ("beforeSend" in options && 2466 typeof options.beforeSend === "function" 2467 ) { 2468 options.beforeSend(xhr) 2469 } 2470 2471 xhr.send(body) 2472 2473 return xhr 2474 2475 2476} 2477 2478function noop() {} 2479 2480},{"global/window":2,"is-function":57,"once":58,"parse-headers":61,"xtend":62}],57:[function(_dereq_,module,exports){ 2481module.exports = isFunction 2482 2483var toString = Object.prototype.toString 2484 2485function isFunction (fn) { 2486 var string = toString.call(fn) 2487 return string === '[object Function]' || 2488 (typeof fn === 'function' && string !== '[object RegExp]') || 2489 (typeof window !== 'undefined' && 2490 // IE8 and below 2491 (fn === window.setTimeout || 2492 fn === window.alert || 2493 fn === window.confirm || 2494 fn === window.prompt)) 2495}; 2496 2497},{}],58:[function(_dereq_,module,exports){ 2498module.exports = once 2499 2500once.proto = once(function () { 2501 Object.defineProperty(Function.prototype, 'once', { 2502 value: function () { 2503 return once(this) 2504 }, 2505 configurable: true 2506 }) 2507}) 2508 2509function once (fn) { 2510 var called = false 2511 return function () { 2512 if (called) return 2513 called = true 2514 return fn.apply(this, arguments) 2515 } 2516} 2517 2518},{}],59:[function(_dereq_,module,exports){ 2519var isFunction = _dereq_('is-function') 2520 2521module.exports = forEach 2522 2523var toString = Object.prototype.toString 2524var hasOwnProperty = Object.prototype.hasOwnProperty 2525 2526function forEach(list, iterator, context) { 2527 if (!isFunction(iterator)) { 2528 throw new TypeError('iterator must be a function') 2529 } 2530 2531 if (arguments.length < 3) { 2532 context = this 2533 } 2534 2535 if (toString.call(list) === '[object Array]')
2536 forEachArray(list, iterator, context) 2537 else if (typeof list === 'string') 2538 forEachString(list, iterator, context) 2539 else 2540 forEachObject(list, iterator, context) 2541} 2542 2543function forEachArray(array, iterator, context) { 2544 for (var i = 0, len = array.length; i < len; i++) { 2545 if (hasOwnProperty.call(array, i)) { 2546 iterator.call(context, array[i], i, array) 2547 } 2548 } 2549} 2550 2551function forEachString(string, iterator, context) { 2552 for (var i = 0, len = string.length; i < len; i++) { 2553 // no such thing as a sparse string. 2554 iterator.call(context, string.charAt(i), i, string) 2555 } 2556} 2557 2558function forEachObject(object, iterator, context) { 2559 for (var k in object) { 2560 if (hasOwnProperty.call(object, k)) { 2561 iterator.call(context, object[k], k, object) 2562 } 2563 } 2564} 2565 2566},{"is-function":57}],60:[function(_dereq_,module,exports){ 2567 2568exports = module.exports = trim; 2569 2570function trim(str){ 2571 return str.replace(/^\s*|\s*$/g, ''); 2572} 2573 2574exports.left = function(str){ 2575 return str.replace(/^\s*/, ''); 2576}; 2577 2578exports.right = function(str){ 2579 return str.replace(/\s*$/, ''); 2580}; 2581 2582},{}],61:[function(_dereq_,module,exports){ 2583var trim = _dereq_('trim') 2584 , forEach = _dereq_('for-each') 2585 , isArray = function(arg) { 2586 return Object.prototype.toString.call(arg) === '[object Array]'; 2587 } 2588 2589module.exports = function (headers) { 2590 if (!headers) 2591 return {} 2592 2593 var result = {} 2594 2595 forEach( 2596 trim(headers).split('\n') 2597 , function (row) { 2598 var index = row.indexOf(':') 2599 , key = trim(row.slice(0, index)).toLowerCase() 2600 , value = trim(row.slice(index + 1)) 2601 2602 if (typeof(result[key]) === 'undefined') { 2603 result[key] = value 2604 } else if (isArray(result[key])) { 2605 result[key].push(value) 2606 } else { 2607 result[key] = [ result[key], value ] 2608 } 2609 } 2610 ) 2611 2612 return result 2613} 2614},{"for-each":59,"trim":60}],62:[function(_dereq_,module,exports){ 2615module.exports = extend 2616 2617var hasOwnProperty = Object.prototype.hasOwnProperty; 2618 2619function extend() { 2620 var target = {} 2621 2622 for (var i = 0; i < arguments.length; i++) { 2623 var source = arguments[i] 2624 2625 for (var key in source) { 2626 if (hasOwnProperty.call(source, key)) { 2627 target[key] = source[key] 2628 } 2629 } 2630 } 2631 2632 return target 2633} 2634 2635},{}],63:[function(_dereq_,module,exports){ 2636/** 2637 * @file big-play-button.js 2638 */ 2639'use strict'; 2640 2641exports.__esModule = true; 2642 2643function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2644 2645function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 2646 2647function _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; } 2648 2649var _buttonJs = _dereq_('./button.js'); 2650 2651var _buttonJs2 = _interopRequireDefault(_buttonJs); 2652 2653var _componentJs = _dereq_('./component.js'); 2654 2655var _componentJs2 = _interopRequireDefault(_componentJs); 2656 2657/** 2658 * Initial play button. Shows before the video has played. The hiding of the 2659 * big play button is done via CSS and player states. 2660 * 2661 * @param {Object} player Main Player 2662 * @param {Object=} options Object of option names and values 2663 * @extends Button 2664 * @class BigPlayButton 2665 */ 2666 2667var BigPlayButton = (function (_Button) { 2668 _inherits(BigPlayButton, _Button); 2669 2670 function BigPlayButton(player, options) { 2671 _classCallCheck(this, BigPlayButton); 2672 2673 _Button.call(this, player, options); 2674 } 2675 2676 /** 2677 * Allow sub components to stack CSS class names 2678 * 2679 * @return {String} The constructed class name 2680 * @method buildCSSClass 2681 */ 2682 2683 BigPlayButton.prototype.buildCSSClass = function buildCSSClass() { 2684 return 'vjs-big-play-button'; 2685 }; 2686 2687 /** 2688 * Handles click for play 2689 * 2690 * @method handleClick 2691 */ 2692 2693 BigPlayButton.prototype.handleClick = function handleClick() { 2694 this.player_.play(); 2695 }; 2696 2697 return BigPlayButton; 2698})(_buttonJs2['default']); 2699 2700BigPlayButton.prototype.controlText_ = 'Play Video'; 2701 2702_componentJs2['default'].registerComponent('BigPlayButton', BigPlayButton); 2703exports['default'] = BigPlayButton; 2704module.exports = exports['default']; 2705 2706},{"./button.js":64,"./component.js":67}],64:[function(_dereq_,module,exports){ 2707/** 2708 * @file button.js 2709 */ 2710'use strict'; 2711 2712exports.__esModule = true; 2713 2714function _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; } } 2715 2716function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2717 2718function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 2719 2720function _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
2720onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 2721 2722var _clickableComponentJs = _dereq_('./clickable-component.js'); 2723 2724var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs); 2725 2726var _component = _dereq_('./component'); 2727 2728var _component2 = _interopRequireDefault(_component); 2729 2730var _utilsEventsJs = _dereq_('./utils/events.js'); 2731 2732var Events = _interopRequireWildcard(_utilsEventsJs); 2733 2734var _utilsFnJs = _dereq_('./utils/fn.js'); 2735 2736var Fn = _interopRequireWildcard(_utilsFnJs); 2737 2738var _utilsLogJs = _dereq_('./utils/log.js'); 2739 2740var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 2741 2742var _globalDocument = _dereq_('global/document'); 2743 2744var _globalDocument2 = _interopRequireDefault(_globalDocument); 2745 2746var _objectAssign = _dereq_('object.assign'); 2747 2748var _objectAssign2 = _interopRequireDefault(_objectAssign); 2749 2750/** 2751 * Base class for all buttons 2752 * 2753 * @param {Object} player Main Player 2754 * @param {Object=} options Object of option names and values 2755 * @extends ClickableComponent 2756 * @class Button 2757 */ 2758 2759var Button = (function (_ClickableComponent) { 2760 _inherits(Button, _ClickableComponent); 2761 2762 function Button(player, options) { 2763 _classCallCheck(this, Button); 2764 2765 _ClickableComponent.call(this, player, options); 2766 } 2767 2768 /** 2769 * Create the component's DOM element 2770 * 2771 * @param {String=} type Element's node type. e.g. 'div' 2772 * @param {Object=} props An object of properties that should be set on the element 2773 * @param {Object=} attributes An object of attributes that should be set on the element 2774 * @return {Element} 2775 * @method createEl 2776 */ 2777 2778 Button.prototype.createEl = function createEl() { 2779 var tag = arguments.length <= 0 || arguments[0] === undefined ? 'button' : arguments[0]; 2780 var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 2781 var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; 2782 2783 props = _objectAssign2['default']({ 2784 className: this.buildCSSClass() 2785 }, props); 2786 2787 if (tag !== 'button') { 2788 _utilsLogJs2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.'); 2789 2790 // Add properties for clickable element which is not a native HTML button 2791 props = _objectAssign2['default']({ 2792 tabIndex: 0 2793 }, props); 2794 2795 // Add ARIA attributes for clickable element which is not a native HTML button 2796 attributes = _objectAssign2['default']({ 2797 role: 'button' 2798 }, attributes); 2799 } 2800 2801 // Add attributes for button element 2802 attributes = _objectAssign2['default']({ 2803 type: 'button', // Necessary since the default button type is "submit" 2804 'aria-live': 'polite' // let the screen reader user know that the text of the button may change 2805 }, attributes); 2806 2807 var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes); 2808 2809 this.createControlTextEl(el); 2810 2811 return el; 2812 }; 2813 2814 /** 2815 * Adds a child component inside this button 2816 * 2817 * @param {String|Component} child The class name or instance of a child to add 2818 * @param {Object=} options Options, including options to be passed to children of the child. 2819 * @return {Component} The child component (created by this process if a string was used) 2820 * @deprecated 2821 * @method addChild 2822 */ 2823 2824 Button.prototype.addChild = function addChild(child) { 2825 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 2826 2827 var className = this.constructor.name; 2828 _utilsLogJs2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.'); 2829 2830 // Avoid the error message generated by ClickableComponent's addChild method 2831 return _component2['default'].prototype.addChild.call(this, child, options); 2832 }; 2833 2834 /** 2835 * Handle KeyPress (document level) - Extend with specific functionality for button 2836 * 2837 * @method handleKeyPress 2838 */ 2839 2840 Button.prototype.handleKeyPress = function handleKeyPress(event) { 2841 // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button. 2842 if (event.which === 32 || event.which === 13) {} else { 2843 _ClickableComponent.prototype.handleKeyPress.call(this, event); // Pass keypress handling up for unsupported keys 2844 } 2845 }; 2846 2847 return Button; 2848})(_clickableComponentJs2['default']); 2849 2850_component2['default'].registerComponent('Button', Button); 2851exports['default'] = Button; 2852module.exports = exports['default']; 2853 2854},{"./clickable-component.js":65,"./component":67,"./utils/events.js":144,"./ut
2854ils/fn.js":145,"./utils/log.js":148,"global/document":1,"object.assign":45}],65:[function(_dereq_,module,exports){ 2855/** 2856 * @file button.js 2857 */ 2858'use strict'; 2859 2860exports.__esModule = true; 2861 2862function _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; } } 2863 2864function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2865 2866function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 2867 2868function _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; } 2869 2870var _component = _dereq_('./component'); 2871 2872var _component2 = _interopRequireDefault(_component); 2873 2874var _utilsDomJs = _dereq_('./utils/dom.js'); 2875 2876var Dom = _interopRequireWildcard(_utilsDomJs); 2877 2878var _utilsEventsJs = _dereq_('./utils/events.js'); 2879 2880var Events = _interopRequireWildcard(_utilsEventsJs); 2881 2882var _utilsFnJs = _dereq_('./utils/fn.js'); 2883 2884var Fn = _interopRequireWildcard(_utilsFnJs); 2885 2886var _utilsLogJs = _dereq_('./utils/log.js'); 2887 2888var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 2889 2890var _globalDocument = _dereq_('global/document'); 2891 2892var _globalDocument2 = _interopRequireDefault(_globalDocument); 2893 2894var _objectAssign = _dereq_('object.assign'); 2895 2896var _objectAssign2 = _interopRequireDefault(_objectAssign); 2897 2898/** 2899 * Clickable Component which is clickable or keyboard actionable, but is not a native HTML button 2900 * 2901 * @param {Object} player Main Player 2902 * @param {Object=} options Object of option names and values 2903 * @extends Component 2904 * @class ClickableComponent 2905 */ 2906 2907var ClickableComponent = (function (_Component) { 2908 _inherits(ClickableComponent, _Component); 2909 2910 function ClickableComponent(player, options) { 2911 _classCallCheck(this, ClickableComponent); 2912 2913 _Component.call(this, player, options); 2914 2915 this.emitTapEvents(); 2916 2917 this.on('tap', this.handleClick); 2918 this.on('click', this.handleClick); 2919 this.on('focus', this.handleFocus); 2920 this.on('blur', this.handleBlur); 2921 } 2922 2923 /** 2924 * Create the component's DOM element 2925 * 2926 * @param {String=} type Element's node type. e.g. 'div' 2927 * @param {Object=} props An object of properties that should be set on the element 2928 * @param {Object=} attributes An object of attributes that should be set on the element 2929 * @return {Element} 2930 * @method createEl 2931 */ 2932 2933 ClickableComponent.prototype.createEl = function createEl() { 2934 var tag = arguments.length <= 0 || arguments[0] === undefined ? 'div' : arguments[0]; 2935 var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 2936 var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; 2937 2938 props = _objectAssign2['default']({ 2939 className: this.buildCSSClass(), 2940 tabIndex: 0 2941 }, props); 2942 2943 if (tag === 'button') { 2944 _utilsLogJs2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.'); 2945 } 2946 2947 // Add ARIA attributes for clickable element which is not a native HTML button 2948 attributes = _objectAssign2['default']({ 2949 role: 'button', 2950 'aria-live': 'polite' // let the screen reader user know that the text of the element may change 2951 }, attributes); 2952 2953 var el = _Component.prototype.createEl.call(this, tag, props, attributes); 2954 2955 this.createControlTextEl(el); 2956 2957 return el; 2958 }; 2959 2960 /** 2961 * create control text 2962 * 2963 * @param {Element} el Parent element for the control text 2964 * @return {Element} 2965 * @method controlText 2966 */ 2967 2968 ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) { 2969 this.controlTextEl_ = Dom.createEl('span', { 2970 className: 'vjs-control-text' 2971 }); 2972 2973 if (el) { 2974 el.appendChild(this.controlTextEl_); 2975 } 2976 2977 this.controlText(this.controlText_); 2978 2979 return this.controlTextEl_; 2980 }; 2981 2982 /** 2983 * Controls text - both request and localize 2984 * 2985 * @param {String} text Text for element 2986 * @return {String} 2987 * @method controlText 2988 */ 2989 2990 ClickableComponent.prototype.controlText = function controlText(text) { 2991 if (!text) return this.controlText_ || 'Need Text'; 2992 2993 this.controlText_ = text; 2994 this.controlTextEl_.innerHTML = this.localize(this.controlText_); 2995 2996 return this; 2997 }; 2998 2999 /** 3000 * Allows sub components to stack CSS class names 3001 * 3002 * @return {String} 3003 * @method buildCSSClass 3004 */ 3005 3006 ClickableComponent.prototype.buildCSSClass = function buildCSSClass() { 3007 return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this); 3008 }; 3009 3010 /** 3011 * Adds a child component inside this clickable-component 3012 * 3013 * @param {String|Component} child The class name or instance of a child to add 3014 * @param {Object=} options Options, including options to be passed to children of the child. 3015 * @return {Component} The child component (created by this process if a string was used) 3016 * @method addChild 3017 */ 3018 3019 ClickableComponent.prototype.addChild = function addChild(child) { 3020 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 3021 3022 // TODO: Fix adding an actionable child to a ClickableComponent; currently 3023 // it will cause issues with assistive technology (e.g. screen readers) 3024 // which support ARIA, since an element with role="button" cannot have 3025 // actionable child elements. 3026 3027 //let className = this.constructor.name; 3028 //log.warn(`Adding a child to a ClickableComponent (${className}) can cause issues with assistive technology which supports ARIA, since an element with role="button" cannot have actionable child elements.`); 3029 3030 return _Component.prototype.addChild.call(this, child, options); 3031 }; 3032 3033 /** 3034 * Enable the component element 3035 * 3036 * @return {Component} 3037 * @method enable 3038 */ 3039 3040 ClickableComponent.prototype.enable = function enable() { 3041 this.removeClass('vjs-disabled'); 3042 this.el_.setAttribute('aria-disabled', 'false'); 3043 return this; 3044 }; 3045 3046 /** 3047 * Disable the component element 3048 * 3049 * @return {Component} 3050 * @method disable 3051 */ 3052 3053 ClickableComponent.prototype.disable = function disable() { 3054 this.addClass('vjs-disabled'); 3055 this.el_.setAttribute('aria-disabled', 'true'); 3056 return this; 3057 }; 3058 3059 /** 3060 * Handle Click - Override with specific functionality for component 3061 * 3062 * @method handleClick 3063 */ 3064 3065 ClickableComponent.prototype.handleClick = function handleClick() {}; 3066 3067 /** 3068 * Handle Focus - Add keyboard functionality to element 3069 * 3070 * @method handleFocus 3071 */ 3072 3073 ClickableComponent.prototype.handleFocus = function handleFocus() { 3074 Events.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); 3075 }; 3076 3077 /** 3078 * Handle KeyPress (document level) - Trigger click when Space or Enter key is pressed 3079 * 3080 * @method handleKeyPress 3081 */ 3082 3083 ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) {
3084 // Support Space (32) or Enter (13) key operation to fire a click event 3085 if (event.which === 32 || event.which === 13) { 3086 event.preventDefault(); 3087 this.handleClick(event); 3088 } else if (_Component.prototype.handleKeyPress) { 3089 _Component.prototype.handleKeyPress.call(this, event); // Pass keypress handling up for unsupported keys 3090 } 3091 }; 3092 3093 /** 3094 * Handle Blur - Remove keyboard triggers 3095 * 3096 * @method handleBlur 3097 */ 3098 3099 ClickableComponent.prototype.handleBlur = function handleBlur() { 3100 Events.off(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); 3101 }; 3102 3103 return ClickableComponent; 3104})(_component2['default']); 3105 3106_component2['default'].registerComponent('ClickableComponent', ClickableComponent); 3107exports['default'] = ClickableComponent; 3108module.exports = exports['default']; 3109 3110},{"./component":67,"./utils/dom.js":143,"./utils/events.js":144,"./utils/fn.js":145,"./utils/log.js":148,"global/document":1,"object.assign":45}],66:[function(_dereq_,module,exports){ 3111'use strict'; 3112 3113exports.__esModule = true; 3114 3115function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3116 3117function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 3118 3119function _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; } 3120 3121var _button = _dereq_('./button'); 3122 3123var _button2 = _interopRequireDefault(_button); 3124 3125var _component = _dereq_('./component'); 3126 3127var _component2 = _interopRequireDefault(_component); 3128 3129/** 3130 * The `CloseButton` component is a button which fires a "close" event 3131 * when it is activated. 3132 * 3133 * @extends Button 3134 * @class CloseButton 3135 */ 3136 3137var CloseButton = (function (_Button) { 3138 _inherits(CloseButton, _Button); 3139 3140 function CloseButton(player, options) { 3141 _classCallCheck(this, CloseButton); 3142 3143 _Button.call(this, player, options); 3144 this.controlText(options && options.controlText || this.localize('Close')); 3145 } 3146 3147 CloseButton.prototype.buildCSSClass = function buildCSSClass() { 3148 return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this); 3149 }; 3150 3151 CloseButton.prototype.handleClick = function handleClick() { 3152 this.trigger({ type: 'close', bubbles: false }); 3153 }; 3154 3155 return CloseButton; 3156})(_button2['default']); 3157 3158_component2['default'].registerComponent('CloseButton', CloseButton); 3159exports['default'] = CloseButton; 3160module.exports = exports['default']; 3161 3162},{"./button":64,"./component":67}],67:[function(_dereq_,module,exports){ 3163/** 3164 * @file component.js 3165 * 3166 * Player Component - Base class for all UI objects 3167 */ 3168 3169'use strict'; 3170 3171exports.__esModule = true; 3172 3173function _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; } } 3174 3175function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3176 3177function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 3178 3179var _globalWindow = _dereq_('global/window'); 3180 3181var _globalWindow2 = _interopRequireDefault(_globalWindow); 3182 3183var _utilsDomJs = _dereq_('./utils/dom.js'); 3184 3185var Dom = _interopRequireWildcard(_utilsDomJs); 3186 3187var _utilsFnJs = _dereq_('./utils/fn.js'); 3188 3189var Fn = _interopRequireWildcard(_utilsFnJs); 3190 3191var _utilsGuidJs = _dereq_('./utils/guid.js'); 3192 3193var Guid = _interopRequireWildcard(_utilsGuidJs); 3194 3195var _utilsEventsJs = _dereq_('./utils/events.js'); 3196 3197var Events = _interopRequireWildcard(_utilsEventsJs); 3198 3199var _utilsLogJs = _dereq_('./utils/log.js'); 3200 3201var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 3202 3203var _utilsToTitleCaseJs = _dereq_('./utils/to-title-case.js'); 3204 3205var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs); 3206 3207var _objectAssign = _dereq_('object.assign'); 3208 3209var _objectAssign2 = _interopRequireDefault(_objectAssign); 3210 3211var _utilsMergeOptionsJs = _dereq_('./utils/merge-options.js'); 3212 3213var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs); 3214 3215/** 3216 * Base UI Component class 3217 * Components are embeddable UI objects that are represented by both a 3218 * javascript object and an element in the DOM. They can be children of other 3219 * components, and can have many children themselves. 3220 * ```js 3221 * // adding a button to the player 3222 * var button = player.addChild('button'); 3223 * button.el(); // -> button element 3224 * ``` 3225 * ```html 3226 * <div class="video-js"> 3227 * <div class="vjs-button">Button</div>
3228 * </div> 3229 * ``` 3230 * Components are also event targets. 3231 * ```js 3232 * button.on('click', function(){ 3233 * console.log('Button Clicked!'); 3234 * }); 3235 * button.trigger('customevent'); 3236 * ``` 3237 * 3238 * @param {Object} player Main Player 3239 * @param {Object=} options Object of option names and values 3240 * @param {Function=} ready Ready callback function 3241 * @class Component 3242 */ 3243 3244var Component = (function () { 3245 function Component(player, options, ready) { 3246 _classCallCheck(this, Component); 3247 3248 // The component might be the player itself and we can't pass `this` to super 3249 if (!player && this.play) { 3250 this.player_ = player = this; // eslint-disable-line 3251 } else { 3252 this.player_ = player; 3253 } 3254 3255 // Make a copy of prototype.options_ to protect against overriding defaults 3256 this.options_ = _utilsMergeOptionsJs2['default']({}, this.options_); 3257 3258 // Updated options with supplied options 3259 options = this.options_ = _utilsMergeOptionsJs2['default'](this.options_, options); 3260 3261 // Get ID from options or options element if one is supplied 3262 this.id_ = options.id || options.el && options.el.id; 3263 3264 // If there was no ID from the options, generate one 3265 if (!this.id_) { 3266 // Don't require the player ID function in the case of mock players 3267 var id = player && player.id && player.id() || 'no_player'; 3268 3269 this.id_ = id + '_component_' + Guid.newGUID(); 3270 } 3271 3272 this.name_ = options.name || null; 3273 3274 // Create element if one wasn't provided in options 3275 if (options.el) { 3276 this.el_ = options.el; 3277 } else if (options.createEl !== false) { 3278 this.el_ = this.createEl(); 3279 } 3280 3281 this.children_ = []; 3282 this.childIndex_ = {}; 3283 this.childNameIndex_ = {}; 3284 3285 // Add any child components in options 3286 if (options.initChildren !== false) { 3287 this.initChildren(); 3288 } 3289 3290 this.ready(ready); 3291 // Don't want to trigger ready here or it will before init is actually 3292 // finished for all children that run this constructor 3293 3294 if (options.reportTouchActivity !== false) { 3295 this.enableTouchActivity(); 3296 } 3297 } 3298 3299 /** 3300 * Dispose of the component and all child components 3301 * 3302 * @method dispose 3303 */ 3304 3305 Component.prototype.dispose = function dispose() { 3306 this.trigger({ type: 'dispose', bubbles: false }); 3307 3308 // Dispose all children. 3309 if (this.children_) { 3310 for (var i = this.children_.length - 1; i >= 0; i--) { 3311 if (this.children_[i].dispose) { 3312 this.children_[i].dispose(); 3313 } 3314 } 3315 } 3316 3317 // Delete child references 3318 this.children_ = null; 3319 this.childIndex_ = null; 3320 this.childNameIndex_ = null; 3321 3322 // Remove all event listeners. 3323 this.off(); 3324 3325 // Remove element from DOM 3326 if (this.el_.parentNode) { 3327 this.el_.parentNode.removeChild(this.el_); 3328 } 3329 3330 Dom.removeElData(this.el_); 3331 this.el_ = null; 3332 }; 3333 3334 /** 3335 * Return the component's player 3336 * 3337 * @return {Player} 3338 * @method player 3339 */ 3340 3341 Component.prototype.player = function player() { 3342 return this.player_; 3343 }; 3344 3345 /** 3346 * Deep merge of options objects 3347 * Whenever a property is an object on both options objects 3348 * the two properties will be merged using mergeOptions. 3349 * 3350 * ```js 3351 * Parent.prototype.options_ = { 3352 * optionSet: { 3353 * 'childOne': { 'foo': 'bar', 'asdf': 'fdsa' }, 3354 * 'childTwo': {}, 3355 * 'childThree': {} 3356 * } 3357 * } 3358 * newOptions = { 3359 * optionSet: { 3360 * 'childOne': { 'foo': 'baz', 'abc': '123' } 3361 * 'childTwo': null, 3362 * 'childFour': {} 3363 * } 3364 * } 3365 * 3366 * this.options(newOptions); 3367 * ``` 3368 * RESULT 3369 * ```js 3370 * { 3371 * optionSet: { 3372 * 'childOne': { 'foo': 'baz', 'asdf': 'fdsa', 'abc': '123' }, 3373 * 'childTwo': null, // Disabled. Won't be initialized. 3374 * 'childThree': {}, 3375 * 'childFour': {} 3376 * } 3377 * } 3378 * ``` 3379 * 3380 * @param {Object} obj Object of new option values 3381 * @return {Object} A NEW object of this.options_ and obj merged 3382 * @method options 3383 */ 3384 3385 Component.prototype.options = function options(obj) { 3386 _utilsLogJs2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0'); 3387 3388 if (!obj) { 3389 return this.options_; 3390 } 3391 3392 this.options_ = _utilsMergeOptionsJs2['default'](this.options_, obj); 3393 return this.options_; 3394 }; 3395 3396 /** 3397 * Get the component's DOM element 3398 * ```js 3399 * var domEl = myComponent.el(); 3400 * ``` 3401 * 3402 * @return {Element} 3403 * @method el 3404 */ 3405 3406 Component.prototype.el = function el() { 3407 return this.el_; 3408 }; 3409 3410 /** 3411 * Create the component's DOM element 3412 * 3413 * @param {String=} tagName Element's node type. e.g. 'div' 3414 * @param {Object=} properties An object of properties that should be set 3415 * @param {Object=} attributes An object of attributes that should be set 3416 * @return {Element} 3417 * @method createEl 3418 */ 3419 3420 Component.prototype.createEl = function createEl(tagName, properties, attributes) { 3421 return Dom.createEl(tagName, properties, attributes); 3422 }; 3423 3424 Component.prototype.localize = function localize(string) { 3425 var code = this.player_.language && this.player_.language(); 3426 var languages = this.player_.languages && this.player_.languages(); 3427 3428 if (!code || !languages) { 3429 return string; 3430 } 3431 3432 var language = languages[code]; 3433 3434 if (language && language[string]) { 3435 return language[string]; 3436 } 3437 3438 var primaryCode = code.split('-')[0]; 3439 var primaryLang = languages[primaryCode]; 3440 3441 if (primaryLang && primaryLang[string]) { 3442 return primaryLang[string]; 3443 } 3444 3445 return string; 3446 }; 3447 3448 /** 3449 * Return the component's DOM element where children are inserted. 3450 * Will either be the same as el() or a new element defined in createEl(). 3451 * 3452 * @return {Element} 3453 * @method contentEl 3454 */ 3455 3456 Component.prototype.contentEl = function contentEl() { 3457 return this.contentEl_ || this.el_; 3458 }; 3459 3460 /** 3461 * Get the component's ID 3462 * ```js 3463 * var id = myComponent.id(); 3464 * ``` 3465 * 3466 * @return {String} 3467 * @method id 3468 */ 3469 3470 Component.prototype.id = function id() { 3471 return this.id_; 3472 }; 3473 3474 /** 3475 * Get the component's name. The name is often used to reference the component. 3476 * ```js 3477 * var name = myComponent.name(); 3478 * ``` 3479 * 3480 * @return {String}
3481 * @method name 3482 */ 3483 3484 Component.prototype.name = function name() { 3485 return this.name_; 3486 }; 3487 3488 /** 3489 * Get an array of all child components 3490 * ```js 3491 * var kids = myComponent.children(); 3492 * ``` 3493 * 3494 * @return {Array} The children 3495 * @method children 3496 */ 3497 3498 Component.prototype.children = function children() { 3499 return this.children_; 3500 }; 3501 3502 /** 3503 * Returns a child component with the provided ID 3504 * 3505 * @return {Component} 3506 * @method getChildById 3507 */ 3508 3509 Component.prototype.getChildById = function getChildById(id) { 3510 return this.childIndex_[id]; 3511 }; 3512 3513 /** 3514 * Returns a child component with the provided name 3515 * 3516 * @return {Component} 3517 * @method getChild 3518 */ 3519 3520 Component.prototype.getChild = function getChild(name) { 3521 return this.childNameIndex_[name]; 3522 }; 3523 3524 /** 3525 * Adds a child component inside this component 3526 * ```js 3527 * myComponent.el(); 3528 * // -> <div class='my-component'></div> 3529 * myComponent.children(); 3530 * // [empty array] 3531 * 3532 * var myButton = myComponent.addChild('MyButton'); 3533 * // -> <div class='my-component'><div class="my-button">myButton<div></div> 3534 * // -> myButton === myComponent.children()[0]; 3535 * ``` 3536 * Pass in options for child constructors and options for children of the child 3537 * ```js 3538 * var myButton = myComponent.addChild('MyButton', { 3539 * text: 'Press Me', 3540 * buttonChildExample: { 3541 * buttonChildOption: true 3542 * } 3543 * }); 3544 * ``` 3545 * 3546 * @param {String|Component} child The class name or instance of a child to add 3547 * @param {Object=} options Options, including options to be passed to children of the child. 3548 * @param {Number} index into our children array to attempt to add the child 3549 * @return {Component} The child component (created by this process if a string was used) 3550 * @method addChild 3551 */ 3552 3553 Component.prototype.addChild = function addChild(child) { 3554 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 3555 var index = arguments.length <= 2 || arguments[2] === undefined ? this.children_.length : arguments[2]; 3556 3557 var component = undefined; 3558 var componentName = undefined; 3559 3560 // If child is a string, create nt with options 3561 if (typeof child === 'string') { 3562 componentName = child; 3563 3564 // Options can also be specified as a boolean, so convert to an empty object if false. 3565 if (!options) { 3566 options = {}; 3567 } 3568 3569 // Same as above, but true is deprecated so show a warning. 3570 if (options === true) { 3571 _utilsLogJs2['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`.'); 3572 options = {}; 3573 } 3574 3575 // If no componentClass in options, assume componentClass is the name lowercased 3576 // (e.g. playButton) 3577 var componentClassName = options.componentClass || _utilsToTitleCaseJs2['default'](componentName); 3578 3579 // Set name through options 3580 options.name = componentName; 3581 3582 // Create a new object & element for this controls set 3583 // If there's no .player_, this is a player 3584 var ComponentClass = Component.getComponent(componentClassName); 3585 3586 if (!ComponentClass) { 3587 throw new Error('Component ' + componentClassName + ' does not exist'); 3588 } 3589 3590 // data stored directly on the videojs object may be 3591 // misidentified as a component to retain 3592 // backwards-compatibility with 4.x. check to make sure the 3593 // component class can be instantiated. 3594 if (typeof ComponentClass !== 'function') { 3595 return null; 3596 } 3597 3598 component = new ComponentClass(this.player_ || this, options); 3599 3600 // child is a component instance 3601 } else { 3602 component = child; 3603 } 3604 3605 this.children_.splice(index, 0, component); 3606 3607 if (typeof component.id === 'function') { 3608 this.childIndex_[component.id()] = component; 3609 } 3610 3611 // If a name wasn't used to create the component, check if we can use the 3612 // name function of the component 3613 componentName = componentName || component.name && component.name(); 3614 3615 if (componentName) { 3616 this.childNameIndex_[componentName] = component; 3617 } 3618 3619 // Add the UI object's element to the container div (box) 3620 // Having an element is not required 3621 if (typeof component.el === 'function' && component.el()) { 3622 var childNodes = this.contentEl().children;
vendor: 5,718 bytes, lines 3623-3806
3623 var refNode = childNodes[index] || null; 3624 this.contentEl().insertBefore(component.el(), refNode); 3625 } 3626 3627 // Return so it can stored on parent object if desired. 3628 return component; 3629 }; 3630 3631 /** 3632 * Remove a child component from this component's list of children, and the 3633 * child component's element from this component's element 3634 * 3635 * @param {Component} component Component to remove 3636 * @method removeChild 3637 */ 3638 3639 Component.prototype.removeChild = function removeChild(component) { 3640 if (typeof component === 'string') { 3641 component = this.getChild(component); 3642 } 3643 3644 if (!component || !this.children_) { 3645 return; 3646 } 3647 3648 var childFound = false; 3649 3650 for (var i = this.children_.length - 1; i >= 0; i--) { 3651 if (this.children_[i] === component) { 3652 childFound = true; 3653 this.children_.splice(i, 1); 3654 break; 3655 } 3656 } 3657 3658 if (!childFound) { 3659 return; 3660 } 3661 3662 this.childIndex_[component.id()] = null; 3663 this.childNameIndex_[component.name()] = null; 3664 3665 var compEl = component.el(); 3666 3667 if (compEl && compEl.parentNode === this.contentEl()) { 3668 this.contentEl().removeChild(component.el()); 3669 } 3670 }; 3671 3672 /** 3673 * Add and initialize default child components from options 3674 * ```js 3675 * // when an instance of MyComponent is created, all children in options 3676 * // will be added to the instance by their name strings and options 3677 * MyComponent.prototype.options_ = { 3678 * children: [ 3679 * 'myChildComponent' 3680 * ], 3681 * myChildComponent: { 3682 * myChildOption: true 3683 * } 3684 * }; 3685 * 3686 * // Or when creating the component 3687 * var myComp = new MyComponent(player, { 3688 * children: [ 3689 * 'myChildComponent' 3690 * ], 3691 * myChildComponent: { 3692 * myChildOption: true 3693 * } 3694 * }); 3695 * ``` 3696 * The children option can also be an array of 3697 * child options objects (that also include a 'name' key). 3698 * This can be used if you have two child components of the 3699 * same type that need different options. 3700 * ```js 3701 * var myComp = new MyComponent(player, { 3702 * children: [ 3703 * 'button', 3704 * { 3705 * name: 'button', 3706 * someOtherOption: true 3707 * }, 3708 * { 3709 * name: 'button', 3710 * someOtherOption: false 3711 * } 3712 * ] 3713 * }); 3714 * ``` 3715 * 3716 * @method initChildren 3717 */ 3718 3719 Component.prototype.initChildren = function initChildren() { 3720 var _this = this; 3721 3722 var children = this.options_.children; 3723 3724 if (children) { 3725 (function () { 3726 // `this` is `parent` 3727 var parentOptions = _this.options_; 3728 3729 var handleAdd = function handleAdd(child) { 3730 var name = child.name; 3731 var opts = child.opts; 3732 3733 // Allow options for children to be set at the parent options 3734 // e.g. videojs(id, { controlBar: false }); 3735 // instead of videojs(id, { children: { controlBar: false }); 3736 if (parentOptions[name] !== undefined) { 3737 opts = parentOptions[name]; 3738 } 3739 3740 // Allow for disabling default components 3741 // e.g. options['children']['posterImage'] = false 3742 if (opts === false) { 3743 return; 3744 } 3745 3746 // Allow options to be passed as a simple boolean if no configuration 3747 // is necessary. 3748 if (opts === true) { 3749 opts = {}; 3750 } 3751 3752 // We also want to pass the original player options to each component as well so they don't need to 3753 // reach back into the player for options later. 3754 opts.playerOptions = _this.options_.playerOptions; 3755 3756 // Create and add the child component. 3757 // Add a direct reference to the child by name on the parent instance. 3758 // If two of the same component are used, different names should be supplied 3759 // for each 3760 var newChild = _this.addChild(name, opts); 3761 if (newChild) { 3762 _this[name] = newChild; 3763 } 3764 }; 3765 3766 // Allow for an array of children details to passed in the options 3767 var workingChildren = undefined; 3768 var Tech = Component.getComponent('Tech'); 3769 3770 if (Array.isArray(children)) { 3771 workingChildren = children; 3772 } else { 3773 workingChildren = Object.keys(children); 3774 } 3775 3776 workingChildren 3777 // children that are in this.options_ but also in workingChildren would 3778 // give us extra children we do not want. So, we want to filter them out. 3779 .concat(Object.keys(_this.options_).filter(function (child) { 3780 return !workingChildren.some(function (wchild) { 3781 if (typeof wchild === 'string') { 3782 return child === wchild; 3783 } else { 3784 return child === wchild.name; 3785 } 3786 }); 3787 })).map(function (child) { 3788 var name = undefined, 3789 opts = undefined; 3790 3791 if (typeof child === 'string') { 3792 name = child; 3793 opts = children[name] || _this.options_[name] || {}; 3794 } else { 3795 name = child.name; 3796 opts = child; 3797 } 3798 3799 return { name: name, opts: opts }; 3800 }).filter(function (child) { 3801 // we have to make sure that child.name isn't in the techOrder since 3802 // techs are registerd as Components but can't aren't compatible 3803 // See https://github.com/videojs/video.js/issues/2772 3804 var c = Component.getComponent(child.opts.componentClass || _utilsToTitleCaseJs2['default'](child.name)); 3805 return c && !Tech.isTech(c); 3806 }
3806).forEach(handleAdd); 3807 })(); 3808 } 3809 }; 3810 3811 /** 3812 * Allows sub components to stack CSS class names 3813 * 3814 * @return {String} The constructed class name 3815 * @method buildCSSClass 3816 */ 3817 3818 Component.prototype.buildCSSClass = function buildCSSClass() { 3819 // Child classes can include a function that does: 3820 // return 'CLASS NAME' + this._super(); 3821 return ''; 3822 }; 3823 3824 /** 3825 * Add an event listener to this component's element 3826 * ```js 3827 * var myFunc = function(){ 3828 * var myComponent = this; 3829 * // Do something when the event is fired 3830 * }; 3831 * 3832 * myComponent.on('eventType', myFunc); 3833 * ``` 3834 * The context of myFunc will be myComponent unless previously bound. 3835 * Alternatively, you can add a listener to another element or component. 3836 * ```js 3837 * myComponent.on(otherElement, 'eventName', myFunc); 3838 * myComponent.on(otherComponent, 'eventName', myFunc); 3839 * ``` 3840 * The benefit of using this over `VjsEvents.on(otherElement, 'eventName', myFunc)` 3841 * and `otherComponent.on('eventName', myFunc)` is that this way the listeners 3842 * will be automatically cleaned up when either component is disposed. 3843 * It will also bind myComponent as the context of myFunc. 3844 * **NOTE**: When using this on elements in the page other than window 3845 * and document (both permanent), if you remove the element from the DOM 3846 * you need to call `myComponent.trigger(el, 'dispose')` on it to clean up 3847 * references to it and allow the browser to garbage collect it. 3848 * 3849 * @param {String|Component} first The event type or other component 3850 * @param {Function|String} second The event handler or event type 3851 * @param {Function} third The event handler 3852 * @return {Component} 3853 * @method on 3854 */ 3855 3856 Component.prototype.on = function on(first, second, third) { 3857 var _this2 = this; 3858 3859 if (typeof first === 'string' || Array.isArray(first)) { 3860 Events.on(this.el_, first, Fn.bind(this, second)); 3861 3862 // Targeting another component or element 3863 } else { 3864 (function () { 3865 var target = first; 3866 var type = second; 3867 var fn = Fn.bind(_this2, third); 3868 3869 // When this component is disposed, remove the listener from the other component 3870 var removeOnDispose = function removeOnDispose() { 3871 return _this2.off(target, type, fn); 3872 }; 3873 3874 // Use the same function ID so we can remove it later it using the ID 3875 // of the original listener 3876 removeOnDispose.guid = fn.guid; 3877 _this2.on('dispose', removeOnDispose); 3878 3879 // If the other component is disposed first we need to clean the reference 3880 // to the other component in this component's removeOnDispose listener 3881 // Otherwise we create a memory leak. 3882 var cleanRemover = function cleanRemover() { 3883 return _this2.off('dispose', removeOnDispose); 3884 }; 3885 3886 // Add the same function ID so we can easily remove it later 3887 cleanRemover.guid = fn.guid; 3888 3889 // Check if this is a DOM node 3890 if (first.nodeName) { 3891 // Add the listener to the other element 3892 Events.on(target, type, fn); 3893 Events.on(target, 'dispose', cleanRemover); 3894 3895 // Should be a component 3896 // Not using `instanceof Component` because it makes mock players difficult 3897 } else if (typeof first.on === 'function') { 3898 // Add the listener to the other component 3899 target.on(type, fn); 3900 target.on('dispose', cleanRemover); 3901 } 3902 })(); 3903 } 3904 3905 return this; 3906 }; 3907 3908 /** 3909 * Remove an event listener from this component's element 3910 * ```js 3911 * myComponent.off('eventType', myFunc); 3912 * ``` 3913 * If myFunc is excluded, ALL listeners for the event type will be removed. 3914 * If eventType is excluded, ALL listeners will be removed from the component. 3915 * Alternatively you can use `off` to remove listeners that were added to other 3916 * elements or components using `myComponent.on(otherComponent...`. 3917 * In this case both the event type and listener function are REQUIRED. 3918 * ```js 3919 * myComponent.off(otherElement, 'eventType', myFunc); 3920 * myComponent.off(otherComponent, 'eventType', myFunc); 3921 * ``` 3922 * 3923 * @param {String=|Component} first The event type or other component 3924 * @param {Function=|String} second The listener function or event type 3925 * @param {Function=} third The listener for other component 3926 * @return {Component} 3927 * @method off 3928 */ 3929 3930 Component.prototype.off = function off(first, second, third) { 3931 if (!first || typeof first === 'string' || Array.isArray(first)) { 3932 Events.off(this.el_, first, second); 3933 } else { 3934 var target = first; 3935 var type = second; 3936 // Ensure there's at least a guid, even if the function hasn't been used 3937 var fn = Fn.bind(this, third); 3938 3939 // Remove the dispose listener on this component, 3940 // which was given the same guid as the event listener 3941 this.off('dispose', fn); 3942 3943 if (first.nodeName) { 3944 // Remove the listener 3945 Events.off(target, type, fn); 3946 // Remove the listener for cleaning the dispose listener 3947 Events.off(target, 'dispose', fn); 3948 } else {
3949 target.off(type, fn); 3950 target.off('dispose', fn); 3951 } 3952 } 3953 3954 return this; 3955 }; 3956 3957 /** 3958 * Add an event listener to be triggered only once and then removed 3959 * ```js 3960 * myComponent.one('eventName', myFunc); 3961 * ``` 3962 * Alternatively you can add a listener to another element or component 3963 * that will be triggered only once. 3964 * ```js 3965 * myComponent.one(otherElement, 'eventName', myFunc); 3966 * myComponent.one(otherComponent, 'eventName', myFunc); 3967 * ``` 3968 * 3969 * @param {String|Component} first The event type or other component 3970 * @param {Function|String} second The listener function or event type 3971 * @param {Function=} third The listener function for other component 3972 * @return {Component} 3973 * @method one 3974 */ 3975 3976 Component.prototype.one = function one(first, second, third) { 3977 var _this3 = this, 3978 _arguments = arguments; 3979 3980 if (typeof first === 'string' || Array.isArray(first)) { 3981 Events.one(this.el_, first, Fn.bind(this, second)); 3982 } else { 3983 (function () { 3984 var target = first; 3985 var type = second; 3986 var fn = Fn.bind(_this3, third); 3987 3988 var newFunc = function newFunc() { 3989 _this3.off(target, type, newFunc); 3990 fn.apply(null, _arguments); 3991 }; 3992 3993 // Keep the same function ID so we can remove it later 3994 newFunc.guid = fn.guid; 3995 3996 _this3.on(target, type, newFunc); 3997 })(); 3998 } 3999 4000 return this; 4001 }; 4002 4003 /** 4004 * Trigger an event on an element 4005 * ```js 4006 * myComponent.trigger('eventName'); 4007 * myComponent.trigger({'type':'eventName'}); 4008 * myComponent.trigger('eventName', {data: 'some data'}); 4009 * myComponent.trigger({'type':'eventName'}, {data: 'some data'}); 4010 * ``` 4011 * 4012 * @param {Event|Object|String} event A string (the type) or an event object with a type attribute 4013 * @param {Object} [hash] data hash to pass along with the event 4014 * @return {Component} self 4015 * @method trigger 4016 */ 4017 4018 Component.prototype.trigger = function trigger(event, hash) { 4019 Events.trigger(this.el_, event, hash); 4020 return this; 4021 }; 4022 4023 /** 4024 * Bind a listener to the component's ready state. 4025 * Different from event listeners in that if the ready event has already happened 4026 * it will trigger the function immediately. 4027 * 4028 * @param {Function} fn Ready listener 4029 * @param {Boolean} sync Exec the listener synchronously if component is ready 4030 * @return {Component} 4031 * @method ready 4032 */ 4033 4034 Component.prototype.ready = function ready(fn) { 4035 var sync = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; 4036 4037 if (fn) { 4038 if (this.isReady_) { 4039 if (sync) { 4040 fn.call(this); 4041 } else { 4042 // Call the function asynchronously by default for consistency 4043 this.setTimeout(fn, 1); 4044 } 4045 } else { 4046 this.readyQueue_ = this.readyQueue_ || []; 4047 this.readyQueue_.push(fn); 4048 } 4049 } 4050 return this; 4051 }; 4052 4053 /** 4054 * Trigger the ready listeners 4055 * 4056 * @return {Component} 4057 * @method triggerReady 4058 */ 4059 4060 Component.prototype.triggerReady = function triggerReady() { 4061 this.isReady_ = true; 4062 4063 // Ensure ready is triggerd asynchronously 4064 this.setTimeout(function () { 4065 var readyQueue = this.readyQueue_; 4066 4067 // Reset Ready Queue 4068 this.readyQueue_ = []; 4069 4070 if (readyQueue && readyQueue.length > 0) { 4071 readyQueue.forEach(function (fn) { 4072 fn.call(this); 4073 }, this); 4074 } 4075 4076 // Allow for using event listeners also 4077 this.trigger('ready'); 4078 }, 1); 4079 }; 4080 4081 /** 4082 * Finds a single DOM element matching `selector` within the component's 4083 * `contentEl` or another custom context. 4084 * 4085 * @method $ 4086 * @param {String} selector 4087 * A valid CSS selector, which will be passed to `querySelector`. 4088 * 4089 * @param {Element|String} [context=document] 4090 * A DOM element within which to query. Can also be a selector 4091 * string in which case the first matching element will be used 4092 * as context. If missing (or no element matches selector), falls 4093 * back to `document`. 4094 * 4095 * @return {Element|null} 4096 */ 4097 4098 Component.prototype.$ = function $(selector, context) { 4099 return Dom.$(selector, context || this.contentEl()); 4100 }; 4101 4102 /** 4103 * Finds a all DOM elements matching `selector` within the component's 4104 * `contentEl` or another custom context. 4105 * 4106 * @method $$ 4107 * @param {String} selector 4108 * A valid CSS selector, which will be passed to `querySelectorAll`. 4109 * 4110 * @param {Element|String} [context=document] 4111 * A DOM element within which to query. Can also be a selector
4112 * string in which case the first matching element will be used 4113 * as context. If missing (or no element matches selector), falls 4114 * back to `document`. 4115 * 4116 * @return {NodeList} 4117 */ 4118 4119 Component.prototype.$$ = function $$(selector, context) { 4120 return Dom.$$(selector, context || this.contentEl()); 4121 }; 4122 4123 /** 4124 * Check if a component's element has a CSS class name 4125 * 4126 * @param {String} classToCheck Classname to check 4127 * @return {Component} 4128 * @method hasClass 4129 */ 4130 4131 Component.prototype.hasClass = function hasClass(classToCheck) { 4132 return Dom.hasElClass(this.el_, classToCheck); 4133 }; 4134 4135 /** 4136 * Add a CSS class name to the component's element 4137 * 4138 * @param {String} classToAdd Classname to add 4139 * @return {Component} 4140 * @method addClass 4141 */ 4142 4143 Component.prototype.addClass = function addClass(classToAdd) { 4144 Dom.addElClass(this.el_, classToAdd); 4145 return this; 4146 }; 4147 4148 /** 4149 * Remove a CSS class name from the component's element 4150 * 4151 * @param {String} classToRemove Classname to remove 4152 * @return {Component} 4153 * @method removeClass 4154 */ 4155 4156 Component.prototype.removeClass = function removeClass(classToRemove) { 4157 Dom.removeElClass(this.el_, classToRemove); 4158 return this; 4159 }; 4160 4161 /** 4162 * Add or remove a CSS class name from the component's element 4163 * 4164 * @param {String} classToToggle 4165 * @param {Boolean|Function} [predicate] 4166 * Can be a function that returns a Boolean. If `true`, the class 4167 * will be added; if `false`, the class will be removed. If not 4168 * given, the class will be added if not present and vice versa. 4169 * 4170 * @return {Component} 4171 * @method toggleClass 4172 */ 4173 4174 Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) { 4175 Dom.toggleElClass(this.el_, classToToggle, predicate); 4176 return this; 4177 }; 4178 4179 /** 4180 * Show the component element if hidden 4181 * 4182 * @return {Component} 4183 * @method show 4184 */ 4185 4186 Component.prototype.show = function show() { 4187 this.removeClass('vjs-hidden'); 4188 return this; 4189 }; 4190 4191 /** 4192 * Hide the component element if currently showing 4193 * 4194 * @return {Component} 4195 * @method hide 4196 */ 4197 4198 Component.prototype.hide = function hide() { 4199 this.addClass('vjs-hidden'); 4200 return this; 4201 }; 4202 4203 /** 4204 * Lock an item in its visible state 4205 * To be used with fadeIn/fadeOut. 4206 * 4207 * @return {Component} 4208 * @private 4209 * @method lockShowing 4210 */ 4211 4212 Component.prototype.lockShowing = function lockShowing() { 4213 this.addClass('vjs-lock-showing'); 4214 return this; 4215 }; 4216 4217 /** 4218 * Unlock an item to be hidden 4219 * To be used with fadeIn/fadeOut. 4220 * 4221 * @return {Component} 4222 * @private 4223 * @method unlockShowing 4224 */ 4225 4226 Component.prototype.unlockShowing = function unlockShowing() { 4227 this.removeClass('vjs-lock-showing'); 4228 return this; 4229 }; 4230 4231 /** 4232 * Set or get the width of the component (CSS values)
4233 * Setting the video tag dimension values only works with values in pixels. 4234 * Percent values will not work. 4235 * Some percents can be used, but width()/height() will return the number + %, 4236 * not the actual computed width/height. 4237 * 4238 * @param {Number|String=} num Optional width number 4239 * @param {Boolean} skipListeners Skip the 'resize' event trigger 4240 * @return {Component} This component, when setting the width 4241 * @return {Number|String} The width, when getting 4242 * @method width 4243 */ 4244 4245 Component.prototype.width = function width(num, skipListeners) { 4246 return this.dimension('width', num, skipListeners); 4247 }; 4248 4249 /** 4250 * Get or set the height of the component (CSS values) 4251 * Setting the video tag dimension values only works with values in pixels. 4252 * Percent values will not work. 4253 * Some percents can be used, but width()/height() will return the number + %, 4254 * not the actual computed width/height. 4255 * 4256 * @param {Number|String=} num New component height 4257 * @param {Boolean=} skipListeners Skip the resize event trigger 4258 * @return {Component} This component, when setting the height 4259 * @return {Number|String} The height, when getting 4260 * @method height 4261 */ 4262 4263 Component.prototype.height = function height(num, skipListeners) { 4264 return this.dimension('height', num, skipListeners); 4265 }; 4266 4267 /** 4268 * Set both width and height at the same time 4269 * 4270 * @param {Number|String} width Width of player 4271 * @param {Number|String} height Height of player 4272 * @return {Component} The component 4273 * @method dimensions 4274 */ 4275 4276 Component.prototype.dimensions = function dimensions(width, height) { 4277 // Skip resize listeners on width for optimization 4278 return this.width(width, true).height(height); 4279 }; 4280 4281 /** 4282 * Get or set width or height 4283 * This is the shared code for the width() and height() methods. 4284 * All for an integer, integer + 'px' or integer + '%'; 4285 * Known issue: Hidden elements officially have a width of 0. We're defaulting 4286 * to the style.width value and falling back to computedStyle which has the 4287 * hidden element issue. Info, but probably not an efficient fix: 4288 * http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/ 4289 * 4290 * @param {String} widthOrHeight 'width' or 'height' 4291 * @param {Number|String=} num New dimension 4292 * @param {Boolean=} skipListeners Skip resize event trigger 4293 * @return {Component} The component if a dimension was set 4294 * @return {Number|String} The dimension if nothing was set 4295 * @private 4296 * @method dimension 4297 */ 4298 4299 Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) { 4300 if (num !== undefined) { 4301 // Set to zero if null or literally NaN (NaN !== NaN) 4302 if (num === null || num !== num) { 4303 num = 0; 4304 } 4305 4306 // Check if using css width/height (% or px) and adjust 4307 if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) { 4308 this.el_.style[widthOrHeight] = num; 4309 } else if (num === 'auto') { 4310 this.el_.style[widthOrHeight] = ''; 4311 } else { 4312 this.el_.style[widthOrHeight] = num + 'px'; 4313 } 4314 4315 // skipListeners allows us to avoid triggering the resize event when setting both width and height 4316 if (!skipListeners) { 4317 this.trigger('resize'); 4318 } 4319 4320 // Return component 4321 return this; 4322 } 4323 4324 // Not setting a value, so getting it 4325 // Make sure element exists 4326 if (!this.el_) { 4327 return 0; 4328 } 4329 4330 // Get dimension value from style 4331 var val = this.el_.style[widthOrHeight]; 4332 var pxIndex = val.indexOf('px'); 4333 4334 if (pxIndex !== -1) { 4335 // Return the pixel value with no 'px' 4336 return parseInt(val.slice(0, pxIndex), 10); 4337 } 4338 4339 // No px so using % or no style was set, so falling back to offsetWidth/height 4340 // If component has display:none, offset will return 0 4341 // TODO: handle display:none and no dimension style using px 4342 return parseInt(this.el_['offset' + _utilsToTitleCaseJs2['default'](widthOrHeight)], 10); 4343 }; 4344 4345 /** 4346 * Get width or height of computed style 4347 * @param {String} widthOrHeight 'width' or 'height' 4348 * @return {Number|Boolean} The bolean false if nothing was set 4349 * @method currentDimension 4350 */ 4351 4352 Component.prototype.currentDimension = function currentDimension(widthOrHeight) { 4353 var computedWidthOrHeight = 0; 4354 4355 if (widthOrHeight !== 'width' && widthOrHeight !== 'height') { 4356 throw new Error('currentDimension only accepts width or height value'); 4357 } 4358 4359 if (typeof _globalWindow2['default'].getComputedStyle === 'function') { 4360 var computedStyle = _globalWindow2['default'].getComputedStyle(this.el_); 4361 computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight]; 4362 } else if (this.el_.currentStyle) { 4363 // ie 8 doesn't support computed style, shim it 4364 // return clientWidth or clientHeight instead for better accuracy 4365 var rule = 'offset' + _utilsToTitleCaseJs2['default'](widthOrHeight); 4366 computedWidthOrHeight = this.el_[rule]; 4367 } 4368 4369 // remove 'px' from variable and parse as integer 4370 computedWidthOrHeight = parseFloat(computedWidthOrHeight); 4371 return computedWidthOrHeight; 4372 }; 4373 4374 /** 4375 * Get an object which contains width and height values of computed style 4376 * @return {Object} The dimensions of element 4377 * @method currentDimensions 4378 */ 4379 4380 Component.prototype.currentDimensions = function currentDimensions() { 4381 return { 4382 width: this.currentDimension('width'), 4383 height: this.currentDimension('height') 4384 }; 4385 }; 4386 4387 /** 4388 * Get width of computed style 4389 * @return {Integer} 4390 * @method currentWidth 4391 */ 4392 4393 Component.prototype.currentWidth = function currentWidth() { 4394 return this.currentDimension('width'); 4395 }; 4396 4397 /** 4398 * Get height of computed style 4399 * @return {Integer} 4400 * @method currentHeight 4401 */ 4402 4403 Component.prototype.currentHeight = function currentHeight() { 4404 return this.currentDimension('height'); 4405 }; 4406 4407 /** 4408 * Emit 'tap' events when touch events are supported 4409 * This is used to support toggling the controls through a tap on the video. 4410 * We're requiring them to be enabled because otherwise every component would 4411 * have this extra overhead unnecessarily, on mobile devices where extra 4412 * overhead is especially bad. 4413 * 4414 * @private 4415 * @method emitTapEvents 4416 */ 4417 4418 Component.prototype.emitTapEvents = function emitTapEvents() { 4419 // Track the start time so we can determine how long the touch lasted 4420 var touchStart = 0; 4421 var firstTouch = null; 4422 4423 // Maximum movement allowed during a touch event to still be considered a tap 4424 // Other popular libs use anywhere from 2 (hammer.js) to 15, so 10 seems like a nice, round number. 4425 var tapMovementThreshold = 10; 4426 4427 // The maximum length a touch can be while still being considered a tap 4428 var touchTimeThreshold = 200; 4429 4430 var couldBeTap = undefined; 4431 4432 this.on('touchstart', function (event) { 4433 // If more than one finger, don't consider treating this as a click 4434 if (event.touches.length === 1) { 4435 // Copy the touches object to prevent modifying the original 4436 firstTouch = _objectAssign2['default']({}, event.touches[0]); 4437 // Record start time so we can detect a tap vs. "touch and hold" 4438 touchStart = new Date().getTime(); 4439 // Reset couldBeTap tracking 4440 couldBeTap = true; 4441 } 4442 }); 4443 4444 this.on('touchmove', function (event) { 4445 // If more than one finger, don't consider treating this as a click 4446 if (event.touches.length > 1) { 4447 couldBeTap = false;
vendor: 4,486 bytes, lines 4448-4557
4448 } else if (firstTouch) { 4449 // Some devices will throw touchmoves for all but the slightest of taps. 4450 // So, if we moved only a small distance, this could still be a tap 4451 var xdiff = event.touches[0].pageX - firstTouch.pageX; 4452 var ydiff = event.touches[0].pageY - firstTouch.pageY; 4453 var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff); 4454 4455 if (touchDistance > tapMovementThreshold) { 4456 couldBeTap = false; 4457 } 4458 } 4459 }); 4460 4461 var noTap = function noTap() { 4462 couldBeTap = false; 4463 }; 4464 4465 // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s 4466 this.on('touchleave', noTap); 4467 this.on('touchcancel', noTap); 4468 4469 // When the touch ends, measure how long it took and trigger the appropriate 4470 // event 4471 this.on('touchend', function (event) { 4472 firstTouch = null; 4473 // Proceed only if the touchmove/leave/cancel event didn't happen 4474 if (couldBeTap === true) { 4475 // Measure how long the touch lasted 4476 var touchTime = new Date().getTime() - touchStart; 4477 4478 // Make sure the touch was less than the threshold to be considered a tap 4479 if (touchTime < touchTimeThreshold) { 4480 // Don't let browser turn this into a click 4481 event.preventDefault(); 4482 this.trigger('tap'); 4483 // It may be good to copy the touchend event object and change the 4484 // type to tap, if the other event properties aren't exact after 4485 // Events.fixEvent runs (e.g. event.target) 4486 } 4487 } 4488 }); 4489 }; 4490 4491 /** 4492 * Report user touch activity when touch events occur 4493 * User activity is used to determine when controls should show/hide. It's 4494 * relatively simple when it comes to mouse events, because any mouse event 4495 * should show the controls. So we capture mouse events that bubble up to the 4496 * player and report activity when that happens. 4497 * With touch events it isn't as easy. We can't rely on touch events at the 4498 * player level, because a tap (touchstart + touchend) on the video itself on 4499 * mobile devices is meant to turn controls off (and on). User activity is 4500 * checked asynchronously, so what could happen is a tap event on the video 4501 * turns the controls off, then the touchend event bubbles up to the player, 4502 * which if it reported user activity, would turn the controls right back on. 4503 * (We also don't want to completely block touch events from bubbling up) 4504 * Also a touchmove, touch+hold, and anything other than a tap is not supposed 4505 * to turn the controls back on on a mobile device. 4506 * Here we're setting the default component behavior to report user activity 4507 * whenever touch events happen, and this can be turned off by components that 4508 * want touch events to act differently. 4509 * 4510 * @method enableTouchActivity 4511 */ 4512 4513 Component.prototype.enableTouchActivity = function enableTouchActivity() { 4514 // Don't continue if the root player doesn't support reporting user activity 4515 if (!this.player() || !this.player().reportUserActivity) { 4516 return; 4517 } 4518 4519 // listener for reporting that the user is active 4520 var report = Fn.bind(this.player(), this.player().reportUserActivity); 4521 4522 var touchHolding = undefined; 4523 4524 this.on('touchstart', function () { 4525 report(); 4526 // For as long as the they are touching the device or have their mouse down, 4527 // we consider them active even if they're not moving their finger or mouse. 4528 // So we want to continue to update that they are active 4529 this.clearInterval(touchHolding); 4530 // report at the same interval as activityCheck 4531 touchHolding = this.setInterval(report, 250); 4532 }); 4533 4534 var touchEnd = function touchEnd(event) { 4535 report(); 4536 // stop the interval that maintains activity if the touch is holding 4537 this.clearInterval(touchHolding); 4538 }; 4539 4540 this.on('touchmove', report); 4541 this.on('touchend', touchEnd); 4542 this.on('touchcancel', touchEnd); 4543 }; 4544 4545 /** 4546 * Creates timeout and sets up disposal automatically. 4547 * 4548 * @param {Function} fn The function to run after the timeout. 4549 * @param {Number} timeout Number of ms to delay before executing specified function. 4550 * @return {Number} Returns the timeout ID 4551 * @method setTimeout 4552 */ 4553 4554 Component.prototype.setTimeout = function setTimeout(fn, timeout) { 4555 fn = Fn.bind(this, fn); 4556 4557 // window.setTimeout would be preferable here, but due to some bizarre issue with Sinon and/
4557or Phantomjs, we can't. 4558 var timeoutId = _globalWindow2['default'].setTimeout(fn, timeout); 4559 4560 var disposeFn = function disposeFn() { 4561 this.clearTimeout(timeoutId); 4562 }; 4563 4564 disposeFn.guid = 'vjs-timeout-' + timeoutId; 4565 4566 this.on('dispose', disposeFn); 4567 4568 return timeoutId; 4569 }; 4570 4571 /** 4572 * Clears a timeout and removes the associated dispose listener 4573 * 4574 * @param {Number} timeoutId The id of the timeout to clear 4575 * @return {Number} Returns the timeout ID 4576 * @method clearTimeout 4577 */ 4578 4579 Component.prototype.clearTimeout = function clearTimeout(timeoutId) { 4580 _globalWindow2['default'].clearTimeout(timeoutId); 4581 4582 var disposeFn = function disposeFn() {}; 4583 4584 disposeFn.guid = 'vjs-timeout-' + timeoutId; 4585 4586 this.off('dispose', disposeFn); 4587 4588 return timeoutId; 4589 }; 4590 4591 /** 4592 * Creates an interval and sets up disposal automatically. 4593 * 4594 * @param {Function} fn The function to run every N seconds. 4595 * @param {Number} interval Number of ms to delay before executing specified function. 4596 * @return {Number} Returns the interval ID 4597 * @method setInterval 4598 */ 4599 4600 Component.prototype.setInterval = function setInterval(fn, interval) { 4601 fn = Fn.bind(this, fn); 4602 4603 var intervalId = _globalWindow2['default'].setInterval(fn, interval); 4604 4605 var disposeFn = function disposeFn() { 4606 this.clearInterval(intervalId); 4607 }; 4608 4609 disposeFn.guid = 'vjs-interval-' + intervalId; 4610 4611 this.on('dispose', disposeFn); 4612 4613 return intervalId; 4614 }; 4615 4616 /** 4617 * Clears an interval and removes the associated dispose listener 4618 * 4619 * @param {Number} intervalId The id of the interval to clear 4620 * @return {Number} Returns the interval ID 4621 * @method clearInterval 4622 */ 4623 4624 Component.prototype.clearInterval = function clearInterval(intervalId) { 4625 _globalWindow2['default'].clearInterval(intervalId); 4626 4627 var disposeFn = function disposeFn() {}; 4628 4629 disposeFn.guid = 'vjs-interval-' + intervalId; 4630 4631 this.off('dispose', disposeFn); 4632 4633 return intervalId; 4634 }; 4635 4636 /** 4637 * Registers a component 4638 * 4639 * @param {String} name Name of the component to register 4640 * @param {Object} comp The component to register 4641 * @static 4642 * @method registerComponent 4643 */ 4644 4645 Component.registerComponent = function registerComponent(name, comp) { 4646 if (!Component.components_) { 4647 Component.components_ = {}; 4648 } 4649 4650 Component.components_[name] = comp; 4651 return comp; 4652 }; 4653 4654 /** 4655 * Gets a component by name 4656 * 4657 * @param {String} name Name of the component to get 4658 * @return {Component} 4659 * @static 4660 * @method getComponent 4661 */ 4662 4663 Component.getComponent = function getComponent(name) { 4664 if (Component.components_ && Component.components_[name]) { 4665 return Component.components_[name]; 4666 } 4667 4668 if (_globalWindow2['default'] && _globalWindow2['default'].videojs && _globalWindow2['default'].videojs[name]) { 4669 _utilsLogJs2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)'); 4670 return _globalWindow2['default'].videojs[name]; 4671 } 4672 }; 4673 4674 /** 4675 * Sets up the constructor using the supplied init method 4676 * or uses the init of the parent object 4677 * 4678 * @param {Object} props An object of properties 4679 * @static 4680 * @deprecated 4681 * @method extend 4682 */ 4683 4684 Component.extend = function extend(props) { 4685 props = props || {}; 4686 4687 _utilsLogJs2['default'].warn('Component.extend({}) has been deprecated, use videojs.extend(Component, {}) instead'); 4688 4689 // Set up the constructor using the supplied init method 4690 // or using the init of the parent object 4691 // Make sure to check the unobfuscated version for external libs 4692 var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {}; 4693 // In Resig's simple class inheritance (previously used) the constructor 4694 // is a function that calls `this.init.apply(arguments)` 4695 // However that would prevent us from using `ParentObject.call(this);` 4696 // in a Child constructor because the `this` in `this.init` 4697 // would still refer to the Child and cause an infinite loop. 4698 // We would instead have to do
4699 // `ParentObject.prototype.init.apply(this, arguments);` 4700 // Bleh. We're not creating a _super() function, so it's good to keep 4701 // the parent constructor reference simple. 4702 var subObj = function subObj() { 4703 init.apply(this, arguments); 4704 }; 4705 4706 // Inherit from this object's prototype 4707 subObj.prototype = Object.create(this.prototype); 4708 // Reset the constructor property for subObj otherwise 4709 // instances of subObj would have the constructor of the parent Object 4710 subObj.prototype.constructor = subObj; 4711 4712 // Make the class extendable 4713 subObj.extend = Component.extend; 4714 4715 // Extend subObj's prototype with functions and other properties from props 4716 for (var _name in props) { 4717 if (props.hasOwnProperty(_name)) { 4718 subObj.prototype[_name] = props[_name]; 4719 } 4720 } 4721 4722 return subObj; 4723 }; 4724 4725 return Component; 4726})(); 4727 4728Component.registerComponent('Component', Component); 4729exports['default'] = Component; 4730module.exports = exports['default']; 4731 4732},{"./utils/dom.js":143,"./utils/events.js":144,"./utils/fn.js":145,"./utils/guid.js":147,"./utils/log.js":148,"./utils/merge-options.js":149,"./utils/to-title-case.js":152,"global/window":2,"object.assign":45}],68:[function(_dereq_,module,exports){ 4733/** 4734 * @file audio-track-button.js 4735 */ 4736'use strict'; 4737 4738exports.__esModule = true; 4739 4740function _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; } } 4741 4742function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4743 4744function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 4745 4746function _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; } 4747 4748var _trackButtonJs = _dereq_('../track-button.js'); 4749 4750var _trackButtonJs2 = _interopRequireDefault(_trackButtonJs); 4751 4752var _componentJs = _dereq_('../../component.js'); 4753 4754var _componentJs2 = _interopRequireDefault(_componentJs); 4755 4756var _utilsFnJs = _dereq_('../../utils/fn.js'); 4757 4758var Fn = _interopRequireWildcard(_utilsFnJs); 4759 4760var _audioTrackMenuItemJs = _dereq_('./audio-track-menu-item.js'); 4761 4762var _audioTrackMenuItemJs2 = _interopRequireDefault(_audioTrackMenuItemJs); 4763 4764/** 4765 * The base class for buttons that toggle specific text track types (e.g. subtitles) 4766 * 4767 * @param {Player|Object} player 4768 * @param {Object=} options 4769 * @extends TrackButton 4770 * @class AudioTrackButton 4771 */ 4772 4773var AudioTrackButton = (function (_TrackButton) { 4774 _inherits(AudioTrackButton, _TrackButton); 4775 4776 function AudioTrackButton(player) { 4777 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 4778 4779 _classCallCheck(this, AudioTrackButton); 4780 4781 options.tracks = player.audioTracks && player.audioTracks(); 4782 4783 _TrackButton.call(this, player, options); 4784 4785 this.el_.setAttribute('aria-label', 'Audio Menu'); 4786 } 4787 4788 /** 4789 * Allow sub components to stack CSS class names 4790 * 4791 * @return {String} The constructed class name 4792 * @method buildCSSClass 4793 */ 4794 4795 AudioTrackButton.prototype.buildCSSClass = function buildCSSClass() { 4796 return 'vjs-audio-button ' + _TrackButton.prototype.buildCSSClass.call(this); 4797 }; 4798 4799 /** 4800 * Create a menu item for each audio track 4801 * 4802 * @return {Array} Array of menu items 4803 * @method createItems 4804 */ 4805 4806 AudioTrackButton.prototype.createItems = function createItems() { 4807 var items = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; 4808 4809 var tracks = this.player_.audioTracks && this.player_.audioTracks(); 4810 4811 if (!tracks) { 4812 return items; 4813 } 4814 4815 for (var i = 0; i < tracks.length; i++) { 4816 var track = tracks[i]; 4817 4818 items.push(new _audioTrackMenuItemJs2['default'](this.player_, { 4819 // MenuItem is selectable 4820 'selectable': true, 4821 'track': track 4822 })); 4823 } 4824 4825 return items; 4826 }; 4827 4828 return AudioTrackButton; 4829})(_trackButtonJs2['default']); 4830 4831_componentJs2['default'].registerComponent('AudioTrackButton', AudioTrackButton); 4832exports['default'] = AudioTrackButton; 4833module.exports = exports['default']; 4834 4835},{"../../component.js":67,"../../utils/fn.js":145,"../track-button.js":98,"./audio-track-menu-item.js":69}],69:[function(_dereq_,module,exports){ 4836/** 4837 * @file audio-track-menu-item.js 4838 */ 4839'use strict'; 4840 4841exports.__esModule = true; 4842 4843function _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; } } 4844 4845function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4846 4847function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 4848 4849function _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
4849onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 4850 4851var _menuMenuItemJs = _dereq_('../../menu/menu-item.js'); 4852 4853var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs); 4854 4855var _componentJs = _dereq_('../../component.js'); 4856 4857var _componentJs2 = _interopRequireDefault(_componentJs); 4858 4859var _utilsFnJs = _dereq_('../../utils/fn.js'); 4860 4861var Fn = _interopRequireWildcard(_utilsFnJs); 4862 4863/** 4864 * The audio track menu item 4865 * 4866 * @param {Player|Object} player 4867 * @param {Object=} options 4868 * @extends MenuItem 4869 * @class AudioTrackMenuItem 4870 */ 4871 4872var AudioTrackMenuItem = (function (_MenuItem) { 4873 _inherits(AudioTrackMenuItem, _MenuItem); 4874 4875 function AudioTrackMenuItem(player, options) { 4876 var _this = this; 4877 4878 _classCallCheck(this, AudioTrackMenuItem); 4879 4880 var track = options.track; 4881 var tracks = player.audioTracks(); 4882 4883 // Modify options for parent MenuItem class's init. 4884 options.label = track.label || track.language || 'Unknown'; 4885 options.selected = track.enabled; 4886 4887 _MenuItem.call(this, player, options); 4888 4889 this.track = track; 4890 4891 if (tracks) { 4892 (function () { 4893 var changeHandler = Fn.bind(_this, _this.handleTracksChange); 4894 4895 tracks.addEventListener('change', changeHandler); 4896 _this.on('dispose', function () { 4897 tracks.removeEventListener('change', changeHandler); 4898 }); 4899 })(); 4900 } 4901 } 4902 4903 /** 4904 * Handle click on audio track 4905 * 4906 * @method handleClick 4907 */ 4908 4909 AudioTrackMenuItem.prototype.handleClick = function handleClick(event) { 4910 var tracks = this.player_.audioTracks(); 4911 4912 _MenuItem.prototype.handleClick.call(this, event); 4913 4914 if (!tracks) return; 4915 4916 for (var i = 0; i < tracks.length; i++) { 4917 var track = tracks[i]; 4918 4919 if (track === this.track) { 4920 track.enabled = true; 4921 } 4922 } 4923 }; 4924 4925 /** 4926 * Handle audio track change 4927 * 4928 * @method handleTracksChange 4929 */ 4930 4931 AudioTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { 4932 this.selected(this.track.enabled); 4933 }; 4934 4935 return AudioTrackMenuItem; 4936})(_menuMenuItemJs2['default']); 4937 4938_componentJs2['default'].registerComponent('AudioTrackMenuItem', AudioTrackMenuItem); 4939exports['default'] = AudioTrackMenuItem; 4940module.exports = exports['default']; 4941 4942},{"../../component.js":67,"../../menu/menu-item.js":110,"../../utils/fn.js":145}],70:[function(_dereq_,module,exports){ 4943/** 4944 * @file control-bar.js 4945 */ 4946'use strict'; 4947 4948exports.__esModule = true; 4949 4950function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4951 4952function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 4953 4954function _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; } 4955 4956var _componentJs = _dereq_('../component.js'); 4957 4958var _componentJs2 = _interopRequireDefault(_componentJs); 4959 4960// Required children 4961 4962var _playToggleJs = _dereq_('./play-toggle.js'); 4963 4964var _playToggleJs2 = _interopRequireDefault(_playToggleJs); 4965 4966var _timeControlsCurrentTimeDisplayJs = _dereq_('./time-controls/current-time-display.js'); 4967 4968var _timeControlsCurrentTimeDisplayJs2 = _interopRequireDefault(_timeControlsCurrentTimeDisplayJs); 4969 4970var _timeControlsDurationDisplayJs = _dereq_('./time-controls/duration-display.js'); 4971 4972var _timeControlsDurationDisplayJs2 = _interopRequireDefault(_timeControlsDurationDisplayJs); 4973 4974var _timeControlsTimeDividerJs = _dereq_('./time-controls/time-divider.js'); 4975 4976var _timeControlsTimeDividerJs2 = _interopRequireDefault(_timeControlsTimeDividerJs); 4977 4978var _timeControlsRemainingTimeDisplayJs = _dereq_('./time-control
4978s/remaining-time-display.js'); 4979 4980var _timeControlsRemainingTimeDisplayJs2 = _interopRequireDefault(_timeControlsRemainingTimeDisplayJs); 4981 4982var _liveDisplayJs = _dereq_('./live-display.js'); 4983 4984var _liveDisplayJs2 = _interopRequireDefault(_liveDisplayJs); 4985 4986var _progressControlProgressControlJs = _dereq_('./progress-control/progress-control.js'); 4987 4988var _progressControlProgressControlJs2 = _interopRequireDefault(_progressControlProgressControlJs); 4989 4990var _fullscreenToggleJs = _dereq_('./fullscreen-toggle.js'); 4991 4992var _fullscreenToggleJs2 = _interopRequireDefault(_fullscreenToggleJs); 4993 4994var _volumeControlVolumeControlJs = _dereq_('./volume-control/volume-control.js'); 4995 4996var _volumeControlVolumeControlJs2 = _interopRequireDefault(_volumeControlVolumeControlJs); 4997 4998var _volumeMenuButtonJs = _dereq_('./volume-menu-button.js'); 4999 5000var _volumeMenuButtonJs2 = _interopRequireDefault(_volumeMenuButtonJs); 5001 5002var _muteToggleJs = _dereq_('./mute-toggle.js'); 5003 5004var _muteToggleJs2 = _interopRequireDefault(_muteToggleJs); 5005 5006var _textTrackControlsChaptersButtonJs = _dereq_('./text-track-controls/chapters-button.js'); 5007 5008var _textTrackControlsChaptersButtonJs2 = _interopRequireDefault(_textTrackControlsChaptersButtonJs); 5009 5010var _textTrackControlsDescriptionsButtonJs = _dereq_('./text-track-controls/descriptions-button.js'); 5011 5012var _textTrackControlsDescriptionsButtonJs2 = _interopRequireDefault(_textTrackControlsDescriptionsButtonJs); 5013 5014var _textTrackControlsSubtitlesButtonJs = _dereq_('./text-track-controls/subtitles-button.js'); 5015 5016var _textTrackControlsSubtitlesButtonJs2 = _interopRequireDefault(_textTrackControlsSubtitlesButtonJs); 5017 5018var _textTrackControlsCaptionsButtonJs = _dereq_('./text-track-controls/captions-button.js'); 5019 5020var _textTrackControlsCaptionsButtonJs2 = _interopRequireDefault(_textTrackControlsCaptionsButtonJs); 5021 5022var _audioTrackControlsAudioTrackButtonJs = _dereq_('./audio-track-controls/audio-track-button.js'); 5023 5024var _audioTrackControlsAudioTrackButtonJs2 = _interopRequireDefault(_audioTrackControlsAudioTrackButtonJs); 5025 5026var _playbackRateMenuPlaybackRateMenuButtonJs = _dereq_('./playback-rate-menu/playback-rate-menu-button.js'); 5027 5028var _playbackRateMenuPlaybackRateMenuButtonJs2 = _interopRequireDefault(_playbackRateMenuPlaybackRateMenuButtonJs); 5029 5030var _spacerControlsCustomControlSpacerJs = _dereq_('./spacer-controls/custom-control-spacer.js'); 5031 5032var _spacerControlsCustomControlSpacerJs2 = _interopRequireDefault(_spacerControlsCustomControlSpacerJs); 5033 5034/** 5035 * Container of main controls 5036 * 5037 * @extends Component 5038 * @class ControlBar 5039 */ 5040 5041var ControlBar = (function (_Component) { 5042 _inherits(ControlBar, _Component); 5043 5044 function ControlBar() { 5045 _classCallCheck(this, ControlBar); 5046 5047 _Component.apply(this, arguments); 5048 } 5049 5050 /** 5051 * Create the component's DOM element 5052 * 5053 * @return {Element} 5054 * @method createEl 5055 */ 5056 5057 ControlBar.prototype.createEl = function createEl() { 5058 return _Component.prototype.createEl.call(this, 'div', { 5059 className: 'vjs-control-bar', 5060 dir: 'ltr' 5061 }, { 5062 'role': 'group' // The control bar is a group, so it can contain menuitems 5063 }); 5064 }; 5065 5066 return ControlBar; 5067})(_componentJs2['default']); 5068 5069ControlBar.prototype.options_ = { 5070 loadEvent: 'play', 5071 children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subtitlesButton', 'captionsButton', 'audioTrackButton', 'fullscreenToggle'] 5072}; 5073 5074_componentJs2['default'].registerComponent('ControlBar', ControlBar); 5075exports['default'] = ControlBar; 5076module.exports = exports['default']; 5077 5078},{"../component.js":67,"./audio-track-controls/audio-track-button.js":68,"./fullscreen-toggle.js":71,"./live-display.js":72,"./mute-toggle.js":73,"./play-toggle.js":74,"./playback-rate-menu/playback-rate-menu-button.js":75,"./progress-control/progress-control.js":80,"./spacer-controls/custom-control-spacer.js":83,"./text-track-controls/captions-button.js":86,"./text-track-controls/chapters-button.js":87,"./text-track-controls/descriptions-button.js":89,"./text-track-controls/subtitles-button.js":91,"./time-control
5078s/current-time-display.js":94,"./time-controls/duration-display.js":95,"./time-controls/remaining-time-display.js":96,"./time-controls/time-divider.js":97,"./volume-control/volume-control.js":100,"./volume-menu-button.js":102}],71:[function(_dereq_,module,exports){ 5079/** 5080 * @file fullscreen-toggle.js 5081 */ 5082'use strict'; 5083 5084exports.__esModule = true; 5085 5086function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5087 5088function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5089 5090function _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; } 5091 5092var _buttonJs = _dereq_('../button.js'); 5093 5094var _buttonJs2 = _interopRequireDefault(_buttonJs); 5095 5096var _componentJs = _dereq_('../component.js'); 5097 5098var _componentJs2 = _interopRequireDefault(_componentJs); 5099 5100/** 5101 * Toggle fullscreen video 5102 * 5103 * @extends Button 5104 * @class FullscreenToggle 5105 */ 5106 5107var FullscreenToggle = (function (_Button) { 5108 _inherits(FullscreenToggle, _Button); 5109 5110 function FullscreenToggle() { 5111 _classCallCheck(this, FullscreenToggle); 5112 5113 _Button.apply(this, arguments); 5114 } 5115 5116 /** 5117 * Allow sub components to stack CSS class names 5118 * 5119 * @return {String} The constructed class name 5120 * @method buildCSSClass 5121 */ 5122 5123 FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() { 5124 return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this); 5125 }; 5126 5127 /** 5128 * Handles click for full screen 5129 * 5130 * @method handleClick 5131 */ 5132 5133 FullscreenToggle.prototype.handleClick = function handleClick() { 5134 if (!this.player_.isFullscreen()) { 5135 this.player_.requestFullscreen(); 5136 this.controlText('Non-Fullscreen'); 5137 } else { 5138 this.player_.exitFullscreen(); 5139 this.controlText('Fullscreen'); 5140 } 5141 }; 5142 5143 return FullscreenToggle; 5144})(_buttonJs2['default']); 5145 5146FullscreenToggle.prototype.controlText_ = 'Fullscreen'; 5147 5148_componentJs2['default'].registerComponent('FullscreenToggle', FullscreenToggle); 5149exports['default'] = FullscreenToggle; 5150module.exports = exports['default']; 5151 5152},{"../button.js":64,"../component.js":67}],72:[function(_dereq_,module,exports){ 5153/** 5154 * @file live-display.js 5155 */ 5156'use strict'; 5157 5158exports.__esModule = true; 5159 5160function _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; } } 5161 5162function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5163 5164function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5165 5166function _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; } 5167 5168var _component = _dereq_('../component'); 5169 5170var _component2 = _interopRequireDefault(_component); 5171 5172var _utilsDomJs = _dereq_('../utils/dom.js'); 5173 5174var Dom = _interopRequireWildcard(_utilsDomJs); 5175 5176/** 5177 * Displays the live indicator 5178 * TODO - Future make it click to snap to live 5179 * 5180 * @extends Component 5181 * @class LiveDisplay 5182 */ 5183 5184var LiveDisplay = (function (_Component) { 5185 _inherits(LiveDisplay, _Component); 5186 5187 function LiveDisplay(player, options) { 5188 _classCallCheck(this, LiveDisplay); 5189 5190 _Component.call(this, player, options); 5191 5192 this.updateShowing(); 5193 this.on(this.player(), 'durationchange', this.updateShowing); 5194 } 5195 5196 /** 5197 * Create the component's DOM element 5198 * 5199 * @return {Element} 5200 * @method createEl 5201 */ 5202 5203 LiveDisplay.prototype.createEl = function createEl() { 5204 var el = _Component.prototype.createEl.call(this, 'div', { 5205 className: 'vjs-live-control vjs-control' 5206 }); 5207 5208 this.contentEl_ = Dom.createEl('div', { 5209 className: 'vjs-live-display', 5210 innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE') 5211 }, {
5212 'aria-live': 'off' 5213 }); 5214 5215 el.appendChild(this.contentEl_); 5216 return el; 5217 }; 5218 5219 LiveDisplay.prototype.updateShowing = function updateShowing() { 5220 if (this.player().duration() === Infinity) { 5221 this.show(); 5222 } else { 5223 this.hide(); 5224 } 5225 }; 5226 5227 return LiveDisplay; 5228})(_component2['default']); 5229 5230_component2['default'].registerComponent('LiveDisplay', LiveDisplay); 5231exports['default'] = LiveDisplay; 5232module.exports = exports['default']; 5233 5234},{"../component":67,"../utils/dom.js":143}],73:[function(_dereq_,module,exports){ 5235/** 5236 * @file mute-toggle.js 5237 */ 5238'use strict'; 5239 5240exports.__esModule = true; 5241 5242function _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; } } 5243 5244function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5245 5246function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5247 5248function _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; } 5249 5250var _button = _dereq_('../button'); 5251 5252var _button2 = _interopRequireDefault(_button); 5253 5254var _component = _dereq_('../component'); 5255 5256var _component2 = _interopRequireDefault(_component); 5257 5258var _utilsDomJs = _dereq_('../utils/dom.js'); 5259 5260var Dom = _interopRequireWildcard(_utilsDomJs); 5261 5262/** 5263 * A button component for muting the audio 5264 * 5265 * @param {Player|Object} player 5266 * @param {Object=} options 5267 * @extends Button 5268 * @class MuteToggle 5269 */ 5270 5271var MuteToggle = (function (_Button) { 5272 _inherits(MuteToggle, _Button); 5273 5274 function MuteToggle(player, options) { 5275 _classCallCheck(this, MuteToggle); 5276 5277 _Button.call(this, player, options); 5278 5279 this.on(player, 'volumechange', this.update); 5280 5281 // hide mute toggle if the current tech doesn't support volume control 5282 if (player.tech_ && player.tech_['featuresVolumeControl'] === false) { 5283 this.addClass('vjs-hidden'); 5284 } 5285 5286 this.on(player, 'loadstart', function () { 5287 this.update(); // We need to update the button to account for a default muted state. 5288 5289 if (player.tech_['featuresVolumeControl'] === false) { 5290 this.addClass('vjs-hidden'); 5291 } else { 5292 this.removeClass('vjs-hidden'); 5293 } 5294 }); 5295 } 5296 5297 /** 5298 * Allow sub components to stack CSS class names 5299 * 5300 * @return {String} The constructed class name 5301 * @method buildCSSClass 5302 */ 5303 5304 MuteToggle.prototype.buildCSSClass = function buildCSSClass() { 5305 return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this); 5306 }; 5307 5308 /** 5309 * Handle click on mute 5310 * 5311 * @method handleClick 5312 */ 5313 5314 MuteToggle.prototype.handleClick = function handleClick() { 5315 this.player_.muted(this.player_.muted() ? false : true); 5316 }; 5317 5318 /** 5319 * Update volume 5320 * 5321 * @method update 5322 */ 5323 5324 MuteToggle.prototype.update = function update() { 5325 var vol = this.player_.volume(), 5326 level = 3; 5327 5328 if (vol === 0 || this.player_.muted()) { 5329 level = 0; 5330 } else if (vol < 0.33) { 5331 level = 1; 5332 } else if (vol < 0.67) { 5333 level = 2; 5334 } 5335 5336 // Don't rewrite the button text if the actual text doesn't change. 5337 // This causes unnecessary and confusing information for screen reader users. 5338 // This check is needed because this function gets called every time the volume level is changed. 5339 var toMute = this.player_.muted() ? 'Unmute' : 'Mute'; 5340 if (this.controlText() !== toMute) { 5341 this.controlText(toMute); 5342 } 5343 5344 /* TODO improve muted icon classes */ 5345 for (var i = 0; i < 4; i++) { 5346 Dom.removeElClass(this.el_, 'vjs-vol-' + i); 5347 } 5348 Dom.addElClass(this.el_, 'vjs-vol-' + level); 5349 }; 5350 5351 return MuteToggle; 5352})(_button2['default']); 5353 5354MuteToggle.prototype.controlText_ = 'Mute'; 5355 5356_component2['default'].registerComponent('MuteToggle', MuteToggle); 5357exports['default'] = MuteToggle; 5358module.exports = exports['default']; 5359 5360},{"../button":64,"../component":67,"../utils/dom.js":143}],74:[function(_dereq_,module,exports){ 5361/** 5362 * @file play-toggle.js 5363 */ 5364'use strict'; 5365 5366exports.__esModule = true; 5367 5368function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5369 5370function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5371 5372function _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
5372onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 5373 5374var _buttonJs = _dereq_('../button.js'); 5375 5376var _buttonJs2 = _interopRequireDefault(_buttonJs); 5377 5378var _componentJs = _dereq_('../component.js'); 5379 5380var _componentJs2 = _interopRequireDefault(_componentJs); 5381 5382/** 5383 * Button to toggle between play and pause 5384 * 5385 * @param {Player|Object} player 5386 * @param {Object=} options 5387 * @extends Button 5388 * @class PlayToggle 5389 */ 5390 5391var PlayToggle = (function (_Button) { 5392 _inherits(PlayToggle, _Button); 5393 5394 function PlayToggle(player, options) { 5395 _classCallCheck(this, PlayToggle); 5396 5397 _Button.call(this, player, options); 5398 5399 this.on(player, 'play', this.handlePlay); 5400 this.on(player, 'pause', this.handlePause); 5401 } 5402 5403 /** 5404 * Allow sub components to stack CSS class names 5405 * 5406 * @return {String} The constructed class name 5407 * @method buildCSSClass 5408 */ 5409 5410 PlayToggle.prototype.buildCSSClass = function buildCSSClass() { 5411 return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this); 5412 }; 5413 5414 /** 5415 * Handle click to toggle between play and pause 5416 * 5417 * @method handleClick 5418 */ 5419 5420 PlayToggle.prototype.handleClick = function handleClick() { 5421 if (this.player_.paused()) { 5422 this.player_.play(); 5423 } else { 5424 this.player_.pause(); 5425 } 5426 }; 5427 5428 /** 5429 * Add the vjs-playing class to the element so it can change appearance 5430 * 5431 * @method handlePlay 5432 */ 5433 5434 PlayToggle.prototype.handlePlay = function handlePlay() { 5435 this.removeClass('vjs-paused'); 5436 this.addClass('vjs-playing'); 5437 this.controlText('Pause'); // change the button text to "Pause" 5438 }; 5439 5440 /** 5441 * Add the vjs-paused class to the element so it can change appearance 5442 * 5443 * @method handlePause 5444 */ 5445 5446 PlayToggle.prototype.handlePause = function handlePause() { 5447 this.removeClass('vjs-playing'); 5448 this.addClass('vjs-paused'); 5449 this.controlText('Play'); // change the button text to "Play" 5450 }; 5451 5452 return PlayToggle; 5453})(_buttonJs2['default']); 5454 5455PlayToggle.prototype.controlText_ = 'Play'; 5456 5457_componentJs2['default'].registerComponent('PlayToggle', PlayToggle); 5458exports['default'] = PlayToggle; 5459module.exports = exports['default']; 5460 5461},{"../button.js":64,"../component.js":67}],75:[function(_dereq_,module,exports){ 5462/** 5463 * @file playback-rate-menu-button.js 5464 */ 5465'use strict'; 5466 5467exports.__esModule = true; 5468 5469function _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; } } 5470 5471function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5472 5473function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5474 5475function _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; } 5476 5477var _menuMenuButtonJs = _dereq_('../../menu/menu-button.js'); 5478 5479var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs); 5480 5481var _menuMenuJs = _dereq_('../../menu/menu.js'); 5482 5483var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs); 5484 5485var _playbackRateMenuItemJs = _dereq_('./playback-rate-menu-item.js'); 5486 5487var _playbackRateMenuItemJs2 = _interopRequireDefault(_playbackRateMenuItemJs); 5488 5489var _componentJs = _dereq_('../../component.js'); 5490 5491var _componentJs2 = _interopRequireDefault(_componentJs); 5492 5493var _utilsDomJs = _dereq_('../../utils/dom.js'); 5494 5495var Dom = _interopRequireWildcard(_utilsDomJs); 5496 5497/** 5498 * The component for controlling the playback rate 5499 * 5500 * @param {Player|Object} player 5501 * @param {Object=} options 5502 * @extends MenuButton 5503 * @class PlaybackRateMenuButton 5504 */ 5505 5506var PlaybackRateMenuButton = (function (_MenuButton) { 5507 _inherits(PlaybackRateMenuButton, _MenuButton); 5508 5509 function PlaybackRateMenuButton(player, options) { 5510 _classCallCheck(this, PlaybackRateMenuButton); 5511 5512 _MenuButton.call(this, player, options); 5513 5514 this.updateVisibility(); 5515 this.updateLabel(); 5516 5517 this.on(player, 'loadstart', this.updateVisibility); 5518 this.on(player, 'ratechange', this.updateLabel); 5519 } 5520 5521 /** 5522 * Create the component's DOM element 5523 * 5524 * @return {Element} 5525 * @method createEl 5526 */ 5527 5528 PlaybackRateMenuButton.prototype.createEl = function createEl() { 5529 var el = _MenuButton.prototype.createEl.call(this); 5530 5531 this.labelEl_ = Dom.createEl('div', { 5532 className: 'vjs-playback-rate-value', 5533 innerHTML: 1.0 5534 }); 5535 5536 el.appendChild(this.labelEl_); 5537 5538 return el; 5539 }; 5540 5541 /** 5542 * Allow sub components to stack CSS class names 5543 * 5544 * @return {String} The constructed class name 5545 * @method buildCSSClass 5546 */ 5547 5548 PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() { 5549 return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this); 5550 }; 5551 5552 /** 5553 * Create the playback rate menu 5554 * 5555 * @return {Menu} Menu object populated with items 5556 * @method createMenu 5557 */ 5558 5559 PlaybackRateMenuButton.prototype.createMenu = function createMenu() { 5560 var menu = new _menuMenuJs2['default'](this.player()); 5561 var rates = this.playbackRates(); 5562 5563 if (rates) { 5564 for (var i = rates.length - 1; i >= 0; i--) { 5565 menu.addChild(new _playbackRateMenuItemJs2['default'](this.player(), { 'rate': rates[i] + 'x' })); 5566 } 5567 } 5568 5569 return menu; 5570 }; 5571 5572 /** 5573 * Updates ARIA accessibility attributes 5574 * 5575 * @method updateARIAAttributes 5576 */ 5577 5578 PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() { 5579 // Current playback rate 5580 this.el().setAttribute('aria-valuenow', this.player().playbackRate()); 5581 }; 5582 5583 /** 5584 * Handle menu item click 5585 * 5586 * @method handleClick 5587 */ 5588 5589 PlaybackRateMenuButton.prototype.handleClick = function handleClick() { 5590 // select next rate option 5591 var currentRate = this.player().playbackRate(); 5592 var rates = this.playbackRates(); 5593 5594 // this will select first one if the last one currently selected 5595 var newRate = rates[0]; 5596 for (var i = 0; i < rates.length; i++) { 5597 if (rates[i] > currentRate) { 5598 newRate = rates[i]; 5599 break; 5600 } 5601 } 5602 this.player().playbackRate(newRate); 5603 }; 5604 5605 /** 5606 * Get possible playback rates 5607 * 5608 * @return {Array} Possible playback rates 5609 * @method playbackRates 5610 */ 5611 5612 PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() { 5613 return this.options_['playbackRates'] || this.options_.playerOptions && this.options_.playerOptions['playbackRates']; 5614 }; 5615 5616 /** 5617 * Get whether playback rates is supported by the tech 5618 * and an array of playback rates exists 5619 * 5620 * @return {Boolean} Whether changing playback rate is supported 5621 * @method playbackRateSupported 5622 */ 5623 5624 PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() { 5625 return this.player().tech_ && this.player().tech_['featuresPlaybackRate'] && this.playbackRates() && this.playbackRates().length > 0; 5626 }; 5627 5628 /** 5629 * Hide playback rate controls when they're no playback rate options to select 5630 * 5631 * @method updateVisibility 5632 */ 5633 5634 PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility() { 5635 if (this.playbackRateSupported()) { 5636 this.removeClass('vjs-hidden'); 5637 } else { 5638 this.addClass('vjs-hidden'); 5639 } 5640 }; 5641 5642 /** 5643 * Update button label when rate changed 5644 * 5645 * @method updateLabel 5646 */ 5647 5648 PlaybackRateMenuButton.prototype.updateLabel = function updateLabel() { 5649 if (this.playbackRateSupported()) { 5650 this.labelEl_.innerHTML = this.player().playbackRate() + 'x'; 5651 } 5652 }; 5653 5654 return PlaybackRateMenuButton; 5655}
5655)(_menuMenuButtonJs2['default']); 5656 5657PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate'; 5658 5659_componentJs2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton); 5660exports['default'] = PlaybackRateMenuButton; 5661module.exports = exports['default']; 5662 5663},{"../../component.js":67,"../../menu/menu-button.js":109,"../../menu/menu.js":111,"../../utils/dom.js":143,"./playback-rate-menu-item.js":76}],76:[function(_dereq_,module,exports){ 5664/** 5665 * @file playback-rate-menu-item.js 5666 */ 5667'use strict'; 5668 5669exports.__esModule = true; 5670 5671function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5672 5673function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5674 5675function _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; } 5676 5677var _menuMenuItemJs = _dereq_('../../menu/menu-item.js'); 5678 5679var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs); 5680 5681var _componentJs = _dereq_('../../component.js'); 5682 5683var _componentJs2 = _interopRequireDefault(_componentJs); 5684 5685/** 5686 * The specific menu item type for selecting a playback rate 5687 * 5688 * @param {Player|Object} player 5689 * @param {Object=} options 5690 * @extends MenuItem 5691 * @class PlaybackRateMenuItem 5692 */ 5693 5694var PlaybackRateMenuItem = (function (_MenuItem) { 5695 _inherits(PlaybackRateMenuItem, _MenuItem); 5696 5697 function PlaybackRateMenuItem(player, options) { 5698 _classCallCheck(this, PlaybackRateMenuItem); 5699 5700 var label = options['rate']; 5701 var rate = parseFloat(label, 10); 5702 5703 // Modify options for parent MenuItem class's init. 5704 options['label'] = label; 5705 options['selected'] = rate === 1; 5706 _MenuItem.call(this, player, options); 5707 5708 this.label = label; 5709 this.rate = rate; 5710 5711 this.on(player, 'ratechange', this.update); 5712 } 5713 5714 /** 5715 * Handle click on menu item 5716 * 5717 * @method handleClick 5718 */ 5719 5720 PlaybackRateMenuItem.prototype.handleClick = function handleClick() { 5721 _MenuItem.prototype.handleClick.call(this); 5722 this.player().playbackRate(this.rate); 5723 }; 5724 5725 /** 5726 * Update playback rate with selected rate 5727 * 5728 * @method update 5729 */ 5730 5731 PlaybackRateMenuItem.prototype.update = function update() { 5732 this.selected(this.player().playbackRate() === this.rate); 5733 }; 5734 5735 return PlaybackRateMenuItem; 5736})(_menuMenuItemJs2['default']); 5737 5738PlaybackRateMenuItem.prototype.contentElType = 'button'; 5739 5740_componentJs2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem); 5741exports['default'] = PlaybackRateMenuItem; 5742module.exports = exports['default']; 5743 5744},{"../../component.js":67,"../../menu/menu-item.js":110}],77:[function(_dereq_,module,exports){ 5745/** 5746 * @file load-progress-bar.js 5747 */ 5748'use strict'; 5749 5750exports.__esModule = true; 5751 5752function _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; } } 5753 5754function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5755 5756function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5757 5758function _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; } 5759 5760var _componentJs = _dereq_('../../component.js'); 5761 5762var _componentJs2 = _interopRequireDefault(_componentJs); 5763 5764var _utilsDomJs = _dereq_('../../utils/dom.js'); 5765 5766var Dom = _interopRequireWildcard(_utilsDomJs); 5767 5768/** 5769 * Shows load progress 5770 * 5771 * @param {Player|Object} player 5772 * @param {Object=} options 5773 * @extends Component 5774 * @class LoadProgressBar 5775 */ 5776 5777var LoadProgressBar = (function (_Component) { 5778 _inherits(LoadProgressBar, _Component); 5779 5780 function LoadProgressBar(player, options) { 5781 _classCallCheck(this, LoadProgressBar); 5782 5783 _Component.call(this, player, options); 5784 this.on(player, 'progress', this.update); 5785 } 5786 5787 /** 5788 * Create the component's DOM element 5789 * 5790 * @return {Element} 5791 * @method createEl 5792 */ 5793 5794 LoadProgressBar.prototype.createEl = function createEl() { 5795 return _Component.prototype.createEl.call(this, 'div', { 5796 className: 'vjs-load-progress', 5797 innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>' 5798 }); 5799 }; 5800 5801 /** 5802 * Update progress bar 5803 * 5804 * @method update 5805 */ 5806
5807 LoadProgressBar.prototype.update = function update() { 5808 var buffered = this.player_.buffered(); 5809 var duration = this.player_.duration(); 5810 var bufferedEnd = this.player_.bufferedEnd(); 5811 var children = this.el_.children; 5812 5813 // get the percent width of a time compared to the total end 5814 var percentify = function percentify(time, end) { 5815 var percent = time / end || 0; // no NaN 5816 return (percent >= 1 ? 1 : percent) * 100 + '%'; 5817 }; 5818 5819 // update the width of the progress bar 5820 this.el_.style.width = percentify(bufferedEnd, duration); 5821 5822 // add child elements to represent the individual buffered time ranges 5823 for (var i = 0; i < buffered.length; i++) { 5824 var start = buffered.start(i); 5825 var end = buffered.end(i); 5826 var part = children[i]; 5827 5828 if (!part) { 5829 part = this.el_.appendChild(Dom.createEl()); 5830 } 5831 5832 // set the percent based on the width of the progress bar (bufferedEnd) 5833 part.style.left = percentify(start, bufferedEnd); 5834 part.style.width = percentify(end - start, bufferedEnd); 5835 } 5836 5837 // remove unused buffered range elements 5838 for (var i = children.length; i > buffered.length; i--) { 5839 this.el_.removeChild(children[i - 1]); 5840 } 5841 }; 5842 5843 return LoadProgressBar; 5844})(_componentJs2['default']); 5845 5846_componentJs2['default'].registerComponent('LoadProgressBar', LoadProgressBar); 5847exports['default'] = LoadProgressBar; 5848module.exports = exports['default']; 5849 5850},{"../../component.js":67,"../../utils/dom.js":143}],78:[function(_dereq_,module,exports){ 5851/** 5852 * @file mouse-time-display.js 5853 */ 5854'use strict'; 5855 5856exports.__esModule = true; 5857 5858function _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; } } 5859 5860function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5861 5862function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5863 5864function _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; } 5865 5866var _globalWindow = _dereq_('global/window'); 5867 5868var _globalWindow2 = _interopRequireDefault(_globalWindow); 5869 5870var _componentJs = _dereq_('../../component.js'); 5871 5872var _componentJs2 = _interopRequireDefault(_componentJs); 5873 5874var _utilsDomJs = _dereq_('../../utils/dom.js'); 5875 5876var Dom = _interopRequireWildcard(_utilsDomJs); 5877 5878var _utilsFnJs = _dereq_('../../utils/fn.js'); 5879 5880var Fn = _interopRequireWildcard(_utilsFnJs); 5881 5882var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js'); 5883 5884var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 5885 5886var _lodashCompatFunctionThrottle = _dereq_('lodash-compat/function/throttle'); 5887 5888var _lodashCompatFunctionThrottle2 = _interopRequireDefault(_lodashCompatFunctionThrottle); 5889 5890/** 5891 * The Mouse Time Display component shows the time you will seek to 5892 * when hovering over the progress bar 5893 * 5894 * @param {Player|Object} player 5895 * @param {Object=} options 5896 * @extends Component 5897 * @class MouseTimeDisplay 5898 */ 5899 5900var MouseTimeDisplay = (function (_Component) { 5901 _inherits(MouseTimeDisplay, _Component); 5902 5903 function MouseTimeDisplay(player, options) { 5904 var _this = this; 5905 5906 _classCallCheck(this, MouseTimeDisplay); 5907 5908 _Component.call(this, player, options); 5909 5910 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) { 5911 this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside; 5912 } 5913 5914 if (this.keepTooltipsInside) { 5915 this.tooltip = Dom.createEl('div', { className: 'vjs-time-tooltip' }); 5916 this.el().appendChild(this.tooltip); 5917 this.addClass('vjs-keep-tooltips-inside'); 5918 } 5919 5920 this.update(0, 0); 5921 5922 player.on('ready', function () { 5923 _this.on(player.controlBar.progressControl.el(), 'mousemove', _lodashCompatFunctionThrottle2['default'](Fn.bind(_this, _this.handleMouseMove), 25)); 5924 }); 5925 } 5926 5927 /** 5928 * Create the component's DOM element 5929 * 5930 * @return {Element} 5931 * @method createEl 5932 */ 5933 5934 MouseTimeDisplay.prototype.createEl = function createEl() { 5935 return _Component.prototype.createEl.call(this, 'div', { 5936 className: 'vjs-mouse-display' 5937 }); 5938 }; 5939 5940 MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) { 5941 var duration = this.player_.duration(); 5942 var newTime = this.calculateDistance(event) * duration; 5943 var position = event.pageX - Dom.findElPosition(this.el().parentNode).left; 5944 5945 this.update(newTime, position); 5946 }; 5947 5948 MouseTimeDisplay.prototype.update = function update(newTime, position) { 5949 var time = _utilsFormatTimeJs2['default'](newTime, this.player_.duration()); 5950 5951 this.el().style.left = position + 'px'; 5952 this.el().setAttribute('data-current-time', time); 5953 5954 if (this.keepTooltipsInside) { 5955 var clampedPosition = this.clampPosition_(position); 5956 var difference = position - clampedPosition + 1; 5957 var tooltipWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.tooltip).width); 5958 var tooltipWidthHalf = tooltipWidth / 2; 5959 5960 this.tooltip.innerHTML = time; 5961 this.tooltip.style.right = '-' + (tooltipWidthHalf - difference) + 'px'; 5962 } 5963 }; 5964 5965 MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) { 5966 return Dom.getPointerPosition(this.el().parentNode, event).x; 5967 }; 5968 5969 /** 5970 * This takes in a horizontal position for the bar and returns a clamped position. 5971 * Clamped position means that it will keep the position greater than half the width 5972 * of the tooltip and smaller than the player width minus half the width o the tooltip. 5973 * It will only clamp the position if `keepTooltipsInside` option is set. 5974 * 5975 * @param {Number} position the position the bar wants to be 5976 * @return {Number} newPosition the (potentially) clamped position 5977 * @method clampPosition_ 5978 */ 5979 5980 MouseTimeDisplay.prototype.clampPosition_ = function clampPosition_(position) { 5981 if (!this.keepTooltipsInside) { 5982 return position; 5983 } 5984 5985 var playerWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.player().el()).width); 5986 var tooltipWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.tooltip).width); 5987 var tooltipWidthHalf = tooltipWidth / 2; 5988 var actualPosition = position; 5989 5990 if (position < tooltipWidthHalf) { 5991 actualPosition = Math.ceil(tooltipWidthHalf); 5992 } else if (position > playerWidth - tooltipWidthHalf) { 5993 actualPosition = Math.floor(playerWidth - tooltipWidthHalf); 5994 } 5995 5996 return actualPosition; 5997 }; 5998 5999 return MouseTimeDisplay; 6000})(_componentJs2['default']); 6001 6002_componentJs2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay); 6003exports['default'] = MouseTimeDisplay; 6004module.exports = exports['default']; 6005 6006},{"../../component.js":67,"../../utils/dom.js":143,"../../utils/fn.js":145,"../../utils/format-time.js":146,"global/window":2,"lodash-compat/function/throttle":7}],79:[function(_dereq_,module,exports){ 6007/** 6008 * @file play-progress-bar.js 6009 */ 6010'use strict'; 6011 6012exports.__esModule = true; 6013 6014function _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; } } 6015 6016function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6017 6018function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6019 6020function _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
6020onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 6021 6022var _componentJs = _dereq_('../../component.js'); 6023 6024var _componentJs2 = _interopRequireDefault(_componentJs); 6025 6026var _utilsFnJs = _dereq_('../../utils/fn.js'); 6027 6028var Fn = _interopRequireWildcard(_utilsFnJs); 6029 6030var _utilsDomJs = _dereq_('../../utils/dom.js'); 6031 6032var Dom = _interopRequireWildcard(_utilsDomJs); 6033 6034var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js'); 6035 6036var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 6037 6038/** 6039 * Shows play progress 6040 * 6041 * @param {Player|Object} player 6042 * @param {Object=} options 6043 * @extends Component 6044 * @class PlayProgressBar 6045 */ 6046 6047var PlayProgressBar = (function (_Component) { 6048 _inherits(PlayProgressBar, _Component); 6049 6050 function PlayProgressBar(player, options) { 6051 _classCallCheck(this, PlayProgressBar); 6052 6053 _Component.call(this, player, options); 6054 this.updateDataAttr(); 6055 this.on(player, 'timeupdate', this.updateDataAttr); 6056 player.ready(Fn.bind(this, this.updateDataAttr)); 6057 6058 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) { 6059 this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside; 6060 } 6061 6062 if (this.keepTooltipsInside) { 6063 this.addClass('vjs-keep-tooltips-inside'); 6064 } 6065 } 6066 6067 /** 6068 * Create the component's DOM element 6069 * 6070 * @return {Element} 6071 * @method createEl 6072 */ 6073 6074 PlayProgressBar.prototype.createEl = function createEl() { 6075 return _Component.prototype.createEl.call(this, 'div', { 6076 className: 'vjs-play-progress vjs-slider-bar', 6077 innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>' 6078 }); 6079 }; 6080 6081 PlayProgressBar.prototype.updateDataAttr = function updateDataAttr() { 6082 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 6083 this.el_.setAttribute('data-current-time', _utilsFormatTimeJs2['default'](time, this.player_.duration())); 6084 }; 6085 6086 return PlayProgressBar; 6087})(_componentJs2['default']); 6088 6089_componentJs2['default'].registerComponent('PlayProgressBar', PlayProgressBar); 6090exports['default'] = PlayProgressBar; 6091module.exports = exports['default']; 6092 6093},{"../../component.js":67,"../../utils/dom.js":143,"../../utils/fn.js":145,"../../utils/format-time.js":146}],80:[function(_dereq_,module,exports){ 6094/** 6095 * @file progress-control.js 6096 */ 6097'use strict'; 6098 6099exports.__esModule = true; 6100 6101function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6102 6103function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6104 6105function _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; } 6106 6107var _componentJs = _dereq_('../../component.js'); 6108 6109var _componentJs2 = _interopRequireDefault(_componentJs); 6110 6111var _seekBarJs = _dereq_('./seek-bar.js'); 6112 6113var _seekBarJs2 = _interopRequireDefault(_seekBarJs); 6114 6115var _mouseTimeDisplayJs = _dereq_('./mouse-time-display.js'); 6116 6117var _mouseTimeDisplayJs2 = _interopRequireDefault(_mouseTimeDisplayJs); 6118 6119/** 6120 * The Progress Control component contains the seek bar, load progress, 6121 * and play progress 6122 * 6123 * @param {Player|Object} player 6124 * @param {Object=} options 6125 * @extends Component 6126 * @class ProgressControl 6127 */ 6128 6129var ProgressControl = (function (_Component) { 6130 _inherits(ProgressControl, _Component); 6131 6132 function ProgressControl() { 6133 _classCallCheck(this, ProgressControl); 6134 6135 _Component.apply(this, arguments); 6136 } 6137 6138 /** 6139 * Create the component's DOM element 6140 * 6141 * @return {Element} 6142 * @method createEl 6143 */ 6144 6145 ProgressControl.prototype.createEl = function createEl() { 6146 return _Component.prototype.createEl.call(this, 'div', { 6147 className: 'vjs-progress-control vjs-control' 6148 }); 6149 }; 6150 6151 return ProgressControl; 6152})(_componentJs2['default']); 6153 6154ProgressControl.prototype.options_ = { 6155 children: ['seekBar'] 6156}; 6157 6158_componentJs2['default'].registerComponent('ProgressControl', ProgressControl); 6159exports['default'] = ProgressControl; 6160module.exports = exports['default']; 6161 6162},{"../../component.js":67,"./mouse-time-display.js":78,"./seek-bar.js":81}],81:[function(_dereq_,module,exports){ 6163/** 6164 * @file seek-bar.js 6165 */ 6166'use strict'; 6167 6168exports.__esModule = true; 6169 6170function _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; } } 6171 6172function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6173 6174function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6175 6176function _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
6176onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 6177 6178var _globalWindow = _dereq_('global/window'); 6179 6180var _globalWindow2 = _interopRequireDefault(_globalWindow); 6181 6182var _sliderSliderJs = _dereq_('../../slider/slider.js'); 6183 6184var _sliderSliderJs2 = _interopRequireDefault(_sliderSliderJs); 6185 6186var _componentJs = _dereq_('../../component.js'); 6187 6188var _componentJs2 = _interopRequireDefault(_componentJs); 6189 6190var _loadProgressBarJs = _dereq_('./load-progress-bar.js'); 6191 6192var _loadProgressBarJs2 = _interopRequireDefault(_loadProgressBarJs); 6193 6194var _playProgressBarJs = _dereq_('./play-progress-bar.js'); 6195 6196var _playProgressBarJs2 = _interopRequireDefault(_playProgressBarJs); 6197 6198var _tooltipProgressBarJs = _dereq_('./tooltip-progress-bar.js'); 6199 6200var _tooltipProgressBarJs2 = _interopRequireDefault(_tooltipProgressBarJs); 6201 6202var _utilsFnJs = _dereq_('../../utils/fn.js'); 6203 6204var Fn = _interopRequireWildcard(_utilsFnJs); 6205 6206var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js'); 6207 6208var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 6209 6210var _objectAssign = _dereq_('object.assign'); 6211 6212var _objectAssign2 = _interopRequireDefault(_objectAssign); 6213 6214/** 6215 * Seek Bar and holder for the progress bars 6216 * 6217 * @param {Player|Object} player 6218 * @param {Object=} options 6219 * @extends Slider 6220 * @class SeekBar 6221 */ 6222 6223var SeekBar = (function (_Slider) { 6224 _inherits(SeekBar, _Slider); 6225 6226 function SeekBar(player, options) { 6227 _classCallCheck(this, SeekBar); 6228 6229 _Slider.call(this, player, options); 6230 this.on(player, 'timeupdate', this.updateProgress); 6231 this.on(player, 'ended', this.updateProgress); 6232 player.ready(Fn.bind(this, this.updateProgress)); 6233 6234 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) { 6235 this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside; 6236 } 6237 6238 if (this.keepTooltipsInside) { 6239 this.tooltipProgressBar = this.addChild('TooltipProgressBar'); 6240 } 6241 } 6242 6243 /** 6244 * Create the component's DOM element 6245 * 6246 * @return {Element} 6247 * @method createEl 6248 */ 6249 6250 SeekBar.prototype.createEl = function createEl() { 6251 return _Slider.prototype.createEl.call(this, 'div', { 6252 className: 'vjs-progress-holder' 6253 }, { 6254 'aria-label': 'progress bar' 6255 }); 6256 }; 6257 6258 /** 6259 * Update ARIA accessibility attributes 6260 * 6261 * @method updateARIAAttributes 6262 */ 6263 6264 SeekBar.prototype.updateProgress = function updateProgress() { 6265 this.updateAriaAttributes(this.el_); 6266 6267 if (this.keepTooltipsInside) { 6268 this.updateAriaAttributes(this.tooltipProgressBar.el_); 6269 this.tooltipProgressBar.el_.style.width = this.bar.el_.style.width; 6270 6271 var playerWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.player().el()).width); 6272 var tooltipWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.tooltipProgressBar.tooltip).width); 6273 var tooltipStyle = this.tooltipProgressBar.el().style; 6274 tooltipStyle.maxWidth = Math.floor(playerWidth - tooltipWidth / 2) + 'px'; 6275 tooltipStyle.minWidth = Math.ceil(tooltipWidth / 2) + 'px'; 6276 tooltipStyle.right = '-' + tooltipWidth / 2 + 'px'; 6277 } 6278 }; 6279 6280 SeekBar.prototype.updateAriaAttributes = function updateAriaAttributes(el) { 6281 // Allows for smooth scrubbing, when player can't keep up. 6282 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 6283 el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2)); // machine readable value of progress bar (percentage complete) 6284 el.setAttribute('aria-valuetext', _utilsFormatTimeJs2['default'](time, this.player_.duration())); // human readable value of progress bar (time complete) 6285 }; 6286 6287 /** 6288 * Get percentage of video played 6289 * 6290 * @return {Number} Percentage played 6291 * @method getPercent 6292 */ 6293 6294 SeekBar.prototype.getPercent = function getPercent() { 6295 var percent = this.player_.currentTime() / this.player_.duration(); 6296 return percent >= 1 ? 1 : percent; 6297 }; 6298 6299 /** 6300 * Handle mouse down on seek bar 6301 * 6302 * @method handleMouseDown 6303 */ 6304 6305 SeekBar.prototype.handleMouseDown = function handleMouseDown(event) { 6306 _Slider.prototype.handleMouseDown.call(this, event); 6307 6308 this.player_.scrubbing(true); 6309 6310 this.videoWasPlaying = !this.player_.paused(); 6311 this.player_.pause(); 6312 }; 6313 6314 /** 6315 * Handle mouse move on seek bar 6316 * 6317 * @method handleMouseMove 6318 */ 6319 6320 SeekBar.prototype.handleMouseMove = function handleMouseMove(event) { 6321 var newTime = this.calculateDistance(event) * this.player_.duration(); 6322 6323 // Don't let video end while scrubbing. 6324 if (newTime === this.player_.duration()) { 6325 newTime = newTime - 0.1; 6326 } 6327 6328 // Set new time (tell player to seek to new time) 6329 this.player_.currentTime(newTime); 6330 }; 6331 6332 /** 6333 * Handle mouse up on seek bar 6334 * 6335 * @method handleMouseUp 6336 */ 6337 6338 SeekBar.prototype.handleMouseUp = function handleMouseUp(event) { 6339 _Slider.prototype.handleMouseUp.call(this, event); 6340 6341 this.player_.scrubbing(false); 6342 if (this.videoWasPlaying) { 6343 this.player_.play(); 6344 } 6345 }; 6346 6347 /** 6348 * Move more quickly fast forward for keyboard-only users 6349 * 6350 * @method stepForward 6351 */ 6352 6353 SeekBar.prototype.stepForward = function stepForward() { 6354 this.player_.currentTime(this.player_.currentTime() + 5); // more quickly fast forward for keyboard-only users 6355 }; 6356 6357 /** 6358 * Move more quickly rewind for keyboard-only users 6359 * 6360 * @method stepBack 6361 */ 6362 6363 SeekBar.prototype.stepBack = function stepBack() { 6364 this.player_.currentTime(this.player_.currentTime() - 5); // more quickly rewind for keyboard-only users 6365 }; 6366 6367 return SeekBar; 6368})(_sliderSliderJs2['default']); 6369 6370SeekBar.prototype.options_ = { 6371 children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'], 6372 'barName': 'playProgressBar' 6373}; 6374 6375SeekBar.prototype.playerEvent = 'timeupdate'; 6376 6377_componentJs2['default'].registerComponent('SeekBar', SeekBar); 6378exports['default'] = SeekBar; 6379module.exports = exports['default']; 6380 6381},{"../../component.js":67,"../../slider/slider.js":119,"../../utils/fn.js":145,"../../utils/format-time.js":146,"./load-progress-bar.js":77,"./play-progress-bar.js":79,"./tooltip-progress-bar.js":82,"global/window":2,"object.assign":45}],82:[function(_dereq_,module,exports){ 6382/** 6383 * @file play-progress-bar.js 6384 */ 6385'use strict'; 6386 6387exports.__esModule = true; 6388 6389function _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; } } 6390 6391function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6392 6393function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 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 6397var _componentJs = _dereq_('../../component.js'); 6398 6399var _componentJs2 = _interopRequireDefault(_componentJs); 6400 6401var _utilsFnJs = _dereq_('../../utils/fn.js'); 6402 6403var Fn = _interopRequireWildcard(_utilsFnJs); 6404 6405var _utilsDomJs = _dereq_('../../utils/dom.js'); 6406 6407var Dom = _interopRequireWildcard(_utilsDomJs); 6408 6409var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js'); 6410 6411var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 6412 6413/** 6414 * Shows play progress 6415 * 6416 * @param {Player|Object} player 6417 * @param {Object=} options 6418 * @extends Component 6419 * @class PlayProgressBar 6420 */ 6421 6422var TooltipProgressBar = (function (_Component) { 6423 _inherits(TooltipProgressBar, _Component); 6424 6425 function TooltipProgressBar(player, options) { 6426 _classCallCheck(this, TooltipProgressBar); 6427 6428 _Component.call(this, player, options); 6429 this.updateDataAttr(); 6430 this.on(player, 'timeupdate', this.updateDataAttr); 6431 player.ready(Fn.bind(this, this.updateDataAttr)); 6432 } 6433 6434 /** 6435 * Create the component's DOM element 6436 * 6437 * @return {Element} 6438 * @method createEl 6439 */ 6440 6441 TooltipProgressBar.prototype.createEl = function createEl() { 6442 var el = _Component.prototype.createEl.call(this, 'div', { 6443 className: 'vjs-tooltip-progress-bar vjs-slider-bar', 6444 innerHTML: '<div class="vjs-time-tooltip"></div>\n <span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>' 6445 }); 6446 6447 this.tooltip = el.querySelector('.vjs-time-tooltip'); 6448 6449 return el; 6450 }; 6451 6452 TooltipProgressBar.prototype.updateDataAttr = function updateDataAttr() { 6453 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 6454 var formattedTime = _utilsFormatTimeJs2['default'](time, this.player_.duration()); 6455 this.el_.setAttribute('data-current-time', formattedTime); 6456 this.tooltip.innerHTML = formattedTime; 6457 }; 6458 6459 return TooltipProgressBar; 6460})(_componentJs2['default']); 6461 6462_componentJs2['default'].registerComponent('TooltipProgressBar', TooltipProgressBar); 6463exports['default'] = TooltipProgressBar; 6464module.exports = exports['default']; 6465 6466},{"../../component.js":67,"../../utils/dom.js":143,"../../utils/fn.js":145,"../../utils/format-time.js":146}],83:[function(_dereq_,module,exports){ 6467/** 6468 * @file custom-control-spacer.js 6469 */ 6470'use strict'; 6471 6472exports.__esModule = true; 6473 6474function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6475 6476function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6477 6478function _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; } 6479 6480var _spacerJs = _dereq_('./spacer.js'); 6481 6482var _spacerJs2 = _interopRequireDefault(_spacerJs); 6483 6484var _componentJs = _dereq_('../../component.js'); 6485 6486var _componentJs2 = _interopRequireDefault(_componentJs); 6487 6488/** 6489 * Spacer specifically meant to be used as an insertion point for new plugins, etc. 6490 * 6491 * @extends Spacer 6492 * @class CustomControlSpacer 6493 */ 6494 6495var CustomControlSpacer = (function (_Spacer) { 6496 _inherits(CustomControlSpacer, _Spacer); 6497 6498 function CustomControlSpacer() { 6499 _classCallCheck(this, CustomControlSpacer); 6500 6501 _Spacer.apply(this, arguments); 6502 } 6503 6504 /** 6505 * Allow sub components to stack CSS class names 6506 * 6507 * @return {String} The constructed class name 6508 * @method buildCSSClass 6509 */ 6510 6511 CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() { 6512 return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this); 6513 }; 6514 6515 /** 6516 * Create the component's DOM element 6517 * 6518 * @return {Element} 6519 * @method createEl 6520 */ 6521 6522 CustomControlSpacer.prototype.createEl = function createEl() { 6523 var el = _Spacer.prototype.createEl.call(this, { 6524 className: this.buildCSSClass() 6525 }); 6526 6527 // No-flex/table-cell mode requires there be some content 6528 // in the cell to fill the remaining space of the table. 6529 el.innerHTML = ' '; 6530 return el; 6531 }; 6532 6533 return CustomControlSpacer; 6534})(_spacerJs2['default']); 6535 6536_componentJs2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer); 6537exports['default'] = CustomControlSpacer; 6538module.exports = exports['default']; 6539 6540},{"../../component.js":67,"./spacer.js":84}],84:[function(_dereq_,module,exports){ 6541/** 6542 * @file spacer.js 6543 */ 6544'use strict'; 6545 6546exports.__esModule = true; 6547 6548function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6549 6550function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6551 6552function _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
6552onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 6553 6554var _componentJs = _dereq_('../../component.js'); 6555 6556var _componentJs2 = _interopRequireDefault(_componentJs); 6557 6558/** 6559 * Just an empty spacer element that can be used as an append point for plugins, etc. 6560 * Also can be used to create space between elements when necessary. 6561 * 6562 * @extends Component 6563 * @class Spacer 6564 */ 6565 6566var Spacer = (function (_Component) { 6567 _inherits(Spacer, _Component); 6568 6569 function Spacer() { 6570 _classCallCheck(this, Spacer); 6571 6572 _Component.apply(this, arguments); 6573 } 6574 6575 /** 6576 * Allow sub components to stack CSS class names 6577 * 6578 * @return {String} The constructed class name 6579 * @method buildCSSClass 6580 */ 6581 6582 Spacer.prototype.buildCSSClass = function buildCSSClass() { 6583 return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this); 6584 }; 6585 6586 /** 6587 * Create the component's DOM element 6588 * 6589 * @return {Element} 6590 * @method createEl 6591 */ 6592 6593 Spacer.prototype.createEl = function createEl() { 6594 return _Component.prototype.createEl.call(this, 'div', { 6595 className: this.buildCSSClass() 6596 }); 6597 }; 6598 6599 return Spacer; 6600})(_componentJs2['default']); 6601 6602_componentJs2['default'].registerComponent('Spacer', Spacer); 6603 6604exports['default'] = Spacer; 6605module.exports = exports['default']; 6606 6607},{"../../component.js":67}],85:[function(_dereq_,module,exports){ 6608/** 6609 * @file caption-settings-menu-item.js 6610 */ 6611'use strict'; 6612 6613exports.__esModule = true; 6614 6615function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6616 6617function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6618 6619function _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; } 6620 6621var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js'); 6622 6623var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs); 6624 6625var _componentJs = _dereq_('../../component.js'); 6626 6627var _componentJs2 = _interopRequireDefault(_componentJs); 6628 6629/** 6630 * The menu item for caption track settings menu 6631 * 6632 * @param {Player|Object} player 6633 * @param {Object=} options 6634 * @extends TextTrackMenuItem 6635 * @class CaptionSettingsMenuItem 6636 */ 6637 6638var CaptionSettingsMenuItem = (function (_TextTrackMenuItem) { 6639 _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem); 6640 6641 function CaptionSettingsMenuItem(player, options) { 6642 _classCallCheck(this, CaptionSettingsMenuItem); 6643 6644 options['track'] = { 6645 'kind': options['kind'], 6646 'player': player, 6647 'label': options['kind'] + ' settings', 6648 'selectable': false, 6649 'default': false, 6650 mode: 'disabled' 6651 }; 6652 6653 // CaptionSettingsMenuItem has no concept of 'selected' 6654 options['selectable'] = false; 6655 6656 _TextTrackMenuItem.call(this, player, options); 6657 this.addClass('vjs-texttrack-settings'); 6658 this.controlText(', opens ' + options['kind'] + ' settings dialog'); 6659 } 6660 6661 /** 6662 * Handle click on menu item 6663 * 6664 * @method handleClick 6665 */ 6666 6667 CaptionSettingsMenuItem.prototype.handleClick = function handleClick() { 6668 this.player().getChild('textTrackSettings').show(); 6669 this.player().getChild('textTrackSettings').el_.focus(); 6670 }; 6671 6672 return CaptionSettingsMenuItem; 6673})(_textTrackMenuItemJs2['default']); 6674 6675_componentJs2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem); 6676exports['default'] = CaptionSettingsMenuItem; 6677module.exports = exports['default']; 6678 6679},{"../../component.js":67,"./text-track-menu-item.js":93}],86:[function(_dereq_,module,exports){ 6680/** 6681 * @file captions-button.js 6682 */ 6683'use strict'; 6684 6685exports.__esModule = true; 6686 6687function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6688 6689function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6690 6691function _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
6691onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 6692 6693var _textTrackButtonJs = _dereq_('./text-track-button.js'); 6694 6695var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs); 6696 6697var _componentJs = _dereq_('../../component.js'); 6698 6699var _componentJs2 = _interopRequireDefault(_componentJs); 6700 6701var _captionSettingsMenuItemJs = _dereq_('./caption-settings-menu-item.js'); 6702 6703var _captionSettingsMenuItemJs2 = _interopRequireDefault(_captionSettingsMenuItemJs); 6704 6705/** 6706 * The button component for toggling and selecting captions 6707 * 6708 * @param {Object} player Player object 6709 * @param {Object=} options Object of option names and values 6710 * @param {Function=} ready Ready callback function 6711 * @extends TextTrackButton 6712 * @class CaptionsButton 6713 */ 6714 6715var CaptionsButton = (function (_TextTrackButton) { 6716 _inherits(CaptionsButton, _TextTrackButton); 6717 6718 function CaptionsButton(player, options, ready) { 6719 _classCallCheck(this, CaptionsButton); 6720 6721 _TextTrackButton.call(this, player, options, ready); 6722 this.el_.setAttribute('aria-label', 'Captions Menu'); 6723 } 6724 6725 /** 6726 * Allow sub components to stack CSS class names 6727 * 6728 * @return {String} The constructed class name 6729 * @method buildCSSClass 6730 */ 6731 6732 CaptionsButton.prototype.buildCSSClass = function buildCSSClass() { 6733 return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 6734 }; 6735 6736 /** 6737 * Update caption menu items 6738 * 6739 * @method update 6740 */ 6741 6742 CaptionsButton.prototype.update = function update() { 6743 var threshold = 2; 6744 _TextTrackButton.prototype.update.call(this); 6745 6746 // if native, then threshold is 1 because no settings button 6747 if (this.player().tech_ && this.player().tech_['featuresNativeTextTracks']) { 6748 threshold = 1; 6749 } 6750 6751 if (this.items && this.items.length > threshold) { 6752 this.show(); 6753 } else { 6754 this.hide(); 6755 } 6756 }; 6757 6758 /** 6759 * Create caption menu items 6760 * 6761 * @return {Array} Array of menu items 6762 * @method createItems 6763 */ 6764 6765 CaptionsButton.prototype.createItems = function createItems() { 6766 var items = []; 6767 6768 if (!(this.player().tech_ && this.player().tech_['featuresNativeTextTracks'])) { 6769 items.push(new _captionSettingsMenuItemJs2['default'](this.player_, { 'kind': this.kind_ })); 6770 } 6771 6772 return _TextTrackButton.prototype.createItems.call(this, items); 6773 }; 6774 6775 return CaptionsButton; 6776})(_textTrackButtonJs2['default']); 6777 6778CaptionsButton.prototype.kind_ = 'captions'; 6779CaptionsButton.prototype.controlText_ = 'Captions'; 6780 6781_componentJs2['default'].registerComponent('CaptionsButton', CaptionsButton); 6782exports['default'] = CaptionsButton; 6783module.exports = exports['default']; 6784 6785},{"../../component.js":67,"./caption-settings-menu-item.js":85,"./text-track-button.js":92}],87:[function(_dereq_,module,exports){ 6786/** 6787 * @file chapters-button.js 6788 */ 6789'use strict'; 6790 6791exports.__esModule = true; 6792 6793function _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; } } 6794 6795function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6796 6797function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6798 6799function _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; } 6800 6801var _textTrackButtonJs = _dereq_('./text-track-button.js'); 6802 6803var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs); 6804 6805var _componentJs = _dereq_('../../component.js'); 6806 6807var _componentJs2 = _interopRequireDefault(_componentJs); 6808 6809var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js'); 6810 6811var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs); 6812 6813var _chaptersTrackMenuItemJs = _dereq_('./chapters-track-menu-item.js'); 6814 6815var _chaptersTrackMenuItemJs2 = _interopRequireDefault(_chaptersTrackMenuItemJs); 6816 6817var _menuMenuJs = _dereq_('../../menu/menu.js'); 6818 6819var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs); 6820 6821var _utilsDomJs = _dereq_('../../utils/dom.js'); 6822 6823var Dom = _interopRequireWildcard(_utilsDomJs); 6824 6825var _utilsFnJs = _dereq_('../../utils/fn.js'); 6826 6827var Fn = _interopRequireWildcard(_utilsFnJs); 6828 6829var _utilsToTitleCaseJs = _dereq_('../../utils/to-title-case.js'); 6830 6831var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs); 6832 6833var _globalWindow = _dereq_('global/window'); 6834 6835var _globalWindow2 = _interopRequireDefault(_globalWindow); 6836 6837/** 6838 * The button component for toggling and selecting chapters 6839 * Chapters act much differently than other text tracks 6840 * Cues are navigation vs. other tracks of alternative languages 6841 * 6842 * @param {Object} player Player object 6843 * @param {Object=} options Object of option names and values 6844 * @param {Function=} ready Ready callback function 6845 * @extends TextTrackButton 6846 * @class ChaptersButton 6847 */ 6848 6849var ChaptersButton = (function (_TextTrackButton) { 6850 _inherits(ChaptersButton, _TextTrackButton); 6851 6852 function ChaptersButton(player, options, ready) { 6853 _classCallCheck(this, ChaptersButton); 6854 6855 _TextTrackButton.call(this, player, options, ready); 6856 this.el_.setAttribute('aria-label', 'Chapters Menu'); 6857 } 6858 6859 /** 6860 * Allow sub components to stack CSS class names 6861 * 6862 * @return {String} The constructed class name 6863 * @method buildCSSClass 6864 */ 6865 6866 ChaptersButton.prototype.buildCSSClass = function buildCSSClass() { 6867 return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 6868 }; 6869 6870 /** 6871 * Create a menu item for each text track 6872 * 6873 * @return {Array} Array of menu items 6874 * @method createItems 6875 */ 6876 6877 ChaptersButton.prototype.createItems = function createItems() { 6878 var items = []; 6879 6880 var tracks = this.player_.textTracks(); 6881 6882 if (!tracks) { 6883 return items; 6884 } 6885 6886 for (var i = 0; i < tracks.length; i++) { 6887 var track = tracks[i]; 6888 if (track['kind'] === this.kind_) { 6889 items.push(new _textTrackMenuItemJs2['default'](this.player_, { 6890 'track': track 6891 })); 6892 } 6893 } 6894 6895 return items; 6896 }; 6897 6898 /** 6899 * Create menu from chapter buttons 6900 * 6901 * @return {Menu} Menu of chapter buttons 6902 * @method createMenu 6903 */ 6904 6905 ChaptersButton.prototype.createMenu = function createMenu() { 6906 var _this = this; 6907 6908 var tracks = this.player_.textTracks() || []; 6909 var chaptersTrack = undefined; 6910 var items = this.items = []; 6911 6912 for (var i = 0, _length = tracks.length; i < _length; i++) { 6913 var track = tracks[i]; 6914 6915 if (track['kind'] === this.kind_) { 6916 chaptersTrack = track; 6917 6918 break; 6919 } 6920 } 6921 6922 var menu = this.menu; 6923 if (menu === undefined) { 6924 menu = new _menuMenuJs2['default'](this.player_); 6925 var title = Dom.createEl('li', { 6926 className: 'vjs-menu-title', 6927 innerHTML: _utilsToTitleCaseJs2['default'](this.kind_), 6928 tabIndex: -1 6929 }); 6930 menu.children_.unshift(title); 6931 Dom.insertElFirst(title, menu.contentEl()); 6932 } 6933
6934 if (chaptersTrack && chaptersTrack.cues == null) { 6935 chaptersTrack['mode'] = 'hidden'; 6936 6937 var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(chaptersTrack); 6938 6939 if (remoteTextTrackEl) { 6940 remoteTextTrackEl.addEventListener('load', function (event) { 6941 return _this.update(); 6942 }); 6943 } 6944 } 6945 6946 if (chaptersTrack && chaptersTrack.cues && chaptersTrack.cues.length > 0) { 6947 var cues = chaptersTrack['cues'], 6948 cue = undefined; 6949 6950 for (var i = 0, l = cues.length; i < l; i++) { 6951 cue = cues[i]; 6952 6953 var mi = new _chaptersTrackMenuItemJs2['default'](this.player_, { 6954 'track': chaptersTrack, 6955 'cue': cue 6956 }); 6957 6958 items.push(mi); 6959 6960 menu.addChild(mi); 6961 } 6962 6963 this.addChild(menu); 6964 } 6965 6966 if (this.items.length > 0) { 6967 this.show(); 6968 } 6969 6970 return menu; 6971 }; 6972 6973 return ChaptersButton; 6974})(_textTrackButtonJs2['default']); 6975 6976ChaptersButton.prototype.kind_ = 'chapters'; 6977ChaptersButton.prototype.controlText_ = 'Chapters'; 6978 6979_componentJs2['default'].registerComponent('ChaptersButton', ChaptersButton); 6980exports['default'] = ChaptersButton; 6981module.exports = exports['default']; 6982 6983},{"../../component.js":67,"../../menu/menu.js":111,"../../utils/dom.js":143,"../../utils/fn.js":145,"../../utils/to-title-case.js":152,"./chapters-track-menu-item.js":88,"./text-track-button.js":92,"./text-track-menu-item.js":93,"global/window":2}],88:[function(_dereq_,module,exports){ 6984/** 6985 * @file chapters-track-menu-item.js 6986 */ 6987'use strict'; 6988 6989exports.__esModule = true; 6990 6991function _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; } } 6992 6993function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6994 6995function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6996 6997function _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; } 6998 6999var _menuMenuItemJs = _dereq_('../../menu/menu-item.js'); 7000 7001var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs); 7002 7003var _componentJs = _dereq_('../../component.js'); 7004 7005var _componentJs2 = _interopRequireDefault(_componentJs); 7006 7007var _utilsFnJs = _dereq_('../../utils/fn.js'); 7008 7009var Fn = _interopRequireWildcard(_utilsFnJs); 7010 7011/** 7012 * The chapter track menu item 7013 * 7014 * @param {Player|Object} player 7015 * @param {Object=} options 7016 * @extends MenuItem 7017 * @class ChaptersTrackMenuItem 7018 */ 7019 7020var ChaptersTrackMenuItem = (function (_MenuItem) { 7021 _inherits(ChaptersTrackMenuItem, _MenuItem); 7022 7023 function ChaptersTrackMenuItem(player, options) { 7024 _classCallCheck(this, ChaptersTrackMenuItem); 7025 7026 var track = options['track']; 7027 var cue = options['cue']; 7028 var currentTime = player.currentTime(); 7029 7030 // Modify options for parent MenuItem class's init. 7031 options['label'] = cue.text; 7032 options['selected'] = cue['startTime'] <= currentTime && currentTime < cue['endTime']; 7033 _MenuItem.call(this, player, options); 7034 7035 this.track = track; 7036 this.cue = cue; 7037 track.addEventListener('cuechange', Fn.bind(this, this.update)); 7038 } 7039 7040 /** 7041 * Handle click on menu item 7042 * 7043 * @method handleClick 7044 */ 7045 7046 ChaptersTrackMenuItem.prototype.handleClick = function handleClick() { 7047 _MenuItem.prototype.handleClick.call(this); 7048 this.player_.currentTime(this.cue.startTime); 7049 this.update(this.cue.startTime); 7050 }; 7051 7052 /** 7053 * Update chapter menu item 7054 * 7055 * @method update 7056 */ 7057
7058 ChaptersTrackMenuItem.prototype.update = function update() { 7059 var cue = this.cue; 7060 var currentTime = this.player_.currentTime(); 7061 7062 // vjs.log(currentTime, cue.startTime); 7063 this.selected(cue['startTime'] <= currentTime && currentTime < cue['endTime']); 7064 }; 7065 7066 return ChaptersTrackMenuItem; 7067})(_menuMenuItemJs2['default']); 7068 7069_componentJs2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem); 7070exports['default'] = ChaptersTrackMenuItem; 7071module.exports = exports['default']; 7072 7073},{"../../component.js":67,"../../menu/menu-item.js":110,"../../utils/fn.js":145}],89:[function(_dereq_,module,exports){ 7074/** 7075 * @file descriptions-button.js 7076 */ 7077'use strict'; 7078 7079exports.__esModule = true; 7080 7081function _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; } } 7082 7083function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7084 7085function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7086 7087function _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; } 7088 7089var _textTrackButtonJs = _dereq_('./text-track-button.js'); 7090 7091var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs); 7092 7093var _componentJs = _dereq_('../../component.js'); 7094 7095var _componentJs2 = _interopRequireDefault(_componentJs); 7096 7097var _utilsFnJs = _dereq_('../../utils/fn.js'); 7098 7099var Fn = _interopRequireWildcard(_utilsFnJs); 7100 7101/** 7102 * The button component for toggling and selecting descriptions 7103 * 7104 * @param {Object} player Player object 7105 * @param {Object=} options Object of option names and values 7106 * @param {Function=} ready Ready callback function 7107 * @extends TextTrackButton 7108 * @class DescriptionsButton 7109 */ 7110 7111var DescriptionsButton = (function (_TextTrackButton) { 7112 _inherits(DescriptionsButton, _TextTrackButton); 7113 7114 function DescriptionsButton(player, options, ready) { 7115 var _this = this; 7116 7117 _classCallCheck(this, DescriptionsButton); 7118 7119 _TextTrackButton.call(this, player, options, ready); 7120 this.el_.setAttribute('aria-label', 'Descriptions Menu'); 7121 7122 var tracks = player.textTracks(); 7123 7124 if (tracks) { 7125 (function () { 7126 var changeHandler = Fn.bind(_this, _this.handleTracksChange); 7127 7128 tracks.addEventListener('change', changeHandler); 7129 _this.on('dispose', function () { 7130 tracks.removeEventListener('change', changeHandler); 7131 }); 7132 })(); 7133 } 7134 } 7135 7136 /** 7137 * Handle text track change 7138 * 7139 * @method handleTracksChange 7140 */ 7141 7142 DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) { 7143 var tracks = this.player().textTracks(); 7144 var disabled = false; 7145 7146 // Check whether a track of a different kind is showing 7147 for (var i = 0, l = tracks.length; i < l; i++) { 7148 var track = tracks[i]; 7149 if (track['kind'] !== this.kind_ && track['mode'] === 'showing') { 7150 disabled = true; 7151 break; 7152 } 7153 } 7154 7155 // If another track is showing, disable this menu button 7156 if (disabled) { 7157 this.disable(); 7158 } else { 7159 this.enable(); 7160 } 7161 }; 7162 7163 /** 7164 * Allow sub components to stack CSS class names 7165 * 7166 * @return {String} The constructed class name 7167 * @method buildCSSClass 7168 */ 7169 7170 DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() { 7171 return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 7172 }; 7173 7174 return DescriptionsButton; 7175})(_textTrackButtonJs2['default']); 7176 7177DescriptionsButton.prototype.kind_ = 'descriptions'; 7178DescriptionsButton.prototype.controlText_ = 'Descriptions'; 7179 7180_componentJs2['default'].registerComponent('DescriptionsButton', DescriptionsButton); 7181exports['default'] = DescriptionsButton; 7182module.exports = exports['default']; 7183 7184},{"../../component.js":67,"../../utils/fn.js":145,"./text-track-button.js":92}],90:[function(_dereq_,module,exports){ 7185/** 7186 * @file off-text-track-menu-item.js 7187 */ 7188'use strict'; 7189 7190exports.__esModule = true; 7191 7192function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7193 7194function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7195 7196function _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
7196onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 7197 7198var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js'); 7199 7200var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs); 7201 7202var _componentJs = _dereq_('../../component.js'); 7203 7204var _componentJs2 = _interopRequireDefault(_componentJs); 7205 7206/** 7207 * A special menu item for turning of a specific type of text track 7208 * 7209 * @param {Player|Object} player 7210 * @param {Object=} options 7211 * @extends TextTrackMenuItem 7212 * @class OffTextTrackMenuItem 7213 */ 7214 7215var OffTextTrackMenuItem = (function (_TextTrackMenuItem) { 7216 _inherits(OffTextTrackMenuItem, _TextTrackMenuItem); 7217 7218 function OffTextTrackMenuItem(player, options) { 7219 _classCallCheck(this, OffTextTrackMenuItem); 7220 7221 // Create pseudo track info 7222 // Requires options['kind'] 7223 options['track'] = { 7224 'kind': options['kind'], 7225 'player': player, 7226 'label': options['kind'] + ' off', 7227 'default': false, 7228 'mode': 'disabled' 7229 }; 7230 7231 // MenuItem is selectable 7232 options['selectable'] = true; 7233 7234 _TextTrackMenuItem.call(this, player, options); 7235 this.selected(true); 7236 } 7237 7238 /** 7239 * Handle text track change 7240 * 7241 * @param {Object} event Event object 7242 * @method handleTracksChange 7243 */ 7244 7245 OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { 7246 var tracks = this.player().textTracks(); 7247 var selected = true; 7248 7249 for (var i = 0, l = tracks.length; i < l; i++) { 7250 var track = tracks[i]; 7251 if (track['kind'] === this.track['kind'] && track['mode'] === 'showing') { 7252 selected = false; 7253 break; 7254 } 7255 } 7256 7257 this.selected(selected); 7258 }; 7259 7260 return OffTextTrackMenuItem; 7261})(_textTrackMenuItemJs2['default']); 7262 7263_componentJs2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem); 7264exports['default'] = OffTextTrackMenuItem; 7265module.exports = exports['default']; 7266 7267},{"../../component.js":67,"./text-track-menu-item.js":93}],91:[function(_dereq_,module,exports){ 7268/** 7269 * @file subtitles-button.js 7270 */ 7271'use strict'; 7272 7273exports.__esModule = true; 7274 7275function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7276 7277function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7278 7279function _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; } 7280 7281var _textTrackButtonJs = _dereq_('./text-track-button.js'); 7282 7283var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs); 7284 7285var _componentJs = _dereq_('../../component.js'); 7286 7287var _componentJs2 = _interopRequireDefault(_componentJs); 7288 7289/** 7290 * The button component for toggling and selecting subtitles 7291 * 7292 * @param {Object} player Player object 7293 * @param {Object=} options Object of option names and values 7294 * @param {Function=} ready Ready callback function 7295 * @extends TextTrackButton 7296 * @class SubtitlesButton 7297 */ 7298 7299var SubtitlesButton = (function (_TextTrackButton) { 7300 _inherits(SubtitlesButton, _TextTrackButton); 7301 7302 function SubtitlesButton(player, options, ready) { 7303 _classCallCheck(this, SubtitlesButton); 7304 7305 _TextTrackButton.call(this, player, options, ready); 7306 this.el_.setAttribute('aria-label', 'Subtitles Menu'); 7307 } 7308 7309 /** 7310 * Allow sub components to stack CSS class names 7311 * 7312 * @return {String} The constructed class name 7313 * @method buildCSSClass 7314 */ 7315 7316 SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() { 7317 return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 7318 }; 7319 7320 return SubtitlesButton; 7321})(_textTrackButtonJs2['default']); 7322 7323SubtitlesButton.prototype.kind_ = 'subtitles'; 7324SubtitlesButton.prototype.controlText_ = 'Subtitles'; 7325 7326_componentJs2['default'].registerComponent('SubtitlesButton', SubtitlesButton); 7327exports['default'] = SubtitlesButton; 7328module.exports = exports['default']; 7329 7330},{"../../component.js":67,"./text-track-button.js":92}],92:[function(_dereq_,module,exports){ 7331/** 7332 * @file text-track-button.js 7333 */ 7334'use strict'; 7335 7336exports.__esModule = true; 7337 7338function _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; } } 7339 7340function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7341 7342function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7343 7344function _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
7344onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 7345 7346var _trackButtonJs = _dereq_('../track-button.js'); 7347 7348var _trackButtonJs2 = _interopRequireDefault(_trackButtonJs); 7349 7350var _componentJs = _dereq_('../../component.js'); 7351 7352var _componentJs2 = _interopRequireDefault(_componentJs); 7353 7354var _utilsFnJs = _dereq_('../../utils/fn.js'); 7355 7356var Fn = _interopRequireWildcard(_utilsFnJs); 7357 7358var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js'); 7359 7360var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs); 7361 7362var _offTextTrackMenuItemJs = _dereq_('./off-text-track-menu-item.js'); 7363 7364var _offTextTrackMenuItemJs2 = _interopRequireDefault(_offTextTrackMenuItemJs); 7365 7366/** 7367 * The base class for buttons that toggle specific text track types (e.g. subtitles) 7368 * 7369 * @param {Player|Object} player 7370 * @param {Object=} options 7371 * @extends MenuButton 7372 * @class TextTrackButton 7373 */ 7374 7375var TextTrackButton = (function (_TrackButton) { 7376 _inherits(TextTrackButton, _TrackButton); 7377 7378 function TextTrackButton(player) { 7379 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 7380 7381 _classCallCheck(this, TextTrackButton); 7382 7383 options.tracks = player.textTracks(); 7384 7385 _TrackButton.call(this, player, options); 7386 } 7387 7388 /** 7389 * Create a menu item for each text track 7390 * 7391 * @return {Array} Array of menu items 7392 * @method createItems 7393 */ 7394 7395 TextTrackButton.prototype.createItems = function createItems() { 7396 var items = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; 7397 7398 // Add an OFF menu item to turn all tracks off 7399 items.push(new _offTextTrackMenuItemJs2['default'](this.player_, { 'kind': this.kind_ })); 7400 7401 var tracks = this.player_.textTracks(); 7402 7403 if (!tracks) { 7404 return items; 7405 } 7406 7407 for (var i = 0; i < tracks.length; i++) { 7408 var track = tracks[i]; 7409 7410 // only add tracks that are of the appropriate kind and have a label 7411 if (track['kind'] === this.kind_) { 7412 items.push(new _textTrackMenuItemJs2['default'](this.player_, { 7413 // MenuItem is selectable 7414 'selectable': true, 7415 'track': track 7416 })); 7417 } 7418 } 7419 7420 return items; 7421 }; 7422 7423 return TextTrackButton; 7424})(_trackButtonJs2['default']); 7425 7426_componentJs2['default'].registerComponent('TextTrackButton', TextTrackButton); 7427exports['default'] = TextTrackButton; 7428module.exports = exports['default']; 7429 7430},{"../../component.js":67,"../../utils/fn.js":145,"../track-button.js":98,"./off-text-track-menu-item.js":90,"./text-track-menu-item.js":93}],93:[function(_dereq_,module,exports){ 7431/** 7432 * @file text-track-menu-item.js 7433 */ 7434'use strict'; 7435 7436exports.__esModule = true; 7437 7438function _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; } } 7439 7440function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7441 7442function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7443 7444function _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; } 7445 7446var _menuMenuItemJs = _dereq_('../../menu/menu-item.js'); 7447 7448var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs); 7449 7450var _componentJs = _dereq_('../../component.js'); 7451 7452var _componentJs2 = _interopRequireDefault(_componentJs); 7453 7454var _utilsFnJs = _dereq_('../../utils/fn.js'); 7455 7456var Fn = _interopRequireWildcard(_utilsFnJs); 7457 7458var _globalWindow = _dereq_('global/window'); 7459 7460var _globalWindow2 = _interopRequireDefault(_globalWindow); 7461 7462var _globalDocument = _dereq_('global/document'); 7463 7464var _globalDocument2 = _interopRequireDefault(_globalDocument); 7465 7466/** 7467 * The specific menu item type for selecting a language within a text track kind 7468 * 7469 * @param {Player|Object} player 7470 * @param {Object=} options 7471 * @extends MenuItem 7472 * @class TextTrackMenuItem 7473 */ 7474 7475var TextTrackMenuItem = (function (_MenuItem) { 7476 _inherits(TextTrackMenuItem, _MenuItem); 7477 7478 function TextTrackMenuItem(player, options) { 7479 var _this = this; 7480 7481 _classCallCheck(this, TextTrackMenuItem); 7482 7483 var track = options['track']; 7484 var tracks = player.textTracks(); 7485 7486 // Modify options for parent MenuItem class's init. 7487 options['label'] = track['label'] || track['language'] || 'Unknown'; 7488 options['selected'] = track['default'] || track['mode'] === 'showing'; 7489 7490 _MenuItem.call(this, player, options); 7491 7492 this.track = track; 7493 7494 if (tracks) { 7495 (function () { 7496 var changeHandler = Fn.bind(_this, _this.handleTracksChange); 7497 7498 tracks.addEventListener('change', changeHandler); 7499 _this.on('dispose', function () { 7500 tracks.removeEventListener('change', changeHandler); 7501 }); 7502 })(); 7503 } 7504 7505 // iOS7 doesn't dispatch change events to TextTrackLists when an 7506 // associated track's mode changes. Without something like 7507 // Object.observe() (also not present on iOS7), it's not 7508 // possible to detect changes to the mode attribute and polyfill 7509 // the change event. As a poor substitute, we manually dispatch 7510 // change events whenever the controls modify the mode. 7511 if (tracks && tracks.onchange === undefined) { 7512 (function () { 7513 var event = undefined; 7514 7515 _this.on(['tap', 'click'], function () { 7516 if (typeof _globalWindow2['default'].Event !== 'object') { 7517 // Android 2.3 throws an Illegal Constructor error for window.Event 7518 try { 7519 event = new _globalWindow2['default'].Event('change'); 7520 } catch (err) {} 7521 } 7522 7523 if (!event) { 7524 event = _globalDocument2['default'].createEvent('Event'); 7525 event.initEvent('change', true, true); 7526 } 7527 7528 tracks.dispatchEvent(event); 7529 }); 7530 })(); 7531 } 7532 } 7533 7534 /** 7535 * Handle click on text track 7536 * 7537 * @method handleClick 7538 */ 7539 7540 TextTrackMenuItem.prototype.handleClick = function handleClick(event) { 7541 var kind = this.track['kind']; 7542 var tracks = this.player_.textTracks(); 7543 7544 _MenuItem.prototype.handleClick.call(this, event); 7545 7546 if (!tracks) return; 7547 7548 for (var i = 0; i < tracks.length; i++) { 7549 var track = tracks[i]; 7550 7551 if (track['kind'] !== kind) { 7552 continue; 7553 } 7554 7555 if (track === this.track) { 7556 track['mode'] = 'showing'; 7557 } else { 7558 track['mode'] = 'disabled'; 7559 } 7560 } 7561 }; 7562 7563 /** 7564 * Handle text track change 7565 * 7566 * @method handleTracksChange 7567 */ 7568 7569 TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { 7570 this.selected(this.track['mode'] === 'showing'); 7571 }; 7572 7573 return TextTrackMenuItem; 7574}
7574)(_menuMenuItemJs2['default']); 7575 7576_componentJs2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem); 7577exports['default'] = TextTrackMenuItem; 7578module.exports = exports['default']; 7579 7580},{"../../component.js":67,"../../menu/menu-item.js":110,"../../utils/fn.js":145,"global/document":1,"global/window":2}],94:[function(_dereq_,module,exports){ 7581/** 7582 * @file current-time-display.js 7583 */ 7584'use strict'; 7585 7586exports.__esModule = true; 7587 7588function _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; } } 7589 7590function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7591 7592function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7593 7594function _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; } 7595 7596var _componentJs = _dereq_('../../component.js'); 7597 7598var _componentJs2 = _interopRequireDefault(_componentJs); 7599 7600var _utilsDomJs = _dereq_('../../utils/dom.js'); 7601 7602var Dom = _interopRequireWildcard(_utilsDomJs); 7603 7604var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js'); 7605 7606var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 7607 7608/** 7609 * Displays the current time 7610 * 7611 * @param {Player|Object} player 7612 * @param {Object=} options 7613 * @extends Component 7614 * @class CurrentTimeDisplay 7615 */ 7616 7617var CurrentTimeDisplay = (function (_Component) { 7618 _inherits(CurrentTimeDisplay, _Component); 7619 7620 function CurrentTimeDisplay(player, options) { 7621 _classCallCheck(this, CurrentTimeDisplay); 7622 7623 _Component.call(this, player, options); 7624 7625 this.on(player, 'timeupdate', this.updateContent); 7626 } 7627 7628 /** 7629 * Create the component's DOM element 7630 * 7631 * @return {Element} 7632 * @method createEl 7633 */ 7634 7635 CurrentTimeDisplay.prototype.createEl = function createEl() { 7636 var el = _Component.prototype.createEl.call(this, 'div', { 7637 className: 'vjs-current-time vjs-time-control vjs-control' 7638 }); 7639 7640 this.contentEl_ = Dom.createEl('div', { 7641 className: 'vjs-current-time-display', 7642 // label the current time for screen reader users 7643 innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00' 7644 }, { 7645 // tell screen readers not to automatically read the time as it changes 7646 'aria-live': 'off' 7647 }); 7648 7649 el.appendChild(this.contentEl_); 7650 return el; 7651 }; 7652 7653 /** 7654 * Update current time display 7655 * 7656 * @method updateContent 7657 */ 7658 7659 CurrentTimeDisplay.prototype.updateContent = function updateContent() { 7660 // Allows for smooth scrubbing, when player can't keep up. 7661 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 7662 var localizedText = this.localize('Current Time'); 7663 var formattedTime = _utilsFormatTimeJs2['default'](time, this.player_.duration()); 7664 if (formattedTime !== this.formattedTime_) { 7665 this.formattedTime_ = formattedTime; 7666 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; 7667 } 7668 }; 7669 7670 return CurrentTimeDisplay; 7671})(_componentJs2['default']); 7672 7673_componentJs2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay); 7674exports['default'] = CurrentTimeDisplay; 7675module.exports = exports['default']; 7676 7677},{"../../component.js":67,"../../utils/dom.js":143,"../../utils/format-time.js":146}],95:[function(_dereq_,module,exports){ 7678/** 7679 * @file duration-display.js 7680 */ 7681'use strict'; 7682 7683exports.__esModule = true; 7684 7685function _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; } } 7686 7687function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7688 7689function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7690 7691function _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
7691onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 7692 7693var _componentJs = _dereq_('../../component.js'); 7694 7695var _componentJs2 = _interopRequireDefault(_componentJs); 7696 7697var _utilsDomJs = _dereq_('../../utils/dom.js'); 7698 7699var Dom = _interopRequireWildcard(_utilsDomJs); 7700 7701var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js'); 7702 7703var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 7704 7705/** 7706 * Displays the duration 7707 * 7708 * @param {Player|Object} player 7709 * @param {Object=} options 7710 * @extends Component 7711 * @class DurationDisplay 7712 */ 7713 7714var DurationDisplay = (function (_Component) { 7715 _inherits(DurationDisplay, _Component); 7716 7717 function DurationDisplay(player, options) { 7718 _classCallCheck(this, DurationDisplay); 7719 7720 _Component.call(this, player, options); 7721 7722 // this might need to be changed to 'durationchange' instead of 'timeupdate' eventually, 7723 // however the durationchange event fires before this.player_.duration() is set, 7724 // so the value cannot be written out using this method. 7725 // Once the order of durationchange and this.player_.duration() being set is figured out, 7726 // this can be updated. 7727 this.on(player, 'timeupdate', this.updateContent); 7728 this.on(player, 'loadedmetadata', this.updateContent); 7729 } 7730 7731 /** 7732 * Create the component's DOM element 7733 * 7734 * @return {Element} 7735 * @method createEl 7736 */ 7737 7738 DurationDisplay.prototype.createEl = function createEl() { 7739 var el = _Component.prototype.createEl.call(this, 'div', { 7740 className: 'vjs-duration vjs-time-control vjs-control' 7741 }); 7742 7743 this.contentEl_ = Dom.createEl('div', { 7744 className: 'vjs-duration-display', 7745 // label the duration time for screen reader users 7746 innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00' 7747 }, { 7748 // tell screen readers not to automatically read the time as it changes 7749 'aria-live': 'off' 7750 }); 7751 7752 el.appendChild(this.contentEl_); 7753 return el; 7754 }; 7755 7756 /** 7757 * Update duration time display 7758 * 7759 * @method updateContent 7760 */ 7761 7762 DurationDisplay.prototype.updateContent = function updateContent() { 7763 var duration = this.player_.duration(); 7764 if (duration && this.duration_ !== duration) { 7765 this.duration_ = duration; 7766 var localizedText = this.localize('Duration Time'); 7767 var formattedTime = _utilsFormatTimeJs2['default'](duration); 7768 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; // label the duration time for screen reader users 7769 } 7770 }; 7771 7772 return DurationDisplay; 7773})(_componentJs2['default']); 7774 7775_componentJs2['default'].registerComponent('DurationDisplay', DurationDisplay); 7776exports['default'] = DurationDisplay; 7777module.exports = exports['default']; 7778 7779},{"../../component.js":67,"../../utils/dom.js":143,"../../utils/format-time.js":146}],96:[function(_dereq_,module,exports){ 7780/** 7781 * @file remaining-time-display.js 7782 */ 7783'use strict'; 7784 7785exports.__esModule = true; 7786 7787function _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; } } 7788 7789function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7790 7791function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7792 7793function _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; } 7794 7795var _componentJs = _dereq_('../../component.js'); 7796 7797var _componentJs2 = _interopRequireDefault(_componentJs); 7798 7799var _utilsDomJs = _dereq_('../../utils/dom.js'); 7800 7801var Dom = _interopRequireWildcard(_utilsDomJs); 7802 7803var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js'); 7804 7805var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 7806 7807/** 7808 * Displays the time left in the video 7809 * 7810 * @param {Player|Object} player 7811 * @param {Object=} options 7812 * @extends Component 7813 * @class RemainingTimeDisplay 7814 */ 7815 7816var RemainingTimeDisplay = (function (_Component) { 7817 _inherits(RemainingTimeDisplay, _Component); 7818 7819 function RemainingTimeDisplay(player, options) { 7820 _classCallCheck(this, RemainingTimeDisplay); 7821 7822 _Component.call(this, player, options); 7823 7824 this.on(player, 'timeupdate', this.updateContent); 7825 } 7826 7827 /** 7828 * Create the component's DOM element 7829 * 7830 * @return {Element} 7831 * @method createEl 7832 */ 7833 7834 RemainingTimeDisplay.prototype.createEl = function createEl() { 7835 var el = _Component.prototype.createEl.call(this, 'div', { 7836 className: 'vjs-remaining-time vjs-time-control vjs-control' 7837 }); 7838 7839 this.contentEl_ = Dom.createEl('div', { 7840 className: 'vjs-remaining-time-display', 7841 // label the remaining time for screen reader users 7842 innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00' 7843 }, {
7844 // tell screen readers not to automatically read the time as it changes 7845 'aria-live': 'off' 7846 }); 7847 7848 el.appendChild(this.contentEl_); 7849 return el; 7850 }; 7851 7852 /** 7853 * Update remaining time display 7854 * 7855 * @method updateContent 7856 */ 7857 7858 RemainingTimeDisplay.prototype.updateContent = function updateContent() { 7859 if (this.player_.duration()) { 7860 var localizedText = this.localize('Remaining Time'); 7861 var formattedTime = _utilsFormatTimeJs2['default'](this.player_.remainingTime()); 7862 if (formattedTime !== this.formattedTime_) { 7863 this.formattedTime_ = formattedTime; 7864 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime; 7865 } 7866 } 7867 7868 // Allows for smooth scrubbing, when player can't keep up. 7869 // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime(); 7870 // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration()); 7871 }; 7872 7873 return RemainingTimeDisplay; 7874})(_componentJs2['default']); 7875 7876_componentJs2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay); 7877exports['default'] = RemainingTimeDisplay; 7878module.exports = exports['default']; 7879 7880},{"../../component.js":67,"../../utils/dom.js":143,"../../utils/format-time.js":146}],97:[function(_dereq_,module,exports){ 7881/** 7882 * @file time-divider.js 7883 */ 7884'use strict'; 7885 7886exports.__esModule = true; 7887 7888function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7889 7890function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7891 7892function _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; } 7893 7894var _componentJs = _dereq_('../../component.js'); 7895 7896var _componentJs2 = _interopRequireDefault(_componentJs); 7897 7898/** 7899 * The separator between the current time and duration. 7900 * Can be hidden if it's not needed in the design. 7901 * 7902 * @param {Player|Object} player 7903 * @param {Object=} options 7904 * @extends Component 7905 * @class TimeDivider 7906 */ 7907 7908var TimeDivider = (function (_Component) { 7909 _inherits(TimeDivider, _Component); 7910 7911 function TimeDivider() { 7912 _classCallCheck(this, TimeDivider); 7913 7914 _Component.apply(this, arguments); 7915 } 7916 7917 /** 7918 * Create the component's DOM element 7919 * 7920 * @return {Element} 7921 * @method createEl 7922 */ 7923 7924 TimeDivider.prototype.createEl = function createEl() { 7925 return _Component.prototype.createEl.call(this, 'div', { 7926 className: 'vjs-time-control vjs-time-divider', 7927 innerHTML: '<div><span>/</span></div>' 7928 }); 7929 }; 7930 7931 return TimeDivider; 7932})(_componentJs2['default']); 7933 7934_componentJs2['default'].registerComponent('TimeDivider', TimeDivider); 7935exports['default'] = TimeDivider; 7936module.exports = exports['default']; 7937 7938},{"../../component.js":67}],98:[function(_dereq_,module,exports){ 7939/** 7940 * @file track-button.js 7941 */ 7942'use strict'; 7943 7944exports.__esModule = true; 7945 7946function _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; } } 7947 7948function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7949 7950function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7951 7952function _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
7952onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 7953 7954var _menuMenuButtonJs = _dereq_('../menu/menu-button.js'); 7955 7956var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs); 7957 7958var _componentJs = _dereq_('../component.js'); 7959 7960var _componentJs2 = _interopRequireDefault(_componentJs); 7961 7962var _utilsFnJs = _dereq_('../utils/fn.js'); 7963 7964var Fn = _interopRequireWildcard(_utilsFnJs); 7965 7966/** 7967 * The base class for buttons that toggle specific text track types (e.g. subtitles) 7968 * 7969 * @param {Player|Object} player 7970 * @param {Object=} options 7971 * @extends MenuButton 7972 * @class TrackButton 7973 */ 7974 7975var TrackButton = (function (_MenuButton) { 7976 _inherits(TrackButton, _MenuButton); 7977 7978 function TrackButton(player, options) { 7979 _classCallCheck(this, TrackButton); 7980 7981 var tracks = options.tracks; 7982 7983 _MenuButton.call(this, player, options); 7984 7985 if (this.items.length <= 1) { 7986 this.hide(); 7987 } 7988 7989 if (!tracks) { 7990 return; 7991 } 7992 7993 var updateHandler = Fn.bind(this, this.update); 7994 tracks.addEventListener('removetrack', updateHandler); 7995 tracks.addEventListener('addtrack', updateHandler); 7996 7997 this.player_.on('dispose', function () { 7998 tracks.removeEventListener('removetrack', updateHandler); 7999 tracks.removeEventListener('addtrack', updateHandler); 8000 }); 8001 } 8002 8003 return TrackButton; 8004}
8004)(_menuMenuButtonJs2['default']); 8005 8006_componentJs2['default'].registerComponent('TrackButton', TrackButton); 8007exports['default'] = TrackButton; 8008module.exports = exports['default']; 8009 8010},{"../component.js":67,"../menu/menu-button.js":109,"../utils/fn.js":145}],99:[function(_dereq_,module,exports){ 8011/** 8012 * @file volume-bar.js 8013 */ 8014'use strict'; 8015 8016exports.__esModule = true; 8017 8018function _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; } } 8019 8020function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8021 8022function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 8023 8024function _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; } 8025 8026var _sliderSliderJs = _dereq_('../../slider/slider.js'); 8027 8028var _sliderSliderJs2 = _interopRequireDefault(_sliderSliderJs); 8029 8030var _componentJs = _dereq_('../../component.js'); 8031 8032var _componentJs2 = _interopRequireDefault(_componentJs); 8033 8034var _utilsFnJs = _dereq_('../../utils/fn.js'); 8035 8036var Fn = _interopRequireWildcard(_utilsFnJs); 8037 8038// Required children 8039 8040var _volumeLevelJs = _dereq_('./volume-level.js'); 8041 8042var _volumeLevelJs2 = _interopRequireDefault(_volumeLevelJs); 8043 8044/** 8045 * The bar that contains the volume level and can be clicked on to adjust the level 8046 * 8047 * @param {Player|Object} player 8048 * @param {Object=} options 8049 * @extends Slider 8050 * @class VolumeBar 8051 */ 8052 8053var VolumeBar = (function (_Slider) { 8054 _inherits(VolumeBar, _Slider); 8055 8056 function VolumeBar(player, options) { 8057 _classCallCheck(this, VolumeBar); 8058 8059 _Slider.call(this, player, options); 8060 this.on(player, 'volumechange', this.updateARIAAttributes); 8061 player.ready(Fn.bind(this, this.updateARIAAttributes)); 8062 } 8063 8064 /** 8065 * Create the component's DOM element 8066 * 8067 * @return {Element} 8068 * @method createEl 8069 */ 8070 8071 VolumeBar.prototype.createEl = function createEl() { 8072 return _Slider.prototype.createEl.call(this, 'div', { 8073 className: 'vjs-volume-bar vjs-slider-bar' 8074 }, { 8075 'aria-label': 'volume level' 8076 }); 8077 }; 8078 8079 /** 8080 * Handle mouse move on volume bar 8081 * 8082 * @method handleMouseMove 8083 */ 8084 8085 VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) { 8086 this.checkMuted(); 8087 this.player_.volume(this.calculateDistance(event)); 8088 }; 8089 8090 VolumeBar.prototype.checkMuted = function checkMuted() { 8091 if (this.player_.muted()) { 8092 this.player_.muted(false); 8093 } 8094 }; 8095 8096 /** 8097 * Get percent of volume level 8098 * 8099 * @retun {Number} Volume level percent 8100 * @method getPercent 8101 */ 8102 8103 VolumeBar.prototype.getPercent = function getPercent() { 8104 if (this.player_.muted()) { 8105 return 0; 8106 } else { 8107 return this.player_.volume(); 8108 } 8109 }; 8110 8111 /** 8112 * Increase volume level for keyboard users 8113 * 8114 * @method stepForward 8115 */ 8116 8117 VolumeBar.prototype.stepForward = function stepForward() { 8118 this.checkMuted(); 8119 this.player_.volume(this.player_.volume() + 0.1); 8120 }; 8121 8122 /** 8123 * Decrease volume level for keyboard users 8124 * 8125 * @method stepBack 8126 */ 8127 8128 VolumeBar.prototype.stepBack = function stepBack() { 8129 this.checkMuted(); 8130 this.player_.volume(this.player_.volume() - 0.1); 8131 }; 8132 8133 /** 8134 * Update ARIA accessibility attributes 8135 * 8136 * @method updateARIAAttributes 8137 */ 8138 8139 VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes() { 8140 // Current value of volume bar as a percentage 8141 var volume = (this.player_.volume() * 100).toFixed(2); 8142 this.el_.setAttribute('aria-valuenow', volume);
8143 this.el_.setAttribute('aria-valuetext', volume + '%'); 8144 }; 8145 8146 return VolumeBar; 8147})(_sliderSliderJs2['default']); 8148 8149VolumeBar.prototype.options_ = { 8150 children: ['volumeLevel'], 8151 'barName': 'volumeLevel' 8152}; 8153 8154VolumeBar.prototype.playerEvent = 'volumechange'; 8155 8156_componentJs2['default'].registerComponent('VolumeBar', VolumeBar); 8157exports['default'] = VolumeBar; 8158module.exports = exports['default']; 8159 8160},{"../../component.js":67,"../../slider/slider.js":119,"../../utils/fn.js":145,"./volume-level.js":101}],100:[function(_dereq_,module,exports){ 8161/** 8162 * @file volume-control.js 8163 */ 8164'use strict'; 8165 8166exports.__esModule = true; 8167 8168function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8169 8170function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 8171 8172function _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; } 8173 8174var _componentJs = _dereq_('../../component.js'); 8175 8176var _componentJs2 = _interopRequireDefault(_componentJs); 8177 8178// Required children 8179 8180var _volumeBarJs = _dereq_('./volume-bar.js'); 8181 8182var _volumeBarJs2 = _interopRequireDefault(_volumeBarJs); 8183 8184/** 8185 * The component for controlling the volume level 8186 * 8187 * @param {Player|Object} player 8188 * @param {Object=} options 8189 * @extends Component 8190 * @class VolumeControl 8191 */ 8192 8193var VolumeControl = (function (_Component) { 8194 _inherits(VolumeControl, _Component); 8195 8196 function VolumeControl(player, options) { 8197 _classCallCheck(this, VolumeControl); 8198 8199 _Component.call(this, player, options); 8200 8201 // hide volume controls when they're not supported by the current tech 8202 if (player.tech_ && player.tech_['featuresVolumeControl'] === false) { 8203 this.addClass('vjs-hidden'); 8204 } 8205 this.on(player, 'loadstart', function () { 8206 if (player.tech_['featuresVolumeControl'] === false) { 8207 this.addClass('vjs-hidden'); 8208 } else { 8209 this.removeClass('vjs-hidden'); 8210 } 8211 }); 8212 } 8213 8214 /** 8215 * Create the component's DOM element 8216 * 8217 * @return {Element} 8218 * @method createEl 8219 */ 8220 8221 VolumeControl.prototype.createEl = function createEl() { 8222 return _Component.prototype.createEl.call(this, 'div', { 8223 className: 'vjs-volume-control vjs-control' 8224 }); 8225 }; 8226 8227 return VolumeControl; 8228})(_componentJs2['default']); 8229 8230VolumeControl.prototype.options_ = { 8231 children: ['volumeBar'] 8232}; 8233 8234_componentJs2['default'].registerComponent('VolumeControl', VolumeControl); 8235exports['default'] = VolumeControl; 8236module.exports = exports['default']; 8237 8238},{"../../component.js":67,"./volume-bar.js":99}],101:[function(_dereq_,module,exports){ 8239/** 8240 * @file volume-level.js 8241 */ 8242'use strict'; 8243 8244exports.__esModule = true; 8245 8246function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8247 8248function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 8249 8250function _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; } 8251 8252var _componentJs = _dereq_('../../component.js'); 8253 8254var _componentJs2 = _interopRequireDefault(_componentJs); 8255 8256/** 8257 * Shows volume level 8258 * 8259 * @param {Player|Object} player 8260 * @param {Object=} options 8261 * @extends Component 8262 * @class VolumeLevel 8263 */ 8264 8265var VolumeLevel = (function (_Component) { 8266 _inherits(VolumeLevel, _Component); 8267 8268 function VolumeLevel() { 8269 _classCallCheck(this, VolumeLevel); 8270 8271 _Component.apply(this, arguments); 8272 } 8273 8274 /** 8275 * Create the component's DOM element 8276 * 8277 * @return {Element} 8278 * @method createEl 8279 */ 8280 8281 VolumeLevel.prototype.createEl = function createEl() { 8282 return _Component.prototype.createEl.call(this, 'div', { 8283 className: 'vjs-volume-level', 8284 innerHTML: '<span class="vjs-control-text"></span>' 8285 }); 8286 }; 8287 8288 return VolumeLevel; 8289})(_componentJs2['default']); 8290 8291_componentJs2['default'].registerComponent('VolumeLevel', VolumeLevel); 8292exports['default'] = VolumeLevel; 8293module.exports = exports['default']; 8294 8295},{"../../component.js":67}],102:[function(_dereq_,module,exports){ 8296/** 8297 * @file volume-menu-button.js 8298 */ 8299'use strict'; 8300 8301exports.__esModule = true; 8302 8303function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8304 8305function _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; } } 8306 8307function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 8308 8309function _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
8309onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 8310 8311var _utilsFnJs = _dereq_('../utils/fn.js'); 8312 8313var Fn = _interopRequireWildcard(_utilsFnJs); 8314 8315var _componentJs = _dereq_('../component.js'); 8316 8317var _componentJs2 = _interopRequireDefault(_componentJs); 8318 8319var _popupPopupJs = _dereq_('../popup/popup.js'); 8320 8321var _popupPopupJs2 = _interopRequireDefault(_popupPopupJs); 8322 8323var _popupPopupButtonJs = _dereq_('../popup/popup-button.js'); 8324 8325var _popupPopupButtonJs2 = _interopRequireDefault(_popupPopupButtonJs); 8326 8327var _muteToggleJs = _dereq_('./mute-toggle.js'); 8328 8329var _muteToggleJs2 = _interopRequireDefault(_muteToggleJs); 8330 8331var _volumeControlVolumeBarJs = _dereq_('./volume-control/volume-bar.js'); 8332 8333var _volumeControlVolumeBarJs2 = _interopRequireDefault(_volumeControlVolumeBarJs); 8334 8335/** 8336 * Button for volume popup 8337 * 8338 * @param {Player|Object} player 8339 * @param {Object=} options 8340 * @extends PopupButton 8341 * @class VolumeMenuButton 8342 */ 8343 8344var VolumeMenuButton = (function (_PopupButton) { 8345 _inherits(VolumeMenuButton, _PopupButton); 8346 8347 function VolumeMenuButton(player) { 8348 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 8349 8350 _classCallCheck(this, VolumeMenuButton); 8351 8352 // Default to inline 8353 if (options.inline === undefined) { 8354 options.inline = true; 8355 } 8356 8357 // If the vertical option isn't passed at all, default to true. 8358 if (options.vertical === undefined) { 8359 // If an inline volumeMenuButton is used, we should default to using 8360 // a horizontal slider for obvious reasons. 8361 if (options.inline) { 8362 options.vertical = false;
8363 } else { 8364 options.vertical = true; 8365 } 8366 } 8367 8368 // The vertical option needs to be set on the volumeBar as well, 8369 // since that will need to be passed along to the VolumeBar constructor 8370 options.volumeBar = options.volumeBar || {}; 8371 options.volumeBar.vertical = !!options.vertical; 8372 8373 _PopupButton.call(this, player, options); 8374 8375 // Same listeners as MuteToggle 8376 this.on(player, 'volumechange', this.volumeUpdate); 8377 this.on(player, 'loadstart', this.volumeUpdate); 8378 8379 // hide mute toggle if the current tech doesn't support volume control 8380 function updateVisibility() { 8381 if (player.tech_ && player.tech_['featuresVolumeControl'] === false) { 8382 this.addClass('vjs-hidden'); 8383 } else { 8384 this.removeClass('vjs-hidden'); 8385 } 8386 } 8387 8388 updateVisibility.call(this); 8389 this.on(player, 'loadstart', updateVisibility); 8390 8391 this.on(this.volumeBar, ['slideractive', 'focus'], function () { 8392 this.addClass('vjs-slider-active'); 8393 }); 8394 8395 this.on(this.volumeBar, ['sliderinactive', 'blur'], function () { 8396 this.removeClass('vjs-slider-active'); 8397 }); 8398 8399 this.on(this.volumeBar, ['focus'], function () { 8400 this.addClass('vjs-lock-showing'); 8401 }); 8402 8403 this.on(this.volumeBar, ['blur'], function () { 8404 this.removeClass('vjs-lock-showing'); 8405 }); 8406 } 8407 8408 /** 8409 * Allow sub components to stack CSS class names 8410 * 8411 * @return {String} The constructed class name 8412 * @method buildCSSClass 8413 */ 8414 8415 VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() { 8416 var orientationClass = ''; 8417 if (!!this.options_.vertical) { 8418 orientationClass = 'vjs-volume-menu-button-vertical'; 8419 } else { 8420 orientationClass = 'vjs-volume-menu-button-horizontal'; 8421 } 8422 8423 return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass; 8424 }; 8425 8426 /** 8427 * Allow sub components to stack CSS class names 8428 * 8429 * @return {Popup} The volume popup button 8430 * @method createPopup 8431 */ 8432 8433 VolumeMenuButton.prototype.createPopup = function createPopup() { 8434 var popup = new _popupPopupJs2['default'](this.player_, { 8435 contentElType: 'div' 8436 }); 8437 8438 var vb = new _volumeControlVolumeBarJs2['default'](this.player_, this.options_.volumeBar); 8439 8440 popup.addChild(vb); 8441 8442 this.menuContent = popup; 8443 this.volumeBar = vb; 8444 8445 this.attachVolumeBarEvents(); 8446 8447 return popup; 8448 }; 8449 8450 /** 8451 * Handle click on volume popup and calls super 8452 * 8453 * @method handleClick 8454 */ 8455 8456 VolumeMenuButton.prototype.handleClick = function handleClick() { 8457 _muteToggleJs2['default'].prototype.handleClick.call(this); 8458 _PopupButton.prototype.handleClick.call(this); 8459 }; 8460 8461 VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() { 8462 this.menuContent.on(['mousedown', 'touchdown'], Fn.bind(this, this.handleMouseDown)); 8463 }; 8464 8465 VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) { 8466 this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove)); 8467 this.on(this.el_.ownerDocument, ['mouseup', 'touchend'], this.handleMouseUp); 8468 }; 8469 8470 VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) { 8471 this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove)); 8472 }; 8473 8474 return VolumeMenuButton; 8475})(_popupPopupButtonJs2['default']); 8476 8477VolumeMenuButton.prototype.volumeUpdate = _muteToggleJs2['default'].prototype.update; 8478VolumeMenuButton.prototype.controlText_ = 'Mute'; 8479 8480_componentJs2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton); 8481exports['default'] = VolumeMenuButton; 8482module.exports = exports['default']; 8483 8484},{"../component.js":67,"../popup/popup-button.js":115,"../popup/popup.js":116,"../utils/fn.js":145,"./mute-toggle.js":73,"./volume-control/volume-bar.js":99}],103:[function(_dereq_,module,exports){ 8485/** 8486 * @file error-display.js 8487 */ 8488'use strict'; 8489 8490exports.__esModule = true; 8491 8492function _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; } } 8493 8494function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8495 8496function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 8497 8498function _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
8498onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 8499 8500var _component = _dereq_('./component'); 8501 8502var _component2 = _interopRequireDefault(_component); 8503 8504var _modalDialog = _dereq_('./modal-dialog'); 8505 8506var _modalDialog2 = _interopRequireDefault(_modalDialog); 8507 8508var _utilsDom = _dereq_('./utils/dom'); 8509 8510var Dom = _interopRequireWildcard(_utilsDom); 8511 8512var _utilsMergeOptions = _dereq_('./utils/merge-options'); 8513 8514var _utilsMergeOptions2 = _interopRequireDefault(_utilsMergeOptions); 8515 8516/** 8517 * Display that an error has occurred making the video unplayable. 8518 * 8519 * @extends ModalDialog 8520 * @class ErrorDisplay 8521 */ 8522 8523var ErrorDisplay = (function (_ModalDialog) { 8524 _inherits(ErrorDisplay, _ModalDialog); 8525 8526 /** 8527 * Constructor for error display modal. 8528 * 8529 * @param {Player} player 8530 * @param {Object} [options] 8531 */ 8532 8533 function ErrorDisplay(player, options) { 8534 _classCallCheck(this, ErrorDisplay); 8535 8536 _ModalDialog.call(this, player, options); 8537 this.on(player, 'error', this.open); 8538 } 8539 8540 /** 8541 * Include the old class for backward-compatibility. 8542 * 8543 * This can be removed in 6.0. 8544 * 8545 * @method buildCSSClass 8546 * @deprecated 8547 * @return {String} 8548 */ 8549 8550 ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() { 8551 return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this); 8552 }; 8553 8554 /** 8555 * Generates the modal content based on the player error. 8556 * 8557 * @return {String|Null} 8558 */ 8559 8560 ErrorDisplay.prototype.content = function content() { 8561 var error = this.player().error(); 8562 return error ? this.localize(error.message) : ''; 8563 }; 8564 8565 return ErrorDisplay; 8566})(_modalDialog2['default']); 8567 8568ErrorDisplay.prototype.options_ = _utilsMergeOptions2['default'](_modalDialog2['default'].prototype.options_, { 8569 fillAlways: true, 8570 temporary: false, 8571 uncloseable: true 8572}); 8573 8574_component2['default'].registerComponent('ErrorDisplay', ErrorDisplay); 8575exports['default'] = ErrorDisplay; 8576module.exports = exports['default']; 8577 8578},{"./component":67,"./modal-dialog":112,"./utils/dom":143,"./utils/merge-options":149}],104:[function(_dereq_,module,exports){ 8579/** 8580 * @file event-target.js 8581 */ 8582'use strict'; 8583 8584exports.__esModule = true; 8585 8586function _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; } } 8587 8588var _utilsEventsJs = _dereq_('./utils/events.js'); 8589 8590var Events = _interopRequireWildcard(_utilsEventsJs); 8591 8592var EventTarget = function EventTarget() {}; 8593 8594EventTarget.prototype.allowedEvents_ = {}; 8595 8596EventTarget.prototype.on = function (type, fn) { 8597 // Remove the addEventListener alias before calling Events.on 8598 // so we don't get into an infinite type loop 8599 var ael = this.addEventListener; 8600 this.addEventListener = function () {}; 8601 Events.on(this, type, fn); 8602 this.addEventListener = ael; 8603}; 8604EventTarget.prototype.addEventListener = EventTarget.prototype.on; 8605 8606EventTarget.prototype.off = function (type, fn) { 8607 Events.off(this, type, fn); 8608}; 8609EventTarget.prototype.removeEventListener = EventTarget.prototype.off; 8610 8611EventTarget.prototype.one = function (type, fn) { 8612 // Remove the addEventListener alias before calling Events.on 8613 // so we don't get into an infinite type loop 8614 var ael = this.addEventListener; 8615 this.addEventListener = function () {}; 8616 Events.one(this, type, fn); 8617 this.addEventListener = ael; 8618}; 8619 8620EventTarget.prototype.trigger = function (event) { 8621 var type = event.type || event; 8622 8623 if (typeof event === 'string') { 8624 event = { 8625 type: type 8626 }; 8627 } 8628 event = Events.fixEvent(event); 8629 8630 if (this.allowedEvents_[type] && this['on' + type]) { 8631 this['on' + type](event); 8632 } 8633 8634 Events.trigger(this, event); 8635}; 8636// The standard DOM EventTarget.dispatchEvent() is aliased to trigger() 8637EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger; 8638 8639exports['default'] = EventTarget; 8640module.exports = exports['default']; 8641 8642},{"./utils/events.js":144}],105:[function(_dereq_,module,exports){ 8643'use strict'; 8644 8645exports.__esModule = true; 8646 8647function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8648 8649var _utilsLog = _dereq_('./utils/log'); 8650 8651var _utilsLog2 = _interopRequireDefault(_utilsLog); 8652 8653/* 8654 * @file extend.js 8655 * 8656 * A combination of node inherits and babel's inherits (after transpile). 8657 * Both work the same but node adds `super_` to the subClass 8658 * and Bable adds the superClass as __proto__. Both seem useful. 8659 */ 8660var _inherits = function _inherits(subClass, superClass) { 8661 if (typeof superClass !== 'function' && superClass !== null) { 8662 throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); 8663 } 8664 8665 subClass.prototype = Object.create(superClass && superClass.prototype, { 8666 constructor: { 8667 value: subClass, 8668 enumerable: false, 8669 writable: true, 8670 configurable: true 8671 } 8672 }); 8673 8674 if (superClass) { 8675 // node 8676 subClass.super_ = superClass; 8677 } 8678}; 8679 8680/*
8681 * Function for subclassing using the same inheritance that 8682 * videojs uses internally 8683 * ```js 8684 * var Button = videojs.getComponent('Button'); 8685 * ``` 8686 * ```js 8687 * var MyButton = videojs.extend(Button, { 8688 * constructor: function(player, options) { 8689 * Button.call(this, player, options); 8690 * }, 8691 * onClick: function() { 8692 * // doSomething 8693 * } 8694 * }); 8695 * ``` 8696 */ 8697var extendFn = function extendFn(superClass) { 8698 var subClassMethods = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 8699 8700 var subClass = function subClass() { 8701 superClass.apply(this, arguments); 8702 }; 8703 var methods = {}; 8704 8705 if (typeof subClassMethods === 'object') { 8706 if (typeof subClassMethods.init === 'function') { 8707 _utilsLog2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.'); 8708 subClassMethods.constructor = subClassMethods.init; 8709 } 8710 if (subClassMethods.constructor !== Object.prototype.constructor) { 8711 subClass = subClassMethods.constructor; 8712 } 8713 methods = subClassMethods; 8714 } else if (typeof subClassMethods === 'function') { 8715 subClass = subClassMethods; 8716 } 8717 8718 _inherits(subClass, superClass); 8719 8720 // Extend subObj's prototype with functions and other properties from props 8721 for (var name in methods) { 8722 if (methods.hasOwnProperty(name)) { 8723 subClass.prototype[name] = methods[name]; 8724 } 8725 } 8726 8727 return subClass; 8728}; 8729 8730exports['default'] = extendFn; 8731module.exports = exports['default']; 8732 8733},{"./utils/log":148}],106:[function(_dereq_,module,exports){ 8734/** 8735 * @file fullscreen-api.js 8736 */ 8737'use strict'; 8738 8739exports.__esModule = true; 8740 8741function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8742 8743var _globalDocument = _dereq_('global/document'); 8744 8745var _globalDocument2 = _interopRequireDefault(_globalDocument); 8746 8747/* 8748 * Store the browser-specific methods for the fullscreen API 8749 * @type {Object|undefined} 8750 * @private 8751 */ 8752var FullscreenApi = {}; 8753 8754// browser API methods 8755// map approach from Screenful.js - https://github.com/sindresorhus/screenfull.js 8756var apiMap = [ 8757// Spec: https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html 8758['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'], 8759// WebKit 8760['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'], 8761// Old WebKit (Safari 5.1) 8762['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'], 8763// Mozilla 8764['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'], 8765// Microsoft 8766['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']]; 8767 8768var specApi = apiMap[0]; 8769var browserApi = undefined; 8770 8771// determine the supported set of functions 8772for (var i = 0; i < apiMap.length; i++) { 8773 // check for exitFullscreen function 8774 if (apiMap[i][1] in _globalDocument2['default']) { 8775 browserApi = apiMap[i]; 8776 break; 8777 } 8778} 8779 8780// map the browser API names to the spec API names 8781if (browserApi) { 8782 for (var i = 0; i < browserApi.length; i++) { 8783 FullscreenApi[specApi[i]] = browserApi[i]; 8784 } 8785} 8786 8787exports['default'] = FullscreenApi; 8788module.exports = exports['default']; 8789 8790},{"global/document":1}],107:[function(_dereq_,module,exports){ 8791/** 8792 * @file loading-spinner.js 8793 */ 8794'use strict'; 8795 8796exports.__esModule = true; 8797 8798function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8799 8800function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 8801 8802function _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
8802onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 8803 8804var _component = _dereq_('./component'); 8805 8806var _component2 = _interopRequireDefault(_component); 8807 8808/* Loading Spinner 8809================================================================================ */ 8810/** 8811 * Loading spinner for waiting events 8812 * 8813 * @extends Component 8814 * @class LoadingSpinner 8815 */ 8816 8817var LoadingSpinner = (function (_Component) { 8818 _inherits(LoadingSpinner, _Component); 8819 8820 function LoadingSpinner() { 8821 _classCallCheck(this, LoadingSpinner); 8822 8823 _Component.apply(this, arguments); 8824 } 8825 8826 /** 8827 * Create the component's DOM element 8828 * 8829 * @method createEl 8830 */ 8831 8832 LoadingSpinner.prototype.createEl = function createEl() { 8833 return _Component.prototype.createEl.call(this, 'div', { 8834 className: 'vjs-loading-spinner', 8835 dir: 'ltr' 8836 }); 8837 }; 8838 8839 return LoadingSpinner; 8840})(_component2['default']); 8841 8842_component2['default'].registerComponent('LoadingSpinner', LoadingSpinner); 8843exports['default'] = LoadingSpinner; 8844module.exports = exports['default']; 8845 8846},{"./component":67}],108:[function(_dereq_,module,exports){ 8847/** 8848 * @file media-error.js 8849 */ 8850'use strict'; 8851 8852exports.__esModule = true; 8853 8854function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8855 8856var _objectAssign = _dereq_('object.assign'); 8857 8858var _objectAssign2 = _interopRequireDefault(_objectAssign); 8859 8860/* 8861 * Custom MediaError to mimic the HTML5 MediaError 8862 * 8863 * @param {Number} code The media error code 8864 */ 8865var MediaError = function MediaError(code) { 8866 if (typeof code === 'number') { 8867 this.code = code; 8868 } else if (typeof code === 'string') {
8869 // default code is zero, so this is a custom error 8870 this.message = code; 8871 } else if (typeof code === 'object') { 8872 // object 8873 _objectAssign2['default'](this, code); 8874 } 8875 8876 if (!this.message) { 8877 this.message = MediaError.defaultMessages[this.code] || ''; 8878 } 8879}; 8880 8881/* 8882 * The error code that refers two one of the defined 8883 * MediaError types 8884 * 8885 * @type {Number} 8886 */ 8887MediaError.prototype.code = 0; 8888 8889/* 8890 * An optional message to be shown with the error. 8891 * Message is not part of the HTML5 video spec 8892 * but allows for more informative custom errors. 8893 * 8894 * @type {String} 8895 */ 8896MediaError.prototype.message = ''; 8897 8898/* 8899 * An optional status code that can be set by plugins 8900 * to allow even more detail about the error. 8901 * For example the HLS plugin might provide the specific 8902 * HTTP status code that was returned when the error 8903 * occurred, then allowing a custom error overlay 8904 * to display more information. 8905 * 8906 * @type {Array} 8907 */ 8908MediaError.prototype.status = null; 8909 8910MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', // = 0 8911'MEDIA_ERR_ABORTED', // = 1 8912'MEDIA_ERR_NETWORK', // = 2 8913'MEDIA_ERR_DECODE', // = 3 8914'MEDIA_ERR_SRC_NOT_SUPPORTED', // = 4 8915'MEDIA_ERR_ENCRYPTED' // = 5 8916]; 8917 8918MediaError.defaultMessages = { 8919 1: 'You aborted the media playback', 8920 2: 'A network error caused the media download to fail part-way.', 8921 3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.', 8922 4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.', 8923 5: 'The media is encrypted and we do not have the keys to decrypt it.' 8924}; 8925 8926// Add types as properties on MediaError 8927// e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4; 8928for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) { 8929 MediaError[MediaError.errorTypes[errNum]] = errNum; 8930 // values should be accessible on both the class and instance 8931 MediaError.prototype[MediaError.errorTypes[errNum]] = errNum; 8932} 8933 8934exports['default'] = MediaError; 8935module.exports = exports['default']; 8936 8937},{"object.assign":45}],109:[function(_dereq_,module,exports){ 8938/** 8939 * @file menu-button.js 8940 */ 8941'use strict'; 8942 8943exports.__esModule = true; 8944 8945function _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; } } 8946 8947function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8948 8949function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 8950 8951function _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; } 8952 8953var _clickableComponentJs = _dereq_('../clickable-component.js'); 8954 8955var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs); 8956 8957var _componentJs = _dereq_('../component.js'); 8958 8959var _componentJs2 = _interopRequireDefault(_componentJs); 8960 8961var _menuJs = _dereq_('./menu.js'); 8962 8963var _menuJs2 = _interopRequireDefault(_menuJs); 8964 8965var _utilsDomJs = _dereq_('../utils/dom.js'); 8966 8967var Dom = _interopRequireWildcard(_utilsDomJs); 8968 8969var _utilsFnJs = _dereq_('../utils/fn.js'); 8970 8971var Fn = _interopRequireWildcard(_utilsFnJs); 8972 8973var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js'); 8974 8975var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs); 8976 8977/** 8978 * A button class with a popup menu 8979 * 8980 * @param {Player|Object} player 8981 * @param {Object=} options 8982 * @extends Button 8983 * @class MenuButton 8984 */ 8985 8986var MenuButton = (function (_ClickableComponent) { 8987 _inherits(MenuButton, _ClickableComponent); 8988 8989 function MenuButton(player) { 8990 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 8991 8992 _classCallCheck(this, MenuButton); 8993 8994 _ClickableComponent.call(this, player, options); 8995 8996 this.update(); 8997 8998 this.enabled_ = true; 8999 9000 this.el_.setAttribute('aria-haspopup', 'true'); 9001 this.el_.setAttribute('role', 'menuitem'); 9002 this.on('keydown', this.handleSubmenuKeyPress); 9003 } 9004 9005 /** 9006 * Update menu 9007 * 9008 * @method update 9009 */ 9010
9011 MenuButton.prototype.update = function update() { 9012 var menu = this.createMenu(); 9013 9014 if (this.menu) { 9015 this.removeChild(this.menu); 9016 } 9017 9018 this.menu = menu; 9019 this.addChild(menu); 9020 9021 /** 9022 * Track the state of the menu button 9023 * 9024 * @type {Boolean} 9025 * @private 9026 */ 9027 this.buttonPressed_ = false; 9028 this.el_.setAttribute('aria-expanded', 'false'); 9029 9030 if (this.items && this.items.length === 0) { 9031 this.hide(); 9032 } else if (this.items && this.items.length > 1) { 9033 this.show(); 9034 } 9035 }; 9036 9037 /** 9038 * Create menu 9039 * 9040 * @return {Menu} The constructed menu 9041 * @method createMenu 9042 */ 9043 9044 MenuButton.prototype.createMenu = function createMenu() { 9045 var menu = new _menuJs2['default'](this.player_); 9046 9047 // Add a title list item to the top 9048 if (this.options_.title) { 9049 var title = Dom.createEl('li', { 9050 className: 'vjs-menu-title', 9051 innerHTML: _utilsToTitleCaseJs2['default'](this.options_.title), 9052 tabIndex: -1 9053 }); 9054 menu.children_.unshift(title); 9055 Dom.insertElFirst(title, menu.contentEl()); 9056 } 9057 9058 this.items = this['createItems'](); 9059 9060 if (this.items) { 9061 // Add menu items to the menu 9062 for (var i = 0; i < this.items.length; i++) { 9063 menu.addItem(this.items[i]); 9064 } 9065 } 9066 9067 return menu; 9068 }; 9069 9070 /** 9071 * Create the list of menu items. Specific to each subclass. 9072 * 9073 * @method createItems 9074 */ 9075 9076 MenuButton.prototype.createItems = function createItems() {}; 9077 9078 /** 9079 * Create the component's DOM element 9080 * 9081 * @return {Element} 9082 * @method createEl 9083 */ 9084 9085 MenuButton.prototype.createEl = function createEl() { 9086 return _ClickableComponent.prototype.createEl.call(this, 'div', { 9087 className: this.buildCSSClass() 9088 }); 9089 }; 9090 9091 /** 9092 * Allow sub components to stack CSS class names 9093 * 9094 * @return {String} The constructed class name 9095 * @method buildCSSClass 9096 */ 9097 9098 MenuButton.prototype.buildCSSClass = function buildCSSClass() { 9099 var menuButtonClass = 'vjs-menu-button'; 9100 9101 // If the inline option is passed, we want to use different styles altogether. 9102 if (this.options_.inline === true) { 9103 menuButtonClass += '-inline'; 9104 } else { 9105 menuButtonClass += '-popup'; 9106 } 9107 9108 return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this); 9109 }; 9110 9111 /** 9112 * When you click the button it adds focus, which 9113 * will show the menu indefinitely. 9114 * So we'll remove focus when the mouse leaves the button. 9115 * Focus is needed for tab navigation. 9116 * Allow sub components to stack CSS class names 9117 * 9118 * @method handleClick 9119 */ 9120 9121 MenuButton.prototype.handleClick = function handleClick() { 9122 this.one('mouseout', Fn.bind(this, function () { 9123 this.menu.unlockShowing(); 9124 this.el_.blur(); 9125 })); 9126 if (this.buttonPressed_) { 9127 this.unpressButton(); 9128 } else { 9129 this.pressButton(); 9130 } 9131 }; 9132 9133 /** 9134 * Handle key press on menu 9135 * 9136 * @param {Object} event Key press event 9137 * @method handleKeyPress 9138 */ 9139 9140 MenuButton.prototype.handleKeyPress = function handleKeyPress(event) { 9141 9142 // Escape (27) key or Tab (9) key unpress the 'button' 9143 if (event.which === 27 || event.which === 9) { 9144 if (this.buttonPressed_) { 9145 this.unpressButton(); 9146 } 9147 // Don't preventDefault for Tab key - we still want to lose focus 9148 if (event.which !== 9) { 9149 event.preventDefault(); 9150 } 9151 // Up (38) key or Down (40) key press the 'button' 9152 } else if (event.which === 38 || event.which === 40) { 9153 if (!this.buttonPressed_) { 9154 this.pressButton(); 9155 event.preventDefault(); 9156 } 9157 } else { 9158 _ClickableComponent.prototype.handleKeyPress.call(this, event); 9159 } 9160 }; 9161 9162 /** 9163 * Handle key press on submenu 9164 * 9165 * @param {Object} event Key press event 9166 * @method handleSubmenuKeyPress 9167 */ 9168 9169 MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) { 9170 9171 // Escape (27) key or Tab (9) key unpress the 'button' 9172 if (event.which === 27 || event.which === 9) { 9173 if (this.buttonPressed_) { 9174 this.unpressButton(); 9175 } 9176 // Don't preventDefault for Tab key - we still want to lose focus 9177 if (event.which !== 9) { 9178 event.preventDefault(); 9179 } 9180 } 9181 }; 9182 9183 /** 9184 * Makes changes based on button pressed 9185 * 9186 * @method pressButton 9187 */ 9188 9189 MenuButton.prototype.pressButton = function pressButton() { 9190 if (this.enabled_) { 9191 this.buttonPressed_ = true; 9192 this.menu.lockShowing(); 9193 this.el_.setAttribute('aria-expanded', 'true'); 9194 this.menu.focus(); // set the focus into the submenu 9195 } 9196 }; 9197 9198 /** 9199 * Makes changes based on button unpressed 9200 * 9201 * @method unpressButton 9202 */ 9203 9204 MenuButton.prototype.unpressButton = function unpressButton() { 9205 if (this.enabled_) { 9206 this.buttonPressed_ = false;
9207 this.menu.unlockShowing(); 9208 this.el_.setAttribute('aria-expanded', 'false'); 9209 this.el_.focus(); // Set focus back to this menu button 9210 } 9211 }; 9212 9213 /** 9214 * Disable the menu button 9215 * 9216 * @return {Component} 9217 * @method disable 9218 */ 9219 9220 MenuButton.prototype.disable = function disable() { 9221 // Unpress, but don't force focus on this button 9222 this.buttonPressed_ = false; 9223 this.menu.unlockShowing(); 9224 this.el_.setAttribute('aria-expanded', 'false'); 9225 9226 this.enabled_ = false; 9227 9228 return _ClickableComponent.prototype.disable.call(this); 9229 }; 9230 9231 /** 9232 * Enable the menu button 9233 * 9234 * @return {Component} 9235 * @method disable 9236 */ 9237 9238 MenuButton.prototype.enable = function enable() { 9239 this.enabled_ = true; 9240 9241 return _ClickableComponent.prototype.enable.call(this); 9242 }; 9243 9244 return MenuButton; 9245})(_clickableComponentJs2['default']); 9246 9247_componentJs2['default'].registerComponent('MenuButton', MenuButton); 9248exports['default'] = MenuButton; 9249module.exports = exports['default']; 9250 9251},{"../clickable-component.js":65,"../component.js":67,"../utils/dom.js":143,"../utils/fn.js":145,"../utils/to-title-case.js":152,"./menu.js":111}],110:[function(_dereq_,module,exports){ 9252/** 9253 * @file menu-item.js 9254 */ 9255'use strict'; 9256 9257exports.__esModule = true; 9258 9259function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 9260 9261function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 9262 9263function _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; } 9264 9265var _clickableComponentJs = _dereq_('../clickable-component.js'); 9266 9267var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs); 9268 9269var _componentJs = _dereq_('../component.js'); 9270 9271var _componentJs2 = _interopRequireDefault(_componentJs); 9272 9273var _objectAssign = _dereq_('object.assign'); 9274 9275var _objectAssign2 = _interopRequireDefault(_objectAssign); 9276 9277/** 9278 * The component for a menu item. `<li>` 9279 * 9280 * @param {Player|Object} player 9281 * @param {Object=} options 9282 * @extends Button 9283 * @class MenuItem 9284 */ 9285 9286var MenuItem = (function (_ClickableComponent) { 9287 _inherits(MenuItem, _ClickableComponent); 9288 9289 function MenuItem(player, options) { 9290 _classCallCheck(this, MenuItem); 9291 9292 _ClickableComponent.call(this, player, options); 9293 9294 this.selectable = options['selectable']; 9295 9296 this.selected(options['selected']); 9297 9298 if (this.selectable) { 9299 // TODO: May need to be either menuitemcheckbox or menuitemradio, 9300 // and may need logical grouping of menu items. 9301 this.el_.setAttribute('role', 'menuitemcheckbox'); 9302 } else { 9303 this.el_.setAttribute('role', 'menuitem'); 9304 } 9305 } 9306 9307 /** 9308 * Create the component's DOM element 9309 * 9310 * @param {String=} type Desc 9311 * @param {Object=} props Desc 9312 * @return {Element} 9313 * @method createEl 9314 */ 9315 9316 MenuItem.prototype.createEl = function createEl(type, props, attrs) { 9317 return _ClickableComponent.prototype.createEl.call(this, 'li', _objectAssign2['default']({ 9318 className: 'vjs-menu-item', 9319 innerHTML: this.localize(this.options_['label']), 9320 tabIndex: -1 9321 }, props), attrs); 9322 }; 9323 9324 /** 9325 * Handle a click on the menu item, and set it to selected 9326 * 9327 * @method handleClick 9328 */ 9329 9330 MenuItem.prototype.handleClick = function handleClick() { 9331 this.selected(true); 9332 }; 9333 9334 /** 9335 * Set this menu item as selected or not 9336 * 9337 * @param {Boolean} selected 9338 * @method selected 9339 */ 9340 9341 MenuItem.prototype.selected = function selected(_selected) { 9342 if (this.selectable) { 9343 if (_selected) { 9344 this.addClass('vjs-selected'); 9345 this.el_.setAttribute('aria-checked', 'true'); 9346 // aria-checked isn't fully supported by browsers/screen readers, 9347 // so indicate selected state to screen reader in the control text. 9348 this.controlText(', selected'); 9349 } else { 9350 this.removeClass('vjs-selected'); 9351 this.el_.setAttribute('aria-checked', 'false'); 9352 // Indicate un-selected state to screen reader 9353 // Note that a space clears out the selected state text 9354 this.controlText(' '); 9355 } 9356 } 9357 }; 9358
9359 return MenuItem; 9360})(_clickableComponentJs2['default']); 9361 9362_componentJs2['default'].registerComponent('MenuItem', MenuItem); 9363exports['default'] = MenuItem; 9364module.exports = exports['default']; 9365 9366},{"../clickable-component.js":65,"../component.js":67,"object.assign":45}],111:[function(_dereq_,module,exports){ 9367/** 9368 * @file menu.js 9369 */ 9370'use strict'; 9371 9372exports.__esModule = true; 9373 9374function _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; } } 9375 9376function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 9377 9378function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 9379 9380function _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; } 9381 9382var _componentJs = _dereq_('../component.js'); 9383 9384var _componentJs2 = _interopRequireDefault(_componentJs); 9385 9386var _utilsDomJs = _dereq_('../utils/dom.js'); 9387 9388var Dom = _interopRequireWildcard(_utilsDomJs); 9389 9390var _utilsFnJs = _dereq_('../utils/fn.js'); 9391 9392var Fn = _interopRequireWildcard(_utilsFnJs); 9393 9394var _utilsEventsJs = _dereq_('../utils/events.js'); 9395 9396var Events = _interopRequireWildcard(_utilsEventsJs); 9397 9398/** 9399 * The Menu component is used to build pop up menus, including subtitle and 9400 * captions selection menus. 9401 * 9402 * @extends Component 9403 * @class Menu 9404 */ 9405 9406var Menu = (function (_Component) { 9407 _inherits(Menu, _Component); 9408 9409 function Menu(player, options) { 9410 _classCallCheck(this, Menu); 9411 9412 _Component.call(this, player, options); 9413 9414 this.focusedChild_ = -1; 9415 9416 this.on('keydown', this.handleKeyPress); 9417 } 9418 9419 /** 9420 * Add a menu item to the menu 9421 * 9422 * @param {Object|String} component Component or component type to add 9423 * @method addItem 9424 */ 9425 9426 Menu.prototype.addItem = function addItem(component) { 9427 this.addChild(component); 9428 component.on('click', Fn.bind(this, function () { 9429 this.unlockShowing(); 9430 //TODO: Need to set keyboard focus back to the menuButton 9431 })); 9432 }; 9433 9434 /** 9435 * Create the component's DOM element 9436 * 9437 * @return {Element} 9438 * @method createEl 9439 */ 9440 9441 Menu.prototype.createEl = function createEl() { 9442 var contentElType = this.options_.contentElType || 'ul'; 9443 this.contentEl_ = Dom.createEl(contentElType, { 9444 className: 'vjs-menu-content' 9445 }); 9446 this.contentEl_.setAttribute('role', 'menu'); 9447 var el = _Component.prototype.createEl.call(this, 'div', { 9448 append: this.contentEl_, 9449 className: 'vjs-menu' 9450 }); 9451 el.setAttribute('role', 'presentation'); 9452 el.appendChild(this.contentEl_); 9453 9454 // Prevent clicks from bubbling up. Needed for Menu Buttons, 9455 // where a click on the parent is significant 9456 Events.on(el, 'click', function (event) { 9457 event.preventDefault(); 9458 event.stopImmediatePropagation(); 9459 }); 9460 9461 return el; 9462 }; 9463 9464 /** 9465 * Handle key press for menu 9466 * 9467 * @param {Object} event Event object 9468 * @method handleKeyPress 9469 */ 9470 9471 Menu.prototype.handleKeyPress = function handleKeyPress(event) { 9472 if (event.which === 37 || event.which === 40) { 9473 // Left and Down Arrows 9474 event.preventDefault(); 9475 this.stepForward(); 9476 } else if (event.which === 38 || event.which === 39) { 9477 // Up and Right Arrows 9478 event.preventDefault(); 9479 this.stepBack(); 9480 } 9481 }; 9482 9483 /** 9484 * Move to next (lower) menu item for keyboard users 9485 * 9486 * @method stepForward 9487 */ 9488 9489 Menu.prototype.stepForward = function stepForward() { 9490 var stepChild = 0; 9491 9492 if (this.focusedChild_ !== undefined) {
9493 stepChild = this.focusedChild_ + 1; 9494 } 9495 this.focus(stepChild); 9496 }; 9497 9498 /** 9499 * Move to previous (higher) menu item for keyboard users 9500 * 9501 * @method stepBack 9502 */ 9503 9504 Menu.prototype.stepBack = function stepBack() { 9505 var stepChild = 0; 9506 9507 if (this.focusedChild_ !== undefined) { 9508 stepChild = this.focusedChild_ - 1; 9509 } 9510 this.focus(stepChild); 9511 }; 9512 9513 /** 9514 * Set focus on a menu item in the menu 9515 * 9516 * @param {Object|String} item Index of child item set focus on 9517 * @method focus 9518 */ 9519 9520 Menu.prototype.focus = function focus() { 9521 var item = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0]; 9522 9523 var children = this.children().slice(); 9524 var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className); 9525 9526 if (haveTitle) { 9527 children.shift(); 9528 } 9529 9530 if (children.length > 0) { 9531 if (item < 0) { 9532 item = 0; 9533 } else if (item >= children.length) { 9534 item = children.length - 1; 9535 } 9536 9537 this.focusedChild_ = item; 9538 9539 children[item].el_.focus(); 9540 } 9541 }; 9542 9543 return Menu; 9544})(_componentJs2['default']); 9545 9546_componentJs2['default'].registerComponent('Menu', Menu); 9547exports['default'] = Menu; 9548module.exports = exports['default']; 9549 9550},{"../component.js":67,"../utils/dom.js":143,"../utils/events.js":144,"../utils/fn.js":145}],112:[function(_dereq_,module,exports){ 9551/** 9552 * @file modal-dialog.js 9553 */ 9554'use strict'; 9555 9556exports.__esModule = true; 9557 9558function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 9559 9560function _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; } } 9561 9562function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 9563 9564function _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; } 9565 9566var _utilsDom = _dereq_('./utils/dom'); 9567 9568var Dom = _interopRequireWildcard(_utilsDom); 9569 9570var _utilsFn = _dereq_('./utils/fn'); 9571 9572var Fn = _interopRequireWildcard(_utilsFn); 9573 9574var _utilsLog = _dereq_('./utils/log'); 9575 9576var _utilsLog2 = _interopRequireDefault(_utilsLog); 9577 9578var _component = _dereq_('./component'); 9579 9580var _component2 = _interopRequireDefault(_component); 9581 9582var _closeButton = _dereq_('./close-button'); 9583 9584var _closeButton2 = _interopRequireDefault(_closeButton); 9585 9586var MODAL_CLASS_NAME = 'vjs-modal-dialog'; 9587var ESC = 27; 9588 9589/** 9590 * The `ModalDialog` displays over the video and its controls, which blocks 9591 * interaction with the player until it is closed. 9592 * 9593 * Modal dialogs include a "Close" button and will close when that button 9594 * is activated - or when ESC is pressed anywhere. 9595 * 9596 * @extends Component 9597 * @class ModalDialog 9598 */ 9599 9600var ModalDialog = (function (_Component) { 9601 _inherits(ModalDialog, _Component); 9602 9603 /** 9604 * Constructor for modals. 9605 * 9606 * @param {Player} player 9607 * @param {Object} [options] 9608 * @param {Mixed} [options.content=undefined] 9609 * Provide customized content for this modal. 9610 * 9611 * @param {String} [options.description] 9612 * A text description for the modal, primarily for accessibility. 9613 * 9614 * @param {Boolean} [options.fillAlways=false] 9615 * Normally, modals are automatically filled only the first time 9616 * they open. This tells the modal to refresh its content 9617 * every time it opens. 9618 * 9619 * @param {String} [options.label] 9620 * A text label for the modal, primarily for accessibility. 9621 * 9622 * @param {Boolean} [options.temporary=true] 9623 * If `true`, the modal can only be opened once; it will be 9624 * disposed as soon as it's closed. 9625 * 9626 * @param {Boolean} [options.uncloseable=false] 9627 * If `true`, the user will not be able to close the modal 9628 * through the UI in the normal ways. Programmatic closing is 9629 * still possible. 9630 * 9631 */ 9632 9633 function ModalDialog(player, options) { 9634 _classCallCheck(this, ModalDialog); 9635 9636 _Component.call(this, player, options); 9637 this.opened_ = this.hasBeenOpened_ = this.hasBeenFilled_ = false;
9638 9639 this.closeable(!this.options_.uncloseable); 9640 this.content(this.options_.content); 9641 9642 // Make sure the contentEl is defined AFTER any children are initialized 9643 // because we only want the contents of the modal in the contentEl 9644 // (not the UI elements like the close button). 9645 this.contentEl_ = Dom.createEl('div', { 9646 className: MODAL_CLASS_NAME + '-content' 9647 }, { 9648 role: 'document' 9649 }); 9650 9651 this.descEl_ = Dom.createEl('p', { 9652 className: MODAL_CLASS_NAME + '-description vjs-offscreen', 9653 id: this.el().getAttribute('aria-describedby') 9654 }); 9655 9656 Dom.textContent(this.descEl_, this.description()); 9657 this.el_.appendChild(this.descEl_); 9658 this.el_.appendChild(this.contentEl_); 9659 } 9660 9661 /* 9662 * Modal dialog default options. 9663 * 9664 * @type {Object} 9665 * @private 9666 */ 9667 9668 /** 9669 * Create the modal's DOM element 9670 * 9671 * @method createEl 9672 * @return {Element} 9673 */ 9674 9675 ModalDialog.prototype.createEl = function createEl() { 9676 return _Component.prototype.createEl.call(this, 'div', { 9677 className: this.buildCSSClass(), 9678 tabIndex: -1 9679 }, { 9680 'aria-describedby': this.id() + '_description', 9681 'aria-hidden': 'true', 9682 'aria-label': this.label(), 9683 role: 'dialog' 9684 }); 9685 }; 9686 9687 /** 9688 * Build the modal's CSS class. 9689 * 9690 * @method buildCSSClass 9691 * @return {String} 9692 */ 9693 9694 ModalDialog.prototype.buildCSSClass = function buildCSSClass() { 9695 return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this); 9696 }; 9697 9698 /** 9699 * Handles key presses on the document, looking for ESC, which closes 9700 * the modal. 9701 * 9702 * @method handleKeyPress 9703 * @param {Event} e 9704 */ 9705 9706 ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) { 9707 if (e.which === ESC && this.closeable()) { 9708 this.close(); 9709 } 9710 }; 9711 9712 /** 9713 * Returns the label string for this modal. Primarily used for accessibility. 9714 * 9715 * @return {String} 9716 */ 9717 9718 ModalDialog.prototype.label = function label() { 9719 return this.options_.label || this.localize('Modal Window'); 9720 }; 9721 9722 /** 9723 * Returns the description string for this modal. Primarily used for 9724 * accessibility. 9725 * 9726 * @return {String} 9727 */ 9728 9729 ModalDialog.prototype.description = function description() { 9730 var desc = this.options_.description || this.localize('This is a modal window.'); 9731 9732 // Append a universal closeability message if the modal is closeable. 9733 if (this.closeable()) { 9734 desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.'); 9735 } 9736 9737 return desc; 9738 }; 9739 9740 /** 9741 * Opens the modal. 9742 * 9743 * @method open 9744 * @return {ModalDialog} 9745 */ 9746 9747 ModalDialog.prototype.open = function open() { 9748 if (!this.opened_) { 9749 var player = this.player(); 9750 9751 this.trigger('beforemodalopen'); 9752 this.opened_ = true; 9753 9754 // Fill content if the modal has never opened before and 9755 // never been filled. 9756 if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) { 9757 this.fill(); 9758 } 9759 9760 // If the player was playing, pause it and take note of its previously 9761 // playing state. 9762 this.wasPlaying_ = !player.paused(); 9763 9764 if (this.wasPlaying_) { 9765 player.pause(); 9766 } 9767 9768 if (this.closeable()) { 9769 this.on(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress)); 9770 } 9771 9772 player.controls(false); 9773 this.show(); 9774 this.el().setAttribute('aria-hidden', 'false'); 9775 this.trigger('modalopen'); 9776 this.hasBeenOpened_ = true; 9777 } 9778 return this; 9779 }; 9780 9781 /** 9782 * Whether or not the modal is opened currently. 9783 * 9784 * @method opened 9785 * @param {Boolean} [value] 9786 * If given, it will open (`true`) or close (`false`) the modal. 9787 * 9788 * @return {Boolean} 9789 */ 9790 9791 ModalDialog.prototype.opened = function opened(value) { 9792 if (typeof value === 'boolean') { 9793 this[value ? 'open' : 'close'](); 9794 } 9795 return this.opened_; 9796 }; 9797 9798 /** 9799 * Closes the modal. 9800 * 9801 * @method close 9802 * @return {ModalDialog} 9803 */ 9804 9805 ModalDialog.prototype.close = function close() { 9806 if (this.opened_) { 9807 var player = this.player(); 9808 9809 this.trigger('beforemodalclose'); 9810 this.opened_ = false;
9811 9812 if (this.wasPlaying_) { 9813 player.play(); 9814 } 9815 9816 if (this.closeable()) { 9817 this.off(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress)); 9818 } 9819 9820 player.controls(true); 9821 this.hide(); 9822 this.el().setAttribute('aria-hidden', 'true'); 9823 this.trigger('modalclose'); 9824 9825 if (this.options_.temporary) { 9826 this.dispose(); 9827 } 9828 } 9829 return this; 9830 }; 9831 9832 /** 9833 * Whether or not the modal is closeable via the UI. 9834 * 9835 * @method closeable 9836 * @param {Boolean} [value] 9837 * If given as a Boolean, it will set the `closeable` option. 9838 * 9839 * @return {Boolean} 9840 */ 9841 9842 ModalDialog.prototype.closeable = function closeable(value) { 9843 if (typeof value === 'boolean') { 9844 var closeable = this.closeable_ = !!value; 9845 var _close = this.getChild('closeButton'); 9846 9847 // If this is being made closeable and has no close button, add one. 9848 if (closeable && !_close) { 9849 9850 // The close button should be a child of the modal - not its 9851 // content element, so temporarily change the content element. 9852 var temp = this.contentEl_; 9853 this.contentEl_ = this.el_; 9854 _close = this.addChild('closeButton'); 9855 this.contentEl_ = temp; 9856 this.on(_close, 'close', this.close); 9857 } 9858 9859 // If this is being made uncloseable and has a close button, remove it. 9860 if (!closeable && _close) { 9861 this.off(_close, 'close', this.close); 9862 this.removeChild(_close); 9863 _close.dispose(); 9864 } 9865 } 9866 return this.closeable_; 9867 }; 9868 9869 /**
9870 * Fill the modal's content element with the modal's "content" option. 9871 * 9872 * The content element will be emptied before this change takes place. 9873 * 9874 * @method fill 9875 * @return {ModalDialog} 9876 */ 9877 9878 ModalDialog.prototype.fill = function fill() { 9879 return this.fillWith(this.content()); 9880 }; 9881 9882 /** 9883 * Fill the modal's content element with arbitrary content. 9884 * 9885 * The content element will be emptied before this change takes place. 9886 * 9887 * @method fillWith 9888 * @param {Mixed} [content] 9889 * The same rules apply to this as apply to the `content` option. 9890 * 9891 * @return {ModalDialog} 9892 */ 9893 9894 ModalDialog.prototype.fillWith = function fillWith(content) { 9895 var contentEl = this.contentEl(); 9896 var parentEl = contentEl.parentNode; 9897 var nextSiblingEl = contentEl.nextSibling; 9898 9899 this.trigger('beforemodalfill'); 9900 this.hasBeenFilled_ = true; 9901 9902 // Detach the content element from the DOM before performing 9903 // manipulation to avoid modifying the live DOM multiple times. 9904 parentEl.removeChild(contentEl); 9905 this.empty(); 9906 Dom.insertContent(contentEl, content); 9907 this.trigger('modalfill'); 9908 9909 // Re-inject the re-filled content element. 9910 if (nextSiblingEl) { 9911 parentEl.insertBefore(contentEl, nextSiblingEl); 9912 } else { 9913 parentEl.appendChild(contentEl); 9914 } 9915 9916 return this; 9917 }; 9918 9919 /** 9920 * Empties the content element. 9921 * 9922 * This happens automatically anytime the modal is filled. 9923 * 9924 * @method empty 9925 * @return {ModalDialog} 9926 */ 9927 9928 ModalDialog.prototype.empty = function empty() { 9929 this.trigger('beforemodalempty'); 9930 Dom.emptyEl(this.contentEl()); 9931 this.trigger('modalempty'); 9932 return this; 9933 }; 9934 9935 /** 9936 * Gets or sets the modal content, which gets normalized before being 9937 * rendered into the DOM. 9938 * 9939 * This does not update the DOM or fill the modal, but it is called during 9940 * that process. 9941 * 9942 * @method content 9943 * @param {Mixed} [value] 9944 * If defined, sets the internal content value to be used on the 9945 * next call(s) to `fill`. This value is normalized before being 9946 * inserted. To "clear" the internal content value, pass `null`. 9947 * 9948 * @return {Mixed} 9949 */ 9950 9951 ModalDialog.prototype.content = function content(value) { 9952 if (typeof value !== 'undefined') { 9953 this.content_ = value; 9954 } 9955 return this.content_; 9956 }; 9957 9958 return ModalDialog; 9959})(_component2['default']); 9960 9961ModalDialog.prototype.options_ = { 9962 temporary: true 9963}; 9964 9965_component2['default'].registerComponent('ModalDialog', ModalDialog); 9966exports['default'] = ModalDialog; 9967module.exports = exports['default']; 9968 9969},{"./close-button":66,"./component":67,"./utils/dom":143,"./utils/fn":145,"./utils/log":148}],113:[function(_dereq_,module,exports){ 9970/** 9971 * @file player.js 9972 */ 9973// Subclasses Component 9974'use strict'; 9975 9976exports.__esModule = true; 9977 9978function _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; } } 9979 9980function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 9981 9982function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 9983 9984function _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; } 9985 9986var _componentJs = _dereq_('./component.js'); 9987 9988var _componentJs2 = _interopRequireDefault(_componentJs); 9989 9990var _globalDocument = _dereq_('global/document'); 9991 9992var _globalDocument2 = _interopRequireDefault(_globalDocument); 9993 9994var _globalWindow = _dereq_('global/window'); 9995 9996var _globalWindow2 = _interopRequireDefault(_globalWindow); 9997 9998var _utilsEventsJs = _dereq_('./utils/events.js'); 9999 10000var Events = _interopRequireWildcard(_utilsEventsJs); 10001 10002var _utilsDomJs = _dereq_('./utils/dom.js'); 10003 10004var Dom = _interopRequireWildcard(_utilsDomJs); 10005 10006var _utilsFnJs = _dereq_('./utils/fn.js'); 10007 10008var Fn = _interopRequireWildcard(_utilsFnJs); 10009 10010var _utilsGuidJs = _dereq_('./utils/guid.js'); 10011 10012var Guid = _interopRequireWildcard(_utilsGuidJs); 10013 10014var _utilsBrowserJs = _dereq_('./utils/browser.js'); 10015 10016var browser = _interopRequireWildcard(_utilsBrowserJs); 10017 10018var _utilsLogJs = _dereq_('./utils/log.js'); 10019 10020var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 10021 10022var _utilsToTitleCaseJs = _dereq_('./utils/to-title-case.js'); 10023 10024var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs); 10025 10026var _utilsTimeRangesJs = _dereq_('./utils/time-ranges.js'); 10027 10028var _utilsBufferJs = _dereq_('./utils/buffer.js'); 10029 10030var _utilsStylesheetJs = _dereq_('./utils/stylesheet.js'); 10031 10032var stylesheet = _interopRequireWildcard(_utilsStylesheetJs); 10033 10034var _fullscreenApiJs = _dereq_('./fullscreen-api.js'); 10035 10036var _fullscreenApiJs2 = _interopRequireDefault(_fullscreenApiJs); 10037 10038var _mediaErrorJs = _dereq_('./media-error.js'); 10039 10040var _mediaErrorJs2 = _interopRequireDefault(_mediaErrorJs); 10041 10042var _safeJsonParseTuple = _dereq_('safe-json-parse/tuple'); 10043 10044var _safeJsonParseTuple2 = _interopRequireDefault(_safeJsonParseTuple); 10045 10046var _objectAssign = _dereq_('object.assign'); 10047 10048var _objectAssign2 = _interopRequireDefault(_objectAssign); 10049 10050var _utilsMergeOptionsJs = _dereq_('./utils/merge-options.js'); 10051 10052var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs); 10053 10054var _tracksTextTrackListConverterJs = _dereq_('./tracks/text-track-list-converter.js'); 10055 10056var _tracksTextTrackListConverterJs2 = _interopRequireDefault(_tracksTextTrackListConverterJs); 10057 10058var _tracksAudioTrackListJs = _dereq_('./tracks/audio-track-list.js'); 10059 10060var _tracksAudioTrackListJs2 = _interopRequireDefault(_tracksAudioTrackListJs); 10061 10062var _tracksVideoTrackListJs = _dereq_('./tracks/video-track-list.js'); 10063 10064var _tracksVideoTrackListJs2 = _interopRequireDefault(_tracksVideoTrackListJs); 10065 10066// Include required child components (importing also registers them) 10067 10068var _techLoaderJs = _dereq_('./tech/loader.js'); 10069 10070var _techLoaderJs2 = _interopRequireDefault(_techLoaderJs); 10071 10072var _posterImageJs = _dereq_('./poster-image.js'); 10073 10074var _posterImageJs2 = _interopRequireDefault(_posterImageJs); 10075 10076var _tracksTextTrackDisplayJs = _dereq_('./tracks/text-track-display.js'); 10077 10078var _tracksTextTrackDisplayJs2 = _interopRequireDefault(_tracksTextTrackDisplayJs); 10079 10080var _loadingSpinnerJs = _dereq_('./loading-spinner.js'); 10081 10082var _loadingSpinnerJs2 = _interopRequireDefault(_loadingSpinnerJs); 10083 10084var _bigPlayButtonJs = _dereq_('./big-play-button.js'); 10085 10086var _bigPlayButtonJs2 = _interopRequireDefault(_bigPlayButtonJs); 10087 10088var _controlBarControlBarJs = _dereq_('./control-bar/control-bar.js'); 10089 10090var _controlBarControlBarJs2 = _interopRequireDefault(_controlBarControlBarJs); 10091 10092var _errorDisplayJs = _dereq_('./error-display.js'); 10093 10094var _errorDisplayJs2 = _interopRequireDefault(_errorDisplayJs); 10095 10096var _tracksTextTrackSettingsJs = _dereq_('./tracks/text-track-settings.js'); 10097 10098var _tracksTextTrackSettingsJs2 = _interopRequireDefault(_tracksTextTrackSettingsJs); 10099 10100var _modalDialog = _dereq_('./modal-dialog'); 10101 10102var _modalDialog2 = _interopRequireDefault(_modalDialog); 10103 10104// Require html5 tech, at least for disposing the original video tag 10105 10106var _techTechJs = _dereq_('./tech/tech.js'); 10107 10108var _techTechJs2 = _interopRequireDefault(_techTechJs); 10109 10110var _techHtml5Js = _dereq_('./tech/html5.js'); 10111 10112var _techHtml5Js2 = _interopRequireDefault(_techHtml5Js); 10113 10114/** 10115 * An instance of the `Player` class is created when any of the Video.js setup methods are used to initialize a video. 10116 * ```js 10117 * var myPlayer = videojs('example_video_1'); 10118 * ``` 10119 * In the following example, the `data-setup` attribute tells the Video.js library to create a player instance when the library is ready. 10120 * ```html 10121 * <video id="example_video_1" data-setup='{}' controls> 10122 * <source src="my-source.mp4" type="video/mp4"> 10123 * </video> 10124 * ``` 10125 * After an instance has been created it can be accessed globally using `Video('example_video_1')`. 10126 * 10127 * @param {Element}
10127 tag The original video tag used for configuring options 10128 * @param {Object=} options Object of option names and values 10129 * @param {Function=} ready Ready callback function 10130 * @extends Component 10131 * @class Player 10132 */ 10133 10134var Player = (function (_Component) { 10135 _inherits(Player, _Component); 10136 10137 /** 10138 * player's constructor function 10139 * 10140 * @constructs 10141 * @method init 10142 * @param {Element} tag The original video tag used for configuring options 10143 * @param {Object=} options Player options 10144 * @param {Function=} ready Ready callback function 10145 */ 10146 10147 function Player(tag, options, ready) { 10148 var _this = this; 10149 10150 _classCallCheck(this, Player); 10151 10152 // Make sure tag ID exists 10153 tag.id = tag.id || 'vjs_video_' + Guid.newGUID(); 10154 10155 // Set Options 10156 // The options argument overrides options set in the video tag 10157 // which overrides globally set options. 10158 // This latter part coincides with the load order 10159 // (tag must exist before Player) 10160 options = _objectAssign2['default'](Player.getTagSettings(tag), options); 10161 10162 // Delay the initialization of children because we need to set up 10163 // player properties first, and can't use `this` before `super()` 10164 options.initChildren = false; 10165 10166 // Same with creating the element 10167 options.createEl = false;
10168 10169 // we don't want the player to report touch activity on itself 10170 // see enableTouchActivity in Component 10171 options.reportTouchActivity = false; 10172 10173 // Run base component initializing with new options 10174 _Component.call(this, null, options, ready); 10175 10176 // if the global option object was accidentally blown away by 10177 // someone, bail early with an informative error 10178 if (!this.options_ || !this.options_.techOrder || !this.options_.techOrder.length) { 10179 throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?'); 10180 } 10181 10182 this.tag = tag; // Store the original tag used to set options 10183 10184 // Store the tag attributes used to restore html5 element 10185 this.tagAttributes = tag && Dom.getElAttributes(tag); 10186 10187 // Update current language 10188 this.language(this.options_.language); 10189 10190 // Update Supported Languages 10191 if (options.languages) { 10192 (function () { 10193 // Normalise player option languages to lowercase 10194 var languagesToLower = {}; 10195 10196 Object.getOwnPropertyNames(options.languages).forEach(function (name) { 10197 languagesToLower[name.toLowerCase()] = options.languages[name]; 10198 }); 10199 _this.languages_ = languagesToLower; 10200 })(); 10201 } else { 10202 this.languages_ = Player.prototype.options_.languages; 10203 } 10204 10205 // Cache for video property values. 10206 this.cache_ = {}; 10207 10208 // Set poster 10209 this.poster_ = options.poster || ''; 10210 10211 // Set controls 10212 this.controls_ = !!options.controls; 10213 10214 // Original tag settings stored in options 10215 // now remove immediately so native controls don't flash. 10216 // May be turned back on by HTML5 tech if nativeControlsForTouch is true 10217 tag.controls = false; 10218 10219 /* 10220 * Store the internal state of scrubbing 10221 * 10222 * @private 10223 * @return {Boolean} True if the user is scrubbing 10224 */ 10225 this.scrubbing_ = false; 10226 10227 this.el_ = this.createEl(); 10228 10229 // We also want to pass the original player options to each component and plugin 10230 // as well so they don't need to reach back into the player for options later. 10231 // We also need to do another copy of this.options_ so we don't end up with 10232 // an infinite loop. 10233 var playerOptionsCopy = _utilsMergeOptionsJs2['default'](this.options_); 10234 10235 // Load plugins 10236 if (options.plugins) { 10237 (function () { 10238 var plugins = options.plugins; 10239 10240 Object.getOwnPropertyNames(plugins).forEach(function (name) { 10241 if (typeof this[name] === 'function') { 10242 this[name](plugins[name]); 10243 } else { 10244 _utilsLogJs2['default'].error('Unable to find plugin:', name); 10245 } 10246 }, _this); 10247 })(); 10248 } 10249 10250 this.options_.playerOptions = playerOptionsCopy; 10251 10252 this.initChildren(); 10253 10254 // Set isAudio based on whether or not an audio tag was used 10255 this.isAudio(tag.nodeName.toLowerCase() === 'audio'); 10256 10257 // Update controls className. Can't do this when the controls are initially 10258 // set because the element doesn't exist yet. 10259 if (this.controls()) { 10260 this.addClass('vjs-controls-enabled'); 10261 } else { 10262 this.addClass('vjs-controls-disabled'); 10263 } 10264 10265 // Set ARIA label and region role depending on player type 10266 this.el_.setAttribute('role', 'region'); 10267 if (this.isAudio()) { 10268 this.el_.setAttribute('aria-label', 'audio player'); 10269 } else { 10270 this.el_.setAttribute('aria-label', 'video player'); 10271 } 10272 10273 if (this.isAudio()) { 10274 this.addClass('vjs-audio'); 10275 } 10276 10277 if (this.flexNotSupported_()) { 10278 this.addClass('vjs-no-flex'); 10279 } 10280 10281 // TODO: Make this smarter. Toggle user state between touching/mousing 10282 // using events, since devices can have both touch and mouse events. 10283 // if (browser.TOUCH_ENABLED) { 10284 // this.addClass('vjs-touch-enabled'); 10285 // } 10286 10287 // iOS Safari has broken hover handling 10288 if (!browser.IS_IOS) { 10289 this.addClass('vjs-workinghover'); 10290 } 10291 10292 // Make player easily findable by ID 10293 Player.players[this.id_] = this; 10294 10295 // When the player is first initialized, trigger activity so components 10296 // like the control bar show themselves if needed 10297 this.userActive(true); 10298 this.reportUserActivity(); 10299 this.listenForUserActivity_(); 10300 10301 this.on('fullscreenchange', this.handleFullscreenChange_); 10302 this.on('stageclick', this.handleStageClick_); 10303 } 10304 10305 /* 10306 * Global player list 10307 * 10308 * @type {Object} 10309 */ 10310 10311 /** 10312 * Destroys the video player and does any necessary cleanup 10313 * ```js
10314 * myPlayer.dispose(); 10315 * ``` 10316 * This is especially helpful if you are dynamically adding and removing videos 10317 * to/from the DOM. 10318 * 10319 * @method dispose 10320 */ 10321 10322 Player.prototype.dispose = function dispose() { 10323 this.trigger('dispose'); 10324 // prevent dispose from being called twice 10325 this.off('dispose'); 10326 10327 if (this.styleEl_ && this.styleEl_.parentNode) { 10328 this.styleEl_.parentNode.removeChild(this.styleEl_); 10329 } 10330 10331 // Kill reference to this player 10332 Player.players[this.id_] = null; 10333 if (this.tag && this.tag.player) { 10334 this.tag.player = null; 10335 } 10336 if (this.el_ && this.el_.player) { 10337 this.el_.player = null; 10338 } 10339 10340 if (this.tech_) { 10341 this.tech_.dispose(); 10342 } 10343 10344 _Component.prototype.dispose.call(this); 10345 }; 10346 10347 /** 10348 * Create the component's DOM element 10349 * 10350 * @return {Element} 10351 * @method createEl 10352 */ 10353 10354 Player.prototype.createEl = function createEl() { 10355 var el = this.el_ = _Component.prototype.createEl.call(this, 'div'); 10356 var tag = this.tag; 10357 10358 // Remove width/height attrs from tag so CSS can make it 100% width/height 10359 tag.removeAttribute('width'); 10360 tag.removeAttribute('height'); 10361 10362 // Copy over all the attributes from the tag, including ID and class 10363 // ID will now reference player box, not the video tag 10364 var attrs = Dom.getElAttributes(tag); 10365 10366 Object.getOwnPropertyNames(attrs).forEach(function (attr) { 10367 // workaround so we don't totally break IE7 10368 // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7 10369 if (attr === 'class') { 10370 el.className = attrs[attr]; 10371 } else { 10372 el.setAttribute(attr, attrs[attr]); 10373 } 10374 }); 10375 10376 // Update tag id/class for use as HTML5 playback tech 10377 // Might think we should do this after embedding in container so .vjs-tech class 10378 // doesn't flash 100% width/height, but class only applies with .video-js parent 10379 tag.playerId = tag.id; 10380 tag.id += '_html5_api'; 10381 tag.className = 'vjs-tech'; 10382 10383 // Make player findable on elements 10384 tag.player = el.player = this; 10385 // Default state of video is paused 10386 this.addClass('vjs-paused'); 10387 10388 // Add a style element in the player that we'll use to set the width/height 10389 // of the player in a way that's still overrideable by CSS, just like the 10390 // video element 10391 if (_globalWindow2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) { 10392 this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions'); 10393 var defaultsStyleEl = Dom.$('.vjs-styles-defaults'); 10394 var head = Dom.$('head'); 10395 head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild); 10396 } 10397 10398 // Pass in the width/height/aspectRatio options which will update the style el 10399 this.width(this.options_.width); 10400 this.height(this.options_.height); 10401 this.fluid(this.options_.fluid); 10402 this.aspectRatio(this.options_.aspectRatio); 10403 10404 // Hide any links within the video/audio tag, because IE doesn't hide them completely. 10405 var links = tag.getElementsByTagName('a'); 10406 for (var i = 0; i < links.length; i++) { 10407 var linkEl = links.item(i); 10408 Dom.addElClass(linkEl, 'vjs-hidden'); 10409 linkEl.setAttribute('hidden', 'hidden'); 10410 } 10411 10412 // insertElFirst seems to cause the networkState to flicker from 3 to 2, so 10413 // keep track of the original for later so we can know if the source originally failed 10414 tag.initNetworkState_ = tag.networkState; 10415 10416 // Wrap video tag in div (el/box) container 10417 if (tag.parentNode) { 10418 tag.parentNode.insertBefore(el, tag); 10419 } 10420 10421 // insert the tag as the first child of the player element 10422 // then manually add it to the children array so that this.addChild 10423 // will work properly for other components 10424 Dom.insertElFirst(tag, el); // Breaks iPhone, fixed in HTML5 setup. 10425 this.children_.unshift(tag); 10426 10427 this.el_ = el; 10428 10429 return el; 10430 }; 10431 10432 /** 10433 * Get/set player width 10434 * 10435 * @param {Number=} value Value for width 10436 * @return {Number} Width when getting 10437 * @method width 10438 */ 10439 10440 Player.prototype.width = function width(value) { 10441 return this.dimension('width', value); 10442 }; 10443 10444 /** 10445 * Get/set player height 10446 * 10447 * @param {Number=} value Value for height 10448 * @return {Number} Height when getting 10449 * @method height 10450 */ 10451 10452 Player.prototype.height = function height(value) { 10453 return this.dimension('height', value); 10454 }; 10455 10456 /** 10457 * Get/set dimension for player 10458 * 10459 * @param {String} dimension Either width or height 10460 * @param {Number=} value Value for dimension 10461 * @return {Component} 10462 * @method dimension 10463 */ 10464 10465 Player.prototype.dimension = function dimension(_dimension, value) { 10466 var privDimension = _dimension + '_'; 10467 10468 if (value === undefined) { 10469 return this[privDimension] || 0; 10470 } 10471 10472 if (value === '') { 10473 // If an empty string is given, reset the dimension to be automatic 10474 this[privDimension] = undefined; 10475 } else { 10476 var parsedVal = parseFloat(value); 10477 10478 if (isNaN(parsedVal)) { 10479 _utilsLogJs2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension); 10480 return this; 10481 } 10482 10483 this[privDimension] = parsedVal; 10484 } 10485 10486 this.updateStyleEl_(); 10487 return this; 10488 }; 10489 10490 /** 10491 * Add/remove the vjs-fluid class 10492 * 10493 * @param {Boolean} bool Value of true adds the class, value of false removes the class 10494 * @method fluid 10495 */ 10496 10497 Player.prototype.fluid = function fluid(bool) { 10498 if (bool === undefined) { 10499 return !!this.fluid_; 10500 } 10501 10502 this.fluid_ = !!bool; 10503 10504 if (bool) { 10505 this.addClass('vjs-fluid'); 10506 } else { 10507 this.removeClass('vjs-fluid'); 10508 } 10509 }; 10510 10511 /** 10512 * Get/Set the aspect ratio 10513 * 10514 * @param {String=} ratio Aspect ratio for player 10515 * @return aspectRatio 10516 * @method aspectRatio 10517 */ 10518 10519 Player.prototype.aspectRatio = function aspectRatio(ratio) { 10520 if (ratio === undefined) { 10521 return this.aspectRatio_; 10522 } 10523 10524 // Check for width:height format 10525 if (!/^\d+\:\d+$/.test(ratio)) { 10526 throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.'); 10527 } 10528 this.aspectRatio_ = ratio; 10529 10530 // We're assuming if you set an aspect ratio you want fluid mode, 10531 // because in fixed mode you could calculate width and height yourself. 10532 this.fluid(true); 10533 10534 this.updateStyleEl_(); 10535 }; 10536 10537 /** 10538 * Update styles of the player element (height, width and aspect ratio) 10539 * 10540 * @method updateStyleEl_ 10541 */ 10542 10543 Player.prototype.updateStyleEl_ = function updateStyleEl_() { 10544 if (_globalWindow2['default'].VIDEOJS_NO_DYNAMIC_STYLE === true) { 10545 var _width = typeof this.width_ === 'number' ? this.width_ : this.options_.width; 10546 var _height = typeof this.height_ === 'number' ? this.height_ : this.options_.height; 10547 var techEl = this.tech_ && this.tech_.el(); 10548 10549 if (techEl) { 10550 if (_width >= 0) { 10551 techEl.width = _width; 10552 } 10553 if (_height >= 0) {
10554 techEl.height = _height; 10555 } 10556 } 10557 10558 return; 10559 } 10560 10561 var width = undefined; 10562 var height = undefined; 10563 var aspectRatio = undefined; 10564 var idClass = undefined; 10565 10566 // The aspect ratio is either used directly or to calculate width and height. 10567 if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') { 10568 // Use any aspectRatio that's been specifically set 10569 aspectRatio = this.aspectRatio_; 10570 } else if (this.videoWidth()) { 10571 // Otherwise try to get the aspect ratio from the video metadata 10572 aspectRatio = this.videoWidth() + ':' + this.videoHeight(); 10573 } else { 10574 // Or use a default. The video element's is 2:1, but 16:9 is more common. 10575 aspectRatio = '16:9'; 10576 } 10577 10578 // Get the ratio as a decimal we can use to calculate dimensions 10579 var ratioParts = aspectRatio.split(':'); 10580 var ratioMultiplier = ratioParts[1] / ratioParts[0]; 10581 10582 if (this.width_ !== undefined) { 10583 // Use any width that's been specifically set 10584 width = this.width_; 10585 } else if (this.height_ !== undefined) { 10586 // Or calulate the width from the aspect ratio if a height has been set 10587 width = this.height_ / ratioMultiplier; 10588 } else { 10589 // Or use the video's metadata, or use the video el's default of 300 10590 width = this.videoWidth() || 300; 10591 } 10592 10593 if (this.height_ !== undefined) { 10594 // Use any height that's been specifically set 10595 height = this.height_; 10596 } else { 10597 // Otherwise calculate the height from the ratio and the width 10598 height = width * ratioMultiplier; 10599 } 10600 10601 // Ensure the CSS class is valid by starting with an alpha character 10602 if (/^[^a-zA-Z]/.test(this.id())) { 10603 idClass = 'dimensions-' + this.id(); 10604 } else { 10605 idClass = this.id() + '-dimensions'; 10606 } 10607 10608 // Ensure the right class is still on the player for the style element 10609 this.addClass(idClass); 10610 10611 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 '); 10612 }; 10613 10614 /** 10615 * Load the Media Playback Technology (tech) 10616 * Load/Create an instance of playback technology including element and API methods 10617 * And append playback element in player div. 10618 * 10619 * @param {String} techName Name of the playback technology 10620 * @param {String} source Video source 10621 * @method loadTech_ 10622 * @private 10623 */ 10624 10625 Player.prototype.loadTech_ = function loadTech_(techName, source) { 10626 10627 // Pause and remove current playback technology 10628 if (this.tech_) { 10629 this.unloadTech_(); 10630 } 10631 10632 // get rid of the HTML5 video tag as soon as we are using another tech 10633 if (techName !== 'Html5' && this.tag) { 10634 _techTechJs2['default'].getTech('Html5').disposeMediaElement(this.tag); 10635 this.tag.player = null; 10636 this.tag = null; 10637 } 10638 10639 this.techName_ = techName; 10640 10641 // Turn off API access because we're loading a new tech that might load asynchronously 10642 this.isReady_ = false; 10643 10644 // Grab tech-specific options from player options and add source and parent element to use. 10645 var techOptions = _objectAssign2['default']({ 10646 'nativeControlsForTouch': this.options_.nativeControlsForTouch, 10647 'source': source, 10648 'playerId': this.id(), 10649 'techId': this.id() + '_' + techName + '_api', 10650 'videoTracks': this.videoTracks_, 10651 'textTracks': this.textTracks_, 10652 'audioTracks': this.audioTracks_, 10653 'autoplay': this.options_.autoplay, 10654 'preload': this.options_.preload, 10655 'loop': this.options_.loop, 10656 'muted': this.options_.muted, 10657 'poster': this.poster(), 10658 'language': this.language(), 10659 'vtt.js': this.options_['vtt.js'] 10660 }, this.options_[techName.toLowerCase()]); 10661 10662 if (this.tag) { 10663 techOptions.tag = this.tag; 10664 } 10665 10666 if (source) { 10667 this.currentType_ = source.type; 10668 if (source.src === this.cache_.src && this.cache_.currentTime > 0) { 10669 techOptions.startTime = this.cache_.currentTime; 10670 } 10671 10672 this.cache_.src = source.src; 10673 } 10674 10675 // Initialize tech instance 10676 var techComponent = _techTechJs2['default'].getTech(techName);
10677 // Support old behavior of techs being registered as components. 10678 // Remove once that deprecated behavior is removed. 10679 if (!techComponent) { 10680 techComponent = _componentJs2['default'].getComponent(techName); 10681 } 10682 this.tech_ = new techComponent(techOptions); 10683 10684 // player.triggerReady is always async, so don't need this to be async 10685 this.tech_.ready(Fn.bind(this, this.handleTechReady_), true); 10686 10687 _tracksTextTrackListConverterJs2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_); 10688 10689 // Listen to all HTML5-defined events and trigger them on the player 10690 this.on(this.tech_, 'loadstart', this.handleTechLoadStart_); 10691 this.on(this.tech_, 'waiting', this.handleTechWaiting_); 10692 this.on(this.tech_, 'canplay', this.handleTechCanPlay_); 10693 this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_); 10694 this.on(this.tech_, 'playing', this.handleTechPlaying_); 10695 this.on(this.tech_, 'ended', this.handleTechEnded_); 10696 this.on(this.tech_, 'seeking', this.handleTechSeeking_); 10697 this.on(this.tech_, 'seeked', this.handleTechSeeked_); 10698 this.on(this.tech_, 'play', this.handleTechPlay_); 10699 this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_); 10700 this.on(this.tech_, 'pause', this.handleTechPause_); 10701 this.on(this.tech_, 'progress', this.handleTechProgress_); 10702 this.on(this.tech_, 'durationchange', this.handleTechDurationChange_); 10703 this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_); 10704 this.on(this.tech_, 'error', this.handleTechError_); 10705 this.on(this.tech_, 'suspend', this.handleTechSuspend_); 10706 this.on(this.tech_, 'abort', this.handleTechAbort_); 10707 this.on(this.tech_, 'emptied', this.handleTechEmptied_); 10708 this.on(this.tech_, 'stalled', this.handleTechStalled_); 10709 this.on(this.tech_, 'loadedmetadata', this.handleTechLoadedMetaData_); 10710 this.on(this.tech_, 'loadeddata', this.handleTechLoadedData_); 10711 this.on(this.tech_, 'timeupdate', this.handleTechTimeUpdate_); 10712 this.on(this.tech_, 'ratechange', this.handleTechRateChange_); 10713 this.on(this.tech_, 'volumechange', this.handleTechVolumeChange_); 10714 this.on(this.tech_, 'texttrackchange', this.handleTechTextTrackChange_); 10715 this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_); 10716 this.on(this.tech_, 'posterchange', this.handleTechPosterChange_); 10717 10718 this.usingNativeControls(this.techGet_('controls')); 10719 10720 if (this.controls() && !this.usingNativeControls()) { 10721 this.addTechControlsListeners_(); 10722 } 10723 10724 // Add the tech element in the DOM if it was not already there 10725 // Make sure to not insert the original video element if using Html5 10726 if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) { 10727 Dom.insertElFirst(this.tech_.el(), this.el()); 10728 } 10729 10730 // Get rid of the original video tag reference after the first tech is loaded 10731 if (this.tag) { 10732 this.tag.player = null; 10733 this.tag = null; 10734 } 10735 }; 10736 10737 /** 10738 * Unload playback technology 10739 * 10740 * @method unloadTech_ 10741 * @private 10742 */ 10743 10744 Player.prototype.unloadTech_ = function unloadTech_() { 10745 // Save the current text tracks so that we can reuse the same text tracks with the next tech 10746 this.videoTracks_ = this.videoTracks(); 10747 this.textTracks_ = this.textTracks(); 10748 this.audioTracks_ = this.audioTracks(); 10749 this.textTracksJson_ = _tracksTextTrackListConverterJs2['default'].textTracksToJson(this.tech_); 10750 10751 this.isReady_ = false; 10752 10753 this.tech_.dispose(); 10754 10755 this.tech_ = false;
10756 }; 10757 10758 /** 10759 * Return a reference to the current tech. 10760 * It will only return a reference to the tech if given an object with the 10761 * `IWillNotUseThisInPlugins` property on it. This is try and prevent misuse 10762 * of techs by plugins. 10763 * 10764 * @param {Object} 10765 * @return {Object} The Tech 10766 * @method tech 10767 */ 10768 10769 Player.prototype.tech = function tech(safety) { 10770 if (safety && safety.IWillNotUseThisInPlugins) { 10771 return this.tech_; 10772 } 10773 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 '; 10774 _globalWindow2['default'].alert(errorText); 10775 throw new Error(errorText); 10776 }; 10777 10778 /** 10779 * Set up click and touch listeners for the playback element 10780 * 10781 * On desktops, a click on the video itself will toggle playback, 10782 * on a mobile device a click on the video toggles controls. 10783 * (toggling controls is done by toggling the user state between active and 10784 * inactive) 10785 * A tap can signal that a user has become active, or has become inactive 10786 * e.g. a quick tap on an iPhone movie should reveal the controls. Another 10787 * quick tap should hide them again (signaling the user is in an inactive 10788 * viewing state) 10789 * In addition to this, we still want the user to be considered inactive after 10790 * a few seconds of inactivity. 10791 * Note: the only part of iOS interaction we can't mimic with this setup 10792 * is a touch and hold on the video element counting as activity in order to 10793 * keep the controls showing, but that shouldn't be an issue. A touch and hold 10794 * on any controls will still keep the user active 10795 * 10796 * @private 10797 * @method addTechControlsListeners_ 10798 */ 10799 10800 Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() { 10801 // Make sure to remove all the previous listeners in case we are called multiple times. 10802 this.removeTechControlsListeners_(); 10803 10804 // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do 10805 // trigger mousedown/up. 10806 // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object 10807 // Any touch events are set to block the mousedown event from happening 10808 this.on(this.tech_, 'mousedown', this.handleTechClick_); 10809 10810 // If the controls were hidden we don't want that to change without a tap event 10811 // so we'll check if the controls were already showing before reporting user 10812 // activity 10813 this.on(this.tech_, 'touchstart', this.handleTechTouchStart_); 10814 this.on(this.tech_, 'touchmove', this.handleTechTouchMove_); 10815 this.on(this.tech_, 'touchend', this.handleTechTouchEnd_); 10816 10817 // The tap listener needs to come after the touchend listener because the tap 10818 // listener cancels out any reportedUserActivity when setting userActive(false) 10819 this.on(this.tech_, 'tap', this.handleTechTap_); 10820 }; 10821 10822 /** 10823 * Remove the listeners used for click and tap controls. This is needed for 10824 * toggling to controls disabled, where a tap/touch should do nothing. 10825 * 10826 * @method removeTechControlsListeners_ 10827 * @private 10828 */ 10829 10830 Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() { 10831 // We don't want to just use `this.off()` because there might be other needed 10832 // listeners added by techs that extend this. 10833 this.off(this.tech_, 'tap', this.handleTechTap_); 10834 this.off(this.tech_, 'touchstart', this.handleTechTouchStart_); 10835 this.off(this.tech_, 'touchmove', this.handleTechTouchMove_); 10836 this.off(this.tech_, 'touchend', this.handleTechTouchEnd_); 10837 this.off(this.tech_, 'mousedown', this.handleTechClick_); 10838 }; 10839 10840 /** 10841 * Player waits for the tech to be ready 10842 * 10843 * @method handleTechReady_ 10844 * @private 10845 */ 10846 10847 Player.prototype.handleTechReady_ = function handleTechReady_() { 10848 this.triggerReady(); 10849 10850 // Keep the same volume as before 10851 if (this.cache_.volume) { 10852 this.techCall_('setVolume', this.cache_.volume); 10853 } 10854 10855 // Look if the tech found a higher resolution poster while loading 10856 this.handleTechPosterChange_(); 10857 10858 // Update the duration if available 10859 this.handleTechDurationChange_(); 10860 10861 // Chrome and Safari both have issues with autoplay. 10862 // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work. 10863 // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays) 10864 // This fixes both issues. Need to wait for API, so it updates displays correctly 10865 if (this.src() && this.tag && this.options_.autoplay && this.paused()) {
vendor: 12,738 bytes, lines 10866-11391
10866 try { 10867 delete this.tag.poster; // Chrome Fix. Fixed in Chrome v16. 10868 } catch (e) { 10869 _utilsLogJs2['default']('deleting tag.poster throws in some browsers', e); 10870 } 10871 this.play(); 10872 } 10873 }; 10874 10875 /** 10876 * Fired when the user agent begins looking for media data 10877 * 10878 * @private 10879 * @method handleTechLoadStart_ 10880 */ 10881 10882 Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() { 10883 // TODO: Update to use `emptied` event instead. See #1277. 10884 10885 this.removeClass('vjs-ended'); 10886 10887 // reset the error state 10888 this.error(null); 10889 10890 // If it's already playing we want to trigger a firstplay event now. 10891 // The firstplay event relies on both the play and loadstart events 10892 // which can happen in any order for a new source 10893 if (!this.paused()) { 10894 this.trigger('loadstart'); 10895 this.trigger('firstplay'); 10896 } else { 10897 // reset the hasStarted state 10898 this.hasStarted(false); 10899 this.trigger('loadstart'); 10900 } 10901 }; 10902 10903 /** 10904 * Add/remove the vjs-has-started class 10905 * 10906 * @param {Boolean} hasStarted The value of true adds the class the value of false remove the class 10907 * @return {Boolean} Boolean value if has started 10908 * @private 10909 * @method hasStarted 10910 */ 10911 10912 Player.prototype.hasStarted = function hasStarted(_hasStarted) { 10913 if (_hasStarted !== undefined) { 10914 // only update if this is a new value 10915 if (this.hasStarted_ !== _hasStarted) { 10916 this.hasStarted_ = _hasStarted; 10917 if (_hasStarted) { 10918 this.addClass('vjs-has-started'); 10919 // trigger the firstplay event if this newly has played 10920 this.trigger('firstplay'); 10921 } else { 10922 this.removeClass('vjs-has-started'); 10923 } 10924 } 10925 return this; 10926 } 10927 return !!this.hasStarted_; 10928 }; 10929 10930 /** 10931 * Fired whenever the media begins or resumes playback 10932 * 10933 * @private 10934 * @method handleTechPlay_ 10935 */ 10936 10937 Player.prototype.handleTechPlay_ = function handleTechPlay_() { 10938 this.removeClass('vjs-ended'); 10939 this.removeClass('vjs-paused'); 10940 this.addClass('vjs-playing'); 10941 10942 // hide the poster when the user hits play 10943 // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play 10944 this.hasStarted(true); 10945 10946 this.trigger('play'); 10947 }; 10948 10949 /** 10950 * Fired whenever the media begins waiting 10951 * 10952 * @private 10953 * @method handleTechWaiting_ 10954 */ 10955 10956 Player.prototype.handleTechWaiting_ = function handleTechWaiting_() { 10957 var _this2 = this; 10958 10959 this.addClass('vjs-waiting'); 10960 this.trigger('waiting'); 10961 this.one('timeupdate', function () { 10962 return _this2.removeClass('vjs-waiting'); 10963 }); 10964 }; 10965 10966 /** 10967 * A handler for events that signal that waiting has ended 10968 * which is not consistent between browsers. See #1351 10969 * 10970 * @private 10971 * @method handleTechCanPlay_ 10972 */ 10973 10974 Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() { 10975 this.removeClass('vjs-waiting'); 10976 this.trigger('canplay'); 10977 }; 10978 10979 /** 10980 * A handler for events that signal that waiting has ended 10981 * which is not consistent between browsers. See #1351 10982 * 10983 * @private 10984 * @method handleTechCanPlayThrough_ 10985 */ 10986 10987 Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() { 10988 this.removeClass('vjs-waiting'); 10989 this.trigger('canplaythrough'); 10990 }; 10991 10992 /** 10993 * A handler for events that signal that waiting has ended 10994 * which is not consistent between browsers. See #1351 10995 * 10996 * @private 10997 * @method handleTechPlaying_ 10998 */ 10999 11000 Player.prototype.handleTechPlaying_ = function handleTechPlaying_() { 11001 this.removeClass('vjs-waiting'); 11002 this.trigger('playing'); 11003 }; 11004 11005 /** 11006 * Fired whenever the player is jumping to a new time 11007 * 11008 * @private 11009 * @method handleTechSeeking_ 11010 */ 11011 11012 Player.prototype.handleTechSeeking_ = function handleTechSeeking_() { 11013 this.addClass('vjs-seeking'); 11014 this.trigger('seeking'); 11015 }; 11016 11017 /** 11018 * Fired when the player has finished jumping to a new time 11019 * 11020 * @private 11021 * @method handleTechSeeked_ 11022 */ 11023 11024 Player.prototype.handleTechSeeked_ = function handleTechSeeked_() { 11025 this.removeClass('vjs-seeking'); 11026 this.trigger('seeked'); 11027 }; 11028 11029 /** 11030 * Fired the first time a video is played 11031 * Not part of the HLS spec, and we're not sure if this is the best 11032 * implementation yet, so use sparingly. If you don't have a reason to 11033 * prevent playback, use `myPlayer.one('play');` instead. 11034 * 11035 * @private 11036 * @method handleTechFirstPlay_ 11037 */ 11038 11039 Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() { 11040 //If the first starttime attribute is specified 11041 //then we will start at the given offset in seconds 11042 if (this.options_.starttime) { 11043 this.currentTime(this.options_.starttime); 11044 } 11045 11046 this.addClass('vjs-has-started'); 11047 this.trigger('firstplay'); 11048 }; 11049 11050 /** 11051 * Fired whenever the media has been paused 11052 * 11053 * @private 11054 * @method handleTechPause_ 11055 */ 11056 11057 Player.prototype.handleTechPause_ = function handleTechPause_() { 11058 this.removeClass('vjs-playing'); 11059 this.addClass('vjs-paused'); 11060 this.trigger('pause'); 11061 }; 11062 11063 /** 11064 * Fired while the user agent is downloading media data 11065 * 11066 * @private 11067 * @method handleTechProgress_ 11068 */ 11069 11070 Player.prototype.handleTechProgress_ = function handleTechProgress_() { 11071 this.trigger('progress'); 11072 }; 11073 11074 /** 11075 * Fired when the end of the media resource is reached (currentTime == duration) 11076 * 11077 * @private 11078 * @method handleTechEnded_ 11079 */ 11080 11081 Player.prototype.handleTechEnded_ = function handleTechEnded_() { 11082 this.addClass('vjs-ended'); 11083 if (this.options_.loop) { 11084 this.currentTime(0); 11085 this.play(); 11086 } else if (!this.paused()) { 11087 this.pause(); 11088 } 11089 11090 this.trigger('ended'); 11091 }; 11092 11093 /** 11094 * Fired when the duration of the media resource is first known or changed 11095 * 11096 * @private 11097 * @method handleTechDurationChange_ 11098 */ 11099 11100 Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() { 11101 this.duration(this.techGet_('duration')); 11102 }; 11103 11104 /** 11105 * Handle a click on the media element to play/pause 11106 * 11107 * @param {Object=} event Event object 11108 * @private 11109 * @method handleTechClick_ 11110 */ 11111 11112 Player.prototype.handleTechClick_ = function handleTechClick_(event) { 11113 // We're using mousedown to detect clicks thanks to Flash, but mousedown 11114 // will also be triggered with right-clicks, so we need to prevent that 11115 if (event.button !== 0) return; 11116 11117 // When controls are disabled a click should not toggle playback because 11118 // the click is considered a control 11119 if (this.controls()) { 11120 if (this.paused()) { 11121 this.play(); 11122 } else { 11123 this.pause(); 11124 } 11125 } 11126 }; 11127 11128 /** 11129 * Handle a tap on the media element. It will toggle the user 11130 * activity state, which hides and shows the controls. 11131 * 11132 * @private 11133 * @method handleTechTap_ 11134 */ 11135 11136 Player.prototype.handleTechTap_ = function handleTechTap_() { 11137 this.userActive(!this.userActive()); 11138 }; 11139 11140 /** 11141 * Handle touch to start 11142 * 11143 * @private 11144 * @method handleTechTouchStart_ 11145 */ 11146 11147 Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() { 11148 this.userWasActive = this.userActive(); 11149 }; 11150 11151 /** 11152 * Handle touch to move 11153 * 11154 * @private 11155 * @method handleTechTouchMove_ 11156 */ 11157 11158 Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() { 11159 if (this.userWasActive) { 11160 this.reportUserActivity(); 11161 } 11162 }; 11163 11164 /** 11165 * Handle touch to end 11166 * 11167 * @private 11168 * @method handleTechTouchEnd_ 11169 */ 11170 11171 Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) { 11172 // Stop the mouse events from also happening 11173 event.preventDefault(); 11174 }; 11175 11176 /** 11177 * Fired when the player switches in or out of fullscreen mode 11178 * 11179 * @private 11180 * @method handleFullscreenChange_ 11181 */ 11182 11183 Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() { 11184 if (this.isFullscreen()) { 11185 this.addClass('vjs-fullscreen'); 11186 } else { 11187 this.removeClass('vjs-fullscreen'); 11188 } 11189 }; 11190 11191 /** 11192 * native click events on the SWF aren't triggered on IE11, Win8.1RT 11193 * use stageclick events triggered from inside the SWF instead 11194 * 11195 * @private 11196 * @method handleStageClick_ 11197 */ 11198 11199 Player.prototype.handleStageClick_ = function handleStageClick_() { 11200 this.reportUserActivity(); 11201 }; 11202 11203 /** 11204 * Handle Tech Fullscreen Change 11205 * 11206 * @private 11207 * @method handleTechFullscreenChange_ 11208 */ 11209 11210 Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) { 11211 if (data) { 11212 this.isFullscreen(data.isFullscreen); 11213 } 11214 this.trigger('fullscreenchange'); 11215 }; 11216 11217 /** 11218 * Fires when an error occurred during the loading of an audio/video 11219 * 11220 * @private 11221 * @method handleTechError_ 11222 */ 11223 11224 Player.prototype.handleTechError_ = function handleTechError_() { 11225 var error = this.tech_.error(); 11226 this.error(error && error.code); 11227 }; 11228 11229 /** 11230 * Fires when the browser is intentionally not getting media data 11231 * 11232 * @private 11233 * @method handleTechSuspend_ 11234 */ 11235 11236 Player.prototype.handleTechSuspend_ = function handleTechSuspend_() { 11237 this.trigger('suspend'); 11238 }; 11239 11240 /** 11241 * Fires when the loading of an audio/video is aborted 11242 * 11243 * @private 11244 * @method handleTechAbort_ 11245 */ 11246 11247 Player.prototype.handleTechAbort_ = function handleTechAbort_() { 11248 this.trigger('abort'); 11249 }; 11250 11251 /** 11252 * Fires when the current playlist is empty 11253 * 11254 * @private 11255 * @method handleTechEmptied_ 11256 */ 11257 11258 Player.prototype.handleTechEmptied_ = function handleTechEmptied_() { 11259 this.trigger('emptied'); 11260 }; 11261 11262 /** 11263 * Fires when the browser is trying to get media data, but data is not available 11264 * 11265 * @private 11266 * @method handleTechStalled_ 11267 */ 11268 11269 Player.prototype.handleTechStalled_ = function handleTechStalled_() { 11270 this.trigger('stalled'); 11271 }; 11272 11273 /** 11274 * Fires when the browser has loaded meta data for the audio/video 11275 * 11276 * @private 11277 * @method handleTechLoadedMetaData_ 11278 */ 11279 11280 Player.prototype.handleTechLoadedMetaData_ = function handleTechLoadedMetaData_() { 11281 this.trigger('loadedmetadata'); 11282 }; 11283 11284 /** 11285 * Fires when the browser has loaded the current frame of the audio/video 11286 * 11287 * @private 11288 * @method handleTechLoadedData_ 11289 */ 11290 11291 Player.prototype.handleTechLoadedData_ = function handleTechLoadedData_() { 11292 this.trigger('loadeddata'); 11293 }; 11294 11295 /** 11296 * Fires when the current playback position has changed 11297 * 11298 * @private 11299 * @method handleTechTimeUpdate_ 11300 */ 11301 11302 Player.prototype.handleTechTimeUpdate_ = function handleTechTimeUpdate_() { 11303 this.trigger('timeupdate'); 11304 }; 11305 11306 /** 11307 * Fires when the playing speed of the audio/video is changed 11308 * 11309 * @private 11310 * @method handleTechRateChange_ 11311 */ 11312 11313 Player.prototype.handleTechRateChange_ = function handleTechRateChange_() { 11314 this.trigger('ratechange'); 11315 }; 11316 11317 /** 11318 * Fires when the volume has been changed 11319 * 11320 * @private 11321 * @method handleTechVolumeChange_ 11322 */ 11323 11324 Player.prototype.handleTechVolumeChange_ = function handleTechVolumeChange_() { 11325 this.trigger('volumechange'); 11326 }; 11327 11328 /** 11329 * Fires when the text track has been changed 11330 * 11331 * @private 11332 * @method handleTechTextTrackChange_ 11333 */ 11334 11335 Player.prototype.handleTechTextTrackChange_ = function handleTechTextTrackChange_() { 11336 this.trigger('texttrackchange'); 11337 }; 11338 11339 /** 11340 * Get object for cached values. 11341 * 11342 * @return {Object} 11343 * @method getCache 11344 */ 11345 11346 Player.prototype.getCache = function getCache() { 11347 return this.cache_; 11348 }; 11349 11350 /** 11351 * Pass values to the playback tech 11352 * 11353 * @param {String=} method Method 11354 * @param {Object=} arg Argument 11355 * @private 11356 * @method techCall_ 11357 */ 11358 11359 Player.prototype.techCall_ = function techCall_(method, arg) { 11360 // If it's not ready yet, call method when it is 11361 if (this.tech_ && !this.tech_.isReady_) { 11362 this.tech_.ready(function () { 11363 this[method](arg); 11364 }, true); 11365 11366 // Otherwise call method now 11367 } else { 11368 try { 11369 this.tech_[method](arg); 11370 } catch (e) { 11371 _utilsLogJs2['default'](e); 11372 throw e; 11373 } 11374 } 11375 }; 11376 11377 /** 11378 * Get calls can't wait for the tech, and sometimes don't need to. 11379 * 11380 * @param {String} method Tech method 11381 * @return {Method} 11382 * @private 11383 * @method techGet_ 11384 */ 11385 11386 Player.prototype.techGet_ = function techGet_(method) { 11387 if (this.tech_ && this.tech_.isReady_) { 11388 11389 // Flash likes to die and reload when you hide or reposition it. 11390 // In these cases the object methods go away and we get errors. 11391 // When that happens we'll catch the errors and inform tech that it's not ready any more.
11392 try { 11393 return this.tech_[method](); 11394 } catch (e) { 11395 // When building additional tech libs, an expected method may not be defined yet 11396 if (this.tech_[method] === undefined) { 11397 _utilsLogJs2['default']('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e); 11398 } else { 11399 // When a method isn't available on the object it throws a TypeError 11400 if (e.name === 'TypeError') { 11401 _utilsLogJs2['default']('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e); 11402 this.tech_.isReady_ = false; 11403 } else { 11404 _utilsLogJs2['default'](e); 11405 } 11406 } 11407 throw e; 11408 } 11409 } 11410 11411 return; 11412 }; 11413 11414 /** 11415 * start media playback 11416 * ```js 11417 * myPlayer.play(); 11418 * ``` 11419 * 11420 * @return {Player} self 11421 * @method play 11422 */ 11423 11424 Player.prototype.play = function play() { 11425 this.techCall_('play'); 11426 return this; 11427 }; 11428 11429 /** 11430 * Pause the video playback 11431 * ```js 11432 * myPlayer.pause(); 11433 * ``` 11434 * 11435 * @return {Player} self 11436 * @method pause 11437 */ 11438 11439 Player.prototype.pause = function pause() { 11440 this.techCall_('pause'); 11441 return this; 11442 }; 11443 11444 /** 11445 * Check if the player is paused 11446 * ```js 11447 * var isPaused = myPlayer.paused(); 11448 * var isPlaying = !myPlayer.paused(); 11449 * ``` 11450 * 11451 * @return {Boolean} false if the media is currently playing, or true otherwise 11452 * @method paused 11453 */ 11454 11455 Player.prototype.paused = function paused() { 11456 // The initial state of paused should be true (in Safari it's actually false) 11457 return this.techGet_('paused') === false ? false : true; 11458 }; 11459 11460 /** 11461 * Returns whether or not the user is "scrubbing". Scrubbing is when the user 11462 * has clicked the progress bar handle and is dragging it along the progress bar. 11463 * 11464 * @param {Boolean} isScrubbing True/false the user is scrubbing 11465 * @return {Boolean} The scrubbing status when getting 11466 * @return {Object} The player when setting 11467 * @method scrubbing 11468 */ 11469 11470 Player.prototype.scrubbing = function scrubbing(isScrubbing) { 11471 if (isScrubbing !== undefined) { 11472 this.scrubbing_ = !!isScrubbing; 11473 11474 if (isScrubbing) { 11475 this.addClass('vjs-scrubbing'); 11476 } else { 11477 this.removeClass('vjs-scrubbing'); 11478 } 11479 11480 return this; 11481 } 11482 11483 return this.scrubbing_; 11484 }; 11485 11486 /** 11487 * Get or set the current time (in seconds) 11488 * ```js 11489 * // get 11490 * var whereYouAt = myPlayer.currentTime(); 11491 * // set 11492 * myPlayer.currentTime(120); // 2 minutes into the video 11493 * ``` 11494 * 11495 * @param {Number|String=} seconds The time to seek to 11496 * @return {Number} The time in seconds, when not setting 11497 * @return {Player} self, when the current time is set 11498 * @method currentTime 11499 */ 11500 11501 Player.prototype.currentTime = function currentTime(seconds) { 11502 if (seconds !== undefined) { 11503 11504 this.techCall_('setCurrentTime', seconds); 11505 11506 return this; 11507 } 11508 11509 // cache last currentTime and return. default to 0 seconds 11510 // 11511 // Caching the currentTime is meant to prevent a massive amount of reads on the tech's 11512 // currentTime when scrubbing, but may not provide much performance benefit afterall. 11513 // Should be tested. Also something has to read the actual current time or the cache will 11514 // never get updated. 11515 return this.cache_.currentTime = this.techGet_('currentTime') || 0; 11516 }; 11517 11518 /** 11519 * Get the length in time of the video in seconds 11520 * ```js 11521 * var lengthOfVideo = myPlayer.duration(); 11522 * ``` 11523 * **NOTE**: The video must have started loading before the duration can be 11524 * known, and in the case of Flash, may not be known until the video starts 11525 * playing. 11526 * 11527 * @param {Number} seconds Duration when setting 11528 * @return {Number} The duration of the video in seconds when getting 11529 * @method duration 11530 */ 11531 11532 Player.prototype.duration = function duration(seconds) { 11533 if (seconds === undefined) { 11534 return this.cache_.duration || 0; 11535 } 11536 11537 seconds = parseFloat(seconds) || 0; 11538 11539 // Standardize on Inifity for signaling video is live 11540 if (seconds < 0) { 11541 seconds = Infinity; 11542 } 11543 11544 if (seconds !== this.cache_.duration) { 11545 // Cache the last set value for optimized scrubbing (esp. Flash) 11546 this.cache_.duration = seconds; 11547 11548 if (seconds === Infinity) { 11549 this.addClass('vjs-live'); 11550 } else { 11551 this.removeClass('vjs-live'); 11552 } 11553 11554 this.trigger('durationchange'); 11555 } 11556 11557 return this; 11558 }; 11559 11560 /** 11561 * Calculates how much time is left. 11562 * ```js 11563 * var timeLeft = myPlayer.remainingTime(); 11564 * ``` 11565 * Not a native video element function, but useful 11566 * 11567 * @return {Number} The time remaining in seconds 11568 * @method remainingTime 11569 */ 11570 11571 Player.prototype.remainingTime = function remainingTime() { 11572 return this.duration() - this.currentTime(); 11573 }; 11574 11575 // http://dev.w3.org/html5/spec/video.html#dom-media-buffered 11576 // Buffered returns a timerange object. 11577 // Kind of like an array of portions of the video that have been downloaded.
vendor: 4,087 bytes, lines 11578-11715
11578 11579 /** 11580 * Get a TimeRange object with the times of the video that have been downloaded 11581 * If you just want the percent of the video that's been downloaded, 11582 * use bufferedPercent. 11583 * ```js 11584 * // Number of different ranges of time have been buffered. Usually 1. 11585 * numberOfRanges = bufferedTimeRange.length, 11586 * // Time in seconds when the first range starts. Usually 0. 11587 * firstRangeStart = bufferedTimeRange.start(0), 11588 * // Time in seconds when the first range ends 11589 * firstRangeEnd = bufferedTimeRange.end(0), 11590 * // Length in seconds of the first time range 11591 * firstRangeLength = firstRangeEnd - firstRangeStart; 11592 * ``` 11593 * 11594 * @return {Object} A mock TimeRange object (following HTML spec) 11595 * @method buffered 11596 */ 11597 11598 Player.prototype.buffered = function buffered() { 11599 var buffered = this.techGet_('buffered'); 11600 11601 if (!buffered || !buffered.length) { 11602 buffered = _utilsTimeRangesJs.createTimeRange(0, 0); 11603 } 11604 11605 return buffered; 11606 }; 11607 11608 /** 11609 * Get the percent (as a decimal) of the video that's been downloaded 11610 * ```js 11611 * var howMuchIsDownloaded = myPlayer.bufferedPercent(); 11612 * ``` 11613 * 0 means none, 1 means all. 11614 * (This method isn't in the HTML5 spec, but it's very convenient) 11615 * 11616 * @return {Number} A decimal between 0 and 1 representing the percent 11617 * @method bufferedPercent 11618 */ 11619 11620 Player.prototype.bufferedPercent = function bufferedPercent() { 11621 return _utilsBufferJs.bufferedPercent(this.buffered(), this.duration()); 11622 }; 11623 11624 /** 11625 * Get the ending time of the last buffered time range 11626 * This is used in the progress bar to encapsulate all time ranges. 11627 * 11628 * @return {Number} The end of the last buffered time range 11629 * @method bufferedEnd 11630 */ 11631 11632 Player.prototype.bufferedEnd = function bufferedEnd() { 11633 var buffered = this.buffered(), 11634 duration = this.duration(), 11635 end = buffered.end(buffered.length - 1); 11636 11637 if (end > duration) { 11638 end = duration; 11639 } 11640 11641 return end; 11642 }; 11643 11644 /** 11645 * Get or set the current volume of the media 11646 * ```js 11647 * // get 11648 * var howLoudIsIt = myPlayer.volume(); 11649 * // set 11650 * myPlayer.volume(0.5); // Set volume to half 11651 * ``` 11652 * 0 is off (muted), 1.0 is all the way up, 0.5 is half way. 11653 * 11654 * @param {Number} percentAsDecimal The new volume as a decimal percent 11655 * @return {Number} The current volume when getting 11656 * @return {Player} self when setting 11657 * @method volume 11658 */ 11659 11660 Player.prototype.volume = function volume(percentAsDecimal) { 11661 var vol = undefined; 11662 11663 if (percentAsDecimal !== undefined) { 11664 vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); // Force value to between 0 and 1 11665 this.cache_.volume = vol; 11666 this.techCall_('setVolume', vol); 11667 11668 return this; 11669 } 11670 11671 // Default to 1 when returning current volume. 11672 vol = parseFloat(this.techGet_('volume')); 11673 return isNaN(vol) ? 1 : vol; 11674 }; 11675 11676 /** 11677 * Get the current muted state, or turn mute on or off 11678 * ```js 11679 * // get 11680 * var isVolumeMuted = myPlayer.muted(); 11681 * // set 11682 * myPlayer.muted(true); // mute the volume 11683 * ``` 11684 * 11685 * @param {Boolean=} muted True to mute, false to unmute 11686 * @return {Boolean} True if mute is on, false if not when getting 11687 * @return {Player} self when setting mute 11688 * @method muted 11689 */ 11690 11691 Player.prototype.muted = function muted(_muted) { 11692 if (_muted !== undefined) { 11693 this.techCall_('setMuted', _muted); 11694 return this; 11695 } 11696 return this.techGet_('muted') || false; // Default to false 11697 }; 11698 11699 // Check if current tech can support native fullscreen 11700 // (e.g. with built in controls like iOS, so not our flash swf) 11701 /** 11702 * Check to see if fullscreen is supported 11703 * 11704 * @return {Boolean} 11705 * @method supportsFullScreen 11706 */ 11707 11708 Player.prototype.supportsFullScreen = function supportsFullScreen() { 11709 return this.techGet_('supportsFullScreen') || false; 11710 }; 11711 11712 /** 11713 * Check if the player is in fullscreen mode 11714 * ```js 11715 * // get
11716 * var fullscreenOrNot = myPlayer.isFullscreen(); 11717 * // set 11718 * myPlayer.isFullscreen(true); // tell the player it's in fullscreen 11719 * ``` 11720 * NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official 11721 * property and instead document.fullscreenElement is used. But isFullscreen is 11722 * still a valuable property for internal player workings. 11723 * 11724 * @param {Boolean=} isFS Update the player's fullscreen state 11725 * @return {Boolean} true if fullscreen false if not when getting 11726 * @return {Player} self when setting 11727 * @method isFullscreen 11728 */ 11729 11730 Player.prototype.isFullscreen = function isFullscreen(isFS) { 11731 if (isFS !== undefined) { 11732 this.isFullscreen_ = !!isFS; 11733 return this; 11734 } 11735 return !!this.isFullscreen_; 11736 }; 11737 11738 /** 11739 * Increase the size of the video to full screen 11740 * ```js 11741 * myPlayer.requestFullscreen(); 11742 * ``` 11743 * In some browsers, full screen is not supported natively, so it enters 11744 * "full window mode", where the video fills the browser window. 11745 * In browsers and devices that support native full screen, sometimes the 11746 * browser's default controls will be shown, and not the Video.js custom skin. 11747 * This includes most mobile devices (iOS, Android) and older versions of 11748 * Safari. 11749 * 11750 * @return {Player} self 11751 * @method requestFullscreen 11752 */ 11753 11754 Player.prototype.requestFullscreen = function requestFullscreen() { 11755 var fsApi = _fullscreenApiJs2['default']; 11756 11757 this.isFullscreen(true); 11758 11759 if (fsApi.requestFullscreen) { 11760 // the browser supports going fullscreen at the element level so we can 11761 // take the controls fullscreen as well as the video 11762 11763 // Trigger fullscreenchange event after change 11764 // We have to specifically add this each time, and remove 11765 // when canceling fullscreen. Otherwise if there's multiple 11766 // players on a page, they would all be reacting to the same fullscreen 11767 // events 11768 Events.on(_globalDocument2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) { 11769 this.isFullscreen(_globalDocument2['default'][fsApi.fullscreenElement]); 11770 11771 // If cancelling fullscreen, remove event listener. 11772 if (this.isFullscreen() === false) { 11773 Events.off(_globalDocument2['default'], fsApi.fullscreenchange, documentFullscreenChange); 11774 } 11775 11776 this.trigger('fullscreenchange'); 11777 })); 11778 11779 this.el_[fsApi.requestFullscreen](); 11780 } else if (this.tech_.supportsFullScreen()) { 11781 // we can't take the video.js controls fullscreen but we can go fullscreen 11782 // with native controls 11783 this.techCall_('enterFullScreen'); 11784 } else { 11785 // fullscreen isn't supported so we'll just stretch the video element to 11786 // fill the viewport 11787 this.enterFullWindow(); 11788 this.trigger('fullscreenchange'); 11789 } 11790 11791 return this; 11792 }; 11793 11794 /** 11795 * Return the video to its normal size after having been in full screen mode 11796 * ```js 11797 * myPlayer.exitFullscreen(); 11798 * ``` 11799 * 11800 * @return {Player} self 11801 * @method exitFullscreen 11802 */ 11803 11804 Player.prototype.exitFullscreen = function exitFullscreen() { 11805 var fsApi = _fullscreenApiJs2['default']; 11806 this.isFullscreen(false); 11807 11808 // Check for browser element fullscreen support 11809 if (fsApi.requestFullscreen) { 11810 _globalDocument2['default'][fsApi.exitFullscreen](); 11811 } else if (this.tech_.supportsFullScreen()) { 11812 this.techCall_('exitFullScreen'); 11813 } else { 11814 this.exitFullWindow(); 11815 this.trigger('fullscreenchange'); 11816 } 11817 11818 return this; 11819 }; 11820 11821 /** 11822 * When fullscreen isn't supported we can stretch the video container to as wide as the browser will let us. 11823 * 11824 * @method enterFullWindow 11825 */ 11826 11827 Player.prototype.enterFullWindow = function enterFullWindow() { 11828 this.isFullWindow = true; 11829 11830 // Storing original doc overflow value to return to when fullscreen is off 11831 this.docOrigOverflow = _globalDocument2['default'].documentElement.style.overflow; 11832 11833 // Add listener for esc key to exit fullscreen 11834 Events.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey)); 11835 11836 // Hide any scroll bars 11837 _globalDocument2['default'].documentElement.style.overflow = 'hidden'; 11838 11839 // Apply fullscreen styles 11840 Dom.addElClass(_globalDocument2['default'].body, 'vjs-full-window'); 11841 11842 this.trigger('enterFullWindow'); 11843 }; 11844 11845 /** 11846 * Check for call to either exit full window or full screen on ESC key 11847 * 11848 * @param {String} event Event to check for key press 11849 * @method fullWindowOnEscKey 11850 */ 11851 11852 Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) { 11853 if (event.keyCode === 27) { 11854 if (this.isFullscreen() === true) { 11855 this.exitFullscreen(); 11856 } else { 11857 this.exitFullWindow(); 11858 } 11859 } 11860 }; 11861 11862 /** 11863 * Exit full window 11864 * 11865 * @method exitFullWindow 11866 */ 11867 11868 Player.prototype.exitFullWindow = function exitFullWindow() { 11869 this.isFullWindow = false;
11870 Events.off(_globalDocument2['default'], 'keydown', this.fullWindowOnEscKey); 11871 11872 // Unhide scroll bars. 11873 _globalDocument2['default'].documentElement.style.overflow = this.docOrigOverflow; 11874 11875 // Remove fullscreen styles 11876 Dom.removeElClass(_globalDocument2['default'].body, 'vjs-full-window'); 11877 11878 // Resize the box, controller, and poster to original sizes 11879 // this.positionAll(); 11880 this.trigger('exitFullWindow'); 11881 }; 11882 11883 /** 11884 * Check whether the player can play a given mimetype 11885 * 11886 * @param {String} type The mimetype to check 11887 * @return {String} 'probably', 'maybe', or '' (empty string) 11888 * @method canPlayType 11889 */ 11890 11891 Player.prototype.canPlayType = function canPlayType(type) { 11892 var can = undefined; 11893 11894 // Loop through each playback technology in the options order 11895 for (var i = 0, j = this.options_.techOrder; i < j.length; i++) { 11896 var techName = _utilsToTitleCaseJs2['default'](j[i]); 11897 var tech = _techTechJs2['default'].getTech(techName); 11898 11899 // Support old behavior of techs being registered as components. 11900 // Remove once that deprecated behavior is removed. 11901 if (!tech) { 11902 tech = _componentJs2['default'].getComponent(techName); 11903 } 11904 11905 // Check if the current tech is defined before continuing 11906 if (!tech) { 11907 _utilsLogJs2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.'); 11908 continue; 11909 } 11910 11911 // Check if the browser supports this technology 11912 if (tech.isSupported()) { 11913 can = tech.canPlayType(type); 11914 11915 if (can) { 11916 return can; 11917 } 11918 } 11919 } 11920 11921 return ''; 11922 }; 11923 11924 /** 11925 * Select source based on tech-order or source-order 11926 * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise, 11927 * defaults to tech-order selection 11928 * 11929 * @param {Array} sources The sources for a media asset 11930 * @return {Object|Boolean} Object of source and tech order, otherwise false 11931 * @method selectSource 11932 */ 11933 11934 Player.prototype.selectSource = function selectSource(sources) { 11935 // Get only the techs specified in `techOrder` that exist and are supported by the 11936 // current platform 11937 var techs = this.options_.techOrder.map(_utilsToTitleCaseJs2['default']).map(function (techName) { 11938 // `Component.getComponent(...)` is for support of old behavior of techs 11939 // being registered as components. 11940 // Remove once that deprecated behavior is removed. 11941 return [techName, _techTechJs2['default'].getTech(techName) || _componentJs2['default'].getComponent(techName)]; 11942 }).filter(function (_ref) { 11943 var techName = _ref[0]; 11944 var tech = _ref[1]; 11945 11946 // Check if the current tech is defined before continuing 11947 if (tech) { 11948 // Check if the browser supports this technology 11949 return tech.isSupported(); 11950 } 11951 11952 _utilsLogJs2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.'); 11953 return false; 11954 }); 11955 11956 // Iterate over each `innerArray` element once per `outerArray` element and execute 11957 // `tester` with both. If `tester` returns a non-falsy value, exit early and return 11958 // that value. 11959 var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) { 11960 var found = undefined; 11961 11962 outerArray.some(function (outerChoice) { 11963 return innerArray.some(function (innerChoice) { 11964 found = tester(outerChoice, innerChoice); 11965 11966 if (found) { 11967 return true; 11968 } 11969 }); 11970 }); 11971 11972 return found; 11973 }; 11974 11975 var foundSourceAndTech = undefined; 11976 var flip = function flip(fn) { 11977 return function (a, b) { 11978 return fn(b, a); 11979 }; 11980 }; 11981 var finder = function finder(_ref2, source) { 11982 var techName = _ref2[0]; 11983 var tech = _ref2[1]; 11984 11985 if (tech.canPlaySource(source)) { 11986 return { source: source, tech: techName }; 11987 } 11988 }; 11989 11990 // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources 11991 // to select from them based on their priority. 11992 if (this.options_.sourceOrder) { 11993 // Source-first ordering 11994 foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder)); 11995 } else { 11996 // Tech-first ordering 11997 foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder); 11998 } 11999 12000 return foundSourceAndTech || false; 12001 }; 12002 12003 /** 12004 * The source function updates the video source 12005 * There are three types of variables you can pass as the argument. 12006 * **URL String**: A URL to the the video file. Use this method if you are sure 12007 * the current playback technology (HTML5/Flash) can support the source you 12008 * provide. Currently only MP4 files can be used in both HTML5 and Flash. 12009 * ```js 12010 * myPlayer.src("http://www.example.com/path/to/video.mp4"); 12011 * ```
12012 * **Source Object (or element):* * A javascript object containing information 12013 * about the source file. Use this method if you want the player to determine if 12014 * it can support the file using the type information. 12015 * ```js 12016 * myPlayer.src({ type: "video/mp4", src: "http://www.example.com/path/to/video.mp4" }); 12017 * ``` 12018 * **Array of Source Objects:* * To provide multiple versions of the source so 12019 * that it can be played using HTML5 across browsers you can use an array of 12020 * source objects. Video.js will detect which version is supported and load that 12021 * file. 12022 * ```js 12023 * myPlayer.src([ 12024 * { type: "video/mp4", src: "http://www.example.com/path/to/video.mp4" }, 12025 * { type: "video/webm", src: "http://www.example.com/path/to/video.webm" }, 12026 * { type: "video/ogg", src: "http://www.example.com/path/to/video.ogv" } 12027 * ]); 12028 * ``` 12029 * 12030 * @param {String|Object|Array=} source The source URL, object, or array of sources 12031 * @return {String} The current video source when getting 12032 * @return {String} The player when setting 12033 * @method src 12034 */ 12035 12036 Player.prototype.src = function src(source) { 12037 if (source === undefined) { 12038 return this.techGet_('src'); 12039 } 12040 12041 var currentTech = _techTechJs2['default'].getTech(this.techName_); 12042 // Support old behavior of techs being registered as components. 12043 // Remove once that deprecated behavior is removed. 12044 if (!currentTech) { 12045 currentTech = _componentJs2['default'].getComponent(this.techName_); 12046 } 12047 12048 // case: Array of source objects to choose from and pick the best to play 12049 if (Array.isArray(source)) { 12050 this.sourceList_(source); 12051 12052 // case: URL String (http://myvideo...) 12053 } else if (typeof source === 'string') { 12054 // create a source object from the string 12055 this.src({ src: source }); 12056 12057 // case: Source object { src: '', type: '' ... } 12058 } else if (source instanceof Object) { 12059 // check if the source has a type and the loaded tech cannot play the source 12060 // if there's no type we'll just try the current tech 12061 if (source.type && !currentTech.canPlaySource(source)) { 12062 // create a source list with the current source and send through 12063 // the tech loop to check for a compatible technology 12064 this.sourceList_([source]); 12065 } else { 12066 this.cache_.src = source.src; 12067 this.currentType_ = source.type || ''; 12068 12069 // wait until the tech is ready to set the source 12070 this.ready(function () { 12071 12072 // The setSource tech method was added with source handlers 12073 // so older techs won't support it 12074 // We need to check the direct prototype for the case where subclasses 12075 // of the tech do not support source handlers 12076 if (currentTech.prototype.hasOwnProperty('setSource')) { 12077 this.techCall_('setSource', source); 12078 } else { 12079 this.techCall_('src', source.src); 12080 } 12081 12082 if (this.options_.preload === 'auto') { 12083 this.load(); 12084 } 12085 12086 if (this.options_.autoplay) { 12087 this.play(); 12088 } 12089 12090 // Set the source synchronously if possible (#2326) 12091 }, true); 12092 } 12093 } 12094 12095 return this; 12096 }; 12097 12098 /** 12099 * Handle an array of source objects 12100 * 12101 * @param {Array} sources Array of source objects 12102 * @private 12103 * @method sourceList_ 12104 */ 12105 12106 Player.prototype.sourceList_ = function sourceList_(sources) { 12107 var sourceTech = this.selectSource(sources); 12108 12109 if (sourceTech) { 12110 if (sourceTech.tech === this.techName_) { 12111 // if this technology is already loaded, set the source 12112 this.src(sourceTech.source); 12113 } else { 12114 // load this technology with the chosen source 12115 this.loadTech_(sourceTech.tech, sourceTech.source); 12116 } 12117 } else { 12118 // We need to wrap this in a timeout to give folks a chance to add error event handlers 12119 this.setTimeout(function () { 12120 this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) }); 12121 }, 0); 12122 12123 // we could not find an appropriate tech, but let's still notify the delegate that this is it 12124 // this needs a better comment about why this is needed 12125 this.triggerReady(); 12126 } 12127 }; 12128 12129 /** 12130 * Begin loading the src data. 12131 * 12132 * @return {Player} Returns the player 12133 * @method load 12134 */ 12135 12136 Player.prototype.load = function load() { 12137 this.techCall_('load'); 12138 return this; 12139 }; 12140 12141 /** 12142 * Reset the player. Loads the first tech in the techOrder, 12143 * and calls `reset` on the tech`. 12144 * 12145 * @return {Player} Returns the player 12146 * @method reset 12147 */ 12148 12149 Player.prototype.reset = function reset() { 12150 this.loadTech_(_utilsToTitleCaseJs2['default'](this.options_.techOrder[0]), null); 12151 this.techCall_('reset'); 12152 return this; 12153 }; 12154 12155 /** 12156 * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4 12157 * Can be used in conjuction with `currentType` to assist in rebuilding the current source object. 12158 * 12159 * @return {String} The current source 12160 * @method currentSrc 12161 */ 12162 12163 Player.prototype.currentSrc = function currentSrc() { 12164 return this.techGet_('currentSrc') || this.cache_.src || ''; 12165 }; 12166 12167 /** 12168 * Get the current source type e.g. video/mp4 12169 * This can allow you rebuild the current source object so that you could load the same 12170 * source and tech later 12171 * 12172 * @return {String} The source MIME type 12173 * @method currentType 12174 */ 12175 12176 Player.prototype.currentType = function currentType() { 12177 return this.currentType_ || ''; 12178 }; 12179 12180 /** 12181 * Get or set the preload attribute 12182 * 12183 * @param {Boolean} value Boolean to determine if preload should be used 12184 * @return {String} The preload attribute value when getting 12185 * @return {Player} Returns the player when setting 12186 * @method preload 12187 */ 12188 12189 Player.prototype.preload = function preload(value) { 12190 if (value !== undefined) { 12191 this.techCall_('setPreload', value); 12192 this.options_.preload = value; 12193 return this; 12194 } 12195 return this.techGet_('preload'); 12196 }; 12197 12198 /** 12199 * Get or set the autoplay attribute. 12200 * 12201 * @param {Boolean} value Boolean to determine if video should autoplay 12202 * @return {String} The autoplay attribute value when getting 12203 * @return {Player} Returns the player when setting 12204 * @method autoplay 12205 */ 12206 12207 Player.prototype.autoplay = function autoplay(value) { 12208 if (value !== undefined) { 12209 this.techCall_('setAutoplay', value); 12210 this.options_.autoplay = value; 12211 return this; 12212 } 12213 return this.techGet_('autoplay', value); 12214 }; 12215 12216 /** 12217 * Get or set the loop attribute on the video element. 12218 * 12219 * @param {Boolean} value Boolean to determine if video should loop 12220 * @return {String} The loop attribute value when getting 12221 * @return {Player} Returns the player when setting 12222 * @method loop 12223 */ 12224 12225 Player.prototype.loop = function loop(value) { 12226 if (value !== undefined) { 12227 this.techCall_('setLoop', value); 12228 this.options_['loop'] = value; 12229 return this; 12230 } 12231 return this.techGet_('loop'); 12232 }; 12233 12234 /** 12235 * Get or set the poster image source url 12236 * 12237 * ##### EXAMPLE: 12238 * ```js 12239 * // get 12240 * var currentPoster = myPlayer.poster(); 12241 * // set 12242 * myPlayer.poster('http://example.com/myImage.jpg'); 12243 * ``` 12244 * 12245 * @param {String=} src Poster image source URL 12246 * @return {String} poster URL when getting 12247 * @return {Player} self when setting 12248 * @method poster 12249 */ 12250 12251 Player.prototype.poster = function poster(src) { 12252 if (src === undefined) { 12253 return this.poster_; 12254 } 12255 12256 // The correct way to remove a poster is to set as an empty string 12257 // other falsey values will throw errors 12258 if (!src) { 12259 src = ''; 12260 } 12261 12262 // update the internal poster variable 12263 this.poster_ = src; 12264 12265 // update the tech's poster 12266 this.techCall_('setPoster', src); 12267 12268 // alert components that the poster has been set 12269 this.trigger('posterchange'); 12270 12271 return this; 12272 }; 12273 12274 /** 12275 * Some techs (e.g. YouTube) can provide a poster source in an 12276 * asynchronous way. We want the poster component to use this 12277 * poster source so that it covers up the tech's controls. 12278 * (YouTube's play button). However we only want to use this 12279 * soruce if the player user hasn't set a poster through 12280 * the normal APIs. 12281 * 12282 * @private 12283 * @method handleTechPosterChange_ 12284 */ 12285 12286 Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() { 12287 if (!this.poster_ && this.tech_ && this.tech_.poster) { 12288 this.poster_ = this.tech_.poster() || ''; 12289 12290 // Let components know the poster has changed 12291 this.trigger('posterchange'); 12292 } 12293 }; 12294 12295 /** 12296 * Get or set whether or not the controls are showing. 12297 * 12298 * @param {Boolean} bool Set controls to showing or not 12299 * @return {Boolean} Controls are showing 12300 * @method controls 12301 */ 12302 12303 Player.prototype.controls = function controls(bool) { 12304 if (bool !== undefined) { 12305 bool = !!bool; // force boolean 12306 // Don't trigger a change event unless it actually changed 12307 if (this.controls_ !== bool) { 12308 this.controls_ = bool; 12309 12310 if (this.usingNativeControls()) { 12311 this.techCall_('setControls', bool); 12312 } 12313 12314 if (bool) { 12315 this.removeClass('vjs-controls-disabled'); 12316 this.addClass('vjs-controls-enabled'); 12317 this.trigger('controlsenabled'); 12318 12319 if (!this.usingNativeControls()) {
12320 this.addTechControlsListeners_(); 12321 } 12322 } else { 12323 this.removeClass('vjs-controls-enabled'); 12324 this.addClass('vjs-controls-disabled'); 12325 this.trigger('controlsdisabled'); 12326 12327 if (!this.usingNativeControls()) { 12328 this.removeTechControlsListeners_(); 12329 } 12330 } 12331 } 12332 return this; 12333 } 12334 return !!this.controls_; 12335 }; 12336 12337 /** 12338 * Toggle native controls on/off. Native controls are the controls built into 12339 * devices (e.g. default iPhone controls), Flash, or other techs 12340 * (e.g. Vimeo Controls) 12341 * **This should only be set by the current tech, because only the tech knows 12342 * if it can support native controls** 12343 * 12344 * @param {Boolean} bool True signals that native controls are on 12345 * @return {Player} Returns the player 12346 * @private 12347 * @method usingNativeControls 12348 */ 12349 12350 Player.prototype.usingNativeControls = function usingNativeControls(bool) { 12351 if (bool !== undefined) { 12352 bool = !!bool; // force boolean 12353 // Don't trigger a change event unless it actually changed 12354 if (this.usingNativeControls_ !== bool) { 12355 this.usingNativeControls_ = bool; 12356 if (bool) { 12357 this.addClass('vjs-using-native-controls'); 12358 12359 /** 12360 * player is using the native device controls 12361 * 12362 * @event usingnativecontrols 12363 * @memberof Player 12364 * @instance 12365 * @private 12366 */ 12367 this.trigger('usingnativecontrols'); 12368 } else { 12369 this.removeClass('vjs-using-native-controls'); 12370 12371 /** 12372 * player is using the custom HTML controls 12373 * 12374 * @event usingcustomcontrols 12375 * @memberof Player 12376 * @instance 12377 * @private 12378 */ 12379 this.trigger('usingcustomcontrols'); 12380 } 12381 } 12382 return this; 12383 } 12384 return !!this.usingNativeControls_; 12385 }; 12386 12387 /** 12388 * Set or get the current MediaError 12389 * 12390 * @param {*} err A MediaError or a String/Number to be turned into a MediaError 12391 * @return {MediaError|null} when getting 12392 * @return {Player} when setting 12393 * @method error 12394 */ 12395 12396 Player.prototype.error = function error(err) { 12397 if (err === undefined) { 12398 return this.error_ || null; 12399 } 12400 12401 // restoring to default 12402 if (err === null) { 12403 this.error_ = err; 12404 this.removeClass('vjs-error'); 12405 this.errorDisplay.close(); 12406 return this; 12407 } 12408 12409 // error instance 12410 if (err instanceof _mediaErrorJs2['default']) { 12411 this.error_ = err; 12412 } else { 12413 this.error_ = new _mediaErrorJs2['default'](err); 12414 } 12415 12416 // add the vjs-error classname to the player 12417 this.addClass('vjs-error'); 12418 12419 // log the name of the error type and any message 12420 // ie8 just logs "[object object]" if you just log the error object 12421 _utilsLogJs2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaErrorJs2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_); 12422 12423 // fire an error event on the player 12424 this.trigger('error'); 12425 12426 return this; 12427 }; 12428 12429 /** 12430 * Returns whether or not the player is in the "ended" state. 12431 * 12432 * @return {Boolean} True if the player is in the ended state, false if not. 12433 * @method ended 12434 */ 12435 12436 Player.prototype.ended = function ended() { 12437 return this.techGet_('ended'); 12438 }; 12439 12440 /** 12441 * Returns whether or not the player is in the "seeking" state. 12442 * 12443 * @return {Boolean} True if the player is in the seeking state, false if not. 12444 * @method seeking 12445 */ 12446 12447 Player.prototype.seeking = function seeking() { 12448 return this.techGet_('seeking'); 12449 }; 12450 12451 /** 12452 * Returns the TimeRanges of the media that are currently available 12453 * for seeking to. 12454 * 12455 * @return {TimeRanges} the seekable intervals of the media timeline 12456 * @method seekable 12457 */ 12458 12459 Player.prototype.seekable = function seekable() { 12460 return this.techGet_('seekable'); 12461 }; 12462 12463 /** 12464 * Report user activity 12465 * 12466 * @param {Object} event Event object 12467 * @method reportUserActivity 12468 */ 12469
12470 Player.prototype.reportUserActivity = function reportUserActivity(event) { 12471 this.userActivity_ = true; 12472 }; 12473 12474 /** 12475 * Get/set if user is active 12476 * 12477 * @param {Boolean} bool Value when setting 12478 * @return {Boolean} Value if user is active user when getting 12479 * @method userActive 12480 */ 12481 12482 Player.prototype.userActive = function userActive(bool) { 12483 if (bool !== undefined) { 12484 bool = !!bool; 12485 if (bool !== this.userActive_) { 12486 this.userActive_ = bool; 12487 if (bool) { 12488 // If the user was inactive and is now active we want to reset the 12489 // inactivity timer 12490 this.userActivity_ = true; 12491 this.removeClass('vjs-user-inactive'); 12492 this.addClass('vjs-user-active'); 12493 this.trigger('useractive'); 12494 } else { 12495 // We're switching the state to inactive manually, so erase any other 12496 // activity 12497 this.userActivity_ = false; 12498 12499 // Chrome/Safari/IE have bugs where when you change the cursor it can 12500 // trigger a mousemove event. This causes an issue when you're hiding 12501 // the cursor when the user is inactive, and a mousemove signals user 12502 // activity. Making it impossible to go into inactive mode. Specifically 12503 // this happens in fullscreen when we really need to hide the cursor. 12504 // 12505 // When this gets resolved in ALL browsers it can be removed 12506 // https://code.google.com/p/chromium/issues/detail?id=103041 12507 if (this.tech_) { 12508 this.tech_.one('mousemove', function (e) { 12509 e.stopPropagation(); 12510 e.preventDefault(); 12511 }); 12512 } 12513 12514 this.removeClass('vjs-user-active'); 12515 this.addClass('vjs-user-inactive'); 12516 this.trigger('userinactive'); 12517 } 12518 } 12519 return this; 12520 } 12521 return this.userActive_; 12522 }; 12523 12524 /** 12525 * Listen for user activity based on timeout value 12526 * 12527 * @private 12528 * @method listenForUserActivity_ 12529 */ 12530 12531 Player.prototype.listenForUserActivity_ = function listenForUserActivity_() { 12532 var mouseInProgress = undefined, 12533 lastMoveX = undefined, 12534 lastMoveY = undefined; 12535 12536 var handleActivity = Fn.bind(this, this.reportUserActivity); 12537 12538 var handleMouseMove = function handleMouseMove(e) { 12539 // #1068 - Prevent mousemove spamming 12540 // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970 12541 if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) { 12542 lastMoveX = e.screenX; 12543 lastMoveY = e.screenY; 12544 handleActivity(); 12545 } 12546 }; 12547 12548 var handleMouseDown = function handleMouseDown() { 12549 handleActivity(); 12550 // For as long as the they are touching the device or have their mouse down, 12551 // we consider them active even if they're not moving their finger or mouse. 12552 // So we want to continue to update that they are active 12553 this.clearInterval(mouseInProgress); 12554 // Setting userActivity=true now and setting the interval to the same time 12555 // as the activityCheck interval (250) should ensure we never miss the 12556 // next activityCheck 12557 mouseInProgress = this.setInterval(handleActivity, 250); 12558 }; 12559 12560 var handleMouseUp = function handleMouseUp(event) { 12561 handleActivity(); 12562 // Stop the interval that maintains activity if the mouse/touch is down 12563 this.clearInterval(mouseInProgress); 12564 }; 12565 12566 // Any mouse movement will be considered user activity 12567 this.on('mousedown', handleMouseDown); 12568 this.on('mousemove', handleMouseMove); 12569 this.on('mouseup', handleMouseUp); 12570 12571 // Listen for keyboard navigation 12572 // Shouldn't need to use inProgress interval because of key repeat 12573 this.on('keydown', handleActivity); 12574 this.on('keyup', handleActivity); 12575 12576 // Run an interval every 250 milliseconds instead of stuffing everything into 12577 // the mousemove/touchmove function itself, to prevent performance degradation. 12578 // `this.reportUserActivity` simply sets this.userActivity_ to true, which 12579 // then gets picked up by this loop 12580 // http://ejohn.org/blog/learning-from-twitter/ 12581 var inactivityTimeout = undefined; 12582 var activityCheck = this.setInterval(function () { 12583 // Check to see if mouse/touch activity has happened 12584 if (this.userActivity_) { 12585 // Reset the activity tracker 12586 this.userActivity_ = false;
12587 12588 // If the user state was inactive, set the state to active 12589 this.userActive(true); 12590 12591 // Clear any existing inactivity timeout to start the timer over 12592 this.clearTimeout(inactivityTimeout); 12593 12594 var timeout = this.options_['inactivityTimeout']; 12595 if (timeout > 0) { 12596 // In <timeout> milliseconds, if no more activity has occurred the 12597 // user will be considered inactive 12598 inactivityTimeout = this.setTimeout(function () { 12599 // Protect against the case where the inactivityTimeout can trigger just 12600 // before the next user activity is picked up by the activityCheck loop 12601 // causing a flicker 12602 if (!this.userActivity_) { 12603 this.userActive(false); 12604 } 12605 }, timeout); 12606 } 12607 } 12608 }, 250); 12609 }; 12610 12611 /** 12612 * Gets or sets the current playback rate. A playback rate of 12613 * 1.0 represents normal speed and 0.5 would indicate half-speed 12614 * playback, for instance. 12615 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate 12616 * 12617 * @param {Number} rate New playback rate to set. 12618 * @return {Number} Returns the new playback rate when setting 12619 * @return {Number} Returns the current playback rate when getting 12620 * @method playbackRate 12621 */ 12622 12623 Player.prototype.playbackRate = function playbackRate(rate) { 12624 if (rate !== undefined) { 12625 this.techCall_('setPlaybackRate', rate); 12626 return this; 12627 } 12628 12629 if (this.tech_ && this.tech_['featuresPlaybackRate']) { 12630 return this.techGet_('playbackRate'); 12631 } else { 12632 return 1.0; 12633 } 12634 }; 12635 12636 /** 12637 * Gets or sets the audio flag 12638 * 12639 * @param {Boolean} bool True signals that this is an audio player. 12640 * @return {Boolean} Returns true if player is audio, false if not when getting 12641 * @return {Player} Returns the player if setting 12642 * @private 12643 * @method isAudio 12644 */ 12645 12646 Player.prototype.isAudio = function isAudio(bool) { 12647 if (bool !== undefined) { 12648 this.isAudio_ = !!bool; 12649 return this; 12650 } 12651 12652 return !!this.isAudio_; 12653 }; 12654 12655 /** 12656 * Returns the current state of network activity for the element, from 12657 * the codes in the list below. 12658 * - NETWORK_EMPTY (numeric value 0) 12659 * The element has not yet been initialised. All attributes are in 12660 * their initial states. 12661 * - NETWORK_IDLE (numeric value 1) 12662 * The element's resource selection algorithm is active and has 12663 * selected a resource, but it is not actually using the network at 12664 * this time. 12665 * - NETWORK_LOADING (numeric value 2) 12666 * The user agent is actively trying to download data. 12667 * - NETWORK_NO_SOURCE (numeric value 3) 12668 * The element's resource selection algorithm is active, but it has 12669 * not yet found a resource to use. 12670 * 12671 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states 12672 * @return {Number} the current network activity state 12673 * @method networkState 12674 */ 12675 12676 Player.prototype.networkState = function networkState() { 12677 return this.techGet_('networkState'); 12678 }; 12679 12680 /** 12681 * Returns a value that expresses the current state of the element 12682 * with respect to rendering the current playback position, from the 12683 * codes in the list below. 12684 * - HAVE_NOTHING (numeric value 0) 12685 * No information regarding the media resource is available. 12686 * - HAVE_METADATA (numeric value 1) 12687 * Enough of the resource has been obtained that the duration of the 12688 * resource is available. 12689 * - HAVE_CURRENT_DATA (numeric value 2) 12690 * Data for the immediate current playback position is available. 12691 * - HAVE_FUTURE_DATA (numeric value 3) 12692 * Data for the immediate current playback position is available, as 12693 * well as enough data for the user agent to advance the current 12694 * playback position in the direction of playback. 12695 * - HAVE_ENOUGH_DATA (numeric value 4) 12696 * The user agent estimates that enough data is available for 12697 * playback to proceed uninterrupted. 12698 * 12699 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate 12700 * @return {Number} the current playback rendering state 12701 * @method readyState 12702 */ 12703 12704 Player.prototype.readyState = function readyState() { 12705 return this.techGet_('readyState'); 12706 }; 12707 12708 /** 12709 * Get a video track list 12710 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist 12711 * 12712 * @return {VideoTrackList} thes current video track list 12713 * @method videoTracks 12714 */ 12715 12716 Player.prototype.videoTracks = function videoTracks() { 12717 // if we have not yet loadTech_, we create videoTracks_ 12718 // these will be passed to the tech during loading 12719 if (!this.tech_) { 12720 this.videoTracks_ = this.videoTracks_ || new _tracksVideoTrackListJs2['default'](); 12721 return this.videoTracks_; 12722 } 12723 12724 return this.tech_.videoTracks(); 12725 }; 12726 12727 /** 12728 * Get an audio track list 12729 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist 12730 * 12731 * @return {AudioTrackList} thes current audio track list 12732 * @method audioTracks 12733 */ 12734 12735 Player.prototype.audioTracks = function audioTracks() { 12736 // if we have not yet loadTech_, we create videoTracks_ 12737 // these will be passed to the tech during loading 12738 if (!this.tech_) { 12739 this.audioTracks_ = this.audioTracks_ || new _tracksAudioTrackListJs2['default'](); 12740 return this.audioTracks_; 12741 } 12742 12743 return this.tech_.audioTracks(); 12744 }; 12745 12746 /* 12747 * Text tracks are tracks of timed text events. 12748 * Captions - text displayed over the video for the hearing impaired
12749 * Subtitles - text displayed over the video for those who don't understand language in the video 12750 * Chapters - text displayed in a menu allowing the user to jump to particular points (chapters) in the video 12751 * Descriptions (not supported yet) - audio descriptions that are read back to the user by a screen reading device 12752 */ 12753 12754 /** 12755 * Get an array of associated text tracks. captions, subtitles, chapters, descriptions 12756 * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks 12757 * 12758 * @return {Array} Array of track objects 12759 * @method textTracks 12760 */ 12761 12762 Player.prototype.textTracks = function textTracks() { 12763 // cannot use techGet_ directly because it checks to see whether the tech is ready. 12764 // Flash is unlikely to be ready in time but textTracks should still work. 12765 return this.tech_ && this.tech_['textTracks'](); 12766 }; 12767 12768 /** 12769 * Get an array of remote text tracks 12770 * 12771 * @return {Array} 12772 * @method remoteTextTracks 12773 */ 12774 12775 Player.prototype.remoteTextTracks = function remoteTextTracks() { 12776 return this.tech_ && this.tech_['remoteTextTracks'](); 12777 }; 12778 12779 /** 12780 * Get an array of remote html track elements 12781 * 12782 * @return {HTMLTrackElement[]} 12783 * @method remoteTextTrackEls 12784 */ 12785 12786 Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() { 12787 return this.tech_ && this.tech_['remoteTextTrackEls'](); 12788 }; 12789 12790 /** 12791 * Add a text track 12792 * In addition to the W3C settings we allow adding additional info through options. 12793 * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack 12794 * 12795 * @param {String} kind Captions, subtitles, chapters, descriptions, or metadata 12796 * @param {String=} label Optional label 12797 * @param {String=} language Optional language 12798 * @method addTextTrack 12799 */ 12800 12801 Player.prototype.addTextTrack = function addTextTrack(kind, label, language) { 12802 return this.tech_ && this.tech_['addTextTrack'](kind, label, language); 12803 }; 12804 12805 /** 12806 * Add a remote text track 12807 * 12808 * @param {Object} options Options for remote text track 12809 * @method addRemoteTextTrack 12810 */ 12811 12812 Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options) { 12813 return this.tech_ && this.tech_['addRemoteTextTrack'](options); 12814 }; 12815 12816 /** 12817 * Remove a remote text track 12818 * 12819 * @param {Object} track Remote text track to remove 12820 * @method removeRemoteTextTrack 12821 */ 12822 // destructure the input into an object with a track argument, defaulting to arguments[0] 12823 // default the whole argument to an empty object if nothing was passed in 12824 12825 Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack() { 12826 var _ref3 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 12827 12828 var _ref3$track = _ref3.track; 12829 var track = _ref3$track === undefined ? arguments[0] : _ref3$track; 12830 // jshint ignore:line 12831 this.tech_ && this.tech_['removeRemoteTextTrack'](track); 12832 }; 12833 12834 /** 12835 * Get video width 12836 * 12837 * @return {Number} Video width 12838 * @method videoWidth 12839 */ 12840 12841 Player.prototype.videoWidth = function videoWidth() { 12842 return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0; 12843 }; 12844 12845 /** 12846 * Get video height 12847 * 12848 * @return {Number} Video height 12849 * @method videoHeight 12850 */ 12851 12852 Player.prototype.videoHeight = function videoHeight() { 12853 return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0; 12854 }; 12855 12856 // Methods to add support for 12857 // initialTime: function(){ return this.techCall_('initialTime'); }, 12858 // startOffsetTime: function(){ return this.techCall_('startOffsetTime'); }, 12859 // played: function(){ return this.techCall_('played'); }, 12860 // defaultPlaybackRate: function(){ return this.techCall_('defaultPlaybackRate'); }, 12861 // defaultMuted: function(){ return this.techCall_('defaultMuted'); } 12862 12863 /** 12864 * The player's language code 12865 * NOTE: The language should be set in the player options if you want the 12866 * the controls to be built with a specific language. Changing the lanugage 12867 * later will not update controls text. 12868 * 12869 * @param {String} code The locale string 12870 * @return {String} The locale string when getting 12871 * @return {Player} self when setting 12872 * @method language 12873 */ 12874 12875 Player.prototype.language = function language(code) { 12876 if (code === undefined) { 12877 return this.language_; 12878 } 12879 12880 this.language_ = ('' + code).toLowerCase(); 12881 return this; 12882 }; 12883 12884 /**
12885 * Get the player's language dictionary 12886 * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time 12887 * Languages specified directly in the player options have precedence 12888 * 12889 * @return {Array} Array of languages 12890 * @method languages 12891 */ 12892 12893 Player.prototype.languages = function languages() { 12894 return _utilsMergeOptionsJs2['default'](Player.prototype.options_.languages, this.languages_); 12895 }; 12896 12897 /** 12898 * Converts track info to JSON 12899 * 12900 * @return {Object} JSON object of options 12901 * @method toJSON 12902 */ 12903 12904 Player.prototype.toJSON = function toJSON() { 12905 var options = _utilsMergeOptionsJs2['default'](this.options_); 12906 var tracks = options.tracks; 12907 12908 options.tracks = []; 12909 12910 for (var i = 0; i < tracks.length; i++) { 12911 var track = tracks[i]; 12912 12913 // deep merge tracks and null out player so no circular references 12914 track = _utilsMergeOptionsJs2['default'](track); 12915 track.player = undefined; 12916 options.tracks[i] = track; 12917 } 12918 12919 return options; 12920 }; 12921 12922 /** 12923 * Creates a simple modal dialog (an instance of the `ModalDialog` 12924 * component) that immediately overlays the player with arbitrary 12925 * content and removes itself when closed. 12926 * 12927 * @param {String|Function|Element|Array|Null} content 12928 * Same as `ModalDialog#content`'s param of the same name. 12929 * 12930 * The most straight-forward usage is to provide a string or DOM 12931 * element. 12932 * 12933 * @param {Object} [options] 12934 * Extra options which will be passed on to the `ModalDialog`. 12935 * 12936 * @return {ModalDialog} 12937 */ 12938 12939 Player.prototype.createModal = function createModal(content, options) { 12940 var player = this; 12941 12942 options = options || {}; 12943 options.content = content || ''; 12944 12945 var modal = new _modalDialog2['default'](player, options); 12946 12947 player.addChild(modal); 12948 modal.on('dispose', function () { 12949 player.removeChild(modal); 12950 }); 12951 12952 return modal.open(); 12953 }; 12954 12955 /** 12956 * Gets tag settings 12957 * 12958 * @param {Element} tag The player tag 12959 * @return {Array} An array of sources and track objects 12960 * @static 12961 * @method getTagSettings 12962 */ 12963 12964 Player.getTagSettings = function getTagSettings(tag) { 12965 var baseOptions = { 12966 'sources': [], 12967 'tracks': [] 12968 }; 12969 12970 var tagOptions = Dom.getElAttributes(tag); 12971 var dataSetup = tagOptions['data-setup']; 12972 12973 // Check if data-setup attr exists. 12974 if (dataSetup !== null) { 12975 // Parse options JSON 12976 12977 var _safeParseTuple = _safeJsonParseTuple2['default'](dataSetup || '{}'); 12978 12979 var err = _safeParseTuple[0]; 12980 var data = _safeParseTuple[1]; 12981 12982 if (err) { 12983 _utilsLogJs2['default'].error(err); 12984 } 12985 _objectAssign2['default'](tagOptions, data); 12986 } 12987 12988 _objectAssign2['default'](baseOptions, tagOptions); 12989 12990 // Get tag children settings 12991 if (tag.hasChildNodes()) { 12992 var children = tag.childNodes; 12993 12994 for (var i = 0, j = children.length; i < j; i++) { 12995 var child = children[i]; 12996 // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/ 12997 var childName = child.nodeName.toLowerCase(); 12998 if (childName === 'source') { 12999 baseOptions.sources.push(Dom.getElAttributes(child)); 13000 } else if (childName === 'track') { 13001 baseOptions.tracks.push(Dom.getElAttributes(child)); 13002 } 13003 } 13004 } 13005 13006 return baseOptions; 13007 }; 13008 13009 return Player; 13010})(_componentJs2['default']); 13011 13012Player.players = {}; 13013 13014var navigator = _globalWindow2['default'].navigator; 13015/* 13016 * Player instance options, surfaced using options 13017 * options = Player.prototype.options_ 13018 * Make changes in options, not here. 13019 * 13020 * @type {Object} 13021 * @private 13022 */ 13023Player.prototype.options_ = { 13024 // Default order of fallback technology 13025 techOrder: ['html5', 'flash'], 13026 // techOrder: ['flash','html5'], 13027 13028 html5: {}, 13029 flash: {}, 13030 13031 // defaultVolume: 0.85, 13032 defaultVolume: 0.00, // The freakin seaguls are driving me crazy! 13033 13034 // default inactivity timeout 13035 inactivityTimeout: 2000, 13036 13037 // default playback rates 13038 playbackRates: [], 13039 // Add playback rate selection by adding rates 13040 // 'playbackRates': [0.5, 1, 1.5, 2],
13041 13042 // Included control sets 13043 children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'], 13044 13045 language: _globalDocument2['default'].getElementsByTagName('html')[0].getAttribute('lang') || navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language || 'en', 13046 13047 // locales and their language translations 13048 languages: {}, 13049 13050 // Default message to show when a video cannot be played. 13051 notSupportedMessage: 'No compatible source was found for this media.' 13052}; 13053 13054/** 13055 * Fired when the player has initial duration and dimension information 13056 * 13057 * @event loadedmetadata 13058 */ 13059Player.prototype.handleLoadedMetaData_; 13060 13061/** 13062 * Fired when the player has downloaded data at the current playback position 13063 * 13064 * @event loadeddata 13065 */ 13066Player.prototype.handleLoadedData_; 13067 13068/** 13069 * Fired when the user is active, e.g. moves the mouse over the player 13070 * 13071 * @event useractive 13072 */ 13073Player.prototype.handleUserActive_; 13074 13075/** 13076 * Fired when the user is inactive, e.g. a short delay after the last mouse move or control interaction 13077 * 13078 * @event userinactive 13079 */ 13080Player.prototype.handleUserInactive_; 13081 13082/** 13083 * Fired when the current playback position has changed * 13084 * During playback this is fired every 15-250 milliseconds, depending on the 13085 * playback technology in use. 13086 * 13087 * @event timeupdate 13088 */ 13089Player.prototype.handleTimeUpdate_; 13090 13091/** 13092 * Fired when video playback ends 13093 * 13094 * @event ended 13095 */ 13096Player.prototype.handleTechEnded_; 13097 13098/** 13099 * Fired when the volume changes 13100 * 13101 * @event volumechange 13102 */ 13103Player.prototype.handleVolumeChange_; 13104 13105/** 13106 * Fired when an error occurs 13107 * 13108 * @event error 13109 */ 13110Player.prototype.handleError_; 13111 13112Player.prototype.flexNotSupported_ = function () { 13113 var elem = _globalDocument2['default'].createElement('i'); 13114 13115 // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more 13116 // common flex features that we can rely on when checking for flex support. 13117 return !('flexBasis' in elem.style || 'webkitFlexBasis' in elem.style || 'mozFlexBasis' in elem.style || 'msFlexBasis' in elem.style || 'msFlexOrder' in elem.style) /* IE10-specific (2012 flex spec) */; 13118}; 13119 13120_componentJs2['default'].registerComponent('Player', Player); 13121exports['default'] = Player; 13122module.exports = exports['default']; 13123// If empty string, make it a parsable json object. 13124 13125},{"./big-play-button.js":63,"./component.js":67,"./control-bar/control-bar.js":70,"./error-display.js":103,"./fullscreen-api.js":106,"./loading-spinner.js":107,"./media-error.js":108,"./modal-dialog":112,"./poster-image.js":117,"./tech/html5.js":122,"./tech/loader.js":123,"./tech/tech.js":124,"./tracks/audio-track-list.js":125,"./tracks/text-track-display.js":130,"./tracks/text-track-list-converter.js":131,"./tracks/text-track-settings.js":133,"./tracks/video-track-list.js":138,"./utils/browser.js":140,"./utils/buffer.js":141,"./utils/dom.js":143,"./utils/events.js":144,"./utils/fn.js":145,"./utils/guid.js":147,"./utils/log.js":148,"./utils/merge-options.js":149,"./utils/stylesheet.js":150,"./utils/time-ranges.js":151,"./utils/to-title-case.js":152,"global/document":1,"global/window":2,"object.assign":45,"safe-json-parse/tuple":54}],114:[function(_dereq_,module,exports){ 13126/** 13127 * @file plugins.js 13128 */ 13129'use strict'; 13130 13131exports.__esModule = true; 13132 13133function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 13134 13135var _playerJs = _dereq_('./player.js'); 13136 13137var _playerJs2 = _interopRequireDefault(_playerJs); 13138 13139/** 13140 * The method for registering a video.js plugin 13141 * 13142 * @param {String} name The name of the plugin 13143 * @param {Function} init The function that is run when the player inits 13144 * @method plugin 13145 */ 13146var plugin = function plugin(name, init) { 13147 _playerJs2['default'].prototype[name] = init; 13148}; 13149 13150exports['default'] = plugin; 13151module.exports = exports['default']; 13152 13153},{"./player.js":113}],115:[function(_dereq_,module,exports){ 13154/** 13155 * @file popup-button.js 13156 */ 13157'use strict'; 13158 13159exports.__esModule = true; 13160 13161function _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; } } 13162 13163function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 13164 13165function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 13166 13167function _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
13167onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 13168 13169var _clickableComponentJs = _dereq_('../clickable-component.js'); 13170 13171var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs); 13172 13173var _componentJs = _dereq_('../component.js'); 13174 13175var _componentJs2 = _interopRequireDefault(_componentJs); 13176 13177var _popupJs = _dereq_('./popup.js'); 13178 13179var _popupJs2 = _interopRequireDefault(_popupJs); 13180 13181var _utilsDomJs = _dereq_('../utils/dom.js'); 13182 13183var Dom = _interopRequireWildcard(_utilsDomJs); 13184 13185var _utilsFnJs = _dereq_('../utils/fn.js'); 13186 13187var Fn = _interopRequireWildcard(_utilsFnJs); 13188 13189var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js'); 13190 13191var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs); 13192 13193/** 13194 * A button class with a popup control 13195 * 13196 * @param {Player|Object} player 13197 * @param {Object=} options 13198 * @extends ClickableComponent 13199 * @class PopupButton 13200 */ 13201 13202var PopupButton = (function (_ClickableComponent) { 13203 _inherits(PopupButton, _ClickableComponent); 13204 13205 function PopupButton(player) { 13206 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 13207 13208 _classCallCheck(this, PopupButton); 13209 13210 _ClickableComponent.call(this, player, options); 13211 13212 this.update(); 13213 } 13214 13215 /** 13216 * Update popup 13217 * 13218 * @method update 13219 */ 13220 13221 PopupButton.prototype.update = function update() { 13222 var popup = this.createPopup(); 13223 13224 if (this.popup) { 13225 this.removeChild(this.popup); 13226 } 13227 13228 this.popup = popup; 13229 this.addChild(popup); 13230 13231 if (this.items && this.items.length === 0) { 13232 this.hide(); 13233 } else if (this.items && this.items.length > 1) { 13234 this.show(); 13235 } 13236 }; 13237 13238 /** 13239 * Create popup - Override with specific functionality for component 13240 * 13241 * @return {Popup} The constructed popup 13242 * @method createPopup 13243 */ 13244 13245 PopupButton.prototype.createPopup = function createPopup() {}; 13246 13247 /** 13248 * Create the component's DOM element 13249 * 13250 * @return {Element} 13251 * @method createEl 13252 */ 13253 13254 PopupButton.prototype.createEl = function createEl() { 13255 return _ClickableComponent.prototype.createEl.call(this, 'div', { 13256 className: this.buildCSSClass() 13257 }); 13258 }; 13259 13260 /** 13261 * Allow sub components to stack CSS class names 13262 * 13263 * @return {String} The constructed class name 13264 * @method buildCSSClass 13265 */ 13266 13267 PopupButton.prototype.buildCSSClass = function buildCSSClass() { 13268 var menuButtonClass = 'vjs-menu-button'; 13269 13270 // If the inline option is passed, we want to use different styles altogether. 13271 if (this.options_.inline === true) { 13272 menuButtonClass += '-inline'; 13273 } else { 13274 menuButtonClass += '-popup'; 13275 } 13276 13277 return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this); 13278 }; 13279 13280 return PopupButton; 13281})(_clickableComponentJs2['default']); 13282 13283_componentJs2['default'].registerComponent('PopupButton', PopupButton); 13284exports['default'] = PopupButton; 13285module.exports = exports['default']; 13286 13287},{"../clickable-component.js":65,"../component.js":67,"../utils/dom.js":143,"../utils/fn.js":145,"../utils/to-title-case.js":152,"./popup.js":116}],116:[function(_dereq_,module,exports){ 13288/** 13289 * @file popup.js 13290 */ 13291'use strict'; 13292 13293exports.__esModule = true; 13294 13295function _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; } } 13296 13297function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 13298 13299function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 13300 13301function _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
13301onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 13302 13303var _componentJs = _dereq_('../component.js'); 13304 13305var _componentJs2 = _interopRequireDefault(_componentJs); 13306 13307var _utilsDomJs = _dereq_('../utils/dom.js'); 13308 13309var Dom = _interopRequireWildcard(_utilsDomJs); 13310 13311var _utilsFnJs = _dereq_('../utils/fn.js'); 13312 13313var Fn = _interopRequireWildcard(_utilsFnJs); 13314 13315var _utilsEventsJs = _dereq_('../utils/events.js'); 13316 13317var Events = _interopRequireWildcard(_utilsEventsJs); 13318 13319/** 13320 * The Popup component is used to build pop up controls. 13321 * 13322 * @extends Component 13323 * @class Popup 13324 */ 13325 13326var Popup = (function (_Component) { 13327 _inherits(Popup, _Component); 13328 13329 function Popup() { 13330 _classCallCheck(this, Popup); 13331 13332 _Component.apply(this, arguments); 13333 } 13334 13335 /** 13336 * Add a popup item to the popup 13337 * 13338 * @param {Object|String} component Component or component type to add 13339 * @method addItem 13340 */ 13341 13342 Popup.prototype.addItem = function addItem(component) { 13343 this.addChild(component); 13344 component.on('click', Fn.bind(this, function () { 13345 this.unlockShowing(); 13346 })); 13347 }; 13348 13349 /** 13350 * Create the component's DOM element 13351 * 13352 * @return {Element} 13353 * @method createEl 13354 */ 13355 13356 Popup.prototype.createEl = function createEl() { 13357 var contentElType = this.options_.contentElType || 'ul'; 13358 this.contentEl_ = Dom.createEl(contentElType, { 13359 className: 'vjs-menu-content' 13360 }); 13361 var el = _Component.prototype.createEl.call(this, 'div', { 13362 append: this.contentEl_, 13363 className: 'vjs-menu' 13364 }); 13365 el.appendChild(this.contentEl_); 13366 13367 // Prevent clicks from bubbling up. Needed for Popup Buttons, 13368 // where a click on the parent is significant 13369 Events.on(el, 'click', function (event) { 13370 event.preventDefault(); 13371 event.stopImmediatePropagation(); 13372 }); 13373 13374 return el; 13375 }; 13376 13377 return Popup; 13378})(_componentJs2['default']); 13379 13380_componentJs2['default'].registerComponent('Popup', Popup); 13381exports['default'] = Popup; 13382module.exports = exports['default']; 13383 13384},{"../component.js":67,"../utils/dom.js":143,"../utils/events.js":144,"../utils/fn.js":145}],117:[function(_dereq_,module,exports){ 13385/** 13386 * @file poster-image.js 13387 */ 13388'use strict'; 13389 13390exports.__esModule = true; 13391 13392function _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; } } 13393 13394function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 13395 13396function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 13397 13398function _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; } 13399 13400var _clickableComponentJs = _dereq_('./clickable-component.js'); 13401 13402var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs); 13403 13404var _componentJs = _dereq_('./component.js'); 13405 13406var _componentJs2 = _interopRequireDefault(_componentJs); 13407 13408var _utilsFnJs = _dereq_('./utils/fn.js'); 13409 13410var Fn = _interopRequireWildcard(_utilsFnJs); 13411 13412var _utilsDomJs = _dereq_('./utils/dom.js'); 13413 13414var Dom = _interopRequireWildcard(_utilsDomJs); 13415 13416var _utilsBrowserJs = _dereq_('./utils/browser.js'); 13417 13418var browser = _interopRequireWildcard(_utilsBrowserJs); 13419 13420/** 13421 * The component that handles showing the poster image. 13422 * 13423 * @param {Player|Object} player 13424 * @param {Object=} options 13425 * @extends Button 13426 * @class PosterImage 13427 */ 13428 13429var PosterImage = (function (_ClickableComponent) { 13430 _inherits(PosterImage, _ClickableComponent); 13431 13432 function PosterImage(player, options) { 13433 _classCallCheck(this, PosterImage); 13434 13435 _ClickableComponent.call(this, player, options); 13436 13437 this.update(); 13438 player.on('posterchange', Fn.bind(this, this.update)); 13439 } 13440 13441 /** 13442 * Clean up the poster image 13443 * 13444 * @method dispose 13445 */ 13446 13447 PosterImage.prototype.dispose = function dispose() { 13448 this.player().off('posterchange', this.update); 13449 _ClickableComponent.prototype.dispose.call(this); 13450 }; 13451 13452 /** 13453 * Create the poster's image element 13454 * 13455 * @return {Element} 13456 * @method createEl 13457 */ 13458 13459 PosterImage.prototype.createEl = function createEl() { 13460 var el = Dom.createEl('div', { 13461 className: 'vjs-poster', 13462 13463 // Don't want poster to be tabbable. 13464 tabIndex: -1 13465 }); 13466 13467 // To ensure the poster image resizes while maintaining its original aspect 13468 // ratio, use a div with `background-size` when available. For browsers that 13469 // do not support `background-size` (e.g. IE8), fall back on using a regular
13470 // img element. 13471 if (!browser.BACKGROUND_SIZE_SUPPORTED) { 13472 this.fallbackImg_ = Dom.createEl('img'); 13473 el.appendChild(this.fallbackImg_); 13474 } 13475 13476 return el; 13477 }; 13478 13479 /** 13480 * Event handler for updates to the player's poster source 13481 * 13482 * @method update 13483 */ 13484 13485 PosterImage.prototype.update = function update() { 13486 var url = this.player().poster(); 13487 13488 this.setSrc(url); 13489 13490 // If there's no poster source we should display:none on this component 13491 // so it's not still clickable or right-clickable 13492 if (url) { 13493 this.show(); 13494 } else { 13495 this.hide(); 13496 } 13497 }; 13498 13499 /** 13500 * Set the poster source depending on the display method 13501 * 13502 * @param {String} url The URL to the poster source 13503 * @method setSrc 13504 */ 13505 13506 PosterImage.prototype.setSrc = function setSrc(url) { 13507 if (this.fallbackImg_) { 13508 this.fallbackImg_.src = url; 13509 } else { 13510 var backgroundImage = ''; 13511 // Any falsey values should stay as an empty string, otherwise 13512 // this will throw an extra error 13513 if (url) { 13514 backgroundImage = 'url("' + url + '")'; 13515 } 13516 13517 this.el_.style.backgroundImage = backgroundImage; 13518 } 13519 }; 13520 13521 /** 13522 * Event handler for clicks on the poster image 13523 * 13524 * @method handleClick 13525 */ 13526 13527 PosterImage.prototype.handleClick = function handleClick() { 13528 // We don't want a click to trigger playback when controls are disabled 13529 // but CSS should be hiding the poster to prevent that from happening 13530 if (this.player_.paused()) { 13531 this.player_.play(); 13532 } else { 13533 this.player_.pause(); 13534 } 13535 }; 13536 13537 return PosterImage; 13538})(_clickableComponentJs2['default']); 13539 13540_componentJs2['default'].registerComponent('PosterImage', PosterImage); 13541exports['default'] = PosterImage; 13542module.exports = exports['default']; 13543 13544},{"./clickable-component.js":65,"./component.js":67,"./utils/browser.js":140,"./utils/dom.js":143,"./utils/fn.js":145}],118:[function(_dereq_,module,exports){ 13545/** 13546 * @file setup.js 13547 * 13548 * Functions for automatically setting up a player 13549 * based on the data-setup attribute of the video tag 13550 */ 13551'use strict'; 13552 13553exports.__esModule = true; 13554 13555function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 13556 13557function _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; } } 13558 13559var _utilsEventsJs = _dereq_('./utils/events.js'); 13560 13561var Events = _interopRequireWildcard(_utilsEventsJs); 13562 13563var _globalDocument = _dereq_('global/document'); 13564 13565var _globalDocument2 = _interopRequireDefault(_globalDocument); 13566 13567var _globalWindow = _dereq_('global/window'); 13568 13569var _globalWindow2 = _interopRequireDefault(_globalWindow); 13570 13571var _windowLoaded = false; 13572var videojs = undefined; 13573 13574// Automatically set up any tags that have a data-setup attribute 13575var autoSetup = function autoSetup() { 13576 // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack* 13577 // var vids = Array.prototype.slice.call(document.getElementsByTagName('video')); 13578 // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio')); 13579 // var mediaEls = vids.concat(audios); 13580 13581 // Because IE8 doesn't support calling slice on a node list, we need to loop through each list of elements 13582 // to build up a new, combined list of elements. 13583 var vids = _globalDocument2['default'].getElementsByTagName('video'); 13584 var audios = _globalDocument2['default'].getElementsByTagName('audio'); 13585 var mediaEls = []; 13586 if (vids && vids.length > 0) { 13587 for (var i = 0, e = vids.length; i < e; i++) { 13588 mediaEls.push(vids[i]); 13589 } 13590 } 13591 if (audios && audios.length > 0) { 13592 for (var i = 0, e = audios.length; i < e; i++) { 13593 mediaEls.push(audios[i]); 13594 } 13595 } 13596 13597 // Check if any media elements exist 13598 if (mediaEls && mediaEls.length > 0) { 13599 13600 for (var i = 0, e = mediaEls.length; i < e; i++) { 13601 var mediaEl = mediaEls[i]; 13602 13603 // Check if element exists, has getAttribute func. 13604 // IE seems to consider typeof el.getAttribute == 'object' instead of 'function' like expected, at least when loading the player immediately. 13605 if (mediaEl && mediaEl.getAttribute) { 13606 13607 // Make sure this player hasn't already been set up. 13608 if (mediaEl['player'] === undefined) { 13609 var options = mediaEl.getAttribute('data-setup'); 13610 13611 // Check if data-setup attr exists. 13612 // We only auto-setup if they've added the data-setup attr. 13613 if (options !== null) { 13614 // Create new video.js instance. 13615 var player = videojs(mediaEl); 13616 } 13617 } 13618 13619 // If getAttribute isn't defined, we need to wait for the DOM. 13620 } else { 13621 autoSetupTimeout(1); 13622 break; 13623 } 13624 } 13625 13626 // No videos were found, so keep looping unless page is finished loading. 13627 } else if (!_windowLoaded) { 13628 autoSetupTimeout(1); 13629 } 13630}; 13631 13632// Pause to let the DOM keep processing 13633var autoSetupTimeout = function autoSetupTimeout(wait, vjs) { 13634 if (vjs) { 13635 videojs = vjs; 13636 } 13637 13638 setTimeout(autoSetup, wait); 13639}; 13640 13641if (_globalDocument2['default'].readyState === 'complete') { 13642 _windowLoaded = true; 13643} else { 13644 Events.one(_globalWindow2['default'], 'load', function () { 13645 _windowLoaded = true; 13646 }); 13647} 13648 13649var hasLoaded = function hasLoaded() { 13650 return _windowLoaded; 13651}; 13652 13653exports.autoSetup = autoSetup; 13654exports.autoSetupTimeout = autoSetupTimeout; 13655exports.hasLoaded = hasLoaded; 13656 13657},{"./utils/events.js":144,"global/document":1,"global/window":2}],119:[function(_dereq_,module,exports){ 13658/** 13659 * @file slider.js 13660 */ 13661'use strict'; 13662 13663exports.__esModule = true; 13664 13665function _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; } } 13666 13667function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 13668 13669function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 13670 13671function _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
13671onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 13672 13673var _componentJs = _dereq_('../component.js'); 13674 13675var _componentJs2 = _interopRequireDefault(_componentJs); 13676 13677var _utilsDomJs = _dereq_('../utils/dom.js'); 13678 13679var Dom = _interopRequireWildcard(_utilsDomJs); 13680 13681var _objectAssign = _dereq_('object.assign'); 13682 13683var _objectAssign2 = _interopRequireDefault(_objectAssign); 13684 13685/** 13686 * The base functionality for sliders like the volume bar and seek bar 13687 * 13688 * @param {Player|Object} player 13689 * @param {Object=} options 13690 * @extends Component 13691 * @class Slider 13692 */ 13693 13694var Slider = (function (_Component) { 13695 _inherits(Slider, _Component); 13696 13697 function Slider(player, options) { 13698 _classCallCheck(this, Slider); 13699 13700 _Component.call(this, player, options); 13701 13702 // Set property names to bar to match with the child Slider class is looking for 13703 this.bar = this.getChild(this.options_.barName); 13704 13705 // Set a horizontal or vertical class on the slider depending on the slider type 13706 this.vertical(!!this.options_.vertical); 13707 13708 this.on('mousedown', this.handleMouseDown); 13709 this.on('touchstart', this.handleMouseDown); 13710 this.on('focus', this.handleFocus); 13711 this.on('blur', this.handleBlur); 13712 this.on('click', this.handleClick); 13713 13714 this.on(player, 'controlsvisible', this.update); 13715 this.on(player, this.playerEvent, this.update); 13716 } 13717 13718 /** 13719 * Create the component's DOM element 13720 * 13721 * @param {String} type Type of element to create 13722 * @param {Object=} props List of properties in Object form 13723 * @return {Element} 13724 * @method createEl 13725 */ 13726 13727 Slider.prototype.createEl = function createEl(type) { 13728 var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 13729 var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; 13730 13731 // Add the slider element class to all sub classes 13732 props.className = props.className + ' vjs-slider'; 13733 props = _objectAssign2['default']({ 13734 tabIndex: 0 13735 }, props); 13736 13737 attributes = _objectAssign2['default']({ 13738 'role': 'slider', 13739 'aria-valuenow': 0, 13740 'aria-valuemin': 0, 13741 'aria-valuemax': 100, 13742 tabIndex: 0 13743 }, attributes); 13744 13745 return _Component.prototype.createEl.call(this, type, props, attributes); 13746 }; 13747 13748 /** 13749 * Handle mouse down on slider 13750 * 13751 * @param {Object} event Mouse down event object 13752 * @method handleMouseDown 13753 */ 13754 13755 Slider.prototype.handleMouseDown = function handleMouseDown(event) { 13756 var doc = this.bar.el_.ownerDocument; 13757 13758 event.preventDefault(); 13759 Dom.blockTextSelection(); 13760 13761 this.addClass('vjs-sliding'); 13762 this.trigger('slideractive'); 13763 13764 this.on(doc, 'mousemove', this.handleMouseMove); 13765 this.on(doc, 'mouseup', this.handleMouseUp); 13766 this.on(doc, 'touchmove', this.handleMouseMove); 13767 this.on(doc, 'touchend', this.handleMouseUp); 13768 13769 this.handleMouseMove(event); 13770 }; 13771 13772 /** 13773 * To be overridden by a subclass 13774 * 13775 * @method handleMouseMove 13776 */ 13777 13778 Slider.prototype.handleMouseMove = function handleMouseMove() {}; 13779 13780 /** 13781 * Handle mouse up on Slider 13782 * 13783 * @method handleMouseUp 13784 */ 13785 13786 Slider.prototype.handleMouseUp = function handleMouseUp() { 13787 var doc = this.bar.el_.ownerDocument; 13788 13789 Dom.unblockTextSelection(); 13790 13791 this.removeClass('vjs-sliding'); 13792 this.trigger('sliderinactive'); 13793 13794 this.off(doc, 'mousemove', this.handleMouseMove); 13795 this.off(doc, 'mouseup', this.handleMouseUp); 13796 this.off(doc, 'touchmove', this.handleMouseMove); 13797 this.off(doc, 'touchend', this.handleMouseUp); 13798 13799 this.update(); 13800 }; 13801 13802 /** 13803 * Update slider 13804 * 13805 * @method update 13806 */ 13807 13808 Slider.prototype.update = function update() { 13809 // In VolumeBar init we have a setTimeout for update that pops and update to the end of the 13810 // execution stack. The player is destroyed before then update will cause an error 13811 if (!this.el_) return; 13812 13813 // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse. 13814 // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later. 13815 // var progress = (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration(); 13816 var progress = this.getPercent(); 13817 var bar = this.bar; 13818 13819 // If there's no bar... 13820 if (!bar) return; 13821 13822 // Protect against no duration and other division issues 13823 if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) { 13824 progress = 0; 13825 } 13826 13827 // Convert to a percentage for setting 13828 var percentage = (progress * 100).toFixed(2) + '%'; 13829 13830 // Set the new bar width or height 13831 if (this.vertical()) { 13832 bar.el().style.height = percentage; 13833 } else { 13834 bar.el().style.width = percentage; 13835 } 13836 }; 13837 13838 /** 13839 * Calculate distance for slider 13840 * 13841 * @param {Object} event Event object 13842 * @method calculateDistance 13843 */ 13844 13845 Slider.prototype.calculateDistance = function calculateDistance(event) { 13846 var position = Dom.getPointerPosition(this.el_, event); 13847 if (this.vertical()) { 13848 return position.y; 13849 } 13850 return position.x; 13851 }; 13852 13853 /** 13854 * Handle on focus for slider 13855 * 13856 * @method handleFocus 13857 */ 13858 13859 Slider.prototype.handleFocus = function handleFocus() { 13860 this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress); 13861 }; 13862 13863 /** 13864 * Handle key press for slider 13865 * 13866 * @param {Object} event Event object 13867 * @method handleKeyPress 13868 */ 13869 13870 Slider.prototype.handleKeyPress = function handleKeyPress(event) { 13871 if (event.which === 37 || event.which === 40) { 13872 // Left and Down Arrows 13873 event.preventDefault(); 13874 this.stepBack(); 13875 } else if (event.which === 38 || event.which === 39) { 13876 // Up and Right Arrows 13877 event.preventDefault(); 13878 this.stepForward(); 13879 } 13880 }; 13881 13882 /** 13883 * Handle on blur for slider 13884 * 13885 * @method handleBlur 13886 */ 13887 13888 Slider.prototype.handleBlur = function handleBlur() { 13889 this.off(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress); 13890 }; 13891 13892 /** 13893 * Listener for click events on slider, used to prevent clicks 13894 * from bubbling up to parent elements like button menus. 13895 * 13896 * @param {Object} event Event object 13897 * @method handleClick 13898 */ 13899 13900 Slider.prototype.handleClick = function handleClick(event) { 13901 event.stopImmediatePropagation(); 13902 event.preventDefault(); 13903 }; 13904 13905 /** 13906 * Get/set if slider is horizontal for vertical 13907 * 13908 * @param {Boolean} bool True if slider is vertical, false is horizontal 13909 * @return {Boolean} True if slider is vertical, false is horizontal 13910 * @method vertical 13911 */ 13912 13913 Slider.prototype.vertical = function vertical(bool) { 13914 if (bool === undefined) { 13915 return this.vertical_ || false; 13916 } 13917 13918 this.vertical_ = !!bool; 13919 13920 if (this.vertical_) { 13921 this.addClass('vjs-slider-vertical'); 13922 } else { 13923 this.addClass('vjs-slider-horizontal'); 13924 } 13925 13926 return this; 13927 }; 13928 13929 return Slider; 13930})(_componentJs2['default']); 13931 13932_componentJs2['default'].registerComponent('Slider', Slider); 13933exports['default'] = Slider; 13934module.exports = exports['default']; 13935 13936},{"../component.js":67,"../utils/dom.js":143,"object.assign":45}],120:[function(_dereq_,module,exports){ 13937/** 13938 * @file flash-rtmp.js 13939 */ 13940'use strict'; 13941 13942exports.__esModule = true; 13943function FlashRtmpDecorator(Flash) { 13944 Flash.streamingFormats = { 13945 'rtmp/mp4': 'MP4', 13946 'rtmp/flv': 'FLV' 13947 }; 13948
13949 Flash.streamFromParts = function (connection, stream) { 13950 return connection + '&' + stream; 13951 }; 13952 13953 Flash.streamToParts = function (src) { 13954 var parts = { 13955 connection: '', 13956 stream: '' 13957 }; 13958 13959 if (!src) return parts; 13960 13961 // Look for the normal URL separator we expect, '&'. 13962 // If found, we split the URL into two pieces around the 13963 // first '&'. 13964 var connEnd = src.search(/&(?!\w+=)/); 13965 var streamBegin = undefined; 13966 if (connEnd !== -1) { 13967 streamBegin = connEnd + 1; 13968 } else { 13969 // If there's not a '&', we use the last '/' as the delimiter. 13970 connEnd = streamBegin = src.lastIndexOf('/') + 1; 13971 if (connEnd === 0) { 13972 // really, there's not a '/'? 13973 connEnd = streamBegin = src.length; 13974 } 13975 } 13976 parts.connection = src.substring(0, connEnd); 13977 parts.stream = src.substring(streamBegin, src.length); 13978 13979 return parts; 13980 }; 13981 13982 Flash.isStreamingType = function (srcType) { 13983 return srcType in Flash.streamingFormats; 13984 }; 13985 13986 // RTMP has four variations, any string starting 13987 // with one of these protocols should be valid 13988 Flash.RTMP_RE = /^rtmp[set]?:\/\//i; 13989 13990 Flash.isStreamingSrc = function (src) { 13991 return Flash.RTMP_RE.test(src); 13992 }; 13993 13994 /** 13995 * A source handler for RTMP urls 13996 * @type {Object} 13997 */ 13998 Flash.rtmpSourceHandler = {}; 13999 14000 /** 14001 * Check if Flash can play the given videotype 14002 * @param {String} type The mimetype to check 14003 * @return {String} 'probably', 'maybe', or '' (empty string) 14004 */ 14005 Flash.rtmpSourceHandler.canPlayType = function (type) { 14006 if (Flash.isStreamingType(type)) { 14007 return 'maybe'; 14008 } 14009 14010 return ''; 14011 }; 14012 14013 /** 14014 * Check if Flash can handle the source natively 14015 * @param {Object} source The source object 14016 * @return {String} 'probably', 'maybe', or '' (empty string) 14017 */ 14018 Flash.rtmpSourceHandler.canHandleSource = function (source) { 14019 var can = Flash.rtmpSourceHandler.canPlayType(source.type); 14020 14021 if (can) { 14022 return can; 14023 } 14024 14025 if (Flash.isStreamingSrc(source.src)) { 14026 return 'maybe'; 14027 } 14028 14029 return ''; 14030 }; 14031 14032 /** 14033 * Pass the source to the flash object 14034 * Adaptive source handlers will have more complicated workflows before passing 14035 * video data to the video element 14036 * @param {Object} source The source object 14037 * @param {Flash} tech The instance of the Flash tech 14038 * @param {Object} options The options to pass to the source 14039 */ 14040 Flash.rtmpSourceHandler.handleSource = function (source, tech, options) { 14041 var srcParts = Flash.streamToParts(source.src); 14042 14043 tech['setRtmpConnection'](srcParts.connection); 14044 tech['setRtmpStream'](srcParts.stream); 14045 }; 14046 14047 // Register the native source handler 14048 Flash.registerSourceHandler(Flash.rtmpSourceHandler); 14049 14050 return Flash; 14051} 14052 14053exports['default'] = FlashRtmpDecorator; 14054module.exports = exports['default']; 14055 14056},{}],121:[function(_dereq_,module,exports){ 14057/** 14058 * @file flash.js 14059 * VideoJS-SWF - Custom Flash Player with HTML5-ish API 14060 * https://github.com/zencoder/video-js-swf 14061 * Not using setupTriggers. Using global onEvent func to distribute events 14062 */ 14063 14064'use strict'; 14065 14066exports.__esModule = true; 14067 14068function _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; } } 14069 14070function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 14071 14072function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 14073 14074function _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; } 14075 14076var _tech = _dereq_('./tech'); 14077 14078var _tech2 = _interopRequireDefault(_tech); 14079 14080var _utilsDomJs = _dereq_('../utils/dom.js'); 14081 14082var Dom = _interopRequireWildcard(_utilsDomJs); 14083 14084var _utilsUrlJs = _dereq_('../utils/url.js'); 14085 14086var Url = _interopRequireWildcard(_utilsUrlJs); 14087 14088var _utilsTimeRangesJs = _dereq_('../utils/time-ranges.js'); 14089 14090var _flashRtmp = _dereq_('./flash-rtmp'); 14091 14092var _flashRtmp2 = _interopRequireDefault(_flashRtmp); 14093 14094var _component = _dereq_('../component'); 14095 14096var _component2 = _interopRequireDefault(_component); 14097 14098var _globalWindow = _dereq_('global/window'); 14099 14100var _globalWindow2 = _interopRequireDefault(_globalWindow); 14101 14102var _objectAssign = _dereq_('object.assign'); 14103 14104var _objectAssign2 = _interopRequireDefault(_objectAssign); 14105 14106var navigator = _globalWindow2['default'].navigator; 14107/** 14108 * Flash Media Controller - Wrapper for fallback SWF API 14109 * 14110 * @param {Object=} options Object of option names and values 14111 * @param {Function=} ready Ready callback function 14112 * @extends Tech 14113 * @class Flash 14114 */ 14115 14116var Flash = (function (_Tech) { 14117 _inherits(Flash, _Tech); 14118 14119 function Flash(options, ready) { 14120 _classCallCheck(this, Flash); 14121 14122 _Tech.call(this, options, ready); 14123 14124 // Set the source when ready 14125 if (options.source) { 14126 this.ready(function () { 14127 this.setSource(options.source); 14128 }, true); 14129 } 14130 14131 // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers 14132 // This allows resetting the playhead when we catch the reload 14133 if (options.startTime) { 14134 this.ready(function () { 14135 this.load(); 14136 this.play(); 14137 this.currentTime(options.startTime); 14138 }, true); 14139 } 14140 14141 // Add global window functions that the swf expects 14142 // A 4.x workflow we weren't able to solve for in 5.0 14143 // because of the need to hard code these functions 14144 // into the swf for security reasons 14145 _globalWindow2['default'].videojs = _globalWindow2['default'].videojs || {}; 14146 _globalWindow2['default'].videojs.Flash = _globalWindow2['default'].videojs.Flash || {}; 14147 _globalWindow2['default'].videojs.Flash.onReady = Flash.onReady; 14148 _globalWindow2['default'].videojs.Flash.onEvent = Flash.onEvent; 14149 _globalWindow2['default'].videojs.Flash.onError = Flash.onError; 14150 14151 this.on('seeked', function () { 14152 this.lastSeekTarget_ = undefined; 14153 }); 14154 } 14155 14156 // Create setters and getters for attributes 14157 14158 /** 14159 * Create the component's DOM element 14160 * 14161 * @return {Element} 14162 * @method createEl 14163 */ 14164 14165 Flash.prototype.createEl = function createEl() { 14166 var options = this.options_; 14167 14168 // If video.js is hosted locally you should also set the location 14169 // for the hosted swf, which should be relative to the page (not video.js) 14170 // Otherwise this adds a CDN url. 14171 // The CDN also auto-adds a swf URL for that specific version. 14172 if (!options.swf) { 14173 options.swf = '//vjs.zencdn.net/swf/5.0.1/video-js.swf'; 14174 } 14175 14176 // Generate ID for swf object 14177 var objId = options.techId; 14178 14179 // Merge default flashvars with ones passed in to init 14180 var flashVars = _objectAssign2['default']({ 14181 14182 // SWF Callback Functions 14183 'readyFunction': 'videojs.Flash.onReady', 14184 'eventProxyFunction': 'videojs.Flash.onEvent', 14185 'errorEventProxyFunction': 'videojs.Flash.onError', 14186 14187 // Player Settings 14188 'autoplay': options.autoplay, 14189 'preload': options.preload, 14190 'loop': options.loop, 14191 'muted': options.muted 14192 14193 }, options.flashVars); 14194 14195 // Merge default parames with ones passed in 14196 var params = _objectAssign2['default']({ 14197 'wmode': 'opaque', // Opaque is needed to overlay controls, but can affect playback performance 14198 'bgcolor': '#000000' // Using bgcolor prevents a white flash when the object is loading 14199 }, options.params); 14200 14201 // Merge default attributes with ones passed in 14202 var attributes = _objectAssign2['default']({ 14203 'id': objId, 14204 'name': objId, // Both ID and Name needed or swf to identify itself 14205 'class': 'vjs-tech' 14206 }, options.attributes); 14207 14208 this.el_ = Flash.embed(options.swf, flashVars, params, attributes); 14209 this.el_.tech = this; 14210 14211 return this.el_; 14212 }; 14213 14214 /** 14215 * Play for flash tech 14216 * 14217 * @method play 14218 */ 14219 14220 Flash.prototype.play = function play() { 14221 if (this.ended()) { 14222 this.setCurrentTime(0); 14223 } 14224 this.el_.vjs_play(); 14225 }; 14226 14227 /** 14228 * Pause for flash tech 14229 * 14230 * @method pause 14231 */ 14232 14233 Flash.prototype.pause = function pause() { 14234 this.el_.vjs_pause(); 14235 }; 14236 14237 /** 14238 * Get/set video 14239 * 14240 * @param {Object=} src Source object 14241 * @return {Object} 14242 * @method src 14243 */ 14244 14245 Flash.prototype.src = function src(_src) { 14246 if (_src === undefined) { 14247 return this.currentSrc(); 14248 } 14249 14250 // Setting src through `src` not `setSrc` will be deprecated 14251 return this.setSrc(_src); 14252 }; 14253 14254 /** 14255 * Set video 14256 * 14257 * @param {Object=} src Source object 14258 * @deprecated 14259 * @method setSrc 14260 */ 14261 14262 Flash.prototype.setSrc = function setSrc(src) { 14263 // Make sure source URL is absolute. 14264 src = Url.getAbsoluteURL(src); 14265 this.el_.vjs_src(src); 14266 14267 // Currently the SWF doesn't autoplay if you load a source later. 14268 // e.g. Load player w/ no source, wait 2s, set src. 14269 if (this.autoplay()) { 14270 var tech = this; 14271 this.setTimeout(function () { 14272 tech.play(); 14273 }, 0); 14274 } 14275 }; 14276 14277 /** 14278 * Returns true if the tech is currently seeking. 14279 * @return {boolean} true if seeking 14280 */ 14281 14282 Flash.prototype.seeking = function seeking() { 14283 return this.lastSeekTarget_ !== undefined; 14284 }; 14285 14286 /** 14287 * Set current time 14288 * 14289 * @param {Number} time Current time of video 14290 * @method setCurrentTime 14291 */ 14292 14293 Flash.prototype.setCurrentTime = function setCurrentTime(time) { 14294 var seekable = this.seekable(); 14295 if (seekable.length) { 14296 // clamp to the current seekable range 14297 time = time > seekable.start(0) ? time : seekable.start(0); 14298 time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1); 14299 14300 this.lastSeekTarget_ = time; 14301 this.trigger('seeking'); 14302 this.el_.vjs_setProperty('currentTime', time); 14303 _Tech.prototype.setCurrentTime.call(this); 14304 } 14305 }; 14306 14307 /** 14308 * Get current time 14309 * 14310 * @param {Number=}
14310 time Current time of video 14311 * @return {Number} Current time 14312 * @method currentTime 14313 */ 14314 14315 Flash.prototype.currentTime = function currentTime(time) { 14316 // when seeking make the reported time keep up with the requested time 14317 // by reading the time we're seeking to 14318 if (this.seeking()) { 14319 return this.lastSeekTarget_ || 0; 14320 } 14321 return this.el_.vjs_getProperty('currentTime'); 14322 }; 14323 14324 /** 14325 * Get current source 14326 * 14327 * @method currentSrc 14328 */ 14329 14330 Flash.prototype.currentSrc = function currentSrc() { 14331 if (this.currentSource_) { 14332 return this.currentSource_.src; 14333 } else { 14334 return this.el_.vjs_getProperty('currentSrc'); 14335 } 14336 }; 14337 14338 /** 14339 * Load media into player 14340 * 14341 * @method load 14342 */ 14343 14344 Flash.prototype.load = function load() { 14345 this.el_.vjs_load(); 14346 }; 14347 14348 /** 14349 * Get poster 14350 * 14351 * @method poster 14352 */ 14353 14354 Flash.prototype.poster = function poster() { 14355 this.el_.vjs_getProperty('poster'); 14356 }; 14357 14358 /** 14359 * Poster images are not handled by the Flash tech so make this a no-op 14360 * 14361 * @method setPoster 14362 */ 14363 14364 Flash.prototype.setPoster = function setPoster() {}; 14365 14366 /** 14367 * Determine if can seek in media 14368 * 14369 * @return {TimeRangeObject} 14370 * @method seekable 14371 */ 14372 14373 Flash.prototype.seekable = function seekable() { 14374 var duration = this.duration(); 14375 if (duration === 0) { 14376 return _utilsTimeRangesJs.createTimeRange(); 14377 } 14378 return _utilsTimeRangesJs.createTimeRange(0, duration); 14379 }; 14380 14381 /** 14382 * Get buffered time range 14383 * 14384 * @return {TimeRangeObject} 14385 * @method buffered 14386 */ 14387 14388 Flash.prototype.buffered = function buffered() { 14389 var ranges = this.el_.vjs_getProperty('buffered'); 14390 if (ranges.length === 0) { 14391 return _utilsTimeRangesJs.createTimeRange(); 14392 } 14393 return _utilsTimeRangesJs.createTimeRange(ranges[0][0], ranges[0][1]); 14394 }; 14395 14396 /** 14397 * Get fullscreen support - 14398 * Flash does not allow fullscreen through javascript 14399 * so always returns false 14400 * 14401 * @return {Boolean} false 14402 * @method supportsFullScreen 14403 */ 14404 14405 Flash.prototype.supportsFullScreen = function supportsFullScreen() { 14406 return false; // Flash does not allow fullscreen through javascript 14407 }; 14408 14409 /** 14410 * Request to enter fullscreen 14411 * Flash does not allow fullscreen through javascript 14412 * so always returns false 14413 * 14414 * @return {Boolean} false 14415 * @method enterFullScreen 14416 */ 14417 14418 Flash.prototype.enterFullScreen = function enterFullScreen() { 14419 return false; 14420 }; 14421 14422 return Flash; 14423})(_tech2['default']); 14424 14425var _api = Flash.prototype; 14426var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(','); 14427var _readOnly = 'networkState,readyState,initialTime,duration,startOffsetTime,paused,ended,videoWidth,videoHeight'.split(','); 14428 14429function _createSetter(attr) { 14430 var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1); 14431 _api['set' + attrUpper] = function (val) { 14432 return this.el_.vjs_setProperty(attr, val); 14433 }; 14434} 14435function _createGetter(attr) { 14436 _api[attr] = function () { 14437 return this.el_.vjs_getProperty(attr); 14438 }; 14439} 14440 14441// Create getter and setters for all read/write attributes 14442for (var i = 0; i < _readWrite.length; i++) { 14443 _createGetter(_readWrite[i]); 14444 _createSetter(_readWrite[i]); 14445} 14446 14447// Create getters for read-only attributes 14448for (var i = 0; i < _readOnly.length; i++) { 14449 _createGetter(_readOnly[i]); 14450} 14451 14452/* Flash Support Testing -------------------------------------------------------- */ 14453 14454Flash.isSupported = function () { 14455 return Flash.version()[0] >= 10; 14456 // return swfobject.hasFlashPlayerVersion('10'); 14457}; 14458 14459// Add Source Handler pattern functions to this tech 14460_tech2['default'].withSourceHandlers(Flash); 14461 14462/* 14463 * The default native source handler. 14464 * This simply passes the source to the video element. Nothing fancy. 14465 * 14466 * @param {Object} source The source object 14467 * @param {Flash} tech The instance of the Flash tech 14468 */ 14469Flash.nativeSourceHandler = {}; 14470 14471/** 14472 * Check if Flash can play the given videotype 14473 * @param {String} type The mimetype to check 14474 * @return {String} 'probably', 'maybe', or '' (empty string) 14475 */ 14476Flash.nativeSourceHandler.canPlayType = function (type) { 14477 if (type in Flash.formats) { 14478 return 'maybe'; 14479 } 14480 14481 return ''; 14482}; 14483 14484/* 14485 * Check Flash can handle the source natively 14486 * 14487 * @param {Object} source The source object 14488 * @return {String} 'probably', 'maybe', or '' (empty string) 14489 */ 14490Flash.nativeSourceHandler.canHandleSource = function (source) { 14491 var type; 14492 14493 function guessMimeType(src) { 14494 var ext = Url.getFileExtension(src); 14495 if (ext) { 14496 return 'video/' + ext; 14497 } 14498 return ''; 14499 } 14500 14501 if (!source.type) { 14502 type = guessMimeType(source.src); 14503 } else { 14504 // Strip code information from the type because we don't get that specific 14505 type = source.type.replace(/;.*/, '').toLowerCase(); 14506 } 14507 14508 return Flash.nativeSourceHandler.canPlayType(type); 14509}; 14510 14511/* 14512 * Pass the source to the flash object 14513 * Adaptive source handlers will have more complicated workflows before passing 14514 * video data to the video element 14515 * 14516 * @param {Object} source The source object 14517 * @param {Flash} tech The instance of the Flash tech 14518 * @param {Object} options The options to pass to the source 14519 */ 14520Flash.nativeSourceHandler.handleSource = function (source, tech, options) { 14521 tech.setSrc(source.src); 14522}; 14523 14524/* 14525 * Clean up the source handler when disposing the player or switching sources.. 14526 * (no cleanup is needed when supporting the format natively) 14527 */ 14528Flash.nativeSourceHandler.dispose = function () {}; 14529 14530// Register the native source handler 14531Flash.registerSourceHandler(Flash.nativeSourceHandler); 14532 14533Flash.formats = { 14534 'video/flv': 'FLV', 14535 'video/x-flv': 'FLV', 14536 'video/mp4': 'MP4', 14537 'video/m4v': 'MP4' 14538}; 14539 14540Flash.onReady = function (currSwf) { 14541 var el = Dom.getEl(currSwf); 14542 var tech = el && el.tech; 14543 14544 // if there is no el then the tech has been disposed 14545 // and the tech element was removed from the player div 14546 if (tech && tech.el()) { 14547 // check that the flash object is really ready 14548 Flash.checkReady(tech); 14549 } 14550}; 14551 14552// The SWF isn't always ready when it says it is. Sometimes the API functions still need to be added to the object. 14553// If it's not ready, we set a timeout to check again shortly. 14554Flash.checkReady = function (tech) {
14555 // stop worrying if the tech has been disposed 14556 if (!tech.el()) { 14557 return; 14558 } 14559 14560 // check if API property exists 14561 if (tech.el().vjs_getProperty) { 14562 // tell tech it's ready 14563 tech.triggerReady(); 14564 } else { 14565 // wait longer 14566 this.setTimeout(function () { 14567 Flash['checkReady'](tech); 14568 }, 50); 14569 } 14570}; 14571 14572// Trigger events from the swf on the player 14573Flash.onEvent = function (swfID, eventName) { 14574 var tech = Dom.getEl(swfID).tech; 14575 tech.trigger(eventName); 14576}; 14577 14578// Log errors from the swf 14579Flash.onError = function (swfID, err) { 14580 var tech = Dom.getEl(swfID).tech; 14581 14582 // trigger MEDIA_ERR_SRC_NOT_SUPPORTED 14583 if (err === 'srcnotfound') { 14584 return tech.error(4); 14585 } 14586 14587 // trigger a custom error 14588 tech.error('FLASH: ' + err); 14589}; 14590 14591// Flash Version Check 14592Flash.version = function () { 14593 var version = '0,0,0'; 14594 14595 // IE 14596 try { 14597 version = new _globalWindow2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; 14598 14599 // other browsers 14600 } catch (e) { 14601 try { 14602 if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) { 14603 version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; 14604 } 14605 } catch (err) {} 14606 } 14607 return version.split(','); 14608}; 14609 14610// Flash embedding method. Only used in non-iframe mode 14611Flash.embed = function (swf, flashVars, params, attributes) { 14612 var code = Flash.getEmbedCode(swf, flashVars, params, attributes); 14613 14614 // Get element by embedding code and retrieving created element 14615 var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0]; 14616 14617 return obj; 14618}; 14619 14620Flash.getEmbedCode = function (swf, flashVars, params, attributes) { 14621 var objTag = '<object type="application/x-shockwave-flash" '; 14622 var flashVarsString = ''; 14623 var paramsString = ''; 14624 var attrsString = ''; 14625 14626 // Convert flash vars to string 14627 if (flashVars) { 14628 Object.getOwnPropertyNames(flashVars).forEach(function (key) { 14629 flashVarsString += key + '=' + flashVars[key] + '&'; 14630 }); 14631 } 14632 14633 // Add swf, flashVars, and other default params 14634 params = _objectAssign2['default']({ 14635 'movie': swf, 14636 'flashvars': flashVarsString, 14637 'allowScriptAccess': 'always', // Required to talk to swf 14638 'allowNetworking': 'all' // All should be default, but having security issues. 14639 }, params); 14640 14641 // Create param tags string 14642 Object.getOwnPropertyNames(params).forEach(function (key) { 14643 paramsString += '<param name="' + key + '" value="' + params[key] + '" />'; 14644 }); 14645 14646 attributes = _objectAssign2['default']({ 14647 // Add swf to attributes (need both for IE and Others to work) 14648 'data': swf, 14649 14650 // Default to 100% width/height 14651 'width': '100%', 14652 'height': '100%' 14653 14654 }, attributes); 14655 14656 // Create Attributes string 14657 Object.getOwnPropertyNames(attributes).forEach(function (key) { 14658 attrsString += key + '="' + attributes[key] + '" '; 14659 }); 14660 14661 return '' + objTag + attrsString + '>' + paramsString + '</object>'; 14662}; 14663 14664// Run Flash through the RTMP decorator 14665_flashRtmp2['default'](Flash); 14666 14667_component2['default'].registerComponent('Flash', Flash); 14668_tech2['default'].registerTech('Flash', Flash); 14669exports['default'] = Flash; 14670module.exports = exports['default']; 14671 14672},{"../component":67,"../utils/dom.js":143,"../utils/time-ranges.js":151,"../utils/url.js":153,"./flash-rtmp":120,"./tech":124,"global/window":2,"object.assign":45}],122:[function(_dereq_,module,exports){ 14673/** 14674 * @file html5.js 14675 * HTML5 Media Controller - Wrapper for HTML5 Media API 14676 */ 14677 14678'use strict'; 14679 14680exports.__esModule = true; 14681 14682var _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.']); 14683 14684function _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; } } 14685 14686function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 14687 14688function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 14689 14690function _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
14690onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 14691 14692function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } 14693 14694var _techJs = _dereq_('./tech.js'); 14695 14696var _techJs2 = _interopRequireDefault(_techJs); 14697 14698var _component = _dereq_('../component'); 14699 14700var _component2 = _interopRequireDefault(_component); 14701 14702var _utilsDomJs = _dereq_('../utils/dom.js'); 14703 14704var Dom = _interopRequireWildcard(_utilsDomJs); 14705 14706var _utilsUrlJs = _dereq_('../utils/url.js'); 14707 14708var Url = _interopRequireWildcard(_utilsUrlJs); 14709 14710var _utilsFnJs = _dereq_('../utils/fn.js'); 14711 14712var Fn = _interopRequireWildcard(_utilsFnJs); 14713 14714var _utilsLogJs = _dereq_('../utils/log.js'); 14715 14716var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 14717 14718var _tsml = _dereq_('tsml'); 14719 14720var _tsml2 = _interopRequireDefault(_tsml); 14721 14722var _srcJsTracksTextTrackJs = _dereq_('../../../src/js/tracks/text-track.js'); 14723 14724var _srcJsTracksTextTrackJs2 = _interopRequireDefault(_srcJsTracksTextTrackJs); 14725 14726var _utilsBrowserJs = _dereq_('../utils/browser.js'); 14727 14728var browser = _interopRequireWildcard(_utilsBrowserJs); 14729 14730var _globalDocument = _dereq_('global/document'); 14731 14732var _globalDocument2 = _interopRequireDefault(_globalDocument); 14733 14734var _globalWindow = _dereq_('global/window'); 14735 14736var _globalWindow2 = _interopRequireDefault(_globalWindow); 14737 14738var _objectAssign = _dereq_('object.assign'); 14739 14740var _objectAssign2 = _interopRequireDefault(_objectAssign); 14741 14742var _utilsMergeOptionsJs = _dereq_('../utils/merge-options.js'); 14743 14744var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs); 14745 14746var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js'); 14747 14748var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs); 14749 14750/** 14751 * HTML5 Media Controller - Wrapper for HTML5 Media API 14752 * 14753 * @param {Object=} options Object of option names and values 14754 * @param {Function=} ready Ready callback function 14755 * @extends Tech 14756 * @class Html5 14757 */ 14758 14759var Html5 = (function (_Tech) { 14760 _inherits(Html5, _Tech); 14761 14762 function Html5(options, ready) { 14763 var _this = this; 14764 14765 _classCallCheck(this, Html5); 14766 14767 _Tech.call(this, options, ready); 14768 14769 var source = options.source; 14770 var crossoriginTracks = false; 14771 14772 // Set the source if one is provided 14773 // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted) 14774 // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source 14775 // anyway so the error gets fired. 14776 if (source && (this.el_.currentSrc !== source.src || options.tag && options.tag.
14776initNetworkState_ === 3)) { 14777 this.setSource(source); 14778 } else { 14779 this.handleLateInit_(this.el_); 14780 } 14781 14782 if (this.el_.hasChildNodes()) { 14783 14784 var nodes = this.el_.childNodes; 14785 var nodesLength = nodes.length; 14786 var removeNodes = []; 14787 14788 while (nodesLength--) { 14789 var node = nodes[nodesLength]; 14790 var nodeName = node.nodeName.toLowerCase(); 14791 14792 if (nodeName === 'track') { 14793 if (!this.featuresNativeTextTracks) { 14794 // Empty video tag tracks so the built-in player doesn't use them also. 14795 // This may not be fast enough to stop HTML5 browsers from reading the tags 14796 // so we'll need to turn off any default tracks if we're manually doing 14797 // captions and subtitles. videoElement.textTracks 14798 removeNodes.push(node); 14799 } else { 14800 // store HTMLTrackElement and TextTrack to remote list 14801 this.remoteTextTrackEls().addTrackElement_(node); 14802 this.remoteTextTracks().addTrack_(node.track); 14803 if (!crossoriginTracks && !this.el_.hasAttribute('crossorigin') && Url.isCrossOrigin(node.src)) { 14804 crossoriginTracks = true; 14805 } 14806 } 14807 } 14808 } 14809 14810 for (var i = 0; i < removeNodes.length; i++) { 14811 this.el_.removeChild(removeNodes[i]); 14812 } 14813 } 14814 14815 var trackTypes = ['audio', 'video']; 14816 14817 // ProxyNativeTextTracks 14818 trackTypes.forEach(function (type) { 14819 var capitalType = _utilsToTitleCaseJs2['default'](type); 14820 14821 if (!_this['featuresNative' + capitalType + 'Tracks']) { 14822 return; 14823 } 14824 var tl = _this.el()[type + 'Tracks']; 14825 14826 if (tl && tl.addEventListener) { 14827 tl.addEventListener('change', Fn.bind(_this, _this['handle' + capitalType + 'TrackChange_'])); 14828 tl.addEventListener('addtrack', Fn.bind(_this, _this['handle' + capitalType + 'TrackAdd_'])); 14829 tl.addEventListener('removetrack', Fn.bind(_this, _this['handle' + capitalType + 'TrackRemove_'])); 14830 } 14831 }); 14832 14833 if (this.featuresNativeTextTracks) { 14834 if (crossoriginTracks) { 14835 _utilsLogJs2['default'].warn(_tsml2['default'](_templateObject)); 14836 } 14837 14838 this.handleTextTrackChange_ = Fn.bind(this, this.handleTextTrackChange); 14839 this.handleTextTrackAdd_ = Fn.bind(this, this.handleTextTrackAdd); 14840 this.handleTextTrackRemove_ = Fn.bind(this, this.handleTextTrackRemove); 14841 this.proxyNativeTextTracks_(); 14842 } 14843 14844 // Determine if native controls should be used 14845 // Our goal should be to get the custom controls on mobile solid everywhere 14846 // so we can remove this all together. Right now this will block custom 14847 // controls on touch enabled laptops like the Chrome Pixel 14848 if (browser.TOUCH_ENABLED && options.nativeControlsForTouch === true || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) { 14849 this.setControls(true); 14850 } 14851 14852 this.triggerReady(); 14853 } 14854 14855 /* HTML5 Support Testing ---------------------------------------------------- */ 14856 14857 /* 14858 * Element for testing browser HTML5 video capabilities 14859 * 14860 * @type {Element} 14861 * @constant 14862 * @private 14863 */ 14864 14865 /** 14866 * Dispose of html5 media element 14867 * 14868 * @method dispose 14869 */ 14870 14871 Html5.prototype.dispose = function dispose() { 14872 var _this2 = this; 14873 14874 // Un-ProxyNativeTracks 14875 ['audio', 'video', 'text'].forEach(function (type) { 14876 var capitalType = _utilsToTitleCaseJs2['default'](type); 14877 var tl = _this2.el_[type + 'Tracks']; 14878 14879 if (tl && tl.removeEventListener) { 14880 tl.removeEventListener('change', _this2['handle' + capitalType + 'TrackChange_']); 14881 tl.removeEventListener('addtrack', _this2['handle' + capitalType + 'TrackAdd_']); 14882 tl.removeEventListener('removetrack', _this2['handle' + capitalType + 'TrackRemove_']); 14883 } 14884 }); 14885 14886 Html5.disposeMediaElement(this.el_); 14887 // tech will handle clearing of the emulated track list 14888 _Tech.prototype.dispose.call(this); 14889 }; 14890 14891 /** 14892 * Create the component's DOM element 14893 * 14894 * @return {Element} 14895 * @method createEl 14896 */ 14897 14898 Html5.prototype.createEl = function createEl() { 14899 var el = this.options_.tag; 14900 14901 // Check if this browser supports moving the element into the box. 14902 // On the iPhone video will break if you move the element, 14903 // So we have to create a brand new element. 14904 if (!el || this['movingMediaElementInDOM'] === false) { 14905 14906 // If the original tag is still there, clone and remove it. 14907 if (el) { 14908 var clone = el.cloneNode(true); 14909 el.parentNode.insertBefore(clone, el); 14910 Html5.disposeMediaElement(el); 14911 el = clone; 14912 } else { 14913 el = _globalDocument2['default'].createElement('video'); 14914 14915 // determine if native controls should be used 14916 var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag); 14917 var attributes = _utilsMergeOptionsJs2['default']({}, tagAttributes); 14918 if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) { 14919 delete attributes.controls; 14920 } 14921 14922 Dom.setElAttributes(el, _objectAssign2['default'](attributes, { 14923 id: this.options_.techId, 14924 'class': 'vjs-tech' 14925 })); 14926 } 14927 } 14928 14929 // Update specific tag settings, in case they were overridden 14930 var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted']; 14931 for (var i = settingsAttrs.length - 1; i >= 0; i--) { 14932 var attr = settingsAttrs[i]; 14933 var overwriteAttrs = {}; 14934 if (typeof this.options_[attr] !== 'undefined') { 14935 overwriteAttrs[attr] = this.options_[attr]; 14936 } 14937 Dom.setElAttributes(el, overwriteAttrs); 14938 } 14939 14940 return el; 14941 // jenniisawesome = true; 14942 }; 14943 14944 // If we're loading the playback object after it has started loading 14945 // or playing the video (often with autoplay on) then the loadstart event 14946 // has already fired and we need to fire it manually because many things 14947 // rely on it. 14948 14949 Html5.prototype.handleLateInit_ = function handleLateInit_(el) { 14950 var _this3 = this; 14951 14952 if (el.networkState === 0 || el.networkState === 3) { 14953 // The video element hasn't started loading the source yet 14954 // or didn't find a source 14955 return; 14956 } 14957 14958 if (el.readyState === 0) { 14959 var _ret = (function () { 14960 // NetworkState is set synchronously BUT loadstart is fired at the 14961 // end of the current stack, usually before setInterval(fn, 0). 14962 // So at this point we know loadstart may have already fired or is 14963 // about to fire, and either way the player hasn't seen it yet. 14964 // We don't want to fire loadstart prematurely here and cause a 14965 // double loadstart so we'll wait and see if it happens between now 14966 // and the next loop, and fire it if not. 14967 // HOWEVER, we also want to make sure it fires before loadedmetadata 14968 // which could also happen between now and the next loop, so we'll 14969 // watch for that also. 14970 var loadstartFired = false;
14971 var setLoadstartFired = function setLoadstartFired() { 14972 loadstartFired = true; 14973 }; 14974 _this3.on('loadstart', setLoadstartFired); 14975 14976 var triggerLoadstart = function triggerLoadstart() { 14977 // We did miss the original loadstart. Make sure the player 14978 // sees loadstart before loadedmetadata 14979 if (!loadstartFired) { 14980 this.trigger('loadstart'); 14981 } 14982 }; 14983 _this3.on('loadedmetadata', triggerLoadstart); 14984 14985 _this3.ready(function () { 14986 this.off('loadstart', setLoadstartFired); 14987 this.off('loadedmetadata', triggerLoadstart); 14988 14989 if (!loadstartFired) { 14990 // We did miss the original native loadstart. Fire it now. 14991 this.trigger('loadstart'); 14992 } 14993 }); 14994 14995 return { 14996 v: undefined 14997 }; 14998 })(); 14999 15000 if (typeof _ret === 'object') return _ret.v; 15001 } 15002 15003 // From here on we know that loadstart already fired and we missed it. 15004 // The other readyState events aren't as much of a problem if we double 15005 // them, so not going to go to as much trouble as loadstart to prevent 15006 // that unless we find reason to. 15007 var eventsToTrigger = ['loadstart']; 15008 15009 // loadedmetadata: newly equal to HAVE_METADATA (1) or greater 15010 eventsToTrigger.push('loadedmetadata'); 15011 15012 // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater 15013 if (el.readyState >= 2) { 15014 eventsToTrigger.push('loadeddata'); 15015 } 15016 15017 // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater 15018 if (el.readyState >= 3) { 15019 eventsToTrigger.push('canplay'); 15020 } 15021 15022 // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4) 15023 if (el.readyState >= 4) { 15024 eventsToTrigger.push('canplaythrough'); 15025 } 15026 15027 // We still need to give the player time to add event listeners 15028 this.ready(function () { 15029 eventsToTrigger.forEach(function (type) { 15030 this.trigger(type); 15031 }, this); 15032 }); 15033 }; 15034 15035 Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() { 15036 var tt = this.el().textTracks; 15037 15038 if (tt) { 15039 // Add tracks - if player is initialised after DOM loaded, textTracks 15040 // will not trigger addtrack 15041 for (var i = 0; i < tt.length; i++) { 15042 this.textTracks().addTrack_(tt[i]); 15043 } 15044 15045 if (tt.addEventListener) { 15046 tt.addEventListener('change', this.handleTextTrackChange_); 15047 tt.addEventListener('addtrack', this.handleTextTrackAdd_); 15048 tt.addEventListener('removetrack', this.handleTextTrackRemove_); 15049 } 15050 } 15051 }; 15052 15053 Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) { 15054 var tt = this.textTracks(); 15055 this.textTracks().trigger({ 15056 type: 'change', 15057 target: tt, 15058 currentTarget: tt, 15059 srcElement: tt 15060 }); 15061 }; 15062 15063 Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) { 15064 this.textTracks().addTrack_(e.track); 15065 }; 15066 15067 Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) { 15068 this.textTracks().removeTrack_(e.track); 15069 }; 15070 15071 Html5.prototype.handleVideoTrackChange_ = function handleVideoTrackChange_(e) { 15072 var vt = this.videoTracks(); 15073 this.videoTracks().trigger({ 15074 type: 'change', 15075 target: vt, 15076 currentTarget: vt, 15077 srcElement: vt 15078 }); 15079 }; 15080 15081 Html5.prototype.handleVideoTrackAdd_ = function handleVideoTrackAdd_(e) { 15082 this.videoTracks().addTrack_(e.track); 15083 }; 15084 15085 Html5.prototype.handleVideoTrackRemove_ = function handleVideoTrackRemove_(e) { 15086 this.videoTracks().removeTrack_(e.track); 15087 }; 15088 15089 Html5.prototype.handleAudioTrackChange_ = function handleAudioTrackChange_(e) { 15090 var audioTrackList = this.audioTracks(); 15091 this.audioTracks().trigger({ 15092 type: 'change', 15093 target: audioTrackList, 15094 currentTarget: audioTrackList, 15095 srcElement: audioTrackList 15096 }); 15097 }; 15098 15099 Html5.prototype.handleAudioTrackAdd_ = function handleAudioTrackAdd_(e) { 15100 this.audioTracks().addTrack_(e.track); 15101 }; 15102 15103 Html5.prototype.handleAudioTrackRemove_ = function handleAudioTrackRemove_(e) { 15104 this.audioTracks().removeTrack_(e.track); 15105 }; 15106 15107 /** 15108 * Play for html5 tech 15109 * 15110 * @method play 15111 */ 15112 15113 Html5.prototype.play = function play() { 15114 this.el_.play(); 15115 }; 15116 15117 /** 15118 * Pause for html5 tech 15119 * 15120 * @method pause 15121 */ 15122 15123 Html5.prototype.pause = function pause() { 15124 this.el_.pause(); 15125 }; 15126 15127 /** 15128 * Paused for html5 tech 15129 * 15130 * @return {Boolean} 15131 * @method paused 15132 */ 15133 15134 Html5.prototype.paused = function paused() { 15135 return this.el_.paused; 15136 }; 15137 15138 /** 15139 * Get current time 15140 * 15141 * @return {Number} 15142 * @method currentTime 15143 */ 15144 15145 Html5.prototype.currentTime = function currentTime() { 15146 return this.el_.currentTime; 15147 }; 15148 15149 /** 15150 * Set current time 15151 * 15152 * @param {Number} seconds Current time of video 15153 * @method setCurrentTime 15154 */ 15155 15156 Html5.prototype.setCurrentTime = function setCurrentTime(seconds) { 15157 try { 15158 this.el_.currentTime = seconds; 15159 } catch (e) { 15160 _utilsLogJs2['default'](e, 'Video is not ready. (Video.js)'); 15161 // this.warning(VideoJS.warnings.videoNotReady); 15162 } 15163 }; 15164 15165 /** 15166 * Get duration 15167 * 15168 * @return {Number} 15169 * @method duration 15170 */ 15171 15172 Html5.prototype.duration = function duration() { 15173 return this.el_.duration || 0; 15174 }; 15175 15176 /** 15177 * Get a TimeRange object that represents the intersection 15178 * of the time ranges for which the user agent has all 15179 * relevant media 15180 * 15181 * @return {TimeRangeObject} 15182 * @method buffered 15183 */ 15184 15185 Html5.prototype.buffered = function buffered() { 15186 return this.el_.buffered; 15187 }; 15188 15189 /** 15190 * Get volume level 15191 * 15192 * @return {Number} 15193 * @method volume 15194 */ 15195 15196 Html5.prototype.volume = function volume() { 15197 return this.el_.volume; 15198 }; 15199 15200 /** 15201 * Set volume level 15202 * 15203 * @param {Number} percentAsDecimal Volume percent as a decimal 15204 * @method setVolume 15205 */ 15206 15207 Html5.prototype.setVolume = function setVolume(percentAsDecimal) { 15208 this.el_.volume = percentAsDecimal; 15209 }; 15210 15211 /** 15212 * Get if muted 15213 * 15214 * @return {Boolean} 15215 * @method muted 15216 */ 15217 15218 Html5.prototype.muted = function muted() { 15219 return this.el_.muted; 15220 }; 15221 15222 /** 15223 * Set muted 15224 * 15225 * @param {Boolean} If player is to be muted or note 15226 * @method setMuted 15227 */ 15228 15229 Html5.prototype.setMuted = function setMuted(muted) { 15230 this.el_.muted = muted; 15231 }; 15232 15233 /** 15234 * Get player width 15235 * 15236 * @return {Number} 15237 * @method width 15238 */ 15239 15240 Html5.prototype.width = function width() { 15241 return this.el_.offsetWidth; 15242 }; 15243 15244 /** 15245 * Get player height 15246 * 15247 * @return {Number} 15248 * @method height 15249 */ 15250 15251 Html5.prototype.height = function height() { 15252 return this.el_.offsetHeight; 15253 }; 15254 15255 /** 15256 * Get if there is fullscreen support 15257 * 15258 * @return {Boolean} 15259 * @method supportsFullScreen 15260 */ 15261 15262 Html5.prototype.supportsFullScreen = function supportsFullScreen() { 15263 if (typeof this.el_.webkitEnterFullScreen === 'function') { 15264 var userAgent = _globalWindow2['default'].navigator.userAgent; 15265 // Seems to be broken in Chromium/Chrome && Safari in Leopard 15266 if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) { 15267 return true; 15268 } 15269 } 15270 return false;
15271 }; 15272 15273 /** 15274 * Request to enter fullscreen 15275 * 15276 * @method enterFullScreen 15277 */ 15278 15279 Html5.prototype.enterFullScreen = function enterFullScreen() { 15280 var video = this.el_; 15281 15282 if ('webkitDisplayingFullscreen' in video) { 15283 this.one('webkitbeginfullscreen', function () { 15284 this.one('webkitendfullscreen', function () { 15285 this.trigger('fullscreenchange', { isFullscreen: false }); 15286 }); 15287 15288 this.trigger('fullscreenchange', { isFullscreen: true }); 15289 }); 15290 } 15291 15292 if (video.paused && video.networkState <= video.HAVE_METADATA) { 15293 // attempt to prime the video element for programmatic access 15294 // this isn't necessary on the desktop but shouldn't hurt 15295 this.el_.play(); 15296 15297 // playing and pausing synchronously during the transition to fullscreen 15298 // can get iOS ~6.1 devices into a play/pause loop 15299 this.setTimeout(function () { 15300 video.pause(); 15301 video.webkitEnterFullScreen(); 15302 }, 0); 15303 } else { 15304 video.webkitEnterFullScreen(); 15305 } 15306 }; 15307 15308 /** 15309 * Request to exit fullscreen 15310 * 15311 * @method exitFullScreen 15312 */ 15313 15314 Html5.prototype.exitFullScreen = function exitFullScreen() { 15315 this.el_.webkitExitFullScreen(); 15316 }; 15317 15318 /** 15319 * Get/set video 15320 * 15321 * @param {Object=} src Source object 15322 * @return {Object} 15323 * @method src 15324 */ 15325 15326 Html5.prototype.src = function src(_src) { 15327 if (_src === undefined) { 15328 return this.el_.src; 15329 } else { 15330 // Setting src through `src` instead of `setSrc` will be deprecated 15331 this.setSrc(_src); 15332 } 15333 }; 15334 15335 /** 15336 * Set video 15337 * 15338 * @param {Object} src Source object 15339 * @deprecated 15340 * @method setSrc 15341 */ 15342 15343 Html5.prototype.setSrc = function setSrc(src) { 15344 this.el_.src = src; 15345 }; 15346 15347 /** 15348 * Load media into player 15349 * 15350 * @method load 15351 */ 15352 15353 Html5.prototype.load = function load() { 15354 this.el_.load(); 15355 }; 15356 15357 /** 15358 * Reset the tech. Removes all sources and calls `load`. 15359 * 15360 * @method reset 15361 */ 15362 15363 Html5.prototype.reset = function reset() { 15364 Html5.resetMediaElement(this.el_); 15365 }; 15366 15367 /** 15368 * Get current source 15369 * 15370 * @return {Object} 15371 * @method currentSrc 15372 */ 15373 15374 Html5.prototype.currentSrc = function currentSrc() { 15375 if (this.currentSource_) { 15376 return this.currentSource_.src; 15377 } else { 15378 return this.el_.currentSrc; 15379 } 15380 }; 15381 15382 /** 15383 * Get poster 15384 * 15385 * @return {String} 15386 * @method poster 15387 */ 15388 15389 Html5.prototype.poster = function poster() { 15390 return this.el_.poster; 15391 }; 15392 15393 /** 15394 * Set poster 15395 * 15396 * @param {String} val URL to poster image 15397 * @method 15398 */ 15399 15400 Html5.prototype.setPoster = function setPoster(val) { 15401 this.el_.poster = val; 15402 }; 15403 15404 /** 15405 * Get preload attribute 15406 * 15407 * @return {String} 15408 * @method preload 15409 */ 15410 15411 Html5.prototype.preload = function preload() { 15412 return this.el_.preload; 15413 }; 15414 15415 /** 15416 * Set preload attribute 15417 * 15418 * @param {String} val Value for preload attribute 15419 * @method setPreload 15420 */ 15421 15422 Html5.prototype.setPreload = function setPreload(val) { 15423 this.el_.preload = val; 15424 }; 15425 15426 /** 15427 * Get autoplay attribute 15428 * 15429 * @return {String} 15430 * @method autoplay 15431 */ 15432 15433 Html5.prototype.autoplay = function autoplay() { 15434 return this.el_.autoplay; 15435 }; 15436 15437 /** 15438 * Set autoplay attribute 15439 * 15440 * @param {String} val Value for preload attribute 15441 * @method setAutoplay 15442 */ 15443 15444 Html5.prototype.setAutoplay = function setAutoplay(val) { 15445 this.el_.autoplay = val; 15446 }; 15447 15448 /** 15449 * Get controls attribute 15450 * 15451 * @return {String} 15452 * @method controls 15453 */ 15454 15455 Html5.prototype.controls = function controls() { 15456 return this.el_.controls; 15457 }; 15458 15459 /** 15460 * Set controls attribute 15461 * 15462 * @param {String} val Value for controls attribute 15463 * @method setControls 15464 */ 15465 15466 Html5.prototype.setControls = function setControls(val) { 15467 this.el_.controls = !!val; 15468 }; 15469 15470 /** 15471 * Get loop attribute 15472 * 15473 * @return {String} 15474 * @method loop 15475 */ 15476 15477 Html5.prototype.loop = function loop() { 15478 return this.el_.loop; 15479 }; 15480 15481 /** 15482 * Set loop attribute 15483 * 15484 * @param {String} val Value for loop attribute 15485 * @method setLoop 15486 */ 15487 15488 Html5.prototype.setLoop = function setLoop(val) { 15489 this.el_.loop = val; 15490 }; 15491 15492 /** 15493 * Get error value 15494 * 15495 * @return {String} 15496 * @method error 15497 */ 15498 15499 Html5.prototype.error = function error() { 15500 return this.el_.error; 15501 }; 15502 15503 /** 15504 * Get whether or not the player is in the "seeking" state 15505 * 15506 * @return {Boolean} 15507 * @method seeking 15508 */ 15509 15510 Html5.prototype.seeking = function seeking() { 15511 return this.el_.seeking; 15512 }; 15513 15514 /** 15515 * Get a TimeRanges object that represents the 15516 * ranges of the media resource to which it is possible 15517 * for the user agent to seek. 15518 * 15519 * @return {TimeRangeObject} 15520 * @method seekable 15521 */ 15522 15523 Html5.prototype.seekable = function seekable() { 15524 return this.el_.seekable; 15525 }; 15526 15527 /** 15528 * Get if video ended 15529 * 15530 * @return {Boolean} 15531 * @method ended 15532 */ 15533 15534 Html5.prototype.ended = function ended() { 15535 return this.el_.ended; 15536 }; 15537 15538 /** 15539 * Get the value of the muted content attribute 15540 * This attribute has no dynamic effect, it only 15541 * controls the default state of the element 15542 * 15543 * @return {Boolean} 15544 * @method defaultMuted 15545 */ 15546 15547 Html5.prototype.defaultMuted = function defaultMuted() { 15548 return this.el_.defaultMuted; 15549 }; 15550 15551 /** 15552 * Get desired speed at which the media resource is to play 15553 * 15554 * @return {Number} 15555 * @method playbackRate 15556 */ 15557 15558 Html5.prototype.playbackRate = function playbackRate() { 15559 return this.el_.playbackRate; 15560 }; 15561 15562 /** 15563 * Returns a TimeRanges object that represents the ranges of the 15564 * media resource that the user agent has played. 15565 * @return {TimeRangeObject} the range of points on the media 15566 * timeline that has been reached through normal playback 15567 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-played 15568 */ 15569 15570 Html5.prototype.played = function played() { 15571 return this.el_.played; 15572 }; 15573 15574 /** 15575 * Set desired speed at which the media resource is to play 15576 * 15577 * @param {Number} val Speed at which the media resource is to play 15578 * @method setPlaybackRate 15579 */ 15580 15581 Html5.prototype.setPlaybackRate = function setPlaybackRate(val) { 15582 this.el_.playbackRate = val; 15583 }; 15584 15585 /** 15586 * Get the current state of network activity for the element, from 15587 * the list below 15588 * NETWORK_EMPTY (numeric value 0) 15589 * NETWORK_IDLE (numeric value 1) 15590 * NETWORK_LOADING (numeric value 2) 15591 * NETWORK_NO_SOURCE (numeric value 3) 15592 * 15593 * @return {Number} 15594 * @method networkState 15595 */ 15596 15597 Html5.prototype.networkState = function networkState() { 15598 return this.el_.networkState; 15599 }; 15600 15601 /** 15602 * Get a value that expresses the current state of the element 15603 * with respect to rendering the current playback position, from 15604 * the codes in the list below 15605 * HAVE_NOTHING (numeric value 0) 15606 * HAVE_METADATA (numeric value 1) 15607 * HAVE_CURRENT_DATA (numeric value 2) 15608 * HAVE_FUTURE_DATA (numeric value 3) 15609 * HAVE_ENOUGH_DATA (numeric value 4) 15610 * 15611 * @return {Number} 15612 * @method readyState 15613 */ 15614 15615 Html5.prototype.readyState = function readyState() { 15616 return this.el_.readyState; 15617 }; 15618 15619 /** 15620 * Get width of video 15621 * 15622 * @return {Number} 15623 * @method videoWidth 15624 */ 15625 15626 Html5.prototype.videoWidth = function videoWidth() { 15627 return this.el_.videoWidth; 15628 }; 15629 15630 /** 15631 * Get height of video 15632 * 15633 * @return {Number} 15634 * @method videoHeight 15635 */ 15636 15637 Html5.prototype.videoHeight = function videoHeight() { 15638 return this.el_.videoHeight; 15639 }; 15640 15641 /** 15642 * Get text tracks 15643 * 15644 * @return {TextTrackList} 15645 * @method textTracks 15646 */ 15647 15648 Html5.prototype.textTracks = function textTracks() { 15649 return _Tech.prototype.textTracks.call(this); 15650 }; 15651 15652 /** 15653 * Creates and returns a text track object 15654 * 15655 * @param {String} kind Text track kind (subtitles, captions, descriptions 15656 * chapters and metadata) 15657 * @param {String=} label Label to identify the text track 15658 * @param {String=} language Two letter language abbreviation 15659 * @return {TextTrackObject} 15660 * @method addTextTrack 15661 */ 15662 15663 Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) { 15664 if (!this['featuresNativeTextTracks']) { 15665 return _Tech.prototype.addTextTrack.call(this, kind, label, language); 15666 } 15667 15668 return this.el_.addTextTrack(kind, label, language); 15669 }; 15670 15671 /** 15672 * Creates a remote text track object and returns a html track element 15673 * 15674 * @param {Object} options The object should contain values for 15675 * kind, language, label and src (location of the WebVTT file) 15676 * @return {HTMLTrackElement} 15677 * @method addRemoteTextTrack 15678 */ 15679 15680 Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack() { 15681 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 15682 15683 if (!this['featuresNativeTextTracks']) { 15684 return _Tech.prototype.addRemoteTextTrack.call(this, options); 15685 } 15686 15687 var htmlTrackElement = _globalDocument2['default'].createElement('track'); 15688 15689 if (options.kind) { 15690 htmlTrackElement.kind = options.kind; 15691 } 15692 if (options.label) { 15693 htmlTrackElement.label = options.label; 15694 } 15695 if (options.language || options.srclang) { 15696 htmlTrackElement.srclang = options.language || options.srclang; 15697 } 15698 if (options['default']) { 15699 htmlTrackElement['default'] = options['default']; 15700 } 15701 if (options.id) { 15702 htmlTrackElement.id = options.id; 15703 } 15704 if (options.src) { 15705 htmlTrackElement.src = options.src; 15706 } 15707 15708 this.el().appendChild(htmlTrackElement); 15709 15710 // store HTMLTrackElement and TextTrack to remote list 15711 this.remoteTextTrackEls().addTrackElement_(htmlTrackElement); 15712 this.remoteTextTracks().addTrack_(htmlTrackElement.track); 15713 15714 return htmlTrackElement; 15715 }; 15716 15717 /** 15718 * Remove remote text track from TextTrackList object 15719 * 15720 * @param {TextTrackObject} track Texttrack object to remove 15721 * @method removeRemoteTextTrack 15722 */ 15723 15724 Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) { 15725 if (!this['featuresNativeTextTracks']) { 15726 return _Tech.prototype.removeRemoteTextTrack.call(this, track); 15727 } 15728 15729 var tracks = undefined, 15730 i = undefined; 15731 15732 var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track); 15733 15734 // remove HTMLTrackElement and TextTrack from remote list 15735 this.remoteTextTrackEls().removeTrackElement_(trackElement); 15736 this.remoteTextTracks().removeTrack_(track); 15737 15738 tracks = this.$$('track'); 15739 15740 i = tracks.length; 15741 while (i--) { 15742 if (track === tracks[i] || track === tracks[i].track) { 15743 this.el().removeChild(tracks[i]); 15744 } 15745 } 15746 }; 15747 15748 return Html5; 15749})(_techJs2['default']); 15750
15751Html5.TEST_VID = _globalDocument2['default'].createElement('video'); 15752var track = _globalDocument2['default'].createElement('track'); 15753track.kind = 'captions'; 15754track.srclang = 'en'; 15755track.label = 'English'; 15756Html5.TEST_VID.appendChild(track); 15757 15758/* 15759 * Check if HTML5 video is supported by this browser/device 15760 * 15761 * @return {Boolean} 15762 */ 15763Html5.isSupported = function () { 15764 // IE9 with no Media Player is a LIAR! (#984) 15765 try { 15766 Html5.TEST_VID['volume'] = 0.5; 15767 } catch (e) { 15768 return false; 15769 } 15770 15771 return !!Html5.TEST_VID.canPlayType; 15772}; 15773 15774// Add Source Handler pattern functions to this tech 15775_techJs2['default'].withSourceHandlers(Html5); 15776 15777/* 15778 * The default native source handler. 15779 * This simply passes the source to the video element. Nothing fancy. 15780 * 15781 * @param {Object} source The source object 15782 * @param {Html5} tech The instance of the HTML5 tech 15783 */ 15784Html5.nativeSourceHandler = {}; 15785 15786/* 15787 * Check if the video element can play the given videotype 15788 * 15789 * @param {String} type The mimetype to check 15790 * @return {String} 'probably', 'maybe', or '' (empty string) 15791 */ 15792Html5.nativeSourceHandler.canPlayType = function (type) { 15793 // IE9 on Windows 7 without MediaPlayer throws an error here 15794 // https://github.com/videojs/video.js/issues/519 15795 try { 15796 return Html5.TEST_VID.canPlayType(type); 15797 } catch (e) { 15798 return ''; 15799 } 15800}; 15801 15802/* 15803 * Check if the video element can handle the source natively 15804 * 15805 * @param {Object} source The source object 15806 * @return {String} 'probably', 'maybe', or '' (empty string) 15807 */ 15808Html5.nativeSourceHandler.canHandleSource = function (source) { 15809 var match, ext; 15810 15811 // If a type was provided we should rely on that 15812 if (source.type) { 15813 return Html5.nativeSourceHandler.canPlayType(source.type); 15814 } else if (source.src) { 15815 // If no type, fall back to checking 'video/[EXTENSION]' 15816 ext = Url.getFileExtension(source.src); 15817 15818 return Html5.nativeSourceHandler.canPlayType('video/' + ext); 15819 } 15820 15821 return ''; 15822}; 15823 15824/* 15825 * Pass the source to the video element 15826 * Adaptive source handlers will have more complicated workflows before passing 15827 * video data to the video element 15828 * 15829 * @param {Object} source The source object 15830 * @param {Html5} tech The instance of the Html5 tech 15831 * @param {Object} options The options to pass to the source 15832 */ 15833Html5.nativeSourceHandler.handleSource = function (source, tech, options) { 15834 tech.setSrc(source.src); 15835}; 15836 15837/* 15838* Clean up the source handler when disposing the player or switching sources.. 15839* (no cleanup is needed when supporting the format natively) 15840*/ 15841Html5.nativeSourceHandler.dispose = function () {}; 15842 15843// Register the native source handler 15844Html5.registerSourceHandler(Html5.nativeSourceHandler); 15845 15846/* 15847 * Check if the volume can be changed in this browser/device. 15848 * Volume cannot be changed in a lot of mobile devices. 15849 * Specifically, it can't be changed from 1 on iOS. 15850 * 15851 * @return {Boolean} 15852 */ 15853Html5.canControlVolume = function () { 15854 var volume = Html5.TEST_VID.volume; 15855 Html5.TEST_VID.volume = volume / 2 + 0.1; 15856 return volume !== Html5.TEST_VID.volume; 15857}; 15858 15859/* 15860 * Check if playbackRate is supported in this browser/device. 15861 * 15862 * @return {Boolean} 15863 */ 15864Html5.canControlPlaybackRate = function () { 15865 // Playback rate API is implemented in Android Chrome, but doesn't do anything 15866 // https://github.com/videojs/video.js/issues/3180 15867 if (browser.IS_ANDROID && browser.IS_CHROME) { 15868 return false; 15869 } 15870 var playbackRate = Html5.TEST_VID.playbackRate; 15871 Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1; 15872 return playbackRate !== Html5.TEST_VID.playbackRate; 15873}; 15874 15875/* 15876 * Check to see if native text tracks are supported by this browser/device 15877 * 15878 * @return {Boolean} 15879 */ 15880Html5.supportsNativeTextTracks = function () { 15881 var supportsTextTracks; 15882 15883 // Figure out native text track support
15884 // If mode is a number, we cannot change it because it'll disappear from view. 15885 // Browsers with numeric modes include IE10 and older (<=2013) samsung android models. 15886 // Firefox isn't playing nice either with modifying the mode 15887 // TODO: Investigate firefox: https://github.com/videojs/video.js/issues/1862 15888 supportsTextTracks = !!Html5.TEST_VID.textTracks; 15889 if (supportsTextTracks && Html5.TEST_VID.textTracks.length > 0) { 15890 supportsTextTracks = typeof Html5.TEST_VID.textTracks[0]['mode'] !== 'number'; 15891 } 15892 if (supportsTextTracks && browser.IS_FIREFOX) { 15893 supportsTextTracks = false; 15894 } 15895 if (supportsTextTracks && !('onremovetrack' in Html5.TEST_VID.textTracks)) { 15896 supportsTextTracks = false; 15897 } 15898 15899 return supportsTextTracks; 15900}; 15901 15902/* 15903 * Check to see if native video tracks are supported by this browser/device 15904 * 15905 * @return {Boolean} 15906 */ 15907Html5.supportsNativeVideoTracks = function () { 15908 var supportsVideoTracks = !!Html5.TEST_VID.videoTracks; 15909 return supportsVideoTracks; 15910}; 15911 15912/* 15913 * Check to see if native audio tracks are supported by this browser/device 15914 * 15915 * @return {Boolean} 15916 */ 15917Html5.supportsNativeAudioTracks = function () { 15918 var supportsAudioTracks = !!Html5.TEST_VID.audioTracks; 15919 return supportsAudioTracks; 15920}; 15921 15922/** 15923 * An array of events available on the Html5 tech. 15924 * 15925 * @private 15926 * @type {Array} 15927 */ 15928Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange']; 15929 15930/* 15931 * Set the tech's volume control support status 15932 * 15933 * @type {Boolean} 15934 */ 15935Html5.prototype['featuresVolumeControl'] = Html5.canControlVolume(); 15936 15937/* 15938 * Set the tech's playbackRate support status 15939 * 15940 * @type {Boolean} 15941 */ 15942Html5.prototype['featuresPlaybackRate'] = Html5.canControlPlaybackRate(); 15943 15944/* 15945 * Set the tech's status on moving the video element. 15946 * In iOS, if you move a video element in the DOM, it breaks video playback. 15947 * 15948 * @type {Boolean} 15949 */ 15950Html5.prototype['movingMediaElementInDOM'] = !browser.IS_IOS; 15951 15952/* 15953 * Set the the tech's fullscreen resize support status. 15954 * HTML video is able to automatically resize when going to fullscreen. 15955 * (No longer appears to be used. Can probably be removed.) 15956 */ 15957Html5.prototype['featuresFullscreenResize'] = true; 15958 15959/* 15960 * Set the tech's progress event support status 15961 * (this disables the manual progress events of the Tech) 15962 */ 15963Html5.prototype['featuresProgressEvents'] = true; 15964 15965/* 15966 * Sets the tech's status on native text track support 15967 * 15968 * @type {Boolean} 15969 */ 15970Html5.prototype['featuresNativeTextTracks'] = Html5.supportsNativeTextTracks(); 15971 15972/** 15973 * Sets the tech's status on native text track support 15974 * 15975 * @type {Boolean} 15976 */ 15977Html5.prototype['featuresNativeVideoTracks'] = Html5.supportsNativeVideoTracks(); 15978 15979/** 15980 * Sets the tech's status on native audio track support 15981 * 15982 * @type {Boolean} 15983 */ 15984Html5.prototype['featuresNativeAudioTracks'] = Html5.supportsNativeAudioTracks(); 15985 15986// HTML5 Feature detection and Device Fixes --------------------------------- // 15987var canPlayType = undefined; 15988var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i; 15989var mp4RE = /^video\/mp4/i; 15990 15991Html5.patchCanPlayType = function () { 15992 // Android 4.0 and above can play HLS to some extent but it reports being unable to do so 15993 if (browser.ANDROID_VERSION >= 4.0) { 15994 if (!canPlayType) { 15995 canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType; 15996 } 15997 15998 Html5.TEST_VID.constructor.prototype.canPlayType = function (type) { 15999 if (type && mpegurlRE.test(type)) { 16000 return 'maybe'; 16001 } 16002 return canPlayType.call(this, type); 16003 }; 16004 } 16005 16006 // Override Android 2.2 and less canPlayType method which is broken 16007 if (browser.IS_OLD_ANDROID) { 16008 if (!canPlayType) { 16009 canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType; 16010 } 16011 16012 Html5.TEST_VID.constructor.prototype.canPlayType = function (type) { 16013 if (type && mp4RE.test(type)) { 16014 return 'maybe'; 16015 } 16016 return canPlayType.call(this, type); 16017 }; 16018 } 16019}; 16020 16021Html5.unpatchCanPlayType = function () {
16022 var r = Html5.TEST_VID.constructor.prototype.canPlayType; 16023 Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType; 16024 canPlayType = null; 16025 return r; 16026}; 16027 16028// by default, patch the video element 16029Html5.patchCanPlayType(); 16030 16031Html5.disposeMediaElement = function (el) { 16032 if (!el) { 16033 return; 16034 } 16035 16036 if (el.parentNode) { 16037 el.parentNode.removeChild(el); 16038 } 16039 16040 // remove any child track or source nodes to prevent their loading 16041 while (el.hasChildNodes()) { 16042 el.removeChild(el.firstChild); 16043 } 16044 16045 // remove any src reference. not setting `src=''` because that causes a warning 16046 // in firefox 16047 el.removeAttribute('src'); 16048 16049 // force the media element to update its loading state by calling load() 16050 // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793) 16051 if (typeof el.load === 'function') { 16052 // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473) 16053 (function () { 16054 try { 16055 el.load(); 16056 } catch (e) { 16057 // not supported 16058 } 16059 })(); 16060 } 16061}; 16062 16063Html5.resetMediaElement = function (el) { 16064 if (!el) { 16065 return; 16066 } 16067 16068 var sources = el.querySelectorAll('source'); 16069 var i = sources.length; 16070 while (i--) { 16071 el.removeChild(sources[i]); 16072 } 16073 16074 // remove any src reference. 16075 // not setting `src=''` because that throws an error 16076 el.removeAttribute('src'); 16077 16078 if (typeof el.load === 'function') { 16079 // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473) 16080 (function () { 16081 try { 16082 el.load(); 16083 } catch (e) {} 16084 })(); 16085 } 16086}; 16087 16088_component2['default'].registerComponent('Html5', Html5); 16089_techJs2['default'].registerTech('Html5', Html5); 16090exports['default'] = Html5; 16091module.exports = exports['default']; 16092 16093},{"../../../src/js/tracks/text-track.js":134,"../component":67,"../utils/browser.js":140,"../utils/dom.js":143,"../utils/fn.js":145,"../utils/log.js":148,"../utils/merge-options.js":149,"../utils/to-title-case.js":152,"../utils/url.js":153,"./tech.js":124,"global/document":1,"global/window":2,"object.assign":45,"tsml":55}],123:[function(_dereq_,module,exports){ 16094/** 16095 * @file loader.js 16096 */ 16097'use strict'; 16098 16099exports.__esModule = true; 16100 16101function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16102 16103function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 16104 16105function _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; } 16106 16107var _componentJs = _dereq_('../component.js'); 16108 16109var _componentJs2 = _interopRequireDefault(_componentJs); 16110 16111var _techJs = _dereq_('./tech.js'); 16112 16113var _techJs2 = _interopRequireDefault(_techJs); 16114 16115var _globalWindow = _dereq_('global/window'); 16116 16117var _globalWindow2 = _interopRequireDefault(_globalWindow); 16118 16119var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js'); 16120 16121var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs); 16122 16123/** 16124 * The Media Loader is the component that decides which playback technology to load 16125 * when the player is initialized. 16126 * 16127 * @param {Object} player Main Player 16128 * @param {Object=} options Object of option names and values 16129 * @param {Function=} ready Ready callback function 16130 * @extends Component 16131 * @class MediaLoader 16132 */ 16133 16134var MediaLoader = (function (_Component) { 16135 _inherits(MediaLoader, _Component); 16136 16137 function MediaLoader(player, options, ready) { 16138 _classCallCheck(this, MediaLoader); 16139 16140 _Component.call(this, player, options, ready); 16141 16142 // If there are no sources when the player is initialized, 16143 // load the first supported playback technology. 16144 16145 if (!options.playerOptions['sources'] || options.playerOptions['sources'].length === 0) { 16146 for (var i = 0, j = options.playerOptions['techOrder']; i < j.length; i++) { 16147 var techName = _utilsToTitleCaseJs2['default'](j[i]); 16148 var tech = _techJs2['default'].getTech(techName);
16149 // Support old behavior of techs being registered as components. 16150 // Remove once that deprecated behavior is removed. 16151 if (!techName) { 16152 tech = _componentJs2['default'].getComponent(techName); 16153 } 16154 16155 // Check if the browser supports this technology 16156 if (tech && tech.isSupported()) { 16157 player.loadTech_(techName); 16158 break; 16159 } 16160 } 16161 } else { 16162 // // Loop through playback technologies (HTML5, Flash) and check for support. 16163 // // Then load the best source. 16164 // // A few assumptions here: 16165 // // All playback technologies respect preload false. 16166 player.src(options.playerOptions['sources']); 16167 } 16168 } 16169 16170 return MediaLoader; 16171})(_componentJs2['default']); 16172 16173_componentJs2['default'].registerComponent('MediaLoader', MediaLoader); 16174exports['default'] = MediaLoader; 16175module.exports = exports['default']; 16176 16177},{"../component.js":67,"../utils/to-title-case.js":152,"./tech.js":124,"global/window":2}],124:[function(_dereq_,module,exports){ 16178/** 16179 * @file tech.js 16180 * Media Technology Controller - Base class for media playback 16181 * technology controllers like Flash and HTML5 16182 */ 16183 16184'use strict'; 16185 16186exports.__esModule = true; 16187 16188function _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; } } 16189 16190function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16191 16192function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 16193 16194function _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; } 16195 16196var _component = _dereq_('../component'); 16197 16198var _component2 = _interopRequireDefault(_component); 16199 16200var _tracksHtmlTrackElement = _dereq_('../tracks/html-track-element'); 16201 16202var _tracksHtmlTrackElement2 = _interopRequireDefault(_tracksHtmlTrackElement); 16203 16204var _tracksHtmlTrackElementList = _dereq_('../tracks/html-track-element-list'); 16205 16206var _tracksHtmlTrackElementList2 = _interopRequireDefault(_tracksHtmlTrackElementList); 16207 16208var _utilsMergeOptionsJs = _dereq_('../utils/merge-options.js'); 16209 16210var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs); 16211 16212var _tracksTextTrack = _dereq_('../tracks/text-track'); 16213 16214var _tracksTextTrack2 = _interopRequireDefault(_tracksTextTrack); 16215 16216var _tracksTextTrackList = _dereq_('../tracks/text-track-list'); 16217 16218var _tracksTextTrackList2 = _interopRequireDefault(_tracksTextTrackList); 16219 16220var _tracksVideoTrack = _dereq_('../tracks/video-track'); 16221 16222var _tracksVideoTrack2 = _interopRequireDefault(_tracksVideoTrack); 16223 16224var _tracksVideoTrackList = _dereq_('../tracks/video-track-list'); 16225 16226var _tracksVideoTrackList2 = _interopRequireDefault(_tracksVideoTrackList); 16227 16228var _tracksAudioTrackList = _dereq_('../tracks/audio-track-list'); 16229 16230var _tracksAudioTrackList2 = _interopRequireDefault(_tracksAudioTrackList); 16231 16232var _tracksAudioTrack = _dereq_('../tracks/audio-track'); 16233 16234var _tracksAudioTrack2 = _interopRequireDefault(_tracksAudioTrack); 16235 16236var _utilsFnJs = _dereq_('../utils/fn.js'); 16237 16238var Fn = _interopRequireWildcard(_utilsFnJs); 16239 16240var _utilsLogJs = _dereq_('../utils/log.js'); 16241 16242var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 16243 16244var _utilsTimeRangesJs = _dereq_('../utils/time-ranges.js'); 16245 16246var _utilsBufferJs = _dereq_('../utils/buffer.js'); 16247 16248var _mediaErrorJs = _dereq_('../media-error.js'); 16249 16250var _mediaErrorJs2 = _interopRequireDefault(_mediaErrorJs); 16251 16252var _globalWindow = _dereq_('global/window'); 16253 16254var _globalWindow2 = _interopRequireDefault(_globalWindow); 16255 16256var _globalDocument = _dereq_('global/document'); 16257 16258var _globalDocument2 = _interopRequireDefault(_globalDocument); 16259 16260/** 16261 * Base class for media (HTML5 Video, Flash) controllers 16262 * 16263 * @param {Object=} options Options object 16264 * @param {Function=} ready Ready callback function 16265 * @extends Component 16266 * @class Tech 16267 */ 16268 16269var Tech = (function (_Component) { 16270 _inherits(Tech, _Component); 16271 16272 function Tech() { 16273 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 16274 var ready = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1]; 16275 16276 _classCallCheck(this, Tech); 16277 16278 // we don't want the tech to report user activity automatically.
16279 // This is done manually in addControlsListeners 16280 options.reportTouchActivity = false; 16281 _Component.call(this, null, options, ready); 16282 16283 // keep track of whether the current source has played at all to 16284 // implement a very limited played() 16285 this.hasStarted_ = false; 16286 this.on('playing', function () { 16287 this.hasStarted_ = true; 16288 }); 16289 this.on('loadstart', function () { 16290 this.hasStarted_ = false; 16291 }); 16292 16293 this.textTracks_ = options.textTracks; 16294 this.videoTracks_ = options.videoTracks; 16295 this.audioTracks_ = options.audioTracks; 16296 16297 // Manually track progress in cases where the browser/flash player doesn't report it. 16298 if (!this.featuresProgressEvents) { 16299 this.manualProgressOn(); 16300 } 16301 16302 // Manually track timeupdates in cases where the browser/flash player doesn't report it. 16303 if (!this.featuresTimeupdateEvents) { 16304 this.manualTimeUpdatesOn(); 16305 } 16306 16307 if (options.nativeCaptions === false || options.nativeTextTracks === false) { 16308 this.featuresNativeTextTracks = false; 16309 } 16310 16311 if (!this.featuresNativeTextTracks) { 16312 this.on('ready', this.emulateTextTracks); 16313 } 16314 16315 this.initTextTrackListeners(); 16316 this.initTrackListeners(); 16317 16318 // Turn on component tap events 16319 this.emitTapEvents(); 16320 } 16321 16322 /** 16323 * List of associated text tracks 16324 * 16325 * @type {TextTrackList} 16326 * @private 16327 */ 16328 16329 /* Fallbacks for unsupported event types 16330 ================================================================================ */ 16331 // Manually trigger progress events based on changes to the buffered amount 16332 // Many flash players and older HTML5 browsers don't send progress or progress-like events 16333 /** 16334 * Turn on progress events 16335 * 16336 * @method manualProgressOn 16337 */ 16338 16339 Tech.prototype.manualProgressOn = function manualProgressOn() { 16340 this.on('durationchange', this.onDurationChange); 16341 16342 this.manualProgress = true; 16343 16344 // Trigger progress watching when a source begins loading 16345 this.one('ready', this.trackProgress); 16346 }; 16347 16348 /** 16349 * Turn off progress events 16350 * 16351 * @method manualProgressOff 16352 */ 16353 16354 Tech.prototype.manualProgressOff = function manualProgressOff() { 16355 this.manualProgress = false; 16356 this.stopTrackingProgress(); 16357 16358 this.off('durationchange', this.onDurationChange); 16359 }; 16360 16361 /** 16362 * Track progress 16363 * 16364 * @method trackProgress 16365 */ 16366 16367 Tech.prototype.trackProgress = function trackProgress() { 16368 this.stopTrackingProgress(); 16369 this.progressInterval = this.setInterval(Fn.bind(this, function () { 16370 // Don't trigger unless buffered amount is greater than last time 16371 16372 var numBufferedPercent = this.bufferedPercent(); 16373 16374 if (this.bufferedPercent_ !== numBufferedPercent) { 16375 this.trigger('progress'); 16376 } 16377 16378 this.bufferedPercent_ = numBufferedPercent; 16379 16380 if (numBufferedPercent === 1) { 16381 this.stopTrackingProgress(); 16382 } 16383 }), 500); 16384 }; 16385 16386 /** 16387 * Update duration 16388 * 16389 * @method onDurationChange 16390 */ 16391 16392 Tech.prototype.onDurationChange = function onDurationChange() { 16393 this.duration_ = this.duration(); 16394 }; 16395 16396 /** 16397 * Create and get TimeRange object for buffering 16398 * 16399 * @return {TimeRangeObject} 16400 * @method buffered 16401 */ 16402 16403 Tech.prototype.buffered = function buffered() { 16404 return _utilsTimeRangesJs.createTimeRange(0, 0); 16405 }; 16406 16407 /** 16408 * Get buffered percent 16409 * 16410 * @return {Number} 16411 * @method bufferedPercent 16412 */ 16413 16414 Tech.prototype.bufferedPercent = function bufferedPercent() { 16415 return _utilsBufferJs.bufferedPercent(this.buffered(), this.duration_); 16416 }; 16417 16418 /** 16419 * Stops tracking progress by clearing progress interval 16420 * 16421 * @method stopTrackingProgress 16422 */ 16423 16424 Tech.prototype.stopTrackingProgress = function stopTrackingProgress() { 16425 this.clearInterval(this.progressInterval); 16426 }; 16427 16428 /*! Time Tracking -------------------------------------------------------------- */ 16429 /** 16430 * Set event listeners for on play and pause and tracking current time 16431 * 16432 * @method manualTimeUpdatesOn 16433 */ 16434 16435 Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() { 16436 this.manualTimeUpdates = true; 16437 16438 this.on('play', this.trackCurrentTime); 16439 this.on('pause', this.stopTrackingCurrentTime); 16440 }; 16441 16442 /** 16443 * Remove event listeners for on play and pause and tracking current time 16444 * 16445 * @method manualTimeUpdatesOff 16446 */ 16447 16448 Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() { 16449 this.manualTimeUpdates = false;
16450 this.stopTrackingCurrentTime(); 16451 this.off('play', this.trackCurrentTime); 16452 this.off('pause', this.stopTrackingCurrentTime); 16453 }; 16454 16455 /** 16456 * Tracks current time 16457 * 16458 * @method trackCurrentTime 16459 */ 16460 16461 Tech.prototype.trackCurrentTime = function trackCurrentTime() { 16462 if (this.currentTimeInterval) { 16463 this.stopTrackingCurrentTime(); 16464 } 16465 this.currentTimeInterval = this.setInterval(function () { 16466 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); 16467 }, 250); // 42 = 24 fps // 250 is what Webkit uses // FF uses 15 16468 }; 16469 16470 /** 16471 * Turn off play progress tracking (when paused or dragging) 16472 * 16473 * @method stopTrackingCurrentTime 16474 */ 16475 16476 Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() { 16477 this.clearInterval(this.currentTimeInterval); 16478 16479 // #1002 - if the video ends right before the next timeupdate would happen, 16480 // the progress bar won't make it all the way to the end 16481 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); 16482 }; 16483 16484 /** 16485 * Turn off any manual progress or timeupdate tracking 16486 * 16487 * @method dispose 16488 */ 16489 16490 Tech.prototype.dispose = function dispose() { 16491 16492 // clear out all tracks because we can't reuse them between techs 16493 this.clearTracks(['audio', 'video', 'text']); 16494 16495 // Turn off any manual progress or timeupdate tracking 16496 if (this.manualProgress) { 16497 this.manualProgressOff(); 16498 } 16499 16500 if (this.manualTimeUpdates) { 16501 this.manualTimeUpdatesOff(); 16502 } 16503 16504 _Component.prototype.dispose.call(this); 16505 }; 16506 16507 /** 16508 * clear out a track list, or multiple track lists 16509 * 16510 * Note: Techs without source handlers should call this between 16511 * sources for video & audio tracks, as usually you don't want 16512 * to use them between tracks and we have no automatic way to do 16513 * it for you 16514 * 16515 * @method clearTracks 16516 * @param {Array|String} types type(s) of track lists to empty 16517 */ 16518 16519 Tech.prototype.clearTracks = function clearTracks(types) { 16520 var _this = this; 16521 16522 types = [].concat(types); 16523 // clear out all tracks because we can't reuse them between techs 16524 types.forEach(function (type) { 16525 var list = _this[type + 'Tracks']() || []; 16526 var i = list.length; 16527 while (i--) { 16528 var track = list[i]; 16529 if (type === 'text') { 16530 _this.removeRemoteTextTrack(track); 16531 } 16532 list.removeTrack_(track); 16533 } 16534 }); 16535 }; 16536 16537 /** 16538 * Reset the tech. Removes all sources and resets readyState. 16539 * 16540 * @method reset 16541 */ 16542 16543 Tech.prototype.reset = function reset() {}; 16544 16545 /** 16546 * When invoked without an argument, returns a MediaError object 16547 * representing the current error state of the player or null if 16548 * there is no error. When invoked with an argument, set the current 16549 * error state of the player. 16550 * @param {MediaError=} err Optional an error object 16551 * @return {MediaError} the current error object or null 16552 * @method error 16553 */ 16554 16555 Tech.prototype.error = function error(err) { 16556 if (err !== undefined) { 16557 if (err instanceof _mediaErrorJs2['default']) { 16558 this.error_ = err; 16559 } else { 16560 this.error_ = new _mediaErrorJs2['default'](err); 16561 } 16562 this.trigger('error'); 16563 } 16564 return this.error_; 16565 }; 16566 16567 /** 16568 * Return the time ranges that have been played through for the 16569 * current source. This implementation is incomplete. It does not 16570 * track the played time ranges, only whether the source has played 16571 * at all or not. 16572 * @return {TimeRangeObject} a single time range if this video has 16573 * played or an empty set of ranges if not. 16574 * @method played 16575 */ 16576 16577 Tech.prototype.played = function played() { 16578 if (this.hasStarted_) { 16579 return _utilsTimeRangesJs.createTimeRange(0, 0); 16580 } 16581 return _utilsTimeRangesJs.createTimeRange(); 16582 }; 16583 16584 /** 16585 * Set current time 16586 * 16587 * @method setCurrentTime 16588 */ 16589 16590 Tech.prototype.setCurrentTime = function setCurrentTime() { 16591 // improve the accuracy of manual timeupdates 16592 if (this.manualTimeUpdates) { 16593 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); 16594 } 16595 }; 16596 16597 /** 16598 * Initialize texttrack listeners 16599 * 16600 * @method initTextTrackListeners 16601 */ 16602 16603 Tech.prototype.initTextTrackListeners = function initTextTrackListeners() { 16604 var textTrackListChanges = Fn.bind(this, function () { 16605 this.trigger('texttrackchange'); 16606 }); 16607 16608 var tracks = this.textTracks(); 16609 16610 if (!tracks) return; 16611 16612 tracks.addEventListener('removetrack', textTrackListChanges); 16613 tracks.addEventListener('addtrack', textTrackListChanges); 16614 16615 this.on('dispose', Fn.bind(this, function () { 16616 tracks.removeEventListener('removetrack', textTrackListChanges); 16617 tracks.removeEventListener('addtrack', textTrackListChanges); 16618 })); 16619 }; 16620 16621 /** 16622 * Initialize audio and video track listeners 16623 * 16624 * @method initTrackListeners 16625 */ 16626 16627 Tech.prototype.initTrackListeners = function initTrackListeners() { 16628 var _this2 = this; 16629 16630 var trackTypes = ['video', 'audio']; 16631
16632 trackTypes.forEach(function (type) { 16633 var trackListChanges = function trackListChanges() { 16634 _this2.trigger(type + 'trackchange'); 16635 }; 16636 16637 var tracks = _this2[type + 'Tracks'](); 16638 16639 tracks.addEventListener('removetrack', trackListChanges); 16640 tracks.addEventListener('addtrack', trackListChanges); 16641 16642 _this2.on('dispose', function () { 16643 tracks.removeEventListener('removetrack', trackListChanges); 16644 tracks.removeEventListener('addtrack', trackListChanges); 16645 }); 16646 }); 16647 }; 16648 16649 /** 16650 * Emulate texttracks 16651 * 16652 * @method emulateTextTracks 16653 */ 16654 16655 Tech.prototype.emulateTextTracks = function emulateTextTracks() { 16656 var _this3 = this; 16657 16658 var tracks = this.textTracks(); 16659 if (!tracks) { 16660 return; 16661 } 16662 16663 if (!_globalWindow2['default']['WebVTT'] && this.el().parentNode != null) { 16664 (function () { 16665 var script = _globalDocument2['default'].createElement('script'); 16666 script.src = _this3.options_['vtt.js'] || 'https://cdn.rawgit.com/gkatsev/vtt.js/vjs-v0.12.1/dist/vtt.min.js'; 16667 script.onload = function () { 16668 _this3.trigger('vttjsloaded'); 16669 }; 16670 script.onerror = function () { 16671 _this3.trigger('vttjserror'); 16672 }; 16673 _this3.on('dispose', function () { 16674 script.onload = null; 16675 script.onerror = null; 16676 }); 16677 // but have not loaded yet and we set it to true before the inject so that 16678 // we don't overwrite the injected window.WebVTT if it loads right away 16679 _globalWindow2['default']['WebVTT'] = true; 16680 _this3.el().parentNode.appendChild(script); 16681 })(); 16682 } 16683 16684 var updateDisplay = function updateDisplay() { 16685 return _this3.trigger('texttrackchange'); 16686 }; 16687 var textTracksChanges = function textTracksChanges() { 16688 updateDisplay(); 16689 16690 for (var i = 0; i < tracks.length; i++) { 16691 var track = tracks[i]; 16692 track.removeEventListener('cuechange', updateDisplay); 16693 if (track.mode === 'showing') { 16694 track.addEventListener('cuechange', updateDisplay); 16695 } 16696 } 16697 }; 16698 16699 textTracksChanges(); 16700 tracks.addEventListener('change', textTracksChanges); 16701 16702 this.on('dispose', function () { 16703 tracks.removeEventListener('change', textTracksChanges); 16704 }); 16705 }; 16706 16707 /** 16708 * Get videotracks 16709 * 16710 * @returns {VideoTrackList} 16711 * @method videoTracks 16712 */ 16713 16714 Tech.prototype.videoTracks = function videoTracks() { 16715 this.videoTracks_ = this.videoTracks_ || new _tracksVideoTrackList2['default'](); 16716 return this.videoTracks_; 16717 }; 16718 16719 /** 16720 * Get audiotracklist 16721 * 16722 * @returns {AudioTrackList} 16723 * @method audioTracks 16724 */ 16725 16726 Tech.prototype.audioTracks = function audioTracks() { 16727 this.audioTracks_ = this.audioTracks_ || new _tracksAudioTrackList2['default'](); 16728 return this.audioTracks_; 16729 }; 16730 16731 /* 16732 * Provide default methods for text tracks. 16733 * 16734 * Html5 tech overrides these. 16735 */ 16736 16737 /** 16738 * Get texttracks 16739 * 16740 * @returns {TextTrackList} 16741 * @method textTracks 16742 */ 16743 16744 Tech.prototype.textTracks = function textTracks() { 16745 this.textTracks_ = this.textTracks_ || new _tracksTextTrackList2['default'](); 16746 return this.textTracks_; 16747 }; 16748 16749 /** 16750 * Get remote texttracks 16751 * 16752 * @returns {TextTrackList} 16753 * @method remoteTextTracks 16754 */ 16755 16756 Tech.prototype.remoteTextTracks = function remoteTextTracks() { 16757 this.remoteTextTracks_ = this.remoteTextTracks_ || new _tracksTextTrackList2['default'](); 16758 return this.remoteTextTracks_; 16759 }; 16760 16761 /** 16762 * Get remote htmltrackelements 16763 * 16764 * @returns {HTMLTrackElementList} 16765 * @method remoteTextTrackEls 16766 */ 16767 16768 Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() { 16769 this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _tracksHtmlTrackElementList2['default'](); 16770 return this.remoteTextTrackEls_; 16771 }; 16772 16773 /** 16774 * Creates and returns a remote text track object 16775 * 16776 * @param {String} kind Text track kind (subtitles, captions, descriptions 16777 * chapters and metadata) 16778 * @param {String=} label Label to identify the text track 16779 * @param {String=} language Two letter language abbreviation 16780 * @return {TextTrackObject} 16781 * @method addTextTrack 16782 */ 16783 16784 Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) { 16785 if (!kind) { 16786 throw new Error('TextTrack kind is required but was not provided'); 16787 } 16788 16789 return createTrackHelper(this, kind, label, language); 16790 }; 16791 16792 /** 16793 * Creates a remote text track object and returns a emulated html track element 16794 * 16795 * @param {Object} options The object should contain values for 16796 * kind, language, label and src (location of the WebVTT file) 16797 * @return {HTMLTrackElement} 16798 * @method addRemoteTextTrack 16799 */ 16800 16801 Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack(options) { 16802 var track = _utilsMergeOptionsJs2['default'](options, { 16803 tech: this 16804 }); 16805 16806 var htmlTrackElement = new _tracksHtmlTrackElement2['default'](track); 16807 16808 // store HTMLTrackElement and TextTrack to remote list 16809 this.remoteTextTrackEls().addTrackElement_(htmlTrackElement); 16810 this.remoteTextTracks().addTrack_(htmlTrackElement.track); 16811 16812 // must come after remoteTextTracks() 16813 this.textTracks().addTrack_(htmlTrackElement.track); 16814 16815 return htmlTrackElement; 16816 }; 16817 16818 /** 16819 * Remove remote texttrack 16820 * 16821 * @param {TextTrackObject} track Texttrack to remove 16822 * @method removeRemoteTextTrack 16823 */ 16824 16825 Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) { 16826 this.textTracks().removeTrack_(track); 16827 16828 var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track); 16829 16830 // remove HTMLTrackElement and TextTrack from remote list 16831 this.remoteTextTrackEls().removeTrackElement_(trackElement); 16832 this.remoteTextTracks().removeTrack_(track); 16833 }; 16834 16835 /** 16836 * Provide a default setPoster method for techs 16837 * Poster support for techs should be optional, so we don't want techs to 16838 * break if they don't have a way to set a poster. 16839 * 16840 * @method setPoster 16841 */ 16842 16843 Tech.prototype.setPoster = function setPoster() {}; 16844 16845 /* 16846 * Check if the tech can support the given type 16847 * 16848 * The base tech does not support any type, but source handlers might 16849 * overwrite this. 16850 * 16851 * @param {String} type The mimetype to check 16852 * @return {String} 'probably', 'maybe', or '' (empty string) 16853 */ 16854 16855 Tech.prototype.canPlayType = function canPlayType() { 16856 return ''; 16857 }; 16858 16859 /* 16860 * Return whether the argument is a Tech or not. 16861 * Can be passed either a Class like `Html5` or a instance like `player.tech_` 16862 * 16863 * @param {Object} component An item to check 16864 * @return {Boolean} Whether it is a tech or not 16865 */ 16866 16867 Tech.isTech = function isTech(component) { 16868 return component.prototype instanceof Tech || component instanceof Tech || component === Tech; 16869 }; 16870 16871 /** 16872 * Registers a Tech 16873 * 16874 * @param {String} name Name of the Tech to register 16875 * @param {Object} tech The tech to register 16876 * @static 16877 * @method registerComponent 16878 */ 16879 16880 Tech.registerTech = function registerTech(name, tech) { 16881 if (!Tech.techs_) { 16882 Tech.techs_ = {}; 16883 } 16884 16885 if (!Tech.isTech(tech)) { 16886 throw new Error('Tech ' + name + ' must be a Tech'); 16887 } 16888 16889 Tech.techs_[name] = tech; 16890 return tech; 16891 }; 16892 16893 /** 16894 * Gets a component by name 16895 * 16896 * @param {String} name Name of the component to get 16897 * @return {Component} 16898 * @static 16899 * @method getComponent 16900 */ 16901 16902 Tech.getTech = function getTech(name) {
16903 if (Tech.techs_ && Tech.techs_[name]) { 16904 return Tech.techs_[name]; 16905 } 16906 16907 if (_globalWindow2['default'] && _globalWindow2['default'].videojs && _globalWindow2['default'].videojs[name]) { 16908 _utilsLogJs2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)'); 16909 return _globalWindow2['default'].videojs[name]; 16910 } 16911 }; 16912 16913 return Tech; 16914})(_component2['default']); 16915 16916Tech.prototype.textTracks_; 16917 16918/** 16919 * List of associated audio tracks 16920 * 16921 * @type {AudioTrackList} 16922 * @private 16923 */ 16924Tech.prototype.audioTracks_; 16925 16926/** 16927 * List of associated video tracks 16928 * 16929 * @type {VideoTrackList} 16930 * @private 16931 */ 16932Tech.prototype.videoTracks_; 16933 16934var createTrackHelper = function createTrackHelper(self, kind, label, language) { 16935 var options = arguments.length <= 4 || arguments[4] === undefined ? {} : arguments[4]; 16936 16937 var tracks = self.textTracks(); 16938 16939 options.kind = kind; 16940 16941 if (label) { 16942 options.label = label; 16943 } 16944 if (language) { 16945 options.language = language; 16946 } 16947 options.tech = self; 16948 16949 var track = new _tracksTextTrack2['default'](options); 16950 tracks.addTrack_(track); 16951 16952 return track; 16953}; 16954 16955Tech.prototype.featuresVolumeControl = true; 16956 16957// Resizing plugins using request fullscreen reloads the plugin 16958Tech.prototype.featuresFullscreenResize = false; 16959Tech.prototype.featuresPlaybackRate = false; 16960 16961// Optional events that we can manually mimic with timers 16962// currently not triggered by video-js-swf 16963Tech.prototype.featuresProgressEvents = false; 16964Tech.prototype.featuresTimeupdateEvents = false; 16965 16966Tech.prototype.featuresNativeTextTracks = false; 16967 16968/* 16969 * A functional mixin for techs that want to use the Source Handler pattern. 16970 * 16971 * ##### EXAMPLE: 16972 * 16973 * Tech.withSourceHandlers.call(MyTech); 16974 * 16975 */ 16976Tech.withSourceHandlers = function (_Tech) { 16977 /* 16978 * Register a source handler 16979 * Source handlers are scripts for handling specific formats. 16980 * The source handler pattern is used for adaptive formats (HLS, DASH) that 16981 * manually load video data and feed it into a Source Buffer (Media Source Extensions) 16982 * @param {Function} handler The source handler 16983 * @param {Boolean} first Register it before any existing handlers 16984 */ 16985 _Tech.registerSourceHandler = function (handler, index) { 16986 var handlers = _Tech.sourceHandlers; 16987 16988 if (!handlers) { 16989 handlers = _Tech.sourceHandlers = []; 16990 } 16991 16992 if (index === undefined) { 16993 // add to the end of the list 16994 index = handlers.length; 16995 } 16996 16997 handlers.splice(index, 0, handler); 16998 }; 16999 17000 /* 17001 * Check if the tech can support the given type 17002 * @param {String} type The mimetype to check 17003 * @return {String} 'probably', 'maybe', or '' (empty string) 17004 */ 17005 _Tech.canPlayType = function (type) { 17006 var handlers = _Tech.sourceHandlers || []; 17007 var can = undefined; 17008 17009 for (var i = 0; i < handlers.length; i++) { 17010 can = handlers[i].canPlayType(type); 17011 17012 if (can) { 17013 return can; 17014 } 17015 } 17016 17017 return ''; 17018 }; 17019 17020 /* 17021 * Return the first source handler that supports the source 17022 * TODO: Answer question: should 'probably' be prioritized over 'maybe' 17023 * @param {Object} source The source object 17024 * @returns {Object} The first source handler that supports the source 17025 * @returns {null} Null if no source handler is found 17026 */ 17027 _Tech.selectSourceHandler = function (source) { 17028 var handlers = _Tech.sourceHandlers || []; 17029 var can = undefined; 17030 17031 for (var i = 0; i < handlers.length; i++) { 17032 can = handlers[i].canHandleSource(source); 17033 17034 if (can) { 17035 return handlers[i]; 17036 } 17037 } 17038 17039 return null; 17040 }; 17041 17042 /* 17043 * Check if the tech can support the given source 17044 * @param {Object} srcObj The source object 17045 * @return {String} 'probably', 'maybe', or '' (empty string) 17046 */ 17047 _Tech.canPlaySource = function (srcObj) { 17048 var sh = _Tech.selectSourceHandler(srcObj); 17049 17050 if (sh) { 17051 return sh.canHandleSource(srcObj); 17052 } 17053 17054 return ''; 17055 }; 17056 17057 /* 17058 * When using a source handler, prefer its implementation of 17059 * any function normally provided by the tech. 17060 */ 17061 var deferrable = ['seekable', 'duration']; 17062 17063 deferrable.forEach(function (fnName) { 17064 var originalFn = this[fnName]; 17065 17066 if (typeof originalFn !== 'function') { 17067 return; 17068 } 17069 17070 this[fnName] = function () { 17071 if (this.sourceHandler_ && this.sourceHandler_[fnName]) { 17072 return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments); 17073 } 17074 return originalFn.apply(this, arguments); 17075 }; 17076 }, _Tech.prototype); 17077 17078 /* 17079 * Create a function for setting the source using a source object 17080 * and source handlers. 17081 * Should never be called unless a source handler was found. 17082 * @param {Object} source A source object with src and type keys 17083 * @return {Tech} self 17084 */ 17085 _Tech.prototype.setSource = function (source) { 17086 var sh = _Tech.selectSourceHandler(source); 17087 17088 if (!sh) { 17089 // Fall back to a native source hander when unsupported sources are 17090 // deliberately set 17091 if (_Tech.nativeSourceHandler) { 17092 sh = _Tech.nativeSourceHandler; 17093 } else { 17094 _utilsLogJs2['default'].error('No source hander found for the current source.'); 17095 } 17096 } 17097 17098 // Dispose any existing source handler 17099 this.disposeSourceHandler(); 17100 this.off('dispose', this.disposeSourceHandler); 17101 17102 // if we have a source and get another one 17103 // then we are loading something new 17104 // than clear all of our current tracks 17105 if (this.currentSource_) { 17106 this.clearTracks(['audio', 'video']); 17107 17108 this.currentSource_ = null; 17109 } 17110 17111 if (sh !== _Tech.nativeSourceHandler) { 17112 17113 this.currentSource_ = source; 17114 17115 // Catch if someone replaced the src without calling setSource. 17116 // If they do, set currentSource_ to null and dispose our source handler. 17117 this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_); 17118 this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); 17119 this.one(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_); 17120 } 17121 17122 this.sourceHandler_ = sh.handleSource(source, this, this.options_); 17123 this.on('dispose', this.disposeSourceHandler); 17124 17125 return this; 17126 }; 17127 17128 // On the first loadstart after setSource 17129 _Tech.prototype.firstLoadStartListener_ = function () { 17130 this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); 17131 }; 17132 17133 // On successive loadstarts when setSource has not been called again 17134 _Tech.prototype.successiveLoadStartListener_ = function () { 17135 this.currentSource_ = null; 17136 this.disposeSourceHandler(); 17137 this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); 17138 }; 17139 17140 /* 17141 * Clean up any existing source handler 17142 */ 17143 _Tech.prototype.disposeSourceHandler = function () { 17144 if (this.sourceHandler_ && this.sourceHandler_.dispose) { 17145 this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_); 17146 this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); 17147 this.sourceHandler_.dispose(); 17148 this.sourceHandler_ = null; 17149 } 17150 }; 17151}; 17152 17153_component2['default'].registerComponent('Tech', Tech); 17154// Old name for Tech 17155_component2['default'].registerComponent('MediaTechController', Tech);
17156Tech.registerTech('Tech', Tech); 17157exports['default'] = Tech; 17158module.exports = exports['default']; 17159 17160},{"../component":67,"../media-error.js":108,"../tracks/audio-track":126,"../tracks/audio-track-list":125,"../tracks/html-track-element":128,"../tracks/html-track-element-list":127,"../tracks/text-track":134,"../tracks/text-track-list":132,"../tracks/video-track":139,"../tracks/video-track-list":138,"../utils/buffer.js":141,"../utils/fn.js":145,"../utils/log.js":148,"../utils/merge-options.js":149,"../utils/time-ranges.js":151,"global/document":1,"global/window":2}],125:[function(_dereq_,module,exports){ 17161/** 17162 * @file audio-track-list.js 17163 */ 17164'use strict'; 17165 17166exports.__esModule = true; 17167 17168function _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; } } 17169 17170function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 17171 17172function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 17173 17174function _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; } 17175 17176var _trackList = _dereq_('./track-list'); 17177 17178var _trackList2 = _interopRequireDefault(_trackList); 17179 17180var _utilsBrowserJs = _dereq_('../utils/browser.js'); 17181 17182var browser = _interopRequireWildcard(_utilsBrowserJs); 17183 17184var _globalDocument = _dereq_('global/document'); 17185 17186var _globalDocument2 = _interopRequireDefault(_globalDocument); 17187 17188/** 17189 * anywhere we call this function we diverge from the spec 17190 * as we only support one enabled audiotrack at a time 17191 * 17192 * @param {Array|AudioTrackList} list list to work on 17193 * @param {AudioTrack} track the track to skip 17194 */ 17195var disableOthers = function disableOthers(list, track) { 17196 for (var i = 0; i < list.length; i++) { 17197 if (track.id === list[i].id) { 17198 continue; 17199 } 17200 // another audio track is enabled, disable it 17201 list[i].enabled = false; 17202 } 17203}; 17204/** 17205 * A list of possible audio tracks. All functionality is in the 17206 * base class Tracklist and the spec for AudioTrackList is located at: 17207 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist 17208 * 17209 * interface AudioTrackList : EventTarget { 17210 * readonly attribute unsigned long length; 17211 * getter AudioTrack (unsigned long index); 17212 * AudioTrack? getTrackById(DOMString id); 17213 * 17214 * attribute EventHandler onchange; 17215 * attribute EventHandler onaddtrack; 17216 * attribute EventHandler onremovetrack; 17217 * }; 17218 * 17219 * @param {AudioTrack[]} tracks a list of audio tracks to instantiate the list with 17220 * @extends TrackList 17221 * @class AudioTrackList 17222 */ 17223 17224var AudioTrackList = (function (_TrackList) { 17225 _inherits(AudioTrackList, _TrackList); 17226 17227 function AudioTrackList() { 17228 var tracks = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; 17229 17230 _classCallCheck(this, AudioTrackList); 17231 17232 var list = undefined; 17233 17234 // make sure only 1 track is enabled 17235 // sorted from last index to first index 17236 for (var i = tracks.length - 1; i >= 0; i--) { 17237 if (tracks[i].enabled) { 17238 disableOthers(tracks, tracks[i]); 17239 break; 17240 } 17241 } 17242 17243 // IE8 forces us to implement inheritance ourselves 17244 // as it does not support Object.defineProperty properly 17245 if (browser.IS_IE8) { 17246 list = _globalDocument2['default'].createElement('custom'); 17247 for (var prop in _trackList2['default'].prototype) { 17248 if (prop !== 'constructor') { 17249 list[prop] = _trackList2['default'].prototype[prop]; 17250 } 17251 } 17252 for (var prop in AudioTrackList.prototype) { 17253 if (prop !== 'constructor') { 17254 list[prop] = AudioTrackList.prototype[prop]; 17255 } 17256 } 17257 } 17258 17259 list = _TrackList.call(this, tracks, list); 17260 list.changing_ = false;
17261 17262 return list; 17263 } 17264 17265 AudioTrackList.prototype.addTrack_ = function addTrack_(track) { 17266 var _this = this; 17267 17268 if (track.enabled) { 17269 disableOthers(this, track); 17270 } 17271 17272 _TrackList.prototype.addTrack_.call(this, track); 17273 // native tracks don't have this 17274 if (!track.addEventListener) { 17275 return; 17276 } 17277 17278 track.addEventListener('enabledchange', function () { 17279 // when we are disabling other tracks (since we don't support 17280 // more than one track at a time) we will set changing_ 17281 // to true so that we don't trigger additional change events 17282 if (_this.changing_) { 17283 return; 17284 } 17285 _this.changing_ = true; 17286 disableOthers(_this, track); 17287 _this.changing_ = false; 17288 _this.trigger('change'); 17289 }); 17290 }; 17291 17292 AudioTrackList.prototype.addTrack = function addTrack(track) { 17293 this.addTrack_(track); 17294 }; 17295 17296 AudioTrackList.prototype.removeTrack = function removeTrack(track) { 17297 _TrackList.prototype.removeTrack_.call(this, track); 17298 }; 17299 17300 return AudioTrackList; 17301})(_trackList2['default']); 17302 17303exports['default'] = AudioTrackList; 17304module.exports = exports['default']; 17305 17306},{"../utils/browser.js":140,"./track-list":136,"global/document":1}],126:[function(_dereq_,module,exports){ 17307'use strict'; 17308 17309exports.__esModule = true; 17310 17311function _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; } } 17312 17313function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 17314 17315function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 17316 17317function _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; } 17318 17319var _trackEnums = _dereq_('./track-enums'); 17320 17321var _track = _dereq_('./track'); 17322 17323var _track2 = _interopRequireDefault(_track); 17324 17325var _utilsMergeOptions = _dereq_('../utils/merge-options'); 17326 17327var _utilsMergeOptions2 = _interopRequireDefault(_utilsMergeOptions); 17328 17329var _utilsBrowserJs = _dereq_('../utils/browser.js'); 17330 17331var browser = _interopRequireWildcard(_utilsBrowserJs); 17332 17333/** 17334 * A single audio text track as defined in: 17335 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack 17336 * 17337 * interface AudioTrack { 17338 * readonly attribute DOMString id; 17339 * readonly attribute DOMString kind; 17340 * readonly attribute DOMString label; 17341 * readonly attribute DOMString language; 17342 * attribute boolean enabled; 17343 * }; 17344 * 17345 * @param {Object=} options Object of option names and values 17346 * @class AudioTrack 17347 */ 17348 17349var AudioTrack = (function (_Track) { 17350 _inherits(AudioTrack, _Track); 17351 17352 function AudioTrack() { 17353 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 17354 17355 _classCallCheck(this, AudioTrack); 17356 17357 var settings = _utilsMergeOptions2['default'](options, { 17358 kind: _trackEnums.AudioTrackKind[options.kind] || '' 17359 }); 17360 // on IE8 this will be a document element 17361 // for every other browser this will be a normal object 17362 var track = _Track.call(this, settings); 17363 var enabled = false; 17364 17365 if (browser.IS_IE8) { 17366 for (var prop in AudioTrack.prototype) { 17367 if (prop !== 'constructor') { 17368 track[prop] = AudioTrack.prototype[prop]; 17369 } 17370 } 17371 } 17372 17373 Object.defineProperty(track, 'enabled', { 17374 get: function get() { 17375 return enabled; 17376 }, 17377 set: function set(newEnabled) { 17378 // an invalid or unchanged value 17379 if (typeof newEnabled !== 'boolean' || newEnabled === enabled) { 17380 return; 17381 } 17382 enabled = newEnabled; 17383 this.trigger('enabledchange'); 17384 } 17385 }); 17386 17387 // if the user sets this track to selected then 17388 // set selected to that true value otherwise 17389 // we keep it false 17390 if (settings.enabled) { 17391 track.enabled = settings.enabled; 17392 } 17393 track.loaded_ = true; 17394 17395 return track; 17396 } 17397 17398 return AudioTrack; 17399})(_track2['default']); 17400 17401exports['default'] = AudioTrack; 17402module.exports = exports['default']; 17403 17404},{"../utils/browser.js":140,"../utils/merge-options":149,"./track":137,"./track-enums":135}],127:[function(_dereq_,module,exports){ 17405/** 17406 * @file html-track-element-list.js 17407 */ 17408 17409'use strict'; 17410 17411exports.__esModule = true; 17412 17413function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 17414 17415function _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; } } 17416 17417function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 17418 17419var _utilsBrowserJs = _dereq_('../utils/browser.js'); 17420 17421var browser = _interopRequireWildcard(_utilsBrowserJs); 17422 17423var _globalDocument = _dereq_('global/document'); 17424 17425var _globalDocument2 = _interopRequireDefault(_globalDocument); 17426 17427var HtmlTrackElementList = (function () { 17428 function HtmlTrackElementList() { 17429 var trackElements = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; 17430 17431 _classCallCheck(this, HtmlTrackElementList); 17432 17433 var list = this; 17434 17435 if (browser.IS_IE8) { 17436 list = _globalDocument2['default'].createElement('custom'); 17437 17438 for (var prop in HtmlTrackElementList.prototype) { 17439 if (prop !== 'constructor') { 17440 list[prop] = HtmlTrackElementList.prototype[prop]; 17441 } 17442 } 17443 } 17444 17445 list.trackElements_ = []; 17446 17447 Object.defineProperty(list, 'length', { 17448 get: function get() { 17449 return this.trackElements_.length; 17450 } 17451 }); 17452 17453 for (var i = 0, _length = trackElements.length; i < _length; i++) { 17454 list.addTrackElement_(trackElements[i]); 17455 } 17456 17457 if (browser.IS_IE8) { 17458 return list; 17459 } 17460 } 17461 17462 HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) {
17463 this.trackElements_.push(trackElement); 17464 }; 17465 17466 HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) { 17467 var trackElement_ = undefined; 17468 17469 for (var i = 0, _length2 = this.trackElements_.length; i < _length2; i++) { 17470 if (track === this.trackElements_[i].track) { 17471 trackElement_ = this.trackElements_[i]; 17472 17473 break; 17474 } 17475 } 17476 17477 return trackElement_; 17478 }; 17479 17480 HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) { 17481 for (var i = 0, _length3 = this.trackElements_.length; i < _length3; i++) { 17482 if (trackElement === this.trackElements_[i]) { 17483 this.trackElements_.splice(i, 1); 17484 17485 break; 17486 } 17487 } 17488 }; 17489 17490 return HtmlTrackElementList; 17491})(); 17492 17493exports['default'] = HtmlTrackElementList; 17494module.exports = exports['default']; 17495 17496},{"../utils/browser.js":140,"global/document":1}],128:[function(_dereq_,module,exports){ 17497/** 17498 * @file html-track-element.js 17499 */ 17500 17501'use strict'; 17502 17503exports.__esModule = true; 17504 17505function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 17506 17507function _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; } } 17508 17509function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 17510 17511function _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; } 17512 17513var _utilsBrowserJs = _dereq_('../utils/browser.js'); 17514 17515var browser = _interopRequireWildcard(_utilsBrowserJs); 17516 17517var _globalDocument = _dereq_('global/document'); 17518 17519var _globalDocument2 = _interopRequireDefault(_globalDocument); 17520 17521var _eventTarget = _dereq_('../event-target'); 17522 17523var _eventTarget2 = _interopRequireDefault(_eventTarget); 17524 17525var _tracksTextTrack = _dereq_('../tracks/text-track'); 17526 17527var _tracksTextTrack2 = _interopRequireDefault(_tracksTextTrack); 17528 17529var NONE = 0; 17530var LOADING = 1; 17531var LOADED = 2; 17532var ERROR = 3; 17533 17534/** 17535 * https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement 17536 * 17537 * interface HTMLTrackElement : HTMLElement { 17538 * attribute DOMString kind; 17539 * attribute DOMString src; 17540 * attribute DOMString srclang; 17541 * attribute DOMString label; 17542 * attribute boolean default; 17543 * 17544 * const unsigned short NONE = 0; 17545 * const unsigned short LOADING = 1; 17546 * const unsigned short LOADED = 2; 17547 * const unsigned short ERROR = 3; 17548 * readonly attribute unsigned short readyState; 17549 * 17550 * readonly attribute TextTrack track; 17551 * }; 17552 * 17553 * @param {Object} options TextTrack configuration 17554 * @class HTMLTrackElement 17555 */ 17556 17557var HTMLTrackElement = (function (_EventTarget) { 17558 _inherits(HTMLTrackElement, _EventTarget); 17559 17560 function HTMLTrackElement() { 17561 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 17562 17563 _classCallCheck(this, HTMLTrackElement); 17564 17565 _EventTarget.call(this); 17566 17567 var readyState = undefined, 17568 trackElement = this; 17569 17570 if (browser.IS_IE8) { 17571 trackElement = _globalDocument2['default'].createElement('custom'); 17572 17573 for (var prop in HTMLTrackElement.prototype) { 17574 if (prop !== 'constructor') { 17575 trackElement[prop] = HTMLTrackElement.prototype[prop]; 17576 } 17577 } 17578 } 17579 17580 var track = new _tracksTextTrack2['default'](options); 17581 17582 trackElement.kind = track.kind; 17583 trackElement.src = track.src; 17584 trackElement.srclang = track.language; 17585 trackElement.label = track.label; 17586 trackElement['default'] = track['default']; 17587 17588 Object.defineProperty(trackElement, 'readyState', { 17589 get: function get() { 17590 return readyState; 17591 } 17592 }); 17593 17594 Object.defineProperty(trackElement, 'track', { 17595 get: function get() { 17596 return track; 17597 } 17598 }); 17599 17600 readyState = NONE; 17601 17602 track.addEventListener('loadeddata', function () { 17603 readyState = LOADED; 17604 17605 trackElement.trigger({ 17606 type: 'load', 17607 target: trackElement 17608 }); 17609 }); 17610 17611 if (browser.IS_IE8) { 17612 return trackElement; 17613 } 17614 } 17615 17616 return HTMLTrackElement; 17617})(_eventTarget2['default']); 17618 17619HTMLTrackElement.prototype.allowedEvents_ = { 17620 load: 'load' 17621}; 17622 17623HTMLTrackElement.NONE = NONE; 17624HTMLTrackElement.LOADING = LOADING; 17625HTMLTrackElement.LOADED = LOADED; 17626HTMLTrackElement.ERROR = ERROR; 17627 17628exports['default'] = HTMLTrackElement; 17629module.exports = exports['default']; 17630 17631},{"../event-target":104,"../tracks/text-track":134,"../utils/browser.js":140,"global/document":1}],129:[function(_dereq_,module,exports){ 17632/** 17633 * @file text-track-cue-list.js 17634 */ 17635'use strict'; 17636 17637exports.__esModule = true; 17638 17639function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 17640 17641function _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; } } 17642 17643function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 17644 17645var _utilsBrowserJs = _dereq_('../utils/browser.js'); 17646 17647var browser = _interopRequireWildcard(_utilsBrowserJs); 17648 17649var _globalDocument = _dereq_('global/document'); 17650 17651var _globalDocument2 = _interopRequireDefault(_globalDocument); 17652 17653/** 17654 * A List of text track cues as defined in: 17655 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist 17656 * 17657 * interface TextTrackCueList { 17658 * readonly attribute unsigned long length; 17659 * getter TextTrackCue (unsigned long index); 17660 * TextTrackCue? getCueById(DOMString id); 17661 * }; 17662 * 17663 * @param {Array} cues A list of cues to be initialized with 17664 * @class TextTrackCueList 17665 */ 17666 17667var TextTrackCueList = (function () { 17668 function TextTrackCueList(cues) { 17669 _classCallCheck(this, TextTrackCueList); 17670 17671 var list = this; 17672 17673 if (browser.IS_IE8) { 17674 list = _globalDocument2['default'].createElement('custom'); 17675 17676 for (var prop in TextTrackCueList.prototype) { 17677 if (prop !== 'constructor') { 17678 list[prop] = TextTrackCueList.prototype[prop]; 17679 } 17680 } 17681 } 17682 17683 TextTrackCueList.prototype.setCues_.call(list, cues); 17684 17685 Object.defineProperty(list, 'length', { 17686 get: function get() { 17687 return this.length_; 17688 } 17689 }); 17690 17691 if (browser.IS_IE8) { 17692 return list; 17693 } 17694 } 17695 17696 /** 17697 * A setter for cues in this list 17698 * 17699 * @param {Array} cues an array of cues 17700 * @method setCues_ 17701 * @private 17702 */ 17703 17704 TextTrackCueList.prototype.setCues_ = function setCues_(cues) { 17705 var oldLength = this.length || 0; 17706 var i = 0; 17707 var l = cues.length; 17708 17709 this.cues_ = cues; 17710 this.length_ = cues.length; 17711 17712 var defineProp = function defineProp(index) { 17713 if (!('' + index in this)) { 17714 Object.defineProperty(this, '' + index, { 17715 get: function get() { 17716 return this.cues_[index]; 17717 } 17718 }); 17719 } 17720 }; 17721 17722 if (oldLength < l) { 17723 i = oldLength; 17724 17725 for (; i < l; i++) { 17726 defineProp.call(this, i); 17727 } 17728 } 17729 }; 17730 17731 /** 17732 * Get a cue that is currently in the Cue list by id 17733 * 17734 * @param {String} id 17735 * @method getCueById 17736 * @return {Object} a single cue 17737 */ 17738 17739 TextTrackCueList.prototype.getCueById = function getCueById(id) { 17740 var result = null; 17741 17742 for (var i = 0, l = this.length; i < l; i++) { 17743 var cue = this[i]; 17744 17745 if (cue.id === id) { 17746 result = cue; 17747 break; 17748 } 17749 } 17750 17751 return result; 17752 }; 17753 17754 return TextTrackCueList; 17755})(); 17756 17757exports['default'] = TextTrackCueList; 17758module.exports = exports['default']; 17759 17760},{"../utils/browser.js":140,"global/document":1}],130:[function(_dereq_,module,exports){ 17761/** 17762 * @file text-track-display.js 17763 */ 17764'use strict'; 17765 17766exports.__esModule = true; 17767 17768function _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; } } 17769 17770function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 17771 17772function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 17773 17774function _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
17774onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 17775 17776var _component = _dereq_('../component'); 17777 17778var _component2 = _interopRequireDefault(_component); 17779 17780var _menuMenuJs = _dereq_('../menu/menu.js'); 17781 17782var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs); 17783 17784var _menuMenuItemJs = _dereq_('../menu/menu-item.js'); 17785 17786var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs); 17787 17788var _menuMenuButtonJs = _dereq_('../menu/menu-button.js'); 17789 17790var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs); 17791 17792var _utilsFnJs = _dereq_('../utils/fn.js'); 17793 17794var Fn = _interopRequireWildcard(_utilsFnJs); 17795 17796var _globalDocument = _dereq_('global/document'); 17797 17798var _globalDocument2 = _interopRequireDefault(_globalDocument); 17799 17800var _globalWindow = _dereq_('global/window'); 17801 17802var _globalWindow2 = _interopRequireDefault(_globalWindow); 17803 17804var darkGray = '#222'; 17805var lightGray = '#ccc'; 17806var fontMap = { 17807 monospace: 'monospace', 17808 sansSerif: 'sans-serif', 17809 serif: 'serif', 17810 monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace', 17811 monospaceSerif: '"Courier New", monospace', 17812 proportionalSansSerif: 'sans-serif', 17813 proportionalSerif: 'serif', 17814 casual: '"Comic Sans MS", Impact, fantasy', 17815 script: '"Monotype Corsiva", cursive', 17816 smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif' 17817}; 17818 17819/** 17820 * The component for displaying text track cues 17821 * 17822 * @param {Object} player Main Player 17823 * @param {Object=} options Object of option names and values 17824 * @param {Function=} ready Ready callback function 17825 * @extends Component 17826 * @class TextTrackDisplay 17827 */ 17828 17829var TextTrackDisplay = (function (_Component) { 17830 _inherits(TextTrackDisplay, _Component); 17831 17832 function TextTrackDisplay(player, options, ready) { 17833 _classCallCheck(this, TextTrackDisplay); 17834 17835 _Component.call(this, player, options, ready); 17836 17837 player.on('loadstart', Fn.bind(this, this.toggleDisplay)); 17838 player.on('texttrackchange', Fn.bind(this, this.updateDisplay)); 17839 17840 // This used to be called during player init, but was causing an error 17841 // if a track should show by default and the display hadn't loaded yet. 17842 // Should probably be moved to an external track loader when we support 17843 // tracks that don't need a display. 17844 player.ready(Fn.bind(this, function () { 17845 if (player.tech_ && player.tech_['featuresNativeTextTracks']) { 17846 this.hide(); 17847 return; 17848 } 17849 17850 player.on('fullscreenchange', Fn.bind(this, this.updateDisplay)); 17851 17852 var tracks = this.options_.playerOptions['tracks'] || []; 17853 for (var i = 0; i < tracks.length; i++) { 17854 var track = tracks[i]; 17855 this.player_.addRemoteTextTrack(track); 17856 } 17857 17858 var modes = { 'captions': 1, 'subtitles': 1 }; 17859 var trackList = this.player_.textTracks(); 17860 var firstDesc = undefined; 17861 var firstCaptions = undefined; 17862 17863 if (trackList) { 17864 for (var i = 0; i < trackList.length; i++) { 17865 var track = trackList[i]; 17866 if (track['default']) { 17867 if (track.kind === 'descriptions' && !firstDesc) { 17868 firstDesc = track; 17869 } else if (track.kind in modes && !firstCaptions) { 17870 firstCaptions = track; 17871 } 17872 } 17873 } 17874 17875 // We want to show the first default track but captions and subtitles 17876 // take precedence over descriptions. 17877 // So, display the first default captions or subtitles track 17878 // and otherwise the first default descriptions track. 17879 if (firstCaptions) { 17880 firstCaptions.mode = 'showing'; 17881 } else if (firstDesc) { 17882 firstDesc.mode = 'showing'; 17883 } 17884 } 17885 })); 17886 } 17887 17888 /** 17889 * Add cue HTML to display 17890 * 17891 * @param {Number} color Hex number for color, like #f0e 17892 * @param {Number} opacity Value for opacity,0.0 - 1.0 17893 * @return {RGBAColor} In the form 'rgba(255, 0, 0, 0.3)' 17894 * @method constructColor 17895 */ 17896 17897 /** 17898 * Toggle display texttracks 17899 * 17900 * @method toggleDisplay 17901 */ 17902 17903 TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() { 17904 if (this.player_.tech_ && this.player_.tech_['featuresNativeTextTracks']) { 17905 this.hide(); 17906 } else { 17907 this.show(); 17908 } 17909 }; 17910 17911 /** 17912 * Create the component's DOM element 17913 * 17914 * @return {Element} 17915 * @method createEl 17916 */ 17917 17918 TextTrackDisplay.prototype.createEl = function createEl() { 17919 return _Component.prototype.createEl.call(this, 'div', { 17920 className: 'vjs-text-track-display' 17921 }, {
17922 'aria-live': 'assertive', 17923 'aria-atomic': 'true' 17924 }); 17925 }; 17926 17927 /** 17928 * Clear display texttracks 17929 * 17930 * @method clearDisplay 17931 */ 17932 17933 TextTrackDisplay.prototype.clearDisplay = function clearDisplay() { 17934 if (typeof _globalWindow2['default']['WebVTT'] === 'function') { 17935 _globalWindow2['default']['WebVTT']['processCues'](_globalWindow2['default'], [], this.el_); 17936 } 17937 }; 17938 17939 /** 17940 * Update display texttracks 17941 * 17942 * @method updateDisplay 17943 */ 17944 17945 TextTrackDisplay.prototype.updateDisplay = function updateDisplay() { 17946 var tracks = this.player_.textTracks(); 17947 17948 this.clearDisplay(); 17949 17950 if (!tracks) { 17951 return; 17952 } 17953 17954 // Track display prioritization model: if multiple tracks are 'showing', 17955 // display the first 'subtitles' or 'captions' track which is 'showing', 17956 // otherwise display the first 'descriptions' track which is 'showing' 17957 17958 var descriptionsTrack = null; 17959 var captionsSubtitlesTrack = null; 17960 17961 var i = tracks.length; 17962 while (i--) { 17963 var track = tracks[i]; 17964 if (track['mode'] === 'showing') { 17965 if (track['kind'] === 'descriptions') { 17966 descriptionsTrack = track; 17967 } else { 17968 captionsSubtitlesTrack = track; 17969 } 17970 } 17971 } 17972 17973 if (captionsSubtitlesTrack) { 17974 this.updateForTrack(captionsSubtitlesTrack); 17975 } else if (descriptionsTrack) { 17976 this.updateForTrack(descriptionsTrack); 17977 } 17978 }; 17979 17980 /** 17981 * Add texttrack to texttrack list 17982 * 17983 * @param {TextTrackObject} track Texttrack object to be added to list 17984 * @method updateForTrack 17985 */ 17986 17987 TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) { 17988 if (typeof _globalWindow2['default']['WebVTT'] !== 'function' || !track['activeCues']) { 17989 return; 17990 } 17991 17992 var overrides = this.player_['textTrackSettings'].getValues(); 17993 17994 var cues = []; 17995 for (var _i = 0; _i < track['activeCues'].length; _i++) { 17996 cues.push(track['activeCues'][_i]); 17997 } 17998 17999 _globalWindow2['default']['WebVTT']['processCues'](_globalWindow2['default'], cues, this.el_); 18000 18001 var i = cues.length; 18002 while (i--) { 18003 var cue = cues[i]; 18004 if (!cue) { 18005 continue; 18006 } 18007 18008 var cueDiv = cue.displayState; 18009 if (overrides.color) { 18010 cueDiv.firstChild.style.color = overrides.color; 18011 } 18012 if (overrides.textOpacity) { 18013 tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity)); 18014 } 18015 if (overrides.backgroundColor) { 18016 cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor; 18017 } 18018 if (overrides.backgroundOpacity) { 18019 tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity)); 18020 } 18021 if (overrides.windowColor) { 18022 if (overrides.windowOpacity) { 18023 tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity)); 18024 } else { 18025 cueDiv.style.backgroundColor = overrides.windowColor; 18026 } 18027 } 18028 if (overrides.edgeStyle) { 18029 if (overrides.edgeStyle === 'dropshadow') { 18030 cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray; 18031 } else if (overrides.edgeStyle === 'raised') { 18032 cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray; 18033 } else if (overrides.edgeStyle === 'depressed') { 18034 cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray; 18035 } else if (overrides.edgeStyle === 'uniform') { 18036 cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray; 18037 } 18038 } 18039 if (overrides.fontPercent && overrides.fontPercent !== 1) { 18040 var fontSize = _globalWindow2['default'].parseFloat(cueDiv.style.fontSize); 18041 cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px'; 18042 cueDiv.style.height = 'auto'; 18043 cueDiv.style.top = 'auto'; 18044 cueDiv.style.bottom = '2px'; 18045 } 18046 if (overrides.fontFamily && overrides.fontFamily !== 'default') { 18047 if (overrides.fontFamily === 'small-caps') { 18048 cueDiv.firstChild.style.fontVariant = 'small-caps'; 18049 } else { 18050 cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily]; 18051 } 18052 } 18053 } 18054 }; 18055 18056 return TextTrackDisplay; 18057})(_component2['default']); 18058 18059function constructColor(color, opacity) { 18060 return 'rgba(' + 18061 // color looks like "#f0e" 18062 parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')'; 18063} 18064 18065/** 18066 * Try to update style 18067 * Some style changes will throw an error, particularly in IE8. Those should be noops. 18068 * 18069 * @param {Element} el The element to be styles 18070 * @param {CSSProperty} style The CSS property to be styled 18071 * @param {CSSStyle} rule The actual style to be applied to the property 18072 * @method tryUpdateStyle 18073 */ 18074function tryUpdateStyle(el, style, rule) { 18075 // 18076 try { 18077 el.style[style] = rule; 18078 } catch (e) {} 18079} 18080 18081_component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay); 18082exports['default'] = TextTrackDisplay; 18083module.exports = exports['default']; 18084 18085},{"../component":67,"../menu/menu-button.js":109,"../menu/menu-item.js":110,"../menu/menu.js":111,"../utils/fn.js":145,"global/document":1,"global/window":2}],131:[function(_dereq_,module,exports){ 18086/** 18087 * Utilities for capturing text track state and re-creating tracks 18088 * based on a capture. 18089 * 18090 * @file text-track-list-converter.js 18091 */ 18092 18093/**
18094 * Examine a single text track and return a JSON-compatible javascript 18095 * object that represents the text track's state. 18096 * @param track {TextTrackObject} the text track to query 18097 * @return {Object} a serializable javascript representation of the 18098 * @private 18099 */ 18100'use strict'; 18101 18102exports.__esModule = true; 18103var trackToJson_ = function trackToJson_(track) { 18104 var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) { 18105 if (track[prop]) { 18106 acc[prop] = track[prop]; 18107 } 18108 18109 return acc; 18110 }, { 18111 cues: track.cues && Array.prototype.map.call(track.cues, function (cue) { 18112 return { 18113 startTime: cue.startTime, 18114 endTime: cue.endTime, 18115 text: cue.text, 18116 id: cue.id 18117 }; 18118 }) 18119 }); 18120 18121 return ret; 18122}; 18123 18124/** 18125 * Examine a tech and return a JSON-compatible javascript array that 18126 * represents the state of all text tracks currently configured. The 18127 * return array is compatible with `jsonToTextTracks`. 18128 * @param tech {tech} the tech object to query 18129 * @return {Array} a serializable javascript representation of the 18130 * @function textTracksToJson 18131 */ 18132var textTracksToJson = function textTracksToJson(tech) { 18133 18134 var trackEls = tech.$$('track'); 18135 18136 var trackObjs = Array.prototype.map.call(trackEls, function (t) { 18137 return t.track; 18138 }); 18139 var tracks = Array.prototype.map.call(trackEls, function (trackEl) { 18140 var json = trackToJson_(trackEl.track); 18141 if (trackEl.src) { 18142 json.src = trackEl.src; 18143 } 18144 return json; 18145 }); 18146 18147 return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) { 18148 return trackObjs.indexOf(track) === -1; 18149 }).map(trackToJson_)); 18150}; 18151 18152/** 18153 * Creates a set of remote text tracks on a tech based on an array of 18154 * javascript text track representations. 18155 * @param json {Array} an array of text track representation objects, 18156 * like those that would be produced by `textTracksToJson` 18157 * @param tech {tech} the tech to create text tracks on 18158 * @function jsonToTextTracks 18159 */ 18160var jsonToTextTracks = function jsonToTextTracks(json, tech) { 18161 json.forEach(function (track) { 18162 var addedTrack = tech.addRemoteTextTrack(track).track; 18163 if (!track.src && track.cues) { 18164 track.cues.forEach(function (cue) { 18165 return addedTrack.addCue(cue); 18166 }); 18167 } 18168 }); 18169 18170 return tech.textTracks(); 18171}; 18172 18173exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ }; 18174module.exports = exports['default']; 18175 18176},{}],132:[function(_dereq_,module,exports){ 18177/** 18178 * @file text-track-list.js 18179 */ 18180'use strict'; 18181 18182exports.__esModule = true; 18183 18184function _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; } } 18185 18186function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18187 18188function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 18189 18190function _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; } 18191 18192var _trackList = _dereq_('./track-list'); 18193 18194var _trackList2 = _interopRequireDefault(_trackList); 18195 18196var _utilsFnJs = _dereq_('../utils/fn.js'); 18197 18198var Fn = _interopRequireWildcard(_utilsFnJs); 18199 18200var _utilsBrowserJs = _dereq_('../utils/browser.js'); 18201 18202var browser = _interopRequireWildcard(_utilsBrowserJs); 18203 18204var _globalDocument = _dereq_('global/document'); 18205 18206var _globalDocument2 = _interopRequireDefault(_globalDocument); 18207 18208/** 18209 * A list of possible text tracks. All functionality is in the 18210 * base class TrackList. The spec for TextTrackList is located at: 18211 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist 18212 * 18213 * interface TextTrackList : EventTarget { 18214 * readonly attribute unsigned long length; 18215 * getter TextTrack (unsigned long index); 18216 * TextTrack? getTrackById(DOMString id); 18217 * 18218 * attribute EventHandler onchange; 18219 * attribute EventHandler onaddtrack; 18220 * attribute EventHandler onremovetrack; 18221 * }; 18222 * 18223 * @param {TextTrack[]} tracks A list of tracks to initialize the list with 18224 * @extends TrackList 18225 * @class TextTrackList 18226 */ 18227 18228var TextTrackList = (function (_TrackList) { 18229 _inherits(TextTrackList, _TrackList); 18230 18231 function TextTrackList() { 18232 var tracks = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; 18233 18234 _classCallCheck(this, TextTrackList); 18235 18236 var list = undefined; 18237 18238 // IE8 forces us to implement inheritance ourselves 18239 // as it does not support Object.defineProperty properly 18240 if (browser.IS_IE8) { 18241 list = _globalDocument2['default'].createElement('custom'); 18242 for (var prop in _trackList2['default'].prototype) { 18243 if (prop !== 'constructor') { 18244 list[prop] = _trackList2['default'].prototype[prop]; 18245 } 18246 } 18247 for (var prop in TextTrackList.prototype) { 18248 if (prop !== 'constructor') { 18249 list[prop] = TextTrackList.prototype[prop]; 18250 } 18251 } 18252 } 18253 18254 list = _TrackList.call(this, tracks, list); 18255 return list; 18256 } 18257 18258 TextTrackList.prototype.addTrack_ = function addTrack_(track) { 18259 _TrackList.prototype.addTrack_.call(this, track); 18260 track.addEventListener('modechange', Fn.bind(this, function () { 18261 this.trigger('change'); 18262 })); 18263 }; 18264 18265 /** 18266 * Remove TextTrack from TextTrackList 18267 * NOTE: Be mindful of what is passed in as it may be a HTMLTrackElement 18268 * 18269 * @param {TextTrack} rtrack 18270 * @method removeTrack_ 18271 * @private 18272 */ 18273 18274 TextTrackList.prototype.removeTrack_ = function removeTrack_(rtrack) { 18275 var track = undefined; 18276 18277 for (var i = 0, l = this.length; i < l; i++) { 18278 if (this[i] === rtrack) { 18279 track = this[i]; 18280 if (track.off) { 18281 track.off(); 18282 } 18283 18284 this.tracks_.splice(i, 1); 18285 18286 break; 18287 } 18288 } 18289 18290 if (!track) { 18291 return; 18292 } 18293 18294 this.trigger({ 18295 track: track, 18296 type: 'removetrack' 18297 }); 18298 }; 18299 18300 /** 18301 * Get a TextTrack from TextTrackList by a tracks id 18302 * 18303 * @param {String} id - the id of the track to get 18304 * @method getTrackById 18305 * @return {TextTrack} 18306 * @private 18307 */ 18308 18309 TextTrackList.prototype.getTrackById = function getTrackById(id) { 18310 var result = null; 18311 18312 for (var i = 0, l = this.length; i < l; i++) { 18313 var track = this[i]; 18314 18315 if (track.id === id) { 18316 result = track; 18317 break; 18318 } 18319 } 18320 18321 return result; 18322 }; 18323 18324 return TextTrackList; 18325})(_trackList2['default']); 18326 18327exports['default'] = TextTrackList; 18328module.exports = exports['default']; 18329 18330},{"../utils/browser.js":140,"../utils/fn.js":145,"./track-list":136,"global/document":1}],133:[function(_dereq_,module,exports){ 18331/** 18332 * @file text-track-settings.js 18333 */ 18334'use strict'; 18335 18336exports.__esModule = true; 18337 18338function _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; } } 18339 18340function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18341 18342function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 18343 18344function _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
18344onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 18345 18346var _component = _dereq_('../component'); 18347 18348var _component2 = _interopRequireDefault(_component); 18349 18350var _utilsEventsJs = _dereq_('../utils/events.js'); 18351 18352var Events = _interopRequireWildcard(_utilsEventsJs); 18353 18354var _utilsFnJs = _dereq_('../utils/fn.js'); 18355 18356var Fn = _interopRequireWildcard(_utilsFnJs); 18357 18358var _utilsLogJs = _dereq_('../utils/log.js'); 18359 18360var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 18361 18362var _safeJsonParseTuple = _dereq_('safe-json-parse/tuple'); 18363 18364var _safeJsonParseTuple2 = _interopRequireDefault(_safeJsonParseTuple); 18365 18366var _globalWindow = _dereq_('global/window'); 18367 18368var _globalWindow2 = _interopRequireDefault(_globalWindow); 18369 18370/** 18371 * Manipulate settings of texttracks 18372 * 18373 * @param {Object} player Main Player 18374 * @param {Object=} options Object of option names and values 18375 * @extends Component 18376 * @class TextTrackSettings 18377 */ 18378 18379var TextTrackSettings = (function (_Component) { 18380 _inherits(TextTrackSettings, _Component); 18381 18382 function TextTrackSettings(player, options) { 18383 _classCallCheck(this, TextTrackSettings); 18384 18385 _Component.call(this, player, options); 18386 this.hide(); 18387 18388 // Grab `persistTextTrackSettings` from the player options if not passed in child options 18389 if (options.persistTextTrackSettings === undefined) { 18390 this.options_.persistTextTrackSettings = this.options_.playerOptions.persistTextTrackSettings; 18391 } 18392 18393 Events.on(this.$('.vjs-done-button'), 'click', Fn.bind(this, function () { 18394 this.saveSettings(); 18395 this.hide(); 18396 })); 18397 18398 Events.on(this.$('.vjs-default-button'), 'click', Fn.bind(this, function () { 18399 this.$('.vjs-fg-color > select').selectedIndex = 0; 18400 this.$('.vjs-bg-color > select').selectedIndex = 0; 18401 this.$('.window-color > select').selectedIndex = 0; 18402 this.$('.vjs-text-opacity > select').selectedIndex = 0; 18403 this.$('.vjs-bg-opacity > select').selectedIndex = 0; 18404 this.$('.vjs-window-opacity > select').selectedIndex = 0; 18405 this.$('.vjs-edge-style select').selectedIndex = 0; 18406 this.$('.vjs-font-family select').selectedIndex = 0; 18407 this.$('.vjs-font-percent select').selectedIndex = 2; 18408 this.updateDisplay(); 18409 })); 18410 18411 Events.on(this.$('.vjs-fg-color > select'), 'change', Fn.bind(this, this.updateDisplay)); 18412 Events.on(this.$('.vjs-bg-color > select'), 'change', Fn.bind(this, this.updateDisplay)); 18413 Events.on(this.$('.window-color > select'), 'change', Fn.bind(this, this.updateDisplay)); 18414 Events.on(this.$('.vjs-text-opacity > select'), 'change', Fn.bind(this, this.updateDisplay)); 18415 Events.on(this.$('.vjs-bg-opacity > select'), 'change', Fn.bind(this, this.updateDisplay)); 18416 Events.on(this.$('.vjs-window-opacity > select'), 'change', Fn.bind(this, this.updateDisplay)); 18417 Events.on(this.$('.vjs-font-percent select'), 'change', Fn.bind(this, this.updateDisplay)); 18418 Events.on(this.$('.vjs-edge-style select'), 'change', Fn.bind(this, this.updateDisplay)); 18419 Events.on(this.$('.vjs-font-family select'), 'change', Fn.bind(this, this.updateDisplay)); 18420 18421 if (this.options_.persistTextTrackSettings) { 18422 this.restoreSettings(); 18423 } 18424 } 18425 18426 /** 18427 * Create the component's DOM element 18428 * 18429 * @return {Element} 18430 * @method createEl 18431 */ 18432 18433 TextTrackSettings.prototype.createEl = function createEl() { 18434 return _Component.prototype.createEl.call(this, 'div', { 18435 className: 'vjs-caption-settings vjs-modal-overlay', 18436 innerHTML: captionOptionsMenuTemplate() 18437 }); 18438 }; 18439 18440 /** 18441 * Get texttrack settings 18442 * Settings are 18443 * .vjs-edge-style 18444 * .vjs-font-family 18445 * .vjs-fg-color 18446 * .vjs-text-opacity 18447 * .vjs-bg-color 18448 * .vjs-bg-opacity 18449 * .window-color 18450 * .vjs-window-opacity 18451 * 18452 * @return {Object} 18453 * @method getValues 18454 */ 18455 18456 TextTrackSettings.prototype.getValues = function getValues() { 18457 var textEdge = getSelectedOptionValue(this.$('.vjs-edge-style select')); 18458 var fontFamily = getSelectedOptionValue(this.$('.vjs-font-family select')); 18459 var fgColor = getSelectedOptionValue(this.$('.vjs-fg-color > select')); 18460 var textOpacity = getSelectedOptionValue(this.$('.vjs-text-opacity > select')); 18461 var bgColor = getSelectedOptionValue(this.$('.vjs-bg-color > select')); 18462 var bgOpacity = getSelectedOptionValue(this.$('.vjs-bg-opacity > select')); 18463 var windowColor = getSelectedOptionValue(this.$('.window-color > select')); 18464 var windowOpacity = getSelectedOptionValue(this.$('.vjs-window-opacity > select')); 18465 var fontPercent = _globalWindow2['default']['parseFloat'](getSelectedOptionValue(this.$('.vjs-font-percent > select'))); 18466 18467 var result = { 18468 'backgroundOpacity': bgOpacity, 18469 'textOpacity': textOpacity, 18470 'windowOpacity': windowOpacity, 18471 'edgeStyle': textEdge, 18472 'fontFamily': fontFamily, 18473 'color': fgColor, 18474 'backgroundColor': bgColor, 18475 'windowColor': windowColor, 18476 'fontPercent': fontPercent 18477 }; 18478 for (var _name in result) { 18479 if (result[_name] === '' || result[_name] === 'none' || _name === 'fontPercent' && result[_name] === 1.00) { 18480 delete result[_name]; 18481 } 18482 } 18483 return result; 18484 }; 18485 18486 /** 18487 * Set texttrack settings 18488 * Settings are 18489 * .vjs-edge-style 18490 * .vjs-font-family 18491 * .vjs-fg-color 18492 * .vjs-text-opacity 18493 * .vjs-bg-color 18494 * .vjs-bg-opacity 18495 * .window-color 18496 * .vjs-window-opacity 18497 * 18498 * @param {Object} values Object with texttrack setting values 18499 * @method setValues 18500 */ 18501 18502 TextTrackSettings.prototype.setValues = function setValues(values) { 18503 setSelectedOption(this.$('.vjs-edge-style select'), values.edgeStyle); 18504 setSelectedOption(this.$('.vjs-font-family select'), values.fontFamily); 18505 setSelectedOption(this.$('.vjs-fg-color > select'), values.color); 18506 setSelectedOption(this.$('.vjs-text-opacity > select'), values.textOpacity); 18507 setSelectedOption(this.$('.vjs-bg-color > select'), values.backgroundColor); 18508 setSelectedOption(this.$('.vjs-bg-opacity > select'), values.backgroundOpacity); 18509 setSelectedOption(this.$('.window-color > select'), values.windowColor); 18510 setSelectedOption(this.$('.vjs-window-opacity > select'), values.windowOpacity); 18511 18512 var fontPercent = values.fontPercent; 18513 18514 if (fontPercent) { 18515 fontPercent = fontPercent.toFixed(2); 18516 } 18517 18518 setSelectedOption(this.$('.vjs-font-percent > select'), fontPercent); 18519 }; 18520 18521 /** 18522 * Restore texttrack settings 18523 * 18524 * @method restoreSettings 18525 */ 18526 18527 TextTrackSettings.prototype.restoreSettings = function restoreSettings() { 18528 var err = undefined, 18529 values = undefined; 18530 18531 try { 18532 var _safeParseTuple = _safeJsonParseTuple2['default'](_globalWindow2['default'].localStorage.getItem('vjs-text-track-settings')); 18533 18534 err = _safeParseTuple[0]; 18535 values = _safeParseTuple[1]; 18536 18537 if (err) { 18538 _utilsLogJs2['default'].error(err); 18539 } 18540 } catch (e) { 18541 _utilsLogJs2['default'].warn(e); 18542 } 18543 18544 if (values) { 18545 this.setValues(values); 18546 } 18547 }; 18548 18549 /** 18550 * Save texttrack settings to local storage 18551 * 18552 * @method saveSettings 18553 */ 18554 18555 TextTrackSettings.prototype.saveSettings = function saveSettings() { 18556 if (!this.options_.persistTextTrackSettings) { 18557 return; 18558 } 18559 18560 var values = this.getValues(); 18561 try { 18562 if (Object.getOwnPropertyNames(values).length > 0) { 18563 _globalWindow2['default'].localStorage.setItem('vjs-text-track-settings', JSON.stringify(values)); 18564 } else { 18565 _globalWindow2['default'].localStorage.removeItem('vjs-text-track-settings'); 18566 } 18567 } catch (e) { 18568 _utilsLogJs2['default'].warn(e); 18569 } 18570 }; 18571 18572 /** 18573 * Update display of texttrack settings 18574 * 18575 * @method updateDisplay 18576 */ 18577 18578 TextTrackSettings.prototype.updateDisplay = function updateDisplay() { 18579 var ttDisplay = this.player_.getChild('textTrackDisplay'); 18580 if (ttDisplay) { 18581 ttDisplay.updateDisplay(); 18582 } 18583 }; 18584 18585 return TextTrackSettings; 18586})(_component2['default']); 18587 18588_component2['default'].registerComponent('TextTrackSettings', TextTrackSettings); 18589 18590function getSelectedOptionValue(target) { 18591 var selectedOption = undefined; 18592 // not all browsers support selectedOptions, so, fallback to options 18593 if (target.selectedOptions) { 18594 selectedOption = target.selectedOptions[0]; 18595 } else if (target.options) { 18596 selectedOption = target.options[target.options.selectedIndex]; 18597 } 18598 18599 return selectedOption.value; 18600} 18601 18602function setSelectedOption(target, value) { 18603 if (!value) { 18604 return; 18605 } 18606 18607 var i = undefined; 18608 for (i = 0; i < target.options.length; i++) { 18609 var option = target.options[i]; 18610 if (option.value === value) { 18611 break; 18612 } 18613 } 18614 18615 target.selectedIndex = i; 18616} 18617 18618function captionOptionsMenuTemplate() { 18619 var template = '<div class="vjs-tracksettings">\n <div class="vjs-tracksettings-colors">\n <div class="vjs-fg-color vjs-tracksetting">\n <label class="vjs-label">Foreground</label>\n <select>\n <option value="">---</option>\n <option value="#FFF">White</option>\n <option value="#000">Black</option>\n <option value="#F00">Red</option>\n <option value="#0F0">Green</option>\n <option value="#00F">Blue</option>\n <option value="#FF0">Yellow</option>\n <option value="#F0F">Magenta</option>\n <option value="#0FF">Cyan</option>\n </select>
18619\n <span class="vjs-text-opacity vjs-opacity">\n <select>\n <option value="">---</option>\n <option value="1">Opaque</option>\n <option value="0.5">Semi-Opaque</option>\n </select>\n </span>\n </div> <!-- vjs-fg-color -->\n <div class="vjs-bg-color vjs-tracksetting">\n <label class="vjs-label">Background</label>\n <select>\n <option value="">---</option>\n <option value="#FFF">White</option>\n <option value="#000">Black</option>\n <option value="#F00">Red</option>\n <option value="#0F0">Green</option>\n <option value="#00F">Blue</option>\n <option value="#FF0">Yellow</option>\n <option value="#F0F">Magenta</option>\n <option value="#0FF">Cyan</option>\n </select>\n <span class="vjs-bg-opacity vjs-opacity">\n <select>\n <option value="">---</option>\n <option value="1">Opaque</option>\n <option value="0.5">Semi-Transparent</option>\n <option value="0">Transparent</option>\n </select>\n </span>\n </div> <!-- vjs-bg-color -->\n <div class="window-color vjs-tracksetting">\n <label class="vjs-label">Window</label>\n <select>\n <option value="">---</option>\n <option value="#FFF">White</option>\n <option value="#000">Black</option>\n <option value="#F00">Red</option>\n <option value="#0F0">Green</option>\n <option value="#00F">Blue</option>\n <option value="#FF0">Yellow</option>\n <option value="#F0F">Magenta</option>\n <option value="#0FF">Cyan</option>\n </select>\n <span class="vjs-window-opacity vjs-opacity">\n <select>\n <option value="">---</option>\n <option value="1">Opaque</option>\n <option value="0.5">Semi-Transparent</option>\n <option value="0">Transparent</option>\n </select>\n </span>\n </div> <!-- vjs-window-color -->\n </div> <!-- vjs-tracksettings -->\n <div class="vjs-tracksettings-font">\n <div class="vjs-font-percent vjs-tracksetting">\n <label class="vjs-label">Font Size</label>\n <select>\n <option value="0.50">50%</option>\n <option value="0.75">75%</option>\n <option value="1.00" selected>100%</option>\n <option value="1.25">125%</option>\n <option value="1.50">150%</option>\n <option value="1.75">175%</option>\n <option value="2.00">200%</option>\n <option value="3.00">300%</option>\n <option value="4.00">400%</option>\n </select>\n </div> <!-- vjs-font-percent -->\n <div class="vjs-edge-style vjs-tracksetting">\n <label class="vjs-label">Text Edge Style</label>\n <select>\n <option value="none">None</option>\n <option value="raised">Raised</option>\n <option value="depressed">Depressed</option>\n <option value="uniform">Uniform</option>\n <option value="dropshadow">Dropshadow</option>\n </select>\n </div> <!-- vjs-edge-style -->\n <div class="vjs-font-family vjs-tracksetting">\n <label class="vjs-label">Font Family</label>\n <select>\n <option value="">Default</option>\n <option value="monospaceSerif">Monospace Serif</option>\n <option value="proportionalSerif">Proportional Serif</option>\n <option value="monospaceSansSerif">Monospace Sans-Serif</option>\n <option value="proportionalSansSerif">Proportional Sans-Serif</option>\n <option value="casual">Casual</option>\n <option value="script">Script</option>\n <option value="small-caps">Small Caps</option>\n </select>\n </div> <!-- vjs-font-family -->\n </div>\n </div>\n <div class="vjs-tracksettings-controls">\n <button class="vjs-default-button">Defaults</button>\n <button class="vjs-done-button">Done</button>\n </div>'; 18620 18621 return template; 18622} 18623 18624exports['default'] = TextTrackSettings; 18625module.exports = exports['default']; 18626 18627},{"../component":67,"../utils/events.js":144,"../utils/fn.js":145,"../utils/log.js":148,"global/window":2,"safe-json-parse/tuple":54}],134:[function(_dereq_,module,exports){ 18628/** 18629 * @file text-track.js 18630 */ 18631'use strict'; 18632 18633exports.__esModule = true; 18634 18635function _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; } } 18636 18637function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18638 18639function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 18640 18641function _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
18641onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 18642 18643var _textTrackCueList = _dereq_('./text-track-cue-list'); 18644 18645var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList); 18646 18647var _utilsFnJs = _dereq_('../utils/fn.js'); 18648 18649var Fn = _interopRequireWildcard(_utilsFnJs); 18650 18651var _trackEnums = _dereq_('./track-enums'); 18652 18653var _utilsLogJs = _dereq_('../utils/log.js'); 18654 18655var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 18656 18657var _globalDocument = _dereq_('global/document'); 18658 18659var _globalDocument2 = _interopRequireDefault(_globalDocument); 18660 18661var _globalWindow = _dereq_('global/window'); 18662 18663var _globalWindow2 = _interopRequireDefault(_globalWindow); 18664 18665var _trackJs = _dereq_('./track.js'); 18666 18667var _trackJs2 = _interopRequireDefault(_trackJs); 18668 18669var _utilsUrlJs = _dereq_('../utils/url.js'); 18670 18671var _xhr = _dereq_('xhr'); 18672 18673var _xhr2 = _interopRequireDefault(_xhr); 18674 18675var _utilsMergeOptions = _dereq_('../utils/merge-options'); 18676 18677var _utilsMergeOptions2 = _interopRequireDefault(_utilsMergeOptions); 18678 18679var _utilsBrowserJs = _dereq_('../utils/browser.js'); 18680 18681var browser = _interopRequireWildcard(_utilsBrowserJs); 18682 18683/** 18684 * takes a webvtt file contents and parses it into cues 18685 * 18686 * @param {String} srcContent webVTT file contents 18687 * @param {Track} track track to addcues to 18688 */ 18689var parseCues = function parseCues(srcContent, track) { 18690 var parser = new _globalWindow2['default'].WebVTT.Parser(_globalWindow2['default'], _globalWindow2['default'].vttjs, _globalWindow2['default'].WebVTT.StringDecoder()); 18691 var errors = []; 18692 18693 parser.oncue = function (cue) { 18694 track.addCue(cue); 18695 }; 18696 18697 parser.onparsingerror = function (error) { 18698 errors.push(error); 18699 }; 18700 18701 parser.onflush = function () { 18702 track.trigger({ 18703 type: 'loadeddata', 18704 target: track 18705 }); 18706 }; 18707 18708 parser.parse(srcContent); 18709 if (errors.length > 0) { 18710 if (console.groupCollapsed) { 18711 console.groupCollapsed('Text Track parsing errors for ' + track.src); 18712 } 18713 errors.forEach(function (error) { 18714 return _utilsLogJs2['default'].error(error); 18715 }); 18716 if (console.groupEnd) { 18717 console.groupEnd(); 18718 } 18719 } 18720 18721 parser.flush(); 18722}; 18723 18724/** 18725 * load a track from a specifed url 18726 * 18727 * @param {String} src url to load track from 18728 * @param {Track} track track to addcues to 18729 */ 18730var loadTrack = function loadTrack(src, track) { 18731 var opts = { 18732 uri: src 18733 }; 18734 var crossOrigin = _utilsUrlJs.isCrossOrigin(src); 18735 18736 if (crossOrigin) { 18737 opts.cors = crossOrigin; 18738 } 18739 18740 _xhr2['default'](opts, Fn.bind(this, function (err, response, responseBody) { 18741 if (err) { 18742 return _utilsLogJs2['default'].error(err, response); 18743 } 18744 18745 track.loaded_ = true; 18746 18747 // Make sure that vttjs has loaded, otherwise, wait till it finished loading 18748 // NOTE: this is only used for the alt/video.novtt.js build 18749 if (typeof _globalWindow2['default'].WebVTT !== 'function') { 18750 if (track.tech_) { 18751 (function () { 18752 var loadHandler = function loadHandler() { 18753 return parseCues(responseBody, track); 18754 }; 18755 track.tech_.on('vttjsloaded', loadHandler); 18756 track.tech_.on('vttjserror', function () { 18757 _utilsLogJs2['default'].error('vttjs failed to load, stopping trying to process ' + track.src); 18758 track.tech_.off('vttjsloaded', loadHandler); 18759 }); 18760 })(); 18761 } 18762 } else { 18763 parseCues(responseBody, track); 18764 } 18765 })); 18766}; 18767 18768/** 18769 * A single text track as defined in: 18770 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack 18771 * 18772 * interface TextTrack : EventTarget { 18773 * readonly attribute TextTrackKind kind; 18774 * readonly attribute DOMString label; 18775 * readonly attribute DOMString language; 18776 * 18777 * readonly attribute DOMString id; 18778 * readonly attribute DOMString inBandMetadataTrackDispatchType; 18779 * 18780 * attribute TextTrackMode mode; 18781 * 18782 * readonly attribute TextTrackCueList? cues; 18783 * readonly attribute TextTrackCueList? activeCues; 18784 * 18785 * void addCue(TextTrackCue cue); 18786 * void removeCue(TextTrackCue cue); 18787 * 18788 * attribute EventHandler oncuechange; 18789 * }; 18790 * 18791 * @param {Object=} options Object of option names and values 18792 * @extends Track 18793 * @class TextTrack 18794 */ 18795 18796var TextTrack = (function (_Track) { 18797 _inherits(TextTrack, _Track); 18798 18799 function TextTrack() { 18800 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 18801 18802 _classCallCheck(this, TextTrack); 18803 18804 if (!options.tech) {
18805 throw new Error('A tech was not provided.'); 18806 } 18807 18808 var settings = _utilsMergeOptions2['default'](options, { 18809 kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles', 18810 language: options.language || options.srclang || '' 18811 }); 18812 var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled'; 18813 var default_ = settings['default']; 18814 18815 if (settings.kind === 'metadata' || settings.kind === 'chapters') { 18816 mode = 'hidden'; 18817 } 18818 // on IE8 this will be a document element 18819 // for every other browser this will be a normal object 18820 var tt = _Track.call(this, settings); 18821 tt.tech_ = settings.tech; 18822 18823 if (browser.IS_IE8) { 18824 for (var prop in TextTrack.prototype) { 18825 if (prop !== 'constructor') { 18826 tt[prop] = TextTrack.prototype[prop]; 18827 } 18828 } 18829 } 18830 18831 tt.cues_ = []; 18832 tt.activeCues_ = []; 18833 18834 var cues = new _textTrackCueList2['default'](tt.cues_); 18835 var activeCues = new _textTrackCueList2['default'](tt.activeCues_); 18836 var changed = false; 18837 var timeupdateHandler = Fn.bind(tt, function () { 18838 this.activeCues; 18839 if (changed) { 18840 this.trigger('cuechange'); 18841 changed = false; 18842 } 18843 }); 18844 18845 if (mode !== 'disabled') { 18846 tt.tech_.on('timeupdate', timeupdateHandler); 18847 } 18848 18849 Object.defineProperty(tt, 'default', { 18850 get: function get() { 18851 return default_; 18852 }, 18853 set: function set() {} 18854 }); 18855 18856 Object.defineProperty(tt, 'mode', { 18857 get: function get() { 18858 return mode; 18859 }, 18860 set: function set(newMode) { 18861 if (!_trackEnums.TextTrackMode[newMode]) { 18862 return; 18863 } 18864 mode = newMode; 18865 if (mode === 'showing') { 18866 this.tech_.on('timeupdate', timeupdateHandler); 18867 } 18868 this.trigger('modechange'); 18869 } 18870 }); 18871 18872 Object.defineProperty(tt, 'cues', { 18873 get: function get() { 18874 if (!this.loaded_) { 18875 return null; 18876 } 18877 18878 return cues; 18879 }, 18880 set: function set() {} 18881 }); 18882 18883 Object.defineProperty(tt, 'activeCues', { 18884 get: function get() { 18885 if (!this.loaded_) { 18886 return null; 18887 } 18888 18889 // nothing to do 18890 if (this.cues.length === 0) { 18891 return activeCues; 18892 } 18893 18894 var ct = this.tech_.currentTime(); 18895 var active = []; 18896 18897 for (var i = 0, l = this.cues.length; i < l; i++) { 18898 var cue = this.cues[i]; 18899 18900 if (cue.startTime <= ct && cue.endTime >= ct) { 18901 active.push(cue); 18902 } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) { 18903 active.push(cue); 18904 } 18905 } 18906 18907 changed = false; 18908 18909 if (active.length !== this.activeCues_.length) { 18910 changed = true; 18911 } else { 18912 for (var i = 0; i < active.length; i++) { 18913 if (this.activeCues_.indexOf(active[i]) === -1) { 18914 changed = true; 18915 } 18916 } 18917 } 18918 18919 this.activeCues_ = active; 18920 activeCues.setCues_(this.activeCues_); 18921 18922 return activeCues; 18923 }, 18924 set: function set() {} 18925 }); 18926 18927 if (settings.src) { 18928 tt.src = settings.src; 18929 loadTrack(settings.src, tt); 18930 } else { 18931 tt.loaded_ = true; 18932 } 18933 18934 return tt; 18935 } 18936 18937 /** 18938 * cuechange - One or more cues in the track have become active or stopped being active. 18939 */ 18940 18941 /** 18942 * add a cue to the internal list of cues 18943 * 18944 * @param {Object} cue the cue to add to our internal list 18945 * @method addCue 18946 */ 18947 18948 TextTrack.prototype.addCue = function addCue(cue) { 18949 var tracks = this.tech_.textTracks(); 18950 18951 if (tracks) { 18952 for (var i = 0; i < tracks.length; i++) { 18953 if (tracks[i] !== this) { 18954 tracks[i].removeCue(cue); 18955 } 18956 } 18957 } 18958 18959 this.cues_.push(cue); 18960 this.cues.setCues_(this.cues_); 18961 }; 18962 18963 /** 18964 * remvoe a cue from our internal list 18965 * 18966 * @param {Object} removeCue the cue to remove from our internal list 18967 * @method removeCue 18968 */ 18969 18970 TextTrack.prototype.removeCue = function removeCue(_removeCue) { 18971 var removed = false;
18972 18973 for (var i = 0, l = this.cues_.length; i < l; i++) { 18974 var cue = this.cues_[i]; 18975 18976 if (cue === _removeCue) { 18977 this.cues_.splice(i, 1); 18978 removed = true; 18979 } 18980 } 18981 18982 if (removed) { 18983 this.cues.setCues_(this.cues_); 18984 } 18985 }; 18986 18987 return TextTrack; 18988})(_trackJs2['default']); 18989 18990TextTrack.prototype.allowedEvents_ = { 18991 cuechange: 'cuechange' 18992}; 18993 18994exports['default'] = TextTrack; 18995module.exports = exports['default']; 18996 18997},{"../utils/browser.js":140,"../utils/fn.js":145,"../utils/log.js":148,"../utils/merge-options":149,"../utils/url.js":153,"./text-track-cue-list":129,"./track-enums":135,"./track.js":137,"global/document":1,"global/window":2,"xhr":56}],135:[function(_dereq_,module,exports){ 18998/** 18999 * @file track-kinds.js 19000 */ 19001 19002/** 19003 * https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind 19004 * 19005 * enum VideoTrackKind { 19006 * "alternative", 19007 * "captions", 19008 * "main", 19009 * "sign", 19010 * "subtitles", 19011 * "commentary", 19012 * "", 19013 * }; 19014 */ 19015'use strict'; 19016 19017exports.__esModule = true; 19018var VideoTrackKind = { 19019 alternative: 'alternative', 19020 captions: 'captions', 19021 main: 'main', 19022 sign: 'sign', 19023 subtitles: 'subtitles', 19024 commentary: 'commentary' 19025}; 19026 19027/** 19028 * https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind 19029 * 19030 * enum AudioTrackKind { 19031 * "alternative", 19032 * "descriptions", 19033 * "main", 19034 * "main-desc", 19035 * "translation", 19036 * "commentary", 19037 * "", 19038 * }; 19039 */ 19040var AudioTrackKind = { 19041 alternative: 'alternative', 19042 descriptions: 'descriptions', 19043 main: 'main', 19044 'main-desc': 'main-desc', 19045 translation: 'translation', 19046 commentary: 'commentary' 19047}; 19048 19049/** 19050 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackkind 19051 * 19052 * enum TextTrackKind { 19053 * "subtitles", 19054 * "captions", 19055 * "descriptions", 19056 * "chapters", 19057 * "metadata" 19058 * }; 19059 */ 19060var TextTrackKind = { 19061 subtitles: 'subtitles', 19062 captions: 'captions', 19063 descriptions: 'descriptions', 19064 chapters: 'chapters', 19065 metadata: 'metadata' 19066}; 19067 19068/** 19069 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode 19070 * 19071 * enum TextTrackMode { "disabled", "hidden", "showing" }; 19072 */ 19073var TextTrackMode = { 19074 disabled: 'disabled', 19075 hidden: 'hidden', 19076 showing: 'showing' 19077}; 19078 19079/* jshint ignore:start */ 19080// we ignore jshint here because it does not see 19081// AudioTrackKind as defined here 19082exports['default'] = { VideoTrackKind: VideoTrackKind, AudioTrackKind: AudioTrackKind, TextTrackKind: TextTrackKind, TextTrackMode: TextTrackMode }; 19083 19084/* jshint ignore:end */ 19085module.exports = exports['default']; 19086 19087},{}],136:[function(_dereq_,module,exports){ 19088/** 19089 * @file track-list.js 19090 */ 19091'use strict'; 19092 19093exports.__esModule = true; 19094 19095function _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; } } 19096 19097function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19098 19099function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 19100 19101function _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; } 19102 19103var _eventTarget = _dereq_('../event-target'); 19104 19105var _eventTarget2 = _interopRequireDefault(_eventTarget); 19106 19107var _utilsFnJs = _dereq_('../utils/fn.js'); 19108 19109var Fn = _interopRequireWildcard(_utilsFnJs); 19110 19111var _utilsBrowserJs = _dereq_('../utils/browser.js'); 19112 19113var browser = _interopRequireWildcard(_utilsBrowserJs); 19114 19115var _globalDocument = _dereq_('global/document'); 19116 19117var _globalDocument2 = _interopRequireDefault(_globalDocument); 19118 19119/** 19120 * Common functionaliy between Text, Audio, and Video TrackLists 19121 * Interfaces defined in the following spec: 19122 * @link https://html.spec.whatwg.org/multipage/embedded-content.html 19123 * 19124 * @param {Track[]} tracks A list of tracks to initialize the list with 19125 * @param {Object} list the child object with inheritance done manually for ie8
19126 * @extends EventTarget 19127 * @class TrackList 19128 */ 19129 19130var TrackList = (function (_EventTarget) { 19131 _inherits(TrackList, _EventTarget); 19132 19133 function TrackList() { 19134 var tracks = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; 19135 var list = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; 19136 19137 _classCallCheck(this, TrackList); 19138 19139 _EventTarget.call(this); 19140 if (!list) { 19141 list = this; 19142 if (browser.IS_IE8) { 19143 list = _globalDocument2['default'].createElement('custom'); 19144 for (var prop in TrackList.prototype) { 19145 if (prop !== 'constructor') { 19146 list[prop] = TrackList.prototype[prop]; 19147 } 19148 } 19149 } 19150 } 19151 19152 list.tracks_ = []; 19153 Object.defineProperty(list, 'length', { 19154 get: function get() { 19155 return this.tracks_.length; 19156 } 19157 }); 19158 19159 for (var i = 0; i < tracks.length; i++) { 19160 list.addTrack_(tracks[i]); 19161 } 19162 19163 return list; 19164 } 19165 19166 /** 19167 * change - One or more tracks in the track list have been enabled or disabled. 19168 * addtrack - A track has been added to the track list. 19169 * removetrack - A track has been removed from the track list. 19170 */ 19171 19172 /** 19173 * Add a Track from TrackList 19174 * 19175 * @param {Mixed} track 19176 * @method addTrack_ 19177 * @private 19178 */ 19179 19180 TrackList.prototype.addTrack_ = function addTrack_(track) { 19181 var index = this.tracks_.length; 19182 19183 if (!('' + index in this)) { 19184 Object.defineProperty(this, index, { 19185 get: function get() { 19186 return this.tracks_[index]; 19187 } 19188 }); 19189 } 19190 19191 // Do not add duplicate tracks 19192 if (this.tracks_.indexOf(track) === -1) { 19193 this.tracks_.push(track); 19194 this.trigger({ 19195 track: track, 19196 type: 'addtrack' 19197 }); 19198 } 19199 }; 19200 19201 /** 19202 * Remove a Track from TrackList 19203 * 19204 * @param {Track} rtrack track to be removed 19205 * @method removeTrack_ 19206 * @private 19207 */ 19208 19209 TrackList.prototype.removeTrack_ = function removeTrack_(rtrack) { 19210 var track = undefined; 19211 19212 for (var i = 0, l = this.length; i < l; i++) { 19213 if (this[i] === rtrack) { 19214 track = this[i]; 19215 if (track.off) { 19216 track.off(); 19217 } 19218 19219 this.tracks_.splice(i, 1); 19220 19221 break; 19222 } 19223 } 19224 19225 if (!track) { 19226 return; 19227 } 19228 19229 this.trigger({ 19230 track: track, 19231 type: 'removetrack' 19232 }); 19233 }; 19234 19235 /** 19236 * Get a Track from the TrackList by a tracks id 19237 * 19238 * @param {String} id - the id of the track to get 19239 * @method getTrackById 19240 * @return {Track} 19241 * @private 19242 */ 19243 19244 TrackList.prototype.getTrackById = function getTrackById(id) { 19245 var result = null; 19246 19247 for (var i = 0, l = this.length; i < l; i++) { 19248 var track = this[i]; 19249 if (track.id === id) { 19250 result = track; 19251 break; 19252 } 19253 } 19254 19255 return result; 19256 }; 19257 19258 return TrackList; 19259})(_eventTarget2['default']); 19260 19261TrackList.prototype.allowedEvents_ = { 19262 change: 'change', 19263 addtrack: 'addtrack', 19264 removetrack: 'removetrack' 19265}; 19266 19267// emulate attribute EventHandler support to allow for feature detection 19268for (var _event in TrackList.prototype.allowedEvents_) { 19269 TrackList.prototype['on' + _event] = null; 19270} 19271 19272exports['default'] = TrackList; 19273module.exports = exports['default']; 19274 19275},{"../event-target":104,"../utils/browser.js":140,"../utils/fn.js":145,"global/document":1}],137:[function(_dereq_,module,exports){ 19276/** 19277 * @file track.js 19278 */ 19279'use strict'; 19280 19281exports.__esModule = true; 19282 19283function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19284 19285function _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; } } 19286 19287function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 19288 19289function _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
19289onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 19290 19291var _utilsBrowserJs = _dereq_('../utils/browser.js'); 19292 19293var browser = _interopRequireWildcard(_utilsBrowserJs); 19294 19295var _globalDocument = _dereq_('global/document'); 19296 19297var _globalDocument2 = _interopRequireDefault(_globalDocument); 19298 19299var _utilsGuidJs = _dereq_('../utils/guid.js'); 19300 19301var Guid = _interopRequireWildcard(_utilsGuidJs); 19302 19303var _eventTarget = _dereq_('../event-target'); 19304 19305var _eventTarget2 = _interopRequireDefault(_eventTarget); 19306 19307/** 19308 * setup the common parts of an audio, video, or text track 19309 * @link https://html.spec.whatwg.org/multipage/embedded-content.html 19310 * 19311 * @param {String} type The type of track we are dealing with audio|video|text 19312 * @param {Object=} options Object of option names and values 19313 * @extends EventTarget 19314 * @class Track 19315 */ 19316 19317var Track = (function (_EventTarget) { 19318 _inherits(Track, _EventTarget); 19319 19320 function Track() { 19321 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 19322 19323 _classCallCheck(this, Track); 19324 19325 _EventTarget.call(this); 19326 19327 var track = this; 19328 if (browser.IS_IE8) { 19329 track = _globalDocument2['default'].createElement('custom'); 19330 for (var prop in Track.prototype) { 19331 if (prop !== 'constructor') { 19332 track[prop] = Track.prototype[prop]; 19333 } 19334 } 19335 } 19336 19337 var trackProps = { 19338 id: options.id || 'vjs_track_' + Guid.newGUID(), 19339 kind: options.kind || '', 19340 label: options.label || '', 19341 language: options.language || '' 19342 }; 19343 19344 var _loop = function (key) { 19345 Object.defineProperty(track, key, { 19346 get: function get() { 19347 return trackProps[key]; 19348 }, 19349 set: function set() {} 19350 }); 19351 }; 19352 19353 for (var key in trackProps) { 19354 _loop(key); 19355 } 19356 19357 return track; 19358 } 19359 19360 return Track; 19361})(_eventTarget2['default']); 19362 19363exports['default'] = Track; 19364module.exports = exports['default']; 19365 19366},{"../event-target":104,"../utils/browser.js":140,"../utils/guid.js":147,"global/document":1}],138:[function(_dereq_,module,exports){ 19367/** 19368 * @file video-track-list.js 19369 */ 19370'use strict'; 19371 19372exports.__esModule = true; 19373 19374function _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; } } 19375 19376function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19377 19378function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 19379 19380function _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; } 19381 19382var _trackList = _dereq_('./track-list'); 19383 19384var _trackList2 = _interopRequireDefault(_trackList); 19385 19386var _utilsBrowserJs = _dereq_('../utils/browser.js'); 19387 19388var browser = _interopRequireWildcard(_utilsBrowserJs); 19389 19390var _globalDocument = _dereq_('global/document'); 19391 19392var _globalDocument2 = _interopRequireDefault(_globalDocument); 19393 19394/** 19395 * disable other video tracks before selecting the new one 19396 * 19397 * @param {Array|VideoTrackList} list list to work on 19398 * @param {VideoTrack} track the track to skip 19399 */ 19400var disableOthers = function disableOthers(list, track) { 19401 for (var i = 0; i < list.length; i++) { 19402 if (track.id === list[i].id) { 19403 continue; 19404 } 19405 // another audio track is enabled, disable it 19406 list[i].selected = false; 19407 } 19408}; 19409 19410/** 19411* A list of possiblee video tracks. Most functionality is in the 19412 * base class Tracklist and the spec for VideoTrackList is located at: 19413 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist 19414 * 19415 * interface VideoTrackList : EventTarget { 19416 * readonly attribute unsigned long length; 19417 * getter VideoTrack (unsigned long index); 19418 * VideoTrack? getTrackById(DOMString id); 19419 * readonly attribute long selectedIndex; 19420 * 19421 * attribute EventHandler onchange; 19422 * attribute EventHandler onaddtrack; 19423 * attribute EventHandler onremovetrack; 19424 * }; 19425 * 19426 * @param {VideoTrack[]} tracks a list of video tracks to instantiate the list with 19427 # @extends TrackList 19428 * @class VideoTrackList 19429 */ 19430 19431var VideoTrackList = (function (_TrackList) { 19432 _inherits(VideoTrackList, _TrackList); 19433 19434 function VideoTrackList() { 19435 var tracks = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; 19436 19437 _classCallCheck(this, VideoTrackList); 19438 19439 var list = undefined; 19440 19441 // make sure only 1 track is enabled 19442 // sorted from last index to first index 19443 for (var i = tracks.length - 1; i >= 0; i--) { 19444 if (tracks[i].selected) { 19445 disableOthers(tracks, tracks[i]); 19446 break; 19447 } 19448 } 19449 19450 // IE8 forces us to implement inheritance ourselves 19451 // as it does not support Object.defineProperty properly 19452 if (browser.IS_IE8) { 19453 list = _globalDocument2['default'].createElement('custom'); 19454 for (var prop in _trackList2['default'].prototype) { 19455 if (prop !== 'constructor') { 19456 list[prop] = _trackList2['default'].prototype[prop]; 19457 } 19458 } 19459 for (var prop in VideoTrackList.prototype) { 19460 if (prop !== 'constructor') { 19461 list[prop] = VideoTrackList.prototype[prop]; 19462 } 19463 } 19464 } 19465 19466 list = _TrackList.call(this, tracks, list); 19467 list.changing_ = false;
19468 19469 Object.defineProperty(list, 'selectedIndex', { 19470 get: function get() { 19471 for (var i = 0; i < this.length; i++) { 19472 if (this[i].selected) { 19473 return i; 19474 } 19475 } 19476 return -1; 19477 }, 19478 set: function set() {} 19479 }); 19480 19481 return list; 19482 } 19483 19484 VideoTrackList.prototype.addTrack_ = function addTrack_(track) { 19485 var _this = this; 19486 19487 if (track.selected) { 19488 disableOthers(this, track); 19489 } 19490 19491 _TrackList.prototype.addTrack_.call(this, track); 19492 // native tracks don't have this 19493 if (!track.addEventListener) { 19494 return; 19495 } 19496 track.addEventListener('selectedchange', function () { 19497 if (_this.changing_) { 19498 return; 19499 } 19500 _this.changing_ = true; 19501 disableOthers(_this, track); 19502 _this.changing_ = false; 19503 _this.trigger('change'); 19504 }); 19505 }; 19506 19507 VideoTrackList.prototype.addTrack = function addTrack(track) { 19508 this.addTrack_(track); 19509 }; 19510 19511 VideoTrackList.prototype.removeTrack = function removeTrack(track) { 19512 _TrackList.prototype.removeTrack_.call(this, track); 19513 }; 19514 19515 return VideoTrackList; 19516})(_trackList2['default']); 19517 19518exports['default'] = VideoTrackList; 19519module.exports = exports['default']; 19520 19521},{"../utils/browser.js":140,"./track-list":136,"global/document":1}],139:[function(_dereq_,module,exports){ 19522'use strict'; 19523 19524exports.__esModule = true; 19525 19526function _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; } } 19527 19528function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19529 19530function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 19531 19532function _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; } 19533 19534var _trackEnums = _dereq_('./track-enums'); 19535 19536var _track = _dereq_('./track'); 19537 19538var _track2 = _interopRequireDefault(_track); 19539 19540var _utilsMergeOptions = _dereq_('../utils/merge-options'); 19541 19542var _utilsMergeOptions2 = _interopRequireDefault(_utilsMergeOptions); 19543 19544var _utilsBrowserJs = _dereq_('../utils/browser.js'); 19545 19546var browser = _interopRequireWildcard(_utilsBrowserJs); 19547 19548/** 19549 * A single video text track as defined in: 19550 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack 19551 * 19552 * interface VideoTrack { 19553 * readonly attribute DOMString id; 19554 * readonly attribute DOMString kind; 19555 * readonly attribute DOMString label; 19556 * readonly attribute DOMString language; 19557 * attribute boolean selected; 19558 * }; 19559 * 19560 * @param {Object=} options Object of option names and values 19561 * @class VideoTrack 19562 */ 19563 19564var VideoTrack = (function (_Track) { 19565 _inherits(VideoTrack, _Track); 19566 19567 function VideoTrack() { 19568 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 19569 19570 _classCallCheck(this, VideoTrack); 19571 19572 var settings = _utilsMergeOptions2['default'](options, { 19573 kind: _trackEnums.VideoTrackKind[options.kind] || '' 19574 }); 19575 19576 // on IE8 this will be a document element 19577 // for every other browser this will be a normal object 19578 var track = _Track.call(this, settings); 19579 var selected = false; 19580 19581 if (browser.IS_IE8) { 19582 for (var prop in VideoTrack.prototype) { 19583 if (prop !== 'constructor') { 19584 track[prop] = VideoTrack.prototype[prop]; 19585 } 19586 } 19587 } 19588 19589 Object.defineProperty(track, 'selected', { 19590 get: function get() { 19591 return selected; 19592 }, 19593 set: function set(newSelected) {
19594 // an invalid or unchanged value 19595 if (typeof newSelected !== 'boolean' || newSelected === selected) { 19596 return; 19597 } 19598 selected = newSelected; 19599 this.trigger('selectedchange'); 19600 } 19601 }); 19602 19603 // if the user sets this track to selected then 19604 // set selected to that true value otherwise 19605 // we keep it false 19606 if (settings.selected) { 19607 track.selected = settings.selected; 19608 } 19609 19610 return track; 19611 } 19612 19613 return VideoTrack; 19614})(_track2['default']); 19615 19616exports['default'] = VideoTrack; 19617module.exports = exports['default']; 19618 19619},{"../utils/browser.js":140,"../utils/merge-options":149,"./track":137,"./track-enums":135}],140:[function(_dereq_,module,exports){ 19620/** 19621 * @file browser.js 19622 */ 19623'use strict'; 19624 19625exports.__esModule = true; 19626 19627function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19628 19629var _globalDocument = _dereq_('global/document'); 19630 19631var _globalDocument2 = _interopRequireDefault(_globalDocument); 19632 19633var _globalWindow = _dereq_('global/window'); 19634 19635var _globalWindow2 = _interopRequireDefault(_globalWindow); 19636 19637var USER_AGENT = _globalWindow2['default'].navigator.userAgent; 19638var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT); 19639var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null; 19640 19641/* 19642 * Device is an iPhone 19643 * 19644 * @type {Boolean} 19645 * @constant 19646 * @private 19647 */ 19648var IS_IPAD = /iPad/i.test(USER_AGENT); 19649 19650exports.IS_IPAD = IS_IPAD; 19651// The Facebook app's UIWebView identifies as both an iPhone and iPad, so 19652// to identify iPhones, we need to exclude iPads. 19653// http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/ 19654var IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD; 19655exports.IS_IPHONE = IS_IPHONE; 19656var IS_IPOD = /iPod/i.test(USER_AGENT); 19657exports.IS_IPOD = IS_IPOD; 19658var IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD; 19659 19660exports.IS_IOS = IS_IOS; 19661var IOS_VERSION = (function () { 19662 var match = USER_AGENT.match(/OS (\d+)_/i); 19663 if (match && match[1]) { 19664 return match[1]; 19665 } 19666})(); 19667 19668exports.IOS_VERSION = IOS_VERSION; 19669var IS_ANDROID = /Android/i.test(USER_AGENT); 19670exports.IS_ANDROID = IS_ANDROID; 19671var ANDROID_VERSION = (function () { 19672 // This matches Android Major.Minor.Patch versions 19673 // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned 19674 var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i), 19675 major, 19676 minor; 19677 19678 if (!match) { 19679 return null; 19680 } 19681 19682 major = match[1] && parseFloat(match[1]); 19683 minor = match[2] && parseFloat(match[2]); 19684 19685 if (major && minor) { 19686 return parseFloat(match[1] + '.' + match[2]); 19687 } else if (major) { 19688 return major; 19689 } else { 19690 return null; 19691 } 19692})(); 19693exports.ANDROID_VERSION = ANDROID_VERSION; 19694// Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser 19695var IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3; 19696exports.IS_OLD_ANDROID = IS_OLD_ANDROID; 19697var IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537; 19698 19699exports.IS_NATIVE_ANDROID = IS_NATIVE_ANDROID; 19700var IS_FIREFOX = /Firefox/i.test(USER_AGENT); 19701exports.IS_FIREFOX = IS_FIREFOX; 19702var IS_EDGE = /Edge/i.test(USER_AGENT); 19703exports.IS_EDGE = IS_EDGE; 19704var IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT); 19705exports.IS_CHROME = IS_CHROME; 19706var IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT); 19707 19708exports.IS_IE8 = IS_IE8; 19709var TOUCH_ENABLED = !!('ontouchstart' in _globalWindow2['default'] || _globalWindow2['default'].DocumentTouch && _globalDocument2['default'] instanceof _globalWindow2['default'].DocumentTouch); 19710exports.TOUCH_ENABLED = TOUCH_ENABLED; 19711var BACKGROUND_SIZE_SUPPORTED = ('backgroundSize' in _globalDocument2['default'].createElement('video').style); 19712exports.BACKGROUND_SIZE_SUPPORTED = BACKGROUND_SIZE_SUPPORTED; 19713 19714},{"global/document":1,"global/window":2}],141:[function(_dereq_,module,exports){ 19715/** 19716 * @file buffer.js 19717 */ 19718'use strict'; 19719 19720exports.__esModule = true; 19721exports.bufferedPercent = bufferedPercent; 19722 19723var _timeRangesJs = _dereq_('./time-ranges.js'); 19724 19725/** 19726 * Compute how much your video has been buffered 19727 * 19728 * @param {Object} Buffered object 19729 * @param {Number} Total duration 19730 * @return {Number} Percent buffered of the total duration 19731 * @private 19732 * @function bufferedPercent 19733 */ 19734 19735function bufferedPercent(buffered, duration) { 19736 var bufferedDuration = 0, 19737 start, 19738 end; 19739 19740 if (!duration) { 19741 return 0; 19742 } 19743 19744 if (!buffered || !buffered.length) { 19745 buffered = _timeRangesJs.createTimeRange(0, 0); 19746 } 19747 19748 for (var i = 0; i < buffered.length; i++) { 19749 start = buffered.start(i); 19750 end = buffered.end(i); 19751 19752 // buffered end can be bigger than duration by a very small fraction 19753 if (end > duration) { 19754 end = duration; 19755 } 19756 19757 bufferedDuration += end - start; 19758 } 19759 19760 return bufferedDuration / duration; 19761} 19762 19763},{"./time-ranges.js":151}],142:[function(_dereq_,module,exports){ 19764'use strict'; 19765 19766exports.__esModule = true; 19767 19768function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19769 19770var _logJs = _dereq_('./log.js'); 19771 19772var _logJs2 = _interopRequireDefault(_logJs); 19773 19774/** 19775 * Object containing the default behaviors for available handler methods. 19776 * 19777 * @private 19778 * @type {Object} 19779 */ 19780var defaultBehaviors = { 19781 get: function get(obj, key) { 19782 return obj[key]; 19783 }, 19784 set: function set(obj, key, value) { 19785 obj[key] = value; 19786 return true; 19787 } 19788}; 19789 19790/** 19791 * Expose private objects publicly using a Proxy to log deprecation warnings. 19792 * 19793 * Browsers that do not support Proxy objects will simply return the `target`
19794 * object, so it can be directly exposed. 19795 * 19796 * @param {Object} target The target object. 19797 * @param {Object} messages Messages to display from a Proxy. Only operations 19798 * with an associated message will be proxied. 19799 * @param {String} [messages.get] 19800 * @param {String} [messages.set] 19801 * @return {Object} A Proxy if supported or the `target` argument. 19802 */ 19803 19804exports['default'] = function (target) { 19805 var messages = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 19806 19807 if (typeof Proxy === 'function') { 19808 var _ret = (function () { 19809 var handler = {}; 19810 19811 // Build a handler object based on those keys that have both messages 19812 // and default behaviors. 19813 Object.keys(messages).forEach(function (key) { 19814 if (defaultBehaviors.hasOwnProperty(key)) { 19815 handler[key] = function () { 19816 _logJs2['default'].warn(messages[key]); 19817 return defaultBehaviors[key].apply(this, arguments); 19818 }; 19819 } 19820 }); 19821 19822 return { 19823 v: new Proxy(target, handler) 19824 }; 19825 })(); 19826 19827 if (typeof _ret === 'object') return _ret.v; 19828 } 19829 return target; 19830}; 19831 19832module.exports = exports['default']; 19833 19834},{"./log.js":148}],143:[function(_dereq_,module,exports){ 19835/** 19836 * @file dom.js 19837 */ 19838'use strict'; 19839 19840exports.__esModule = true; 19841exports.getEl = getEl; 19842exports.createEl = createEl; 19843exports.textContent = textContent; 19844exports.insertElFirst = insertElFirst; 19845exports.getElData = getElData; 19846exports.hasElData = hasElData; 19847exports.removeElData = removeElData; 19848exports.hasElClass = hasElClass; 19849exports.addElClass = addElClass; 19850exports.removeElClass = removeElClass; 19851exports.toggleElClass = toggleElClass; 19852exports.setElAttributes = setElAttributes; 19853exports.getElAttributes = getElAttributes; 19854exports.blockTextSelection = blockTextSelection; 19855exports.unblockTextSelection = unblockTextSelection; 19856exports.findElPosition = findElPosition; 19857exports.getPointerPosition = getPointerPosition; 19858exports.isEl = isEl; 19859exports.isTextNode = isTextNode; 19860exports.emptyEl = emptyEl; 19861exports.normalizeContent = normalizeContent; 19862exports.appendContent = appendContent; 19863exports.insertContent = insertContent; 19864 19865var _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 ', '.']); 19866 19867function _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; } } 19868 19869function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19870 19871function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } 19872 19873var _globalDocument = _dereq_('global/document'); 19874 19875var _globalDocument2 = _interopRequireDefault(_globalDocument); 19876 19877var _globalWindow = _dereq_('global/window'); 19878 19879var _globalWindow2 = _interopRequireDefault(_globalWindow); 19880 19881var _guidJs = _dereq_('./guid.js'); 19882 19883var Guid = _interopRequireWildcard(_guidJs); 19884 19885var _logJs = _dereq_('./log.js'); 19886 19887var _logJs2 = _interopRequireDefault(_logJs); 19888 19889var _tsml = _dereq_('tsml'); 19890 19891var _tsml2 = _interopRequireDefault(_tsml); 19892 19893/** 19894 * Detect if a value is a string with any non-whitespace characters. 19895 * 19896 * @param {String} str 19897 * @return {Boolean} 19898 */ 19899function isNonBlankString(str) { 19900 return typeof str === 'string' && /\S/.test(str); 19901} 19902 19903/** 19904 * Throws an error if the passed string has whitespace. This is used by 19905 * class methods to be relatively consistent with the classList API. 19906 * 19907 * @param {String} str 19908 * @return {Boolean} 19909 */ 19910function throwIfWhitespace(str) { 19911 if (/\s/.test(str)) { 19912 throw new Error('class has illegal whitespace characters'); 19913 } 19914} 19915 19916/** 19917 * Produce a regular expression for matching a class name. 19918 * 19919 * @param {String} className 19920 * @return {RegExp} 19921 */ 19922function classRegExp(className) { 19923 return new RegExp('(^|\\s)' + className + '($|\\s)'); 19924} 19925 19926/** 19927 * Creates functions to query the DOM using a given method. 19928 * 19929 * @function createQuerier 19930 * @private 19931 * @param {String} method 19932 * @return {Function} 19933 */ 19934function createQuerier(method) { 19935 return function (selector, context) { 19936 if (!isNonBlankString(selector)) { 19937 return _globalDocument2['default'][method](null); 19938 } 19939 if (isNonBlankString(context)) { 19940 context = _globalDocument2['default'].querySelector(context); 19941 } 19942 return (isEl(context) ? context : _globalDocument2['default'])[method](selector); 19943 }; 19944} 19945 19946/** 19947 * Shorthand for document.getElementById() 19948 * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs. 19949 * 19950 * @param {String} id Element ID 19951 * @return {Element} Element with supplied ID 19952 * @function getEl 19953 */ 19954 19955function getEl(id) { 19956 if (id.indexOf('#') === 0) { 19957 id = id.slice(1); 19958 } 19959 19960 return _globalDocument2['default'].getElementById(id); 19961} 19962 19963/** 19964 * Creates an element and applies properties. 19965 * 19966 * @param {String} [tagName='div'] Name of tag to be created. 19967 * @param {Object} [properties={}] Element properties to be applied. 19968 * @param {Object} [attributes={}] Element attributes to be applied. 19969 * @return {Element} 19970 * @function createEl 19971 */ 19972 19973function createEl() { 19974 var tagName = arguments.length <= 0 || arguments[0] === undefined ? 'div' : arguments[0]; 19975 var properties = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 19976 var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; 19977 19978 var el = _globalDocument2['default'].createElement(tagName); 19979
vendor: 4,103 bytes, lines 19980-20164
19980 Object.getOwnPropertyNames(properties).forEach(function (propName) { 19981 var val = properties[propName]; 19982 19983 // See #2176 19984 // We originally were accepting both properties and attributes in the 19985 // same object, but that doesn't work so well. 19986 if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') { 19987 _logJs2['default'].warn(_tsml2['default'](_templateObject, propName, val)); 19988 el.setAttribute(propName, val); 19989 } else { 19990 el[propName] = val; 19991 } 19992 }); 19993 19994 Object.getOwnPropertyNames(attributes).forEach(function (attrName) { 19995 var val = attributes[attrName]; 19996 el.setAttribute(attrName, attributes[attrName]); 19997 }); 19998 19999 return el; 20000} 20001 20002/** 20003 * Injects text into an element, replacing any existing contents entirely. 20004 * 20005 * @param {Element} el 20006 * @param {String} text 20007 * @return {Element} 20008 * @function textContent 20009 */ 20010 20011function textContent(el, text) { 20012 if (typeof el.textContent === 'undefined') { 20013 el.innerText = text; 20014 } else { 20015 el.textContent = text; 20016 } 20017} 20018 20019/** 20020 * Insert an element as the first child node of another 20021 * 20022 * @param {Element} child Element to insert 20023 * @param {Element} parent Element to insert child into 20024 * @private 20025 * @function insertElFirst 20026 */ 20027 20028function insertElFirst(child, parent) { 20029 if (parent.firstChild) { 20030 parent.insertBefore(child, parent.firstChild); 20031 } else { 20032 parent.appendChild(child); 20033 } 20034} 20035 20036/** 20037 * Element Data Store. Allows for binding data to an element without putting it directly on the element. 20038 * Ex. Event listeners are stored here. 20039 * (also from jsninja.com, slightly modified and updated for closure compiler) 20040 * 20041 * @type {Object} 20042 * @private 20043 */ 20044var elData = {}; 20045 20046/* 20047 * Unique attribute name to store an element's guid in 20048 * 20049 * @type {String} 20050 * @constant 20051 * @private 20052 */ 20053var elIdAttr = 'vdata' + new Date().getTime(); 20054 20055/** 20056 * Returns the cache object where data for an element is stored 20057 * 20058 * @param {Element} el Element to store data for. 20059 * @return {Object} 20060 * @function getElData 20061 */ 20062 20063function getElData(el) { 20064 var id = el[elIdAttr]; 20065 20066 if (!id) { 20067 id = el[elIdAttr] = Guid.newGUID(); 20068 } 20069 20070 if (!elData[id]) { 20071 elData[id] = {}; 20072 } 20073 20074 return elData[id]; 20075} 20076 20077/** 20078 * Returns whether or not an element has cached data 20079 * 20080 * @param {Element} el A dom element 20081 * @return {Boolean} 20082 * @private 20083 * @function hasElData 20084 */ 20085 20086function hasElData(el) { 20087 var id = el[elIdAttr]; 20088 20089 if (!id) { 20090 return false; 20091 } 20092 20093 return !!Object.getOwnPropertyNames(elData[id]).length; 20094} 20095 20096/** 20097 * Delete data for the element from the cache and the guid attr from getElementById 20098 * 20099 * @param {Element} el Remove data for an element 20100 * @private 20101 * @function removeElData 20102 */ 20103 20104function removeElData(el) { 20105 var id = el[elIdAttr]; 20106 20107 if (!id) { 20108 return; 20109 } 20110 20111 // Remove all stored data 20112 delete elData[id]; 20113 20114 // Remove the elIdAttr property from the DOM node 20115 try { 20116 delete el[elIdAttr]; 20117 } catch (e) { 20118 if (el.removeAttribute) { 20119 el.removeAttribute(elIdAttr); 20120 } else { 20121 // IE doesn't appear to support removeAttribute on the document element 20122 el[elIdAttr] = null; 20123 } 20124 } 20125} 20126 20127/** 20128 * Check if an element has a CSS class 20129 * 20130 * @function hasElClass 20131 * @param {Element} element Element to check 20132 * @param {String} classToCheck Classname to check 20133 */ 20134 20135function hasElClass(element, classToCheck) { 20136 if (element.classList) { 20137 return element.classList.contains(classToCheck); 20138 } else { 20139 throwIfWhitespace(classToCheck); 20140 return classRegExp(classToCheck).test(element.className); 20141 } 20142} 20143 20144/** 20145 * Add a CSS class name to an element 20146 * 20147 * @function addElClass 20148 * @param {Element} element Element to add class name to 20149 * @param {String} classToAdd Classname to add 20150 */ 20151 20152function addElClass(element, classToAdd) { 20153 if (element.classList) { 20154 element.classList.add(classToAdd); 20155 20156 // Don't need to `throwIfWhitespace` here because `hasElClass` will do it 20157 // in the case of classList not being supported. 20158 } else if (!hasElClass(element, classToAdd)) { 20159 element.className = (element.className + ' ' + classToAdd).trim(); 20160 } 20161 20162 return element; 20163} 20164
20165/** 20166 * Remove a CSS class name from an element 20167 * 20168 * @function removeElClass 20169 * @param {Element} element Element to remove from class name 20170 * @param {String} classToRemove Classname to remove 20171 */ 20172 20173function removeElClass(element, classToRemove) { 20174 if (element.classList) { 20175 element.classList.remove(classToRemove); 20176 } else { 20177 throwIfWhitespace(classToRemove); 20178 element.className = element.className.split(/\s+/).filter(function (c) { 20179 return c !== classToRemove; 20180 }).join(' '); 20181 } 20182 20183 return element; 20184} 20185 20186/** 20187 * Adds or removes a CSS class name on an element depending on an optional 20188 * condition or the presence/absence of the class name. 20189 * 20190 * @function toggleElClass 20191 * @param {Element} element 20192 * @param {String} classToToggle 20193 * @param {Boolean|Function} [predicate] 20194 * Can be a function that returns a Boolean. If `true`, the class 20195 * will be added; if `false`, the class will be removed. If not 20196 * given, the class will be added if not present and vice versa. 20197 */ 20198 20199function toggleElClass(element, classToToggle, predicate) { 20200 20201 // This CANNOT use `classList` internally because IE does not support the 20202 // second parameter to the `classList.toggle()` method! Which is fine because 20203 // `classList` will be used by the add/remove functions. 20204 var has = hasElClass(element, classToToggle); 20205 20206 if (typeof predicate === 'function') { 20207 predicate = predicate(element, classToToggle); 20208 } 20209 20210 if (typeof predicate !== 'boolean') { 20211 predicate = !has; 20212 } 20213 20214 // If the necessary class operation matches the current state of the 20215 // element, no action is required. 20216 if (predicate === has) { 20217 return; 20218 } 20219 20220 if (predicate) { 20221 addElClass(element, classToToggle); 20222 } else { 20223 removeElClass(element, classToToggle); 20224 } 20225 20226 return element; 20227} 20228 20229/** 20230 * Apply attributes to an HTML element. 20231 * 20232 * @param {Element} el Target element. 20233 * @param {Object=} attributes Element attributes to be applied. 20234 * @private 20235 * @function setElAttributes 20236 */ 20237 20238function setElAttributes(el, attributes) { 20239 Object.getOwnPropertyNames(attributes).forEach(function (attrName) { 20240 var attrValue = attributes[attrName]; 20241 20242 if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) { 20243 el.removeAttribute(attrName); 20244 } else { 20245 el.setAttribute(attrName, attrValue === true ? '' : attrValue); 20246 } 20247 }); 20248} 20249 20250/** 20251 * Get an element's attribute values, as defined on the HTML tag 20252 * Attributes are not the same as properties. They're defined on the tag 20253 * or with setAttribute (which shouldn't be used with HTML) 20254 * This will return true or false for boolean attributes. 20255 * 20256 * @param {Element} tag Element from which to get tag attributes 20257 * @return {Object} 20258 * @private 20259 * @function getElAttributes 20260 */ 20261 20262function getElAttributes(tag) { 20263 var obj, knownBooleans, attrs, attrName, attrVal; 20264 20265 obj = {}; 20266 20267 // known boolean attributes 20268 // we can check for matching boolean properties, but older browsers 20269 // won't know about HTML5 boolean attributes that we still read from 20270 knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ','; 20271 20272 if (tag && tag.attributes && tag.attributes.length > 0) { 20273 attrs = tag.attributes; 20274 20275 for (var i = attrs.length - 1; i >= 0; i--) { 20276 attrName = attrs[i].name; 20277 attrVal = attrs[i].value; 20278 20279 // check for known booleans 20280 // the matching element property will return a value for typeof 20281 if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) { 20282 // the value of an included boolean attribute is typically an empty 20283 // string ('') which would equal false if we just check for a false value. 20284 // we also don't want support bad code like autoplay='false' 20285 attrVal = attrVal !== null ? true : false; 20286 } 20287 20288 obj[attrName] = attrVal; 20289 } 20290 } 20291 20292 return obj; 20293} 20294 20295/** 20296 * Attempt to block the ability to select text while dragging controls 20297 * 20298 * @return {Boolean} 20299 * @function blockTextSelection 20300 */ 20301 20302function blockTextSelection() { 20303 _globalDocument2['default'].body.focus(); 20304 _globalDocument2['default'].onselectstart = function () { 20305 return false;
20306 }; 20307} 20308 20309/** 20310 * Turn off text selection blocking 20311 * 20312 * @return {Boolean} 20313 * @function unblockTextSelection 20314 */ 20315 20316function unblockTextSelection() { 20317 _globalDocument2['default'].onselectstart = function () { 20318 return true; 20319 }; 20320} 20321 20322/** 20323 * Offset Left 20324 * getBoundingClientRect technique from 20325 * John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/ 20326 * 20327 * @function findElPosition 20328 * @param {Element} el Element from which to get offset 20329 * @return {Object} 20330 */ 20331 20332function findElPosition(el) { 20333 var box = undefined; 20334 20335 if (el.getBoundingClientRect && el.parentNode) { 20336 box = el.getBoundingClientRect(); 20337 } 20338 20339 if (!box) { 20340 return { 20341 left: 0, 20342 top: 0 20343 }; 20344 } 20345 20346 var docEl = _globalDocument2['default'].documentElement; 20347 var body = _globalDocument2['default'].body; 20348 20349 var clientLeft = docEl.clientLeft || body.clientLeft || 0; 20350 var scrollLeft = _globalWindow2['default'].pageXOffset || body.scrollLeft; 20351 var left = box.left + scrollLeft - clientLeft; 20352 20353 var clientTop = docEl.clientTop || body.clientTop || 0; 20354 var scrollTop = _globalWindow2['default'].pageYOffset || body.scrollTop; 20355 var top = box.top + scrollTop - clientTop; 20356 20357 // Android sometimes returns slightly off decimal values, so need to round 20358 return { 20359 left: Math.round(left), 20360 top: Math.round(top) 20361 }; 20362} 20363 20364/** 20365 * Get pointer position in element 20366 * Returns an object with x and y coordinates. 20367 * The base on the coordinates are the bottom left of the element. 20368 * 20369 * @function getPointerPosition 20370 * @param {Element} el Element on which to get the pointer position on 20371 * @param {Event} event Event object 20372 * @return {Object} This object will have x and y coordinates corresponding to the mouse position 20373 */ 20374 20375function getPointerPosition(el, event) { 20376 var position = {}; 20377 var box = findElPosition(el); 20378 var boxW = el.offsetWidth; 20379 var boxH = el.offsetHeight; 20380 20381 var boxY = box.top; 20382 var boxX = box.left; 20383 var pageY = event.pageY; 20384 var pageX = event.pageX; 20385 20386 if (event.changedTouches) { 20387 pageX = event.changedTouches[0].pageX; 20388 pageY = event.changedTouches[0].pageY; 20389 } 20390 20391 position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH)); 20392 position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW)); 20393 20394 return position; 20395} 20396 20397/** 20398 * Determines, via duck typing, whether or not a value is a DOM element. 20399 * 20400 * @function isEl 20401 * @param {Mixed} value 20402 * @return {Boolean} 20403 */ 20404 20405function isEl(value) { 20406 return !!value && typeof value === 'object' && value.nodeType === 1; 20407} 20408 20409/** 20410 * Determines, via duck typing, whether or not a value is a text node. 20411 * 20412 * @param {Mixed} value 20413 * @return {Boolean} 20414 */ 20415 20416function isTextNode(value) { 20417 return !!value && typeof value === 'object' && value.nodeType === 3; 20418} 20419 20420/** 20421 * Empties the contents of an element. 20422 * 20423 * @function emptyEl 20424 * @param {Element} el 20425 * @return {Element} 20426 */ 20427 20428function emptyEl(el) { 20429 while (el.firstChild) { 20430 el.removeChild(el.firstChild); 20431 } 20432 return el; 20433} 20434 20435/** 20436 * Normalizes content for eventual insertion into the DOM. 20437 * 20438 * This allows a wide range of content definition methods, but protects 20439 * from falling into the trap of simply writing to `innerHTML`, which is 20440 * an XSS concern. 20441 * 20442 * The content for an element can be passed in multiple types and 20443 * combinations, whose behavior is as follows: 20444 * 20445 * - String 20446 * Normalized into a text node. 20447 * 20448 * - Element, TextNode 20449 * Passed through. 20450 * 20451 * - Array 20452 * A one-dimensional array of strings, elements, nodes, or functions (which 20453 * return single strings, elements, or nodes). 20454 * 20455 * - Function 20456 * If the sole argument, is expected to produce a string, element, 20457 * node, or array. 20458 * 20459 * @function normalizeContent 20460 * @param {String|Element|TextNode|Array|Function} content 20461 * @return {Array} 20462 */ 20463 20464function normalizeContent(content) { 20465 20466 // First, invoke content if it is a function. If it produces an array, 20467 // that needs to happen before normalization. 20468 if (typeof content === 'function') { 20469 content = content(); 20470 } 20471 20472 // Next up, normalize to an array, so one or many items can be normalized, 20473 // filtered, and returned.
20474 return (Array.isArray(content) ? content : [content]).map(function (value) { 20475 20476 // First, invoke value if it is a function to produce a new value, 20477 // which will be subsequently normalized to a Node of some kind. 20478 if (typeof value === 'function') { 20479 value = value(); 20480 } 20481 20482 if (isEl(value) || isTextNode(value)) { 20483 return value; 20484 } 20485 20486 if (typeof value === 'string' && /\S/.test(value)) { 20487 return _globalDocument2['default'].createTextNode(value); 20488 } 20489 }).filter(function (value) { 20490 return value; 20491 }); 20492} 20493 20494/** 20495 * Normalizes and appends content to an element. 20496 * 20497 * @function appendContent 20498 * @param {Element} el 20499 * @param {String|Element|TextNode|Array|Function} content 20500 * See: `normalizeContent` 20501 * @return {Element} 20502 */ 20503 20504function appendContent(el, content) { 20505 normalizeContent(content).forEach(function (node) { 20506 return el.appendChild(node); 20507 }); 20508 return el; 20509} 20510 20511/** 20512 * Normalizes and inserts content into an element; this is identical to 20513 * `appendContent()`, except it empties the element first. 20514 * 20515 * @function insertContent 20516 * @param {Element} el 20517 * @param {String|Element|TextNode|Array|Function} content 20518 * See: `normalizeContent` 20519 * @return {Element} 20520 */ 20521 20522function insertContent(el, content) { 20523 return appendContent(emptyEl(el), content); 20524} 20525 20526/** 20527 * Finds a single DOM element matching `selector` within the optional 20528 * `context` of another DOM element (defaulting to `document`). 20529 * 20530 * @function $ 20531 * @param {String} selector 20532 * A valid CSS selector, which will be passed to `querySelector`. 20533 * 20534 * @param {Element|String} [context=document] 20535 * A DOM element within which to query. Can also be a selector 20536 * string in which case the first matching element will be used 20537 * as context. If missing (or no element matches selector), falls 20538 * back to `document`. 20539 * 20540 * @return {Element|null} 20541 */ 20542var $ = createQuerier('querySelector'); 20543 20544exports.$ = $; 20545/** 20546 * Finds a all DOM elements matching `selector` within the optional 20547 * `context` of another DOM element (defaulting to `document`). 20548 * 20549 * @function $$ 20550 * @param {String} selector 20551 * A valid CSS selector, which will be passed to `querySelectorAll`. 20552 * 20553 * @param {Element|String} [context=document] 20554 * A DOM element within which to query. Can also be a selector 20555 * string in which case the first matching element will be used 20556 * as context. If missing (or no element matches selector), falls 20557 * back to `document`. 20558 * 20559 * @return {NodeList} 20560 */ 20561var $$ = createQuerier('querySelectorAll'); 20562exports.$$ = $$; 20563 20564},{"./guid.js":147,"./log.js":148,"global/document":1,"global/window":2,"tsml":55}],144:[function(_dereq_,module,exports){ 20565/** 20566 * @file events.js 20567 * 20568 * Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/) 20569 * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible) 20570 * This should work very similarly to jQuery's events, however it's based off the book version which isn't as 20571 * robust as jquery's, so there's probably some differences. 20572 */ 20573 20574'use strict'; 20575 20576exports.__esModule = true; 20577exports.on = on; 20578exports.off = off; 20579exports.trigger = trigger; 20580exports.one = one; 20581exports.fixEvent = fixEvent; 20582 20583function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20584 20585function _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; } } 20586 20587var _domJs = _dereq_('./dom.js'); 20588 20589var Dom = _interopRequireWildcard(_domJs); 20590 20591var _guidJs = _dereq_('./guid.js'); 20592 20593var Guid = _interopRequireWildcard(_guidJs); 20594 20595var _globalWindow = _dereq_('global/window'); 20596 20597var _globalWindow2 = _interopRequireDefault(_globalWindow); 20598 20599var _globalDocument = _dereq_('global/document'); 20600 20601var _globalDocument2 = _interopRequireDefault(_globalDocument); 20602 20603/** 20604 * Add an event listener to element 20605 * It stores the handler function in a separate cache object 20606 * and adds a generic handler to the element's event, 20607 * along with a unique id (guid) to the element. 20608 *
20609 * @param {Element|Object} elem Element or object to bind listeners to 20610 * @param {String|Array} type Type of event to bind to. 20611 * @param {Function} fn Event listener. 20612 * @method on 20613 */ 20614 20615function on(elem, type, fn) { 20616 if (Array.isArray(type)) { 20617 return _handleMultipleEvents(on, elem, type, fn); 20618 } 20619 20620 var data = Dom.getElData(elem); 20621 20622 // We need a place to store all our handler data 20623 if (!data.handlers) data.handlers = {}; 20624 20625 if (!data.handlers[type]) data.handlers[type] = []; 20626 20627 if (!fn.guid) fn.guid = Guid.newGUID(); 20628 20629 data.handlers[type].push(fn); 20630 20631 if (!data.dispatcher) { 20632 data.disabled = false; 20633 20634 data.dispatcher = function (event, hash) { 20635 20636 if (data.disabled) return; 20637 event = fixEvent(event); 20638 20639 var handlers = data.handlers[event.type]; 20640 20641 if (handlers) { 20642 // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off. 20643 var handlersCopy = handlers.slice(0); 20644 20645 for (var m = 0, n = handlersCopy.length; m < n; m++) { 20646 if (event.isImmediatePropagationStopped()) { 20647 break; 20648 } else { 20649 handlersCopy[m].call(elem, event, hash); 20650 } 20651 } 20652 } 20653 }; 20654 } 20655 20656 if (data.handlers[type].length === 1) { 20657 if (elem.addEventListener) { 20658 elem.addEventListener(type, data.dispatcher, false); 20659 } else if (elem.attachEvent) { 20660 elem.attachEvent('on' + type, data.dispatcher); 20661 } 20662 } 20663} 20664 20665/** 20666 * Removes event listeners from an element 20667 * 20668 * @param {Element|Object} elem Object to remove listeners from 20669 * @param {String|Array=} type Type of listener to remove. Don't include to remove all events from element. 20670 * @param {Function} fn Specific listener to remove. Don't include to remove listeners for an event type. 20671 * @method off 20672 */ 20673 20674function off(elem, type, fn) { 20675 // Don't want to add a cache object through getElData if not needed 20676 if (!Dom.hasElData(elem)) return; 20677 20678 var data = Dom.getElData(elem); 20679 20680 // If no events exist, nothing to unbind 20681 if (!data.handlers) { 20682 return; 20683 } 20684 20685 if (Array.isArray(type)) { 20686 return _handleMultipleEvents(off, elem, type, fn); 20687 } 20688 20689 // Utility function 20690 var removeType = function removeType(t) { 20691 data.handlers[t] = []; 20692 _cleanUpEvents(elem, t); 20693 }; 20694 20695 // Are we removing all bound events? 20696 if (!type) { 20697 for (var t in data.handlers) { 20698 removeType(t); 20699 }return; 20700 } 20701 20702 var handlers = data.handlers[type]; 20703 20704 // If no handlers exist, nothing to unbind 20705 if (!handlers) return; 20706 20707 // If no listener was provided, remove all listeners for type 20708 if (!fn) { 20709 removeType(type); 20710 return; 20711 } 20712 20713 // We're only removing a single handler 20714 if (fn.guid) { 20715 for (var n = 0; n < handlers.length; n++) { 20716 if (handlers[n].guid === fn.guid) { 20717 handlers.splice(n--, 1); 20718 } 20719 } 20720 } 20721 20722 _cleanUpEvents(elem, type); 20723} 20724 20725/** 20726 * Trigger an event for an element 20727 * 20728 * @param {Element|Object} elem Element to trigger an event on 20729 * @param {Event|Object|String} event A string (the type) or an event object with a type attribute 20730 * @param {Object} [hash] data hash to pass along with the event 20731 * @return {Boolean=} Returned only if default was prevented 20732 * @method trigger 20733 */ 20734 20735function trigger(elem, event, hash) { 20736 // Fetches element data and a reference to the parent (for bubbling). 20737 // Don't want to add a data object to cache for every parent, 20738 // so checking hasElData first. 20739 var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {}; 20740 var parent = elem.parentNode || elem.ownerDocument; 20741 // type = event.type || event, 20742 // handler; 20743 20744 // If an event name was passed as a string, creates an event out of it 20745 if (typeof event === 'string') { 20746 event = { type: event, target: elem }; 20747 } 20748 // Normalizes the event properties. 20749 event = fixEvent(event); 20750 20751 // If the passed element has a dispatcher, executes the established handlers. 20752 if (elemData.dispatcher) { 20753 elemData.dispatcher.call(elem, event, hash); 20754 } 20755 20756 // Unless explicitly stopped or the event does not bubble (e.g. media events) 20757 // recursively calls this function to bubble the event up the DOM. 20758 if (parent && !event.isPropagationStopped() && event.bubbles === true) { 20759 trigger.call(null, parent, event, hash); 20760 20761 // If at the top of the DOM, triggers the default action unless disabled. 20762 } else if (!parent && !event.defaultPrevented) { 20763 var targetData = Dom.getElData(event.target); 20764 20765 // Checks if the target has a default action for this event. 20766 if (event.target[event.type]) { 20767 // Temporarily disables event dispatching on the target as we have already executed the handler. 20768 targetData.disabled = true; 20769 // Executes the default action. 20770 if (typeof event.target[event.type] === 'function') { 20771 event.target[event.type](); 20772 } 20773 // Re-enables event dispatching. 20774 targetData.disabled = false;
vendor: 4,549 bytes, lines 20775-20916
20775 } 20776 } 20777 20778 // Inform the triggerer if the default was prevented by returning false 20779 return !event.defaultPrevented; 20780} 20781 20782/** 20783 * Trigger a listener only once for an event 20784 * 20785 * @param {Element|Object} elem Element or object to 20786 * @param {String|Array} type Name/type of event 20787 * @param {Function} fn Event handler function 20788 * @method one 20789 */ 20790 20791function one(elem, type, fn) { 20792 if (Array.isArray(type)) { 20793 return _handleMultipleEvents(one, elem, type, fn); 20794 } 20795 var func = function func() { 20796 off(elem, type, func); 20797 fn.apply(this, arguments); 20798 }; 20799 // copy the guid to the new function so it can removed using the original function's ID 20800 func.guid = fn.guid = fn.guid || Guid.newGUID(); 20801 on(elem, type, func); 20802} 20803 20804/** 20805 * Fix a native event to have standard property values 20806 * 20807 * @param {Object} event Event object to fix 20808 * @return {Object} 20809 * @private 20810 * @method fixEvent 20811 */ 20812 20813function fixEvent(event) { 20814 20815 function returnTrue() { 20816 return true; 20817 } 20818 function returnFalse() { 20819 return false; 20820 } 20821 20822 // Test if fixing up is needed 20823 // Used to check if !event.stopPropagation instead of isPropagationStopped 20824 // But native events return true for stopPropagation, but don't have 20825 // other expected methods like isPropagationStopped. Seems to be a problem 20826 // with the Javascript Ninja code. So we're just overriding all events now. 20827 if (!event || !event.isPropagationStopped) { 20828 var old = event || _globalWindow2['default'].event; 20829 20830 event = {}; 20831 // Clone the old object so that we can modify the values event = {}; 20832 // IE8 Doesn't like when you mess with native event properties 20833 // Firefox returns false for event.hasOwnProperty('type') and other props 20834 // which makes copying more difficult. 20835 // TODO: Probably best to create a whitelist of event props 20836 for (var key in old) { 20837 // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y 20838 // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation 20839 // and webkitMovementX/Y 20840 if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') { 20841 // Chrome 32+ warns if you try to copy deprecated returnValue, but 20842 // we still want to if preventDefault isn't supported (IE8). 20843 if (!(key === 'returnValue' && old.preventDefault)) { 20844 event[key] = old[key]; 20845 } 20846 } 20847 } 20848 20849 // The event occurred on this element 20850 if (!event.target) { 20851 event.target = event.srcElement || _globalDocument2['default']; 20852 } 20853 20854 // Handle which other element the event is related to 20855 if (!event.relatedTarget) { 20856 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; 20857 } 20858 20859 // Stop the default browser action 20860 event.preventDefault = function () { 20861 if (old.preventDefault) { 20862 old.preventDefault(); 20863 } 20864 event.returnValue = false; 20865 old.returnValue = false; 20866 event.defaultPrevented = true; 20867 }; 20868 20869 event.defaultPrevented = false; 20870 20871 // Stop the event from bubbling 20872 event.stopPropagation = function () { 20873 if (old.stopPropagation) { 20874 old.stopPropagation(); 20875 } 20876 event.cancelBubble = true; 20877 old.cancelBubble = true; 20878 event.isPropagationStopped = returnTrue; 20879 }; 20880 20881 event.isPropagationStopped = returnFalse; 20882 20883 // Stop the event from bubbling and executing other handlers 20884 event.stopImmediatePropagation = function () { 20885 if (old.stopImmediatePropagation) { 20886 old.stopImmediatePropagation(); 20887 } 20888 event.isImmediatePropagationStopped = returnTrue; 20889 event.stopPropagation(); 20890 }; 20891 20892 event.isImmediatePropagationStopped = returnFalse; 20893 20894 // Handle mouse position 20895 if (event.clientX != null) { 20896 var doc = _globalDocument2['default'].documentElement, 20897 body = _globalDocument2['default'].body; 20898 20899 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); 20900 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); 20901 } 20902 20903 // Handle key presses 20904 event.which = event.charCode || event.keyCode; 20905 20906 // Fix button for mouse clicks: 20907 // 0 == left; 1 == middle; 2 == right 20908 if (event.button != null) { 20909 event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0; 20910 } 20911 } 20912 20913 // Returns fixed-up instance 20914 return event; 20915} 20916
20917/** 20918 * Clean up the listener cache and dispatchers 20919* 20920 * @param {Element|Object} elem Element to clean up 20921 * @param {String} type Type of event to clean up 20922 * @private 20923 * @method _cleanUpEvents 20924 */ 20925function _cleanUpEvents(elem, type) { 20926 var data = Dom.getElData(elem); 20927 20928 // Remove the events of a particular type if there are none left 20929 if (data.handlers[type].length === 0) { 20930 delete data.handlers[type]; 20931 // data.handlers[type] = null; 20932 // Setting to null was causing an error with data.handlers 20933 20934 // Remove the meta-handler from the element 20935 if (elem.removeEventListener) { 20936 elem.removeEventListener(type, data.dispatcher, false); 20937 } else if (elem.detachEvent) { 20938 elem.detachEvent('on' + type, data.dispatcher); 20939 } 20940 } 20941 20942 // Remove the events object if there are no types left 20943 if (Object.getOwnPropertyNames(data.handlers).length <= 0) { 20944 delete data.handlers; 20945 delete data.dispatcher; 20946 delete data.disabled; 20947 } 20948 20949 // Finally remove the element data if there is no data left 20950 if (Object.getOwnPropertyNames(data).length === 0) { 20951 Dom.removeElData(elem); 20952 } 20953} 20954 20955/** 20956 * Loops through an array of event types and calls the requested method for each type. 20957 * 20958 * @param {Function} fn The event method we want to use. 20959 * @param {Element|Object} elem Element or object to bind listeners to 20960 * @param {String} type Type of event to bind to. 20961 * @param {Function} callback Event listener. 20962 * @private 20963 * @function _handleMultipleEvents 20964 */ 20965function _handleMultipleEvents(fn, elem, types, callback) { 20966 types.forEach(function (type) { 20967 //Call the event method for each one of the types 20968 fn(elem, type, callback); 20969 }); 20970} 20971 20972},{"./dom.js":143,"./guid.js":147,"global/document":1,"global/window":2}],145:[function(_dereq_,module,exports){ 20973/** 20974 * @file fn.js 20975 */ 20976'use strict'; 20977 20978exports.__esModule = true; 20979 20980var _guidJs = _dereq_('./guid.js'); 20981 20982/** 20983 * Bind (a.k.a proxy or Context). A simple method for changing the context of a function 20984 * It also stores a unique id on the function so it can be easily removed from events 20985 * 20986 * @param {*} context The object to bind as scope 20987 * @param {Function} fn The function to be bound to a scope 20988 * @param {Number=} uid An optional unique ID for the function to be set 20989 * @return {Function} 20990 * @private 20991 * @method bind 20992 */ 20993var bind = function bind(context, fn, uid) { 20994 // Make sure the function has a unique ID 20995 if (!fn.guid) { 20996 fn.guid = _guidJs.newGUID(); 20997 } 20998 20999 // Create the new function that changes the context 21000 var ret = function ret() { 21001 return fn.apply(context, arguments); 21002 }; 21003 21004 // Allow for the ability to individualize this function 21005 // Needed in the case where multiple objects might share the same prototype 21006 // IF both items add an event listener with the same function, then you try to remove just one 21007 // it will remove both because they both have the same guid. 21008 // when using this, you need to use the bind method when you remove the listener as well. 21009 // currently used in text tracks 21010 ret.guid = uid ? uid + '_' + fn.guid : fn.guid; 21011 21012 return ret; 21013}; 21014exports.bind = bind; 21015 21016},{"./guid.js":147}],146:[function(_dereq_,module,exports){ 21017/** 21018 * @file format-time.js 21019 * 21020 * Format seconds as a time string, H:MM:SS or M:SS 21021 * Supplying a guide (in seconds) will force a number of leading zeros 21022 * to cover the length of the guide 21023 * 21024 * @param {Number} seconds Number of seconds to be turned into a string 21025 * @param {Number} guide Number (in seconds) to model the string after 21026 * @return {String} Time formatted as H:MM:SS or M:SS 21027 * @private 21028 * @function formatTime 21029 */ 21030'use strict'; 21031 21032exports.__esModule = true; 21033function formatTime(seconds) { 21034 var guide = arguments.length <= 1 || arguments[1] === undefined ? seconds : arguments[1]; 21035 return (function () { 21036 seconds = seconds < 0 ? 0 : seconds; 21037 var s = Math.floor(seconds % 60); 21038 var m = Math.floor(seconds / 60 % 60); 21039 var h = Math.floor(seconds / 3600); 21040 var gm = Math.floor(guide / 60 % 60); 21041 var gh = Math.floor(guide / 3600); 21042 21043 // handle invalid times 21044 if (isNaN(seconds) || seconds === Infinity) { 21045 // '-' is false for all relational operators (e.g. <, >
21045=) so this setting 21046 // will add the minimum number of fields specified by the guide 21047 h = m = s = '-'; 21048 } 21049 21050 // Check if we need to show hours 21051 h = h > 0 || gh > 0 ? h + ':' : ''; 21052 21053 // If hours are showing, we may need to add a leading zero. 21054 // Always show at least one digit of minutes. 21055 m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':'; 21056 21057 // Check if leading zero is need for seconds 21058 s = s < 10 ? '0' + s : s; 21059 21060 return h + m + s; 21061 })(); 21062} 21063 21064exports['default'] = formatTime; 21065module.exports = exports['default']; 21066 21067},{}],147:[function(_dereq_,module,exports){ 21068/** 21069 * @file guid.js 21070 * 21071 * Unique ID for an element or function 21072 * @type {Number} 21073 * @private 21074 */ 21075"use strict"; 21076 21077exports.__esModule = true; 21078exports.newGUID = newGUID; 21079var _guid = 1; 21080 21081/** 21082 * Get the next unique ID 21083 * 21084 * @return {String} 21085 * @function newGUID 21086 */ 21087 21088function newGUID() { 21089 return _guid++; 21090} 21091 21092},{}],148:[function(_dereq_,module,exports){ 21093/** 21094 * @file log.js 21095 */ 21096'use strict'; 21097 21098exports.__esModule = true; 21099 21100function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21101 21102var _globalWindow = _dereq_('global/window'); 21103 21104var _globalWindow2 = _interopRequireDefault(_globalWindow); 21105 21106/** 21107 * Log plain debug messages 21108 */ 21109var log = function log() { 21110 _logType(null, arguments); 21111}; 21112 21113/** 21114 * Keep a history of log messages 21115 * @type {Array} 21116 */ 21117log.history = []; 21118 21119/** 21120 * Log error messages 21121 */ 21122log.error = function () { 21123 _logType('error', arguments); 21124}; 21125 21126/** 21127 * Log warning messages 21128 */ 21129log.warn = function () { 21130 _logType('warn', arguments); 21131}; 21132 21133/** 21134 * Log messages to the console and history based on the type of message 21135 * 21136 * @param {String} type The type of message, or `null` for `log` 21137 * @param {Object} args The args to be passed to the log 21138 * @private 21139 * @method _logType 21140 */ 21141function _logType(type, args) { 21142 // convert args to an array to get array functions 21143 var argsArray = Array.prototype.slice.call(args); 21144 // if there's no console then don't try to output messages 21145 // they will still be stored in log.history 21146 // Was setting these once outside of this function, but containing them 21147 // in the function makes it easier to test cases where console doesn't exist 21148 var noop = function noop() {}; 21149 21150 var console = _globalWindow2['default']['console'] || { 21151 'log': noop, 21152 'warn': noop, 21153 'error': noop 21154 }; 21155 21156 if (type) { 21157 // add the type to the front of the message 21158 argsArray.unshift(type.toUpperCase() + ':'); 21159 } else { 21160 // default to log with no prefix 21161 type = 'log'; 21162 } 21163 21164 // add to history 21165 log.history.push(argsArray); 21166 21167 // add console prefix after adding to history 21168 argsArray.unshift('VIDEOJS:'); 21169 21170 // call appropriate log function 21171 if (console[type].apply) { 21172 console[type].apply(console, argsArray); 21173 } else { 21174 // ie8 doesn't allow error.apply, but it will just join() the array anyway 21175 console[type](argsArray.join(' ')); 21176 } 21177} 21178 21179exports['default'] = log; 21180module.exports = exports['default']; 21181 21182},{"global/window":2}],149:[function(_dereq_,module,exports){ 21183/** 21184 * @file merge-options.js 21185 */ 21186'use strict'; 21187 21188exports.__esModule = true; 21189exports['default'] = mergeOptions; 21190 21191function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21192 21193var _lodashCompatObjectMerge = _dereq_('lodash-compat/object/merge'); 21194 21195var _lodashCompatObjectMerge2 = _interopRequireDefault(_lodashCompatObjectMerge); 21196 21197function isPlain(obj) { 21198 return !!obj && typeof obj === 'object' && obj.toString() === '[object Object]' && obj.constructor === Object; 21199} 21200 21201/** 21202 * Merge customizer. video.js simply overwrites non-simple objects 21203 * (like arrays) instead of attempting to overlay them. 21204 * @see https://lodash.com/docs#merge 21205 */ 21206var customizer = function customizer(destination, source) { 21207 // If we're not working with a plain object, copy the value as is 21208 // If source is an array, for instance, it will replace destination 21209 if (!isPlain(source)) { 21210 return source; 21211 } 21212 21213 // If the new value is a plain object but the first object value is not 21214 // we need to create a new object for the first object to merge with. 21215 // This makes it consistent with how merge() works by default 21216 // and also protects from later changes the to first object affecting 21217 // the second object's values. 21218 if (!isPlain(destination)) { 21219 return mergeOptions(source); 21220 } 21221}; 21222 21223/** 21224 * Merge one or more options objects, recursively merging **only** 21225 * plain object properties. Previously `deepMerge`. 21226 * 21227 * @param {...Object} source One or more objects to merge 21228 * @returns {Object} a new object that is the union of all 21229 * provided objects 21230 * @function mergeOptions 21231 */ 21232 21233function mergeOptions() { 21234 // contruct the call dynamically to handle the variable number of 21235 // objects to merge 21236 var args = Array.prototype.slice.call(arguments); 21237 21238 // unshift an empty object into the front of the call as the target 21239 // of the merge 21240 args.unshift({}); 21241 21242 // customize conflict resolution to match our historical merge behavior 21243 args.push(customizer); 21244
21245 _lodashCompatObjectMerge2['default'].apply(null, args); 21246 21247 // return the mutated result object 21248 return args[0]; 21249} 21250 21251module.exports = exports['default']; 21252 21253},{"lodash-compat/object/merge":40}],150:[function(_dereq_,module,exports){ 21254'use strict'; 21255 21256exports.__esModule = true; 21257 21258function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21259 21260var _globalDocument = _dereq_('global/document'); 21261 21262var _globalDocument2 = _interopRequireDefault(_globalDocument); 21263 21264var createStyleElement = function createStyleElement(className) { 21265 var style = _globalDocument2['default'].createElement('style'); 21266 style.className = className; 21267 21268 return style; 21269}; 21270 21271exports.createStyleElement = createStyleElement; 21272var setTextContent = function setTextContent(el, content) { 21273 if (el.styleSheet) { 21274 el.styleSheet.cssText = content; 21275 } else { 21276 el.textContent = content; 21277 } 21278}; 21279exports.setTextContent = setTextContent; 21280 21281},{"global/document":1}],151:[function(_dereq_,module,exports){ 21282'use strict'; 21283 21284exports.__esModule = true; 21285exports.createTimeRanges = createTimeRanges; 21286 21287function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21288 21289var _logJs = _dereq_('./log.js'); 21290 21291var _logJs2 = _interopRequireDefault(_logJs); 21292 21293/** 21294 * @file time-ranges.js 21295 * 21296 * Should create a fake TimeRange object 21297 * Mimics an HTML5 time range instance, which has functions that 21298 * return the start and end times for a range 21299 * TimeRanges are returned by the buffered() method 21300 * 21301 * @param {(Number|Array)} Start of a single range or an array of ranges 21302 * @param {Number} End of a single range 21303 * @private 21304 * @method createTimeRanges 21305 */ 21306 21307function createTimeRanges(start, end) { 21308 if (Array.isArray(start)) { 21309 return createTimeRangesObj(start); 21310 } else if (start === undefined || end === undefined) { 21311 return createTimeRangesObj(); 21312 } 21313 return createTimeRangesObj([[start, end]]); 21314} 21315 21316exports.createTimeRange = createTimeRanges; 21317 21318function createTimeRangesObj(ranges) { 21319 if (ranges === undefined || ranges.length === 0) { 21320 return { 21321 length: 0, 21322 start: function start() { 21323 throw new Error('This TimeRanges object is empty'); 21324 }, 21325 end: function end() { 21326 throw new Error('This TimeRanges object is empty'); 21327 } 21328 }; 21329 } 21330 return { 21331 length: ranges.length, 21332 start: getRange.bind(null, 'start', 0, ranges), 21333 end: getRange.bind(null, 'end', 1, ranges) 21334 }; 21335} 21336 21337function getRange(fnName, valueIndex, ranges, rangeIndex) { 21338 if (rangeIndex === undefined) { 21339 _logJs2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.'); 21340 rangeIndex = 0; 21341 } 21342 rangeCheck(fnName, rangeIndex, ranges.length - 1); 21343 return ranges[rangeIndex][valueIndex]; 21344} 21345 21346function rangeCheck(fnName, index, maxIndex) { 21347 if (index < 0 || index > maxIndex) { 21348 throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').'); 21349 } 21350} 21351 21352},{"./log.js":148}],152:[function(_dereq_,module,exports){ 21353/** 21354 * @file to-title-case.js 21355 * 21356 * Uppercase the first letter of a string 21357 * 21358 * @param {String} string String to be uppercased 21359 * @return {String} 21360 * @private 21361 * @method toTitleCase 21362 */ 21363"use strict"; 21364 21365exports.__esModule = true; 21366function toTitleCase(string) { 21367 return string.charAt(0).toUpperCase() + string.slice(1); 21368} 21369 21370exports["default"] = toTitleCase; 21371module.exports = exports["default"]; 21372 21373},{}],153:[function(_dereq_,module,exports){ 21374/** 21375 * @file url.js 21376 */ 21377'use strict'; 21378 21379exports.__esModule = true; 21380 21381function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21382 21383var _globalDocument = _dereq_('global/document'); 21384 21385var _globalDocument2 = _interopRequireDefault(_globalDocument); 21386 21387var _globalWindow = _dereq_('global/window'); 21388 21389var _globalWindow2 = _interopRequireDefault(_globalWindow); 21390 21391/** 21392 * Resolve and parse the elements of a URL 21393 * 21394 * @param {String} url The url to parse 21395 * @return {Object} An object of url details 21396 * @method parseUrl 21397 */ 21398var parseUrl = function parseUrl(url) { 21399 var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host']; 21400 21401 // add the url to an anchor and let the browser parse the URL 21402 var a = _globalDocument2['default'].createElement('a'); 21403 a.href = url; 21404 21405 // IE8 (and 9?) Fix
21406 // ie8 doesn't parse the URL correctly until the anchor is actually 21407 // added to the body, and an innerHTML is needed to trigger the parsing 21408 var addToBody = a.host === '' && a.protocol !== 'file:'; 21409 var div = undefined; 21410 if (addToBody) { 21411 div = _globalDocument2['default'].createElement('div'); 21412 div.innerHTML = '<a href="' + url + '"></a>'; 21413 a = div.firstChild; 21414 // prevent the div from affecting layout 21415 div.setAttribute('style', 'display:none; position:absolute;'); 21416 _globalDocument2['default'].body.appendChild(div); 21417 } 21418 21419 // Copy the specific URL properties to a new object 21420 // This is also needed for IE8 because the anchor loses its 21421 // properties when it's removed from the dom 21422 var details = {}; 21423 for (var i = 0; i < props.length; i++) { 21424 details[props[i]] = a[props[i]]; 21425 } 21426 21427 // IE9 adds the port to the host property unlike everyone else. If 21428 // a port identifier is added for standard ports, strip it. 21429 if (details.protocol === 'http:') { 21430 details.host = details.host.replace(/:80$/, ''); 21431 } 21432 if (details.protocol === 'https:') { 21433 details.host = details.host.replace(/:443$/, ''); 21434 } 21435 21436 if (addToBody) { 21437 _globalDocument2['default'].body.removeChild(div); 21438 } 21439 21440 return details; 21441}; 21442 21443exports.parseUrl = parseUrl; 21444/** 21445 * Get absolute version of relative URL. Used to tell flash correct URL. 21446 * http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue 21447 * 21448 * @param {String} url URL to make absolute 21449 * @return {String} Absolute URL 21450 * @private 21451 * @method getAbsoluteURL 21452 */ 21453var getAbsoluteURL = function getAbsoluteURL(url) { 21454 // Check if absolute URL 21455 if (!url.match(/^https?:\/\//)) { 21456 // Convert to absolute URL. Flash hosted off-site needs an absolute URL. 21457 var div = _globalDocument2['default'].createElement('div'); 21458 div.innerHTML = '<a href="' + url + '">x</a>'; 21459 url = div.firstChild.href; 21460 } 21461 21462 return url; 21463}; 21464 21465exports.getAbsoluteURL = getAbsoluteURL; 21466/** 21467 * Returns the extension of the passed file name. It will return an empty string if you pass an invalid path 21468 * 21469 * @param {String} path The fileName path like '/path/to/file.mp4' 21470 * @returns {String} The extension in lower case or an empty string if no extension could be found. 21471 * @method getFileExtension 21472 */ 21473var getFileExtension = function getFileExtension(path) { 21474 if (typeof path === 'string') { 21475 var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i; 21476 var pathParts = splitPathRe.exec(path); 21477 21478 if (pathParts) { 21479 return pathParts.pop().toLowerCase(); 21480 } 21481 } 21482 21483 return ''; 21484}; 21485 21486exports.getFileExtension = getFileExtension; 21487/** 21488 * Returns whether the url passed is a cross domain request or not. 21489 * 21490 * @param {String} url The url to check 21491 * @return {Boolean} Whether it is a cross domain request or not 21492 * @method isCrossOrigin 21493 */ 21494var isCrossOrigin = function isCrossOrigin(url) { 21495 var winLoc = _globalWindow2['default'].location; 21496 var urlInfo = parseUrl(url); 21497 21498 // IE8 protocol relative urls will return ':' for protocol 21499 var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol; 21500 21501 // Check if url is for another domain/origin 21502 // IE8 doesn't know location.origin, so we won't rely on it here 21503 var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host; 21504 21505 return crossOrigin; 21506}; 21507exports.isCrossOrigin = isCrossOrigin; 21508 21509},{"global/document":1,"global/window":2}],154:[function(_dereq_,module,exports){ 21510/** 21511 * @file video.js 21512 */ 21513'use strict'; 21514 21515exports.__esModule = true; 21516 21517function _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; } } 21518 21519function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21520 21521var _globalWindow = _dereq_('global/window'); 21522 21523var _globalWindow2 = _interopRequireDefault(_globalWindow); 21524 21525var _globalDocument = _dereq_('global/document'); 21526 21527var _globalDocument2 = _interopRequireDefault(_globalDocument); 21528 21529var _setup = _dereq_('./setup'); 21530 21531var setup = _interopRequireWildcard(_setup); 21532 21533var _utilsStylesheetJs = _dereq_('./utils/stylesheet.js'); 21534 21535var stylesheet = _interopRequireWildcard(_utilsStylesheetJs); 21536 21537var _component = _dereq_('./component'); 21538 21539var _component2 = _interopRequireDefault(_component); 21540 21541var _eventTarget = _dereq_('./event-target'); 21542 21543var _eventTarget2 = _interopRequireDefault(_eventTarget); 21544 21545var _utilsEventsJs = _dereq_('./utils/events.js'); 21546 21547var Events = _interopRequireWildcard(_utilsEventsJs); 21548 21549var _player = _dereq_('./player'); 21550 21551var _player2 = _interopRequireDefault(_player); 21552 21553var _pluginsJs = _dereq_('./plugins.js'); 21554 21555var _pluginsJs2 = _interopRequireDefault(_pluginsJs); 21556 21557var _srcJsUtilsMergeOptionsJs = _dereq_('../../src/js/utils/merge-options.js'); 21558 21559var _srcJsUtilsMergeOptionsJs2 = _interopRequireDefault(_srcJsUtilsMergeOptionsJs); 21560 21561var _utilsFnJs = _dereq_('./utils/fn.js'); 21562 21563var Fn = _interopRequireWildcard(_utilsFnJs); 21564 21565var _tracksTextTrackJs = _dereq_('./tracks/text-track.js'); 21566 21567var _tracksTextTrackJs2 = _interopRequireDefault(_tracksTextTrackJs); 21568 21569var _tracksAudioTrackJs = _dereq_('./tracks/audio-track.js'); 21570 21571var _tracksAudioTrackJs2 = _interopRequireDefault(_tracksAudioTrackJs); 21572 21573var _tracksVideoTrackJs = _dereq_('./tracks/video-track.js'); 21574 21575var _tracksVideoTrackJs2 = _interopRequireDefault(_tracksVideoTrackJs); 21576 21577var _objectAssign = _dereq_('object.assign'); 21578 21579var _objectAssign2 = _interopRequireDefault(_objectAssign); 21580 21581var _utilsTimeRangesJs = _dereq_('./utils/time-ranges.js'); 21582 21583var _utilsFormatTimeJs = _dereq_('./utils/format-time.js'); 21584 21585var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 21586 21587var _utilsLogJs = _dereq_('./utils/log.js'); 21588 21589var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 21590 21591var _utilsDomJs = _dereq_('./utils/dom.js'); 21592 21593var Dom = _interopRequireWildcard(_utilsDomJs); 21594 21595var _utilsBrowserJs = _dereq_('./utils/browser.js'); 21596 21597var browser = _interopRequireWildcard(_utilsBrowserJs); 21598 21599var _utilsUrlJs = _dereq_('./utils/url.js'); 21600 21601var Url = _interopRequireWildcard(_utilsUrlJs); 21602 21603var _extendJs = _dereq_('./extend.js'); 21604 21605var _extendJs2 = _interopRequireDefault(_extendJs); 21606 21607var _lodashCompatObjectMerge = _dereq_('lodash-compat/object/merge'); 21608 21609var _lodashCompatObjectMerge2 = _interopRequireDefault(_lodashCompatObjectMerge); 21610 21611var _utilsCreateDeprecationProxyJs = _dereq_('./utils/create-deprecation-proxy.js'); 21612 21613var _utilsCreateDeprecationProxyJs2 = _interopRequireDefault(_utilsCreateDeprecationProxyJs); 21614 21615var _xhr = _dereq_('xhr'); 21616
21617var _xhr2 = _interopRequireDefault(_xhr); 21618 21619// Include the built-in techs 21620 21621var _techTechJs = _dereq_('./tech/tech.js'); 21622 21623var _techTechJs2 = _interopRequireDefault(_techTechJs); 21624 21625var _techHtml5Js = _dereq_('./tech/html5.js'); 21626 21627var _techHtml5Js2 = _interopRequireDefault(_techHtml5Js); 21628 21629var _techFlashJs = _dereq_('./tech/flash.js'); 21630 21631var _techFlashJs2 = _interopRequireDefault(_techFlashJs); 21632 21633// HTML5 Element Shim for IE8 21634if (typeof HTMLVideoElement === 'undefined') { 21635 _globalDocument2['default'].createElement('video'); 21636 _globalDocument2['default'].createElement('audio'); 21637 _globalDocument2['default'].createElement('track'); 21638} 21639 21640/** 21641 * Doubles as the main function for users to create a player instance and also 21642 * the main library object. 21643 * The `videojs` function can be used to initialize or retrieve a player. 21644 * ```js 21645 * var myPlayer = videojs('my_video_id'); 21646 * ``` 21647 * 21648 * @param {String|Element} id Video element or video element ID 21649 * @param {Object=} options Optional options object for config/settings 21650 * @param {Function=} ready Optional ready callback 21651 * @return {Player} A player instance 21652 * @mixes videojs 21653 * @method videojs 21654 */ 21655function videojs(id, options, ready) { 21656 var tag = undefined; // Element of ID 21657 21658 // Allow for element or ID to be passed in 21659 // String ID 21660 if (typeof id === 'string') { 21661 21662 // Adjust for jQuery ID syntax 21663 if (id.indexOf('#') === 0) { 21664 id = id.slice(1); 21665 } 21666 21667 // If a player instance has already been created for this ID return it. 21668 if (videojs.getPlayers()[id]) { 21669 21670 // If options or ready funtion are passed, warn 21671 if (options) { 21672 _utilsLogJs2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.'); 21673 } 21674 21675 if (ready) { 21676 videojs.getPlayers()[id].ready(ready); 21677 } 21678 21679 return videojs.getPlayers()[id]; 21680 21681 // Otherwise get element for ID 21682 } else { 21683 tag = Dom.getEl(id); 21684 } 21685 21686 // ID is a media element 21687 } else { 21688 tag = id; 21689 } 21690 21691 // Check for a useable element 21692 if (!tag || !tag.nodeName) { 21693 // re: nodeName, could be a box div also 21694 throw new TypeError('The element or ID supplied is not valid. (videojs)'); // Returns 21695 } 21696 21697 // Element may have a player attr referring to an already created player instance. 21698 // If not, set up a new player and return the instance. 21699 return tag['player'] || _player2['default'].players[tag.playerId] || new _player2['default'](tag, options, ready); 21700} 21701 21702// Add default styles 21703if (_globalWindow2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) { 21704 var style = Dom.$('.vjs-styles-defaults'); 21705 21706 if (!style) { 21707 style = stylesheet.createStyleElement('vjs-styles-defaults'); 21708 var head = Dom.$('head'); 21709 head.insertBefore(style, head.firstChild); 21710 stylesheet.setTextContent(style, '\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n '); 21711 } 21712} 21713 21714// Run Auto-load players 21715// You have to wait at least once in case this script is loaded after your video in the DOM (weird behavior only with minified version) 21716setup.autoSetupTimeout(1, videojs); 21717 21718/* 21719 * Current software version (semver) 21720 * 21721 * @type {String} 21722 */ 21723videojs.VERSION = '5.10.5'; 21724 21725/** 21726 * The global options object. These are the settings that take effect 21727 * if no overrides are specified when the player is created. 21728 * 21729 * ```js 21730 * videojs.options.autoplay = true 21731 * // -> all players will autoplay by default 21732 * ``` 21733 * 21734 * @type {Object} 21735 */ 21736videojs.options = _player2['default'].prototype.options_; 21737 21738/** 21739 * Get an object with the currently created players, keyed by player ID 21740 * 21741 * @return {Object} The created players 21742 * @mixes videojs 21743 * @method getPlayers 21744 */ 21745videojs.getPlayers = function () { 21746 return _player2['default'].players; 21747}; 21748 21749/** 21750 * For backward compatibility, expose players object. 21751 * 21752 * @deprecated 21753 * @memberOf videojs 21754 * @property {Object|Proxy} players 21755 */ 21756videojs.players = _utilsCreateDeprecationProxyJs2['default'](_player2['default'].players, { 21757 get: 'Access to videojs.players is deprecated; use videojs.getPlayers instead', 21758 set: 'Modification of videojs.players is deprecated' 21759}); 21760 21761/** 21762 * Get a component class object by name 21763 * ```js 21764 * var VjsButton = videojs.getComponent('Button'); 21765 * // Create a new instance of the component 21766 * var myButton = new VjsButton(myPlayer); 21767 * ``` 21768 * 21769 * @return {Component} Component identified by name 21770 * @mixes videojs 21771 * @method getComponent 21772 */ 21773videojs.getComponent = _component2['default'].getComponent; 21774 21775/** 21776 * Register a component so it can referred to by name 21777 * Used when adding to other 21778 * components, either through addChild 21779 * `component.addChild('myComponent')` 21780 * or through default children options 21781 * `{ children: ['myComponent'] }`. 21782 * ```js 21783 * // Get a component to subclass 21784 * var VjsButton = videojs.getComponent('Button'); 21785 * // Subclass the component (see 'extend' doc for more info) 21786 * var MySpecialButton = videojs.extend(VjsButton, {}); 21787 * // Register the new component 21788 * VjsButton.registerComponent('MySepcialButton', MySepcialButton); 21789 * // (optionally) add the new component as a default player child 21790 * myPlayer.addChild('MySepcialButton'); 21791 * ``` 21792 * NOTE: You could also just initialize the component before adding. 21793 * `component.addChild(new MyComponent());` 21794 * 21795 * @param {String} The class name of the component 21796 * @param {Component} The component class 21797 * @return {Component} The newly registered component 21798 * @mixes videojs 21799 * @method registerComponent 21800 */ 21801videojs.registerComponent = function (name, comp) { 21802 if (_techTechJs2['default'].isTech(comp)) { 21803 _utilsLogJs2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)'); 21804 } 21805 21806 _component2['default'].registerComponent.call(_component2['default'], name, comp); 21807}; 21808 21809/** 21810 * Get a Tech class object by name 21811 * ```js 21812 * var Html5 = videojs.getTech('Html5'); 21813 * // Create a new instance of the component 21814 * var html5 = new Html5(options); 21815 * ``` 21816 * 21817 * @return {Tech} Tech identified by name 21818 * @mixes videojs 21819 * @method getComponent 21820 */ 21821videojs.getTech = _techTechJs2['default'].getTech; 21822 21823/** 21824 * Register a Tech so it can referred to by name. 21825 * This is used in the tech order for the player. 21826 * 21827 * ```js 21828 * // get the Html5 Tech 21829 * var Html5 = videojs.getTech('Html5'); 21830 * var MyTech = videojs.extend(Html5, {}); 21831 * // Register the new Tech 21832 * VjsButton.registerTech('Tech', MyTech); 21833 * var player = videojs('myplayer', { 21834 * techOrder: ['myTech', 'html5'] 21835 * }); 21836 * ``` 21837 * 21838 * @param {String} The class name of the tech 21839 * @param {Tech} The tech class 21840 * @return {Tech} The newly registered Tech 21841 * @mixes videojs 21842 * @method registerTech 21843 */ 21844videojs.registerTech = _techTechJs2['default'].registerTech; 21845 21846/** 21847 * A suite of browser and device tests 21848 * 21849 * @type {Object} 21850 * @private 21851 */ 21852videojs.browser = browser; 21853 21854/** 21855 * Whether or not the browser supports touch events. Included for backward 21856 * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED` 21857 * instead going forward. 21858 * 21859 * @deprecated 21860 * @type {Boolean} 21861 */ 21862videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED; 21863 21864/** 21865 * Subclass an existing class 21866 * Mimics ES6 subclassing with the `extend` keyword 21867 * ```js 21868 * // Create a basic javascript 'class' 21869 * function MyClass(name){ 21870 * // Set a property at initialization 21871 * this.myName = name; 21872 * } 21873 * // Create an instance method 21874 * MyClass.prototype.sayMyName = function(){ 21875 * alert(this.myName); 21876 * }; 21877 * // Subclass the exisitng class and change the name 21878 * // when initializing 21879 * var MySubClass = videojs.extend(MyClass, { 21880 * constructor: function(name) { 21881 * // Call the super class constructor for the subclass 21882 * MyClass.call(this, name) 21883 * } 21884 * }); 21885 * // Create an instance of the new sub class 21886 * var myInstance = new MySubClass('John'); 21887 * myInstance.sayMyName(); // -> should alert "John" 21888 * ``` 21889 * 21890 * @param {Function} The Class to subclass 21891 * @param {Object} An object including instace methods for the new class 21892 * Optionally including a `constructor` function 21893 * @return {Function} The newly created subclass 21894 * @mixes videojs 21895 * @method extend 21896 */ 21897videojs.extend = _extendJs2['default']; 21898 21899/** 21900 * Merge two options objects recursively 21901 * Performs a deep merge like lodash.merge but **only merges plain objects** 21902 * (not arrays, elements, anything else) 21903 * Other values will be copied directly from the second object. 21904 * ```js 21905 * var defaultOptions = { 21906 * foo: true, 21907 * bar: { 21908 * a: true, 21909 * b: [1,2,3] 21910 * } 21911 * }; 21912 * var newOptions = { 21913 * foo: false, 21914 * bar: { 21915 * b: [4,5,6] 21916 * } 21917 * }; 21918 * var result = videojs.mergeOptions(defaultOptions, newOptions); 21919 * // result.foo = false;
21920 * // result.bar.a = true; 21921 * // result.bar.b = [4,5,6]; 21922 * ``` 21923 * 21924 * @param {Object} defaults The options object whose values will be overriden 21925 * @param {Object} overrides The options object with values to override the first 21926 * @param {Object} etc Any number of additional options objects 21927 * 21928 * @return {Object} a new object with the merged values 21929 * @mixes videojs 21930 * @method mergeOptions 21931 */ 21932videojs.mergeOptions = _srcJsUtilsMergeOptionsJs2['default']; 21933 21934/** 21935 * Change the context (this) of a function 21936 * 21937 * videojs.bind(newContext, function(){ 21938 * this === newContext 21939 * }); 21940 * 21941 * NOTE: as of v5.0 we require an ES5 shim, so you should use the native 21942 * `function(){}.bind(newContext);` instead of this. 21943 * 21944 * @param {*} context The object to bind as scope 21945 * @param {Function} fn The function to be bound to a scope 21946 * @param {Number=} uid An optional unique ID for the function to be set 21947 * @return {Function} 21948 */ 21949videojs.bind = Fn.bind; 21950 21951/** 21952 * Create a Video.js player plugin 21953 * Plugins are only initialized when options for the plugin are included 21954 * in the player options, or the plugin function on the player instance is 21955 * called. 21956 * **See the plugin guide in the docs for a more detailed example** 21957 * ```js 21958 * // Make a plugin that alerts when the player plays 21959 * videojs.plugin('myPlugin', function(myPluginOptions) { 21960 * myPluginOptions = myPluginOptions || {}; 21961 * 21962 * var player = this; 21963 * var alertText = myPluginOptions.text || 'Player is playing!' 21964 * 21965 * player.on('play', function(){ 21966 * alert(alertText); 21967 * }); 21968 * }); 21969 * // USAGE EXAMPLES 21970 * // EXAMPLE 1: New player with plugin options, call plugin immediately 21971 * var player1 = videojs('idOne', { 21972 * myPlugin: { 21973 * text: 'Custom text!' 21974 * } 21975 * }); 21976 * // Click play 21977 * // --> Should alert 'Custom text!' 21978 * // EXAMPLE 3: New player, initialize plugin later 21979 * var player3 = videojs('idThree'); 21980 * // Click play 21981 * // --> NO ALERT 21982 * // Click pause 21983 * // Initialize plugin using the plugin function on the player instance 21984 * player3.myPlugin({ 21985 * text: 'Plugin added later!' 21986 * }); 21987 * // Click play 21988 * // --> Should alert 'Plugin added later!' 21989 * ``` 21990 * 21991 * @param {String} name The plugin name 21992 * @param {Function} fn The plugin function that will be called with options 21993 * @mixes videojs 21994 * @method plugin 21995 */ 21996videojs.plugin = _pluginsJs2['default']; 21997 21998/** 21999 * Adding languages so that they're available to all players. 22000 * ```js 22001 * videojs.addLanguage('es', { 'Hello': 'Hola' }); 22002 * ``` 22003 * 22004 * @param {String} code The language code or dictionary property 22005 * @param {Object} data The data values to be translated 22006 * @return {Object} The resulting language dictionary object 22007 * @mixes videojs 22008 * @method addLanguage 22009 */ 22010videojs.addLanguage = function (code, data) { 22011 var _merge; 22012 22013 code = ('' + code).toLowerCase(); 22014 return _lodashCompatObjectMerge2['default'](videojs.options.languages, (_merge = {}, _merge[code] = data, _merge))[code]; 22015}; 22016 22017/** 22018 * Log debug messages. 22019 * 22020 * @param {...Object} messages One or more messages to log 22021 */ 22022videojs.log = _utilsLogJs2['default']; 22023 22024/** 22025 * Creates an emulated TimeRange object. 22026 * 22027 * @param {Number|Array} start Start time in seconds or an array of ranges 22028 * @param {Number} end End time in seconds 22029 * @return {Object} Fake TimeRange object 22030 * @method createTimeRange 22031 */ 22032videojs.createTimeRange = videojs.createTimeRanges = _utilsTimeRangesJs.createTimeRanges; 22033 22034/** 22035 * Format seconds as a time string, H:MM:SS or M:SS 22036 * Supplying a guide (in seconds) will force a number of leading zeros 22037 * to cover the length of the guide 22038 * 22039 * @param {Number} seconds Number of seconds to be turned into a string 22040 * @param {Number} guide Number (in seconds) to model the string after 22041 * @return {String} Time formatted as H:MM:SS or M:SS 22042 * @method formatTime 22043 */ 22044videojs.formatTime = _utilsFormatTimeJs2['default']; 22045 22046/** 22047 * Resolve and parse the elements of a URL 22048 * 22049 * @param {String} url The url to parse 22050 * @return {Object} An object of url details 22051 * @method parseUrl 22052 */ 22053videojs.parseUrl = Url.parseUrl; 22054 22055/** 22056 * Returns whether the url passed is a cross domain request or not. 22057 * 22058 * @param {String} url The url to check 22059 * @return {Boolean} Whether it is a cross domain request or not 22060 * @method isCrossOrigin 22061 */
22062videojs.isCrossOrigin = Url.isCrossOrigin; 22063 22064/** 22065 * Event target class. 22066 * 22067 * @type {Function} 22068 */ 22069videojs.EventTarget = _eventTarget2['default']; 22070 22071/** 22072 * Add an event listener to element 22073 * It stores the handler function in a separate cache object 22074 * and adds a generic handler to the element's event, 22075 * along with a unique id (guid) to the element. 22076 * 22077 * @param {Element|Object} elem Element or object to bind listeners to 22078 * @param {String|Array} type Type of event to bind to. 22079 * @param {Function} fn Event listener. 22080 * @method on 22081 */ 22082videojs.on = Events.on; 22083 22084/** 22085 * Trigger a listener only once for an event 22086 * 22087 * @param {Element|Object} elem Element or object to 22088 * @param {String|Array} type Name/type of event 22089 * @param {Function} fn Event handler function 22090 * @method one 22091 */ 22092videojs.one = Events.one; 22093 22094/** 22095 * Removes event listeners from an element 22096 * 22097 * @param {Element|Object} elem Object to remove listeners from 22098 * @param {String|Array=} type Type of listener to remove. Don't include to remove all events from element. 22099 * @param {Function} fn Specific listener to remove. Don't include to remove listeners for an event type. 22100 * @method off 22101 */ 22102videojs.off = Events.off; 22103 22104/** 22105 * Trigger an event for an element 22106 * 22107 * @param {Element|Object} elem Element to trigger an event on 22108 * @param {Event|Object|String} event A string (the type) or an event object with a type attribute 22109 * @param {Object} [hash] data hash to pass along with the event 22110 * @return {Boolean=} Returned only if default was prevented 22111 * @method trigger 22112 */ 22113videojs.trigger = Events.trigger; 22114 22115/** 22116 * A cross-browser XMLHttpRequest wrapper. Here's a simple example: 22117 * 22118 * videojs.xhr({ 22119 * body: someJSONString, 22120 * uri: "/foo", 22121 * headers: { 22122 * "Content-Type": "application/json" 22123 * } 22124 * }, function (err, resp, body) { 22125 * // check resp.statusCode 22126 * }); 22127 * 22128 * Check out the [full 22129 * documentation](https://github.com/Raynos/xhr/blob/v2.1.0/README.md) 22130 * for more options. 22131 * 22132 * @param {Object} options settings for the request. 22133 * @return {XMLHttpRequest|XDomainRequest} the request object. 22134 * @see https://github.com/Raynos/xhr 22135 */ 22136videojs.xhr = _xhr2['default']; 22137 22138/** 22139 * TextTrack class 22140 * 22141 * @type {Function} 22142 */ 22143videojs.TextTrack = _tracksTextTrackJs2['default']; 22144 22145/** 22146 * export the AudioTrack class so that source handlers can create 22147 * AudioTracks and then add them to the players AudioTrackList 22148 * 22149 * @type {Function} 22150 */ 22151videojs.AudioTrack = _tracksAudioTrackJs2['default']; 22152 22153/** 22154 * export the VideoTrack class so that source handlers can create 22155 * VideoTracks and then add them to the players VideoTrackList 22156 * 22157 * @type {Function} 22158 */ 22159videojs.VideoTrack = _tracksVideoTrackJs2['default']; 22160 22161/** 22162 * Determines, via duck typing, whether or not a value is a DOM element. 22163 * 22164 * @method isEl 22165 * @param {Mixed} value 22166 * @return {Boolean} 22167 */ 22168videojs.isEl = Dom.isEl; 22169 22170/** 22171 * Determines, via duck typing, whether or not a value is a text node. 22172 * 22173 * @method isTextNode 22174 * @param {Mixed} value 22175 * @return {Boolean} 22176 */ 22177videojs.isTextNode = Dom.isTextNode; 22178 22179/** 22180 * Creates an element and applies properties. 22181 * 22182 * @method createEl 22183 * @param {String} [tagName='div'] Name of tag to be created. 22184 * @param {Object} [properties={}] Element properties to be applied. 22185 * @param {Object} [attributes={}] Element attributes to be applied. 22186 * @return {Element} 22187 */ 22188videojs.createEl = Dom.createEl; 22189 22190/** 22191 * Check if an element has a CSS class 22192 * 22193 * @method hasClass 22194 * @param {Element} element Element to check 22195 * @param {String} classToCheck Classname to check 22196 */ 22197videojs.hasClass = Dom.hasElClass; 22198 22199/** 22200 * Add a CSS class name to an element 22201 * 22202 * @method addClass 22203 * @param {Element} element Element to add class name to 22204 * @param {String} classToAdd Classname to add 22205 */ 22206videojs.addClass = Dom.addElClass; 22207 22208/** 22209 * Remove a CSS class name from an element 22210 * 22211 * @method removeClass 22212 * @param {Element} element Element to remove from class name 22213 * @param {String} classToRemove Classname to remove 22214 */ 22215videojs.removeClass = Dom.removeElClass; 22216 22217/** 22218 * Adds or removes a CSS class name on an element depending on an optional 22219 * condition or the presence/absence of the class name. 22220 * 22221 * @method toggleElClass 22222 * @param {Element} element 22223 * @param {String} classToToggle 22224 * @param {Boolean|Function} [predicate] 22225 * Can be a function that returns a Boolean. If `true`, the class 22226 * will be added; if `false`, the class will be removed. If not 22227 * given, the class will be added if not present and vice versa. 22228 */ 22229videojs.toggleClass = Dom.toggleElClass; 22230 22231/** 22232 * Apply attributes to an HTML element. 22233 * 22234 * @method setAttributes 22235 * @param {Element} el Target element. 22236 * @param {Object=} attributes Element attributes to be applied. 22237 */ 22238videojs.setAttributes = Dom.setElAttributes; 22239 22240/** 22241 * Get an element's attribute values, as defined on the HTML tag 22242 * Attributes are not the same as properties. They're defined on the tag 22243 * or with setAttribute (which shouldn't be used with HTML) 22244 * This will return true or false for boolean attributes. 22245 * 22246 * @method getAttributes 22247 * @param {Element} tag Element from which to get tag attributes 22248 * @return {Object} 22249 */ 22250videojs.getAttributes = Dom.getElAttributes; 22251 22252/** 22253 * Empties the contents of an element. 22254 * 22255 * @method emptyEl 22256 * @param {Element} el 22257 * @return {Element} 22258 */ 22259videojs.emptyEl = Dom.emptyEl; 22260 22261/** 22262 * Normalizes and appends content to an element. 22263 * 22264 * The content for an element can be passed in multiple types and 22265 * combinations, whose behavior is as follows: 22266 * 22267 * - String 22268 * Normalized into a text node. 22269 * 22270 * - Element, TextNode 22271 * Passed through. 22272 * 22273 * - Array
22274 * A one-dimensional array of strings, elements, nodes, or functions (which 22275 * return single strings, elements, or nodes). 22276 * 22277 * - Function 22278 * If the sole argument, is expected to produce a string, element, 22279 * node, or array. 22280 * 22281 * @method appendContent 22282 * @param {Element} el 22283 * @param {String|Element|TextNode|Array|Function} content 22284 * @return {Element} 22285 */ 22286videojs.appendContent = Dom.appendContent; 22287 22288/** 22289 * Normalizes and inserts content into an element; this is identical to 22290 * `appendContent()`, except it empties the element first. 22291 * 22292 * The content for an element can be passed in multiple types and 22293 * combinations, whose behavior is as follows: 22294 * 22295 * - String 22296 * Normalized into a text node. 22297 * 22298 * - Element, TextNode 22299 * Passed through. 22300 * 22301 * - Array 22302 * A one-dimensional array of strings, elements, nodes, or functions (which 22303 * return single strings, elements, or nodes). 22304 * 22305 * - Function 22306 * If the sole argument, is expected to produce a string, element, 22307 * node, or array. 22308 * 22309 * @method insertContent 22310 * @param {Element} el 22311 * @param {String|Element|TextNode|Array|Function} content 22312 * @return {Element} 22313 */ 22314videojs.insertContent = Dom.insertContent; 22315 22316/* 22317 * Custom Universal Module Definition (UMD) 22318 * 22319 * Video.js will never be a non-browser lib so we can simplify UMD a bunch and 22320 * still support requirejs and browserify. This also needs to be closure 22321 * compiler compatible, so string keys are used. 22322 */ 22323if (typeof define === 'function' && define['amd']) { 22324 define('videojs', [], function () { 22325 return videojs; 22326 }); 22327 22328 // checking that module is an object too because of umdjs/umd#35 22329} else if (typeof exports === 'object' && typeof module === 'object') { 22330 module['exports'] = videojs; 22331 } 22332 22333exports['default'] = videojs; 22334module.exports = exports['default']; 22335 22336},{"../../src/js/utils/merge-options.js":149,"./component":67,"./event-target":104,"./extend.js":105,"./player":113,"./plugins.js":114,"./setup":118,"./tech/flash.js":121,"./tech/html5.js":122,"./tech/tech.js":124,"./tracks/audio-track.js":126,"./tracks/text-track.js":134,"./tracks/video-track.js":139,"./utils/browser.js":140,"./utils/create-deprecation-proxy.js":142,"./utils/dom.js":143,"./utils/events.js":144,"./utils/fn.js":145,"./utils/format-time.js":146,"./utils/log.js":148,"./utils/stylesheet.js":150,"./utils/time-ranges.js":151,"./utils/url.js":153,"global/document":1,"global/window":2,"lodash-compat/object/merge":40,"object.assign":45,"xhr":56}]},{},[154])(154) 22337}); 22338 22339 22340//# sourceMappingURL=video.js.map 22341/* vtt.js - v0.12.1 (https://github.com/mozilla/vtt.js) built on 08-07-2015 */ 22342 22343(function(root) { 22344 var vttjs = root.vttjs = {}; 22345 var cueShim = vttjs.VTTCue; 22346 var regionShim = vttjs.VTTRegion; 22347 var oldVTTCue = root.VTTCue; 22348 var oldVTTRegion = root.VTTRegion; 22349 22350 vttjs.shim = function() { 22351 vttjs.VTTCue = cueShim; 22352 vttjs.VTTRegion = regionShim; 22353 }; 22354 22355 vttjs.restore = function() { 22356 vttjs.VTTCue = oldVTTCue; 22357 vttjs.VTTRegion = oldVTTRegion; 22358 }; 22359}(this)); 22360 22361/** 22362 * Copyright 2013 vtt.js Contributors 22363 * 22364 * Licensed under the Apache License, Version 2.0 (the "License"); 22365 * you may not use this file except in compliance with the License. 22366 * You may obtain a copy of the License at 22367 * 22368 * http://www.apache.org/licenses/LICENSE-2.0 22369 * 22370 * Unless required by applicable law or agreed to in writing, software 22371 * distributed under the License is distributed on an "AS IS" BASIS, 22372 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22373 * See the License for the specific language governing permissions and 22374 * limitations under the License. 22375 */ 22376 22377(function(root, vttjs) { 22378 22379 var autoKeyword = "auto"; 22380 var directionSetting = { 22381 "": true, 22382 "lr": true, 22383 "rl": true 22384 }; 22385 var alignSetting = { 22386 "start": true, 22387 "middle": true, 22388 "end": true, 22389 "left": true, 22390 "right": true 22391 }; 22392 22393 function findDirectionSetting(value) { 22394 if (typeof value !== "string") { 22395 return false; 22396 } 22397 var dir = directionSetting[value.toLowerCase()]; 22398 return dir ? value.toLowerCase() : false; 22399 } 22400 22401 function findAlignSetting(value) { 22402 if (typeof value !== "string") { 22403 return false;
22404 } 22405 var align = alignSetting[value.toLowerCase()]; 22406 return align ? value.toLowerCase() : false; 22407 } 22408 22409 function extend(obj) { 22410 var i = 1; 22411 for (; i < arguments.length; i++) { 22412 var cobj = arguments[i]; 22413 for (var p in cobj) { 22414 obj[p] = cobj[p]; 22415 } 22416 } 22417 22418 return obj; 22419 } 22420 22421 function VTTCue(startTime, endTime, text) { 22422 var cue = this; 22423 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); 22424 var baseObj = {}; 22425 22426 if (isIE8) { 22427 cue = document.createElement('custom'); 22428 } else { 22429 baseObj.enumerable = true; 22430 } 22431 22432 /** 22433 * Shim implementation specific properties. These properties are not in 22434 * the spec. 22435 */ 22436 22437 // Lets us know when the VTTCue's data has changed in such a way that we need 22438 // to recompute its display state. This lets us compute its display state 22439 // lazily. 22440 cue.hasBeenReset = false; 22441 22442 /** 22443 * VTTCue and TextTrackCue properties 22444 * http://dev.w3.org/html5/webvtt/#vttcue-interface 22445 */ 22446 22447 var _id = ""; 22448 var _pauseOnExit = false; 22449 var _startTime = startTime; 22450 var _endTime = endTime; 22451 var _text = text; 22452 var _region = null; 22453 var _vertical = ""; 22454 var _snapToLines = true; 22455 var _line = "auto"; 22456 var _lineAlign = "start"; 22457 var _position = 50; 22458 var _positionAlign = "middle"; 22459 var _size = 50; 22460 var _align = "middle"; 22461 22462 Object.defineProperty(cue, 22463 "id", extend({}, baseObj, { 22464 get: function() { 22465 return _id; 22466 }, 22467 set: function(value) { 22468 _id = "" + value; 22469 } 22470 })); 22471 22472 Object.defineProperty(cue, 22473 "pauseOnExit", extend({}, baseObj, { 22474 get: function() { 22475 return _pauseOnExit; 22476 }, 22477 set: function(value) { 22478 _pauseOnExit = !!value; 22479 } 22480 })); 22481 22482 Object.defineProperty(cue, 22483 "startTime", extend({}, baseObj, { 22484 get: function() { 22485 return _startTime; 22486 }, 22487 set: function(value) { 22488 if (typeof value !== "number") { 22489 throw new TypeError("Start time must be set to a number."); 22490 } 22491 _startTime = value; 22492 this.hasBeenReset = true; 22493 } 22494 })); 22495 22496 Object.defineProperty(cue, 22497 "endTime", extend({}, baseObj, { 22498 get: function() { 22499 return _endTime; 22500 }, 22501 set: function(value) { 22502 if (typeof value !== "number") { 22503 throw new TypeError("End time must be set to a number."); 22504 } 22505 _endTime = value; 22506 this.hasBeenReset = true; 22507 } 22508 })); 22509 22510 Object.defineProperty(cue, 22511 "text", extend({}, baseObj, { 22512 get: function() { 22513 return _text; 22514 }, 22515 set: function(value) { 22516 _text = "" + value; 22517 this.hasBeenReset = true; 22518 } 22519 })); 22520 22521 Object.defineProperty(cue, 22522 "region", extend({}, baseObj, { 22523 get: function() { 22524 return _region; 22525 }, 22526 set: function(value) { 22527 _region = value; 22528 this.hasBeenReset = true; 22529 } 22530 })); 22531 22532 Object.defineProperty(cue, 22533 "vertical", extend({}, baseObj, { 22534 get: function() { 22535 return _vertical; 22536 }, 22537 set: function(value) { 22538 var setting = findDirectionSetting(value); 22539 // Have to check for false because the setting an be an empty string. 22540 if (setting === false) { 22541 throw new SyntaxError("An invalid or illegal string was specified."); 22542 } 22543 _vertical = setting; 22544 this.hasBeenReset = true; 22545 } 22546 })); 22547 22548 Object.defineProperty(cue, 22549 "snapToLines", extend({}, baseObj, { 22550 get: function() { 22551 return _snapToLines; 22552 }, 22553 set: function(value) { 22554 _snapToLines = !!value; 22555 this.hasBeenReset = true; 22556 } 22557 })); 22558 22559 Object.defineProperty(cue, 22560 "line", extend({}, baseObj, { 22561 get: function() { 22562 return _line; 22563 }, 22564 set: function(value) { 22565 if (typeof value !== "number" && value !== autoKeyword) { 22566 throw new SyntaxError("An invalid number or illegal string was specified."); 22567 } 22568 _line = value; 22569 this.hasBeenReset = true; 22570 } 22571 })); 22572 22573 Object.defineProperty(cue, 22574 "lineAlign", extend({}, baseObj, { 22575 get: function() { 22576 return _lineAlign; 22577 }, 22578 set: function(value) {
22579 var setting = findAlignSetting(value); 22580 if (!setting) { 22581 throw new SyntaxError("An invalid or illegal string was specified."); 22582 } 22583 _lineAlign = setting; 22584 this.hasBeenReset = true; 22585 } 22586 })); 22587 22588 Object.defineProperty(cue, 22589 "position", extend({}, baseObj, { 22590 get: function() { 22591 return _position; 22592 }, 22593 set: function(value) { 22594 if (value < 0 || value > 100) { 22595 throw new Error("Position must be between 0 and 100."); 22596 } 22597 _position = value; 22598 this.hasBeenReset = true; 22599 } 22600 })); 22601 22602 Object.defineProperty(cue, 22603 "positionAlign", extend({}, baseObj, { 22604 get: function() { 22605 return _positionAlign; 22606 }, 22607 set: function(value) { 22608 var setting = findAlignSetting(value); 22609 if (!setting) { 22610 throw new SyntaxError("An invalid or illegal string was specified."); 22611 } 22612 _positionAlign = setting; 22613 this.hasBeenReset = true; 22614 } 22615 })); 22616 22617 Object.defineProperty(cue, 22618 "size", extend({}, baseObj, { 22619 get: function() { 22620 return _size; 22621 }, 22622 set: function(value) { 22623 if (value < 0 || value > 100) { 22624 throw new Error("Size must be between 0 and 100."); 22625 } 22626 _size = value; 22627 this.hasBeenReset = true; 22628 } 22629 })); 22630 22631 Object.defineProperty(cue, 22632 "align", extend({}, baseObj, { 22633 get: function() { 22634 return _align; 22635 }, 22636 set: function(value) { 22637 var setting = findAlignSetting(value); 22638 if (!setting) { 22639 throw new SyntaxError("An invalid or illegal string was specified."); 22640 } 22641 _align = setting; 22642 this.hasBeenReset = true; 22643 } 22644 })); 22645 22646 /** 22647 * Other <track> spec defined properties 22648 */ 22649 22650 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state 22651 cue.displayState = undefined; 22652 22653 if (isIE8) { 22654 return cue; 22655 } 22656 } 22657 22658 /** 22659 * VTTCue methods 22660 */ 22661 22662 VTTCue.prototype.getCueAsHTML = function() { 22663 // Assume WebVTT.convertCueToDOMTree is on the global. 22664 return WebVTT.convertCueToDOMTree(window, this.text); 22665 }; 22666 22667 root.VTTCue = root.VTTCue || VTTCue; 22668 vttjs.VTTCue = VTTCue; 22669}(this, (this.vttjs || {}))); 22670 22671/** 22672 * Copyright 2013 vtt.js Contributors 22673 * 22674 * Licensed under the Apache License, Version 2.0 (the "License"); 22675 * you may not use this file except in compliance with the License. 22676 * You may obtain a copy of the License at 22677 * 22678 * http://www.apache.org/licenses/LICENSE-2.0 22679 * 22680 * Unless required by applicable law or agreed to in writing, software 22681 * distributed under the License is distributed on an "AS IS" BASIS, 22682 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22683 * See the License for the specific language governing permissions and 22684 * limitations under the License. 22685 */ 22686 22687(function(root, vttjs) { 22688 22689 var scrollSetting = { 22690 "": true, 22691 "up": true 22692 }; 22693 22694 function findScrollSetting(value) { 22695 if (typeof value !== "string") { 22696 return false; 22697 } 22698 var scroll = scrollSetting[value.toLowerCase()]; 22699 return scroll ? value.toLowerCase() : false; 22700 } 22701 22702 function isValidPercentValue(value) { 22703 return typeof value === "number" && (value >= 0 && value <= 100); 22704 } 22705 22706 // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface 22707 function VTTRegion() { 22708 var _width = 100; 22709 var _lines = 3; 22710 var _regionAnchorX = 0; 22711 var _regionAnchorY = 100; 22712 var _viewportAnchorX = 0; 22713 var _viewportAnchorY = 100; 22714 var _scroll = ""; 22715 22716 Object.defineProperties(this, { 22717 "width": { 22718 enumerable: true, 22719 get: function() { 22720 return _width; 22721 }, 22722 set: function(value) { 22723 if (!isValidPercentValue(value)) { 22724 throw new Error("Width must be between 0 and 100."); 22725 } 22726 _width = value; 22727 } 22728 }, 22729 "lines": { 22730 enumerable: true, 22731 get: function() { 22732 return _lines; 22733 }, 22734 set: function(value) {
vendor: 16,471 bytes, lines 22735-23239
22735 if (typeof value !== "number") { 22736 throw new TypeError("Lines must be set to a number."); 22737 } 22738 _lines = value; 22739 } 22740 }, 22741 "regionAnchorY": { 22742 enumerable: true, 22743 get: function() { 22744 return _regionAnchorY; 22745 }, 22746 set: function(value) { 22747 if (!isValidPercentValue(value)) { 22748 throw new Error("RegionAnchorX must be between 0 and 100."); 22749 } 22750 _regionAnchorY = value; 22751 } 22752 }, 22753 "regionAnchorX": { 22754 enumerable: true, 22755 get: function() { 22756 return _regionAnchorX; 22757 }, 22758 set: function(value) { 22759 if(!isValidPercentValue(value)) { 22760 throw new Error("RegionAnchorY must be between 0 and 100."); 22761 } 22762 _regionAnchorX = value; 22763 } 22764 }, 22765 "viewportAnchorY": { 22766 enumerable: true, 22767 get: function() { 22768 return _viewportAnchorY; 22769 }, 22770 set: function(value) { 22771 if (!isValidPercentValue(value)) { 22772 throw new Error("ViewportAnchorY must be between 0 and 100."); 22773 } 22774 _viewportAnchorY = value; 22775 } 22776 }, 22777 "viewportAnchorX": { 22778 enumerable: true, 22779 get: function() { 22780 return _viewportAnchorX; 22781 }, 22782 set: function(value) { 22783 if (!isValidPercentValue(value)) { 22784 throw new Error("ViewportAnchorX must be between 0 and 100."); 22785 } 22786 _viewportAnchorX = value; 22787 } 22788 }, 22789 "scroll": { 22790 enumerable: true, 22791 get: function() { 22792 return _scroll; 22793 }, 22794 set: function(value) { 22795 var setting = findScrollSetting(value); 22796 // Have to check for false as an empty string is a legal value. 22797 if (setting === false) { 22798 throw new SyntaxError("An invalid or illegal string was specified."); 22799 } 22800 _scroll = setting; 22801 } 22802 } 22803 }); 22804 } 22805 22806 root.VTTRegion = root.VTTRegion || VTTRegion; 22807 vttjs.VTTRegion = VTTRegion; 22808}(this, (this.vttjs || {}))); 22809 22810/** 22811 * Copyright 2013 vtt.js Contributors 22812 * 22813 * Licensed under the Apache License, Version 2.0 (the "License"); 22814 * you may not use this file except in compliance with the License. 22815 * You may obtain a copy of the License at 22816 * 22817 * http://www.apache.org/licenses/LICENSE-2.0 22818 * 22819 * Unless required by applicable law or agreed to in writing, software 22820 * distributed under the License is distributed on an "AS IS" BASIS, 22821 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22822 * See the License for the specific language governing permissions and 22823 * limitations under the License. 22824 */ 22825 22826/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 22827/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 22828 22829(function(global) { 22830 22831 var _objCreate = Object.create || (function() { 22832 function F() {} 22833 return function(o) { 22834 if (arguments.length !== 1) { 22835 throw new Error('Object.create shim only accepts one parameter.'); 22836 } 22837 F.prototype = o; 22838 return new F(); 22839 }; 22840 })(); 22841 22842 // Creates a new ParserError object from an errorData object. The errorData 22843 // object should have default code and message properties. The default message 22844 // property can be overriden by passing in a message parameter. 22845 // See ParsingError.Errors below for acceptable errors. 22846 function ParsingError(errorData, message) { 22847 this.name = "ParsingError"; 22848 this.code = errorData.code; 22849 this.message = message || errorData.message; 22850 } 22851 ParsingError.prototype = _objCreate(Error.prototype); 22852 ParsingError.prototype.constructor = ParsingError; 22853 22854 // ParsingError metadata for acceptable ParsingErrors. 22855 ParsingError.Errors = { 22856 BadSignature: { 22857 code: 0, 22858 message: "Malformed WebVTT signature." 22859 }, 22860 BadTimeStamp: { 22861 code: 1, 22862 message: "Malformed time stamp." 22863 } 22864 }; 22865 22866 // Try to parse input as a time stamp. 22867 function parseTimeStamp(input) { 22868 22869 function computeSeconds(h, m, s, f) { 22870 return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000; 22871 } 22872 22873 var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/); 22874 if (!m) { 22875 return null; 22876 } 22877 22878 if (m[3]) { 22879 // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds] 22880 return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]); 22881 } else if (m[1] > 59) { 22882 // Timestamp takes the form of [hours]:[minutes].[milliseconds] 22883 // First position is hours as it's over 59. 22884 return computeSeconds(m[1], m[2], 0, m[4]); 22885 } else { 22886 // Timestamp takes the form of [minutes]:[seconds].[milliseconds] 22887 return computeSeconds(0, m[1], m[2], m[4]); 22888 } 22889 } 22890 22891 // A settings object holds key/value pairs and will ignore anything but the first 22892 // assignment to a specific key. 22893 function Settings() { 22894 this.values = _objCreate(null); 22895 } 22896 22897 Settings.prototype = { 22898 // Only accept the first assignment to any key. 22899 set: function(k, v) { 22900 if (!this.get(k) && v !== "") { 22901 this.values[k] = v; 22902 } 22903 }, 22904 // Return the value for a key, or a default value. 22905 // If 'defaultKey' is passed then 'dflt' is assumed to be an object with 22906 // a number of possible default values as properties where 'defaultKey' is 22907 // the key of the property that will be chosen; otherwise it's assumed to be 22908 // a single value. 22909 get: function(k, dflt, defaultKey) { 22910 if (defaultKey) { 22911 return this.has(k) ? this.values[k] : dflt[defaultKey]; 22912 } 22913 return this.has(k) ? this.values[k] : dflt; 22914 }, 22915 // Check whether we have a value for a key. 22916 has: function(k) { 22917 return k in this.values; 22918 }, 22919 // Accept a setting if its one of the given alternatives. 22920 alt: function(k, v, a) { 22921 for (var n = 0; n < a.length; ++n) { 22922 if (v === a[n]) { 22923 this.set(k, v); 22924 break; 22925 } 22926 } 22927 }, 22928 // Accept a setting if its a valid (signed) integer. 22929 integer: function(k, v) { 22930 if (/^-?\d+$/.test(v)) { // integer 22931 this.set(k, parseInt(v, 10)); 22932 } 22933 }, 22934 // Accept a setting if its a valid percentage. 22935 percent: function(k, v) { 22936 var m; 22937 if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) { 22938 v = parseFloat(v); 22939 if (v >= 0 && v <= 100) { 22940 this.set(k, v); 22941 return true; 22942 } 22943 } 22944 return false; 22945 } 22946 }; 22947 22948 // Helper function to parse input into groups separated by 'groupDelim', and 22949 // interprete each group as a key/value pair separated by 'keyValueDelim'. 22950 function parseOptions(input, callback, keyValueDelim, groupDelim) { 22951 var groups = groupDelim ? input.split(groupDelim) : [input]; 22952 for (var i in groups) { 22953 if (typeof groups[i] !== "string") { 22954 continue; 22955 } 22956 var kv = groups[i].split(keyValueDelim); 22957 if (kv.length !== 2) { 22958 continue; 22959 } 22960 var k = kv[0]; 22961 var v = kv[1]; 22962 callback(k, v); 22963 } 22964 } 22965 22966 function parseCue(input, cue, regionList) { 22967 // Remember the original input if we need to throw an error. 22968 var oInput = input; 22969 // 4.1 WebVTT timestamp 22970 function consumeTimeStamp() { 22971 var ts = parseTimeStamp(input); 22972 if (ts === null) { 22973 throw new ParsingError(ParsingError.Errors.BadTimeStamp, 22974 "Malformed timestamp: " + oInput); 22975 } 22976 // Remove time stamp from input. 22977 input = input.replace(/^[^\sa-zA-Z-]+/, ""); 22978 return ts; 22979 } 22980 22981 // 4.4.2 WebVTT cue settings 22982 function consumeCueSettings(input, cue) { 22983 var settings = new Settings(); 22984 22985 parseOptions(input, function (k, v) { 22986 switch (k) { 22987 case "region": 22988 // Find the last region we parsed with the same region id. 22989 for (var i = regionList.length - 1; i >= 0; i--) { 22990 if (regionList[i].id === v) { 22991 settings.set(k, regionList[i].region); 22992 break; 22993 } 22994 } 22995 break; 22996 case "vertical": 22997 settings.alt(k, v, ["rl", "lr"]); 22998 break; 22999 case "line": 23000 var vals = v.split(","), 23001 vals0 = vals[0]; 23002 settings.integer(k, vals0); 23003 settings.percent(k, vals0) ? settings.set("snapToLines", false) : null; 23004 settings.alt(k, vals0, ["auto"]); 23005 if (vals.length === 2) { 23006 settings.alt("lineAlign", vals[1], ["start", "middle", "end"]); 23007 } 23008 break; 23009 case "position": 23010 vals = v.split(","); 23011 settings.percent(k, vals[0]); 23012 if (vals.length === 2) { 23013 settings.alt("positionAlign", vals[1], ["start", "middle", "end"]); 23014 } 23015 break; 23016 case "size": 23017 settings.percent(k, v); 23018 break; 23019 case "align": 23020 settings.alt(k, v, ["start", "middle", "end", "left", "right"]); 23021 break; 23022 } 23023 }, /:/, /\s/); 23024 23025 // Apply default values for any missing fields. 23026 cue.region = settings.get("region", null); 23027 cue.vertical = settings.get("vertical", ""); 23028 cue.line = settings.get("line", "auto"); 23029 cue.lineAlign = settings.get("lineAlign", "start"); 23030 cue.snapToLines = settings.get("snapToLines", true); 23031 cue.size = settings.get("size", 100); 23032 cue.align = settings.get("align", "middle"); 23033 cue.position = settings.get("position", { 23034 start: 0, 23035 left: 0, 23036 middle: 50, 23037 end: 100, 23038 right: 100 23039 }, cue.align); 23040 cue.positionAlign = settings.get("positionAlign", { 23041 start: "start", 23042 left: "start", 23043 middle: "middle", 23044 end: "end", 23045 right: "end" 23046 }, cue.align); 23047 } 23048 23049 function skipWhitespace() { 23050 input = input.replace(/^\s+/, ""); 23051 } 23052 23053 // 4.1 WebVTT cue timings. 23054 skipWhitespace(); 23055 cue.startTime = consumeTimeStamp(); // (1) collect cue start time 23056 skipWhitespace(); 23057 if (input.substr(0, 3) !== "-->") { // (3) next characters must match "-->" 23058 throw new ParsingError(ParsingError.Errors.BadTimeStamp, 23059 "Malformed time stamp (time stamps must be separated by '-->'): " + 23060 oInput); 23061 } 23062 input = input.substr(3); 23063 skipWhitespace(); 23064 cue.endTime = consumeTimeStamp(); // (5) collect cue end time 23065 23066 // 4.1 WebVTT cue settings list. 23067 skipWhitespace(); 23068 consumeCueSettings(input, cue); 23069 } 23070 23071 var ESCAPE = { 23072 "&": "&", 23073 "<": "<", 23074 ">": ">", 23075 "‎": "\u200e", 23076 "‏": "\u200f", 23077 " ": "\u00a0" 23078 }; 23079 23080 var TAG_NAME = { 23081 c: "span", 23082 i: "i", 23083 b: "b", 23084 u: "u", 23085 ruby: "ruby", 23086 rt: "rt", 23087 v: "span", 23088 lang: "span" 23089 }; 23090 23091 var TAG_ANNOTATION = { 23092 v: "title", 23093 lang: "lang" 23094 }; 23095 23096 var NEEDS_PARENT = { 23097 rt: "ruby" 23098 }; 23099 23100 // Parse content into a document fragment. 23101 function parseContent(window, input) { 23102 function nextToken() { 23103 // Check for end-of-string. 23104 if (!input) { 23105 return null; 23106 } 23107 23108 // Consume 'n' characters from the input. 23109 function consume(result) { 23110 input = input.substr(result.length); 23111 return result; 23112 } 23113 23114 var m = input.match(/^([^<]*)(<[^>]+>?)?/); 23115 // If there is some text before the next tag, return it, otherwise return 23116 // the tag. 23117 return consume(m[1] ? m[1] : m[2]); 23118 } 23119 23120 // Unescape a string 's'. 23121 function unescape1(e) { 23122 return ESCAPE[e]; 23123 } 23124 function unescape(s) { 23125 while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) { 23126 s = s.replace(m[0], unescape1); 23127 } 23128 return s; 23129 } 23130 23131 function shouldAdd(current, element) { 23132 return !NEEDS_PARENT[element.localName] || 23133 NEEDS_PARENT[element.localName] === current.localName; 23134 } 23135 23136 // Create an element for this tag. 23137 function createElement(type, annotation) { 23138 var tagName = TAG_NAME[type]; 23139 if (!tagName) { 23140 return null; 23141 } 23142 var element = window.document.createElement(tagName); 23143 element.localName = tagName; 23144 var name = TAG_ANNOTATION[type]; 23145 if (name && annotation) { 23146 element[name] = annotation.trim(); 23147 } 23148 return element; 23149 } 23150 23151 var rootDiv = window.document.createElement("div"), 23152 current = rootDiv, 23153 t, 23154 tagStack = []; 23155 23156 while ((t = nextToken()) !== null) { 23157 if (t[0] === '<') { 23158 if (t[1] === "/") { 23159 // If the closing tag matches, move back up to the parent node. 23160 if (tagStack.length && 23161 tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) { 23162 tagStack.pop(); 23163 current = current.parentNode; 23164 } 23165 // Otherwise just ignore the end tag. 23166 continue; 23167 } 23168 var ts = parseTimeStamp(t.substr(1, t.length - 2)); 23169 var node; 23170 if (ts) { 23171 // Timestamps are lead nodes as well. 23172 node = window.document.createProcessingInstruction("timestamp", ts); 23173 current.appendChild(node); 23174 continue; 23175 } 23176 var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/); 23177 // If we can't parse the tag, skip to the next tag. 23178 if (!m) { 23179 continue; 23180 } 23181 // Try to construct an element, and ignore the tag if we couldn't. 23182 node = createElement(m[1], m[3]); 23183 if (!node) { 23184 continue; 23185 } 23186 // Determine if the tag should be added based on the context of where it 23187 // is placed in the cuetext. 23188 if (!shouldAdd(current, node)) { 23189 continue; 23190 } 23191 // Set the class list (as a list of classes, separated by space). 23192 if (m[2]) { 23193 node.className = m[2].substr(1).replace('.', ' '); 23194 } 23195 // Append the node to the current node, and enter the scope of the new 23196 // node. 23197 tagStack.push(m[1]); 23198 current.appendChild(node); 23199 current = node; 23200 continue; 23201 } 23202 23203 // Text nodes are leaf nodes. 23204 current.appendChild(window.document.createTextNode(unescape(t))); 23205 } 23206 23207 return rootDiv; 23208 } 23209 23210 // This is a list of all the Unicode characters that have a strong 23211 // right-to-left category. What this means is that these characters are 23212 // written right-to-left for sure. It was generated by pulling all the strong 23213 // right-to-left characters out of the Unicode data table. That table can 23214 // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt 23215 var strongRTLChars = [0x05BE, 0x05C0, 0x05C3, 0x05C6, 0x05D0, 0x05D1, 23216 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 23217 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 23218 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x05F0, 0x05F1, 23219 0x05F2, 0x05F3, 0x05F4, 0x0608, 0x060B, 0x060D, 0x061B, 0x061E, 0x061F, 23220 0x0620, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 23221 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 23222 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 23223 0x063B, 0x063C, 0x063D, 0x063E, 0x063F, 0x0640, 0x0641, 0x0642, 0x0643, 23224 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x066D, 0x066E, 23225 0x066F, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0x0677, 0x0678, 23226 0x0679, 0x067A, 0x067B, 0x067C, 0x067D, 0x067E, 0x067F, 0x0680, 0x0681, 23227 0x0682, 0x0683, 0x0684, 0x0685, 0x0686, 0x0687, 0x0688, 0x0689, 0x068A, 23228 0x068B, 0x068C, 0x068D, 0x068E, 0x068F, 0x0690, 0x0691, 0x0692, 0x0693, 23229 0x0694, 0x0695, 0x0696, 0x0697, 0x0698, 0x0699, 0x069A, 0x069B, 0x069C, 23230 0x069D, 0x069E, 0x069F, 0x06A0, 0x06A1, 0x06A2, 0x06A3, 0x06A4, 0x06A5, 23231 0x06A6, 0x06A7, 0x06A8, 0x06A9, 0x06AA, 0x06AB, 0x06AC, 0x06AD, 0x06AE, 23232 0x06AF, 0x06B0, 0x06B1, 0x06B2, 0x06B3, 0x06B4, 0x06B5, 0x06B6, 0x06B7, 23233 0x06B8, 0x06B9, 0x06BA, 0x06BB, 0x06BC, 0x06BD, 0x06BE, 0x06BF, 0x06C0, 23234 0x06C1, 0x06C2, 0x06C3, 0x06C4, 0x06C5, 0x06C6, 0x06C7, 0x06C8, 0x06C9, 23235 0x06CA, 0x06CB, 0x06CC, 0x06CD, 0x06CE, 0x06CF, 0x06D0, 0x06D1, 0x06D2, 23236 0x06D3, 0x06D4, 0x06D5, 0x06E5, 0x06E6, 0x06EE, 0x06EF, 0x06FA, 0x06FB, 23237 0x06FC, 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, 0x0703, 0x0704, 23238 0x0705, 0x0706, 0x0707, 0x0708, 0x0709, 0x070A, 0x070B, 0x070C, 0x070D, 23239 0x070F, 0x0710, 0x0712, 0x0713, 0x0714, 0x0715, 0x0716, 0x0717, 0x0718,
23240 0x0719, 0x071A, 0x071B, 0x071C, 0x071D, 0x071E, 0x071F, 0x0720, 0x0721, 23241 0x0722, 0x0723, 0x0724, 0x0725, 0x0726, 0x0727, 0x0728, 0x0729, 0x072A, 23242 0x072B, 0x072C, 0x072D, 0x072E, 0x072F, 0x074D, 0x074E, 0x074F, 0x0750, 23243 0x0751, 0x0752, 0x0753, 0x0754, 0x0755, 0x0756, 0x0757, 0x0758, 0x0759, 23244 0x075A, 0x075B, 0x075C, 0x075D, 0x075E, 0x075F, 0x0760, 0x0761, 0x0762, 23245 0x0763, 0x0764, 0x0765, 0x0766, 0x0767, 0x0768, 0x0769, 0x076A, 0x076B, 23246 0x076C, 0x076D, 0x076E, 0x076F, 0x0770, 0x0771, 0x0772, 0x0773, 0x0774, 23247 0x0775, 0x0776, 0x0777, 0x0778, 0x0779, 0x077A, 0x077B, 0x077C, 0x077D, 23248 0x077E, 0x077F, 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0786, 23249 0x0787, 0x0788, 0x0789, 0x078A, 0x078B, 0x078C, 0x078D, 0x078E, 0x078F, 23250 0x0790, 0x0791, 0x0792, 0x0793, 0x0794, 0x0795, 0x0796, 0x0797, 0x0798, 23251 0x0799, 0x079A, 0x079B, 0x079C, 0x079D, 0x079E, 0x079F, 0x07A0, 0x07A1, 23252 0x07A2, 0x07A3, 0x07A4, 0x07A5, 0x07B1, 0x07C0, 0x07C1, 0x07C2, 0x07C3, 23253 0x07C4, 0x07C5, 0x07C6, 0x07C7, 0x07C8, 0x07C9, 0x07CA, 0x07CB, 0x07CC, 23254 0x07CD, 0x07CE, 0x07CF, 0x07D0, 0x07D1, 0x07D2, 0x07D3, 0x07D4, 0x07D5, 23255 0x07D6, 0x07D7, 0x07D8, 0x07D9, 0x07DA, 0x07DB, 0x07DC, 0x07DD, 0x07DE, 23256 0x07DF, 0x07E0, 0x07E1, 0x07E2, 0x07E3, 0x07E4, 0x07E5, 0x07E6, 0x07E7, 23257 0x07E8, 0x07E9, 0x07EA, 0x07F4, 0x07F5, 0x07FA, 0x0800, 0x0801, 0x0802, 23258 0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809, 0x080A, 0x080B, 23259 0x080C, 0x080D, 0x080E, 0x080F, 0x0810, 0x0811, 0x0812, 0x0813, 0x0814, 23260 0x0815, 0x081A, 0x0824, 0x0828, 0x0830, 0x0831, 0x0832, 0x0833, 0x0834, 23261 0x0835, 0x0836, 0x0837, 0x0838, 0x0839, 0x083A, 0x083B, 0x083C, 0x083D, 23262 0x083E, 0x0840, 0x0841, 0x0842, 0x0843, 0x0844, 0x0845, 0x0846, 0x0847, 23263 0x0848, 0x0849, 0x084A, 0x084B, 0x084C, 0x084D, 0x084E, 0x084F, 0x0850, 23264 0x0851, 0x0852, 0x0853, 0x0854, 0x0855, 0x0856, 0x0857, 0x0858, 0x085E, 23265 0x08A0, 0x08A2, 0x08A3, 0x08A4, 0x08A5, 0x08A6, 0x08A7, 0x08A8, 0x08A9, 23266 0x08AA, 0x08AB, 0x08AC, 0x200F, 0xFB1D, 0xFB1F, 0xFB20, 0xFB21, 0xFB22, 23267 0xFB23, 0xFB24, 0xFB25, 0xFB26, 0xFB27, 0xFB28, 0xFB2A, 0xFB2B, 0xFB2C, 23268 0xFB2D, 0xFB2E, 0xFB2F, 0xFB30, 0xFB31, 0xFB32, 0xFB33, 0xFB34, 0xFB35, 23269 0xFB36, 0xFB38, 0xFB39, 0xFB3A, 0xFB3B, 0xFB3C, 0xFB3E, 0xFB40, 0xFB41, 23270 0xFB43, 0xFB44, 0xFB46, 0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C, 23271 0xFB4D, 0xFB4E, 0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54, 0xFB55,
23272 0xFB56, 0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B, 0xFB5C, 0xFB5D, 0xFB5E, 23273 0xFB5F, 0xFB60, 0xFB61, 0xFB62, 0xFB63, 0xFB64, 0xFB65, 0xFB66, 0xFB67, 23274 0xFB68, 0xFB69, 0xFB6A, 0xFB6B, 0xFB6C, 0xFB6D, 0xFB6E, 0xFB6F, 0xFB70, 23275 0xFB71, 0xFB72, 0xFB73, 0xFB74, 0xFB75, 0xFB76, 0xFB77, 0xFB78, 0xFB79, 23276 0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D, 0xFB7E, 0xFB7F, 0xFB80, 0xFB81, 0xFB82, 23277 0xFB83, 0xFB84, 0xFB85, 0xFB86, 0xFB87, 0xFB88, 0xFB89, 0xFB8A, 0xFB8B, 23278 0xFB8C, 0xFB8D, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91, 0xFB92, 0xFB93, 0xFB94, 23279 0xFB95, 0xFB96, 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B, 0xFB9C, 0xFB9D, 23280 0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3, 0xFBA4, 0xFBA5, 0xFBA6, 23281 0xFBA7, 0xFBA8, 0xFBA9, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD, 0xFBAE, 0xFBAF, 23282 0xFBB0, 0xFBB1, 0xFBB2, 0xFBB3, 0xFBB4, 0xFBB5, 0xFBB6, 0xFBB7, 0xFBB8, 23283 0xFBB9, 0xFBBA, 0xFBBB, 0xFBBC, 0xFBBD, 0xFBBE, 0xFBBF, 0xFBC0, 0xFBC1, 23284 0xFBD3, 0xFBD4, 0xFBD5, 0xFBD6, 0xFBD7, 0xFBD8, 0xFBD9, 0xFBDA, 0xFBDB, 23285 0xFBDC, 0xFBDD, 0xFBDE, 0xFBDF, 0xFBE0, 0xFBE1, 0xFBE2, 0xFBE3, 0xFBE4, 23286 0xFBE5, 0xFBE6, 0xFBE7, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEB, 0xFBEC, 0xFBED, 23287 0xFBEE, 0xFBEF, 0xFBF0, 0xFBF1, 0xFBF2, 0xFBF3, 0xFBF4, 0xFBF5, 0xFBF6, 23288 0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF, 23289 0xFC00, 0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08, 23290 0xFC09, 0xFC0A, 0xFC0B, 0xFC0C, 0xFC0D, 0xFC0E, 0xFC0F, 0xFC10, 0xFC11, 23291 0xFC12, 0xFC13, 0xFC14, 0xFC15, 0xFC16, 0xFC17, 0xFC18, 0xFC19, 0xFC1A, 23292 0xFC1B, 0xFC1C, 0xFC1D, 0xFC1E, 0xFC1F, 0xFC20, 0xFC21, 0xFC22, 0xFC23, 23293 0xFC24, 0xFC25, 0xFC26, 0xFC27, 0xFC28, 0xFC29, 0xFC2A, 0xFC2B, 0xFC2C, 23294 0xFC2D, 0xFC2E, 0xFC2F, 0xFC30, 0xFC31, 0xFC32, 0xFC33, 0xFC34, 0xFC35, 23295 0xFC36, 0xFC37, 0xFC38, 0xFC39, 0xFC3A, 0xFC3B, 0xFC3C, 0xFC3D, 0xFC3E, 23296 0xFC3F, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44, 0xFC45, 0xFC46, 0xFC47, 23297 0xFC48, 0xFC49, 0xFC4A, 0xFC4B, 0xFC4C, 0xFC4D, 0xFC4E, 0xFC4F, 0xFC50,
23298 0xFC51, 0xFC52, 0xFC53, 0xFC54, 0xFC55, 0xFC56, 0xFC57, 0xFC58, 0xFC59, 23299 0xFC5A, 0xFC5B, 0xFC5C, 0xFC5D, 0xFC5E, 0xFC5F, 0xFC60, 0xFC61, 0xFC62, 23300 0xFC63, 0xFC64, 0xFC65, 0xFC66, 0xFC67, 0xFC68, 0xFC69, 0xFC6A, 0xFC6B, 23301 0xFC6C, 0xFC6D, 0xFC6E, 0xFC6F, 0xFC70, 0xFC71, 0xFC72, 0xFC73, 0xFC74, 23302 0xFC75, 0xFC76, 0xFC77, 0xFC78, 0xFC79, 0xFC7A, 0xFC7B, 0xFC7C, 0xFC7D, 23303 0xFC7E, 0xFC7F, 0xFC80, 0xFC81, 0xFC82, 0xFC83, 0xFC84, 0xFC85, 0xFC86, 23304 0xFC87, 0xFC88, 0xFC89, 0xFC8A, 0xFC8B, 0xFC8C, 0xFC8D, 0xFC8E, 0xFC8F, 23305 0xFC90, 0xFC91, 0xFC92, 0xFC93, 0xFC94, 0xFC95, 0xFC96, 0xFC97, 0xFC98, 23306 0xFC99, 0xFC9A, 0xFC9B, 0xFC9C, 0xFC9D, 0xFC9E, 0xFC9F, 0xFCA0, 0xFCA1, 23307 0xFCA2, 0xFCA3, 0xFCA4, 0xFCA5, 0xFCA6, 0xFCA7, 0xFCA8, 0xFCA9, 0xFCAA, 23308 0xFCAB, 0xFCAC, 0xFCAD, 0xFCAE, 0xFCAF, 0xFCB0, 0xFCB1, 0xFCB2, 0xFCB3, 23309 0xFCB4, 0xFCB5, 0xFCB6, 0xFCB7, 0xFCB8, 0xFCB9, 0xFCBA, 0xFCBB, 0xFCBC, 23310 0xFCBD, 0xFCBE, 0xFCBF, 0xFCC0, 0xFCC1, 0xFCC2, 0xFCC3, 0xFCC4, 0xFCC5, 23311 0xFCC6, 0xFCC7, 0xFCC8, 0xFCC9, 0xFCCA, 0xFCCB, 0xFCCC, 0xFCCD, 0xFCCE, 23312 0xFCCF, 0xFCD0, 0xFCD1, 0xFCD2, 0xFCD3, 0xFCD4, 0xFCD5, 0xFCD6, 0xFCD7, 23313 0xFCD8, 0xFCD9, 0xFCDA, 0xFCDB, 0xFCDC, 0xFCDD, 0xFCDE, 0xFCDF, 0xFCE0, 23314 0xFCE1, 0xFCE2, 0xFCE3, 0xFCE4, 0xFCE5, 0xFCE6, 0xFCE7, 0xFCE8, 0xFCE9, 23315 0xFCEA, 0xFCEB, 0xFCEC, 0xFCED, 0xFCEE, 0xFCEF, 0xFCF0, 0xFCF1, 0xFCF2, 23316 0xFCF3, 0xFCF4, 0xFCF5, 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, 0xFCFA, 0xFCFB, 23317 0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04, 23318 0xFD05, 0xFD06, 0xFD07, 0xFD08, 0xFD09, 0xFD0A, 0xFD0B, 0xFD0C, 0xFD0D, 23319 0xFD0E, 0xFD0F, 0xFD10, 0xFD11, 0xFD12, 0xFD13, 0xFD14, 0xFD15, 0xFD16, 23320 0xFD17, 0xFD18, 0xFD19, 0xFD1A, 0xFD1B, 0xFD1C, 0xFD1D, 0xFD1E, 0xFD1F, 23321 0xFD20, 0xFD21, 0xFD22, 0xFD23, 0xFD24, 0xFD25, 0xFD26, 0xFD27, 0xFD28, 23322 0xFD29, 0xFD2A, 0xFD2B, 0xFD2C, 0xFD2D, 0xFD2E, 0xFD2F, 0xFD30, 0xFD31, 23323 0xFD32, 0xFD33, 0xFD34, 0xFD35, 0xFD36, 0xFD37, 0xFD38, 0xFD39, 0xFD3A, 23324 0xFD3B, 0xFD3C, 0xFD3D, 0xFD50, 0xFD51, 0xFD52, 0xFD53, 0xFD54, 0xFD55, 23325 0xFD56, 0xFD57, 0xFD58, 0xFD59, 0xFD5A, 0xFD5B, 0xFD5C, 0xFD5D, 0xFD5E, 23326 0xFD5F, 0xFD60, 0xFD61, 0xFD62, 0xFD63, 0xFD64, 0xFD65, 0xFD66, 0xFD67, 23327 0xFD68, 0xFD69, 0xFD6A, 0xFD6B, 0xFD6C, 0xFD6D, 0xFD6E, 0xFD6F, 0xFD70, 23328 0xFD71, 0xFD72, 0xFD73, 0xFD74, 0xFD75, 0xFD76, 0xFD77, 0xFD78, 0xFD79, 23329 0xFD7A, 0xFD7B, 0xFD7C, 0xFD7D, 0xFD7E, 0xFD7F, 0xFD80, 0xFD81, 0xFD82, 23330 0xFD83, 0xFD84, 0xFD85, 0xFD86, 0xFD87, 0xFD88, 0xFD89, 0xFD8A, 0xFD8B, 23331 0xFD8C, 0xFD8D, 0xFD8E, 0xFD8F, 0xFD92, 0xFD93, 0xFD94, 0xFD95, 0xFD96, 23332 0xFD97, 0xFD98, 0xFD99, 0xFD9A, 0xFD9B, 0xFD9C, 0xFD9D, 0xFD9E, 0xFD9F, 23333 0xFDA0, 0xFDA1, 0xFDA2, 0xFDA3, 0xFDA4, 0xFDA5, 0xFDA6, 0xFDA7, 0xFDA8, 23334 0xFDA9, 0xFDAA, 0xFDAB, 0xFDAC, 0xFDAD, 0xFDAE, 0xFDAF, 0xFDB0, 0xFDB1, 23335 0xFDB2, 0xFDB3, 0xFDB4, 0xFDB5, 0xFDB6, 0xFDB7, 0xFDB8, 0xFDB9, 0xFDBA, 23336 0xFDBB, 0xFDBC, 0xFDBD, 0xFDBE, 0xFDBF, 0xFDC0, 0xFDC1, 0xFDC2, 0xFDC3, 23337 0xFDC4, 0xFDC5, 0xFDC6, 0xFDC7, 0xFDF0, 0xFDF1, 0xFDF2, 0xFDF3, 0xFDF4, 23338 0xFDF5, 0xFDF6, 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, 0xFE70, 23339 0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE76, 0xFE77, 0xFE78, 0xFE79, 0xFE7A, 23340 0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F, 0xFE80, 0xFE81, 0xFE82, 0xFE83, 23341 0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C, 23342 0xFE8D, 0xFE8E, 0xFE8F, 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95, 23343 0xFE96, 0xFE97, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E, 23344 0xFE9F, 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7, 23345 0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF, 0xFEB0, 23346 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9, 23347 0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0, 0xFEC1, 0xFEC2, 23348 0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9, 0xFECA, 0xFECB, 23349 0xFECC, 0xFECD, 0xFECE, 0xFECF, 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4, 23350 0xFED5, 0xFED6, 0xFED7, 0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD, 23351 0xFEDE, 0xFEDF, 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6,
23352 0xFEE7, 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF, 23353 0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8, 23354 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0x10800, 0x10801, 0x10802, 0x10803, 23355 0x10804, 0x10805, 0x10808, 0x1080A, 0x1080B, 0x1080C, 0x1080D, 0x1080E, 23356 0x1080F, 0x10810, 0x10811, 0x10812, 0x10813, 0x10814, 0x10815, 0x10816, 23357 0x10817, 0x10818, 0x10819, 0x1081A, 0x1081B, 0x1081C, 0x1081D, 0x1081E, 23358 0x1081F, 0x10820, 0x10821, 0x10822, 0x10823, 0x10824, 0x10825, 0x10826, 23359 0x10827, 0x10828, 0x10829, 0x1082A, 0x1082B, 0x1082C, 0x1082D, 0x1082E, 23360 0x1082F, 0x10830, 0x10831, 0x10832, 0x10833, 0x10834, 0x10835, 0x10837, 23361 0x10838, 0x1083C, 0x1083F, 0x10840, 0x10841, 0x10842, 0x10843, 0x10844, 23362 0x10845, 0x10846, 0x10847, 0x10848, 0x10849, 0x1084A, 0x1084B, 0x1084C, 23363 0x1084D, 0x1084E, 0x1084F, 0x10850, 0x10851, 0x10852, 0x10853, 0x10854, 23364 0x10855, 0x10857, 0x10858, 0x10859, 0x1085A, 0x1085B, 0x1085C, 0x1085D, 23365 0x1085E, 0x1085F, 0x10900, 0x10901, 0x10902, 0x10903, 0x10904, 0x10905, 23366 0x10906, 0x10907, 0x10908, 0x10909, 0x1090A, 0x1090B, 0x1090C, 0x1090D, 23367 0x1090E, 0x1090F, 0x10910, 0x10911, 0x10912, 0x10913, 0x10914, 0x10915, 23368 0x10916, 0x10917, 0x10918, 0x10919, 0x1091A, 0x1091B, 0x10920, 0x10921, 23369 0x10922, 0x10923, 0x10924, 0x10925, 0x10926, 0x10927, 0x10928, 0x10929, 23370 0x1092A, 0x1092B, 0x1092C, 0x1092D, 0x1092E, 0x1092F, 0x10930, 0x10931, 23371 0x10932, 0x10933, 0x10934, 0x10935, 0x10936, 0x10937, 0x10938, 0x10939, 23372 0x1093F, 0x10980, 0x10981, 0x10982, 0x10983, 0x10984, 0x10985, 0x10986, 23373 0x10987, 0x10988, 0x10989, 0x1098A, 0x1098B, 0x1098C, 0x1098D, 0x1098E, 23374 0x1098F, 0x10990, 0x10991, 0x10992, 0x10993, 0x10994, 0x10995, 0x10996, 23375 0x10997, 0x10998, 0x10999, 0x1099A, 0x1099B, 0x1099C, 0x1099D, 0x1099E, 23376 0x1099F, 0x109A0, 0x109A1, 0x109A2, 0x109A3, 0x109A4, 0x109A5, 0x109A6, 23377 0x109A7, 0x109A8, 0x109A9, 0x109AA, 0x109AB, 0x109AC, 0x109AD, 0x109AE, 23378 0x109AF, 0x109B0, 0x109B1, 0x109B2, 0x109B3, 0x109B4, 0x109B5, 0x109B6, 23379 0x109B7, 0x109BE, 0x109BF, 0x10A00, 0x10A10, 0x10A11, 0x10A12, 0x10A13, 23380 0x10A15, 0x10A16, 0x10A17, 0x10A19, 0x10A1A, 0x10A1B, 0x10A1C, 0x10A1D, 23381 0x10A1E, 0x10A1F, 0x10A20, 0x10A21, 0x10A22, 0x10A23, 0x10A24, 0x10A25, 23382 0x10A26, 0x10A27, 0x10A28, 0x10A29, 0x10A2A, 0x10A2B, 0x10A2C, 0x10A2D, 23383 0x10A2E, 0x10A2F, 0x10A30, 0x10A31, 0x10A32, 0x10A33, 0x10A40, 0x10A41, 23384 0x10A42, 0x10A43, 0x10A44, 0x10A45, 0x10A46, 0x10A47, 0x10A50, 0x10A51, 23385 0x10A52, 0x10A53, 0x10A54, 0x10A55, 0x10A56, 0x10A57, 0x10A58, 0x10A60, 23386 0x10A61, 0x10A62, 0x10A63, 0x10A64, 0x10A65, 0x10A66, 0x10A67, 0x10A68, 23387 0x10A69, 0x10A6A, 0x10A6B, 0x10A6C, 0x10A6D, 0x10A6E, 0x10A6F, 0x10A70, 23388 0x10A71, 0x10A72, 0x10A73, 0x10A74, 0x10A75, 0x10A76, 0x10A77, 0x10A78, 23389 0x10A79, 0x10A7A, 0x10A7B, 0x10A7C, 0x10A7D, 0x10A7E, 0x10A7F, 0x10B00, 23390 0x10B01, 0x10B02, 0x10B03, 0x10B04, 0x10B05, 0x10B06, 0x10B07, 0x10B08, 23391 0x10B09, 0x10B0A, 0x10B0B, 0x10B0C, 0x10B0D, 0x10B0E, 0x10B0F, 0x10B10, 23392 0x10B11, 0x10B12, 0x10B13, 0x10B14, 0x10B15, 0x10B16, 0x10B17, 0x10B18, 23393 0x10B19, 0x10B1A, 0x10B1B, 0x10B1C, 0x10B1D, 0x10B1E, 0x10B1F, 0x10B20, 23394 0x10B21, 0x10B22, 0x10B23, 0x10B24, 0x10B25, 0x10B26, 0x10B27, 0x10B28, 23395 0x10B29, 0x10B2A, 0x10B2B, 0x10B2C, 0x10B2D, 0x10B2E, 0x10B2F, 0x10B30, 23396 0x10B31, 0x10B32, 0x10B33, 0x10B34, 0x10B35, 0x10B40, 0x10B41, 0x10B42, 23397 0x10B43, 0x10B44, 0x10B45, 0x10B46, 0x10B47, 0x10B48, 0x10B49, 0x10B4A, 23398 0x10B4B, 0x10B4C, 0x10B4D, 0x10B4E, 0x10B4F, 0x10B50, 0x10B51, 0x10B52, 23399 0x10B53, 0x10B54, 0x10B55, 0x10B58, 0x10B59, 0x10B5A, 0x10B5B, 0x10B5C, 23400 0x10B5D, 0x10B5E, 0x10B5F, 0x10B60, 0x10B61, 0x10B62, 0x10B63, 0x10B64, 23401 0x10B65, 0x10B66, 0x10B67, 0x10B68, 0x10B69, 0x10B6A, 0x10B6B, 0x10B6C, 23402 0x10B6D, 0x10B6E, 0x10B6F, 0x10B70, 0x10B71, 0x10B72, 0x10B78, 0x10B79, 23403 0x10B7A, 0x10B7B, 0x10B7C, 0x10B7D, 0x10B7E, 0x10B7F, 0x10C00, 0x10C01, 23404 0x10C02, 0x10C03, 0x10C04, 0x10C05, 0x10C06, 0x10C07, 0x10C08, 0x10C09, 23405 0x10C0A, 0x10C0B, 0x10C0C, 0x10C0D, 0x10C0E, 0x10C0F, 0x10C10, 0x10C11, 23406 0x10C12, 0x10C13, 0x10C14, 0x10C15, 0x10C16, 0x10C17, 0x10C18, 0x10C19, 23407 0x10C1A, 0x10C1B, 0x10C1C, 0x10C1D, 0x10C1E, 0x10C1F, 0x10C20, 0x10C21, 23408 0x10C22, 0x10C23, 0x10C24, 0x10C25, 0x10C26, 0x10C27, 0x10C28, 0x10C29, 23409 0x10C2A, 0x10C2B, 0x10C2C, 0x10C2D, 0x10C2E, 0x10C2F, 0x10C30, 0x10C31, 23410 0x10C32, 0x10C33, 0x10C34, 0x10C35, 0x10C36, 0x10C37, 0x10C38, 0x10C39, 23411 0x10C3A, 0x10C3B, 0x10C3C, 0x10C3D, 0x10C3E, 0x10C3F, 0x10C40, 0x10C41, 23412 0x10C42, 0x10C43, 0x10C44, 0x10C45, 0x10C46, 0x10C47, 0x10C48, 0x1EE00, 23413 0x1EE01, 0x1EE02, 0x1EE03, 0x1EE05, 0x1EE06, 0x1EE07, 0x1EE08, 0x1EE09, 23414 0x1EE0A, 0x1EE0B, 0x1EE0C, 0x1EE0D, 0x1EE0E, 0x1EE0F, 0x1EE10, 0x1EE11, 23415 0x1EE12, 0x1EE13, 0x1EE14, 0x1EE15, 0x1EE16, 0x1EE17, 0x1EE18, 0x1EE19, 23416 0x1EE1A, 0x1EE1B, 0x1EE1C, 0x1EE1D, 0x1EE1E, 0x1EE1F, 0x1EE21, 0x1EE22, 23417 0x1EE24, 0x1EE27, 0x1EE29, 0x1EE2A, 0x1EE2B, 0x1EE2C, 0x1EE2D, 0x1EE2E, 23418 0x1EE2F, 0x1EE30, 0x1EE31, 0x1EE32, 0x1EE34, 0x1EE35, 0x1EE36, 0x1EE37, 23419 0x1EE39, 0x1EE3B, 0x1EE42, 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE4D, 0x1EE4E, 23420 0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE57, 0x1EE59, 0x1EE5B, 0x1EE5D, 23421 0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE67, 0x1EE68, 0x1EE69, 0x1EE6A, 23422 0x1EE6C, 0x1EE6D, 0x1EE6E, 0x1EE6F, 0x1EE70, 0x1EE71, 0x1EE72, 0x1EE74, 23423 0x1EE75, 0x1EE76, 0x1EE77, 0x1EE79, 0x1EE7A, 0x1EE7B, 0x1EE7C, 0x1EE7E, 23424 0x1EE80, 0x1EE81, 0x1EE82, 0x1EE83, 0x1EE84, 0x1EE85, 0x1EE86, 0x1EE87, 23425 0x1EE88, 0x1EE89, 0x1EE8B, 0x1EE8C, 0x1EE8D, 0x1EE8E, 0x1EE8F, 0x1EE90, 23426 0x1EE91, 0x1EE92, 0x1EE93, 0x1EE94, 0x1EE95, 0x1EE96, 0x1EE97, 0x1EE98, 23427 0x1EE99, 0x1EE9A, 0x1EE9B, 0x1EEA1, 0x1EEA2, 0x1EEA3, 0x1EEA5, 0x1EEA6, 23428 0x1EEA7, 0x1EEA8, 0x1EEA9, 0x1EEAB, 0x1EEAC, 0x1EEAD, 0x1EEAE, 0x1EEAF, 23429 0x1EEB0, 0x1EEB1, 0x1EEB2, 0x1EEB3, 0x1EEB4, 0x1EEB5, 0x1EEB6, 0x1EEB7, 23430 0x1EEB8, 0x1EEB9, 0x1EEBA, 0x1EEBB, 0x10FFFD]; 23431 23432 function determineBidi(cueDiv) { 23433 var nodeStack = [], 23434 text = "",
vendor: 6,425 bytes, lines 23435-23638
23435 charCode; 23436 23437 if (!cueDiv || !cueDiv.childNodes) { 23438 return "ltr"; 23439 } 23440 23441 function pushNodes(nodeStack, node) { 23442 for (var i = node.childNodes.length - 1; i >= 0; i--) { 23443 nodeStack.push(node.childNodes[i]); 23444 } 23445 } 23446 23447 function nextTextNode(nodeStack) { 23448 if (!nodeStack || !nodeStack.length) { 23449 return null; 23450 } 23451 23452 var node = nodeStack.pop(), 23453 text = node.textContent || node.innerText; 23454 if (text) { 23455 // TODO: This should match all unicode type B characters (paragraph 23456 // separator characters). See issue #115. 23457 var m = text.match(/^.*(\n|\r)/); 23458 if (m) { 23459 nodeStack.length = 0; 23460 return m[0]; 23461 } 23462 return text; 23463 } 23464 if (node.tagName === "ruby") { 23465 return nextTextNode(nodeStack); 23466 } 23467 if (node.childNodes) { 23468 pushNodes(nodeStack, node); 23469 return nextTextNode(nodeStack); 23470 } 23471 } 23472 23473 pushNodes(nodeStack, cueDiv); 23474 while ((text = nextTextNode(nodeStack))) { 23475 for (var i = 0; i < text.length; i++) { 23476 charCode = text.charCodeAt(i); 23477 for (var j = 0; j < strongRTLChars.length; j++) { 23478 if (strongRTLChars[j] === charCode) { 23479 return "rtl"; 23480 } 23481 } 23482 } 23483 } 23484 return "ltr"; 23485 } 23486 23487 function computeLinePos(cue) { 23488 if (typeof cue.line === "number" && 23489 (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) { 23490 return cue.line; 23491 } 23492 if (!cue.track || !cue.track.textTrackList || 23493 !cue.track.textTrackList.mediaElement) { 23494 return -1; 23495 } 23496 var track = cue.track, 23497 trackList = track.textTrackList, 23498 count = 0; 23499 for (var i = 0; i < trackList.length && trackList[i] !== track; i++) { 23500 if (trackList[i].mode === "showing") { 23501 count++; 23502 } 23503 } 23504 return ++count * -1; 23505 } 23506 23507 function StyleBox() { 23508 } 23509 23510 // Apply styles to a div. If there is no div passed then it defaults to the 23511 // div on 'this'. 23512 StyleBox.prototype.applyStyles = function(styles, div) { 23513 div = div || this.div; 23514 for (var prop in styles) { 23515 if (styles.hasOwnProperty(prop)) { 23516 div.style[prop] = styles[prop]; 23517 } 23518 } 23519 }; 23520 23521 StyleBox.prototype.formatStyle = function(val, unit) { 23522 return val === 0 ? 0 : val + unit; 23523 }; 23524 23525 // Constructs the computed display state of the cue (a div). Places the div 23526 // into the overlay which should be a block level element (usually a div). 23527 function CueStyleBox(window, cue, styleOptions) { 23528 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); 23529 var color = "rgba(255, 255, 255, 1)"; 23530 var backgroundColor = "rgba(0, 0, 0, 0.8)"; 23531 23532 if (isIE8) { 23533 color = "rgb(255, 255, 255)"; 23534 backgroundColor = "rgb(0, 0, 0)"; 23535 } 23536 23537 StyleBox.call(this); 23538 this.cue = cue; 23539 23540 // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will 23541 // have inline positioning and will function as the cue background box. 23542 this.cueDiv = parseContent(window, cue.text); 23543 var styles = { 23544 color: color, 23545 backgroundColor: backgroundColor, 23546 position: "relative", 23547 left: 0, 23548 right: 0, 23549 top: 0, 23550 bottom: 0, 23551 display: "inline" 23552 }; 23553 23554 if (!isIE8) { 23555 styles.writingMode = cue.vertical === "" ? "horizontal-tb" 23556 : cue.vertical === "lr" ? "vertical-lr" 23557 : "vertical-rl"; 23558 styles.unicodeBidi = "plaintext"; 23559 } 23560 this.applyStyles(styles, this.cueDiv); 23561 23562 // Create an absolutely positioned div that will be used to position the cue 23563 // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS 23564 // mirrors of them except "middle" which is "center" in CSS. 23565 this.div = window.document.createElement("div"); 23566 styles = { 23567 textAlign: cue.align === "middle" ? "center" : cue.align, 23568 font: styleOptions.font, 23569 whiteSpace: "pre-line", 23570 position: "absolute" 23571 }; 23572 23573 if (!isIE8) { 23574 styles.direction = determineBidi(this.cueDiv); 23575 styles.writingMode = cue.vertical === "" ? "horizontal-tb" 23576 : cue.vertical === "lr" ? "vertical-lr" 23577 : "vertical-rl". 23578 stylesunicodeBidi = "plaintext"; 23579 } 23580 23581 this.applyStyles(styles); 23582 23583 this.div.appendChild(this.cueDiv); 23584 23585 // Calculate the distance from the reference edge of the viewport to the text 23586 // position of the cue box. The reference edge will be resolved later when 23587 // the box orientation styles are applied. 23588 var textPos = 0; 23589 switch (cue.positionAlign) { 23590 case "start": 23591 textPos = cue.position; 23592 break; 23593 case "middle": 23594 textPos = cue.position - (cue.size / 2); 23595 break; 23596 case "end": 23597 textPos = cue.position - cue.size; 23598 break; 23599 } 23600 23601 // Horizontal box orientation; textPos is the distance from the left edge of the 23602 // area to the left edge of the box and cue.size is the distance extending to 23603 // the right from there. 23604 if (cue.vertical === "") { 23605 this.applyStyles({ 23606 left: this.formatStyle(textPos, "%"), 23607 width: this.formatStyle(cue.size, "%") 23608 }); 23609 // Vertical box orientation; textPos is the distance from the top edge of the 23610 // area to the top edge of the box and cue.size is the height extending 23611 // downwards from there. 23612 } else { 23613 this.applyStyles({ 23614 top: this.formatStyle(textPos, "%"), 23615 height: this.formatStyle(cue.size, "%") 23616 }); 23617 } 23618 23619 this.move = function(box) { 23620 this.applyStyles({ 23621 top: this.formatStyle(box.top, "px"), 23622 bottom: this.formatStyle(box.bottom, "px"), 23623 left: this.formatStyle(box.left, "px"), 23624 right: this.formatStyle(box.right, "px"), 23625 height: this.formatStyle(box.height, "px"), 23626 width: this.formatStyle(box.width, "px") 23627 }); 23628 }; 23629 } 23630 CueStyleBox.prototype = _objCreate(StyleBox.prototype); 23631 CueStyleBox.prototype.constructor = CueStyleBox; 23632 23633 // Represents the co-ordinates of an Element in a way that we can easily 23634 // compute things with such as if it overlaps or intersects with another Element. 23635 // Can initialize it with either a StyleBox or another BoxPosition. 23636 function BoxPosition(obj) { 23637 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); 23638
vendor: 11,730 bytes, lines 23639-23976
23639 // Either a BoxPosition was passed in and we need to copy it, or a StyleBox 23640 // was passed in and we need to copy the results of 'getBoundingClientRect' 23641 // as the object returned is readonly. All co-ordinate values are in reference 23642 // to the viewport origin (top left). 23643 var lh, height, width, top; 23644 if (obj.div) { 23645 height = obj.div.offsetHeight; 23646 width = obj.div.offsetWidth; 23647 top = obj.div.offsetTop; 23648 23649 var rects = (rects = obj.div.childNodes) && (rects = rects[0]) && 23650 rects.getClientRects && rects.getClientRects(); 23651 obj = obj.div.getBoundingClientRect(); 23652 // In certain cases the outter div will be slightly larger then the sum of 23653 // the inner div's lines. This could be due to bold text, etc, on some platforms. 23654 // In this case we should get the average line height and use that. This will 23655 // result in the desired behaviour. 23656 lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length) 23657 : 0; 23658 23659 } 23660 this.left = obj.left; 23661 this.right = obj.right; 23662 this.top = obj.top || top; 23663 this.height = obj.height || height; 23664 this.bottom = obj.bottom || (top + (obj.height || height)); 23665 this.width = obj.width || width; 23666 this.lineHeight = lh !== undefined ? lh : obj.lineHeight; 23667 23668 if (isIE8 && !this.lineHeight) { 23669 this.lineHeight = 13; 23670 } 23671 } 23672 23673 // Move the box along a particular axis. Optionally pass in an amount to move 23674 // the box. If no amount is passed then the default is the line height of the 23675 // box. 23676 BoxPosition.prototype.move = function(axis, toMove) { 23677 toMove = toMove !== undefined ? toMove : this.lineHeight; 23678 switch (axis) { 23679 case "+x": 23680 this.left += toMove; 23681 this.right += toMove; 23682 break; 23683 case "-x": 23684 this.left -= toMove; 23685 this.right -= toMove; 23686 break; 23687 case "+y": 23688 this.top += toMove; 23689 this.bottom += toMove; 23690 break; 23691 case "-y": 23692 this.top -= toMove; 23693 this.bottom -= toMove; 23694 break; 23695 } 23696 }; 23697 23698 // Check if this box overlaps another box, b2. 23699 BoxPosition.prototype.overlaps = function(b2) { 23700 return this.left < b2.right && 23701 this.right > b2.left && 23702 this.top < b2.bottom && 23703 this.bottom > b2.top; 23704 }; 23705 23706 // Check if this box overlaps any other boxes in boxes. 23707 BoxPosition.prototype.overlapsAny = function(boxes) { 23708 for (var i = 0; i < boxes.length; i++) { 23709 if (this.overlaps(boxes[i])) { 23710 return true; 23711 } 23712 } 23713 return false; 23714 }; 23715 23716 // Check if this box is within another box. 23717 BoxPosition.prototype.within = function(container) { 23718 return this.top >= container.top && 23719 this.bottom <= container.bottom && 23720 this.left >= container.left && 23721 this.right <= container.right; 23722 }; 23723 23724 // Check if this box is entirely within the container or it is overlapping 23725 // on the edge opposite of the axis direction passed. For example, if "+x" is 23726 // passed and the box is overlapping on the left edge of the container, then 23727 // return true. 23728 BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) { 23729 switch (axis) { 23730 case "+x": 23731 return this.left < container.left; 23732 case "-x": 23733 return this.right > container.right; 23734 case "+y": 23735 return this.top < container.top; 23736 case "-y": 23737 return this.bottom > container.bottom; 23738 } 23739 }; 23740 23741 // Find the percentage of the area that this box is overlapping with another 23742 // box. 23743 BoxPosition.prototype.intersectPercentage = function(b2) { 23744 var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)), 23745 y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)), 23746 intersectArea = x * y; 23747 return intersectArea / (this.height * this.width); 23748 }; 23749 23750 // Convert the positions from this box to CSS compatible positions using 23751 // the reference container's positions. This has to be done because this 23752 // box's positions are in reference to the viewport origin, whereas, CSS 23753 // values are in referecne to their respective edges. 23754 BoxPosition.prototype.toCSSCompatValues = function(reference) { 23755 return { 23756 top: this.top - reference.top, 23757 bottom: reference.bottom - this.bottom, 23758 left: this.left - reference.left, 23759 right: reference.right - this.right, 23760 height: this.height, 23761 width: this.width 23762 }; 23763 }; 23764 23765 // Get an object that represents the box's position without anything extra. 23766 // Can pass a StyleBox, HTMLElement, or another BoxPositon. 23767 BoxPosition.getSimpleBoxPosition = function(obj) { 23768 var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0; 23769 var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0; 23770 var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0; 23771 23772 obj = obj.div ? obj.div.getBoundingClientRect() : 23773 obj.tagName ? obj.getBoundingClientRect() : obj; 23774 var ret = { 23775 left: obj.left, 23776 right: obj.right, 23777 top: obj.top || top, 23778 height: obj.height || height, 23779 bottom: obj.bottom || (top + (obj.height || height)), 23780 width: obj.width || width 23781 }; 23782 return ret; 23783 }; 23784 23785 // Move a StyleBox to its specified, or next best, position. The containerBox 23786 // is the box that contains the StyleBox, such as a div. boxPositions are 23787 // a list of other boxes that the styleBox can't overlap with. 23788 function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) { 23789 23790 // Find the best position for a cue box, b, on the video. The axis parameter 23791 // is a list of axis, the order of which, it will move the box along. For example: 23792 // Passing ["+x", "-x"] will move the box first along the x axis in the positive 23793 // direction. If it doesn't find a good position for it there it will then move 23794 // it along the x axis in the negative direction. 23795 function findBestPosition(b, axis) { 23796 var bestPosition, 23797 specifiedPosition = new BoxPosition(b), 23798 percentage = 1; // Highest possible so the first thing we get is better. 23799 23800 for (var i = 0; i < axis.length; i++) { 23801 while (b.overlapsOppositeAxis(containerBox, axis[i]) || 23802 (b.within(containerBox) && b.overlapsAny(boxPositions))) { 23803 b.move(axis[i]); 23804 } 23805 // We found a spot where we aren't overlapping anything. This is our 23806 // best position. 23807 if (b.within(containerBox)) { 23808 return b; 23809 } 23810 var p = b.intersectPercentage(containerBox); 23811 // If we're outside the container box less then we were on our last try 23812 // then remember this position as the best position. 23813 if (percentage > p) { 23814 bestPosition = new BoxPosition(b); 23815 percentage = p; 23816 } 23817 // Reset the box position to the specified position. 23818 b = new BoxPosition(specifiedPosition); 23819 } 23820 return bestPosition || specifiedPosition; 23821 } 23822 23823 var boxPosition = new BoxPosition(styleBox), 23824 cue = styleBox.cue, 23825 linePos = computeLinePos(cue), 23826 axis = []; 23827 23828 // If we have a line number to align the cue to. 23829 if (cue.snapToLines) { 23830 var size; 23831 switch (cue.vertical) { 23832 case "": 23833 axis = [ "+y", "-y" ]; 23834 size = "height"; 23835 break; 23836 case "rl": 23837 axis = [ "+x", "-x" ]; 23838 size = "width"; 23839 break; 23840 case "lr": 23841 axis = [ "-x", "+x" ]; 23842 size = "width"; 23843 break; 23844 } 23845 23846 var step = boxPosition.lineHeight, 23847 position = step * Math.round(linePos), 23848 maxPosition = containerBox[size] + step, 23849 initialAxis = axis[0]; 23850 23851 // If the specified intial position is greater then the max position then 23852 // clamp the box to the amount of steps it would take for the box to 23853 // reach the max position. 23854 if (Math.abs(position) > maxPosition) { 23855 position = position < 0 ? -1 : 1; 23856 position *= Math.ceil(maxPosition / step) * step; 23857 } 23858 23859 // If computed line position returns negative then line numbers are 23860 // relative to the bottom of the video instead of the top. Therefore, we 23861 // need to increase our initial position by the length or width of the 23862 // video, depending on the writing direction, and reverse our axis directions. 23863 if (linePos < 0) { 23864 position += cue.vertical === "" ? containerBox.height : containerBox.width; 23865 axis = axis.reverse(); 23866 } 23867 23868 // Move the box to the specified position. This may not be its best 23869 // position. 23870 boxPosition.move(initialAxis, position); 23871 23872 } else { 23873 // If we have a percentage line value for the cue. 23874 var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100; 23875 23876 switch (cue.lineAlign) { 23877 case "middle": 23878 linePos -= (calculatedPercentage / 2); 23879 break; 23880 case "end": 23881 linePos -= calculatedPercentage; 23882 break; 23883 } 23884 23885 // Apply initial line position to the cue box. 23886 switch (cue.vertical) { 23887 case "": 23888 styleBox.applyStyles({ 23889 top: styleBox.formatStyle(linePos, "%") 23890 }); 23891 break; 23892 case "rl": 23893 styleBox.applyStyles({ 23894 left: styleBox.formatStyle(linePos, "%") 23895 }); 23896 break; 23897 case "lr": 23898 styleBox.applyStyles({ 23899 right: styleBox.formatStyle(linePos, "%") 23900 }); 23901 break; 23902 } 23903 23904 axis = [ "+y", "-x", "+x", "-y" ]; 23905 23906 // Get the box position again after we've applied the specified positioning 23907 // to it. 23908 boxPosition = new BoxPosition(styleBox); 23909 } 23910 23911 var bestPosition = findBestPosition(boxPosition, axis); 23912 styleBox.move(bestPosition.toCSSCompatValues(containerBox)); 23913 } 23914 23915 function WebVTT() { 23916 // Nothing 23917 } 23918 23919 // Helper to allow strings to be decoded instead of the default binary utf8 data. 23920 WebVTT.StringDecoder = function() { 23921 return { 23922 decode: function(data) { 23923 if (!data) { 23924 return ""; 23925 } 23926 if (typeof data !== "string") { 23927 throw new Error("Error - expected string data."); 23928 } 23929 return decodeURIComponent(encodeURIComponent(data)); 23930 } 23931 }; 23932 }; 23933 23934 WebVTT.convertCueToDOMTree = function(window, cuetext) { 23935 if (!window || !cuetext) { 23936 return null; 23937 } 23938 return parseContent(window, cuetext); 23939 }; 23940 23941 var FONT_SIZE_PERCENT = 0.05; 23942 var FONT_STYLE = "sans-serif"; 23943 var CUE_BACKGROUND_PADDING = "1.5%"; 23944 23945 // Runs the processing model over the cues and regions passed to it. 23946 // @param overlay A block level element (usually a div) that the computed cues 23947 // and regions will be placed into. 23948 WebVTT.processCues = function(window, cues, overlay) { 23949 if (!window || !cues || !overlay) { 23950 return null; 23951 } 23952 23953 // Remove all previous children. 23954 while (overlay.firstChild) { 23955 overlay.removeChild(overlay.firstChild); 23956 } 23957 23958 var paddedOverlay = window.document.createElement("div"); 23959 paddedOverlay.style.position = "absolute"; 23960 paddedOverlay.style.left = "0"; 23961 paddedOverlay.style.right = "0"; 23962 paddedOverlay.style.top = "0"; 23963 paddedOverlay.style.bottom = "0"; 23964 paddedOverlay.style.margin = CUE_BACKGROUND_PADDING; 23965 overlay.appendChild(paddedOverlay); 23966 23967 // Determine if we need to compute the display states of the cues. This could 23968 // be the case if a cue's state has been changed since the last computation or 23969 // if it has not been computed yet. 23970 function shouldCompute(cues) { 23971 for (var i = 0; i < cues.length; i++) { 23972 if (cues[i].hasBeenReset || !cues[i].displayState) { 23973 return true; 23974 } 23975 } 23976 return false;
vendor: 9,362 bytes, lines 23977-24266
23977 } 23978 23979 // We don't need to recompute the cues' display states. Just reuse them. 23980 if (!shouldCompute(cues)) { 23981 for (var i = 0; i < cues.length; i++) { 23982 paddedOverlay.appendChild(cues[i].displayState); 23983 } 23984 return; 23985 } 23986 23987 var boxPositions = [], 23988 containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay), 23989 fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100; 23990 var styleOptions = { 23991 font: fontSize + "px " + FONT_STYLE 23992 }; 23993 23994 (function() { 23995 var styleBox, cue; 23996 23997 for (var i = 0; i < cues.length; i++) { 23998 cue = cues[i]; 23999 24000 // Compute the intial position and styles of the cue div. 24001 styleBox = new CueStyleBox(window, cue, styleOptions); 24002 paddedOverlay.appendChild(styleBox.div); 24003 24004 // Move the cue div to it's correct line position. 24005 moveBoxToLinePosition(window, styleBox, containerBox, boxPositions); 24006 24007 // Remember the computed div so that we don't have to recompute it later 24008 // if we don't have too. 24009 cue.displayState = styleBox.div; 24010 24011 boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox)); 24012 } 24013 })(); 24014 }; 24015 24016 WebVTT.Parser = function(window, vttjs, decoder) { 24017 if (!decoder) { 24018 decoder = vttjs; 24019 vttjs = {}; 24020 } 24021 if (!vttjs) { 24022 vttjs = {}; 24023 } 24024 24025 this.window = window; 24026 this.vttjs = vttjs; 24027 this.state = "INITIAL"; 24028 this.buffer = ""; 24029 this.decoder = decoder || new TextDecoder("utf8"); 24030 this.regionList = []; 24031 }; 24032 24033 WebVTT.Parser.prototype = { 24034 // If the error is a ParsingError then report it to the consumer if 24035 // possible. If it's not a ParsingError then throw it like normal. 24036 reportOrThrowError: function(e) { 24037 if (e instanceof ParsingError) { 24038 this.onparsingerror && this.onparsingerror(e); 24039 } else { 24040 throw e; 24041 } 24042 }, 24043 parse: function (data) { 24044 var self = this; 24045 24046 // If there is no data then we won't decode it, but will just try to parse 24047 // whatever is in buffer already. This may occur in circumstances, for 24048 // example when flush() is called. 24049 if (data) { 24050 // Try to decode the data that we received. 24051 self.buffer += self.decoder.decode(data, {stream: true}); 24052 } 24053 24054 function collectNextLine() { 24055 var buffer = self.buffer; 24056 var pos = 0; 24057 while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') { 24058 ++pos; 24059 } 24060 var line = buffer.substr(0, pos); 24061 // Advance the buffer early in case we fail below. 24062 if (buffer[pos] === '\r') { 24063 ++pos; 24064 } 24065 if (buffer[pos] === '\n') { 24066 ++pos; 24067 } 24068 self.buffer = buffer.substr(pos); 24069 return line; 24070 } 24071 24072 // 3.4 WebVTT region and WebVTT region settings syntax 24073 function parseRegion(input) { 24074 var settings = new Settings(); 24075 24076 parseOptions(input, function (k, v) { 24077 switch (k) { 24078 case "id": 24079 settings.set(k, v); 24080 break; 24081 case "width": 24082 settings.percent(k, v); 24083 break; 24084 case "lines": 24085 settings.integer(k, v); 24086 break; 24087 case "regionanchor": 24088 case "viewportanchor": 24089 var xy = v.split(','); 24090 if (xy.length !== 2) { 24091 break; 24092 } 24093 // We have to make sure both x and y parse, so use a temporary 24094 // settings object here. 24095 var anchor = new Settings(); 24096 anchor.percent("x", xy[0]); 24097 anchor.percent("y", xy[1]); 24098 if (!anchor.has("x") || !anchor.has("y")) { 24099 break; 24100 } 24101 settings.set(k + "X", anchor.get("x")); 24102 settings.set(k + "Y", anchor.get("y")); 24103 break; 24104 case "scroll": 24105 settings.alt(k, v, ["up"]); 24106 break; 24107 } 24108 }, /=/, /\s/); 24109 24110 // Create the region, using default values for any values that were not 24111 // specified. 24112 if (settings.has("id")) { 24113 var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)(); 24114 region.width = settings.get("width", 100); 24115 region.lines = settings.get("lines", 3); 24116 region.regionAnchorX = settings.get("regionanchorX", 0); 24117 region.regionAnchorY = settings.get("regionanchorY", 100); 24118 region.viewportAnchorX = settings.get("viewportanchorX", 0); 24119 region.viewportAnchorY = settings.get("viewportanchorY", 100); 24120 region.scroll = settings.get("scroll", ""); 24121 // Register the region. 24122 self.onregion && self.onregion(region); 24123 // Remember the VTTRegion for later in case we parse any VTTCues that 24124 // reference it. 24125 self.regionList.push({ 24126 id: settings.get("id"), 24127 region: region 24128 }); 24129 } 24130 } 24131 24132 // 3.2 WebVTT metadata header syntax 24133 function parseHeader(input) { 24134 parseOptions(input, function (k, v) { 24135 switch (k) { 24136 case "Region": 24137 // 3.3 WebVTT region metadata header syntax 24138 parseRegion(v); 24139 break; 24140 } 24141 }, /:/); 24142 } 24143 24144 // 5.1 WebVTT file parsing. 24145 try { 24146 var line; 24147 if (self.state === "INITIAL") { 24148 // We can't start parsing until we have the first line. 24149 if (!/\r\n|\n/.test(self.buffer)) { 24150 return this; 24151 } 24152 24153 line = collectNextLine(); 24154 24155 var m = line.match(/^WEBVTT([ \t].*)?$/); 24156 if (!m || !m[0]) { 24157 throw new ParsingError(ParsingError.Errors.BadSignature); 24158 } 24159 24160 self.state = "HEADER"; 24161 } 24162 24163 var alreadyCollectedLine = false; 24164 while (self.buffer) { 24165 // We can't parse a line until we have the full line. 24166 if (!/\r\n|\n/.test(self.buffer)) { 24167 return this; 24168 } 24169 24170 if (!alreadyCollectedLine) { 24171 line = collectNextLine(); 24172 } else { 24173 alreadyCollectedLine = false; 24174 } 24175 24176 switch (self.state) { 24177 case "HEADER": 24178 // 13-18 - Allow a header (metadata) under the WEBVTT line. 24179 if (/:/.test(line)) { 24180 parseHeader(line); 24181 } else if (!line) { 24182 // An empty line terminates the header and starts the body (cues). 24183 self.state = "ID"; 24184 } 24185 continue; 24186 case "NOTE": 24187 // Ignore NOTE blocks. 24188 if (!line) { 24189 self.state = "ID"; 24190 } 24191 continue; 24192 case "ID": 24193 // Check for the start of NOTE blocks. 24194 if (/^NOTE($|[ \t])/.test(line)) { 24195 self.state = "NOTE"; 24196 break; 24197 } 24198 // 19-29 - Allow any number of line terminators, then initialize new cue values. 24199 if (!line) { 24200 continue; 24201 } 24202 self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, ""); 24203 self.state = "CUE"; 24204 // 30-39 - Check if self line contains an optional identifier or timing data. 24205 if (line.indexOf("-->") === -1) { 24206 self.cue.id = line; 24207 continue; 24208 } 24209 // Process line as start of a cue. 24210 /*falls through*/ 24211 case "CUE": 24212 // 40 - Collect cue timings and settings. 24213 try { 24214 parseCue(line, self.cue, self.regionList); 24215 } catch (e) { 24216 self.reportOrThrowError(e); 24217 // In case of an error ignore rest of the cue. 24218 self.cue = null; 24219 self.state = "BADCUE"; 24220 continue; 24221 } 24222 self.state = "CUETEXT"; 24223 continue; 24224 case "CUETEXT": 24225 var hasSubstring = line.indexOf("-->") !== -1; 24226 // 34 - If we have an empty line then report the cue. 24227 // 35 - If we have the special substring '-->' then report the cue, 24228 // but do not collect the line as we need to process the current 24229 // one as a new cue. 24230 if (!line || hasSubstring && (alreadyCollectedLine = true)) { 24231 // We are done parsing self cue. 24232 self.oncue && self.oncue(self.cue); 24233 self.cue = null; 24234 self.state = "ID"; 24235 continue; 24236 } 24237 if (self.cue.text) { 24238 self.cue.text += "\n"; 24239 } 24240 self.cue.text += line; 24241 continue; 24242 case "BADCUE": // BADCUE 24243 // 54-62 - Collect and discard the remaining cue. 24244 if (!line) { 24245 self.state = "ID"; 24246 } 24247 continue; 24248 } 24249 } 24250 } catch (e) { 24251 self.reportOrThrowError(e); 24252 24253 // If we are currently parsing a cue, report what we have. 24254 if (self.state === "CUETEXT" && self.cue && self.oncue) { 24255 self.oncue(self.cue); 24256 } 24257 self.cue = null; 24258 // Enter BADWEBVTT state if header was not parsed correctly otherwise 24259 // another exception occurred so enter BADCUE state. 24260 self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE"; 24261 } 24262 return this; 24263 }, 24264 flush: function () { 24265 var self = this; 24266 try {
24267 // Finish decoding the stream. 24268 self.buffer += self.decoder.decode(); 24269 // Synthesize the end of the current cue or region. 24270 if (self.cue || self.state === "HEADER") { 24271 self.buffer += "\n\n"; 24272 self.parse(); 24273 } 24274 // If we've flushed, parsed, and we're still on the INITIAL state then 24275 // that means we don't have enough of the stream to parse the first 24276 // line. 24277 if (self.state === "INITIAL") { 24278 throw new ParsingError(ParsingError.Errors.BadSignature); 24279 } 24280 } catch(e) { 24281 self.reportOrThrowError(e); 24282 } 24283 self.onflush && self.onflush(); 24284 return this; 24285 } 24286 }; 24287 24288 global.WebVTT = WebVTT; 24289 24290}(this, (this.vttjs || {})));
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.