1/** 2 * @license 3 * Video.js 5.7.0 <http://videojs.com/> 4 * Copyright Brightcove, Inc. <https://www.brightcove.com/> 5 * Available under Apache License Version 2.0 6 * <https://github.com/videojs/video.js/blob/master/LICENSE> 7 * 8 * Includes vtt.js <https://github.com/mozilla/vtt.js> 9 * Available under Apache License Version 2.0 10 * <https://github.com/mozilla/vtt.js/blob/master/LICENSE> 11 */ 12 13(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.videojs = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ 14(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":49}],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":48,"object-keys":49}],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":51,"./shim":52,"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":49}],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 binder = function () { 1970 if (this instanceof bound) { 1971 var result = target.apply( 1972 this, 1973 args.concat(slice.call(arguments)) 1974 ); 1975 if (Object(result) === result) { 1976 return result; 1977 } 1978 return this; 1979 } else { 1980 return target.apply( 1981 that, 1982 args.concat(slice.call(arguments)) 1983 ); 1984 } 1985 }; 1986 1987 var boundLength = Math.max(0, target.length - args.length); 1988 var boundArgs = []; 1989 for (var i = 0; i < boundLength; i++) { 1990 boundArgs.push('$' + i); 1991 } 1992 1993 var bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder); 1994 1995 if (target.prototype) { 1996 var Empty = function Empty() {}; 1997 Empty.prototype = target.prototype; 1998 bound.prototype = new Empty(); 1999 Empty.prototype = null; 2000 } 2001 2002 return bound; 2003}; 2004 2005 2006},{}],49:[function(_dereq_,module,exports){ 2007'use strict'; 2008 2009// modified from https://github.com/es-shims/es5-shim 2010var has = Object.prototype.hasOwnProperty; 2011var toStr = Object.prototype.toString; 2012var slice = Array.prototype.slice; 2013var isArgs = _dereq_('./isArguments'); 2014var hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'); 2015var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype'); 2016var dontEnums = [ 2017 'toString', 2018 'toLocaleString', 2019 'valueOf', 2020 'hasOwnProperty', 2021 'isPrototypeOf', 2022 'propertyIsEnumerable', 2023 'constructor' 2024]; 2025var equalsConstructorPrototype = function (o) { 2026 var ctor = o.constructor; 2027 return ctor && ctor.prototype === o; 2028}; 2029var blacklistedKeys = { 2030 $console: true, 2031 $frame: true, 2032 $frameElement: true, 2033 $frames: true, 2034 $parent: true, 2035 $self: true, 2036 $webkitIndexedDB: true, 2037 $webkitStorageInfo: true, 2038 $window: true 2039}; 2040var hasAutomationEqualityBug = (function () { 2041 /* global window */ 2042 if (typeof window === 'undefined') { return false; } 2043 for (var k in window) { 2044 try { 2045 if (!blacklistedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') { 2046 try { 2047 equalsConstructorPrototype(window[k]); 2048 } catch (e) { 2049 return true; 2050 } 2051 } 2052 } catch (e) { 2053 return true; 2054 } 2055 } 2056 return false;
2057}()); 2058var equalsConstructorPrototypeIfNotBuggy = function (o) { 2059 /* global window */ 2060 if (typeof window === 'undefined' || !hasAutomationEqualityBug) { 2061 return equalsConstructorPrototype(o); 2062 } 2063 try { 2064 return equalsConstructorPrototype(o); 2065 } catch (e) { 2066 return false; 2067 } 2068}; 2069 2070var keysShim = function keys(object) { 2071 var isObject = object !== null && typeof object === 'object'; 2072 var isFunction = toStr.call(object) === '[object Function]'; 2073 var isArguments = isArgs(object); 2074 var isString = isObject && toStr.call(object) === '[object String]'; 2075 var theKeys = []; 2076 2077 if (!isObject && !isFunction && !isArguments) { 2078 throw new TypeError('Object.keys called on a non-object'); 2079 } 2080 2081 var skipProto = hasProtoEnumBug && isFunction; 2082 if (isString && object.length > 0 && !has.call(object, 0)) { 2083 for (var i = 0; i < object.length; ++i) { 2084 theKeys.push(String(i)); 2085 } 2086 } 2087 2088 if (isArguments && object.length > 0) { 2089 for (var j = 0; j < object.length; ++j) { 2090 theKeys.push(String(j)); 2091 } 2092 } else { 2093 for (var name in object) { 2094 if (!(skipProto && name === 'prototype') && has.call(object, name)) { 2095 theKeys.push(String(name)); 2096 } 2097 } 2098 } 2099 2100 if (hasDontEnumBug) { 2101 var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object); 2102 2103 for (var k = 0; k < dontEnums.length; ++k) { 2104 if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) { 2105 theKeys.push(dontEnums[k]); 2106 } 2107 } 2108 } 2109 return theKeys; 2110}; 2111 2112keysShim.shim = function shimObjectKeys() { 2113 if (Object.keys) { 2114 var keysWorksWithArguments = (function () { 2115 // Safari 5.0 bug 2116 return (Object.keys(arguments) || '').length === 2; 2117 }(1, 2)); 2118 if (!keysWorksWithArguments) { 2119 var originalKeys = Object.keys; 2120 Object.keys = function keys(object) { 2121 if (isArgs(object)) { 2122 return originalKeys(slice.call(object)); 2123 } else { 2124 return originalKeys(object); 2125 } 2126 }; 2127 } 2128 } else { 2129 Object.keys = keysShim; 2130 } 2131 return Object.keys || keysShim; 2132}; 2133 2134module.exports = keysShim; 2135 2136},{"./isArguments":50}],50:[function(_dereq_,module,exports){ 2137'use strict'; 2138 2139var toStr = Object.prototype.toString; 2140 2141module.exports = function isArguments(value) { 2142 var str = toStr.call(value); 2143 var isArgs = str === '[object Arguments]'; 2144 if (!isArgs) { 2145 isArgs = str !== '[object Array]' && 2146 value !== null && 2147 typeof value === 'object' && 2148 typeof value.length === 'number' && 2149 value.length >= 0 && 2150 toStr.call(value.callee) === '[object Function]'; 2151 } 2152 return isArgs; 2153}; 2154 2155},{}],51:[function(_dereq_,module,exports){ 2156'use strict'; 2157 2158var implementation = _dereq_('./implementation'); 2159 2160var lacksProperEnumerationOrder = function () { 2161 if (!Object.assign) { 2162 return false; 2163 } 2164 // v8, specifically in node 4.x, has a bug with incorrect property enumeration order 2165 // note: this does not detect the bug unless there's 20 characters 2166 var str = 'abcdefghijklmnopqrst'; 2167 var letters = str.split(''); 2168 var map = {}; 2169 for (var i = 0; i < letters.length; ++i) { 2170 map[letters[i]] = letters[i]; 2171 } 2172 var obj = Object.assign({}, map); 2173 var actual = ''; 2174 for (var k in obj) { 2175 actual += k; 2176 } 2177 return str !== actual; 2178}; 2179 2180var assignHasPendingExceptions = function () { 2181 if (!Object.assign || !Object.preventExtensions) { 2182 return false; 2183 } 2184 // Firefox 37 still has "pending exception" logic in its Object.assign implementation, 2185 // which is 72% slower than our shim, and Firefox 40's native implementation. 2186 var thrower = Object.preventExtensions({ 1: 2 }); 2187 try { 2188 Object.assign(thrower, 'xy'); 2189 } catch (e) { 2190 return thrower[1] === 'y'; 2191 } 2192}; 2193 2194module.exports = function getPolyfill() { 2195 if (!Object.assign) { 2196 return implementation; 2197 } 2198 if (lacksProperEnumerationOrder()) { 2199 return implementation; 2200 } 2201 if (assignHasPendingExceptions()) { 2202 return implementation; 2203 } 2204 return Object.assign; 2205}; 2206 2207},{"./implementation":44}],52:[function(_dereq_,module,exports){ 2208'use strict'; 2209 2210var define = _dereq_('define-properties'); 2211var getPolyfill = _dereq_('./polyfill'); 2212 2213module.exports = function shimAssign() { 2214 var polyfill = getPolyfill(); 2215 define( 2216 Object, 2217 { assign: polyfill }, 2218 { assign: function () { return Object.assign !== polyfill; } } 2219 ); 2220 return polyfill; 2221}; 2222 2223},{"./polyfill":51,"define-properties":46}],53:[function(_dereq_,module,exports){ 2224module.exports = SafeParseTuple 2225 2226function SafeParseTuple(obj, reviver) { 2227 var json 2228 var error = null 2229 2230 try { 2231 json = JSON.parse(obj, reviver) 2232 } catch (err) { 2233 error = err 2234 } 2235 2236 return [error, json] 2237} 2238 2239},{}],54:[function(_dereq_,module,exports){ 2240function clean (s) { 2241 return s.replace(/\n\r?\s*/g, '') 2242} 2243 2244 2245module.exports = function tsml (sa) { 2246 var s = '' 2247 , i = 0 2248 2249 for (; i < arguments.length; i++) 2250 s += clean(sa[i]) + (arguments[i + 1] || '') 2251 2252 return s 2253} 2254},{}],55:[function(_dereq_,module,exports){ 2255"use strict"; 2256var window = _dereq_("global/window") 2257var once = _dereq_("once") 2258var isFunction = _dereq_("is-function") 2259var parseHeaders = _dereq_("parse-headers") 2260var xtend = _dereq_("xtend") 2261 2262module.exports = createXHR 2263createXHR.XMLHttpRequest = window.XMLHttpRequest || noop 2264createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest 2265 2266forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) { 2267 createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) { 2268 options = initParams(uri, options, callback) 2269 options.method = method.toUpperCase() 2270 return _createXHR(options) 2271 } 2272}) 2273 2274function forEachArray(array, iterator) { 2275 for (var i = 0; i < array.length; i++) { 2276 iterator(array[i]) 2277 } 2278} 2279 2280function isEmpty(obj){ 2281 for(var i in obj){ 2282 if(obj.hasOwnProperty(i)) return false 2283 } 2284 return true 2285} 2286 2287function initParams(uri, options, callback) { 2288 var params = uri 2289 2290 if (isFunction(options)) { 2291 callback = options 2292 if (typeof uri === "string") { 2293 params = {uri:uri} 2294 } 2295 } else { 2296 params = xtend(options, {uri: uri}) 2297 } 2298 2299 params.callback = callback 2300 return params 2301} 2302 2303function createXHR(uri, options, callback) { 2304 options = initParams(uri, options, callback) 2305 return _createXHR(options) 2306} 2307 2308function _createXHR(options) { 2309 var callback = options.callback 2310 if(typeof callback === "undefined"){ 2311 throw new Error("callback argument missing") 2312 } 2313 callback = once(callback) 2314 2315 function readystatechange() { 2316 if (xhr.readyState === 4) { 2317 loadFunc() 2318 } 2319 } 2320 2321 function getBody() { 2322 // Chrome with requestType=blob throws errors arround when even testing access to responseText 2323 var body = undefined 2324 2325 if (xhr.response) { 2326 body = xhr.response 2327 } else if (xhr.responseType === "text" || !xhr.responseType) { 2328 body = xhr.responseText || xhr.responseXML 2329 } 2330 2331 if (isJson) { 2332 try { 2333 body = JSON.parse(body) 2334 } catch (e) {} 2335 } 2336 2337 return body 2338 } 2339 2340 var failureResponse = { 2341 body: undefined, 2342 headers: {}, 2343 statusCode: 0, 2344 method: method,
2345 url: uri, 2346 rawRequest: xhr 2347 } 2348 2349 function errorFunc(evt) { 2350 clearTimeout(timeoutTimer) 2351 if(!(evt instanceof Error)){ 2352 evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") ) 2353 } 2354 evt.statusCode = 0 2355 callback(evt, failureResponse) 2356 } 2357 2358 // will load the data & process the response in a special response object 2359 function loadFunc() { 2360 if (aborted) return 2361 var status 2362 clearTimeout(timeoutTimer) 2363 if(options.useXDR && xhr.status===undefined) { 2364 //IE8 CORS GET successful response doesn't have a status field, but body is fine 2365 status = 200 2366 } else { 2367 status = (xhr.status === 1223 ? 204 : xhr.status) 2368 } 2369 var response = failureResponse 2370 var err = null 2371 2372 if (status !== 0){ 2373 response = { 2374 body: getBody(), 2375 statusCode: status, 2376 method: method, 2377 headers: {}, 2378 url: uri, 2379 rawRequest: xhr 2380 } 2381 if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE 2382 response.headers = parseHeaders(xhr.getAllResponseHeaders()) 2383 } 2384 } else { 2385 err = new Error("Internal XMLHttpRequest Error") 2386 } 2387 callback(err, response, response.body) 2388 2389 } 2390 2391 var xhr = options.xhr || null 2392 2393 if (!xhr) { 2394 if (options.cors || options.useXDR) { 2395 xhr = new createXHR.XDomainRequest() 2396 }else{ 2397 xhr = new createXHR.XMLHttpRequest() 2398 } 2399 } 2400 2401 var key 2402 var aborted 2403 var uri = xhr.url = options.uri || options.url 2404 var method = xhr.method = options.method || "GET" 2405 var body = options.body || options.data || null 2406 var headers = xhr.headers = options.headers || {} 2407 var sync = !!options.sync 2408 var isJson = false 2409 var timeoutTimer 2410 2411 if ("json" in options) { 2412 isJson = true 2413 headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user 2414 if (method !== "GET" && method !== "HEAD") { 2415 headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user 2416 body = JSON.stringify(options.json) 2417 } 2418 } 2419 2420 xhr.onreadystatechange = readystatechange 2421 xhr.onload = loadFunc 2422 xhr.onerror = errorFunc 2423 // IE9 must have onprogress be set to a unique function. 2424 xhr.onprogress = function () { 2425 // IE must die 2426 } 2427 xhr.ontimeout = errorFunc 2428 xhr.open(method, uri, !sync, options.username, options.password) 2429 //has to be after open 2430 if(!sync) { 2431 xhr.withCredentials = !!options.withCredentials 2432 } 2433 // Cannot set timeout with sync request 2434 // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly 2435 // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent 2436 if (!sync && options.timeout > 0 ) { 2437 timeoutTimer = setTimeout(function(){ 2438 aborted=true//IE9 may still call readystatechange 2439 xhr.abort("timeout") 2440 var e = new Error("XMLHttpRequest timeout") 2441 e.code = "ETIMEDOUT" 2442 errorFunc(e) 2443 }, options.timeout ) 2444 } 2445 2446 if (xhr.setRequestHeader) { 2447 for(key in headers){ 2448 if(headers.hasOwnProperty(key)){ 2449 xhr.setRequestHeader(key, headers[key]) 2450 } 2451 } 2452 } else if (options.headers && !isEmpty(options.headers)) { 2453 throw new Error("Headers cannot be set on an XDomainRequest object") 2454 } 2455 2456 if ("responseType" in options) { 2457 xhr.responseType = options.responseType 2458 } 2459 2460 if ("beforeSend" in options && 2461 typeof options.beforeSend === "function" 2462 ) { 2463 options.beforeSend(xhr) 2464 } 2465 2466 xhr.send(body) 2467 2468 return xhr 2469 2470 2471} 2472 2473function noop() {} 2474 2475},{"global/window":2,"is-function":56,"once":57,"parse-headers":60,"xtend":61}],56:[function(_dereq_,module,exports){ 2476module.exports = isFunction 2477 2478var toString = Object.prototype.toString 2479 2480function isFunction (fn) { 2481 var string = toString.call(fn) 2482 return string === '[object Function]' || 2483 (typeof fn === 'function' && string !== '[object RegExp]') || 2484 (typeof window !== 'undefined' && 2485 // IE8 and below 2486 (fn === window.setTimeout || 2487 fn === window.alert || 2488 fn === window.confirm || 2489 fn === window.prompt)) 2490}; 2491 2492},{}],57:[function(_dereq_,module,exports){ 2493module.exports = once 2494 2495once.proto = once(function () { 2496 Object.defineProperty(Function.prototype, 'once', { 2497 value: function () { 2498 return once(this) 2499 }, 2500 configurable: true 2501 }) 2502}) 2503 2504function once (fn) { 2505 var called = false 2506 return function () { 2507 if (called) return 2508 called = true 2509 return fn.apply(this, arguments) 2510 } 2511} 2512 2513},{}],58:[function(_dereq_,module,exports){ 2514var isFunction = _dereq_('is-function') 2515 2516module.exports = forEach 2517 2518var toString = Object.prototype.toString 2519var hasOwnProperty = Object.prototype.hasOwnProperty 2520 2521function forEach(list, iterator, context) { 2522 if (!isFunction(iterator)) { 2523 throw new TypeError('iterator must be a function') 2524 } 2525 2526 if (arguments.length < 3) { 2527 context = this 2528 } 2529 2530 if (toString.call(list) === '[object Array]')
2531 forEachArray(list, iterator, context) 2532 else if (typeof list === 'string') 2533 forEachString(list, iterator, context) 2534 else 2535 forEachObject(list, iterator, context) 2536} 2537 2538function forEachArray(array, iterator, context) { 2539 for (var i = 0, len = array.length; i < len; i++) { 2540 if (hasOwnProperty.call(array, i)) { 2541 iterator.call(context, array[i], i, array) 2542 } 2543 } 2544} 2545 2546function forEachString(string, iterator, context) { 2547 for (var i = 0, len = string.length; i < len; i++) { 2548 // no such thing as a sparse string. 2549 iterator.call(context, string.charAt(i), i, string) 2550 } 2551} 2552 2553function forEachObject(object, iterator, context) { 2554 for (var k in object) { 2555 if (hasOwnProperty.call(object, k)) { 2556 iterator.call(context, object[k], k, object) 2557 } 2558 } 2559} 2560 2561},{"is-function":56}],59:[function(_dereq_,module,exports){ 2562 2563exports = module.exports = trim; 2564 2565function trim(str){ 2566 return str.replace(/^\s*|\s*$/g, ''); 2567} 2568 2569exports.left = function(str){ 2570 return str.replace(/^\s*/, ''); 2571}; 2572 2573exports.right = function(str){ 2574 return str.replace(/\s*$/, ''); 2575}; 2576 2577},{}],60:[function(_dereq_,module,exports){ 2578var trim = _dereq_('trim') 2579 , forEach = _dereq_('for-each') 2580 , isArray = function(arg) { 2581 return Object.prototype.toString.call(arg) === '[object Array]'; 2582 } 2583 2584module.exports = function (headers) { 2585 if (!headers) 2586 return {} 2587 2588 var result = {} 2589 2590 forEach( 2591 trim(headers).split('\n') 2592 , function (row) { 2593 var index = row.indexOf(':') 2594 , key = trim(row.slice(0, index)).toLowerCase() 2595 , value = trim(row.slice(index + 1)) 2596 2597 if (typeof(result[key]) === 'undefined') { 2598 result[key] = value 2599 } else if (isArray(result[key])) { 2600 result[key].push(value) 2601 } else { 2602 result[key] = [ result[key], value ] 2603 } 2604 } 2605 ) 2606 2607 return result 2608} 2609},{"for-each":58,"trim":59}],61:[function(_dereq_,module,exports){ 2610module.exports = extend 2611 2612var hasOwnProperty = Object.prototype.hasOwnProperty; 2613 2614function extend() { 2615 var target = {} 2616 2617 for (var i = 0; i < arguments.length; i++) { 2618 var source = arguments[i] 2619 2620 for (var key in source) { 2621 if (hasOwnProperty.call(source, key)) { 2622 target[key] = source[key] 2623 } 2624 } 2625 } 2626 2627 return target 2628} 2629 2630},{}],62:[function(_dereq_,module,exports){ 2631/** 2632 * @file big-play-button.js 2633 */ 2634'use strict'; 2635 2636exports.__esModule = true; 2637 2638function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2639 2640function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 2641 2642function _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; } 2643 2644var _buttonJs = _dereq_('./button.js'); 2645 2646var _buttonJs2 = _interopRequireDefault(_buttonJs); 2647 2648var _componentJs = _dereq_('./component.js'); 2649 2650var _componentJs2 = _interopRequireDefault(_componentJs); 2651 2652/** 2653 * Initial play button. Shows before the video has played. The hiding of the 2654 * big play button is done via CSS and player states. 2655 * 2656 * @param {Object} player Main Player 2657 * @param {Object=} options Object of option names and values 2658 * @extends Button 2659 * @class BigPlayButton 2660 */ 2661 2662var BigPlayButton = (function (_Button) { 2663 _inherits(BigPlayButton, _Button); 2664 2665 function BigPlayButton(player, options) { 2666 _classCallCheck(this, BigPlayButton); 2667 2668 _Button.call(this, player, options); 2669 } 2670 2671 /** 2672 * Allow sub components to stack CSS class names 2673 * 2674 * @return {String} The constructed class name 2675 * @method buildCSSClass 2676 */ 2677 2678 BigPlayButton.prototype.buildCSSClass = function buildCSSClass() { 2679 return 'vjs-big-play-button'; 2680 }; 2681 2682 /** 2683 * Handles click for play 2684 * 2685 * @method handleClick 2686 */ 2687 2688 BigPlayButton.prototype.handleClick = function handleClick() { 2689 this.player_.play(); 2690 }; 2691 2692 return BigPlayButton; 2693})(_buttonJs2['default']); 2694 2695BigPlayButton.prototype.controlText_ = 'Play Video'; 2696 2697_componentJs2['default'].registerComponent('BigPlayButton', BigPlayButton); 2698exports['default'] = BigPlayButton; 2699module.exports = exports['default']; 2700 2701},{"./button.js":63,"./component.js":66}],63:[function(_dereq_,module,exports){ 2702/** 2703 * @file button.js 2704 */ 2705'use strict'; 2706 2707exports.__esModule = true; 2708 2709function _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; } } 2710 2711function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2712 2713function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 2714 2715function _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
2715onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 2716 2717var _clickableComponentJs = _dereq_('./clickable-component.js'); 2718 2719var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs); 2720 2721var _component = _dereq_('./component'); 2722 2723var _component2 = _interopRequireDefault(_component); 2724 2725var _utilsEventsJs = _dereq_('./utils/events.js'); 2726 2727var Events = _interopRequireWildcard(_utilsEventsJs); 2728 2729var _utilsFnJs = _dereq_('./utils/fn.js'); 2730 2731var Fn = _interopRequireWildcard(_utilsFnJs); 2732 2733var _utilsLogJs = _dereq_('./utils/log.js'); 2734 2735var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 2736 2737var _globalDocument = _dereq_('global/document'); 2738 2739var _globalDocument2 = _interopRequireDefault(_globalDocument); 2740 2741var _objectAssign = _dereq_('object.assign'); 2742 2743var _objectAssign2 = _interopRequireDefault(_objectAssign); 2744 2745/** 2746 * Base class for all buttons 2747 * 2748 * @param {Object} player Main Player 2749 * @param {Object=} options Object of option names and values 2750 * @extends ClickableComponent 2751 * @class Button 2752 */ 2753 2754var Button = (function (_ClickableComponent) { 2755 _inherits(Button, _ClickableComponent); 2756 2757 function Button(player, options) { 2758 _classCallCheck(this, Button); 2759 2760 _ClickableComponent.call(this, player, options); 2761 } 2762 2763 /** 2764 * Create the component's DOM element 2765 * 2766 * @param {String=} type Element's node type. e.g. 'div' 2767 * @param {Object=} props An object of properties that should be set on the element 2768 * @param {Object=} attributes An object of attributes that should be set on the element 2769 * @return {Element} 2770 * @method createEl 2771 */ 2772 2773 Button.prototype.createEl = function createEl() { 2774 var tag = arguments.length <= 0 || arguments[0] === undefined ? 'button' : arguments[0]; 2775 var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 2776 var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; 2777 2778 props = _objectAssign2['default']({ 2779 className: this.buildCSSClass() 2780 }, props); 2781 2782 if (tag !== 'button') { 2783 _utilsLogJs2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.'); 2784 } 2785 2786 // Add attributes for button element 2787 attributes = _objectAssign2['default']({ 2788 type: 'button', // Necessary since the default button type is "submit" 2789 'aria-live': 'polite' // let the screen reader user know that the text of the button may change 2790 }, attributes); 2791 2792 var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes); 2793 2794 this.createControlTextEl(el); 2795 2796 return el; 2797 }; 2798 2799 /** 2800 * Adds a child component inside this button 2801 * 2802 * @param {String|Component} child The class name or instance of a child to add 2803 * @param {Object=} options Options, including options to be passed to children of the child. 2804 * @return {Component} The child component (created by this process if a string was used) 2805 * @deprecated 2806 * @method addChild 2807 */ 2808 2809 Button.prototype.addChild = function addChild(child) { 2810 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 2811 2812 var className = this.constructor.name; 2813 _utilsLogJs2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.'); 2814 2815 // Avoid the error message generated by ClickableComponent's addChild method 2816 return _component2['default'].prototype.addChild.call(this, child, options); 2817 }; 2818 2819 /** 2820 * Handle KeyPress (document level) - Extend with specific functionality for button 2821 * 2822 * @method handleKeyPress 2823 */ 2824 2825 Button.prototype.handleKeyPress = function handleKeyPress(event) { 2826 // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button. 2827 if (event.which === 32 || event.which === 13) {} else { 2828 _ClickableComponent.prototype.handleKeyPress.call(this, event); // Pass keypress handling up for unsupported keys 2829 } 2830 }; 2831 2832 return Button; 2833})(_clickableComponentJs2['default']); 2834 2835_component2['default'].registerComponent('Button', Button); 2836exports['default'] = Button; 2837module.exports = exports['default']; 2838 2839},{"./clickable-component.js":64,"./component":66,"./utils/events.js":132,"./ut
2839ils/fn.js":133,"./utils/log.js":136,"global/document":1,"object.assign":45}],64:[function(_dereq_,module,exports){ 2840/** 2841 * @file button.js 2842 */ 2843'use strict'; 2844 2845exports.__esModule = true; 2846 2847function _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; } } 2848 2849function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2850 2851function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 2852 2853function _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; } 2854 2855var _component = _dereq_('./component'); 2856 2857var _component2 = _interopRequireDefault(_component); 2858 2859var _utilsDomJs = _dereq_('./utils/dom.js'); 2860 2861var Dom = _interopRequireWildcard(_utilsDomJs); 2862 2863var _utilsEventsJs = _dereq_('./utils/events.js'); 2864 2865var Events = _interopRequireWildcard(_utilsEventsJs); 2866 2867var _utilsFnJs = _dereq_('./utils/fn.js'); 2868 2869var Fn = _interopRequireWildcard(_utilsFnJs); 2870 2871var _utilsLogJs = _dereq_('./utils/log.js'); 2872 2873var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 2874 2875var _globalDocument = _dereq_('global/document'); 2876 2877var _globalDocument2 = _interopRequireDefault(_globalDocument); 2878 2879var _objectAssign = _dereq_('object.assign'); 2880 2881var _objectAssign2 = _interopRequireDefault(_objectAssign); 2882 2883/** 2884 * Clickable Component which is clickable or keyboard actionable, but is not a native HTML button 2885 * 2886 * @param {Object} player Main Player 2887 * @param {Object=} options Object of option names and values 2888 * @extends Component 2889 * @class ClickableComponent 2890 */ 2891 2892var ClickableComponent = (function (_Component) { 2893 _inherits(ClickableComponent, _Component); 2894 2895 function ClickableComponent(player, options) { 2896 _classCallCheck(this, ClickableComponent); 2897 2898 _Component.call(this, player, options); 2899 2900 this.emitTapEvents(); 2901 2902 this.on('tap', this.handleClick); 2903 this.on('click', this.handleClick); 2904 this.on('focus', this.handleFocus); 2905 this.on('blur', this.handleBlur); 2906 } 2907 2908 /** 2909 * Create the component's DOM element 2910 * 2911 * @param {String=} type Element's node type. e.g. 'div' 2912 * @param {Object=} props An object of properties that should be set on the element 2913 * @param {Object=} attributes An object of attributes that should be set on the element 2914 * @return {Element} 2915 * @method createEl 2916 */ 2917 2918 ClickableComponent.prototype.createEl = function createEl() { 2919 var tag = arguments.length <= 0 || arguments[0] === undefined ? 'div' : arguments[0]; 2920 var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 2921 var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; 2922 2923 props = _objectAssign2['default']({ 2924 className: this.buildCSSClass(), 2925 tabIndex: 0 2926 }, props); 2927 2928 if (tag === 'button') { 2929 _utilsLogJs2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.'); 2930 } 2931 2932 // Add ARIA attributes for clickable element which is not a native HTML button 2933 attributes = _objectAssign2['default']({ 2934 role: 'button', 2935 'aria-live': 'polite' // let the screen reader user know that the text of the element may change 2936 }, attributes); 2937 2938 var el = _Component.prototype.createEl.call(this, tag, props, attributes); 2939 2940 this.createControlTextEl(el); 2941 2942 return el; 2943 }; 2944 2945 /** 2946 * create control text 2947 * 2948 * @param {Element} el Parent element for the control text 2949 * @return {Element} 2950 * @method controlText 2951 */ 2952 2953 ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) { 2954 this.controlTextEl_ = Dom.createEl('span', { 2955 className: 'vjs-control-text' 2956 }); 2957 2958 if (el) { 2959 el.appendChild(this.controlTextEl_); 2960 } 2961 2962 this.controlText(this.controlText_); 2963 2964 return this.controlTextEl_; 2965 }; 2966 2967 /** 2968 * Controls text - both request and localize 2969 * 2970 * @param {String} text Text for element 2971 * @return {String} 2972 * @method controlText 2973 */ 2974 2975 ClickableComponent.prototype.controlText = function controlText(text) { 2976 if (!text) return this.controlText_ || 'Need Text'; 2977 2978 this.controlText_ = text; 2979 this.controlTextEl_.innerHTML = this.localize(this.controlText_); 2980 2981 return this; 2982 }; 2983 2984 /** 2985 * Allows sub components to stack CSS class names 2986 * 2987 * @return {String} 2988 * @method buildCSSClass 2989 */ 2990 2991 ClickableComponent.prototype.buildCSSClass = function buildCSSClass() { 2992 return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this); 2993 }; 2994 2995 /** 2996 * Adds a child component inside this clickable-component 2997 * 2998 * @param {String|Component} child The class name or instance of a child to add 2999 * @param {Object=} options Options, including options to be passed to children of the child. 3000 * @return {Component} The child component (created by this process if a string was used) 3001 * @method addChild 3002 */ 3003 3004 ClickableComponent.prototype.addChild = function addChild(child) { 3005 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 3006 3007 // TODO: Fix adding an actionable child to a ClickableComponent; currently 3008 // it will cause issues with assistive technology (e.g. screen readers) 3009 // which support ARIA, since an element with role="button" cannot have 3010 // actionable child elements. 3011 3012 //let className = this.constructor.name; 3013 //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.`); 3014 3015 return _Component.prototype.addChild.call(this, child, options); 3016 }; 3017 3018 /** 3019 * Handle Click - Override with specific functionality for component 3020 * 3021 * @method handleClick 3022 */ 3023 3024 ClickableComponent.prototype.handleClick = function handleClick() {}; 3025 3026 /** 3027 * Handle Focus - Add keyboard functionality to element 3028 * 3029 * @method handleFocus 3030 */ 3031 3032 ClickableComponent.prototype.handleFocus = function handleFocus() { 3033 Events.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); 3034 }; 3035 3036 /** 3037 * Handle KeyPress (document level) - Trigger click when Space or Enter key is pressed 3038 * 3039 * @method handleKeyPress 3040 */ 3041 3042 ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) {
3043 // Support Space (32) or Enter (13) key operation to fire a click event 3044 if (event.which === 32 || event.which === 13) { 3045 event.preventDefault(); 3046 this.handleClick(event); 3047 } else if (_Component.prototype.handleKeyPress) { 3048 _Component.prototype.handleKeyPress.call(this, event); // Pass keypress handling up for unsupported keys 3049 } 3050 }; 3051 3052 /** 3053 * Handle Blur - Remove keyboard triggers 3054 * 3055 * @method handleBlur 3056 */ 3057 3058 ClickableComponent.prototype.handleBlur = function handleBlur() { 3059 Events.off(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); 3060 }; 3061 3062 return ClickableComponent; 3063})(_component2['default']); 3064 3065_component2['default'].registerComponent('ClickableComponent', ClickableComponent); 3066exports['default'] = ClickableComponent; 3067module.exports = exports['default']; 3068 3069},{"./component":66,"./utils/dom.js":131,"./utils/events.js":132,"./utils/fn.js":133,"./utils/log.js":136,"global/document":1,"object.assign":45}],65:[function(_dereq_,module,exports){ 3070'use strict'; 3071 3072exports.__esModule = true; 3073 3074function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3075 3076function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 3077 3078function _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; } 3079 3080var _button = _dereq_('./button'); 3081 3082var _button2 = _interopRequireDefault(_button); 3083 3084var _component = _dereq_('./component'); 3085 3086var _component2 = _interopRequireDefault(_component); 3087 3088/** 3089 * The `CloseButton` component is a button which fires a "close" event 3090 * when it is activated. 3091 * 3092 * @extends Button 3093 * @class CloseButton 3094 */ 3095 3096var CloseButton = (function (_Button) { 3097 _inherits(CloseButton, _Button); 3098 3099 function CloseButton(player, options) { 3100 _classCallCheck(this, CloseButton); 3101 3102 _Button.call(this, player, options); 3103 this.controlText(options && options.controlText || this.localize('Close')); 3104 } 3105 3106 CloseButton.prototype.buildCSSClass = function buildCSSClass() { 3107 return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this); 3108 }; 3109 3110 CloseButton.prototype.handleClick = function handleClick() { 3111 this.trigger({ type: 'close', bubbles: false }); 3112 }; 3113 3114 return CloseButton; 3115})(_button2['default']); 3116 3117_component2['default'].registerComponent('CloseButton', CloseButton); 3118exports['default'] = CloseButton; 3119module.exports = exports['default']; 3120 3121},{"./button":63,"./component":66}],66:[function(_dereq_,module,exports){ 3122/** 3123 * @file component.js 3124 * 3125 * Player Component - Base class for all UI objects 3126 */ 3127 3128'use strict'; 3129 3130exports.__esModule = true; 3131 3132function _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; } } 3133 3134function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 3135 3136function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 3137 3138var _globalWindow = _dereq_('global/window'); 3139 3140var _globalWindow2 = _interopRequireDefault(_globalWindow); 3141 3142var _utilsDomJs = _dereq_('./utils/dom.js'); 3143 3144var Dom = _interopRequireWildcard(_utilsDomJs); 3145 3146var _utilsFnJs = _dereq_('./utils/fn.js'); 3147 3148var Fn = _interopRequireWildcard(_utilsFnJs); 3149 3150var _utilsGuidJs = _dereq_('./utils/guid.js'); 3151 3152var Guid = _interopRequireWildcard(_utilsGuidJs); 3153 3154var _utilsEventsJs = _dereq_('./utils/events.js'); 3155 3156var Events = _interopRequireWildcard(_utilsEventsJs); 3157 3158var _utilsLogJs = _dereq_('./utils/log.js'); 3159 3160var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 3161 3162var _utilsToTitleCaseJs = _dereq_('./utils/to-title-case.js'); 3163 3164var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs); 3165 3166var _objectAssign = _dereq_('object.assign'); 3167 3168var _objectAssign2 = _interopRequireDefault(_objectAssign); 3169 3170var _utilsMergeOptionsJs = _dereq_('./utils/merge-options.js'); 3171 3172var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs); 3173 3174/** 3175 * Base UI Component class 3176 * Components are embeddable UI objects that are represented by both a 3177 * javascript object and an element in the DOM. They can be children of other 3178 * components, and can have many children themselves. 3179 * ```js 3180 * // adding a button to the player 3181 * var button = player.addChild('button'); 3182 * button.el(); // -> button element 3183 * ``` 3184 * ```html 3185 * <div class="video-js"> 3186 * <div class="vjs-button">Button</div>
3187 * </div> 3188 * ``` 3189 * Components are also event targets. 3190 * ```js 3191 * button.on('click', function(){ 3192 * console.log('Button Clicked!'); 3193 * }); 3194 * button.trigger('customevent'); 3195 * ``` 3196 * 3197 * @param {Object} player Main Player 3198 * @param {Object=} options Object of option names and values 3199 * @param {Function=} ready Ready callback function 3200 * @class Component 3201 */ 3202 3203var Component = (function () { 3204 function Component(player, options, ready) { 3205 _classCallCheck(this, Component); 3206 3207 // The component might be the player itself and we can't pass `this` to super 3208 if (!player && this.play) { 3209 this.player_ = player = this; // eslint-disable-line 3210 } else { 3211 this.player_ = player; 3212 } 3213 3214 // Make a copy of prototype.options_ to protect against overriding defaults 3215 this.options_ = _utilsMergeOptionsJs2['default']({}, this.options_); 3216 3217 // Updated options with supplied options 3218 options = this.options_ = _utilsMergeOptionsJs2['default'](this.options_, options); 3219 3220 // Get ID from options or options element if one is supplied 3221 this.id_ = options.id || options.el && options.el.id; 3222 3223 // If there was no ID from the options, generate one 3224 if (!this.id_) { 3225 // Don't require the player ID function in the case of mock players 3226 var id = player && player.id && player.id() || 'no_player'; 3227 3228 this.id_ = id + '_component_' + Guid.newGUID(); 3229 } 3230 3231 this.name_ = options.name || null; 3232 3233 // Create element if one wasn't provided in options 3234 if (options.el) { 3235 this.el_ = options.el; 3236 } else if (options.createEl !== false) { 3237 this.el_ = this.createEl(); 3238 } 3239 3240 this.children_ = []; 3241 this.childIndex_ = {}; 3242 this.childNameIndex_ = {}; 3243 3244 // Add any child components in options 3245 if (options.initChildren !== false) { 3246 this.initChildren(); 3247 } 3248 3249 this.ready(ready); 3250 // Don't want to trigger ready here or it will before init is actually 3251 // finished for all children that run this constructor 3252 3253 if (options.reportTouchActivity !== false) { 3254 this.enableTouchActivity(); 3255 } 3256 } 3257 3258 /** 3259 * Dispose of the component and all child components 3260 * 3261 * @method dispose 3262 */ 3263 3264 Component.prototype.dispose = function dispose() { 3265 this.trigger({ type: 'dispose', bubbles: false }); 3266 3267 // Dispose all children. 3268 if (this.children_) { 3269 for (var i = this.children_.length - 1; i >= 0; i--) { 3270 if (this.children_[i].dispose) { 3271 this.children_[i].dispose(); 3272 } 3273 } 3274 } 3275 3276 // Delete child references 3277 this.children_ = null; 3278 this.childIndex_ = null; 3279 this.childNameIndex_ = null; 3280 3281 // Remove all event listeners. 3282 this.off(); 3283 3284 // Remove element from DOM 3285 if (this.el_.parentNode) { 3286 this.el_.parentNode.removeChild(this.el_); 3287 } 3288 3289 Dom.removeElData(this.el_); 3290 this.el_ = null; 3291 }; 3292 3293 /** 3294 * Return the component's player 3295 * 3296 * @return {Player} 3297 * @method player 3298 */ 3299 3300 Component.prototype.player = function player() { 3301 return this.player_; 3302 }; 3303 3304 /** 3305 * Deep merge of options objects 3306 * Whenever a property is an object on both options objects 3307 * the two properties will be merged using mergeOptions. 3308 * 3309 * ```js 3310 * Parent.prototype.options_ = { 3311 * optionSet: { 3312 * 'childOne': { 'foo': 'bar', 'asdf': 'fdsa' }, 3313 * 'childTwo': {}, 3314 * 'childThree': {} 3315 * } 3316 * } 3317 * newOptions = { 3318 * optionSet: { 3319 * 'childOne': { 'foo': 'baz', 'abc': '123' } 3320 * 'childTwo': null, 3321 * 'childFour': {} 3322 * } 3323 * } 3324 * 3325 * this.options(newOptions); 3326 * ``` 3327 * RESULT 3328 * ```js 3329 * { 3330 * optionSet: { 3331 * 'childOne': { 'foo': 'baz', 'asdf': 'fdsa', 'abc': '123' }, 3332 * 'childTwo': null, // Disabled. Won't be initialized. 3333 * 'childThree': {}, 3334 * 'childFour': {} 3335 * } 3336 * } 3337 * ``` 3338 * 3339 * @param {Object} obj Object of new option values 3340 * @return {Object} A NEW object of this.options_ and obj merged 3341 * @method options 3342 */ 3343 3344 Component.prototype.options = function options(obj) { 3345 _utilsLogJs2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0'); 3346 3347 if (!obj) { 3348 return this.options_; 3349 } 3350 3351 this.options_ = _utilsMergeOptionsJs2['default'](this.options_, obj); 3352 return this.options_; 3353 }; 3354 3355 /** 3356 * Get the component's DOM element 3357 * ```js 3358 * var domEl = myComponent.el(); 3359 * ``` 3360 * 3361 * @return {Element} 3362 * @method el 3363 */ 3364 3365 Component.prototype.el = function el() { 3366 return this.el_; 3367 }; 3368 3369 /** 3370 * Create the component's DOM element 3371 * 3372 * @param {String=} tagName Element's node type. e.g. 'div' 3373 * @param {Object=} properties An object of properties that should be set 3374 * @param {Object=} attributes An object of attributes that should be set 3375 * @return {Element} 3376 * @method createEl 3377 */ 3378 3379 Component.prototype.createEl = function createEl(tagName, properties, attributes) { 3380 return Dom.createEl(tagName, properties, attributes); 3381 }; 3382 3383 Component.prototype.localize = function localize(string) { 3384 var code = this.player_.language && this.player_.language(); 3385 var languages = this.player_.languages && this.player_.languages(); 3386 3387 if (!code || !languages) { 3388 return string; 3389 } 3390 3391 var language = languages[code]; 3392 3393 if (language && language[string]) { 3394 return language[string]; 3395 } 3396 3397 var primaryCode = code.split('-')[0]; 3398 var primaryLang = languages[primaryCode]; 3399 3400 if (primaryLang && primaryLang[string]) { 3401 return primaryLang[string]; 3402 } 3403 3404 return string; 3405 }; 3406 3407 /** 3408 * Return the component's DOM element where children are inserted. 3409 * Will either be the same as el() or a new element defined in createEl(). 3410 * 3411 * @return {Element} 3412 * @method contentEl 3413 */ 3414 3415 Component.prototype.contentEl = function contentEl() { 3416 return this.contentEl_ || this.el_; 3417 }; 3418 3419 /** 3420 * Get the component's ID 3421 * ```js 3422 * var id = myComponent.id(); 3423 * ``` 3424 * 3425 * @return {String} 3426 * @method id 3427 */ 3428 3429 Component.prototype.id = function id() { 3430 return this.id_; 3431 }; 3432 3433 /** 3434 * Get the component's name. The name is often used to reference the component. 3435 * ```js 3436 * var name = myComponent.name(); 3437 * ``` 3438 * 3439 * @return {String}
3440 * @method name 3441 */ 3442 3443 Component.prototype.name = function name() { 3444 return this.name_; 3445 }; 3446 3447 /** 3448 * Get an array of all child components 3449 * ```js 3450 * var kids = myComponent.children(); 3451 * ``` 3452 * 3453 * @return {Array} The children 3454 * @method children 3455 */ 3456 3457 Component.prototype.children = function children() { 3458 return this.children_; 3459 }; 3460 3461 /** 3462 * Returns a child component with the provided ID 3463 * 3464 * @return {Component} 3465 * @method getChildById 3466 */ 3467 3468 Component.prototype.getChildById = function getChildById(id) { 3469 return this.childIndex_[id]; 3470 }; 3471 3472 /** 3473 * Returns a child component with the provided name 3474 * 3475 * @return {Component} 3476 * @method getChild 3477 */ 3478 3479 Component.prototype.getChild = function getChild(name) { 3480 return this.childNameIndex_[name]; 3481 }; 3482 3483 /** 3484 * Adds a child component inside this component 3485 * ```js 3486 * myComponent.el(); 3487 * // -> <div class='my-component'></div> 3488 * myComponent.children(); 3489 * // [empty array] 3490 * 3491 * var myButton = myComponent.addChild('MyButton'); 3492 * // -> <div class='my-component'><div class="my-button">myButton<div></div> 3493 * // -> myButton === myComponent.children()[0]; 3494 * ``` 3495 * Pass in options for child constructors and options for children of the child 3496 * ```js 3497 * var myButton = myComponent.addChild('MyButton', { 3498 * text: 'Press Me', 3499 * buttonChildExample: { 3500 * buttonChildOption: true 3501 * } 3502 * }); 3503 * ``` 3504 * 3505 * @param {String|Component} child The class name or instance of a child to add 3506 * @param {Object=} options Options, including options to be passed to children of the child. 3507 * @param {Number} index into our children array to attempt to add the child 3508 * @return {Component} The child component (created by this process if a string was used) 3509 * @method addChild 3510 */ 3511 3512 Component.prototype.addChild = function addChild(child) { 3513 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 3514 var index = arguments.length <= 2 || arguments[2] === undefined ? this.children_.length : arguments[2]; 3515 3516 var component = undefined; 3517 var componentName = undefined; 3518 3519 // If child is a string, create nt with options 3520 if (typeof child === 'string') { 3521 componentName = child; 3522 3523 // Options can also be specified as a boolean, so convert to an empty object if false. 3524 if (!options) { 3525 options = {}; 3526 } 3527 3528 // Same as above, but true is deprecated so show a warning. 3529 if (options === true) { 3530 _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`.'); 3531 options = {}; 3532 } 3533 3534 // If no componentClass in options, assume componentClass is the name lowercased 3535 // (e.g. playButton) 3536 var componentClassName = options.componentClass || _utilsToTitleCaseJs2['default'](componentName); 3537 3538 // Set name through options 3539 options.name = componentName; 3540 3541 // Create a new object & element for this controls set 3542 // If there's no .player_, this is a player 3543 var ComponentClass = Component.getComponent(componentClassName); 3544 3545 if (!ComponentClass) { 3546 throw new Error('Component ' + componentClassName + ' does not exist'); 3547 } 3548 3549 // data stored directly on the videojs object may be 3550 // misidentified as a component to retain 3551 // backwards-compatibility with 4.x. check to make sure the 3552 // component class can be instantiated. 3553 if (typeof ComponentClass !== 'function') { 3554 return null; 3555 } 3556 3557 component = new ComponentClass(this.player_ || this, options); 3558 3559 // child is a component instance 3560 } else { 3561 component = child; 3562 } 3563 3564 this.children_.splice(index, 0, component); 3565 3566 if (typeof component.id === 'function') { 3567 this.childIndex_[component.id()] = component; 3568 } 3569 3570 // If a name wasn't used to create the component, check if we can use the 3571 // name function of the component 3572 componentName = componentName || component.name && component.name(); 3573 3574 if (componentName) { 3575 this.childNameIndex_[componentName] = component; 3576 } 3577 3578 // Add the UI object's element to the container div (box) 3579 // Having an element is not required 3580 if (typeof component.el === 'function' && component.el()) { 3581 var childNodes = this.contentEl().children;
vendor: 5,718 bytes, lines 3582-3765
3582 var refNode = childNodes[index] || null; 3583 this.contentEl().insertBefore(component.el(), refNode); 3584 } 3585 3586 // Return so it can stored on parent object if desired. 3587 return component; 3588 }; 3589 3590 /** 3591 * Remove a child component from this component's list of children, and the 3592 * child component's element from this component's element 3593 * 3594 * @param {Component} component Component to remove 3595 * @method removeChild 3596 */ 3597 3598 Component.prototype.removeChild = function removeChild(component) { 3599 if (typeof component === 'string') { 3600 component = this.getChild(component); 3601 } 3602 3603 if (!component || !this.children_) { 3604 return; 3605 } 3606 3607 var childFound = false; 3608 3609 for (var i = this.children_.length - 1; i >= 0; i--) { 3610 if (this.children_[i] === component) { 3611 childFound = true; 3612 this.children_.splice(i, 1); 3613 break; 3614 } 3615 } 3616 3617 if (!childFound) { 3618 return; 3619 } 3620 3621 this.childIndex_[component.id()] = null; 3622 this.childNameIndex_[component.name()] = null; 3623 3624 var compEl = component.el(); 3625 3626 if (compEl && compEl.parentNode === this.contentEl()) { 3627 this.contentEl().removeChild(component.el()); 3628 } 3629 }; 3630 3631 /** 3632 * Add and initialize default child components from options 3633 * ```js 3634 * // when an instance of MyComponent is created, all children in options 3635 * // will be added to the instance by their name strings and options 3636 * MyComponent.prototype.options_ = { 3637 * children: [ 3638 * 'myChildComponent' 3639 * ], 3640 * myChildComponent: { 3641 * myChildOption: true 3642 * } 3643 * }; 3644 * 3645 * // Or when creating the component 3646 * var myComp = new MyComponent(player, { 3647 * children: [ 3648 * 'myChildComponent' 3649 * ], 3650 * myChildComponent: { 3651 * myChildOption: true 3652 * } 3653 * }); 3654 * ``` 3655 * The children option can also be an array of 3656 * child options objects (that also include a 'name' key). 3657 * This can be used if you have two child components of the 3658 * same type that need different options. 3659 * ```js 3660 * var myComp = new MyComponent(player, { 3661 * children: [ 3662 * 'button', 3663 * { 3664 * name: 'button', 3665 * someOtherOption: true 3666 * }, 3667 * { 3668 * name: 'button', 3669 * someOtherOption: false 3670 * } 3671 * ] 3672 * }); 3673 * ``` 3674 * 3675 * @method initChildren 3676 */ 3677 3678 Component.prototype.initChildren = function initChildren() { 3679 var _this = this; 3680 3681 var children = this.options_.children; 3682 3683 if (children) { 3684 (function () { 3685 // `this` is `parent` 3686 var parentOptions = _this.options_; 3687 3688 var handleAdd = function handleAdd(child) { 3689 var name = child.name; 3690 var opts = child.opts; 3691 3692 // Allow options for children to be set at the parent options 3693 // e.g. videojs(id, { controlBar: false }); 3694 // instead of videojs(id, { children: { controlBar: false }); 3695 if (parentOptions[name] !== undefined) { 3696 opts = parentOptions[name]; 3697 } 3698 3699 // Allow for disabling default components 3700 // e.g. options['children']['posterImage'] = false 3701 if (opts === false) { 3702 return; 3703 } 3704 3705 // Allow options to be passed as a simple boolean if no configuration 3706 // is necessary. 3707 if (opts === true) { 3708 opts = {}; 3709 } 3710 3711 // We also want to pass the original player options to each component as well so they don't need to 3712 // reach back into the player for options later. 3713 opts.playerOptions = _this.options_.playerOptions; 3714 3715 // Create and add the child component. 3716 // Add a direct reference to the child by name on the parent instance. 3717 // If two of the same component are used, different names should be supplied 3718 // for each 3719 var newChild = _this.addChild(name, opts); 3720 if (newChild) { 3721 _this[name] = newChild; 3722 } 3723 }; 3724 3725 // Allow for an array of children details to passed in the options 3726 var workingChildren = undefined; 3727 var Tech = Component.getComponent('Tech'); 3728 3729 if (Array.isArray(children)) { 3730 workingChildren = children; 3731 } else { 3732 workingChildren = Object.keys(children); 3733 } 3734 3735 workingChildren 3736 // children that are in this.options_ but also in workingChildren would 3737 // give us extra children we do not want. So, we want to filter them out. 3738 .concat(Object.keys(_this.options_).filter(function (child) { 3739 return !workingChildren.some(function (wchild) { 3740 if (typeof wchild === 'string') { 3741 return child === wchild; 3742 } else { 3743 return child === wchild.name; 3744 } 3745 }); 3746 })).map(function (child) { 3747 var name = undefined, 3748 opts = undefined; 3749 3750 if (typeof child === 'string') { 3751 name = child; 3752 opts = children[name] || _this.options_[name] || {}; 3753 } else { 3754 name = child.name; 3755 opts = child; 3756 } 3757 3758 return { name: name, opts: opts }; 3759 }).filter(function (child) { 3760 // we have to make sure that child.name isn't in the techOrder since 3761 // techs are registerd as Components but can't aren't compatible 3762 // See https://github.com/videojs/video.js/issues/2772 3763 var c = Component.getComponent(child.opts.componentClass || _utilsToTitleCaseJs2['default'](child.name)); 3764 return c && !Tech.isTech(c); 3765 }
3765).forEach(handleAdd); 3766 })(); 3767 } 3768 }; 3769 3770 /** 3771 * Allows sub components to stack CSS class names 3772 * 3773 * @return {String} The constructed class name 3774 * @method buildCSSClass 3775 */ 3776 3777 Component.prototype.buildCSSClass = function buildCSSClass() { 3778 // Child classes can include a function that does: 3779 // return 'CLASS NAME' + this._super(); 3780 return ''; 3781 }; 3782 3783 /** 3784 * Add an event listener to this component's element 3785 * ```js 3786 * var myFunc = function(){ 3787 * var myComponent = this; 3788 * // Do something when the event is fired 3789 * }; 3790 * 3791 * myComponent.on('eventType', myFunc); 3792 * ``` 3793 * The context of myFunc will be myComponent unless previously bound. 3794 * Alternatively, you can add a listener to another element or component. 3795 * ```js 3796 * myComponent.on(otherElement, 'eventName', myFunc); 3797 * myComponent.on(otherComponent, 'eventName', myFunc); 3798 * ``` 3799 * The benefit of using this over `VjsEvents.on(otherElement, 'eventName', myFunc)` 3800 * and `otherComponent.on('eventName', myFunc)` is that this way the listeners 3801 * will be automatically cleaned up when either component is disposed. 3802 * It will also bind myComponent as the context of myFunc. 3803 * **NOTE**: When using this on elements in the page other than window 3804 * and document (both permanent), if you remove the element from the DOM 3805 * you need to call `myComponent.trigger(el, 'dispose')` on it to clean up 3806 * references to it and allow the browser to garbage collect it. 3807 * 3808 * @param {String|Component} first The event type or other component 3809 * @param {Function|String} second The event handler or event type 3810 * @param {Function} third The event handler 3811 * @return {Component} 3812 * @method on 3813 */ 3814 3815 Component.prototype.on = function on(first, second, third) { 3816 var _this2 = this; 3817 3818 if (typeof first === 'string' || Array.isArray(first)) { 3819 Events.on(this.el_, first, Fn.bind(this, second)); 3820 3821 // Targeting another component or element 3822 } else { 3823 (function () { 3824 var target = first; 3825 var type = second; 3826 var fn = Fn.bind(_this2, third); 3827 3828 // When this component is disposed, remove the listener from the other component 3829 var removeOnDispose = function removeOnDispose() { 3830 return _this2.off(target, type, fn); 3831 }; 3832 3833 // Use the same function ID so we can remove it later it using the ID 3834 // of the original listener 3835 removeOnDispose.guid = fn.guid; 3836 _this2.on('dispose', removeOnDispose); 3837 3838 // If the other component is disposed first we need to clean the reference 3839 // to the other component in this component's removeOnDispose listener 3840 // Otherwise we create a memory leak. 3841 var cleanRemover = function cleanRemover() { 3842 return _this2.off('dispose', removeOnDispose); 3843 }; 3844 3845 // Add the same function ID so we can easily remove it later 3846 cleanRemover.guid = fn.guid; 3847 3848 // Check if this is a DOM node 3849 if (first.nodeName) { 3850 // Add the listener to the other element 3851 Events.on(target, type, fn); 3852 Events.on(target, 'dispose', cleanRemover); 3853 3854 // Should be a component 3855 // Not using `instanceof Component` because it makes mock players difficult 3856 } else if (typeof first.on === 'function') { 3857 // Add the listener to the other component 3858 target.on(type, fn); 3859 target.on('dispose', cleanRemover); 3860 } 3861 })(); 3862 } 3863 3864 return this; 3865 }; 3866 3867 /** 3868 * Remove an event listener from this component's element 3869 * ```js 3870 * myComponent.off('eventType', myFunc); 3871 * ``` 3872 * If myFunc is excluded, ALL listeners for the event type will be removed. 3873 * If eventType is excluded, ALL listeners will be removed from the component. 3874 * Alternatively you can use `off` to remove listeners that were added to other 3875 * elements or components using `myComponent.on(otherComponent...`. 3876 * In this case both the event type and listener function are REQUIRED. 3877 * ```js 3878 * myComponent.off(otherElement, 'eventType', myFunc); 3879 * myComponent.off(otherComponent, 'eventType', myFunc); 3880 * ``` 3881 * 3882 * @param {String=|Component} first The event type or other component 3883 * @param {Function=|String} second The listener function or event type 3884 * @param {Function=} third The listener for other component 3885 * @return {Component} 3886 * @method off 3887 */ 3888 3889 Component.prototype.off = function off(first, second, third) { 3890 if (!first || typeof first === 'string' || Array.isArray(first)) { 3891 Events.off(this.el_, first, second); 3892 } else { 3893 var target = first; 3894 var type = second; 3895 // Ensure there's at least a guid, even if the function hasn't been used 3896 var fn = Fn.bind(this, third); 3897 3898 // Remove the dispose listener on this component, 3899 // which was given the same guid as the event listener 3900 this.off('dispose', fn); 3901 3902 if (first.nodeName) { 3903 // Remove the listener 3904 Events.off(target, type, fn); 3905 // Remove the listener for cleaning the dispose listener 3906 Events.off(target, 'dispose', fn); 3907 } else {
3908 target.off(type, fn); 3909 target.off('dispose', fn); 3910 } 3911 } 3912 3913 return this; 3914 }; 3915 3916 /** 3917 * Add an event listener to be triggered only once and then removed 3918 * ```js 3919 * myComponent.one('eventName', myFunc); 3920 * ``` 3921 * Alternatively you can add a listener to another element or component 3922 * that will be triggered only once. 3923 * ```js 3924 * myComponent.one(otherElement, 'eventName', myFunc); 3925 * myComponent.one(otherComponent, 'eventName', myFunc); 3926 * ``` 3927 * 3928 * @param {String|Component} first The event type or other component 3929 * @param {Function|String} second The listener function or event type 3930 * @param {Function=} third The listener function for other component 3931 * @return {Component} 3932 * @method one 3933 */ 3934 3935 Component.prototype.one = function one(first, second, third) { 3936 var _this3 = this, 3937 _arguments = arguments; 3938 3939 if (typeof first === 'string' || Array.isArray(first)) { 3940 Events.one(this.el_, first, Fn.bind(this, second)); 3941 } else { 3942 (function () { 3943 var target = first; 3944 var type = second; 3945 var fn = Fn.bind(_this3, third); 3946 3947 var newFunc = function newFunc() { 3948 _this3.off(target, type, newFunc); 3949 fn.apply(null, _arguments); 3950 }; 3951 3952 // Keep the same function ID so we can remove it later 3953 newFunc.guid = fn.guid; 3954 3955 _this3.on(target, type, newFunc); 3956 })(); 3957 } 3958 3959 return this; 3960 }; 3961 3962 /** 3963 * Trigger an event on an element 3964 * ```js 3965 * myComponent.trigger('eventName'); 3966 * myComponent.trigger({'type':'eventName'}); 3967 * myComponent.trigger('eventName', {data: 'some data'}); 3968 * myComponent.trigger({'type':'eventName'}, {data: 'some data'}); 3969 * ``` 3970 * 3971 * @param {Event|Object|String} event A string (the type) or an event object with a type attribute 3972 * @param {Object} [hash] data hash to pass along with the event 3973 * @return {Component} self 3974 * @method trigger 3975 */ 3976 3977 Component.prototype.trigger = function trigger(event, hash) { 3978 Events.trigger(this.el_, event, hash); 3979 return this; 3980 }; 3981 3982 /** 3983 * Bind a listener to the component's ready state. 3984 * Different from event listeners in that if the ready event has already happened 3985 * it will trigger the function immediately. 3986 * 3987 * @param {Function} fn Ready listener 3988 * @param {Boolean} sync Exec the listener synchronously if component is ready 3989 * @return {Component} 3990 * @method ready 3991 */ 3992 3993 Component.prototype.ready = function ready(fn) { 3994 var sync = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; 3995 3996 if (fn) { 3997 if (this.isReady_) { 3998 if (sync) { 3999 fn.call(this); 4000 } else { 4001 // Call the function asynchronously by default for consistency 4002 this.setTimeout(fn, 1); 4003 } 4004 } else { 4005 this.readyQueue_ = this.readyQueue_ || []; 4006 this.readyQueue_.push(fn); 4007 } 4008 } 4009 return this; 4010 }; 4011 4012 /** 4013 * Trigger the ready listeners 4014 * 4015 * @return {Component} 4016 * @method triggerReady 4017 */ 4018 4019 Component.prototype.triggerReady = function triggerReady() { 4020 this.isReady_ = true; 4021 4022 // Ensure ready is triggerd asynchronously 4023 this.setTimeout(function () { 4024 var readyQueue = this.readyQueue_; 4025 4026 // Reset Ready Queue 4027 this.readyQueue_ = []; 4028 4029 if (readyQueue && readyQueue.length > 0) { 4030 readyQueue.forEach(function (fn) { 4031 fn.call(this); 4032 }, this); 4033 } 4034 4035 // Allow for using event listeners also 4036 this.trigger('ready'); 4037 }, 1); 4038 }; 4039 4040 /** 4041 * Finds a single DOM element matching `selector` within the component's 4042 * `contentEl` or another custom context. 4043 * 4044 * @method $ 4045 * @param {String} selector 4046 * A valid CSS selector, which will be passed to `querySelector`. 4047 * 4048 * @param {Element|String} [context=document] 4049 * A DOM element within which to query. Can also be a selector 4050 * string in which case the first matching element will be used 4051 * as context. If missing (or no element matches selector), falls 4052 * back to `document`. 4053 * 4054 * @return {Element|null} 4055 */ 4056 4057 Component.prototype.$ = function $(selector, context) { 4058 return Dom.$(selector, context || this.contentEl()); 4059 }; 4060 4061 /** 4062 * Finds a all DOM elements matching `selector` within the component's 4063 * `contentEl` or another custom context. 4064 * 4065 * @method $$ 4066 * @param {String} selector 4067 * A valid CSS selector, which will be passed to `querySelectorAll`. 4068 * 4069 * @param {Element|String} [context=document] 4070 * A DOM element within which to query. Can also be a selector
4071 * string in which case the first matching element will be used 4072 * as context. If missing (or no element matches selector), falls 4073 * back to `document`. 4074 * 4075 * @return {NodeList} 4076 */ 4077 4078 Component.prototype.$$ = function $$(selector, context) { 4079 return Dom.$$(selector, context || this.contentEl()); 4080 }; 4081 4082 /** 4083 * Check if a component's element has a CSS class name 4084 * 4085 * @param {String} classToCheck Classname to check 4086 * @return {Component} 4087 * @method hasClass 4088 */ 4089 4090 Component.prototype.hasClass = function hasClass(classToCheck) { 4091 return Dom.hasElClass(this.el_, classToCheck); 4092 }; 4093 4094 /** 4095 * Add a CSS class name to the component's element 4096 * 4097 * @param {String} classToAdd Classname to add 4098 * @return {Component} 4099 * @method addClass 4100 */ 4101 4102 Component.prototype.addClass = function addClass(classToAdd) { 4103 Dom.addElClass(this.el_, classToAdd); 4104 return this; 4105 }; 4106 4107 /** 4108 * Remove a CSS class name from the component's element 4109 * 4110 * @param {String} classToRemove Classname to remove 4111 * @return {Component} 4112 * @method removeClass 4113 */ 4114 4115 Component.prototype.removeClass = function removeClass(classToRemove) { 4116 Dom.removeElClass(this.el_, classToRemove); 4117 return this; 4118 }; 4119 4120 /** 4121 * Add or remove a CSS class name from the component's element 4122 * 4123 * @param {String} classToToggle 4124 * @param {Boolean|Function} [predicate] 4125 * Can be a function that returns a Boolean. If `true`, the class 4126 * will be added; if `false`, the class will be removed. If not 4127 * given, the class will be added if not present and vice versa. 4128 * 4129 * @return {Component} 4130 * @method toggleClass 4131 */ 4132 4133 Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) { 4134 Dom.toggleElClass(this.el_, classToToggle, predicate); 4135 return this; 4136 }; 4137 4138 /** 4139 * Show the component element if hidden 4140 * 4141 * @return {Component} 4142 * @method show 4143 */ 4144 4145 Component.prototype.show = function show() { 4146 this.removeClass('vjs-hidden'); 4147 return this; 4148 }; 4149 4150 /** 4151 * Hide the component element if currently showing 4152 * 4153 * @return {Component} 4154 * @method hide 4155 */ 4156 4157 Component.prototype.hide = function hide() { 4158 this.addClass('vjs-hidden'); 4159 return this; 4160 }; 4161 4162 /** 4163 * Lock an item in its visible state 4164 * To be used with fadeIn/fadeOut. 4165 * 4166 * @return {Component} 4167 * @private 4168 * @method lockShowing 4169 */ 4170 4171 Component.prototype.lockShowing = function lockShowing() { 4172 this.addClass('vjs-lock-showing'); 4173 return this; 4174 }; 4175 4176 /** 4177 * Unlock an item to be hidden 4178 * To be used with fadeIn/fadeOut. 4179 * 4180 * @return {Component} 4181 * @private 4182 * @method unlockShowing 4183 */ 4184 4185 Component.prototype.unlockShowing = function unlockShowing() { 4186 this.removeClass('vjs-lock-showing'); 4187 return this; 4188 }; 4189 4190 /** 4191 * Set or get the width of the component (CSS values)
4192 * Setting the video tag dimension values only works with values in pixels. 4193 * Percent values will not work. 4194 * Some percents can be used, but width()/height() will return the number + %, 4195 * not the actual computed width/height. 4196 * 4197 * @param {Number|String=} num Optional width number 4198 * @param {Boolean} skipListeners Skip the 'resize' event trigger 4199 * @return {Component} This component, when setting the width 4200 * @return {Number|String} The width, when getting 4201 * @method width 4202 */ 4203 4204 Component.prototype.width = function width(num, skipListeners) { 4205 return this.dimension('width', num, skipListeners); 4206 }; 4207 4208 /** 4209 * Get or set the height of the component (CSS values) 4210 * Setting the video tag dimension values only works with values in pixels. 4211 * Percent values will not work. 4212 * Some percents can be used, but width()/height() will return the number + %, 4213 * not the actual computed width/height. 4214 * 4215 * @param {Number|String=} num New component height 4216 * @param {Boolean=} skipListeners Skip the resize event trigger 4217 * @return {Component} This component, when setting the height 4218 * @return {Number|String} The height, when getting 4219 * @method height 4220 */ 4221 4222 Component.prototype.height = function height(num, skipListeners) { 4223 return this.dimension('height', num, skipListeners); 4224 }; 4225 4226 /** 4227 * Set both width and height at the same time 4228 * 4229 * @param {Number|String} width Width of player 4230 * @param {Number|String} height Height of player 4231 * @return {Component} The component 4232 * @method dimensions 4233 */ 4234 4235 Component.prototype.dimensions = function dimensions(width, height) { 4236 // Skip resize listeners on width for optimization 4237 return this.width(width, true).height(height); 4238 }; 4239 4240 /** 4241 * Get or set width or height 4242 * This is the shared code for the width() and height() methods. 4243 * All for an integer, integer + 'px' or integer + '%'; 4244 * Known issue: Hidden elements officially have a width of 0. We're defaulting 4245 * to the style.width value and falling back to computedStyle which has the 4246 * hidden element issue. Info, but probably not an efficient fix: 4247 * http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/ 4248 * 4249 * @param {String} widthOrHeight 'width' or 'height' 4250 * @param {Number|String=} num New dimension 4251 * @param {Boolean=} skipListeners Skip resize event trigger 4252 * @return {Component} The component if a dimension was set 4253 * @return {Number|String} The dimension if nothing was set 4254 * @private 4255 * @method dimension 4256 */ 4257 4258 Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) { 4259 if (num !== undefined) { 4260 // Set to zero if null or literally NaN (NaN !== NaN) 4261 if (num === null || num !== num) { 4262 num = 0; 4263 } 4264 4265 // Check if using css width/height (% or px) and adjust 4266 if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) { 4267 this.el_.style[widthOrHeight] = num; 4268 } else if (num === 'auto') { 4269 this.el_.style[widthOrHeight] = ''; 4270 } else { 4271 this.el_.style[widthOrHeight] = num + 'px'; 4272 } 4273 4274 // skipListeners allows us to avoid triggering the resize event when setting both width and height 4275 if (!skipListeners) { 4276 this.trigger('resize'); 4277 } 4278 4279 // Return component 4280 return this; 4281 } 4282 4283 // Not setting a value, so getting it 4284 // Make sure element exists 4285 if (!this.el_) { 4286 return 0; 4287 } 4288 4289 // Get dimension value from style 4290 var val = this.el_.style[widthOrHeight]; 4291 var pxIndex = val.indexOf('px'); 4292 4293 if (pxIndex !== -1) { 4294 // Return the pixel value with no 'px' 4295 return parseInt(val.slice(0, pxIndex), 10); 4296 } 4297 4298 // No px so using % or no style was set, so falling back to offsetWidth/height 4299 // If component has display:none, offset will return 0 4300 // TODO: handle display:none and no dimension style using px 4301 return parseInt(this.el_['offset' + _utilsToTitleCaseJs2['default'](widthOrHeight)], 10); 4302 }; 4303 4304 /** 4305 * Emit 'tap' events when touch events are supported 4306 * This is used to support toggling the controls through a tap on the video. 4307 * We're requiring them to be enabled because otherwise every component would 4308 * have this extra overhead unnecessarily, on mobile devices where extra 4309 * overhead is especially bad. 4310 * 4311 * @private 4312 * @method emitTapEvents 4313 */ 4314 4315 Component.prototype.emitTapEvents = function emitTapEvents() { 4316 // Track the start time so we can determine how long the touch lasted 4317 var touchStart = 0; 4318 var firstTouch = null; 4319 4320 // Maximum movement allowed during a touch event to still be considered a tap 4321 // Other popular libs use anywhere from 2 (hammer.js) to 15, so 10 seems like a nice, round number. 4322 var tapMovementThreshold = 10; 4323 4324 // The maximum length a touch can be while still being considered a tap 4325 var touchTimeThreshold = 200; 4326 4327 var couldBeTap = undefined; 4328 4329 this.on('touchstart', function (event) { 4330 // If more than one finger, don't consider treating this as a click 4331 if (event.touches.length === 1) { 4332 // Copy the touches object to prevent modifying the original 4333 firstTouch = _objectAssign2['default']({}, event.touches[0]); 4334 // Record start time so we can detect a tap vs. "touch and hold" 4335 touchStart = new Date().getTime(); 4336 // Reset couldBeTap tracking 4337 couldBeTap = true; 4338 } 4339 }); 4340 4341 this.on('touchmove', function (event) { 4342 // If more than one finger, don't consider treating this as a click 4343 if (event.touches.length > 1) { 4344 couldBeTap = false;
vendor: 4,486 bytes, lines 4345-4454
4345 } else if (firstTouch) { 4346 // Some devices will throw touchmoves for all but the slightest of taps. 4347 // So, if we moved only a small distance, this could still be a tap 4348 var xdiff = event.touches[0].pageX - firstTouch.pageX; 4349 var ydiff = event.touches[0].pageY - firstTouch.pageY; 4350 var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff); 4351 4352 if (touchDistance > tapMovementThreshold) { 4353 couldBeTap = false; 4354 } 4355 } 4356 }); 4357 4358 var noTap = function noTap() { 4359 couldBeTap = false; 4360 }; 4361 4362 // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s 4363 this.on('touchleave', noTap); 4364 this.on('touchcancel', noTap); 4365 4366 // When the touch ends, measure how long it took and trigger the appropriate 4367 // event 4368 this.on('touchend', function (event) { 4369 firstTouch = null; 4370 // Proceed only if the touchmove/leave/cancel event didn't happen 4371 if (couldBeTap === true) { 4372 // Measure how long the touch lasted 4373 var touchTime = new Date().getTime() - touchStart; 4374 4375 // Make sure the touch was less than the threshold to be considered a tap 4376 if (touchTime < touchTimeThreshold) { 4377 // Don't let browser turn this into a click 4378 event.preventDefault(); 4379 this.trigger('tap'); 4380 // It may be good to copy the touchend event object and change the 4381 // type to tap, if the other event properties aren't exact after 4382 // Events.fixEvent runs (e.g. event.target) 4383 } 4384 } 4385 }); 4386 }; 4387 4388 /** 4389 * Report user touch activity when touch events occur 4390 * User activity is used to determine when controls should show/hide. It's 4391 * relatively simple when it comes to mouse events, because any mouse event 4392 * should show the controls. So we capture mouse events that bubble up to the 4393 * player and report activity when that happens. 4394 * With touch events it isn't as easy. We can't rely on touch events at the 4395 * player level, because a tap (touchstart + touchend) on the video itself on 4396 * mobile devices is meant to turn controls off (and on). User activity is 4397 * checked asynchronously, so what could happen is a tap event on the video 4398 * turns the controls off, then the touchend event bubbles up to the player, 4399 * which if it reported user activity, would turn the controls right back on. 4400 * (We also don't want to completely block touch events from bubbling up) 4401 * Also a touchmove, touch+hold, and anything other than a tap is not supposed 4402 * to turn the controls back on on a mobile device. 4403 * Here we're setting the default component behavior to report user activity 4404 * whenever touch events happen, and this can be turned off by components that 4405 * want touch events to act differently. 4406 * 4407 * @method enableTouchActivity 4408 */ 4409 4410 Component.prototype.enableTouchActivity = function enableTouchActivity() { 4411 // Don't continue if the root player doesn't support reporting user activity 4412 if (!this.player() || !this.player().reportUserActivity) { 4413 return; 4414 } 4415 4416 // listener for reporting that the user is active 4417 var report = Fn.bind(this.player(), this.player().reportUserActivity); 4418 4419 var touchHolding = undefined; 4420 4421 this.on('touchstart', function () { 4422 report(); 4423 // For as long as the they are touching the device or have their mouse down, 4424 // we consider them active even if they're not moving their finger or mouse. 4425 // So we want to continue to update that they are active 4426 this.clearInterval(touchHolding); 4427 // report at the same interval as activityCheck 4428 touchHolding = this.setInterval(report, 250); 4429 }); 4430 4431 var touchEnd = function touchEnd(event) { 4432 report(); 4433 // stop the interval that maintains activity if the touch is holding 4434 this.clearInterval(touchHolding); 4435 }; 4436 4437 this.on('touchmove', report); 4438 this.on('touchend', touchEnd); 4439 this.on('touchcancel', touchEnd); 4440 }; 4441 4442 /** 4443 * Creates timeout and sets up disposal automatically. 4444 * 4445 * @param {Function} fn The function to run after the timeout. 4446 * @param {Number} timeout Number of ms to delay before executing specified function. 4447 * @return {Number} Returns the timeout ID 4448 * @method setTimeout 4449 */ 4450 4451 Component.prototype.setTimeout = function setTimeout(fn, timeout) { 4452 fn = Fn.bind(this, fn); 4453 4454 // window.setTimeout would be preferable here, but due to some bizarre issue with Sinon and/
4454or Phantomjs, we can't. 4455 var timeoutId = _globalWindow2['default'].setTimeout(fn, timeout); 4456 4457 var disposeFn = function disposeFn() { 4458 this.clearTimeout(timeoutId); 4459 }; 4460 4461 disposeFn.guid = 'vjs-timeout-' + timeoutId; 4462 4463 this.on('dispose', disposeFn); 4464 4465 return timeoutId; 4466 }; 4467 4468 /** 4469 * Clears a timeout and removes the associated dispose listener 4470 * 4471 * @param {Number} timeoutId The id of the timeout to clear 4472 * @return {Number} Returns the timeout ID 4473 * @method clearTimeout 4474 */ 4475 4476 Component.prototype.clearTimeout = function clearTimeout(timeoutId) { 4477 _globalWindow2['default'].clearTimeout(timeoutId); 4478 4479 var disposeFn = function disposeFn() {}; 4480 4481 disposeFn.guid = 'vjs-timeout-' + timeoutId; 4482 4483 this.off('dispose', disposeFn); 4484 4485 return timeoutId; 4486 }; 4487 4488 /** 4489 * Creates an interval and sets up disposal automatically. 4490 * 4491 * @param {Function} fn The function to run every N seconds. 4492 * @param {Number} interval Number of ms to delay before executing specified function. 4493 * @return {Number} Returns the interval ID 4494 * @method setInterval 4495 */ 4496 4497 Component.prototype.setInterval = function setInterval(fn, interval) { 4498 fn = Fn.bind(this, fn); 4499 4500 var intervalId = _globalWindow2['default'].setInterval(fn, interval); 4501 4502 var disposeFn = function disposeFn() { 4503 this.clearInterval(intervalId); 4504 }; 4505 4506 disposeFn.guid = 'vjs-interval-' + intervalId; 4507 4508 this.on('dispose', disposeFn); 4509 4510 return intervalId; 4511 }; 4512 4513 /** 4514 * Clears an interval and removes the associated dispose listener 4515 * 4516 * @param {Number} intervalId The id of the interval to clear 4517 * @return {Number} Returns the interval ID 4518 * @method clearInterval 4519 */ 4520 4521 Component.prototype.clearInterval = function clearInterval(intervalId) { 4522 _globalWindow2['default'].clearInterval(intervalId); 4523 4524 var disposeFn = function disposeFn() {}; 4525 4526 disposeFn.guid = 'vjs-interval-' + intervalId; 4527 4528 this.off('dispose', disposeFn); 4529 4530 return intervalId; 4531 }; 4532 4533 /** 4534 * Registers a component 4535 * 4536 * @param {String} name Name of the component to register 4537 * @param {Object} comp The component to register 4538 * @static 4539 * @method registerComponent 4540 */ 4541 4542 Component.registerComponent = function registerComponent(name, comp) { 4543 if (!Component.components_) { 4544 Component.components_ = {}; 4545 } 4546 4547 Component.components_[name] = comp; 4548 return comp; 4549 }; 4550 4551 /** 4552 * Gets a component by name 4553 * 4554 * @param {String} name Name of the component to get 4555 * @return {Component} 4556 * @static 4557 * @method getComponent 4558 */ 4559 4560 Component.getComponent = function getComponent(name) { 4561 if (Component.components_ && Component.components_[name]) { 4562 return Component.components_[name]; 4563 } 4564 4565 if (_globalWindow2['default'] && _globalWindow2['default'].videojs && _globalWindow2['default'].videojs[name]) { 4566 _utilsLogJs2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)'); 4567 return _globalWindow2['default'].videojs[name]; 4568 } 4569 }; 4570 4571 /** 4572 * Sets up the constructor using the supplied init method 4573 * or uses the init of the parent object 4574 * 4575 * @param {Object} props An object of properties 4576 * @static 4577 * @deprecated 4578 * @method extend 4579 */ 4580 4581 Component.extend = function extend(props) { 4582 props = props || {}; 4583 4584 _utilsLogJs2['default'].warn('Component.extend({}) has been deprecated, use videojs.extend(Component, {}) instead'); 4585 4586 // Set up the constructor using the supplied init method 4587 // or using the init of the parent object 4588 // Make sure to check the unobfuscated version for external libs 4589 var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {}; 4590 // In Resig's simple class inheritance (previously used) the constructor 4591 // is a function that calls `this.init.apply(arguments)` 4592 // However that would prevent us from using `ParentObject.call(this);` 4593 // in a Child constructor because the `this` in `this.init` 4594 // would still refer to the Child and cause an infinite loop. 4595 // We would instead have to do
4596 // `ParentObject.prototype.init.apply(this, arguments);` 4597 // Bleh. We're not creating a _super() function, so it's good to keep 4598 // the parent constructor reference simple. 4599 var subObj = function subObj() { 4600 init.apply(this, arguments); 4601 }; 4602 4603 // Inherit from this object's prototype 4604 subObj.prototype = Object.create(this.prototype); 4605 // Reset the constructor property for subObj otherwise 4606 // instances of subObj would have the constructor of the parent Object 4607 subObj.prototype.constructor = subObj; 4608 4609 // Make the class extendable 4610 subObj.extend = Component.extend; 4611 4612 // Extend subObj's prototype with functions and other properties from props 4613 for (var _name in props) { 4614 if (props.hasOwnProperty(_name)) { 4615 subObj.prototype[_name] = props[_name]; 4616 } 4617 } 4618 4619 return subObj; 4620 }; 4621 4622 return Component; 4623})(); 4624 4625Component.registerComponent('Component', Component); 4626exports['default'] = Component; 4627module.exports = exports['default']; 4628 4629},{"./utils/dom.js":131,"./utils/events.js":132,"./utils/fn.js":133,"./utils/guid.js":135,"./utils/log.js":136,"./utils/merge-options.js":137,"./utils/to-title-case.js":140,"global/window":2,"object.assign":45}],67:[function(_dereq_,module,exports){ 4630/** 4631 * @file control-bar.js 4632 */ 4633'use strict'; 4634 4635exports.__esModule = true; 4636 4637function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4638 4639function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 4640 4641function _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; } 4642 4643var _componentJs = _dereq_('../component.js'); 4644 4645var _componentJs2 = _interopRequireDefault(_componentJs); 4646 4647// Required children 4648 4649var _playToggleJs = _dereq_('./play-toggle.js'); 4650 4651var _playToggleJs2 = _interopRequireDefault(_playToggleJs); 4652 4653var _timeControlsCurrentTimeDisplayJs = _dereq_('./time-controls/current-time-display.js'); 4654 4655var _timeControlsCurrentTimeDisplayJs2 = _interopRequireDefault(_timeControlsCurrentTimeDisplayJs); 4656 4657var _timeControlsDurationDisplayJs = _dereq_('./time-controls/duration-display.js'); 4658 4659var _timeControlsDurationDisplayJs2 = _interopRequireDefault(_timeControlsDurationDisplayJs); 4660 4661var _timeControlsTimeDividerJs = _dereq_('./time-controls/time-divider.js'); 4662 4663var _timeControlsTimeDividerJs2 = _interopRequireDefault(_timeControlsTimeDividerJs); 4664 4665var _timeControlsRemainingTimeDisplayJs = _dereq_('./time-controls/remaining-time-display.js'); 4666 4667var _timeControlsRemainingTimeDisplayJs2 = _interopRequireDefault(_timeControlsRemainingTimeDisplayJs); 4668 4669var _liveDisplayJs = _dereq_('./live-display.js'); 4670 4671var _liveDisplayJs2 = _interopRequireDefault(_liveDisplayJs); 4672 4673var _progressControlProgressControlJs = _dereq_('./progress-control/progress-control.js'); 4674 4675var _progressControlProgressControlJs2 = _interopRequireDefault(_progressControlProgressControlJs); 4676 4677var _fullscreenToggleJs = _dereq_('./fullscreen-toggle.js'); 4678 4679var _fullscreenToggleJs2 = _interopRequireDefault(_fullscreenToggleJs); 4680 4681var _volumeControlVolumeControlJs = _dereq_('./volume-control/volume-control.js'); 4682 4683var _volumeControlVolumeControlJs2 = _interopRequireDefault(_volumeControlVolumeControlJs); 4684 4685var _volumeMenuButtonJs = _dereq_('./volume-menu-button.js'); 4686 4687var _volumeMenuButtonJs2 = _interopRequireDefault(_volumeMenuButtonJs); 4688 4689var _muteToggleJs = _dereq_('./mute-toggle.js'); 4690 4691var _muteToggleJs2 = _interopRequireDefault(_muteToggleJs); 4692 4693var _textTrackControlsChaptersButtonJs = _dereq_('./text-track-controls/chapters-button.js'); 4694 4695var _textTrackControlsChaptersButtonJs2 = _interopRequireDefault(_textTrackControlsChapter
4695sButtonJs); 4696 4697var _textTrackControlsSubtitlesButtonJs = _dereq_('./text-track-controls/subtitles-button.js'); 4698 4699var _textTrackControlsSubtitlesButtonJs2 = _interopRequireDefault(_textTrackControlsSubtitlesButtonJs); 4700 4701var _textTrackControlsCaptionsButtonJs = _dereq_('./text-track-controls/captions-button.js'); 4702 4703var _textTrackControlsCaptionsButtonJs2 = _interopRequireDefault(_textTrackControlsCaptionsButtonJs); 4704 4705var _playbackRateMenuPlaybackRateMenuButtonJs = _dereq_('./playback-rate-menu/playback-rate-menu-button.js'); 4706 4707var _playbackRateMenuPlaybackRateMenuButtonJs2 = _interopRequireDefault(_playbackRateMenuPlaybackRateMenuButtonJs); 4708 4709var _spacerControlsCustomControlSpacerJs = _dereq_('./spacer-controls/custom-control-spacer.js'); 4710 4711var _spacerControlsCustomControlSpacerJs2 = _interopRequireDefault(_spacerControlsCustomControlSpacerJs); 4712 4713/** 4714 * Container of main controls 4715 * 4716 * @extends Component 4717 * @class ControlBar 4718 */ 4719 4720var ControlBar = (function (_Component) { 4721 _inherits(ControlBar, _Component); 4722 4723 function ControlBar() { 4724 _classCallCheck(this, ControlBar); 4725 4726 _Component.apply(this, arguments); 4727 } 4728 4729 /** 4730 * Create the component's DOM element 4731 * 4732 * @return {Element} 4733 * @method createEl 4734 */ 4735 4736 ControlBar.prototype.createEl = function createEl() { 4737 return _Component.prototype.createEl.call(this, 'div', { 4738 className: 'vjs-control-bar' 4739 }, { 4740 'role': 'group' // The control bar is a group, so it can contain menuitems 4741 }); 4742 }; 4743 4744 return ControlBar; 4745})(_componentJs2['default']); 4746 4747ControlBar.prototype.options_ = { 4748 loadEvent: 'play', 4749 children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'subtitlesButton', 'captionsButton', 'fullscreenToggle'] 4750}; 4751 4752_componentJs2['default'].registerComponent('ControlBar', ControlBar); 4753exports['default'] = ControlBar; 4754module.exports = exports['default']; 4755 4756},{"../component.js":66,"./fullscreen-toggle.js":68,"./live-display.js":69,"./mute-toggle.js":70,"./play-toggle.js":71,"./playback-rate-menu/playback-rate-menu-button.js":72,"./progress-control/progress-control.js":77,"./spacer-controls/custom-control-spacer.js":79,"./text-track-controls/captions-button.js":82,"./text-track-controls/chapters-button.js":83,"./text-track-controls/subtitles-button.js":86,"./time-controls/current-time-display.js":89,"./time-controls/duration-display.js":90,"./time-controls/remaining-time-display.js":91,"./time-controls/time-divider.js":92,"./volume-control/volume-control.js":94,"./volume-menu-button.js":96}],68:[function(_dereq_,module,exports){ 4757/** 4758 * @file fullscreen-toggle.js 4759 */ 4760'use strict'; 4761 4762exports.__esModule = true; 4763 4764function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4765 4766function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 4767 4768function _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; } 4769 4770var _buttonJs = _dereq_('../button.js'); 4771 4772var _buttonJs2 = _interopRequireDefault(_buttonJs); 4773 4774var _componentJs = _dereq_('../component.js'); 4775 4776var _componentJs2 = _interopRequireDefault(_componentJs); 4777 4778/** 4779 * Toggle fullscreen video 4780 * 4781 * @extends Button 4782 * @class FullscreenToggle 4783 */ 4784 4785var FullscreenToggle = (function (_Button) { 4786 _inherits(FullscreenToggle, _Button); 4787 4788 function FullscreenToggle() { 4789 _classCallCheck(this, FullscreenToggle); 4790 4791 _Button.apply(this, arguments); 4792 } 4793 4794 /** 4795 * Allow sub components to stack CSS class names 4796 * 4797 * @return {String} The constructed class name 4798 * @method buildCSSClass 4799 */ 4800 4801 FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() { 4802 return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this); 4803 }; 4804 4805 /** 4806 * Handles click for full screen 4807 * 4808 * @method handleClick 4809 */ 4810 4811 FullscreenToggle.prototype.handleClick = function handleClick() { 4812 if (!this.player_.isFullscreen()) { 4813 this.player_.requestFullscreen(); 4814 this.controlText('Non-Fullscreen'); 4815 } else { 4816 this.player_.exitFullscreen(); 4817 this.controlText('Fullscreen'); 4818 } 4819 }; 4820 4821 return FullscreenToggle; 4822})(_buttonJs2['default']); 4823 4824FullscreenToggle.prototype.controlText_ = 'Fullscreen'; 4825 4826_componentJs2['default'].registerComponent('FullscreenToggle', FullscreenToggle); 4827exports['default'] = FullscreenToggle; 4828module.exports = exports['default']; 4829 4830},{"../button.js":63,"../component.js":66}],69:[function(_dereq_,module,exports){ 4831/** 4832 * @file live-display.js 4833 */ 4834'use strict'; 4835 4836exports.__esModule = true; 4837 4838function _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; } } 4839 4840function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4841 4842function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 4843 4844function _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
4844onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 4845 4846var _component = _dereq_('../component'); 4847 4848var _component2 = _interopRequireDefault(_component); 4849 4850var _utilsDomJs = _dereq_('../utils/dom.js'); 4851 4852var Dom = _interopRequireWildcard(_utilsDomJs); 4853 4854/** 4855 * Displays the live indicator 4856 * TODO - Future make it click to snap to live 4857 * 4858 * @extends Component 4859 * @class LiveDisplay 4860 */ 4861 4862var LiveDisplay = (function (_Component) { 4863 _inherits(LiveDisplay, _Component); 4864 4865 function LiveDisplay(player, options) { 4866 _classCallCheck(this, LiveDisplay); 4867 4868 _Component.call(this, player, options); 4869 4870 this.updateShowing(); 4871 this.on(this.player(), 'durationchange', this.updateShowing); 4872 } 4873 4874 /** 4875 * Create the component's DOM element 4876 * 4877 * @return {Element} 4878 * @method createEl 4879 */ 4880 4881 LiveDisplay.prototype.createEl = function createEl() { 4882 var el = _Component.prototype.createEl.call(this, 'div', { 4883 className: 'vjs-live-control vjs-control' 4884 }); 4885 4886 this.contentEl_ = Dom.createEl('div', { 4887 className: 'vjs-live-display', 4888 innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE') 4889 }, { 4890 'aria-live': 'off' 4891 }); 4892 4893 el.appendChild(this.contentEl_); 4894 return el; 4895 }; 4896 4897 LiveDisplay.prototype.updateShowing = function updateShowing() { 4898 if (this.player().duration() === Infinity) { 4899 this.show(); 4900 } else { 4901 this.hide(); 4902 } 4903 }; 4904 4905 return LiveDisplay; 4906})(_component2['default']); 4907 4908_component2['default'].registerComponent('LiveDisplay', LiveDisplay); 4909exports['default'] = LiveDisplay; 4910module.exports = exports['default']; 4911 4912},{"../component":66,"../utils/dom.js":131}],70:[function(_dereq_,module,exports){ 4913/** 4914 * @file mute-toggle.js 4915 */ 4916'use strict'; 4917 4918exports.__esModule = true; 4919 4920function _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; } } 4921 4922function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 4923 4924function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 4925 4926function _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; } 4927 4928var _button = _dereq_('../button'); 4929 4930var _button2 = _interopRequireDefault(_button); 4931 4932var _component = _dereq_('../component'); 4933 4934var _component2 = _interopRequireDefault(_component); 4935 4936var _utilsDomJs = _dereq_('../utils/dom.js'); 4937 4938var Dom = _interopRequireWildcard(_utilsDomJs); 4939 4940/** 4941 * A button component for muting the audio 4942 * 4943 * @param {Player|Object} player 4944 * @param {Object=} options 4945 * @extends Button 4946 * @class MuteToggle 4947 */ 4948 4949var MuteToggle = (function (_Button) { 4950 _inherits(MuteToggle, _Button); 4951 4952 function MuteToggle(player, options) { 4953 _classCallCheck(this, MuteToggle); 4954 4955 _Button.call(this, player, options); 4956 4957 this.on(player, 'volumechange', this.update); 4958 4959 // hide mute toggle if the current tech doesn't support volume control 4960 if (player.tech_ && player.tech_['featuresVolumeControl'] === false) { 4961 this.addClass('vjs-hidden'); 4962 } 4963 4964 this.on(player, 'loadstart', function () { 4965 this.update(); // We need to update the button to account for a default muted state. 4966 4967 if (player.tech_['featuresVolumeControl'] === false) { 4968 this.addClass('vjs-hidden'); 4969 } else { 4970 this.removeClass('vjs-hidden'); 4971 } 4972 }); 4973 } 4974 4975 /** 4976 * Allow sub components to stack CSS class names 4977 * 4978 * @return {String} The constructed class name 4979 * @method buildCSSClass 4980 */ 4981 4982 MuteToggle.prototype.buildCSSClass = function buildCSSClass() { 4983 return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this); 4984 }; 4985 4986 /** 4987 * Handle click on mute 4988 * 4989 * @method handleClick 4990 */ 4991 4992 MuteToggle.prototype.handleClick = function handleClick() { 4993 this.player_.muted(this.player_.muted() ? false : true); 4994 }; 4995 4996 /** 4997 * Update volume 4998 * 4999 * @method update 5000 */ 5001
5002 MuteToggle.prototype.update = function update() { 5003 var vol = this.player_.volume(), 5004 level = 3; 5005 5006 if (vol === 0 || this.player_.muted()) { 5007 level = 0; 5008 } else if (vol < 0.33) { 5009 level = 1; 5010 } else if (vol < 0.67) { 5011 level = 2; 5012 } 5013 5014 // Don't rewrite the button text if the actual text doesn't change. 5015 // This causes unnecessary and confusing information for screen reader users. 5016 // This check is needed because this function gets called every time the volume level is changed. 5017 var toMute = this.player_.muted() ? 'Unmute' : 'Mute'; 5018 if (this.controlText() !== toMute) { 5019 this.controlText(toMute); 5020 } 5021 5022 /* TODO improve muted icon classes */ 5023 for (var i = 0; i < 4; i++) { 5024 Dom.removeElClass(this.el_, 'vjs-vol-' + i); 5025 } 5026 Dom.addElClass(this.el_, 'vjs-vol-' + level); 5027 }; 5028 5029 return MuteToggle; 5030})(_button2['default']); 5031 5032MuteToggle.prototype.controlText_ = 'Mute'; 5033 5034_component2['default'].registerComponent('MuteToggle', MuteToggle); 5035exports['default'] = MuteToggle; 5036module.exports = exports['default']; 5037 5038},{"../button":63,"../component":66,"../utils/dom.js":131}],71:[function(_dereq_,module,exports){ 5039/** 5040 * @file play-toggle.js 5041 */ 5042'use strict'; 5043 5044exports.__esModule = true; 5045 5046function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5047 5048function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5049 5050function _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; } 5051 5052var _buttonJs = _dereq_('../button.js'); 5053 5054var _buttonJs2 = _interopRequireDefault(_buttonJs); 5055 5056var _componentJs = _dereq_('../component.js'); 5057 5058var _componentJs2 = _interopRequireDefault(_componentJs); 5059 5060/** 5061 * Button to toggle between play and pause 5062 * 5063 * @param {Player|Object} player 5064 * @param {Object=} options 5065 * @extends Button 5066 * @class PlayToggle 5067 */ 5068 5069var PlayToggle = (function (_Button) { 5070 _inherits(PlayToggle, _Button); 5071 5072 function PlayToggle(player, options) { 5073 _classCallCheck(this, PlayToggle); 5074 5075 _Button.call(this, player, options); 5076 5077 this.on(player, 'play', this.handlePlay); 5078 this.on(player, 'pause', this.handlePause); 5079 } 5080 5081 /** 5082 * Allow sub components to stack CSS class names 5083 * 5084 * @return {String} The constructed class name 5085 * @method buildCSSClass 5086 */ 5087 5088 PlayToggle.prototype.buildCSSClass = function buildCSSClass() { 5089 return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this); 5090 }; 5091 5092 /** 5093 * Handle click to toggle between play and pause 5094 * 5095 * @method handleClick 5096 */ 5097 5098 PlayToggle.prototype.handleClick = function handleClick() { 5099 if (this.player_.paused()) { 5100 this.player_.play(); 5101 } else { 5102 this.player_.pause(); 5103 } 5104 }; 5105 5106 /** 5107 * Add the vjs-playing class to the element so it can change appearance 5108 * 5109 * @method handlePlay 5110 */ 5111 5112 PlayToggle.prototype.handlePlay = function handlePlay() { 5113 this.removeClass('vjs-paused'); 5114 this.addClass('vjs-playing'); 5115 this.controlText('Pause'); // change the button text to "Pause" 5116 }; 5117 5118 /** 5119 * Add the vjs-paused class to the element so it can change appearance 5120 * 5121 * @method handlePause 5122 */ 5123 5124 PlayToggle.prototype.handlePause = function handlePause() { 5125 this.removeClass('vjs-playing'); 5126 this.addClass('vjs-paused'); 5127 this.controlText('Play'); // change the button text to "Play" 5128 }; 5129 5130 return PlayToggle; 5131})(_buttonJs2['default']); 5132 5133PlayToggle.prototype.controlText_ = 'Play'; 5134 5135_componentJs2['default'].registerComponent('PlayToggle', PlayToggle); 5136exports['default'] = PlayToggle; 5137module.exports = exports['default']; 5138 5139},{"../button.js":63,"../component.js":66}],72:[function(_dereq_,module,exports){ 5140/** 5141 * @file playback-rate-menu-button.js 5142 */ 5143'use strict'; 5144 5145exports.__esModule = true; 5146 5147function _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; } } 5148 5149function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5150 5151function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5152 5153function _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
5153onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 5154 5155var _menuMenuButtonJs = _dereq_('../../menu/menu-button.js'); 5156 5157var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs); 5158 5159var _menuMenuJs = _dereq_('../../menu/menu.js'); 5160 5161var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs); 5162 5163var _playbackRateMenuItemJs = _dereq_('./playback-rate-menu-item.js'); 5164 5165var _playbackRateMenuItemJs2 = _interopRequireDefault(_playbackRateMenuItemJs); 5166 5167var _componentJs = _dereq_('../../component.js'); 5168 5169var _componentJs2 = _interopRequireDefault(_componentJs); 5170 5171var _utilsDomJs = _dereq_('../../utils/dom.js'); 5172 5173var Dom = _interopRequireWildcard(_utilsDomJs); 5174 5175/** 5176 * The component for controlling the playback rate 5177 * 5178 * @param {Player|Object} player 5179 * @param {Object=} options 5180 * @extends MenuButton 5181 * @class PlaybackRateMenuButton 5182 */ 5183 5184var PlaybackRateMenuButton = (function (_MenuButton) { 5185 _inherits(PlaybackRateMenuButton, _MenuButton); 5186 5187 function PlaybackRateMenuButton(player, options) { 5188 _classCallCheck(this, PlaybackRateMenuButton); 5189 5190 _MenuButton.call(this, player, options); 5191 5192 this.updateVisibility(); 5193 this.updateLabel(); 5194 5195 this.on(player, 'loadstart', this.updateVisibility); 5196 this.on(player, 'ratechange', this.updateLabel); 5197 } 5198 5199 /** 5200 * Create the component's DOM element 5201 * 5202 * @return {Element} 5203 * @method createEl 5204 */ 5205 5206 PlaybackRateMenuButton.prototype.createEl = function createEl() { 5207 var el = _MenuButton.prototype.createEl.call(this); 5208 5209 this.labelEl_ = Dom.createEl('div', { 5210 className: 'vjs-playback-rate-value', 5211 innerHTML: 1.0 5212 }); 5213 5214 el.appendChild(this.labelEl_); 5215 5216 return el; 5217 }; 5218 5219 /** 5220 * Allow sub components to stack CSS class names 5221 * 5222 * @return {String} The constructed class name 5223 * @method buildCSSClass 5224 */ 5225 5226 PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() { 5227 return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this); 5228 }; 5229 5230 /** 5231 * Create the playback rate menu 5232 * 5233 * @return {Menu} Menu object populated with items 5234 * @method createMenu 5235 */ 5236 5237 PlaybackRateMenuButton.prototype.createMenu = function createMenu() { 5238 var menu = new _menuMenuJs2['default'](this.player()); 5239 var rates = this.playbackRates(); 5240 5241 if (rates) { 5242 for (var i = rates.length - 1; i >= 0; i--) { 5243 menu.addChild(new _playbackRateMenuItemJs2['default'](this.player(), { 'rate': rates[i] + 'x' })); 5244 } 5245 } 5246 5247 return menu; 5248 }; 5249 5250 /** 5251 * Updates ARIA accessibility attributes 5252 * 5253 * @method updateARIAAttributes 5254 */ 5255 5256 PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() { 5257 // Current playback rate 5258 this.el().setAttribute('aria-valuenow', this.player().playbackRate()); 5259 }; 5260 5261 /** 5262 * Handle menu item click 5263 * 5264 * @method handleClick 5265 */ 5266 5267 PlaybackRateMenuButton.prototype.handleClick = function handleClick() { 5268 // select next rate option 5269 var currentRate = this.player().playbackRate(); 5270 var rates = this.playbackRates(); 5271 5272 // this will select first one if the last one currently selected 5273 var newRate = rates[0]; 5274 for (var i = 0; i < rates.length; i++) { 5275 if (rates[i] > currentRate) { 5276 newRate = rates[i]; 5277 break; 5278 } 5279 } 5280 this.player().playbackRate(newRate); 5281 }; 5282 5283 /** 5284 * Get possible playback rates 5285 * 5286 * @return {Array} Possible playback rates 5287 * @method playbackRates 5288 */ 5289 5290 PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() { 5291 return this.options_['playbackRates'] || this.options_.playerOptions && this.options_.playerOptions['playbackRates']; 5292 }; 5293 5294 /** 5295 * Get supported playback rates 5296 * 5297 * @return {Array} Supported playback rates 5298 * @method playbackRateSupported 5299 */ 5300 5301 PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() { 5302 return this.player().tech_ && this.player().tech_['featuresPlaybackRate'] && this.playbackRates() && this.playbackRates().length > 0; 5303 }; 5304 5305 /** 5306 * Hide playback rate controls when they're no playback rate options to select 5307 * 5308 * @method updateVisibility 5309 */ 5310 5311 PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility() { 5312 if (this.playbackRateSupported()) { 5313 this.removeClass('vjs-hidden'); 5314 } else { 5315 this.addClass('vjs-hidden'); 5316 } 5317 }; 5318 5319 /** 5320 * Update button label when rate changed 5321 * 5322 * @method updateLabel 5323 */ 5324 5325 PlaybackRateMenuButton.prototype.updateLabel = function updateLabel() { 5326 if (this.playbackRateSupported()) { 5327 this.labelEl_.innerHTML = this.player().playbackRate() + 'x'; 5328 } 5329 }; 5330 5331 return PlaybackRateMenuButton; 5332}
5332)(_menuMenuButtonJs2['default']); 5333 5334PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate'; 5335 5336_componentJs2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton); 5337exports['default'] = PlaybackRateMenuButton; 5338module.exports = exports['default']; 5339 5340},{"../../component.js":66,"../../menu/menu-button.js":103,"../../menu/menu.js":105,"../../utils/dom.js":131,"./playback-rate-menu-item.js":73}],73:[function(_dereq_,module,exports){ 5341/** 5342 * @file playback-rate-menu-item.js 5343 */ 5344'use strict'; 5345 5346exports.__esModule = true; 5347 5348function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5349 5350function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5351 5352function _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; } 5353 5354var _menuMenuItemJs = _dereq_('../../menu/menu-item.js'); 5355 5356var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs); 5357 5358var _componentJs = _dereq_('../../component.js'); 5359 5360var _componentJs2 = _interopRequireDefault(_componentJs); 5361 5362/** 5363 * The specific menu item type for selecting a playback rate 5364 * 5365 * @param {Player|Object} player 5366 * @param {Object=} options 5367 * @extends MenuItem 5368 * @class PlaybackRateMenuItem 5369 */ 5370 5371var PlaybackRateMenuItem = (function (_MenuItem) { 5372 _inherits(PlaybackRateMenuItem, _MenuItem); 5373 5374 function PlaybackRateMenuItem(player, options) { 5375 _classCallCheck(this, PlaybackRateMenuItem); 5376 5377 var label = options['rate']; 5378 var rate = parseFloat(label, 10); 5379 5380 // Modify options for parent MenuItem class's init. 5381 options['label'] = label; 5382 options['selected'] = rate === 1; 5383 _MenuItem.call(this, player, options); 5384 5385 this.label = label; 5386 this.rate = rate; 5387 5388 this.on(player, 'ratechange', this.update); 5389 } 5390 5391 /** 5392 * Handle click on menu item 5393 * 5394 * @method handleClick 5395 */ 5396 5397 PlaybackRateMenuItem.prototype.handleClick = function handleClick() { 5398 _MenuItem.prototype.handleClick.call(this); 5399 this.player().playbackRate(this.rate); 5400 }; 5401 5402 /** 5403 * Update playback rate with selected rate 5404 * 5405 * @method update 5406 */ 5407 5408 PlaybackRateMenuItem.prototype.update = function update() { 5409 this.selected(this.player().playbackRate() === this.rate); 5410 }; 5411 5412 return PlaybackRateMenuItem; 5413})(_menuMenuItemJs2['default']); 5414 5415PlaybackRateMenuItem.prototype.contentElType = 'button'; 5416 5417_componentJs2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem); 5418exports['default'] = PlaybackRateMenuItem; 5419module.exports = exports['default']; 5420 5421},{"../../component.js":66,"../../menu/menu-item.js":104}],74:[function(_dereq_,module,exports){ 5422/** 5423 * @file load-progress-bar.js 5424 */ 5425'use strict'; 5426 5427exports.__esModule = true; 5428 5429function _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; } } 5430 5431function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5432 5433function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5434 5435function _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; } 5436 5437var _componentJs = _dereq_('../../component.js'); 5438 5439var _componentJs2 = _interopRequireDefault(_componentJs); 5440 5441var _utilsDomJs = _dereq_('../../utils/dom.js'); 5442 5443var Dom = _interopRequireWildcard(_utilsDomJs); 5444 5445/** 5446 * Shows load progress 5447 * 5448 * @param {Player|Object} player 5449 * @param {Object=} options 5450 * @extends Component 5451 * @class LoadProgressBar 5452 */ 5453 5454var LoadProgressBar = (function (_Component) { 5455 _inherits(LoadProgressBar, _Component); 5456 5457 function LoadProgressBar(player, options) { 5458 _classCallCheck(this, LoadProgressBar); 5459 5460 _Component.call(this, player, options); 5461 this.on(player, 'progress', this.update); 5462 } 5463 5464 /** 5465 * Create the component's DOM element 5466 * 5467 * @return {Element} 5468 * @method createEl 5469 */ 5470 5471 LoadProgressBar.prototype.createEl = function createEl() { 5472 return _Component.prototype.createEl.call(this, 'div', { 5473 className: 'vjs-load-progress', 5474 innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>' 5475 }); 5476 }; 5477 5478 /** 5479 * Update progress bar 5480 * 5481 * @method update 5482 */ 5483
5484 LoadProgressBar.prototype.update = function update() { 5485 var buffered = this.player_.buffered(); 5486 var duration = this.player_.duration(); 5487 var bufferedEnd = this.player_.bufferedEnd(); 5488 var children = this.el_.children; 5489 5490 // get the percent width of a time compared to the total end 5491 var percentify = function percentify(time, end) { 5492 var percent = time / end || 0; // no NaN 5493 return (percent >= 1 ? 1 : percent) * 100 + '%'; 5494 }; 5495 5496 // update the width of the progress bar 5497 this.el_.style.width = percentify(bufferedEnd, duration); 5498 5499 // add child elements to represent the individual buffered time ranges 5500 for (var i = 0; i < buffered.length; i++) { 5501 var start = buffered.start(i); 5502 var end = buffered.end(i); 5503 var part = children[i]; 5504 5505 if (!part) { 5506 part = this.el_.appendChild(Dom.createEl()); 5507 } 5508 5509 // set the percent based on the width of the progress bar (bufferedEnd) 5510 part.style.left = percentify(start, bufferedEnd); 5511 part.style.width = percentify(end - start, bufferedEnd); 5512 } 5513 5514 // remove unused buffered range elements 5515 for (var i = children.length; i > buffered.length; i--) { 5516 this.el_.removeChild(children[i - 1]); 5517 } 5518 }; 5519 5520 return LoadProgressBar; 5521})(_componentJs2['default']); 5522 5523_componentJs2['default'].registerComponent('LoadProgressBar', LoadProgressBar); 5524exports['default'] = LoadProgressBar; 5525module.exports = exports['default']; 5526 5527},{"../../component.js":66,"../../utils/dom.js":131}],75:[function(_dereq_,module,exports){ 5528/** 5529 * @file mouse-time-display.js 5530 */ 5531'use strict'; 5532 5533exports.__esModule = true; 5534 5535function _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; } } 5536 5537function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5538 5539function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5540 5541function _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; } 5542 5543var _componentJs = _dereq_('../../component.js'); 5544 5545var _componentJs2 = _interopRequireDefault(_componentJs); 5546 5547var _utilsDomJs = _dereq_('../../utils/dom.js'); 5548 5549var Dom = _interopRequireWildcard(_utilsDomJs); 5550 5551var _utilsFnJs = _dereq_('../../utils/fn.js'); 5552 5553var Fn = _interopRequireWildcard(_utilsFnJs); 5554 5555var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js'); 5556 5557var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 5558 5559var _lodashCompatFunctionThrottle = _dereq_('lodash-compat/function/throttle'); 5560 5561var _lodashCompatFunctionThrottle2 = _interopRequireDefault(_lodashCompatFunctionThrottle); 5562 5563/** 5564 * The Mouse Time Display component shows the time you will seek to 5565 * when hovering over the progress bar 5566 * 5567 * @param {Player|Object} player 5568 * @param {Object=} options 5569 * @extends Component 5570 * @class MouseTimeDisplay 5571 */ 5572 5573var MouseTimeDisplay = (function (_Component) { 5574 _inherits(MouseTimeDisplay, _Component); 5575 5576 function MouseTimeDisplay(player, options) { 5577 var _this = this; 5578 5579 _classCallCheck(this, MouseTimeDisplay); 5580 5581 _Component.call(this, player, options); 5582 5583 this.update(0, 0); 5584 5585 player.on('ready', function () { 5586 _this.on(player.controlBar.progressControl.el(), 'mousemove', _lodashCompatFunctionThrottle2['default'](Fn.bind(_this, _this.handleMouseMove), 25)); 5587 }); 5588 } 5589 5590 /** 5591 * Create the component's DOM element 5592 * 5593 * @return {Element} 5594 * @method createEl 5595 */ 5596 5597 MouseTimeDisplay.prototype.createEl = function createEl() { 5598 return _Component.prototype.createEl.call(this, 'div', { 5599 className: 'vjs-mouse-display' 5600 }); 5601 }; 5602 5603 MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) { 5604 var duration = this.player_.duration(); 5605 var newTime = this.calculateDistance(event) * duration; 5606 var position = event.pageX - Dom.findElPosition(this.el().parentNode).left; 5607 5608 this.update(newTime, position); 5609 }; 5610 5611 MouseTimeDisplay.prototype.update = function update(newTime, position) { 5612 var time = _utilsFormatTimeJs2['default'](newTime, this.player_.duration()); 5613 5614 this.el().style.left = position + 'px'; 5615 this.el().setAttribute('data-current-time', time); 5616 }; 5617 5618 MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) { 5619 return Dom.getPointerPosition(this.el().parentNode, event).x; 5620 }; 5621 5622 return MouseTimeDisplay; 5623})(_componentJs2['default']); 5624 5625_componentJs2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay); 5626exports['default'] = MouseTimeDisplay; 5627module.exports = exports['default']; 5628 5629},{"../../component.js":66,"../../utils/dom.js":131,"../../utils/fn.js":133,"../../utils/format-time.js":134,"lodash-compat/function/throttle":7}],76:[function(_dereq_,module,exports){ 5630/** 5631 * @file play-progress-bar.js 5632 */ 5633'use strict'; 5634 5635exports.__esModule = true; 5636 5637function _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; } } 5638 5639function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5640 5641function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5642 5643function _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
5643onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 5644 5645var _componentJs = _dereq_('../../component.js'); 5646 5647var _componentJs2 = _interopRequireDefault(_componentJs); 5648 5649var _utilsFnJs = _dereq_('../../utils/fn.js'); 5650 5651var Fn = _interopRequireWildcard(_utilsFnJs); 5652 5653var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js'); 5654 5655var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 5656 5657/** 5658 * Shows play progress 5659 * 5660 * @param {Player|Object} player 5661 * @param {Object=} options 5662 * @extends Component 5663 * @class PlayProgressBar 5664 */ 5665 5666var PlayProgressBar = (function (_Component) { 5667 _inherits(PlayProgressBar, _Component); 5668 5669 function PlayProgressBar(player, options) { 5670 _classCallCheck(this, PlayProgressBar); 5671 5672 _Component.call(this, player, options); 5673 this.updateDataAttr(); 5674 this.on(player, 'timeupdate', this.updateDataAttr); 5675 player.ready(Fn.bind(this, this.updateDataAttr)); 5676 } 5677 5678 /** 5679 * Create the component's DOM element 5680 * 5681 * @return {Element} 5682 * @method createEl 5683 */ 5684 5685 PlayProgressBar.prototype.createEl = function createEl() { 5686 return _Component.prototype.createEl.call(this, 'div', { 5687 className: 'vjs-play-progress vjs-slider-bar', 5688 innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>' 5689 }); 5690 }; 5691 5692 PlayProgressBar.prototype.updateDataAttr = function updateDataAttr() { 5693 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 5694 this.el_.setAttribute('data-current-time', _utilsFormatTimeJs2['default'](time, this.player_.duration())); 5695 }; 5696 5697 return PlayProgressBar; 5698})(_componentJs2['default']); 5699 5700_componentJs2['default'].registerComponent('PlayProgressBar', PlayProgressBar); 5701exports['default'] = PlayProgressBar; 5702module.exports = exports['default']; 5703 5704},{"../../component.js":66,"../../utils/fn.js":133,"../../utils/format-time.js":134}],77:[function(_dereq_,module,exports){ 5705/** 5706 * @file progress-control.js 5707 */ 5708'use strict'; 5709 5710exports.__esModule = true; 5711 5712function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5713 5714function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5715 5716function _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; } 5717 5718var _componentJs = _dereq_('../../component.js'); 5719 5720var _componentJs2 = _interopRequireDefault(_componentJs); 5721 5722var _seekBarJs = _dereq_('./seek-bar.js'); 5723 5724var _seekBarJs2 = _interopRequireDefault(_seekBarJs); 5725 5726var _mouseTimeDisplayJs = _dereq_('./mouse-time-display.js'); 5727 5728var _mouseTimeDisplayJs2 = _interopRequireDefault(_mouseTimeDisplayJs); 5729 5730/** 5731 * The Progress Control component contains the seek bar, load progress, 5732 * and play progress 5733 * 5734 * @param {Player|Object} player 5735 * @param {Object=} options 5736 * @extends Component 5737 * @class ProgressControl 5738 */ 5739 5740var ProgressControl = (function (_Component) { 5741 _inherits(ProgressControl, _Component); 5742 5743 function ProgressControl() { 5744 _classCallCheck(this, ProgressControl); 5745 5746 _Component.apply(this, arguments); 5747 } 5748 5749 /** 5750 * Create the component's DOM element 5751 * 5752 * @return {Element} 5753 * @method createEl 5754 */ 5755 5756 ProgressControl.prototype.createEl = function createEl() { 5757 return _Component.prototype.createEl.call(this, 'div', { 5758 className: 'vjs-progress-control vjs-control' 5759 }); 5760 }; 5761 5762 return ProgressControl; 5763})(_componentJs2['default']); 5764 5765ProgressControl.prototype.options_ = { 5766 children: ['seekBar'] 5767}; 5768 5769_componentJs2['default'].registerComponent('ProgressControl', ProgressControl); 5770exports['default'] = ProgressControl; 5771module.exports = exports['default']; 5772 5773},{"../../component.js":66,"./mouse-time-display.js":75,"./seek-bar.js":78}],78:[function(_dereq_,module,exports){ 5774/** 5775 * @file seek-bar.js 5776 */ 5777'use strict'; 5778 5779exports.__esModule = true; 5780 5781function _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; } } 5782 5783function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5784 5785function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5786 5787function _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
5787onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 5788 5789var _sliderSliderJs = _dereq_('../../slider/slider.js'); 5790 5791var _sliderSliderJs2 = _interopRequireDefault(_sliderSliderJs); 5792 5793var _componentJs = _dereq_('../../component.js'); 5794 5795var _componentJs2 = _interopRequireDefault(_componentJs); 5796 5797var _loadProgressBarJs = _dereq_('./load-progress-bar.js'); 5798 5799var _loadProgressBarJs2 = _interopRequireDefault(_loadProgressBarJs); 5800 5801var _playProgressBarJs = _dereq_('./play-progress-bar.js'); 5802 5803var _playProgressBarJs2 = _interopRequireDefault(_playProgressBarJs); 5804 5805var _utilsFnJs = _dereq_('../../utils/fn.js'); 5806 5807var Fn = _interopRequireWildcard(_utilsFnJs); 5808 5809var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js'); 5810 5811var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 5812 5813var _objectAssign = _dereq_('object.assign'); 5814 5815var _objectAssign2 = _interopRequireDefault(_objectAssign); 5816 5817/** 5818 * Seek Bar and holder for the progress bars 5819 * 5820 * @param {Player|Object} player 5821 * @param {Object=} options 5822 * @extends Slider 5823 * @class SeekBar 5824 */ 5825 5826var SeekBar = (function (_Slider) { 5827 _inherits(SeekBar, _Slider); 5828 5829 function SeekBar(player, options) { 5830 _classCallCheck(this, SeekBar); 5831 5832 _Slider.call(this, player, options); 5833 this.on(player, 'timeupdate', this.updateARIAAttributes); 5834 player.ready(Fn.bind(this, this.updateARIAAttributes)); 5835 } 5836 5837 /** 5838 * Create the component's DOM element 5839 * 5840 * @return {Element} 5841 * @method createEl 5842 */ 5843 5844 SeekBar.prototype.createEl = function createEl() { 5845 return _Slider.prototype.createEl.call(this, 'div', { 5846 className: 'vjs-progress-holder' 5847 }, { 5848 'aria-label': 'video progress bar' 5849 }); 5850 }; 5851 5852 /** 5853 * Update ARIA accessibility attributes 5854 * 5855 * @method updateARIAAttributes 5856 */ 5857 5858 SeekBar.prototype.updateARIAAttributes = function updateARIAAttributes() { 5859 // Allows for smooth scrubbing, when player can't keep up. 5860 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 5861 this.el_.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2)); // machine readable value of progress bar (percentage complete) 5862 this.el_.setAttribute('aria-valuetext', _utilsFormatTimeJs2['default'](time, this.player_.duration())); // human readable value of progress bar (time complete) 5863 }; 5864 5865 /** 5866 * Get percentage of video played 5867 * 5868 * @return {Number} Percentage played 5869 * @method getPercent 5870 */ 5871 5872 SeekBar.prototype.getPercent = function getPercent() { 5873 var percent = this.player_.currentTime() / this.player_.duration(); 5874 return percent >= 1 ? 1 : percent; 5875 }; 5876 5877 /** 5878 * Handle mouse down on seek bar 5879 * 5880 * @method handleMouseDown 5881 */ 5882 5883 SeekBar.prototype.handleMouseDown = function handleMouseDown(event) { 5884 _Slider.prototype.handleMouseDown.call(this, event); 5885 5886 this.player_.scrubbing(true); 5887 5888 this.videoWasPlaying = !this.player_.paused(); 5889 this.player_.pause(); 5890 }; 5891 5892 /** 5893 * Handle mouse move on seek bar 5894 * 5895 * @method handleMouseMove 5896 */ 5897 5898 SeekBar.prototype.handleMouseMove = function handleMouseMove(event) { 5899 var newTime = this.calculateDistance(event) * this.player_.duration(); 5900 5901 // Don't let video end while scrubbing. 5902 if (newTime === this.player_.duration()) { 5903 newTime = newTime - 0.1; 5904 } 5905 5906 // Set new time (tell player to seek to new time) 5907 this.player_.currentTime(newTime); 5908 }; 5909 5910 /** 5911 * Handle mouse up on seek bar 5912 * 5913 * @method handleMouseUp 5914 */ 5915 5916 SeekBar.prototype.handleMouseUp = function handleMouseUp(event) { 5917 _Slider.prototype.handleMouseUp.call(this, event); 5918 5919 this.player_.scrubbing(false); 5920 if (this.videoWasPlaying) { 5921 this.player_.play(); 5922 } 5923 }; 5924 5925 /** 5926 * Move more quickly fast forward for keyboard-only users 5927 * 5928 * @method stepForward 5929 */ 5930 5931 SeekBar.prototype.stepForward = function stepForward() { 5932 this.player_.currentTime(this.player_.currentTime() + 5); // more quickly fast forward for keyboard-only users 5933 }; 5934 5935 /** 5936 * Move more quickly rewind for keyboard-only users 5937 * 5938 * @method stepBack 5939 */ 5940 5941 SeekBar.prototype.stepBack = function stepBack() { 5942 this.player_.currentTime(this.player_.currentTime() - 5); // more quickly rewind for keyboard-only users 5943 }; 5944 5945 return SeekBar; 5946})(_sliderSliderJs2['default']); 5947 5948SeekBar.prototype.options_ = { 5949 children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'], 5950 'barName': 'playProgressBar' 5951}; 5952 5953SeekBar.prototype.playerEvent = 'timeupdate'; 5954 5955_componentJs2['default'].registerComponent('SeekBar', SeekBar); 5956exports['default'] = SeekBar; 5957module.exports = exports['default']; 5958 5959},{"../../component.js":66,"../../slider/slider.js":113,"../../utils/fn.js":133,"../../utils/format-time.js":134,"./load-progress-bar.js":74,"./play-progress-bar.js":76,"object.assign":45}],79:[function(_dereq_,module,exports){ 5960/** 5961 * @file custom-control-spacer.js 5962 */ 5963'use strict'; 5964 5965exports.__esModule = true; 5966 5967function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 5968 5969function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 5970 5971function _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
5971onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 5972 5973var _spacerJs = _dereq_('./spacer.js'); 5974 5975var _spacerJs2 = _interopRequireDefault(_spacerJs); 5976 5977var _componentJs = _dereq_('../../component.js'); 5978 5979var _componentJs2 = _interopRequireDefault(_componentJs); 5980 5981/** 5982 * Spacer specifically meant to be used as an insertion point for new plugins, etc. 5983 * 5984 * @extends Spacer 5985 * @class CustomControlSpacer 5986 */ 5987 5988var CustomControlSpacer = (function (_Spacer) { 5989 _inherits(CustomControlSpacer, _Spacer); 5990 5991 function CustomControlSpacer() { 5992 _classCallCheck(this, CustomControlSpacer); 5993 5994 _Spacer.apply(this, arguments); 5995 } 5996 5997 /** 5998 * Allow sub components to stack CSS class names 5999 * 6000 * @return {String} The constructed class name 6001 * @method buildCSSClass 6002 */ 6003 6004 CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() { 6005 return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this); 6006 }; 6007 6008 /** 6009 * Create the component's DOM element 6010 * 6011 * @return {Element} 6012 * @method createEl 6013 */ 6014 6015 CustomControlSpacer.prototype.createEl = function createEl() { 6016 var el = _Spacer.prototype.createEl.call(this, { 6017 className: this.buildCSSClass() 6018 }); 6019 6020 // No-flex/table-cell mode requires there be some content 6021 // in the cell to fill the remaining space of the table. 6022 el.innerHTML = ' '; 6023 return el; 6024 }; 6025 6026 return CustomControlSpacer; 6027})(_spacerJs2['default']); 6028 6029_componentJs2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer); 6030exports['default'] = CustomControlSpacer; 6031module.exports = exports['default']; 6032 6033},{"../../component.js":66,"./spacer.js":80}],80:[function(_dereq_,module,exports){ 6034/** 6035 * @file spacer.js 6036 */ 6037'use strict'; 6038 6039exports.__esModule = true; 6040 6041function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6042 6043function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6044 6045function _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; } 6046 6047var _componentJs = _dereq_('../../component.js'); 6048 6049var _componentJs2 = _interopRequireDefault(_componentJs); 6050 6051/** 6052 * Just an empty spacer element that can be used as an append point for plugins, etc. 6053 * Also can be used to create space between elements when necessary. 6054 * 6055 * @extends Component 6056 * @class Spacer 6057 */ 6058 6059var Spacer = (function (_Component) { 6060 _inherits(Spacer, _Component); 6061 6062 function Spacer() { 6063 _classCallCheck(this, Spacer); 6064 6065 _Component.apply(this, arguments); 6066 } 6067 6068 /** 6069 * Allow sub components to stack CSS class names 6070 * 6071 * @return {String} The constructed class name 6072 * @method buildCSSClass 6073 */ 6074 6075 Spacer.prototype.buildCSSClass = function buildCSSClass() { 6076 return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this); 6077 }; 6078 6079 /** 6080 * Create the component's DOM element 6081 * 6082 * @return {Element} 6083 * @method createEl 6084 */ 6085 6086 Spacer.prototype.createEl = function createEl() { 6087 return _Component.prototype.createEl.call(this, 'div', { 6088 className: this.buildCSSClass() 6089 }); 6090 }; 6091 6092 return Spacer; 6093})(_componentJs2['default']); 6094 6095_componentJs2['default'].registerComponent('Spacer', Spacer); 6096 6097exports['default'] = Spacer; 6098module.exports = exports['default']; 6099 6100},{"../../component.js":66}],81:[function(_dereq_,module,exports){ 6101/** 6102 * @file caption-settings-menu-item.js 6103 */ 6104'use strict'; 6105 6106exports.__esModule = true; 6107 6108function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6109 6110function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6111 6112function _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
6112onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 6113 6114var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js'); 6115 6116var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs); 6117 6118var _componentJs = _dereq_('../../component.js'); 6119 6120var _componentJs2 = _interopRequireDefault(_componentJs); 6121 6122/** 6123 * The menu item for caption track settings menu 6124 * 6125 * @param {Player|Object} player 6126 * @param {Object=} options 6127 * @extends TextTrackMenuItem 6128 * @class CaptionSettingsMenuItem 6129 */ 6130 6131var CaptionSettingsMenuItem = (function (_TextTrackMenuItem) { 6132 _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem); 6133 6134 function CaptionSettingsMenuItem(player, options) { 6135 _classCallCheck(this, CaptionSettingsMenuItem); 6136 6137 options['track'] = { 6138 'kind': options['kind'], 6139 'player': player, 6140 'label': options['kind'] + ' settings', 6141 'selectable': false, 6142 'default': false, 6143 mode: 'disabled' 6144 }; 6145 6146 // CaptionSettingsMenuItem has no concept of 'selected' 6147 options['selectable'] = false; 6148 6149 _TextTrackMenuItem.call(this, player, options); 6150 this.addClass('vjs-texttrack-settings'); 6151 this.controlText(', opens ' + options['kind'] + ' settings dialog'); 6152 } 6153 6154 /** 6155 * Handle click on menu item 6156 * 6157 * @method handleClick 6158 */ 6159 6160 CaptionSettingsMenuItem.prototype.handleClick = function handleClick() { 6161 this.player().getChild('textTrackSettings').show(); 6162 this.player().getChild('textTrackSettings').el_.focus(); 6163 }; 6164 6165 return CaptionSettingsMenuItem; 6166})(_textTrackMenuItemJs2['default']); 6167 6168_componentJs2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem); 6169exports['default'] = CaptionSettingsMenuItem; 6170module.exports = exports['default']; 6171 6172},{"../../component.js":66,"./text-track-menu-item.js":88}],82:[function(_dereq_,module,exports){ 6173/** 6174 * @file captions-button.js 6175 */ 6176'use strict'; 6177 6178exports.__esModule = true; 6179 6180function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6181 6182function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6183 6184function _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; } 6185 6186var _textTrackButtonJs = _dereq_('./text-track-button.js'); 6187 6188var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs); 6189 6190var _componentJs = _dereq_('../../component.js'); 6191 6192var _componentJs2 = _interopRequireDefault(_componentJs); 6193 6194var _captionSettingsMenuItemJs = _dereq_('./caption-settings-menu-item.js'); 6195 6196var _captionSettingsMenuItemJs2 = _interopRequireDefault(_captionSettingsMenuItemJs); 6197 6198/** 6199 * The button component for toggling and selecting captions 6200 * 6201 * @param {Object} player Player object 6202 * @param {Object=} options Object of option names and values 6203 * @param {Function=} ready Ready callback function 6204 * @extends TextTrackButton 6205 * @class CaptionsButton 6206 */ 6207 6208var CaptionsButton = (function (_TextTrackButton) { 6209 _inherits(CaptionsButton, _TextTrackButton); 6210 6211 function CaptionsButton(player, options, ready) { 6212 _classCallCheck(this, CaptionsButton); 6213 6214 _TextTrackButton.call(this, player, options, ready); 6215 this.el_.setAttribute('aria-label', 'Captions Menu'); 6216 } 6217 6218 /** 6219 * Allow sub components to stack CSS class names 6220 * 6221 * @return {String} The constructed class name 6222 * @method buildCSSClass 6223 */ 6224 6225 CaptionsButton.prototype.buildCSSClass = function buildCSSClass() { 6226 return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 6227 }; 6228 6229 /** 6230 * Update caption menu items 6231 * 6232 * @method update 6233 */ 6234
6235 CaptionsButton.prototype.update = function update() { 6236 var threshold = 2; 6237 _TextTrackButton.prototype.update.call(this); 6238 6239 // if native, then threshold is 1 because no settings button 6240 if (this.player().tech_ && this.player().tech_['featuresNativeTextTracks']) { 6241 threshold = 1; 6242 } 6243 6244 if (this.items && this.items.length > threshold) { 6245 this.show(); 6246 } else { 6247 this.hide(); 6248 } 6249 }; 6250 6251 /** 6252 * Create caption menu items 6253 * 6254 * @return {Array} Array of menu items 6255 * @method createItems 6256 */ 6257 6258 CaptionsButton.prototype.createItems = function createItems() { 6259 var items = []; 6260 6261 if (!(this.player().tech_ && this.player().tech_['featuresNativeTextTracks'])) { 6262 items.push(new _captionSettingsMenuItemJs2['default'](this.player_, { 'kind': this.kind_ })); 6263 } 6264 6265 return _TextTrackButton.prototype.createItems.call(this, items); 6266 }; 6267 6268 return CaptionsButton; 6269})(_textTrackButtonJs2['default']); 6270 6271CaptionsButton.prototype.kind_ = 'captions'; 6272CaptionsButton.prototype.controlText_ = 'Captions'; 6273 6274_componentJs2['default'].registerComponent('CaptionsButton', CaptionsButton); 6275exports['default'] = CaptionsButton; 6276module.exports = exports['default']; 6277 6278},{"../../component.js":66,"./caption-settings-menu-item.js":81,"./text-track-button.js":87}],83:[function(_dereq_,module,exports){ 6279/** 6280 * @file chapters-button.js 6281 */ 6282'use strict'; 6283 6284exports.__esModule = true; 6285 6286function _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; } } 6287 6288function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6289 6290function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6291 6292function _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; } 6293 6294var _textTrackButtonJs = _dereq_('./text-track-button.js'); 6295 6296var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs); 6297 6298var _componentJs = _dereq_('../../component.js'); 6299 6300var _componentJs2 = _interopRequireDefault(_componentJs); 6301 6302var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js'); 6303 6304var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs); 6305 6306var _chaptersTrackMenuItemJs = _dereq_('./chapters-track-menu-item.js'); 6307 6308var _chaptersTrackMenuItemJs2 = _interopRequireDefault(_chaptersTrackMenuItemJs); 6309 6310var _menuMenuJs = _dereq_('../../menu/menu.js'); 6311 6312var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs); 6313 6314var _utilsDomJs = _dereq_('../../utils/dom.js'); 6315 6316var Dom = _interopRequireWildcard(_utilsDomJs); 6317 6318var _utilsFnJs = _dereq_('../../utils/fn.js'); 6319 6320var Fn = _interopRequireWildcard(_utilsFnJs); 6321 6322var _utilsToTitleCaseJs = _dereq_('../../utils/to-title-case.js'); 6323 6324var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs); 6325 6326var _globalWindow = _dereq_('global/window'); 6327 6328var _globalWindow2 = _interopRequireDefault(_globalWindow); 6329 6330/** 6331 * The button component for toggling and selecting chapters 6332 * Chapters act much differently than other text tracks 6333 * Cues are navigation vs. other tracks of alternative languages 6334 * 6335 * @param {Object} player Player object 6336 * @param {Object=} options Object of option names and values 6337 * @param {Function=} ready Ready callback function 6338 * @extends TextTrackButton 6339 * @class ChaptersButton 6340 */ 6341 6342var ChaptersButton = (function (_TextTrackButton) { 6343 _inherits(ChaptersButton, _TextTrackButton); 6344 6345 function ChaptersButton(player, options, ready) { 6346 _classCallCheck(this, ChaptersButton); 6347 6348 _TextTrackButton.call(this, player, options, ready); 6349 this.el_.setAttribute('aria-label', 'Chapters Menu'); 6350 } 6351 6352 /** 6353 * Allow sub components to stack CSS class names 6354 * 6355 * @return {String} The constructed class name 6356 * @method buildCSSClass 6357 */ 6358 6359 ChaptersButton.prototype.buildCSSClass = function buildCSSClass() { 6360 return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 6361 }; 6362 6363 /** 6364 * Create a menu item for each text track 6365 * 6366 * @return {Array} Array of menu items 6367 * @method createItems 6368 */ 6369 6370 ChaptersButton.prototype.createItems = function createItems() { 6371 var items = []; 6372 6373 var tracks = this.player_.textTracks(); 6374 6375 if (!tracks) { 6376 return items; 6377 } 6378 6379 for (var i = 0; i < tracks.length; i++) { 6380 var track = tracks[i]; 6381 if (track['kind'] === this.kind_) { 6382 items.push(new _textTrackMenuItemJs2['default'](this.player_, { 6383 'track': track 6384 })); 6385 } 6386 } 6387 6388 return items; 6389 }; 6390 6391 /** 6392 * Create menu from chapter buttons 6393 * 6394 * @return {Menu} Menu of chapter buttons 6395 * @method createMenu 6396 */ 6397 6398 ChaptersButton.prototype.createMenu = function createMenu() { 6399 var _this = this; 6400 6401 var tracks = this.player_.textTracks() || []; 6402 var chaptersTrack = undefined; 6403 var items = this.items = []; 6404 6405 for (var i = 0, _length = tracks.length; i < _length; i++) { 6406 var track = tracks[i]; 6407 6408 if (track['kind'] === this.kind_) { 6409 chaptersTrack = track; 6410 6411 break; 6412 } 6413 } 6414 6415 var menu = this.menu; 6416 if (menu === undefined) { 6417 menu = new _menuMenuJs2['default'](this.player_); 6418 menu.contentEl().appendChild(Dom.createEl('li', { 6419 className: 'vjs-menu-title', 6420 innerHTML: _utilsToTitleCaseJs2['default'](this.kind_), 6421 tabIndex: -1 6422 })); 6423 } 6424
6425 if (chaptersTrack && chaptersTrack.cues == null) { 6426 chaptersTrack['mode'] = 'hidden'; 6427 6428 var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(chaptersTrack); 6429 6430 if (remoteTextTrackEl) { 6431 remoteTextTrackEl.addEventListener('load', function (event) { 6432 return _this.update(); 6433 }); 6434 } 6435 } 6436 6437 if (chaptersTrack && chaptersTrack.cues && chaptersTrack.cues.length > 0) { 6438 var cues = chaptersTrack['cues'], 6439 cue = undefined; 6440 6441 for (var i = 0, l = cues.length; i < l; i++) { 6442 cue = cues[i]; 6443 6444 var mi = new _chaptersTrackMenuItemJs2['default'](this.player_, { 6445 'track': chaptersTrack, 6446 'cue': cue 6447 }); 6448 6449 items.push(mi); 6450 6451 menu.addChild(mi); 6452 } 6453 6454 this.addChild(menu); 6455 } 6456 6457 if (this.items.length > 0) { 6458 this.show(); 6459 } 6460 6461 return menu; 6462 }; 6463 6464 return ChaptersButton; 6465})(_textTrackButtonJs2['default']); 6466 6467ChaptersButton.prototype.kind_ = 'chapters'; 6468ChaptersButton.prototype.controlText_ = 'Chapters'; 6469 6470_componentJs2['default'].registerComponent('ChaptersButton', ChaptersButton); 6471exports['default'] = ChaptersButton; 6472module.exports = exports['default']; 6473 6474},{"../../component.js":66,"../../menu/menu.js":105,"../../utils/dom.js":131,"../../utils/fn.js":133,"../../utils/to-title-case.js":140,"./chapters-track-menu-item.js":84,"./text-track-button.js":87,"./text-track-menu-item.js":88,"global/window":2}],84:[function(_dereq_,module,exports){ 6475/** 6476 * @file chapters-track-menu-item.js 6477 */ 6478'use strict'; 6479 6480exports.__esModule = true; 6481 6482function _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; } } 6483 6484function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6485 6486function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6487 6488function _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; } 6489 6490var _menuMenuItemJs = _dereq_('../../menu/menu-item.js'); 6491 6492var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs); 6493 6494var _componentJs = _dereq_('../../component.js'); 6495 6496var _componentJs2 = _interopRequireDefault(_componentJs); 6497 6498var _utilsFnJs = _dereq_('../../utils/fn.js'); 6499 6500var Fn = _interopRequireWildcard(_utilsFnJs); 6501 6502/** 6503 * The chapter track menu item 6504 * 6505 * @param {Player|Object} player 6506 * @param {Object=} options 6507 * @extends MenuItem 6508 * @class ChaptersTrackMenuItem 6509 */ 6510 6511var ChaptersTrackMenuItem = (function (_MenuItem) { 6512 _inherits(ChaptersTrackMenuItem, _MenuItem); 6513 6514 function ChaptersTrackMenuItem(player, options) { 6515 _classCallCheck(this, ChaptersTrackMenuItem); 6516 6517 var track = options['track']; 6518 var cue = options['cue']; 6519 var currentTime = player.currentTime(); 6520 6521 // Modify options for parent MenuItem class's init. 6522 options['label'] = cue.text; 6523 options['selected'] = cue['startTime'] <= currentTime && currentTime < cue['endTime']; 6524 _MenuItem.call(this, player, options); 6525 6526 this.track = track; 6527 this.cue = cue; 6528 track.addEventListener('cuechange', Fn.bind(this, this.update)); 6529 } 6530 6531 /** 6532 * Handle click on menu item 6533 * 6534 * @method handleClick 6535 */ 6536 6537 ChaptersTrackMenuItem.prototype.handleClick = function handleClick() { 6538 _MenuItem.prototype.handleClick.call(this); 6539 this.player_.currentTime(this.cue.startTime); 6540 this.update(this.cue.startTime); 6541 }; 6542 6543 /** 6544 * Update chapter menu item 6545 * 6546 * @method update 6547 */ 6548
6549 ChaptersTrackMenuItem.prototype.update = function update() { 6550 var cue = this.cue; 6551 var currentTime = this.player_.currentTime(); 6552 6553 // vjs.log(currentTime, cue.startTime); 6554 this.selected(cue['startTime'] <= currentTime && currentTime < cue['endTime']); 6555 }; 6556 6557 return ChaptersTrackMenuItem; 6558})(_menuMenuItemJs2['default']); 6559 6560_componentJs2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem); 6561exports['default'] = ChaptersTrackMenuItem; 6562module.exports = exports['default']; 6563 6564},{"../../component.js":66,"../../menu/menu-item.js":104,"../../utils/fn.js":133}],85:[function(_dereq_,module,exports){ 6565/** 6566 * @file off-text-track-menu-item.js 6567 */ 6568'use strict'; 6569 6570exports.__esModule = true; 6571 6572function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6573 6574function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6575 6576function _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; } 6577 6578var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js'); 6579 6580var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs); 6581 6582var _componentJs = _dereq_('../../component.js'); 6583 6584var _componentJs2 = _interopRequireDefault(_componentJs); 6585 6586/** 6587 * A special menu item for turning of a specific type of text track 6588 * 6589 * @param {Player|Object} player 6590 * @param {Object=} options 6591 * @extends TextTrackMenuItem 6592 * @class OffTextTrackMenuItem 6593 */ 6594 6595var OffTextTrackMenuItem = (function (_TextTrackMenuItem) { 6596 _inherits(OffTextTrackMenuItem, _TextTrackMenuItem); 6597 6598 function OffTextTrackMenuItem(player, options) { 6599 _classCallCheck(this, OffTextTrackMenuItem); 6600 6601 // Create pseudo track info 6602 // Requires options['kind'] 6603 options['track'] = { 6604 'kind': options['kind'], 6605 'player': player, 6606 'label': options['kind'] + ' off', 6607 'default': false, 6608 'mode': 'disabled' 6609 }; 6610 6611 // MenuItem is selectable 6612 options['selectable'] = true; 6613 6614 _TextTrackMenuItem.call(this, player, options); 6615 this.selected(true); 6616 } 6617 6618 /** 6619 * Handle text track change 6620 * 6621 * @param {Object} event Event object 6622 * @method handleTracksChange 6623 */ 6624 6625 OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { 6626 var tracks = this.player().textTracks(); 6627 var selected = true; 6628 6629 for (var i = 0, l = tracks.length; i < l; i++) { 6630 var track = tracks[i]; 6631 if (track['kind'] === this.track['kind'] && track['mode'] === 'showing') { 6632 selected = false; 6633 break; 6634 } 6635 } 6636 6637 this.selected(selected); 6638 }; 6639 6640 return OffTextTrackMenuItem; 6641})(_textTrackMenuItemJs2['default']); 6642 6643_componentJs2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem); 6644exports['default'] = OffTextTrackMenuItem; 6645module.exports = exports['default']; 6646 6647},{"../../component.js":66,"./text-track-menu-item.js":88}],86:[function(_dereq_,module,exports){ 6648/** 6649 * @file subtitles-button.js 6650 */ 6651'use strict'; 6652 6653exports.__esModule = true; 6654 6655function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6656 6657function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6658 6659function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 6660 6661var _textTrackButtonJs = _dereq_('./text-track-button.js'); 6662 6663var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs); 6664 6665var _componentJs = _dereq_('../../component.js'); 6666 6667var _componentJs2 = _interopRequireDefault(_componentJs); 6668 6669/** 6670 * The button component for toggling and selecting subtitles 6671 * 6672 * @param {Object} player Player object 6673 * @param {Object=} options Object of option names and values 6674 * @param {Function=} ready Ready callback function 6675 * @extends TextTrackButton 6676 * @class SubtitlesButton 6677 */ 6678 6679var SubtitlesButton = (function (_TextTrackButton) { 6680 _inherits(SubtitlesButton, _TextTrackButton); 6681
6682 function SubtitlesButton(player, options, ready) { 6683 _classCallCheck(this, SubtitlesButton); 6684 6685 _TextTrackButton.call(this, player, options, ready); 6686 this.el_.setAttribute('aria-label', 'Subtitles Menu'); 6687 } 6688 6689 /** 6690 * Allow sub components to stack CSS class names 6691 * 6692 * @return {String} The constructed class name 6693 * @method buildCSSClass 6694 */ 6695 6696 SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() { 6697 return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); 6698 }; 6699 6700 return SubtitlesButton; 6701})(_textTrackButtonJs2['default']); 6702 6703SubtitlesButton.prototype.kind_ = 'subtitles'; 6704SubtitlesButton.prototype.controlText_ = 'Subtitles'; 6705 6706_componentJs2['default'].registerComponent('SubtitlesButton', SubtitlesButton); 6707exports['default'] = SubtitlesButton; 6708module.exports = exports['default']; 6709 6710},{"../../component.js":66,"./text-track-button.js":87}],87:[function(_dereq_,module,exports){ 6711/** 6712 * @file text-track-button.js 6713 */ 6714'use strict'; 6715 6716exports.__esModule = true; 6717 6718function _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; } } 6719 6720function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6721 6722function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6723 6724function _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; } 6725 6726var _menuMenuButtonJs = _dereq_('../../menu/menu-button.js'); 6727 6728var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs); 6729 6730var _componentJs = _dereq_('../../component.js'); 6731 6732var _componentJs2 = _interopRequireDefault(_componentJs); 6733 6734var _utilsFnJs = _dereq_('../../utils/fn.js'); 6735 6736var Fn = _interopRequireWildcard(_utilsFnJs); 6737 6738var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js'); 6739 6740var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs); 6741 6742var _offTextTrackMenuItemJs = _dereq_('./off-text-track-menu-item.js'); 6743 6744var _offTextTrackMenuItemJs2 = _interopRequireDefault(_offTextTrackMenuItemJs); 6745 6746/** 6747 * The base class for buttons that toggle specific text track types (e.g. subtitles) 6748 * 6749 * @param {Player|Object} player 6750 * @param {Object=} options 6751 * @extends MenuButton 6752 * @class TextTrackButton 6753 */ 6754 6755var TextTrackButton = (function (_MenuButton) { 6756 _inherits(TextTrackButton, _MenuButton); 6757 6758 function TextTrackButton(player, options) { 6759 _classCallCheck(this, TextTrackButton); 6760 6761 _MenuButton.call(this, player, options); 6762 6763 var tracks = this.player_.textTracks(); 6764 6765 if (this.items.length <= 1) { 6766 this.hide(); 6767 } 6768 6769 if (!tracks) { 6770 return; 6771 } 6772 6773 var updateHandler = Fn.bind(this, this.update); 6774 tracks.addEventListener('removetrack', updateHandler); 6775 tracks.addEventListener('addtrack', updateHandler); 6776 6777 this.player_.on('dispose', function () { 6778 tracks.removeEventListener('removetrack', updateHandler); 6779 tracks.removeEventListener('addtrack', updateHandler); 6780 }); 6781 } 6782 6783 // Create a menu item for each text track 6784 6785 TextTrackButton.prototype.createItems = function createItems() { 6786 var items = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; 6787 6788 // Add an OFF menu item to turn all tracks off 6789 items.push(new _offTextTrackMenuItemJs2['default'](this.player_, { 'kind': this.kind_ })); 6790 6791 var tracks = this.player_.textTracks(); 6792 6793 if (!tracks) { 6794 return items; 6795 } 6796 6797 for (var i = 0; i < tracks.length; i++) { 6798 var track = tracks[i]; 6799 6800 // only add tracks that are of the appropriate kind and have a label 6801 if (track['kind'] === this.kind_) { 6802 items.push(new _textTrackMenuItemJs2['default'](this.player_, { 6803 // MenuItem is selectable 6804 'selectable': true, 6805 'track': track 6806 })); 6807 } 6808 } 6809 6810 return items; 6811 }; 6812 6813 return TextTrackButton; 6814}
6814)(_menuMenuButtonJs2['default']); 6815 6816_componentJs2['default'].registerComponent('TextTrackButton', TextTrackButton); 6817exports['default'] = TextTrackButton; 6818module.exports = exports['default']; 6819 6820},{"../../component.js":66,"../../menu/menu-button.js":103,"../../utils/fn.js":133,"./off-text-track-menu-item.js":85,"./text-track-menu-item.js":88}],88:[function(_dereq_,module,exports){ 6821/** 6822 * @file text-track-menu-item.js 6823 */ 6824'use strict'; 6825 6826exports.__esModule = true; 6827 6828function _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; } } 6829 6830function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6831 6832function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6833 6834function _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; } 6835 6836var _menuMenuItemJs = _dereq_('../../menu/menu-item.js'); 6837 6838var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs); 6839 6840var _componentJs = _dereq_('../../component.js'); 6841 6842var _componentJs2 = _interopRequireDefault(_componentJs); 6843 6844var _utilsFnJs = _dereq_('../../utils/fn.js'); 6845 6846var Fn = _interopRequireWildcard(_utilsFnJs); 6847 6848var _globalWindow = _dereq_('global/window'); 6849 6850var _globalWindow2 = _interopRequireDefault(_globalWindow); 6851 6852var _globalDocument = _dereq_('global/document'); 6853 6854var _globalDocument2 = _interopRequireDefault(_globalDocument); 6855 6856/** 6857 * The specific menu item type for selecting a language within a text track kind 6858 * 6859 * @param {Player|Object} player 6860 * @param {Object=} options 6861 * @extends MenuItem 6862 * @class TextTrackMenuItem 6863 */ 6864 6865var TextTrackMenuItem = (function (_MenuItem) { 6866 _inherits(TextTrackMenuItem, _MenuItem); 6867 6868 function TextTrackMenuItem(player, options) { 6869 var _this = this; 6870 6871 _classCallCheck(this, TextTrackMenuItem); 6872 6873 var track = options['track']; 6874 var tracks = player.textTracks(); 6875 6876 // Modify options for parent MenuItem class's init. 6877 options['label'] = track['label'] || track['language'] || 'Unknown'; 6878 options['selected'] = track['default'] || track['mode'] === 'showing'; 6879 6880 _MenuItem.call(this, player, options); 6881 6882 this.track = track; 6883 6884 if (tracks) { 6885 (function () { 6886 var changeHandler = Fn.bind(_this, _this.handleTracksChange); 6887 6888 tracks.addEventListener('change', changeHandler); 6889 _this.on('dispose', function () { 6890 tracks.removeEventListener('change', changeHandler); 6891 }); 6892 })(); 6893 } 6894 6895 // iOS7 doesn't dispatch change events to TextTrackLists when an 6896 // associated track's mode changes. Without something like 6897 // Object.observe() (also not present on iOS7), it's not 6898 // possible to detect changes to the mode attribute and polyfill 6899 // the change event. As a poor substitute, we manually dispatch 6900 // change events whenever the controls modify the mode. 6901 if (tracks && tracks.onchange === undefined) { 6902 (function () { 6903 var event = undefined; 6904 6905 _this.on(['tap', 'click'], function () { 6906 if (typeof _globalWindow2['default'].Event !== 'object') { 6907 // Android 2.3 throws an Illegal Constructor error for window.Event 6908 try { 6909 event = new _globalWindow2['default'].Event('change'); 6910 } catch (err) {} 6911 } 6912 6913 if (!event) { 6914 event = _globalDocument2['default'].createEvent('Event'); 6915 event.initEvent('change', true, true); 6916 } 6917 6918 tracks.dispatchEvent(event); 6919 }); 6920 })(); 6921 } 6922 } 6923 6924 /** 6925 * Handle click on text track 6926 * 6927 * @method handleClick 6928 */ 6929 6930 TextTrackMenuItem.prototype.handleClick = function handleClick(event) { 6931 var kind = this.track['kind']; 6932 var tracks = this.player_.textTracks(); 6933 6934 _MenuItem.prototype.handleClick.call(this, event); 6935 6936 if (!tracks) return; 6937 6938 for (var i = 0; i < tracks.length; i++) { 6939 var track = tracks[i]; 6940 6941 if (track['kind'] !== kind) { 6942 continue; 6943 } 6944 6945 if (track === this.track) { 6946 track['mode'] = 'showing'; 6947 } else { 6948 track['mode'] = 'disabled'; 6949 } 6950 } 6951 }; 6952 6953 /** 6954 * Handle text track change 6955 * 6956 * @method handleTracksChange 6957 */ 6958 6959 TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { 6960 this.selected(this.track['mode'] === 'showing'); 6961 }; 6962 6963 return TextTrackMenuItem; 6964}
6964)(_menuMenuItemJs2['default']); 6965 6966_componentJs2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem); 6967exports['default'] = TextTrackMenuItem; 6968module.exports = exports['default']; 6969 6970},{"../../component.js":66,"../../menu/menu-item.js":104,"../../utils/fn.js":133,"global/document":1,"global/window":2}],89:[function(_dereq_,module,exports){ 6971/** 6972 * @file current-time-display.js 6973 */ 6974'use strict'; 6975 6976exports.__esModule = true; 6977 6978function _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; } } 6979 6980function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 6981 6982function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6983 6984function _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; } 6985 6986var _componentJs = _dereq_('../../component.js'); 6987 6988var _componentJs2 = _interopRequireDefault(_componentJs); 6989 6990var _utilsDomJs = _dereq_('../../utils/dom.js'); 6991 6992var Dom = _interopRequireWildcard(_utilsDomJs); 6993 6994var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js'); 6995 6996var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 6997 6998/** 6999 * Displays the current time 7000 * 7001 * @param {Player|Object} player 7002 * @param {Object=} options 7003 * @extends Component 7004 * @class CurrentTimeDisplay 7005 */ 7006 7007var CurrentTimeDisplay = (function (_Component) { 7008 _inherits(CurrentTimeDisplay, _Component); 7009 7010 function CurrentTimeDisplay(player, options) { 7011 _classCallCheck(this, CurrentTimeDisplay); 7012 7013 _Component.call(this, player, options); 7014 7015 this.on(player, 'timeupdate', this.updateContent); 7016 } 7017 7018 /** 7019 * Create the component's DOM element 7020 * 7021 * @return {Element} 7022 * @method createEl 7023 */ 7024 7025 CurrentTimeDisplay.prototype.createEl = function createEl() { 7026 var el = _Component.prototype.createEl.call(this, 'div', { 7027 className: 'vjs-current-time vjs-time-control vjs-control' 7028 }); 7029 7030 this.contentEl_ = Dom.createEl('div', { 7031 className: 'vjs-current-time-display', 7032 // label the current time for screen reader users 7033 innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00' 7034 }, { 7035 // tell screen readers not to automatically read the time as it changes 7036 'aria-live': 'off' 7037 }); 7038 7039 el.appendChild(this.contentEl_); 7040 return el; 7041 }; 7042 7043 /** 7044 * Update current time display 7045 * 7046 * @method updateContent 7047 */ 7048 7049 CurrentTimeDisplay.prototype.updateContent = function updateContent() { 7050 // Allows for smooth scrubbing, when player can't keep up. 7051 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); 7052 var localizedText = this.localize('Current Time'); 7053 var formattedTime = _utilsFormatTimeJs2['default'](time, this.player_.duration()); 7054 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; 7055 }; 7056 7057 return CurrentTimeDisplay; 7058})(_componentJs2['default']); 7059 7060_componentJs2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay); 7061exports['default'] = CurrentTimeDisplay; 7062module.exports = exports['default']; 7063 7064},{"../../component.js":66,"../../utils/dom.js":131,"../../utils/format-time.js":134}],90:[function(_dereq_,module,exports){ 7065/** 7066 * @file duration-display.js 7067 */ 7068'use strict'; 7069 7070exports.__esModule = true; 7071 7072function _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; } } 7073 7074function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7075 7076function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7077 7078function _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
7078onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 7079 7080var _componentJs = _dereq_('../../component.js'); 7081 7082var _componentJs2 = _interopRequireDefault(_componentJs); 7083 7084var _utilsDomJs = _dereq_('../../utils/dom.js'); 7085 7086var Dom = _interopRequireWildcard(_utilsDomJs); 7087 7088var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js'); 7089 7090var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 7091 7092/** 7093 * Displays the duration 7094 * 7095 * @param {Player|Object} player 7096 * @param {Object=} options 7097 * @extends Component 7098 * @class DurationDisplay 7099 */ 7100 7101var DurationDisplay = (function (_Component) { 7102 _inherits(DurationDisplay, _Component); 7103 7104 function DurationDisplay(player, options) { 7105 _classCallCheck(this, DurationDisplay); 7106 7107 _Component.call(this, player, options); 7108 7109 // this might need to be changed to 'durationchange' instead of 'timeupdate' eventually, 7110 // however the durationchange event fires before this.player_.duration() is set, 7111 // so the value cannot be written out using this method. 7112 // Once the order of durationchange and this.player_.duration() being set is figured out, 7113 // this can be updated. 7114 this.on(player, 'timeupdate', this.updateContent); 7115 this.on(player, 'loadedmetadata', this.updateContent); 7116 } 7117 7118 /** 7119 * Create the component's DOM element 7120 * 7121 * @return {Element} 7122 * @method createEl 7123 */ 7124 7125 DurationDisplay.prototype.createEl = function createEl() { 7126 var el = _Component.prototype.createEl.call(this, 'div', { 7127 className: 'vjs-duration vjs-time-control vjs-control' 7128 }); 7129 7130 this.contentEl_ = Dom.createEl('div', { 7131 className: 'vjs-duration-display', 7132 // label the duration time for screen reader users 7133 innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00' 7134 }, { 7135 // tell screen readers not to automatically read the time as it changes 7136 'aria-live': 'off' 7137 }); 7138 7139 el.appendChild(this.contentEl_); 7140 return el; 7141 }; 7142 7143 /** 7144 * Update duration time display 7145 * 7146 * @method updateContent 7147 */ 7148 7149 DurationDisplay.prototype.updateContent = function updateContent() { 7150 var duration = this.player_.duration(); 7151 if (duration) { 7152 var localizedText = this.localize('Duration Time'); 7153 var formattedTime = _utilsFormatTimeJs2['default'](duration); 7154 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; // label the duration time for screen reader users 7155 } 7156 }; 7157 7158 return DurationDisplay; 7159})(_componentJs2['default']); 7160 7161_componentJs2['default'].registerComponent('DurationDisplay', DurationDisplay); 7162exports['default'] = DurationDisplay; 7163module.exports = exports['default']; 7164 7165},{"../../component.js":66,"../../utils/dom.js":131,"../../utils/format-time.js":134}],91:[function(_dereq_,module,exports){ 7166/** 7167 * @file remaining-time-display.js 7168 */ 7169'use strict'; 7170 7171exports.__esModule = true; 7172 7173function _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; } } 7174 7175function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7176 7177function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7178 7179function _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; } 7180 7181var _componentJs = _dereq_('../../component.js'); 7182 7183var _componentJs2 = _interopRequireDefault(_componentJs); 7184 7185var _utilsDomJs = _dereq_('../../utils/dom.js'); 7186 7187var Dom = _interopRequireWildcard(_utilsDomJs); 7188 7189var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js'); 7190 7191var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 7192 7193/** 7194 * Displays the time left in the video 7195 * 7196 * @param {Player|Object} player 7197 * @param {Object=} options 7198 * @extends Component 7199 * @class RemainingTimeDisplay 7200 */ 7201 7202var RemainingTimeDisplay = (function (_Component) { 7203 _inherits(RemainingTimeDisplay, _Component); 7204 7205 function RemainingTimeDisplay(player, options) { 7206 _classCallCheck(this, RemainingTimeDisplay); 7207 7208 _Component.call(this, player, options); 7209 7210 this.on(player, 'timeupdate', this.updateContent); 7211 } 7212 7213 /** 7214 * Create the component's DOM element 7215 * 7216 * @return {Element} 7217 * @method createEl 7218 */ 7219 7220 RemainingTimeDisplay.prototype.createEl = function createEl() { 7221 var el = _Component.prototype.createEl.call(this, 'div', { 7222 className: 'vjs-remaining-time vjs-time-control vjs-control' 7223 }); 7224 7225 this.contentEl_ = Dom.createEl('div', { 7226 className: 'vjs-remaining-time-display', 7227 // label the remaining time for screen reader users 7228 innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00' 7229 }, {
7230 // tell screen readers not to automatically read the time as it changes 7231 'aria-live': 'off' 7232 }); 7233 7234 el.appendChild(this.contentEl_); 7235 return el; 7236 }; 7237 7238 /** 7239 * Update remaining time display 7240 * 7241 * @method updateContent 7242 */ 7243 7244 RemainingTimeDisplay.prototype.updateContent = function updateContent() { 7245 if (this.player_.duration()) { 7246 var localizedText = this.localize('Remaining Time'); 7247 var formattedTime = _utilsFormatTimeJs2['default'](this.player_.remainingTime()); 7248 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime; 7249 } 7250 7251 // Allows for smooth scrubbing, when player can't keep up. 7252 // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime(); 7253 // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration()); 7254 }; 7255 7256 return RemainingTimeDisplay; 7257})(_componentJs2['default']); 7258 7259_componentJs2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay); 7260exports['default'] = RemainingTimeDisplay; 7261module.exports = exports['default']; 7262 7263},{"../../component.js":66,"../../utils/dom.js":131,"../../utils/format-time.js":134}],92:[function(_dereq_,module,exports){ 7264/** 7265 * @file time-divider.js 7266 */ 7267'use strict'; 7268 7269exports.__esModule = true; 7270 7271function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7272 7273function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7274 7275function _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; } 7276 7277var _componentJs = _dereq_('../../component.js'); 7278 7279var _componentJs2 = _interopRequireDefault(_componentJs); 7280 7281/** 7282 * The separator between the current time and duration. 7283 * Can be hidden if it's not needed in the design. 7284 * 7285 * @param {Player|Object} player 7286 * @param {Object=} options 7287 * @extends Component 7288 * @class TimeDivider 7289 */ 7290 7291var TimeDivider = (function (_Component) { 7292 _inherits(TimeDivider, _Component); 7293 7294 function TimeDivider() { 7295 _classCallCheck(this, TimeDivider); 7296 7297 _Component.apply(this, arguments); 7298 } 7299 7300 /** 7301 * Create the component's DOM element 7302 * 7303 * @return {Element} 7304 * @method createEl 7305 */ 7306 7307 TimeDivider.prototype.createEl = function createEl() { 7308 return _Component.prototype.createEl.call(this, 'div', { 7309 className: 'vjs-time-control vjs-time-divider', 7310 innerHTML: '<div><span>/</span></div>' 7311 }); 7312 }; 7313 7314 return TimeDivider; 7315})(_componentJs2['default']); 7316 7317_componentJs2['default'].registerComponent('TimeDivider', TimeDivider); 7318exports['default'] = TimeDivider; 7319module.exports = exports['default']; 7320 7321},{"../../component.js":66}],93:[function(_dereq_,module,exports){ 7322/** 7323 * @file volume-bar.js 7324 */ 7325'use strict'; 7326 7327exports.__esModule = true; 7328 7329function _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; } } 7330 7331function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7332 7333function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7334 7335function _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; } 7336 7337var _sliderSliderJs = _dereq_('../../slider/slider.js'); 7338 7339var _sliderSliderJs2 = _interopRequireDefault(_sliderSliderJs); 7340 7341var _componentJs = _dereq_('../../component.js'); 7342 7343var _componentJs2 = _interopRequireDefault(_componentJs); 7344 7345var _utilsFnJs = _dereq_('../../utils/fn.js'); 7346 7347var Fn = _interopRequireWildcard(_utilsFnJs); 7348 7349// Required children 7350 7351var _volumeLevelJs = _dereq_('./volume-level.js'); 7352 7353var _volumeLevelJs2 = _interopRequireDefault(_volumeLevelJs); 7354 7355/** 7356 * The bar that contains the volume level and can be clicked on to adjust the level 7357 * 7358 * @param {Player|Object} player 7359 * @param {Object=} options 7360 * @extends Slider 7361 * @class VolumeBar 7362 */ 7363
7364var VolumeBar = (function (_Slider) { 7365 _inherits(VolumeBar, _Slider); 7366 7367 function VolumeBar(player, options) { 7368 _classCallCheck(this, VolumeBar); 7369 7370 _Slider.call(this, player, options); 7371 this.on(player, 'volumechange', this.updateARIAAttributes); 7372 player.ready(Fn.bind(this, this.updateARIAAttributes)); 7373 } 7374 7375 /** 7376 * Create the component's DOM element 7377 * 7378 * @return {Element} 7379 * @method createEl 7380 */ 7381 7382 VolumeBar.prototype.createEl = function createEl() { 7383 return _Slider.prototype.createEl.call(this, 'div', { 7384 className: 'vjs-volume-bar vjs-slider-bar' 7385 }, { 7386 'aria-label': 'volume level' 7387 }); 7388 }; 7389 7390 /** 7391 * Handle mouse move on volume bar 7392 * 7393 * @method handleMouseMove 7394 */ 7395 7396 VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) { 7397 this.checkMuted(); 7398 this.player_.volume(this.calculateDistance(event)); 7399 }; 7400 7401 VolumeBar.prototype.checkMuted = function checkMuted() { 7402 if (this.player_.muted()) { 7403 this.player_.muted(false); 7404 } 7405 }; 7406 7407 /** 7408 * Get percent of volume level 7409 * 7410 * @retun {Number} Volume level percent 7411 * @method getPercent 7412 */ 7413 7414 VolumeBar.prototype.getPercent = function getPercent() { 7415 if (this.player_.muted()) { 7416 return 0; 7417 } else { 7418 return this.player_.volume(); 7419 } 7420 }; 7421 7422 /** 7423 * Increase volume level for keyboard users 7424 * 7425 * @method stepForward 7426 */ 7427 7428 VolumeBar.prototype.stepForward = function stepForward() { 7429 this.checkMuted(); 7430 this.player_.volume(this.player_.volume() + 0.1); 7431 }; 7432 7433 /** 7434 * Decrease volume level for keyboard users 7435 * 7436 * @method stepBack 7437 */ 7438 7439 VolumeBar.prototype.stepBack = function stepBack() { 7440 this.checkMuted(); 7441 this.player_.volume(this.player_.volume() - 0.1); 7442 }; 7443 7444 /** 7445 * Update ARIA accessibility attributes 7446 * 7447 * @method updateARIAAttributes 7448 */ 7449 7450 VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes() { 7451 // Current value of volume bar as a percentage 7452 var volume = (this.player_.volume() * 100).toFixed(2); 7453 this.el_.setAttribute('aria-valuenow', volume); 7454 this.el_.setAttribute('aria-valuetext', volume + '%'); 7455 }; 7456 7457 return VolumeBar; 7458})(_sliderSliderJs2['default']); 7459 7460VolumeBar.prototype.options_ = { 7461 children: ['volumeLevel'], 7462 'barName': 'volumeLevel' 7463}; 7464 7465VolumeBar.prototype.playerEvent = 'volumechange'; 7466 7467_componentJs2['default'].registerComponent('VolumeBar', VolumeBar); 7468exports['default'] = VolumeBar; 7469module.exports = exports['default']; 7470 7471},{"../../component.js":66,"../../slider/slider.js":113,"../../utils/fn.js":133,"./volume-level.js":95}],94:[function(_dereq_,module,exports){ 7472/** 7473 * @file volume-control.js 7474 */ 7475'use strict'; 7476 7477exports.__esModule = true; 7478 7479function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7480 7481function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7482 7483function _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; } 7484 7485var _componentJs = _dereq_('../../component.js'); 7486 7487var _componentJs2 = _interopRequireDefault(_componentJs); 7488 7489// Required children 7490 7491var _volumeBarJs = _dereq_('./volume-bar.js'); 7492 7493var _volumeBarJs2 = _interopRequireDefault(_volumeBarJs); 7494 7495/** 7496 * The component for controlling the volume level 7497 * 7498 * @param {Player|Object} player 7499 * @param {Object=} options 7500 * @extends Component 7501 * @class VolumeControl 7502 */ 7503 7504var VolumeControl = (function (_Component) { 7505 _inherits(VolumeControl, _Component); 7506 7507 function VolumeControl(player, options) { 7508 _classCallCheck(this, VolumeControl); 7509 7510 _Component.call(this, player, options); 7511 7512 // hide volume controls when they're not supported by the current tech 7513 if (player.tech_ && player.tech_['featuresVolumeControl'] === false) { 7514 this.addClass('vjs-hidden'); 7515 } 7516 this.on(player, 'loadstart', function () { 7517 if (player.tech_['featuresVolumeControl'] === false) { 7518 this.addClass('vjs-hidden'); 7519 } else { 7520 this.removeClass('vjs-hidden'); 7521 } 7522 }); 7523 } 7524 7525 /** 7526 * Create the component's DOM element 7527 * 7528 * @return {Element} 7529 * @method createEl 7530 */ 7531 7532 VolumeControl.prototype.createEl = function createEl() { 7533 return _Component.prototype.createEl.call(this, 'div', { 7534 className: 'vjs-volume-control vjs-control' 7535 }); 7536 }; 7537 7538 return VolumeControl; 7539})(_componentJs2['default']); 7540 7541VolumeControl.prototype.options_ = { 7542 children: ['volumeBar'] 7543}; 7544 7545_componentJs2['default'].registerComponent('VolumeControl', VolumeControl); 7546exports['default'] = VolumeControl; 7547module.exports = exports['default']; 7548 7549},{"../../component.js":66,"./volume-bar.js":93}],95:[function(_dereq_,module,exports){ 7550/** 7551 * @file volume-level.js 7552 */ 7553'use strict'; 7554 7555exports.__esModule = true; 7556 7557function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7558 7559function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7560 7561function _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
7561onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 7562 7563var _componentJs = _dereq_('../../component.js'); 7564 7565var _componentJs2 = _interopRequireDefault(_componentJs); 7566 7567/** 7568 * Shows volume level 7569 * 7570 * @param {Player|Object} player 7571 * @param {Object=} options 7572 * @extends Component 7573 * @class VolumeLevel 7574 */ 7575 7576var VolumeLevel = (function (_Component) { 7577 _inherits(VolumeLevel, _Component); 7578 7579 function VolumeLevel() { 7580 _classCallCheck(this, VolumeLevel); 7581 7582 _Component.apply(this, arguments); 7583 } 7584 7585 /** 7586 * Create the component's DOM element 7587 * 7588 * @return {Element} 7589 * @method createEl 7590 */ 7591 7592 VolumeLevel.prototype.createEl = function createEl() { 7593 return _Component.prototype.createEl.call(this, 'div', { 7594 className: 'vjs-volume-level', 7595 innerHTML: '<span class="vjs-control-text"></span>' 7596 }); 7597 }; 7598 7599 return VolumeLevel; 7600})(_componentJs2['default']); 7601 7602_componentJs2['default'].registerComponent('VolumeLevel', VolumeLevel); 7603exports['default'] = VolumeLevel; 7604module.exports = exports['default']; 7605 7606},{"../../component.js":66}],96:[function(_dereq_,module,exports){ 7607/** 7608 * @file volume-menu-button.js 7609 */ 7610'use strict'; 7611 7612exports.__esModule = true; 7613 7614function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7615 7616function _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; } } 7617 7618function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7619 7620function _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; } 7621 7622var _utilsFnJs = _dereq_('../utils/fn.js'); 7623 7624var Fn = _interopRequireWildcard(_utilsFnJs); 7625 7626var _componentJs = _dereq_('../component.js'); 7627 7628var _componentJs2 = _interopRequireDefault(_componentJs); 7629 7630var _popupPopupJs = _dereq_('../popup/popup.js'); 7631 7632var _popupPopupJs2 = _interopRequireDefault(_popupPopupJs); 7633 7634var _popupPopupButtonJs = _dereq_('../popup/popup-button.js'); 7635 7636var _popupPopupButtonJs2 = _interopRequireDefault(_popupPopupButtonJs); 7637 7638var _muteToggleJs = _dereq_('./mute-toggle.js'); 7639 7640var _muteToggleJs2 = _interopRequireDefault(_muteToggleJs); 7641 7642var _volumeControlVolumeBarJs = _dereq_('./volume-control/volume-bar.js'); 7643 7644var _volumeControlVolumeBarJs2 = _interopRequireDefault(_volumeControlVolumeBarJs); 7645 7646var _globalDocument = _dereq_('global/document'); 7647 7648var _globalDocument2 = _interopRequireDefault(_globalDocument); 7649 7650/** 7651 * Button for volume popup 7652 * 7653 * @param {Player|Object} player 7654 * @param {Object=} options 7655 * @extends PopupButton 7656 * @class VolumeMenuButton 7657 */ 7658 7659var VolumeMenuButton = (function (_PopupButton) { 7660 _inherits(VolumeMenuButton, _PopupButton); 7661 7662 function VolumeMenuButton(player) { 7663 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 7664 7665 _classCallCheck(this, VolumeMenuButton); 7666 7667 // Default to inline 7668 if (options.inline === undefined) { 7669 options.inline = true; 7670 } 7671 7672 // If the vertical option isn't passed at all, default to true. 7673 if (options.vertical === undefined) { 7674 // If an inline volumeMenuButton is used, we should default to using 7675 // a horizontal slider for obvious reasons. 7676 if (options.inline) { 7677 options.vertical = false;
7678 } else { 7679 options.vertical = true; 7680 } 7681 } 7682 7683 // The vertical option needs to be set on the volumeBar as well, 7684 // since that will need to be passed along to the VolumeBar constructor 7685 options.volumeBar = options.volumeBar || {}; 7686 options.volumeBar.vertical = !!options.vertical; 7687 7688 _PopupButton.call(this, player, options); 7689 7690 // Same listeners as MuteToggle 7691 this.on(player, 'volumechange', this.volumeUpdate); 7692 this.on(player, 'loadstart', this.volumeUpdate); 7693 7694 // hide mute toggle if the current tech doesn't support volume control 7695 function updateVisibility() { 7696 if (player.tech_ && player.tech_['featuresVolumeControl'] === false) { 7697 this.addClass('vjs-hidden'); 7698 } else { 7699 this.removeClass('vjs-hidden'); 7700 } 7701 } 7702 7703 updateVisibility.call(this); 7704 this.on(player, 'loadstart', updateVisibility); 7705 7706 this.on(this.volumeBar, ['slideractive', 'focus'], function () { 7707 this.addClass('vjs-slider-active'); 7708 }); 7709 7710 this.on(this.volumeBar, ['sliderinactive', 'blur'], function () { 7711 this.removeClass('vjs-slider-active'); 7712 }); 7713 7714 this.on(this.volumeBar, ['focus'], function () { 7715 this.addClass('vjs-lock-showing'); 7716 }); 7717 7718 this.on(this.volumeBar, ['blur'], function () { 7719 this.removeClass('vjs-lock-showing'); 7720 }); 7721 } 7722 7723 /** 7724 * Allow sub components to stack CSS class names 7725 * 7726 * @return {String} The constructed class name 7727 * @method buildCSSClass 7728 */ 7729 7730 VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() { 7731 var orientationClass = ''; 7732 if (!!this.options_.vertical) { 7733 orientationClass = 'vjs-volume-menu-button-vertical'; 7734 } else { 7735 orientationClass = 'vjs-volume-menu-button-horizontal'; 7736 } 7737 7738 return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass; 7739 }; 7740 7741 /** 7742 * Allow sub components to stack CSS class names 7743 * 7744 * @return {Popup} The volume popup button 7745 * @method createPopup 7746 */ 7747 7748 VolumeMenuButton.prototype.createPopup = function createPopup() { 7749 var popup = new _popupPopupJs2['default'](this.player_, { 7750 contentElType: 'div' 7751 }); 7752 7753 var vb = new _volumeControlVolumeBarJs2['default'](this.player_, this.options_.volumeBar); 7754 7755 popup.addChild(vb); 7756 7757 this.volumeBar = vb; 7758 7759 this.attachVolumeBarEvents(); 7760 7761 return popup; 7762 }; 7763 7764 /** 7765 * Handle click on volume popup and calls super 7766 * 7767 * @method handleClick 7768 */ 7769 7770 VolumeMenuButton.prototype.handleClick = function handleClick() { 7771 _muteToggleJs2['default'].prototype.handleClick.call(this); 7772 _PopupButton.prototype.handleClick.call(this); 7773 }; 7774 7775 VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() { 7776 this.on(['mousedown', 'touchdown'], this.handleMouseDown); 7777 }; 7778 7779 VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) { 7780 this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove)); 7781 this.on(_globalDocument2['default'], ['mouseup', 'touchend'], this.handleMouseUp); 7782 }; 7783 7784 VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) { 7785 this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove)); 7786 }; 7787 7788 return VolumeMenuButton; 7789})(_popupPopupButtonJs2['default']); 7790 7791VolumeMenuButton.prototype.volumeUpdate = _muteToggleJs2['default'].prototype.update; 7792VolumeMenuButton.prototype.controlText_ = 'Mute'; 7793 7794_componentJs2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton); 7795exports['default'] = VolumeMenuButton; 7796module.exports = exports['default']; 7797 7798},{"../component.js":66,"../popup/popup-button.js":109,"../popup/popup.js":110,"../utils/fn.js":133,"./mute-toggle.js":70,"./volume-control/volume-bar.js":93,"global/document":1}],97:[function(_dereq_,module,exports){ 7799/** 7800 * @file error-display.js 7801 */ 7802'use strict'; 7803 7804exports.__esModule = true; 7805 7806function _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; } } 7807 7808function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7809 7810function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 7811 7812function _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
7812onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 7813 7814var _component = _dereq_('./component'); 7815 7816var _component2 = _interopRequireDefault(_component); 7817 7818var _modalDialog = _dereq_('./modal-dialog'); 7819 7820var _modalDialog2 = _interopRequireDefault(_modalDialog); 7821 7822var _utilsDom = _dereq_('./utils/dom'); 7823 7824var Dom = _interopRequireWildcard(_utilsDom); 7825 7826var _utilsMergeOptions = _dereq_('./utils/merge-options'); 7827 7828var _utilsMergeOptions2 = _interopRequireDefault(_utilsMergeOptions); 7829 7830/** 7831 * Display that an error has occurred making the video unplayable. 7832 * 7833 * @extends ModalDialog 7834 * @class ErrorDisplay 7835 */ 7836 7837var ErrorDisplay = (function (_ModalDialog) { 7838 _inherits(ErrorDisplay, _ModalDialog); 7839 7840 /** 7841 * Constructor for error display modal. 7842 * 7843 * @param {Player} player 7844 * @param {Object} [options] 7845 */ 7846 7847 function ErrorDisplay(player, options) { 7848 _classCallCheck(this, ErrorDisplay); 7849 7850 _ModalDialog.call(this, player, options); 7851 this.on(player, 'error', this.open); 7852 } 7853 7854 /** 7855 * Include the old class for backward-compatibility. 7856 * 7857 * This can be removed in 6.0. 7858 * 7859 * @method buildCSSClass 7860 * @deprecated 7861 * @return {String} 7862 */ 7863 7864 ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() { 7865 return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this); 7866 }; 7867 7868 /** 7869 * Generates the modal content based on the player error. 7870 * 7871 * @return {String|Null} 7872 */ 7873 7874 ErrorDisplay.prototype.content = function content() { 7875 var error = this.player().error(); 7876 return error ? this.localize(error.message) : ''; 7877 }; 7878 7879 return ErrorDisplay; 7880})(_modalDialog2['default']); 7881 7882ErrorDisplay.prototype.options_ = _utilsMergeOptions2['default'](_modalDialog2['default'].prototype.options_, { 7883 fillAlways: true, 7884 temporary: false, 7885 uncloseable: true 7886}); 7887 7888_component2['default'].registerComponent('ErrorDisplay', ErrorDisplay); 7889exports['default'] = ErrorDisplay; 7890module.exports = exports['default']; 7891 7892},{"./component":66,"./modal-dialog":106,"./utils/dom":131,"./utils/merge-options":137}],98:[function(_dereq_,module,exports){ 7893/** 7894 * @file event-target.js 7895 */ 7896'use strict'; 7897 7898exports.__esModule = true; 7899 7900function _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; } } 7901 7902var _utilsEventsJs = _dereq_('./utils/events.js'); 7903 7904var Events = _interopRequireWildcard(_utilsEventsJs); 7905 7906var EventTarget = function EventTarget() {}; 7907 7908EventTarget.prototype.allowedEvents_ = {}; 7909 7910EventTarget.prototype.on = function (type, fn) { 7911 // Remove the addEventListener alias before calling Events.on 7912 // so we don't get into an infinite type loop 7913 var ael = this.addEventListener; 7914 this.addEventListener = Function.prototype; 7915 Events.on(this, type, fn); 7916 this.addEventListener = ael; 7917}; 7918EventTarget.prototype.addEventListener = EventTarget.prototype.on; 7919 7920EventTarget.prototype.off = function (type, fn) { 7921 Events.off(this, type, fn); 7922}; 7923EventTarget.prototype.removeEventListener = EventTarget.prototype.off; 7924 7925EventTarget.prototype.one = function (type, fn) { 7926 Events.one(this, type, fn); 7927}; 7928 7929EventTarget.prototype.trigger = function (event) { 7930 var type = event.type || event; 7931 7932 if (typeof event === 'string') { 7933 event = { 7934 type: type 7935 }; 7936 } 7937 event = Events.fixEvent(event); 7938 7939 if (this.allowedEvents_[type] && this['on' + type]) { 7940 this['on' + type](event); 7941 } 7942 7943 Events.trigger(this, event); 7944}; 7945// The standard DOM EventTarget.dispatchEvent() is aliased to trigger() 7946EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger; 7947 7948exports['default'] = EventTarget; 7949module.exports = exports['default']; 7950 7951},{"./utils/events.js":132}],99:[function(_dereq_,module,exports){ 7952'use strict'; 7953 7954exports.__esModule = true; 7955 7956function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 7957 7958var _utilsLog = _dereq_('./utils/log'); 7959 7960var _utilsLog2 = _interopRequireDefault(_utilsLog); 7961 7962/* 7963 * @file extend.js 7964 * 7965 * A combination of node inherits and babel's inherits (after transpile). 7966 * Both work the same but node adds `super_` to the subClass 7967 * and Bable adds the superClass as __proto__. Both seem useful. 7968 */ 7969var _inherits = function _inherits(subClass, superClass) { 7970 if (typeof superClass !== 'function' && superClass !== null) { 7971 throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); 7972 } 7973 7974 subClass.prototype = Object.create(superClass && superClass.prototype, { 7975 constructor: { 7976 value: subClass, 7977 enumerable: false, 7978 writable: true, 7979 configurable: true 7980 } 7981 }); 7982 7983 if (superClass) { 7984 // node 7985 subClass.super_ = superClass; 7986 } 7987}; 7988 7989/*
7990 * Function for subclassing using the same inheritance that 7991 * videojs uses internally 7992 * ```js 7993 * var Button = videojs.getComponent('Button'); 7994 * ``` 7995 * ```js 7996 * var MyButton = videojs.extend(Button, { 7997 * constructor: function(player, options) { 7998 * Button.call(this, player, options); 7999 * }, 8000 * onClick: function() { 8001 * // doSomething 8002 * } 8003 * }); 8004 * ``` 8005 */ 8006var extendFn = function extendFn(superClass) { 8007 var subClassMethods = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 8008 8009 var subClass = function subClass() { 8010 superClass.apply(this, arguments); 8011 }; 8012 var methods = {}; 8013 8014 if (typeof subClassMethods === 'object') { 8015 if (typeof subClassMethods.init === 'function') { 8016 _utilsLog2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.'); 8017 subClassMethods.constructor = subClassMethods.init; 8018 } 8019 if (subClassMethods.constructor !== Object.prototype.constructor) { 8020 subClass = subClassMethods.constructor; 8021 } 8022 methods = subClassMethods; 8023 } else if (typeof subClassMethods === 'function') { 8024 subClass = subClassMethods; 8025 } 8026 8027 _inherits(subClass, superClass); 8028 8029 // Extend subObj's prototype with functions and other properties from props 8030 for (var name in methods) { 8031 if (methods.hasOwnProperty(name)) { 8032 subClass.prototype[name] = methods[name]; 8033 } 8034 } 8035 8036 return subClass; 8037}; 8038 8039exports['default'] = extendFn; 8040module.exports = exports['default']; 8041 8042},{"./utils/log":136}],100:[function(_dereq_,module,exports){ 8043/** 8044 * @file fullscreen-api.js 8045 */ 8046'use strict'; 8047 8048exports.__esModule = true; 8049 8050function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8051 8052var _globalDocument = _dereq_('global/document'); 8053 8054var _globalDocument2 = _interopRequireDefault(_globalDocument); 8055 8056/* 8057 * Store the browser-specific methods for the fullscreen API 8058 * @type {Object|undefined} 8059 * @private 8060 */ 8061var FullscreenApi = {}; 8062 8063// browser API methods 8064// map approach from Screenful.js - https://github.com/sindresorhus/screenfull.js 8065var apiMap = [ 8066// Spec: https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html 8067['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'], 8068// WebKit 8069['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'], 8070// Old WebKit (Safari 5.1) 8071['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'], 8072// Mozilla 8073['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'], 8074// Microsoft 8075['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']]; 8076 8077var specApi = apiMap[0]; 8078var browserApi = undefined; 8079 8080// determine the supported set of functions 8081for (var i = 0; i < apiMap.length; i++) { 8082 // check for exitFullscreen function 8083 if (apiMap[i][1] in _globalDocument2['default']) { 8084 browserApi = apiMap[i]; 8085 break; 8086 } 8087} 8088 8089// map the browser API names to the spec API names 8090if (browserApi) { 8091 for (var i = 0; i < browserApi.length; i++) { 8092 FullscreenApi[specApi[i]] = browserApi[i]; 8093 } 8094} 8095 8096exports['default'] = FullscreenApi; 8097module.exports = exports['default']; 8098 8099},{"global/document":1}],101:[function(_dereq_,module,exports){ 8100/** 8101 * @file loading-spinner.js 8102 */ 8103'use strict'; 8104 8105exports.__esModule = true; 8106 8107function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8108 8109function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 8110 8111function _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
8111onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 8112 8113var _component = _dereq_('./component'); 8114 8115var _component2 = _interopRequireDefault(_component); 8116 8117/* Loading Spinner 8118================================================================================ */ 8119/** 8120 * Loading spinner for waiting events 8121 * 8122 * @extends Component 8123 * @class LoadingSpinner 8124 */ 8125 8126var LoadingSpinner = (function (_Component) { 8127 _inherits(LoadingSpinner, _Component); 8128 8129 function LoadingSpinner() { 8130 _classCallCheck(this, LoadingSpinner); 8131 8132 _Component.apply(this, arguments); 8133 } 8134 8135 /** 8136 * Create the component's DOM element 8137 * 8138 * @method createEl 8139 */ 8140 8141 LoadingSpinner.prototype.createEl = function createEl() { 8142 return _Component.prototype.createEl.call(this, 'div', { 8143 className: 'vjs-loading-spinner' 8144 }); 8145 }; 8146 8147 return LoadingSpinner; 8148})(_component2['default']); 8149 8150_component2['default'].registerComponent('LoadingSpinner', LoadingSpinner); 8151exports['default'] = LoadingSpinner; 8152module.exports = exports['default']; 8153 8154},{"./component":66}],102:[function(_dereq_,module,exports){ 8155/** 8156 * @file media-error.js 8157 */ 8158'use strict'; 8159 8160exports.__esModule = true; 8161 8162function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8163 8164var _objectAssign = _dereq_('object.assign'); 8165 8166var _objectAssign2 = _interopRequireDefault(_objectAssign); 8167 8168/* 8169 * Custom MediaError to mimic the HTML5 MediaError 8170 * 8171 * @param {Number} code The media error code 8172 */ 8173var MediaError = function MediaError(code) { 8174 if (typeof code === 'number') { 8175 this.code = code; 8176 } else if (typeof code === 'string') {
8177 // default code is zero, so this is a custom error 8178 this.message = code; 8179 } else if (typeof code === 'object') { 8180 // object 8181 _objectAssign2['default'](this, code); 8182 } 8183 8184 if (!this.message) { 8185 this.message = MediaError.defaultMessages[this.code] || ''; 8186 } 8187}; 8188 8189/* 8190 * The error code that refers two one of the defined 8191 * MediaError types 8192 * 8193 * @type {Number} 8194 */ 8195MediaError.prototype.code = 0; 8196 8197/* 8198 * An optional message to be shown with the error. 8199 * Message is not part of the HTML5 video spec 8200 * but allows for more informative custom errors. 8201 * 8202 * @type {String} 8203 */ 8204MediaError.prototype.message = ''; 8205 8206/* 8207 * An optional status code that can be set by plugins 8208 * to allow even more detail about the error. 8209 * For example the HLS plugin might provide the specific 8210 * HTTP status code that was returned when the error 8211 * occurred, then allowing a custom error overlay 8212 * to display more information. 8213 * 8214 * @type {Array} 8215 */ 8216MediaError.prototype.status = null; 8217 8218MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', // = 0 8219'MEDIA_ERR_ABORTED', // = 1 8220'MEDIA_ERR_NETWORK', // = 2 8221'MEDIA_ERR_DECODE', // = 3 8222'MEDIA_ERR_SRC_NOT_SUPPORTED', // = 4 8223'MEDIA_ERR_ENCRYPTED' // = 5 8224]; 8225 8226MediaError.defaultMessages = { 8227 1: 'You aborted the media playback', 8228 2: 'A network error caused the media download to fail part-way.', 8229 3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.', 8230 4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.', 8231 5: 'The media is encrypted and we do not have the keys to decrypt it.' 8232}; 8233 8234// Add types as properties on MediaError 8235// e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4; 8236for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) { 8237 MediaError[MediaError.errorTypes[errNum]] = errNum; 8238 // values should be accessible on both the class and instance 8239 MediaError.prototype[MediaError.errorTypes[errNum]] = errNum; 8240} 8241 8242exports['default'] = MediaError; 8243module.exports = exports['default']; 8244 8245},{"object.assign":45}],103:[function(_dereq_,module,exports){ 8246/** 8247 * @file menu-button.js 8248 */ 8249'use strict'; 8250 8251exports.__esModule = true; 8252 8253function _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; } } 8254 8255function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8256 8257function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 8258 8259function _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; } 8260 8261var _clickableComponentJs = _dereq_('../clickable-component.js'); 8262 8263var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs); 8264 8265var _componentJs = _dereq_('../component.js'); 8266 8267var _componentJs2 = _interopRequireDefault(_componentJs); 8268 8269var _menuJs = _dereq_('./menu.js'); 8270 8271var _menuJs2 = _interopRequireDefault(_menuJs); 8272 8273var _utilsDomJs = _dereq_('../utils/dom.js'); 8274 8275var Dom = _interopRequireWildcard(_utilsDomJs); 8276 8277var _utilsFnJs = _dereq_('../utils/fn.js'); 8278 8279var Fn = _interopRequireWildcard(_utilsFnJs); 8280 8281var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js'); 8282 8283var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs); 8284 8285/** 8286 * A button class with a popup menu 8287 * 8288 * @param {Player|Object} player 8289 * @param {Object=} options 8290 * @extends Button 8291 * @class MenuButton 8292 */ 8293 8294var MenuButton = (function (_ClickableComponent) { 8295 _inherits(MenuButton, _ClickableComponent); 8296 8297 function MenuButton(player) { 8298 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 8299 8300 _classCallCheck(this, MenuButton); 8301 8302 _ClickableComponent.call(this, player, options); 8303 8304 this.update(); 8305 8306 this.el_.setAttribute('aria-haspopup', true); 8307 this.el_.setAttribute('role', 'menuitem'); 8308 this.on('keydown', this.handleSubmenuKeyPress); 8309 } 8310 8311 /** 8312 * Update menu 8313 * 8314 * @method update 8315 */ 8316
8317 MenuButton.prototype.update = function update() { 8318 var menu = this.createMenu(); 8319 8320 if (this.menu) { 8321 this.removeChild(this.menu); 8322 } 8323 8324 this.menu = menu; 8325 this.addChild(menu); 8326 8327 /** 8328 * Track the state of the menu button 8329 * 8330 * @type {Boolean} 8331 * @private 8332 */ 8333 this.buttonPressed_ = false; 8334 this.el_.setAttribute('aria-expanded', false); 8335 8336 if (this.items && this.items.length === 0) { 8337 this.hide(); 8338 } else if (this.items && this.items.length > 1) { 8339 this.show(); 8340 } 8341 }; 8342 8343 /** 8344 * Create menu 8345 * 8346 * @return {Menu} The constructed menu 8347 * @method createMenu 8348 */ 8349 8350 MenuButton.prototype.createMenu = function createMenu() { 8351 var menu = new _menuJs2['default'](this.player_); 8352 8353 // Add a title list item to the top 8354 if (this.options_.title) { 8355 menu.contentEl().appendChild(Dom.createEl('li', { 8356 className: 'vjs-menu-title', 8357 innerHTML: _utilsToTitleCaseJs2['default'](this.options_.title), 8358 tabIndex: -1 8359 })); 8360 } 8361 8362 this.items = this['createItems'](); 8363 8364 if (this.items) { 8365 // Add menu items to the menu 8366 for (var i = 0; i < this.items.length; i++) { 8367 menu.addItem(this.items[i]); 8368 } 8369 } 8370 8371 return menu; 8372 }; 8373 8374 /** 8375 * Create the list of menu items. Specific to each subclass. 8376 * 8377 * @method createItems 8378 */ 8379 8380 MenuButton.prototype.createItems = function createItems() {}; 8381 8382 /** 8383 * Create the component's DOM element 8384 * 8385 * @return {Element} 8386 * @method createEl 8387 */ 8388 8389 MenuButton.prototype.createEl = function createEl() { 8390 return _ClickableComponent.prototype.createEl.call(this, 'div', { 8391 className: this.buildCSSClass() 8392 }); 8393 }; 8394 8395 /** 8396 * Allow sub components to stack CSS class names 8397 * 8398 * @return {String} The constructed class name 8399 * @method buildCSSClass 8400 */ 8401 8402 MenuButton.prototype.buildCSSClass = function buildCSSClass() { 8403 var menuButtonClass = 'vjs-menu-button'; 8404 8405 // If the inline option is passed, we want to use different styles altogether. 8406 if (this.options_.inline === true) { 8407 menuButtonClass += '-inline'; 8408 } else { 8409 menuButtonClass += '-popup'; 8410 } 8411 8412 return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this); 8413 }; 8414 8415 /** 8416 * When you click the button it adds focus, which 8417 * will show the menu indefinitely. 8418 * So we'll remove focus when the mouse leaves the button. 8419 * Focus is needed for tab navigation. 8420 * Allow sub components to stack CSS class names 8421 * 8422 * @method handleClick 8423 */ 8424 8425 MenuButton.prototype.handleClick = function handleClick() { 8426 this.one('mouseout', Fn.bind(this, function () { 8427 this.menu.unlockShowing(); 8428 this.el_.blur(); 8429 })); 8430 if (this.buttonPressed_) { 8431 this.unpressButton(); 8432 } else { 8433 this.pressButton(); 8434 } 8435 }; 8436 8437 /** 8438 * Handle key press on menu 8439 * 8440 * @param {Object} event Key press event 8441 * @method handleKeyPress 8442 */ 8443 8444 MenuButton.prototype.handleKeyPress = function handleKeyPress(event) { 8445 8446 // Escape (27) key or Tab (9) key unpress the 'button' 8447 if (event.which === 27 || event.which === 9) { 8448 if (this.buttonPressed_) { 8449 this.unpressButton(); 8450 } 8451 // Don't preventDefault for Tab key - we still want to lose focus 8452 if (event.which !== 9) { 8453 event.preventDefault(); 8454 } 8455 // Up (38) key or Down (40) key press the 'button' 8456 } else if (event.which === 38 || event.which === 40) { 8457 if (!this.buttonPressed_) { 8458 this.pressButton(); 8459 event.preventDefault(); 8460 } 8461 } else { 8462 _ClickableComponent.prototype.handleKeyPress.call(this, event); 8463 } 8464 }; 8465 8466 /** 8467 * Handle key press on submenu 8468 * 8469 * @param {Object} event Key press event 8470 * @method handleSubmenuKeyPress 8471 */ 8472 8473 MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) { 8474 8475 // Escape (27) key or Tab (9) key unpress the 'button' 8476 if (event.which === 27 || event.which === 9) { 8477 if (this.buttonPressed_) { 8478 this.unpressButton(); 8479 } 8480 // Don't preventDefault for Tab key - we still want to lose focus 8481 if (event.which !== 9) { 8482 event.preventDefault(); 8483 } 8484 } 8485 }; 8486 8487 /** 8488 * Makes changes based on button pressed 8489 * 8490 * @method pressButton 8491 */ 8492 8493 MenuButton.prototype.pressButton = function pressButton() { 8494 this.buttonPressed_ = true; 8495 this.menu.lockShowing(); 8496 this.el_.setAttribute('aria-expanded', true); 8497 this.menu.focus(); // set the focus into the submenu 8498 }; 8499 8500 /** 8501 * Makes changes based on button unpressed 8502 * 8503 * @method unpressButton 8504 */ 8505 8506 MenuButton.prototype.unpressButton = function unpressButton() { 8507 this.buttonPressed_ = false;
8508 this.menu.unlockShowing(); 8509 this.el_.setAttribute('aria-expanded', false); 8510 this.el_.focus(); // Set focus back to this menu button 8511 }; 8512 8513 return MenuButton; 8514})(_clickableComponentJs2['default']); 8515 8516_componentJs2['default'].registerComponent('MenuButton', MenuButton); 8517exports['default'] = MenuButton; 8518module.exports = exports['default']; 8519 8520},{"../clickable-component.js":64,"../component.js":66,"../utils/dom.js":131,"../utils/fn.js":133,"../utils/to-title-case.js":140,"./menu.js":105}],104:[function(_dereq_,module,exports){ 8521/** 8522 * @file menu-item.js 8523 */ 8524'use strict'; 8525 8526exports.__esModule = true; 8527 8528function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8529 8530function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 8531 8532function _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; } 8533 8534var _clickableComponentJs = _dereq_('../clickable-component.js'); 8535 8536var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs); 8537 8538var _componentJs = _dereq_('../component.js'); 8539 8540var _componentJs2 = _interopRequireDefault(_componentJs); 8541 8542var _objectAssign = _dereq_('object.assign'); 8543 8544var _objectAssign2 = _interopRequireDefault(_objectAssign); 8545 8546/** 8547 * The component for a menu item. `<li>` 8548 * 8549 * @param {Player|Object} player 8550 * @param {Object=} options 8551 * @extends Button 8552 * @class MenuItem 8553 */ 8554 8555var MenuItem = (function (_ClickableComponent) { 8556 _inherits(MenuItem, _ClickableComponent); 8557 8558 function MenuItem(player, options) { 8559 _classCallCheck(this, MenuItem); 8560 8561 _ClickableComponent.call(this, player, options); 8562 8563 this.selectable = options['selectable']; 8564 8565 this.selected(options['selected']); 8566 8567 if (this.selectable) { 8568 // TODO: May need to be either menuitemcheckbox or menuitemradio, 8569 // and may need logical grouping of menu items. 8570 this.el_.setAttribute('role', 'menuitemcheckbox'); 8571 } else { 8572 this.el_.setAttribute('role', 'menuitem'); 8573 } 8574 } 8575 8576 /** 8577 * Create the component's DOM element 8578 * 8579 * @param {String=} type Desc 8580 * @param {Object=} props Desc 8581 * @return {Element} 8582 * @method createEl 8583 */ 8584 8585 MenuItem.prototype.createEl = function createEl(type, props, attrs) { 8586 return _ClickableComponent.prototype.createEl.call(this, 'li', _objectAssign2['default']({ 8587 className: 'vjs-menu-item', 8588 innerHTML: this.localize(this.options_['label']), 8589 tabIndex: -1 8590 }, props), attrs); 8591 }; 8592 8593 /** 8594 * Handle a click on the menu item, and set it to selected 8595 * 8596 * @method handleClick 8597 */ 8598 8599 MenuItem.prototype.handleClick = function handleClick() { 8600 this.selected(true); 8601 }; 8602 8603 /** 8604 * Set this menu item as selected or not 8605 * 8606 * @param {Boolean} selected 8607 * @method selected 8608 */ 8609 8610 MenuItem.prototype.selected = function selected(_selected) { 8611 if (this.selectable) { 8612 if (_selected) { 8613 this.addClass('vjs-selected'); 8614 this.el_.setAttribute('aria-checked', true); 8615 // aria-checked isn't fully supported by browsers/screen readers, 8616 // so indicate selected state to screen reader in the control text. 8617 this.controlText(', selected'); 8618 } else { 8619 this.removeClass('vjs-selected'); 8620 this.el_.setAttribute('aria-checked', false); 8621 // Indicate un-selected state to screen reader 8622 // Note that a space clears out the selected state text 8623 this.controlText(' '); 8624 } 8625 } 8626 }; 8627 8628 return MenuItem; 8629})(_clickableComponentJs2['default']); 8630 8631_componentJs2['default'].registerComponent('MenuItem', MenuItem); 8632exports['default'] = MenuItem; 8633module.exports = exports['default']; 8634 8635},{"../clickable-component.js":64,"../component.js":66,"object.assign":45}],105:[function(_dereq_,module,exports){ 8636/** 8637 * @file menu.js 8638 */ 8639'use strict'; 8640 8641exports.__esModule = true; 8642 8643function _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; } } 8644 8645function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8646 8647function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 8648 8649function _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
8649onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 8650 8651var _componentJs = _dereq_('../component.js'); 8652 8653var _componentJs2 = _interopRequireDefault(_componentJs); 8654 8655var _utilsDomJs = _dereq_('../utils/dom.js'); 8656 8657var Dom = _interopRequireWildcard(_utilsDomJs); 8658 8659var _utilsFnJs = _dereq_('../utils/fn.js'); 8660 8661var Fn = _interopRequireWildcard(_utilsFnJs); 8662 8663var _utilsEventsJs = _dereq_('../utils/events.js'); 8664 8665var Events = _interopRequireWildcard(_utilsEventsJs); 8666 8667/** 8668 * The Menu component is used to build pop up menus, including subtitle and 8669 * captions selection menus. 8670 * 8671 * @extends Component 8672 * @class Menu 8673 */ 8674 8675var Menu = (function (_Component) { 8676 _inherits(Menu, _Component); 8677 8678 function Menu(player, options) { 8679 _classCallCheck(this, Menu); 8680 8681 _Component.call(this, player, options); 8682 8683 this.focusedChild_ = -1; 8684 8685 this.on('keydown', this.handleKeyPress); 8686 } 8687 8688 /** 8689 * Add a menu item to the menu 8690 * 8691 * @param {Object|String} component Component or component type to add 8692 * @method addItem 8693 */ 8694 8695 Menu.prototype.addItem = function addItem(component) { 8696 this.addChild(component); 8697 component.on('click', Fn.bind(this, function () { 8698 this.unlockShowing(); 8699 //TODO: Need to set keyboard focus back to the menuButton 8700 })); 8701 }; 8702 8703 /** 8704 * Create the component's DOM element 8705 * 8706 * @return {Element} 8707 * @method createEl 8708 */ 8709 8710 Menu.prototype.createEl = function createEl() { 8711 var contentElType = this.options_.contentElType || 'ul'; 8712 this.contentEl_ = Dom.createEl(contentElType, { 8713 className: 'vjs-menu-content' 8714 }); 8715 this.contentEl_.setAttribute('role', 'menu'); 8716 var el = _Component.prototype.createEl.call(this, 'div', { 8717 append: this.contentEl_, 8718 className: 'vjs-menu' 8719 }); 8720 el.setAttribute('role', 'presentation'); 8721 el.appendChild(this.contentEl_); 8722 8723 // Prevent clicks from bubbling up. Needed for Menu Buttons, 8724 // where a click on the parent is significant 8725 Events.on(el, 'click', function (event) { 8726 event.preventDefault(); 8727 event.stopImmediatePropagation(); 8728 }); 8729 8730 return el; 8731 }; 8732 8733 /** 8734 * Handle key press for menu 8735 * 8736 * @param {Object} event Event object 8737 * @method handleKeyPress 8738 */ 8739 8740 Menu.prototype.handleKeyPress = function handleKeyPress(event) { 8741 if (event.which === 37 || event.which === 40) { 8742 // Left and Down Arrows 8743 event.preventDefault(); 8744 this.stepForward(); 8745 } else if (event.which === 38 || event.which === 39) { 8746 // Up and Right Arrows 8747 event.preventDefault(); 8748 this.stepBack(); 8749 } 8750 }; 8751 8752 /** 8753 * Move to next (lower) menu item for keyboard users 8754 * 8755 * @method stepForward 8756 */ 8757 8758 Menu.prototype.stepForward = function stepForward() { 8759 var stepChild = 0; 8760 8761 if (this.focusedChild_ !== undefined) { 8762 stepChild = this.focusedChild_ + 1; 8763 } 8764 this.focus(stepChild); 8765 }; 8766 8767 /** 8768 * Move to previous (higher) menu item for keyboard users 8769 * 8770 * @method stepBack 8771 */ 8772 8773 Menu.prototype.stepBack = function stepBack() { 8774 var stepChild = 0; 8775 8776 if (this.focusedChild_ !== undefined) { 8777 stepChild = this.focusedChild_ - 1; 8778 } 8779 this.focus(stepChild); 8780 }; 8781 8782 /** 8783 * Set focus on a menu item in the menu 8784 * 8785 * @param {Object|String} item Index of child item set focus on 8786 * @method focus 8787 */ 8788 8789 Menu.prototype.focus = function focus() { 8790 var item = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0]; 8791 8792 var children = this.children(); 8793 8794 if (children.length > 0) { 8795 if (item < 0) { 8796 item = 0; 8797 } else if (item >= children.length) { 8798 item = children.length - 1; 8799 } 8800 8801 this.focusedChild_ = item; 8802 8803 children[item].el_.focus(); 8804 } 8805 }; 8806 8807 return Menu; 8808})(_componentJs2['default']); 8809 8810_componentJs2['default'].registerComponent('Menu', Menu); 8811exports['default'] = Menu; 8812module.exports = exports['default']; 8813 8814},{"../component.js":66,"../utils/dom.js":131,"../utils/events.js":132,"../utils/fn.js":133}],106:[function(_dereq_,module,exports){ 8815/** 8816 * @file modal-dialog.js 8817 */ 8818'use strict'; 8819 8820exports.__esModule = true; 8821 8822function _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; } } 8823 8824function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 8825 8826function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 8827 8828function _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
8828onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 8829 8830var _globalDocument = _dereq_('global/document'); 8831 8832var _globalDocument2 = _interopRequireDefault(_globalDocument); 8833 8834var _utilsDom = _dereq_('./utils/dom'); 8835 8836var Dom = _interopRequireWildcard(_utilsDom); 8837 8838var _utilsFn = _dereq_('./utils/fn'); 8839 8840var Fn = _interopRequireWildcard(_utilsFn); 8841 8842var _utilsLog = _dereq_('./utils/log'); 8843 8844var _utilsLog2 = _interopRequireDefault(_utilsLog); 8845 8846var _component = _dereq_('./component'); 8847 8848var _component2 = _interopRequireDefault(_component); 8849 8850var _closeButton = _dereq_('./close-button'); 8851 8852var _closeButton2 = _interopRequireDefault(_closeButton); 8853 8854var MODAL_CLASS_NAME = 'vjs-modal-dialog'; 8855var ESC = 27; 8856 8857/** 8858 * The `ModalDialog` displays over the video and its controls, which blocks 8859 * interaction with the player until it is closed. 8860 * 8861 * Modal dialogs include a "Close" button and will close when that button 8862 * is activated - or when ESC is pressed anywhere. 8863 * 8864 * @extends Component 8865 * @class ModalDialog 8866 */ 8867 8868var ModalDialog = (function (_Component) { 8869 _inherits(ModalDialog, _Component); 8870 8871 /** 8872 * Constructor for modals. 8873 * 8874 * @param {Player} player 8875 * @param {Object} [options] 8876 * @param {Mixed} [options.content=undefined] 8877 * Provide customized content for this modal. 8878 * 8879 * @param {String} [options.description] 8880 * A text description for the modal, primarily for accessibility. 8881 * 8882 * @param {Boolean} [options.fillAlways=false] 8883 * Normally, modals are automatically filled only the first time 8884 * they open. This tells the modal to refresh its content 8885 * every time it opens. 8886 * 8887 * @param {String} [options.label] 8888 * A text label for the modal, primarily for accessibility. 8889 * 8890 * @param {Boolean} [options.temporary=true] 8891 * If `true`, the modal can only be opened once; it will be 8892 * disposed as soon as it's closed. 8893 * 8894 * @param {Boolean} [options.uncloseable=false] 8895 * If `true`, the user will not be able to close the modal 8896 * through the UI in the normal ways. Programmatic closing is 8897 * still possible. 8898 * 8899 */ 8900 8901 function ModalDialog(player, options) { 8902 _classCallCheck(this, ModalDialog); 8903 8904 _Component.call(this, player, options); 8905 this.opened_ = this.hasBeenOpened_ = this.hasBeenFilled_ = false; 8906 8907 this.closeable(!this.options_.uncloseable); 8908 this.content(this.options_.content); 8909 8910 // Make sure the contentEl is defined AFTER any children are initialized 8911 // because we only want the contents of the modal in the contentEl 8912 // (not the UI elements like the close button). 8913 this.contentEl_ = Dom.createEl('div', { 8914 className: MODAL_CLASS_NAME + '-content' 8915 }, { 8916 role: 'document' 8917 }); 8918 8919 this.descEl_ = Dom.createEl('p', { 8920 className: MODAL_CLASS_NAME + '-description vjs-offscreen', 8921 id: this.el().getAttribute('aria-describedby') 8922 }); 8923 8924 Dom.textContent(this.descEl_, this.description()); 8925 this.el_.appendChild(this.descEl_); 8926 this.el_.appendChild(this.contentEl_); 8927 } 8928 8929 /* 8930 * Modal dialog default options. 8931 * 8932 * @type {Object} 8933 * @private 8934 */ 8935 8936 /**
8937 * Create the modal's DOM element 8938 * 8939 * @method createEl 8940 * @return {Element} 8941 */ 8942 8943 ModalDialog.prototype.createEl = function createEl() { 8944 return _Component.prototype.createEl.call(this, 'div', { 8945 className: this.buildCSSClass(), 8946 tabIndex: -1 8947 }, { 8948 'aria-describedby': this.id() + '_description', 8949 'aria-hidden': 'true', 8950 'aria-label': this.label(), 8951 role: 'dialog' 8952 }); 8953 }; 8954 8955 /** 8956 * Build the modal's CSS class. 8957 * 8958 * @method buildCSSClass 8959 * @return {String} 8960 */ 8961 8962 ModalDialog.prototype.buildCSSClass = function buildCSSClass() { 8963 return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this); 8964 }; 8965 8966 /** 8967 * Handles key presses on the document, looking for ESC, which closes 8968 * the modal. 8969 * 8970 * @method handleKeyPress 8971 * @param {Event} e 8972 */ 8973 8974 ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) { 8975 if (e.which === ESC && this.closeable()) { 8976 this.close(); 8977 } 8978 }; 8979 8980 /** 8981 * Returns the label string for this modal. Primarily used for accessibility. 8982 * 8983 * @return {String} 8984 */ 8985 8986 ModalDialog.prototype.label = function label() { 8987 return this.options_.label || this.localize('Modal Window'); 8988 }; 8989 8990 /** 8991 * Returns the description string for this modal. Primarily used for 8992 * accessibility. 8993 * 8994 * @return {String} 8995 */ 8996 8997 ModalDialog.prototype.description = function description() { 8998 var desc = this.options_.description || this.localize('This is a modal window.'); 8999 9000 // Append a universal closeability message if the modal is closeable. 9001 if (this.closeable()) { 9002 desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.'); 9003 } 9004 9005 return desc; 9006 }; 9007 9008 /** 9009 * Opens the modal. 9010 * 9011 * @method open 9012 * @return {ModalDialog} 9013 */ 9014 9015 ModalDialog.prototype.open = function open() { 9016 if (!this.opened_) { 9017 var player = this.player(); 9018 9019 this.trigger('beforemodalopen'); 9020 this.opened_ = true; 9021 9022 // Fill content if the modal has never opened before and 9023 // never been filled. 9024 if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) { 9025 this.fill(); 9026 } 9027 9028 // If the player was playing, pause it and take note of its previously 9029 // playing state. 9030 this.wasPlaying_ = !player.paused(); 9031 9032 if (this.wasPlaying_) { 9033 player.pause(); 9034 } 9035 9036 if (this.closeable()) { 9037 this.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); 9038 } 9039 9040 player.controls(false); 9041 this.show(); 9042 this.el().setAttribute('aria-hidden', 'false'); 9043 this.trigger('modalopen'); 9044 this.hasBeenOpened_ = true; 9045 } 9046 return this; 9047 }; 9048 9049 /** 9050 * Whether or not the modal is opened currently. 9051 * 9052 * @method opened 9053 * @param {Boolean} [value] 9054 * If given, it will open (`true`) or close (`false`) the modal. 9055 * 9056 * @return {Boolean} 9057 */ 9058 9059 ModalDialog.prototype.opened = function opened(value) { 9060 if (typeof value === 'boolean') { 9061 this[value ? 'open' : 'close'](); 9062 } 9063 return this.opened_; 9064 }; 9065 9066 /** 9067 * Closes the modal. 9068 * 9069 * @method close 9070 * @return {ModalDialog} 9071 */ 9072 9073 ModalDialog.prototype.close = function close() { 9074 if (this.opened_) { 9075 var player = this.player(); 9076 9077 this.trigger('beforemodalclose'); 9078 this.opened_ = false; 9079 9080 if (this.wasPlaying_) { 9081 player.play(); 9082 } 9083 9084 if (this.closeable()) { 9085 this.off(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); 9086 } 9087 9088 player.controls(true); 9089 this.hide(); 9090 this.el().setAttribute('aria-hidden', 'true'); 9091 this.trigger('modalclose'); 9092 9093 if (this.options_.temporary) { 9094 this.dispose(); 9095 } 9096 } 9097 return this; 9098 }; 9099 9100 /** 9101 * Whether or not the modal is closeable via the UI. 9102 * 9103 * @method closeable 9104 * @param {Boolean} [value] 9105 * If given as a Boolean, it will set the `closeable` option. 9106 * 9107 * @return {Boolean} 9108 */ 9109 9110 ModalDialog.prototype.closeable = function closeable(value) { 9111 if (typeof value === 'boolean') { 9112 var closeable = this.closeable_ = !!value; 9113 var _close = this.getChild('closeButton'); 9114 9115 // If this is being made closeable and has no close button, add one. 9116 if (closeable && !_close) { 9117
9118 // The close button should be a child of the modal - not its 9119 // content element, so temporarily change the content element. 9120 var temp = this.contentEl_; 9121 this.contentEl_ = this.el_; 9122 _close = this.addChild('closeButton'); 9123 this.contentEl_ = temp; 9124 this.on(_close, 'close', this.close); 9125 } 9126 9127 // If this is being made uncloseable and has a close button, remove it. 9128 if (!closeable && _close) { 9129 this.off(_close, 'close', this.close); 9130 this.removeChild(_close); 9131 _close.dispose(); 9132 } 9133 } 9134 return this.closeable_; 9135 }; 9136 9137 /** 9138 * Fill the modal's content element with the modal's "content" option. 9139 * 9140 * The content element will be emptied before this change takes place. 9141 * 9142 * @method fill 9143 * @return {ModalDialog} 9144 */ 9145 9146 ModalDialog.prototype.fill = function fill() { 9147 return this.fillWith(this.content()); 9148 }; 9149 9150 /** 9151 * Fill the modal's content element with arbitrary content. 9152 * 9153 * The content element will be emptied before this change takes place. 9154 * 9155 * @method fillWith 9156 * @param {Mixed} [content] 9157 * The same rules apply to this as apply to the `content` option. 9158 * 9159 * @return {ModalDialog} 9160 */ 9161 9162 ModalDialog.prototype.fillWith = function fillWith(content) { 9163 var contentEl = this.contentEl(); 9164 var parentEl = contentEl.parentNode; 9165 var nextSiblingEl = contentEl.nextSibling; 9166 9167 this.trigger('beforemodalfill'); 9168 this.hasBeenFilled_ = true; 9169 9170 // Detach the content element from the DOM before performing 9171 // manipulation to avoid modifying the live DOM multiple times. 9172 parentEl.removeChild(contentEl); 9173 this.empty(); 9174 Dom.insertContent(contentEl, content); 9175 this.trigger('modalfill'); 9176 9177 // Re-inject the re-filled content element. 9178 if (nextSiblingEl) { 9179 parentEl.insertBefore(contentEl, nextSiblingEl); 9180 } else { 9181 parentEl.appendChild(contentEl); 9182 } 9183 9184 return this; 9185 }; 9186 9187 /** 9188 * Empties the content element. 9189 * 9190 * This happens automatically anytime the modal is filled. 9191 * 9192 * @method empty 9193 * @return {ModalDialog} 9194 */ 9195 9196 ModalDialog.prototype.empty = function empty() { 9197 this.trigger('beforemodalempty'); 9198 Dom.emptyEl(this.contentEl()); 9199 this.trigger('modalempty'); 9200 return this; 9201 }; 9202 9203 /** 9204 * Gets or sets the modal content, which gets normalized before being 9205 * rendered into the DOM. 9206 * 9207 * This does not update the DOM or fill the modal, but it is called during 9208 * that process. 9209 * 9210 * @method content 9211 * @param {Mixed} [value] 9212 * If defined, sets the internal content value to be used on the 9213 * next call(s) to `fill`. This value is normalized before being 9214 * inserted. To "clear" the internal content value, pass `null`. 9215 * 9216 * @return {Mixed} 9217 */ 9218 9219 ModalDialog.prototype.content = function content(value) { 9220 if (typeof value !== 'undefined') { 9221 this.content_ = value; 9222 } 9223 return this.content_; 9224 }; 9225 9226 return ModalDialog; 9227})(_component2['default']); 9228 9229ModalDialog.prototype.options_ = { 9230 temporary: true 9231}; 9232 9233_component2['default'].registerComponent('ModalDialog', ModalDialog); 9234exports['default'] = ModalDialog; 9235module.exports = exports['default']; 9236 9237},{"./close-button":65,"./component":66,"./utils/dom":131,"./utils/fn":133,"./utils/log":136,"global/document":1}],107:[function(_dereq_,module,exports){ 9238/** 9239 * @file player.js 9240 */ 9241// Subclasses Component 9242'use strict'; 9243 9244exports.__esModule = true; 9245 9246function _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; } } 9247 9248function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 9249 9250function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 9251 9252function _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
9252onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 9253 9254var _componentJs = _dereq_('./component.js'); 9255 9256var _componentJs2 = _interopRequireDefault(_componentJs); 9257 9258var _globalDocument = _dereq_('global/document'); 9259 9260var _globalDocument2 = _interopRequireDefault(_globalDocument); 9261 9262var _globalWindow = _dereq_('global/window'); 9263 9264var _globalWindow2 = _interopRequireDefault(_globalWindow); 9265 9266var _utilsEventsJs = _dereq_('./utils/events.js'); 9267 9268var Events = _interopRequireWildcard(_utilsEventsJs); 9269 9270var _utilsDomJs = _dereq_('./utils/dom.js'); 9271 9272var Dom = _interopRequireWildcard(_utilsDomJs); 9273 9274var _utilsFnJs = _dereq_('./utils/fn.js'); 9275 9276var Fn = _interopRequireWildcard(_utilsFnJs); 9277 9278var _utilsGuidJs = _dereq_('./utils/guid.js'); 9279 9280var Guid = _interopRequireWildcard(_utilsGuidJs); 9281 9282var _utilsBrowserJs = _dereq_('./utils/browser.js'); 9283 9284var browser = _interopRequireWildcard(_utilsBrowserJs); 9285 9286var _utilsLogJs = _dereq_('./utils/log.js'); 9287 9288var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 9289 9290var _utilsToTitleCaseJs = _dereq_('./utils/to-title-case.js'); 9291 9292var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs); 9293 9294var _utilsTimeRangesJs = _dereq_('./utils/time-ranges.js'); 9295 9296var _utilsBufferJs = _dereq_('./utils/buffer.js'); 9297 9298var _utilsStylesheetJs = _dereq_('./utils/stylesheet.js'); 9299 9300var stylesheet = _interopRequireWildcard(_utilsStylesheetJs); 9301 9302var _fullscreenApiJs = _dereq_('./fullscreen-api.js'); 9303 9304var _fullscreenApiJs2 = _interopRequireDefault(_fullscreenApiJs); 9305 9306var _mediaErrorJs = _dereq_('./media-error.js'); 9307 9308var _mediaErrorJs2 = _interopRequireDefault(_mediaErrorJs); 9309 9310var _safeJsonParseTuple = _dereq_('safe-json-parse/tuple'); 9311 9312var _safeJsonParseTuple2 = _interopRequireDefault(_safeJsonParseTuple); 9313 9314var _objectAssign = _dereq_('object.assign'); 9315 9316var _objectAssign2 = _interopRequireDefault(_objectAssign); 9317 9318var _utilsMergeOptionsJs = _dereq_('./utils/merge-options.js'); 9319 9320var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs); 9321 9322var _tracksTextTrackListConverterJs = _dereq_('./tracks/text-track-list-converter.js'); 9323 9324var _tracksTextTrackListConverterJs2 = _interopRequireDefault(_tracksTextTrackListConverterJs); 9325 9326// Include required child components (importing also registers them) 9327 9328var _techLoaderJs = _dereq_('./tech/loader.js'); 9329 9330var _techLoaderJs2 = _interopRequireDefault(_techLoaderJs); 9331 9332var _posterImageJs = _dereq_('./poster-image.js'); 9333 9334var _posterImageJs2 = _interopRequireDefault(_posterImageJs); 9335 9336var _tracksTextTrackDisplayJs = _dereq_('./tracks/text-track-display.js'); 9337 9338var _tracksTextTrackDisplayJs2 = _interopRequireDefault(_tracksTextTrackDisplayJs); 9339 9340var _loadingSpinnerJs = _dereq_('./loading-spinner.js'); 9341 9342var _loadingSpinnerJs2 = _interopRequireDefault(_loadingSpinnerJs); 9343 9344var _bigPlayButtonJs = _dereq_('./big-play-button.js'); 9345 9346var _bigPlayButtonJs2 = _interopRequireDefault(_bigPlayButtonJs); 9347 9348var _controlBarControlBarJs = _dereq_('./control-bar/control-bar.js'); 9349 9350var _controlBarControlBarJs2 = _interopRequireDefault(_controlBarControlBarJs); 9351 9352var _errorDisplayJs = _dereq_('./error-display.js'); 9353 9354var _errorDisplayJs2 = _interopRequireDefault(_errorDisplayJs); 9355 9356var _tracksTextTrackSettingsJs = _dereq_('./tracks/text-track-settings.js'); 9357 9358var _tracksTextTrackSettingsJs2 = _interopRequireDefault(_tracksTextTrackSettingsJs); 9359 9360var _modalDialog = _dereq_('./modal-dialog'); 9361 9362var _modalDialog2 = _interopRequireDefault(_modalDialog); 9363 9364// Require html5 tech, at least for disposing the original video tag 9365 9366var _techTechJs = _dereq_('./tech/tech.js'); 9367 9368var _techTechJs2 = _interopRequireDefault(_techTechJs); 9369 9370var _techHtml5Js = _dereq_('./tech/html5.js'); 9371 9372var _techHtml5Js2 = _interopRequireDefault(_techHtml5Js); 9373 9374/** 9375 * An instance of the `Player` class is created when any of the Video.js setup methods are used to initialize a video. 9376 * ```js 9377 * var myPlayer = videojs('example_video_1'); 9378 * ``` 9379 * In the following example, the `data-setup` attribute tells the Video.js library to create a player instance when the library is ready. 9380 * ```html 9381 * <video id="example_video_1" data-setup='{}' controls> 9382 * <source src="my-source.mp4" type="video/mp4"> 9383 * </video> 9384 * ``` 9385 * After an instance has been created it can be accessed globally using `Video('example_video_1')`. 9386 * 9387 * @param {Element}
9387 tag The original video tag used for configuring options 9388 * @param {Object=} options Object of option names and values 9389 * @param {Function=} ready Ready callback function 9390 * @extends Component 9391 * @class Player 9392 */ 9393 9394var Player = (function (_Component) { 9395 _inherits(Player, _Component); 9396 9397 /** 9398 * player's constructor function 9399 * 9400 * @constructs 9401 * @method init 9402 * @param {Element} tag The original video tag used for configuring options 9403 * @param {Object=} options Player options 9404 * @param {Function=} ready Ready callback function 9405 */ 9406 9407 function Player(tag, options, ready) { 9408 var _this = this; 9409 9410 _classCallCheck(this, Player); 9411 9412 // Make sure tag ID exists 9413 tag.id = tag.id || 'vjs_video_' + Guid.newGUID(); 9414 9415 // Set Options 9416 // The options argument overrides options set in the video tag 9417 // which overrides globally set options. 9418 // This latter part coincides with the load order 9419 // (tag must exist before Player) 9420 options = _objectAssign2['default'](Player.getTagSettings(tag), options); 9421 9422 // Delay the initialization of children because we need to set up 9423 // player properties first, and can't use `this` before `super()` 9424 options.initChildren = false; 9425 9426 // Same with creating the element 9427 options.createEl = false;
9428 9429 // we don't want the player to report touch activity on itself 9430 // see enableTouchActivity in Component 9431 options.reportTouchActivity = false; 9432 9433 // Run base component initializing with new options 9434 _Component.call(this, null, options, ready); 9435 9436 // if the global option object was accidentally blown away by 9437 // someone, bail early with an informative error 9438 if (!this.options_ || !this.options_.techOrder || !this.options_.techOrder.length) { 9439 throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?'); 9440 } 9441 9442 this.tag = tag; // Store the original tag used to set options 9443 9444 // Store the tag attributes used to restore html5 element 9445 this.tagAttributes = tag && Dom.getElAttributes(tag); 9446 9447 // Update current language 9448 this.language(this.options_.language); 9449 9450 // Update Supported Languages 9451 if (options.languages) { 9452 (function () { 9453 // Normalise player option languages to lowercase 9454 var languagesToLower = {}; 9455 9456 Object.getOwnPropertyNames(options.languages).forEach(function (name) { 9457 languagesToLower[name.toLowerCase()] = options.languages[name]; 9458 }); 9459 _this.languages_ = languagesToLower; 9460 })(); 9461 } else { 9462 this.languages_ = Player.prototype.options_.languages; 9463 } 9464 9465 // Cache for video property values. 9466 this.cache_ = {}; 9467 9468 // Set poster 9469 this.poster_ = options.poster || ''; 9470 9471 // Set controls 9472 this.controls_ = !!options.controls; 9473 9474 // Original tag settings stored in options 9475 // now remove immediately so native controls don't flash. 9476 // May be turned back on by HTML5 tech if nativeControlsForTouch is true 9477 tag.controls = false; 9478 9479 /* 9480 * Store the internal state of scrubbing 9481 * 9482 * @private 9483 * @return {Boolean} True if the user is scrubbing 9484 */ 9485 this.scrubbing_ = false; 9486 9487 this.el_ = this.createEl(); 9488 9489 // We also want to pass the original player options to each component and plugin 9490 // as well so they don't need to reach back into the player for options later. 9491 // We also need to do another copy of this.options_ so we don't end up with 9492 // an infinite loop. 9493 var playerOptionsCopy = _utilsMergeOptionsJs2['default'](this.options_); 9494 9495 // Load plugins 9496 if (options.plugins) { 9497 (function () { 9498 var plugins = options.plugins; 9499 9500 Object.getOwnPropertyNames(plugins).forEach(function (name) { 9501 if (typeof this[name] === 'function') { 9502 this[name](plugins[name]); 9503 } else { 9504 _utilsLogJs2['default'].error('Unable to find plugin:', name); 9505 } 9506 }, _this); 9507 })(); 9508 } 9509 9510 this.options_.playerOptions = playerOptionsCopy; 9511 9512 this.initChildren(); 9513 9514 // Set isAudio based on whether or not an audio tag was used 9515 this.isAudio(tag.nodeName.toLowerCase() === 'audio'); 9516 9517 // Update controls className. Can't do this when the controls are initially 9518 // set because the element doesn't exist yet. 9519 if (this.controls()) { 9520 this.addClass('vjs-controls-enabled'); 9521 } else { 9522 this.addClass('vjs-controls-disabled'); 9523 } 9524 9525 if (this.isAudio()) { 9526 this.addClass('vjs-audio'); 9527 } 9528 9529 if (this.flexNotSupported_()) { 9530 this.addClass('vjs-no-flex'); 9531 } 9532 9533 // TODO: Make this smarter. Toggle user state between touching/mousing 9534 // using events, since devices can have both touch and mouse events. 9535 // if (browser.TOUCH_ENABLED) { 9536 // this.addClass('vjs-touch-enabled'); 9537 // } 9538 9539 // Make player easily findable by ID 9540 Player.players[this.id_] = this; 9541 9542 // When the player is first initialized, trigger activity so components 9543 // like the control bar show themselves if needed 9544 this.userActive(true); 9545 this.reportUserActivity(); 9546 this.listenForUserActivity_(); 9547 9548 this.on('fullscreenchange', this.handleFullscreenChange_); 9549 this.on('stageclick', this.handleStageClick_); 9550 } 9551 9552 /* 9553 * Global player list 9554 * 9555 * @type {Object} 9556 */ 9557 9558 /** 9559 * Destroys the video player and does any necessary cleanup 9560 * ```js
9561 * myPlayer.dispose(); 9562 * ``` 9563 * This is especially helpful if you are dynamically adding and removing videos 9564 * to/from the DOM. 9565 * 9566 * @method dispose 9567 */ 9568 9569 Player.prototype.dispose = function dispose() { 9570 this.trigger('dispose'); 9571 // prevent dispose from being called twice 9572 this.off('dispose'); 9573 9574 if (this.styleEl_ && this.styleEl_.parentNode) { 9575 this.styleEl_.parentNode.removeChild(this.styleEl_); 9576 } 9577 9578 // Kill reference to this player 9579 Player.players[this.id_] = null; 9580 if (this.tag && this.tag.player) { 9581 this.tag.player = null; 9582 } 9583 if (this.el_ && this.el_.player) { 9584 this.el_.player = null; 9585 } 9586 9587 if (this.tech_) { 9588 this.tech_.dispose(); 9589 } 9590 9591 _Component.prototype.dispose.call(this); 9592 }; 9593 9594 /** 9595 * Create the component's DOM element 9596 * 9597 * @return {Element} 9598 * @method createEl 9599 */ 9600 9601 Player.prototype.createEl = function createEl() { 9602 var el = this.el_ = _Component.prototype.createEl.call(this, 'div'); 9603 var tag = this.tag; 9604 9605 // Remove width/height attrs from tag so CSS can make it 100% width/height 9606 tag.removeAttribute('width'); 9607 tag.removeAttribute('height'); 9608 9609 // Copy over all the attributes from the tag, including ID and class 9610 // ID will now reference player box, not the video tag 9611 var attrs = Dom.getElAttributes(tag); 9612 9613 Object.getOwnPropertyNames(attrs).forEach(function (attr) { 9614 // workaround so we don't totally break IE7 9615 // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7 9616 if (attr === 'class') { 9617 el.className = attrs[attr]; 9618 } else { 9619 el.setAttribute(attr, attrs[attr]); 9620 } 9621 }); 9622 9623 // Update tag id/class for use as HTML5 playback tech 9624 // Might think we should do this after embedding in container so .vjs-tech class 9625 // doesn't flash 100% width/height, but class only applies with .video-js parent 9626 tag.playerId = tag.id; 9627 tag.id += '_html5_api'; 9628 tag.className = 'vjs-tech'; 9629 9630 // Make player findable on elements 9631 tag.player = el.player = this; 9632 // Default state of video is paused 9633 this.addClass('vjs-paused'); 9634 9635 // Add a style element in the player that we'll use to set the width/height 9636 // of the player in a way that's still overrideable by CSS, just like the 9637 // video element 9638 this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions'); 9639 var defaultsStyleEl = Dom.$('.vjs-styles-defaults'); 9640 var head = Dom.$('head'); 9641 head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild); 9642 9643 // Pass in the width/height/aspectRatio options which will update the style el 9644 this.width(this.options_.width); 9645 this.height(this.options_.height); 9646 this.fluid(this.options_.fluid); 9647 this.aspectRatio(this.options_.aspectRatio); 9648 9649 // insertElFirst seems to cause the networkState to flicker from 3 to 2, so 9650 // keep track of the original for later so we can know if the source originally failed 9651 tag.initNetworkState_ = tag.networkState; 9652 9653 // Wrap video tag in div (el/box) container 9654 if (tag.parentNode) { 9655 tag.parentNode.insertBefore(el, tag); 9656 } 9657 9658 // insert the tag as the first child of the player element 9659 // then manually add it to the children array so that this.addChild 9660 // will work properly for other components 9661 Dom.insertElFirst(tag, el); // Breaks iPhone, fixed in HTML5 setup. 9662 this.children_.unshift(tag); 9663 9664 this.el_ = el; 9665 9666 return el; 9667 }; 9668 9669 /** 9670 * Get/set player width 9671 * 9672 * @param {Number=} value Value for width 9673 * @return {Number} Width when getting 9674 * @method width 9675 */ 9676 9677 Player.prototype.width = function width(value) { 9678 return this.dimension('width', value); 9679 }; 9680 9681 /** 9682 * Get/set player height 9683 * 9684 * @param {Number=} value Value for height 9685 * @return {Number} Height when getting 9686 * @method height 9687 */ 9688 9689 Player.prototype.height = function height(value) { 9690 return this.dimension('height', value); 9691 }; 9692 9693 /** 9694 * Get/set dimension for player 9695 * 9696 * @param {String} dimension Either width or height 9697 * @param {Number=} value Value for dimension 9698 * @return {Component} 9699 * @method dimension 9700 */ 9701 9702 Player.prototype.dimension = function dimension(_dimension, value) { 9703 var privDimension = _dimension + '_'; 9704 9705 if (value === undefined) { 9706 return this[privDimension] || 0; 9707 } 9708 9709 if (value === '') { 9710 // If an empty string is given, reset the dimension to be automatic 9711 this[privDimension] = undefined; 9712 } else { 9713 var parsedVal = parseFloat(value); 9714 9715 if (isNaN(parsedVal)) { 9716 _utilsLogJs2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension); 9717 return this; 9718 } 9719 9720 this[privDimension] = parsedVal; 9721 } 9722 9723 this.updateStyleEl_(); 9724 return this; 9725 }; 9726 9727 /** 9728 * Add/remove the vjs-fluid class 9729 * 9730 * @param {Boolean} bool Value of true adds the class, value of false removes the class 9731 * @method fluid 9732 */ 9733 9734 Player.prototype.fluid = function fluid(bool) { 9735 if (bool === undefined) { 9736 return !!this.fluid_; 9737 } 9738 9739 this.fluid_ = !!bool; 9740 9741 if (bool) { 9742 this.addClass('vjs-fluid'); 9743 } else { 9744 this.removeClass('vjs-fluid'); 9745 } 9746 }; 9747 9748 /** 9749 * Get/Set the aspect ratio 9750 * 9751 * @param {String=} ratio Aspect ratio for player 9752 * @return aspectRatio 9753 * @method aspectRatio 9754 */ 9755 9756 Player.prototype.aspectRatio = function aspectRatio(ratio) { 9757 if (ratio === undefined) { 9758 return this.aspectRatio_; 9759 } 9760 9761 // Check for width:height format 9762 if (!/^\d+\:\d+$/.test(ratio)) { 9763 throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.'); 9764 } 9765 this.aspectRatio_ = ratio; 9766 9767 // We're assuming if you set an aspect ratio you want fluid mode, 9768 // because in fixed mode you could calculate width and height yourself. 9769 this.fluid(true); 9770 9771 this.updateStyleEl_(); 9772 }; 9773 9774 /** 9775 * Update styles of the player element (height, width and aspect ratio) 9776 * 9777 * @method updateStyleEl_ 9778 */ 9779 9780 Player.prototype.updateStyleEl_ = function updateStyleEl_() { 9781 var width = undefined; 9782 var height = undefined; 9783 var aspectRatio = undefined; 9784 var idClass = undefined; 9785 9786 // The aspect ratio is either used directly or to calculate width and height. 9787 if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') { 9788 // Use any aspectRatio that's been specifically set 9789 aspectRatio = this.aspectRatio_; 9790 } else if (this.videoWidth()) { 9791 // Otherwise try to get the aspect ratio from the video metadata 9792 aspectRatio = this.videoWidth() + ':' + this.videoHeight(); 9793 } else { 9794 // Or use a default. The video element's is 2:1, but 16:9 is more common. 9795 aspectRatio = '16:9'; 9796 } 9797 9798 // Get the ratio as a decimal we can use to calculate dimensions 9799 var ratioParts = aspectRatio.split(':'); 9800 var ratioMultiplier = ratioParts[1] / ratioParts[0]; 9801 9802 if (this.width_ !== undefined) { 9803 // Use any width that's been specifically set 9804 width = this.width_; 9805 } else if (this.height_ !== undefined) { 9806 // Or calulate the width from the aspect ratio if a height has been set 9807 width = this.height_ / ratioMultiplier; 9808 } else { 9809 // Or use the video's metadata, or use the video el's default of 300 9810 width = this.videoWidth() || 300; 9811 } 9812 9813 if (this.height_ !== undefined) { 9814 // Use any height that's been specifically set 9815 height = this.height_; 9816 } else { 9817 // Otherwise calculate the height from the ratio and the width 9818 height = width * ratioMultiplier; 9819 } 9820 9821 // Ensure the CSS class is valid by starting with an alpha character 9822 if (/^[^a-zA-Z]/.test(this.id())) { 9823 idClass = 'dimensions-' + this.id(); 9824 } else { 9825 idClass = this.id() + '-dimensions'; 9826 } 9827 9828 // Ensure the right class is still on the player for the style element 9829 this.addClass(idClass); 9830 9831 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 '); 9832 }; 9833 9834 /** 9835 * Load the Media Playback Technology (tech) 9836 * Load/Create an instance of playback technology including element and API methods 9837 * And append playback element in player div. 9838 * 9839 * @param {String} techName Name of the playback technology 9840 * @param {String} source Video source 9841 * @method loadTech_ 9842 * @private 9843 */ 9844 9845 Player.prototype.loadTech_ = function loadTech_(techName, source) { 9846 9847 // Pause and remove current playback technology 9848 if (this.tech_) { 9849 this.unloadTech_(); 9850 } 9851 9852 // get rid of the HTML5 video tag as soon as we are using another tech 9853 if (techName !== 'Html5' && this.tag) { 9854 _techTechJs2['default'].getTech('Html5').disposeMediaElement(this.tag); 9855 this.tag.player = null; 9856 this.tag = null; 9857 } 9858 9859 this.techName_ = techName; 9860 9861 // Turn off API access because we're loading a new tech that might load asynchronously 9862 this.isReady_ = false;
9863 9864 // Grab tech-specific options from player options and add source and parent element to use. 9865 var techOptions = _objectAssign2['default']({ 9866 'nativeControlsForTouch': this.options_.nativeControlsForTouch, 9867 'source': source, 9868 'playerId': this.id(), 9869 'techId': this.id() + '_' + techName + '_api', 9870 'textTracks': this.textTracks_, 9871 'autoplay': this.options_.autoplay, 9872 'preload': this.options_.preload, 9873 'loop': this.options_.loop, 9874 'muted': this.options_.muted, 9875 'poster': this.poster(), 9876 'language': this.language(), 9877 'vtt.js': this.options_['vtt.js'] 9878 }, this.options_[techName.toLowerCase()]); 9879 9880 if (this.tag) { 9881 techOptions.tag = this.tag; 9882 } 9883 9884 if (source) { 9885 this.currentType_ = source.type; 9886 if (source.src === this.cache_.src && this.cache_.currentTime > 0) { 9887 techOptions.startTime = this.cache_.currentTime; 9888 } 9889 9890 this.cache_.src = source.src; 9891 } 9892 9893 // Initialize tech instance 9894 var techComponent = _techTechJs2['default'].getTech(techName); 9895 // Support old behavior of techs being registered as components. 9896 // Remove once that deprecated behavior is removed. 9897 if (!techComponent) { 9898 techComponent = _componentJs2['default'].getComponent(techName); 9899 } 9900 this.tech_ = new techComponent(techOptions); 9901 9902 // player.triggerReady is always async, so don't need this to be async 9903 this.tech_.ready(Fn.bind(this, this.handleTechReady_), true); 9904 9905 _tracksTextTrackListConverterJs2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_); 9906 9907 // Listen to all HTML5-defined events and trigger them on the player 9908 this.on(this.tech_, 'loadstart', this.handleTechLoadStart_); 9909 this.on(this.tech_, 'waiting', this.handleTechWaiting_); 9910 this.on(this.tech_, 'canplay', this.handleTechCanPlay_); 9911 this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_); 9912 this.on(this.tech_, 'playing', this.handleTechPlaying_); 9913 this.on(this.tech_, 'ended', this.handleTechEnded_); 9914 this.on(this.tech_, 'seeking', this.handleTechSeeking_); 9915 this.on(this.tech_, 'seeked', this.handleTechSeeked_); 9916 this.on(this.tech_, 'play', this.handleTechPlay_); 9917 this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_); 9918 this.on(this.tech_, 'pause', this.handleTechPause_); 9919 this.on(this.tech_, 'progress', this.handleTechProgress_); 9920 this.on(this.tech_, 'durationchange', this.handleTechDurationChange_); 9921 this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_); 9922 this.on(this.tech_, 'error', this.handleTechError_); 9923 this.on(this.tech_, 'suspend', this.handleTechSuspend_); 9924 this.on(this.tech_, 'abort', this.handleTechAbort_); 9925 this.on(this.tech_, 'emptied', this.handleTechEmptied_); 9926 this.on(this.tech_, 'stalled', this.handleTechStalled_); 9927 this.on(this.tech_, 'loadedmetadata', this.handleTechLoadedMetaData_); 9928 this.on(this.tech_, 'loadeddata', this.handleTechLoadedData_); 9929 this.on(this.tech_, 'timeupdate', this.handleTechTimeUpdate_); 9930 this.on(this.tech_, 'ratechange', this.handleTechRateChange_); 9931 this.on(this.tech_, 'volumechange', this.handleTechVolumeChange_); 9932 this.on(this.tech_, 'texttrackchange', this.handleTechTextTrackChange_); 9933 this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_); 9934 this.on(this.tech_, 'posterchange', this.handleTechPosterChange_); 9935 9936 this.usingNativeControls(this.techGet_('controls')); 9937 9938 if (this.controls() && !this.usingNativeControls()) { 9939 this.addTechControlsListeners_(); 9940 } 9941 9942 // Add the tech element in the DOM if it was not already there 9943 // Make sure to not insert the original video element if using Html5 9944 if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) { 9945 Dom.insertElFirst(this.tech_.el(), this.el()); 9946 } 9947 9948 // Get rid of the original video tag reference after the first tech is loaded 9949 if (this.tag) { 9950 this.tag.player = null; 9951 this.tag = null; 9952 } 9953 }; 9954 9955 /** 9956 * Unload playback technology 9957 * 9958 * @method unloadTech_ 9959 * @private 9960 */ 9961 9962 Player.prototype.unloadTech_ = function unloadTech_() { 9963 // Save the current text tracks so that we can reuse the same text tracks with the next tech 9964 this.textTracks_ = this.textTracks(); 9965 this.textTracksJson_ = _tracksTextTrackListConverterJs2['default'].textTracksToJson(this.tech_); 9966 9967 this.isReady_ = false;
vendor: 16,384 bytes, lines 9968-10567
9968 9969 this.tech_.dispose(); 9970 9971 this.tech_ = false; 9972 }; 9973 9974 /** 9975 * Return a reference to the current tech. 9976 * It will only return a reference to the tech if given an object with the 9977 * `IWillNotUseThisInPlugins` property on it. This is try and prevent misuse 9978 * of techs by plugins. 9979 * 9980 * @param {Object} 9981 * @return {Object} The Tech 9982 * @method tech 9983 */ 9984 9985 Player.prototype.tech = function tech(safety) { 9986 if (safety && safety.IWillNotUseThisInPlugins) { 9987 return this.tech_; 9988 } 9989 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 '; 9990 _globalWindow2['default'].alert(errorText); 9991 throw new Error(errorText); 9992 }; 9993 9994 /** 9995 * Set up click and touch listeners for the playback element 9996 * 9997 * On desktops, a click on the video itself will toggle playback, 9998 * on a mobile device a click on the video toggles controls. 9999 * (toggling controls is done by toggling the user state between active and 10000 * inactive) 10001 * A tap can signal that a user has become active, or has become inactive 10002 * e.g. a quick tap on an iPhone movie should reveal the controls. Another 10003 * quick tap should hide them again (signaling the user is in an inactive 10004 * viewing state) 10005 * In addition to this, we still want the user to be considered inactive after 10006 * a few seconds of inactivity. 10007 * Note: the only part of iOS interaction we can't mimic with this setup 10008 * is a touch and hold on the video element counting as activity in order to 10009 * keep the controls showing, but that shouldn't be an issue. A touch and hold 10010 * on any controls will still keep the user active 10011 * 10012 * @private 10013 * @method addTechControlsListeners_ 10014 */ 10015 10016 Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() { 10017 // Make sure to remove all the previous listeners in case we are called multiple times. 10018 this.removeTechControlsListeners_(); 10019 10020 // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do 10021 // trigger mousedown/up. 10022 // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object 10023 // Any touch events are set to block the mousedown event from happening 10024 this.on(this.tech_, 'mousedown', this.handleTechClick_); 10025 10026 // If the controls were hidden we don't want that to change without a tap event 10027 // so we'll check if the controls were already showing before reporting user 10028 // activity 10029 this.on(this.tech_, 'touchstart', this.handleTechTouchStart_); 10030 this.on(this.tech_, 'touchmove', this.handleTechTouchMove_); 10031 this.on(this.tech_, 'touchend', this.handleTechTouchEnd_); 10032 10033 // The tap listener needs to come after the touchend listener because the tap 10034 // listener cancels out any reportedUserActivity when setting userActive(false) 10035 this.on(this.tech_, 'tap', this.handleTechTap_); 10036 }; 10037 10038 /** 10039 * Remove the listeners used for click and tap controls. This is needed for 10040 * toggling to controls disabled, where a tap/touch should do nothing. 10041 * 10042 * @method removeTechControlsListeners_ 10043 * @private 10044 */ 10045 10046 Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() { 10047 // We don't want to just use `this.off()` because there might be other needed 10048 // listeners added by techs that extend this. 10049 this.off(this.tech_, 'tap', this.handleTechTap_); 10050 this.off(this.tech_, 'touchstart', this.handleTechTouchStart_); 10051 this.off(this.tech_, 'touchmove', this.handleTechTouchMove_); 10052 this.off(this.tech_, 'touchend', this.handleTechTouchEnd_); 10053 this.off(this.tech_, 'mousedown', this.handleTechClick_); 10054 }; 10055 10056 /** 10057 * Player waits for the tech to be ready 10058 * 10059 * @method handleTechReady_ 10060 * @private 10061 */ 10062 10063 Player.prototype.handleTechReady_ = function handleTechReady_() { 10064 this.triggerReady(); 10065 10066 // Keep the same volume as before 10067 if (this.cache_.volume) { 10068 this.techCall_('setVolume', this.cache_.volume); 10069 } 10070 10071 // Look if the tech found a higher resolution poster while loading 10072 this.handleTechPosterChange_(); 10073 10074 // Update the duration if available 10075 this.handleTechDurationChange_(); 10076 10077 // Chrome and Safari both have issues with autoplay. 10078 // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work. 10079 // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays) 10080 // This fixes both issues. Need to wait for API, so it updates displays correctly 10081 if (this.src() && this.tag && this.options_.autoplay && this.paused()) { 10082 delete this.tag.poster; // Chrome Fix. Fixed in Chrome v16. 10083 this.play(); 10084 } 10085 }; 10086 10087 /** 10088 * Fired when the user agent begins looking for media data 10089 * 10090 * @private 10091 * @method handleTechLoadStart_ 10092 */ 10093 10094 Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() { 10095 // TODO: Update to use `emptied` event instead. See #1277. 10096 10097 this.removeClass('vjs-ended'); 10098 10099 // reset the error state 10100 this.error(null); 10101 10102 // If it's already playing we want to trigger a firstplay event now. 10103 // The firstplay event relies on both the play and loadstart events 10104 // which can happen in any order for a new source 10105 if (!this.paused()) { 10106 this.trigger('loadstart'); 10107 this.trigger('firstplay'); 10108 } else { 10109 // reset the hasStarted state 10110 this.hasStarted(false); 10111 this.trigger('loadstart'); 10112 } 10113 }; 10114 10115 /** 10116 * Add/remove the vjs-has-started class 10117 * 10118 * @param {Boolean} hasStarted The value of true adds the class the value of false remove the class 10119 * @return {Boolean} Boolean value if has started 10120 * @private 10121 * @method hasStarted 10122 */ 10123 10124 Player.prototype.hasStarted = function hasStarted(_hasStarted) { 10125 if (_hasStarted !== undefined) { 10126 // only update if this is a new value 10127 if (this.hasStarted_ !== _hasStarted) { 10128 this.hasStarted_ = _hasStarted; 10129 if (_hasStarted) { 10130 this.addClass('vjs-has-started'); 10131 // trigger the firstplay event if this newly has played 10132 this.trigger('firstplay'); 10133 } else { 10134 this.removeClass('vjs-has-started'); 10135 } 10136 } 10137 return this; 10138 } 10139 return !!this.hasStarted_; 10140 }; 10141 10142 /** 10143 * Fired whenever the media begins or resumes playback 10144 * 10145 * @private 10146 * @method handleTechPlay_ 10147 */ 10148 10149 Player.prototype.handleTechPlay_ = function handleTechPlay_() { 10150 this.removeClass('vjs-ended'); 10151 this.removeClass('vjs-paused'); 10152 this.addClass('vjs-playing'); 10153 10154 // hide the poster when the user hits play 10155 // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play 10156 this.hasStarted(true); 10157 10158 this.trigger('play'); 10159 }; 10160 10161 /** 10162 * Fired whenever the media begins waiting 10163 * 10164 * @private 10165 * @method handleTechWaiting_ 10166 */ 10167 10168 Player.prototype.handleTechWaiting_ = function handleTechWaiting_() { 10169 this.addClass('vjs-waiting'); 10170 this.trigger('waiting'); 10171 }; 10172 10173 /** 10174 * A handler for events that signal that waiting has ended 10175 * which is not consistent between browsers. See #1351 10176 * 10177 * @private 10178 * @method handleTechCanPlay_ 10179 */ 10180 10181 Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() { 10182 this.removeClass('vjs-waiting'); 10183 this.trigger('canplay'); 10184 }; 10185 10186 /** 10187 * A handler for events that signal that waiting has ended 10188 * which is not consistent between browsers. See #1351 10189 * 10190 * @private 10191 * @method handleTechCanPlayThrough_ 10192 */ 10193 10194 Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() { 10195 this.removeClass('vjs-waiting'); 10196 this.trigger('canplaythrough'); 10197 }; 10198 10199 /** 10200 * A handler for events that signal that waiting has ended 10201 * which is not consistent between browsers. See #1351 10202 * 10203 * @private 10204 * @method handleTechPlaying_ 10205 */ 10206 10207 Player.prototype.handleTechPlaying_ = function handleTechPlaying_() { 10208 this.removeClass('vjs-waiting'); 10209 this.trigger('playing'); 10210 }; 10211 10212 /** 10213 * Fired whenever the player is jumping to a new time 10214 * 10215 * @private 10216 * @method handleTechSeeking_ 10217 */ 10218 10219 Player.prototype.handleTechSeeking_ = function handleTechSeeking_() { 10220 this.addClass('vjs-seeking'); 10221 this.trigger('seeking'); 10222 }; 10223 10224 /** 10225 * Fired when the player has finished jumping to a new time 10226 * 10227 * @private 10228 * @method handleTechSeeked_ 10229 */ 10230 10231 Player.prototype.handleTechSeeked_ = function handleTechSeeked_() { 10232 this.removeClass('vjs-seeking'); 10233 this.trigger('seeked'); 10234 }; 10235 10236 /** 10237 * Fired the first time a video is played 10238 * Not part of the HLS spec, and we're not sure if this is the best 10239 * implementation yet, so use sparingly. If you don't have a reason to 10240 * prevent playback, use `myPlayer.one('play');` instead. 10241 * 10242 * @private 10243 * @method handleTechFirstPlay_ 10244 */ 10245 10246 Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() { 10247 //If the first starttime attribute is specified 10248 //then we will start at the given offset in seconds 10249 if (this.options_.starttime) { 10250 this.currentTime(this.options_.starttime); 10251 } 10252 10253 this.addClass('vjs-has-started'); 10254 this.trigger('firstplay'); 10255 }; 10256 10257 /** 10258 * Fired whenever the media has been paused 10259 * 10260 * @private 10261 * @method handleTechPause_ 10262 */ 10263 10264 Player.prototype.handleTechPause_ = function handleTechPause_() { 10265 this.removeClass('vjs-playing'); 10266 this.addClass('vjs-paused'); 10267 this.trigger('pause'); 10268 }; 10269 10270 /** 10271 * Fired while the user agent is downloading media data 10272 * 10273 * @private 10274 * @method handleTechProgress_ 10275 */ 10276 10277 Player.prototype.handleTechProgress_ = function handleTechProgress_() { 10278 this.trigger('progress'); 10279 }; 10280 10281 /** 10282 * Fired when the end of the media resource is reached (currentTime == duration) 10283 * 10284 * @private 10285 * @method handleTechEnded_ 10286 */ 10287 10288 Player.prototype.handleTechEnded_ = function handleTechEnded_() { 10289 this.addClass('vjs-ended'); 10290 if (this.options_.loop) { 10291 this.currentTime(0); 10292 this.play(); 10293 } else if (!this.paused()) { 10294 this.pause(); 10295 } 10296 10297 this.trigger('ended'); 10298 }; 10299 10300 /** 10301 * Fired when the duration of the media resource is first known or changed 10302 * 10303 * @private 10304 * @method handleTechDurationChange_ 10305 */ 10306 10307 Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() { 10308 this.duration(this.techGet_('duration')); 10309 }; 10310 10311 /** 10312 * Handle a click on the media element to play/pause 10313 * 10314 * @param {Object=} event Event object 10315 * @private 10316 * @method handleTechClick_ 10317 */ 10318 10319 Player.prototype.handleTechClick_ = function handleTechClick_(event) { 10320 // We're using mousedown to detect clicks thanks to Flash, but mousedown 10321 // will also be triggered with right-clicks, so we need to prevent that 10322 if (event.button !== 0) return; 10323 10324 // When controls are disabled a click should not toggle playback because 10325 // the click is considered a control 10326 if (this.controls()) { 10327 if (this.paused()) { 10328 this.play(); 10329 } else { 10330 this.pause(); 10331 } 10332 } 10333 }; 10334 10335 /** 10336 * Handle a tap on the media element. It will toggle the user 10337 * activity state, which hides and shows the controls. 10338 * 10339 * @private 10340 * @method handleTechTap_ 10341 */ 10342 10343 Player.prototype.handleTechTap_ = function handleTechTap_() { 10344 this.userActive(!this.userActive()); 10345 }; 10346 10347 /** 10348 * Handle touch to start 10349 * 10350 * @private 10351 * @method handleTechTouchStart_ 10352 */ 10353 10354 Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() { 10355 this.userWasActive = this.userActive(); 10356 }; 10357 10358 /** 10359 * Handle touch to move 10360 * 10361 * @private 10362 * @method handleTechTouchMove_ 10363 */ 10364 10365 Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() { 10366 if (this.userWasActive) { 10367 this.reportUserActivity(); 10368 } 10369 }; 10370 10371 /** 10372 * Handle touch to end 10373 * 10374 * @private 10375 * @method handleTechTouchEnd_ 10376 */ 10377 10378 Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) { 10379 // Stop the mouse events from also happening 10380 event.preventDefault(); 10381 }; 10382 10383 /** 10384 * Fired when the player switches in or out of fullscreen mode 10385 * 10386 * @private 10387 * @method handleFullscreenChange_ 10388 */ 10389 10390 Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() { 10391 if (this.isFullscreen()) { 10392 this.addClass('vjs-fullscreen'); 10393 } else { 10394 this.removeClass('vjs-fullscreen'); 10395 } 10396 }; 10397 10398 /** 10399 * native click events on the SWF aren't triggered on IE11, Win8.1RT 10400 * use stageclick events triggered from inside the SWF instead 10401 * 10402 * @private 10403 * @method handleStageClick_ 10404 */ 10405 10406 Player.prototype.handleStageClick_ = function handleStageClick_() { 10407 this.reportUserActivity(); 10408 }; 10409 10410 /** 10411 * Handle Tech Fullscreen Change 10412 * 10413 * @private 10414 * @method handleTechFullscreenChange_ 10415 */ 10416 10417 Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) { 10418 if (data) { 10419 this.isFullscreen(data.isFullscreen); 10420 } 10421 this.trigger('fullscreenchange'); 10422 }; 10423 10424 /** 10425 * Fires when an error occurred during the loading of an audio/video 10426 * 10427 * @private 10428 * @method handleTechError_ 10429 */ 10430 10431 Player.prototype.handleTechError_ = function handleTechError_() { 10432 var error = this.tech_.error(); 10433 this.error(error && error.code); 10434 }; 10435 10436 /** 10437 * Fires when the browser is intentionally not getting media data 10438 * 10439 * @private 10440 * @method handleTechSuspend_ 10441 */ 10442 10443 Player.prototype.handleTechSuspend_ = function handleTechSuspend_() { 10444 this.trigger('suspend'); 10445 }; 10446 10447 /** 10448 * Fires when the loading of an audio/video is aborted 10449 * 10450 * @private 10451 * @method handleTechAbort_ 10452 */ 10453 10454 Player.prototype.handleTechAbort_ = function handleTechAbort_() { 10455 this.trigger('abort'); 10456 }; 10457 10458 /** 10459 * Fires when the current playlist is empty 10460 * 10461 * @private 10462 * @method handleTechEmptied_ 10463 */ 10464 10465 Player.prototype.handleTechEmptied_ = function handleTechEmptied_() { 10466 this.trigger('emptied'); 10467 }; 10468 10469 /** 10470 * Fires when the browser is trying to get media data, but data is not available 10471 * 10472 * @private 10473 * @method handleTechStalled_ 10474 */ 10475 10476 Player.prototype.handleTechStalled_ = function handleTechStalled_() { 10477 this.trigger('stalled'); 10478 }; 10479 10480 /** 10481 * Fires when the browser has loaded meta data for the audio/video 10482 * 10483 * @private 10484 * @method handleTechLoadedMetaData_ 10485 */ 10486 10487 Player.prototype.handleTechLoadedMetaData_ = function handleTechLoadedMetaData_() { 10488 this.trigger('loadedmetadata'); 10489 }; 10490 10491 /** 10492 * Fires when the browser has loaded the current frame of the audio/video 10493 * 10494 * @private 10495 * @method handleTechLoadedData_ 10496 */ 10497 10498 Player.prototype.handleTechLoadedData_ = function handleTechLoadedData_() { 10499 this.trigger('loadeddata'); 10500 }; 10501 10502 /** 10503 * Fires when the current playback position has changed 10504 * 10505 * @private 10506 * @method handleTechTimeUpdate_ 10507 */ 10508 10509 Player.prototype.handleTechTimeUpdate_ = function handleTechTimeUpdate_() { 10510 this.trigger('timeupdate'); 10511 }; 10512 10513 /** 10514 * Fires when the playing speed of the audio/video is changed 10515 * 10516 * @private 10517 * @method handleTechRateChange_ 10518 */ 10519 10520 Player.prototype.handleTechRateChange_ = function handleTechRateChange_() { 10521 this.trigger('ratechange'); 10522 }; 10523 10524 /** 10525 * Fires when the volume has been changed 10526 * 10527 * @private 10528 * @method handleTechVolumeChange_ 10529 */ 10530 10531 Player.prototype.handleTechVolumeChange_ = function handleTechVolumeChange_() { 10532 this.trigger('volumechange'); 10533 }; 10534 10535 /** 10536 * Fires when the text track has been changed 10537 * 10538 * @private 10539 * @method handleTechTextTrackChange_ 10540 */ 10541 10542 Player.prototype.handleTechTextTrackChange_ = function handleTechTextTrackChange_() { 10543 this.trigger('texttrackchange'); 10544 }; 10545 10546 /** 10547 * Get object for cached values. 10548 * 10549 * @return {Object} 10550 * @method getCache 10551 */ 10552 10553 Player.prototype.getCache = function getCache() { 10554 return this.cache_; 10555 }; 10556 10557 /** 10558 * Pass values to the playback tech 10559 * 10560 * @param {String=} method Method 10561 * @param {Object=} arg Argument 10562 * @private 10563 * @method techCall_ 10564 */ 10565 10566 Player.prototype.techCall_ = function techCall_(method, arg) { 10567 //
10567If it's not ready yet, call method when it is 10568 if (this.tech_ && !this.tech_.isReady_) { 10569 this.tech_.ready(function () { 10570 this[method](arg); 10571 }, true); 10572 10573 // Otherwise call method now 10574 } else { 10575 try { 10576 this.tech_[method](arg); 10577 } catch (e) { 10578 _utilsLogJs2['default'](e); 10579 throw e; 10580 } 10581 } 10582 }; 10583 10584 /** 10585 * Get calls can't wait for the tech, and sometimes don't need to. 10586 * 10587 * @param {String} method Tech method 10588 * @return {Method} 10589 * @private 10590 * @method techGet_ 10591 */ 10592 10593 Player.prototype.techGet_ = function techGet_(method) { 10594 if (this.tech_ && this.tech_.isReady_) { 10595 10596 // Flash likes to die and reload when you hide or reposition it. 10597 // In these cases the object methods go away and we get errors. 10598 // When that happens we'll catch the errors and inform tech that it's not ready any more. 10599 try { 10600 return this.tech_[method](); 10601 } catch (e) { 10602 // When building additional tech libs, an expected method may not be defined yet 10603 if (this.tech_[method] === undefined) { 10604 _utilsLogJs2['default']('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e); 10605 } else { 10606 // When a method isn't available on the object it throws a TypeError 10607 if (e.name === 'TypeError') { 10608 _utilsLogJs2['default']('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e); 10609 this.tech_.isReady_ = false; 10610 } else { 10611 _utilsLogJs2['default'](e); 10612 } 10613 } 10614 throw e; 10615 } 10616 } 10617 10618 return; 10619 }; 10620 10621 /** 10622 * start media playback 10623 * ```js 10624 * myPlayer.play(); 10625 * ``` 10626 * 10627 * @return {Player} self 10628 * @method play 10629 */ 10630 10631 Player.prototype.play = function play() { 10632 this.techCall_('play'); 10633 return this; 10634 }; 10635 10636 /** 10637 * Pause the video playback 10638 * ```js 10639 * myPlayer.pause(); 10640 * ``` 10641 * 10642 * @return {Player} self 10643 * @method pause 10644 */ 10645 10646 Player.prototype.pause = function pause() { 10647 this.techCall_('pause'); 10648 return this; 10649 }; 10650 10651 /** 10652 * Check if the player is paused 10653 * ```js 10654 * var isPaused = myPlayer.paused(); 10655 * var isPlaying = !myPlayer.paused(); 10656 * ``` 10657 * 10658 * @return {Boolean} false if the media is currently playing, or true otherwise 10659 * @method paused 10660 */ 10661 10662 Player.prototype.paused = function paused() { 10663 // The initial state of paused should be true (in Safari it's actually false) 10664 return this.techGet_('paused') === false ? false : true; 10665 }; 10666 10667 /** 10668 * Returns whether or not the user is "scrubbing". Scrubbing is when the user 10669 * has clicked the progress bar handle and is dragging it along the progress bar. 10670 * 10671 * @param {Boolean} isScrubbing True/false the user is scrubbing 10672 * @return {Boolean} The scrubbing status when getting 10673 * @return {Object} The player when setting 10674 * @method scrubbing 10675 */ 10676 10677 Player.prototype.scrubbing = function scrubbing(isScrubbing) { 10678 if (isScrubbing !== undefined) { 10679 this.scrubbing_ = !!isScrubbing; 10680 10681 if (isScrubbing) { 10682 this.addClass('vjs-scrubbing'); 10683 } else { 10684 this.removeClass('vjs-scrubbing'); 10685 } 10686 10687 return this; 10688 } 10689 10690 return this.scrubbing_; 10691 }; 10692 10693 /** 10694 * Get or set the current time (in seconds) 10695 * ```js 10696 * // get 10697 * var whereYouAt = myPlayer.currentTime(); 10698 * // set 10699 * myPlayer.currentTime(120); // 2 minutes into the video 10700 * ``` 10701 * 10702 * @param {Number|String=} seconds The time to seek to 10703 * @return {Number} The time in seconds, when not setting 10704 * @return {Player} self, when the current time is set 10705 * @method currentTime 10706 */ 10707 10708 Player.prototype.currentTime = function currentTime(seconds) { 10709 if (seconds !== undefined) { 10710 10711 this.techCall_('setCurrentTime', seconds); 10712 10713 return this; 10714 } 10715 10716 // cache last currentTime and return. default to 0 seconds 10717 // 10718 // Caching the currentTime is meant to prevent a massive amount of reads on the tech's
10719 // currentTime when scrubbing, but may not provide much performance benefit afterall. 10720 // Should be tested. Also something has to read the actual current time or the cache will 10721 // never get updated. 10722 return this.cache_.currentTime = this.techGet_('currentTime') || 0; 10723 }; 10724 10725 /** 10726 * Get the length in time of the video in seconds 10727 * ```js 10728 * var lengthOfVideo = myPlayer.duration(); 10729 * ``` 10730 * **NOTE**: The video must have started loading before the duration can be 10731 * known, and in the case of Flash, may not be known until the video starts 10732 * playing. 10733 * 10734 * @param {Number} seconds Duration when setting 10735 * @return {Number} The duration of the video in seconds when getting 10736 * @method duration 10737 */ 10738 10739 Player.prototype.duration = function duration(seconds) { 10740 if (seconds === undefined) { 10741 return this.cache_.duration || 0; 10742 } 10743 10744 seconds = parseFloat(seconds) || 0; 10745 10746 // Standardize on Inifity for signaling video is live 10747 if (seconds < 0) { 10748 seconds = Infinity; 10749 } 10750 10751 if (seconds !== this.cache_.duration) { 10752 // Cache the last set value for optimized scrubbing (esp. Flash) 10753 this.cache_.duration = seconds; 10754 10755 if (seconds === Infinity) { 10756 this.addClass('vjs-live'); 10757 } else { 10758 this.removeClass('vjs-live'); 10759 } 10760 10761 this.trigger('durationchange'); 10762 } 10763 10764 return this; 10765 }; 10766 10767 /** 10768 * Calculates how much time is left. 10769 * ```js 10770 * var timeLeft = myPlayer.remainingTime(); 10771 * ``` 10772 * Not a native video element function, but useful 10773 * 10774 * @return {Number} The time remaining in seconds 10775 * @method remainingTime 10776 */ 10777 10778 Player.prototype.remainingTime = function remainingTime() { 10779 return this.duration() - this.currentTime(); 10780 }; 10781 10782 // http://dev.w3.org/html5/spec/video.html#dom-media-buffered 10783 // Buffered returns a timerange object. 10784 // Kind of like an array of portions of the video that have been downloaded. 10785 10786 /** 10787 * Get a TimeRange object with the times of the video that have been downloaded 10788 * If you just want the percent of the video that's been downloaded, 10789 * use bufferedPercent. 10790 * ```js 10791 * // Number of different ranges of time have been buffered. Usually 1. 10792 * numberOfRanges = bufferedTimeRange.length, 10793 * // Time in seconds when the first range starts. Usually 0. 10794 * firstRangeStart = bufferedTimeRange.start(0), 10795 * // Time in seconds when the first range ends 10796 * firstRangeEnd = bufferedTimeRange.end(0), 10797 * // Length in seconds of the first time range 10798 * firstRangeLength = firstRangeEnd - firstRangeStart; 10799 * ``` 10800 * 10801 * @return {Object} A mock TimeRange object (following HTML spec) 10802 * @method buffered 10803 */ 10804 10805 Player.prototype.buffered = function buffered() { 10806 var buffered = this.techGet_('buffered'); 10807 10808 if (!buffered || !buffered.length) { 10809 buffered = _utilsTimeRangesJs.createTimeRange(0, 0); 10810 } 10811 10812 return buffered; 10813 }; 10814 10815 /** 10816 * Get the percent (as a decimal) of the video that's been downloaded 10817 * ```js 10818 * var howMuchIsDownloaded = myPlayer.bufferedPercent(); 10819 * ``` 10820 * 0 means none, 1 means all. 10821 * (This method isn't in the HTML5 spec, but it's very convenient) 10822 * 10823 * @return {Number} A decimal between 0 and 1 representing the percent 10824 * @method bufferedPercent 10825 */ 10826 10827 Player.prototype.bufferedPercent = function bufferedPercent() { 10828 return _utilsBufferJs.bufferedPercent(this.buffered(), this.duration()); 10829 }; 10830 10831 /** 10832 * Get the ending time of the last buffered time range 10833 * This is used in the progress bar to encapsulate all time ranges. 10834 * 10835 * @return {Number} The end of the last buffered time range 10836 * @method bufferedEnd 10837 */ 10838 10839 Player.prototype.bufferedEnd = function bufferedEnd() { 10840 var buffered = this.buffered(), 10841 duration = this.duration(), 10842 end = buffered.end(buffered.length - 1); 10843 10844 if (end > duration) { 10845 end = duration; 10846 } 10847 10848 return end; 10849 }; 10850 10851 /** 10852 * Get or set the current volume of the media 10853 * ```js 10854 * // get 10855 * var howLoudIsIt = myPlayer.volume(); 10856 * // set 10857 * myPlayer.volume(0.5); // Set volume to half 10858 * ``` 10859 * 0 is off (muted), 1.0 is all the way up, 0.5 is half way. 10860 * 10861 * @param {Number} percentAsDecimal The new volume as a decimal percent 10862 * @return {Number} The current volume when getting 10863 * @return {Player} self when setting 10864 * @method volume 10865 */ 10866 10867 Player.prototype.volume = function volume(percentAsDecimal) { 10868 var vol = undefined; 10869 10870 if (percentAsDecimal !== undefined) { 10871 vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); // Force value to between 0 and 1 10872 this.cache_.volume = vol; 10873 this.techCall_('setVolume', vol); 10874 10875 return this; 10876 } 10877 10878 // Default to 1 when returning current volume. 10879 vol = parseFloat(this.techGet_('volume')); 10880 return isNaN(vol) ? 1 : vol; 10881 }; 10882 10883 /** 10884 * Get the current muted state, or turn mute on or off 10885 * ```js 10886 * // get 10887 * var isVolumeMuted = myPlayer.muted(); 10888 * // set 10889 * myPlayer.muted(true); // mute the volume 10890 * ``` 10891 * 10892 * @param {Boolean=} muted True to mute, false to unmute 10893 * @return {Boolean} True if mute is on, false if not when getting 10894 * @return {Player} self when setting mute 10895 * @method muted 10896 */ 10897 10898 Player.prototype.muted = function muted(_muted) { 10899 if (_muted !== undefined) { 10900 this.techCall_('setMuted', _muted); 10901 return this; 10902 } 10903 return this.techGet_('muted') || false; // Default to false 10904 }; 10905 10906 // Check if current tech can support native fullscreen 10907 // (e.g. with built in controls like iOS, so not our flash swf) 10908 /** 10909 * Check to see if fullscreen is supported 10910 * 10911 * @return {Boolean} 10912 * @method supportsFullScreen 10913 */ 10914 10915 Player.prototype.supportsFullScreen = function supportsFullScreen() { 10916 return this.techGet_('supportsFullScreen') || false; 10917 }; 10918 10919 /** 10920 * Check if the player is in fullscreen mode 10921 * ```js 10922 * // get
10923 * var fullscreenOrNot = myPlayer.isFullscreen(); 10924 * // set 10925 * myPlayer.isFullscreen(true); // tell the player it's in fullscreen 10926 * ``` 10927 * NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official 10928 * property and instead document.fullscreenElement is used. But isFullscreen is 10929 * still a valuable property for internal player workings. 10930 * 10931 * @param {Boolean=} isFS Update the player's fullscreen state 10932 * @return {Boolean} true if fullscreen false if not when getting 10933 * @return {Player} self when setting 10934 * @method isFullscreen 10935 */ 10936 10937 Player.prototype.isFullscreen = function isFullscreen(isFS) { 10938 if (isFS !== undefined) { 10939 this.isFullscreen_ = !!isFS; 10940 return this; 10941 } 10942 return !!this.isFullscreen_; 10943 }; 10944 10945 /** 10946 * Increase the size of the video to full screen 10947 * ```js 10948 * myPlayer.requestFullscreen(); 10949 * ``` 10950 * In some browsers, full screen is not supported natively, so it enters 10951 * "full window mode", where the video fills the browser window. 10952 * In browsers and devices that support native full screen, sometimes the 10953 * browser's default controls will be shown, and not the Video.js custom skin. 10954 * This includes most mobile devices (iOS, Android) and older versions of 10955 * Safari. 10956 * 10957 * @return {Player} self 10958 * @method requestFullscreen 10959 */ 10960 10961 Player.prototype.requestFullscreen = function requestFullscreen() { 10962 var fsApi = _fullscreenApiJs2['default']; 10963 10964 this.isFullscreen(true); 10965 10966 if (fsApi.requestFullscreen) { 10967 // the browser supports going fullscreen at the element level so we can 10968 // take the controls fullscreen as well as the video 10969 10970 // Trigger fullscreenchange event after change 10971 // We have to specifically add this each time, and remove 10972 // when canceling fullscreen. Otherwise if there's multiple 10973 // players on a page, they would all be reacting to the same fullscreen 10974 // events 10975 Events.on(_globalDocument2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) { 10976 this.isFullscreen(_globalDocument2['default'][fsApi.fullscreenElement]); 10977 10978 // If cancelling fullscreen, remove event listener. 10979 if (this.isFullscreen() === false) { 10980 Events.off(_globalDocument2['default'], fsApi.fullscreenchange, documentFullscreenChange); 10981 } 10982 10983 this.trigger('fullscreenchange'); 10984 })); 10985 10986 this.el_[fsApi.requestFullscreen](); 10987 } else if (this.tech_.supportsFullScreen()) { 10988 // we can't take the video.js controls fullscreen but we can go fullscreen 10989 // with native controls 10990 this.techCall_('enterFullScreen'); 10991 } else { 10992 // fullscreen isn't supported so we'll just stretch the video element to 10993 // fill the viewport 10994 this.enterFullWindow(); 10995 this.trigger('fullscreenchange'); 10996 } 10997 10998 return this; 10999 }; 11000 11001 /** 11002 * Return the video to its normal size after having been in full screen mode 11003 * ```js 11004 * myPlayer.exitFullscreen(); 11005 * ``` 11006 * 11007 * @return {Player} self 11008 * @method exitFullscreen 11009 */ 11010 11011 Player.prototype.exitFullscreen = function exitFullscreen() { 11012 var fsApi = _fullscreenApiJs2['default']; 11013 this.isFullscreen(false); 11014 11015 // Check for browser element fullscreen support 11016 if (fsApi.requestFullscreen) { 11017 _globalDocument2['default'][fsApi.exitFullscreen](); 11018 } else if (this.tech_.supportsFullScreen()) { 11019 this.techCall_('exitFullScreen'); 11020 } else { 11021 this.exitFullWindow(); 11022 this.trigger('fullscreenchange'); 11023 } 11024 11025 return this; 11026 }; 11027 11028 /** 11029 * When fullscreen isn't supported we can stretch the video container to as wide as the browser will let us. 11030 * 11031 * @method enterFullWindow 11032 */ 11033 11034 Player.prototype.enterFullWindow = function enterFullWindow() { 11035 this.isFullWindow = true; 11036 11037 // Storing original doc overflow value to return to when fullscreen is off 11038 this.docOrigOverflow = _globalDocument2['default'].documentElement.style.overflow; 11039 11040 // Add listener for esc key to exit fullscreen 11041 Events.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey)); 11042 11043 // Hide any scroll bars 11044 _globalDocument2['default'].documentElement.style.overflow = 'hidden'; 11045 11046 // Apply fullscreen styles 11047 Dom.addElClass(_globalDocument2['default'].body, 'vjs-full-window'); 11048 11049 this.trigger('enterFullWindow'); 11050 }; 11051 11052 /** 11053 * Check for call to either exit full window or full screen on ESC key 11054 * 11055 * @param {String} event Event to check for key press 11056 * @method fullWindowOnEscKey 11057 */ 11058 11059 Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) { 11060 if (event.keyCode === 27) { 11061 if (this.isFullscreen() === true) { 11062 this.exitFullscreen(); 11063 } else { 11064 this.exitFullWindow(); 11065 } 11066 } 11067 }; 11068 11069 /** 11070 * Exit full window 11071 * 11072 * @method exitFullWindow 11073 */ 11074 11075 Player.prototype.exitFullWindow = function exitFullWindow() { 11076 this.isFullWindow = false;
11077 Events.off(_globalDocument2['default'], 'keydown', this.fullWindowOnEscKey); 11078 11079 // Unhide scroll bars. 11080 _globalDocument2['default'].documentElement.style.overflow = this.docOrigOverflow; 11081 11082 // Remove fullscreen styles 11083 Dom.removeElClass(_globalDocument2['default'].body, 'vjs-full-window'); 11084 11085 // Resize the box, controller, and poster to original sizes 11086 // this.positionAll(); 11087 this.trigger('exitFullWindow'); 11088 }; 11089 11090 /** 11091 * Check whether the player can play a given mimetype 11092 * 11093 * @param {String} type The mimetype to check 11094 * @return {String} 'probably', 'maybe', or '' (empty string) 11095 * @method canPlayType 11096 */ 11097 11098 Player.prototype.canPlayType = function canPlayType(type) { 11099 var can = undefined; 11100 11101 // Loop through each playback technology in the options order 11102 for (var i = 0, j = this.options_.techOrder; i < j.length; i++) { 11103 var techName = _utilsToTitleCaseJs2['default'](j[i]); 11104 var tech = _techTechJs2['default'].getTech(techName); 11105 11106 // Support old behavior of techs being registered as components. 11107 // Remove once that deprecated behavior is removed. 11108 if (!tech) { 11109 tech = _componentJs2['default'].getComponent(techName); 11110 } 11111 11112 // Check if the current tech is defined before continuing 11113 if (!tech) { 11114 _utilsLogJs2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.'); 11115 continue; 11116 } 11117 11118 // Check if the browser supports this technology 11119 if (tech.isSupported()) { 11120 can = tech.canPlayType(type); 11121 11122 if (can) { 11123 return can; 11124 } 11125 } 11126 } 11127 11128 return ''; 11129 }; 11130 11131 /** 11132 * Select source based on tech-order or source-order 11133 * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise, 11134 * defaults to tech-order selection 11135 * 11136 * @param {Array} sources The sources for a media asset 11137 * @return {Object|Boolean} Object of source and tech order, otherwise false 11138 * @method selectSource 11139 */ 11140 11141 Player.prototype.selectSource = function selectSource(sources) { 11142 // Get only the techs specified in `techOrder` that exist and are supported by the 11143 // current platform 11144 var techs = this.options_.techOrder.map(_utilsToTitleCaseJs2['default']).map(function (techName) { 11145 // `Component.getComponent(...)` is for support of old behavior of techs 11146 // being registered as components. 11147 // Remove once that deprecated behavior is removed. 11148 return [techName, _techTechJs2['default'].getTech(techName) || _componentJs2['default'].getComponent(techName)]; 11149 }).filter(function (_ref) { 11150 var techName = _ref[0]; 11151 var tech = _ref[1]; 11152 11153 // Check if the current tech is defined before continuing 11154 if (tech) { 11155 // Check if the browser supports this technology 11156 return tech.isSupported(); 11157 } 11158 11159 _utilsLogJs2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.'); 11160 return false; 11161 }); 11162 11163 // Iterate over each `innerArray` element once per `outerArray` element and execute 11164 // `tester` with both. If `tester` returns a non-falsy value, exit early and return 11165 // that value. 11166 var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) { 11167 var found = undefined; 11168 11169 outerArray.some(function (outerChoice) { 11170 return innerArray.some(function (innerChoice) { 11171 found = tester(outerChoice, innerChoice); 11172 11173 if (found) { 11174 return true; 11175 } 11176 }); 11177 }); 11178 11179 return found; 11180 }; 11181 11182 var foundSourceAndTech = undefined; 11183 var flip = function flip(fn) { 11184 return function (a, b) { 11185 return fn(b, a); 11186 }; 11187 }; 11188 var finder = function finder(_ref2, source) { 11189 var techName = _ref2[0]; 11190 var tech = _ref2[1]; 11191 11192 if (tech.canPlaySource(source)) { 11193 return { source: source, tech: techName }; 11194 } 11195 }; 11196 11197 // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources 11198 // to select from them based on their priority. 11199 if (this.options_.sourceOrder) { 11200 // Source-first ordering 11201 foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder)); 11202 } else { 11203 // Tech-first ordering 11204 foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder); 11205 } 11206 11207 return foundSourceAndTech || false; 11208 }; 11209 11210 /** 11211 * The source function updates the video source 11212 * There are three types of variables you can pass as the argument. 11213 * **URL String**: A URL to the the video file. Use this method if you are sure 11214 * the current playback technology (HTML5/Flash) can support the source you 11215 * provide. Currently only MP4 files can be used in both HTML5 and Flash. 11216 * ```js 11217 * myPlayer.src("http://www.example.com/path/to/video.mp4"); 11218 * ```
11219 * **Source Object (or element):* * A javascript object containing information 11220 * about the source file. Use this method if you want the player to determine if 11221 * it can support the file using the type information. 11222 * ```js 11223 * myPlayer.src({ type: "video/mp4", src: "http://www.example.com/path/to/video.mp4" }); 11224 * ``` 11225 * **Array of Source Objects:* * To provide multiple versions of the source so 11226 * that it can be played using HTML5 across browsers you can use an array of 11227 * source objects. Video.js will detect which version is supported and load that 11228 * file. 11229 * ```js 11230 * myPlayer.src([ 11231 * { type: "video/mp4", src: "http://www.example.com/path/to/video.mp4" }, 11232 * { type: "video/webm", src: "http://www.example.com/path/to/video.webm" }, 11233 * { type: "video/ogg", src: "http://www.example.com/path/to/video.ogv" } 11234 * ]); 11235 * ``` 11236 * 11237 * @param {String|Object|Array=} source The source URL, object, or array of sources 11238 * @return {String} The current video source when getting 11239 * @return {String} The player when setting 11240 * @method src 11241 */ 11242 11243 Player.prototype.src = function src(source) { 11244 if (source === undefined) { 11245 return this.techGet_('src'); 11246 } 11247 11248 var currentTech = _techTechJs2['default'].getTech(this.techName_); 11249 // Support old behavior of techs being registered as components. 11250 // Remove once that deprecated behavior is removed. 11251 if (!currentTech) { 11252 currentTech = _componentJs2['default'].getComponent(this.techName_); 11253 } 11254 11255 // case: Array of source objects to choose from and pick the best to play 11256 if (Array.isArray(source)) { 11257 this.sourceList_(source); 11258 11259 // case: URL String (http://myvideo...) 11260 } else if (typeof source === 'string') { 11261 // create a source object from the string 11262 this.src({ src: source }); 11263 11264 // case: Source object { src: '', type: '' ... } 11265 } else if (source instanceof Object) { 11266 // check if the source has a type and the loaded tech cannot play the source 11267 // if there's no type we'll just try the current tech 11268 if (source.type && !currentTech.canPlaySource(source)) { 11269 // create a source list with the current source and send through 11270 // the tech loop to check for a compatible technology 11271 this.sourceList_([source]); 11272 } else { 11273 this.cache_.src = source.src; 11274 this.currentType_ = source.type || ''; 11275 11276 // wait until the tech is ready to set the source 11277 this.ready(function () { 11278 11279 // The setSource tech method was added with source handlers 11280 // so older techs won't support it 11281 // We need to check the direct prototype for the case where subclasses 11282 // of the tech do not support source handlers 11283 if (currentTech.prototype.hasOwnProperty('setSource')) { 11284 this.techCall_('setSource', source); 11285 } else { 11286 this.techCall_('src', source.src); 11287 } 11288 11289 if (this.options_.preload === 'auto') { 11290 this.load(); 11291 } 11292 11293 if (this.options_.autoplay) { 11294 this.play(); 11295 } 11296 11297 // Set the source synchronously if possible (#2326) 11298 }, true); 11299 } 11300 } 11301 11302 return this; 11303 }; 11304 11305 /** 11306 * Handle an array of source objects 11307 * 11308 * @param {Array} sources Array of source objects 11309 * @private 11310 * @method sourceList_ 11311 */ 11312 11313 Player.prototype.sourceList_ = function sourceList_(sources) { 11314 var sourceTech = this.selectSource(sources); 11315 11316 if (sourceTech) { 11317 if (sourceTech.tech === this.techName_) { 11318 // if this technology is already loaded, set the source 11319 this.src(sourceTech.source); 11320 } else { 11321 // load this technology with the chosen source 11322 this.loadTech_(sourceTech.tech, sourceTech.source); 11323 } 11324 } else { 11325 // We need to wrap this in a timeout to give folks a chance to add error event handlers 11326 this.setTimeout(function () { 11327 this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) }); 11328 }, 0); 11329 11330 // we could not find an appropriate tech, but let's still notify the delegate that this is it 11331 // this needs a better comment about why this is needed 11332 this.triggerReady(); 11333 } 11334 }; 11335 11336 /** 11337 * Begin loading the src data. 11338 * 11339 * @return {Player} Returns the player 11340 * @method load 11341 */ 11342 11343 Player.prototype.load = function load() { 11344 this.techCall_('load'); 11345 return this; 11346 }; 11347 11348 /** 11349 * Reset the player. Loads the first tech in the techOrder, 11350 * and calls `reset` on the tech`. 11351 * 11352 * @return {Player} Returns the player 11353 * @method reset 11354 */ 11355 11356 Player.prototype.reset = function reset() { 11357 this.loadTech_(_utilsToTitleCaseJs2['default'](this.options_.techOrder[0]), null); 11358 this.techCall_('reset'); 11359 return this; 11360 }; 11361 11362 /** 11363 * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4 11364 * Can be used in conjuction with `currentType` to assist in rebuilding the current source object. 11365 * 11366 * @return {String} The current source 11367 * @method currentSrc 11368 */ 11369 11370 Player.prototype.currentSrc = function currentSrc() { 11371 return this.techGet_('currentSrc') || this.cache_.src || ''; 11372 }; 11373 11374 /** 11375 * Get the current source type e.g. video/mp4 11376 * This can allow you rebuild the current source object so that you could load the same 11377 * source and tech later 11378 * 11379 * @return {String} The source MIME type 11380 * @method currentType 11381 */ 11382 11383 Player.prototype.currentType = function currentType() { 11384 return this.currentType_ || ''; 11385 }; 11386 11387 /** 11388 * Get or set the preload attribute 11389 * 11390 * @param {Boolean} value Boolean to determine if preload should be used 11391 * @return {String} The preload attribute value when getting 11392 * @return {Player} Returns the player when setting 11393 * @method preload 11394 */ 11395 11396 Player.prototype.preload = function preload(value) { 11397 if (value !== undefined) { 11398 this.techCall_('setPreload', value); 11399 this.options_.preload = value; 11400 return this; 11401 } 11402 return this.techGet_('preload'); 11403 }; 11404 11405 /** 11406 * Get or set the autoplay attribute. 11407 * 11408 * @param {Boolean} value Boolean to determine if video should autoplay 11409 * @return {String} The autoplay attribute value when getting 11410 * @return {Player} Returns the player when setting 11411 * @method autoplay 11412 */ 11413 11414 Player.prototype.autoplay = function autoplay(value) { 11415 if (value !== undefined) { 11416 this.techCall_('setAutoplay', value); 11417 this.options_.autoplay = value; 11418 return this; 11419 } 11420 return this.techGet_('autoplay', value); 11421 }; 11422 11423 /** 11424 * Get or set the loop attribute on the video element. 11425 * 11426 * @param {Boolean} value Boolean to determine if video should loop 11427 * @return {String} The loop attribute value when getting 11428 * @return {Player} Returns the player when setting 11429 * @method loop 11430 */ 11431 11432 Player.prototype.loop = function loop(value) { 11433 if (value !== undefined) { 11434 this.techCall_('setLoop', value); 11435 this.options_['loop'] = value; 11436 return this; 11437 } 11438 return this.techGet_('loop'); 11439 }; 11440 11441 /** 11442 * Get or set the poster image source url 11443 * 11444 * ##### EXAMPLE: 11445 * ```js 11446 * // get 11447 * var currentPoster = myPlayer.poster(); 11448 * // set 11449 * myPlayer.poster('http://example.com/myImage.jpg'); 11450 * ``` 11451 * 11452 * @param {String=} src Poster image source URL 11453 * @return {String} poster URL when getting 11454 * @return {Player} self when setting 11455 * @method poster 11456 */ 11457 11458 Player.prototype.poster = function poster(src) { 11459 if (src === undefined) { 11460 return this.poster_; 11461 } 11462 11463 // The correct way to remove a poster is to set as an empty string 11464 // other falsey values will throw errors 11465 if (!src) { 11466 src = ''; 11467 } 11468 11469 // update the internal poster variable 11470 this.poster_ = src; 11471 11472 // update the tech's poster 11473 this.techCall_('setPoster', src); 11474 11475 // alert components that the poster has been set 11476 this.trigger('posterchange'); 11477 11478 return this; 11479 }; 11480 11481 /** 11482 * Some techs (e.g. YouTube) can provide a poster source in an 11483 * asynchronous way. We want the poster component to use this 11484 * poster source so that it covers up the tech's controls. 11485 * (YouTube's play button). However we only want to use this 11486 * soruce if the player user hasn't set a poster through 11487 * the normal APIs. 11488 * 11489 * @private 11490 * @method handleTechPosterChange_ 11491 */ 11492 11493 Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() { 11494 if (!this.poster_ && this.tech_ && this.tech_.poster) { 11495 this.poster_ = this.tech_.poster() || ''; 11496 11497 // Let components know the poster has changed 11498 this.trigger('posterchange'); 11499 } 11500 }; 11501 11502 /** 11503 * Get or set whether or not the controls are showing. 11504 * 11505 * @param {Boolean} bool Set controls to showing or not 11506 * @return {Boolean} Controls are showing 11507 * @method controls 11508 */ 11509 11510 Player.prototype.controls = function controls(bool) { 11511 if (bool !== undefined) { 11512 bool = !!bool; // force boolean 11513 // Don't trigger a change event unless it actually changed 11514 if (this.controls_ !== bool) { 11515 this.controls_ = bool; 11516 11517 if (this.usingNativeControls()) { 11518 this.techCall_('setControls', bool); 11519 } 11520 11521 if (bool) { 11522 this.removeClass('vjs-controls-disabled'); 11523 this.addClass('vjs-controls-enabled'); 11524 this.trigger('controlsenabled'); 11525 11526 if (!this.usingNativeControls()) {
11527 this.addTechControlsListeners_(); 11528 } 11529 } else { 11530 this.removeClass('vjs-controls-enabled'); 11531 this.addClass('vjs-controls-disabled'); 11532 this.trigger('controlsdisabled'); 11533 11534 if (!this.usingNativeControls()) { 11535 this.removeTechControlsListeners_(); 11536 } 11537 } 11538 } 11539 return this; 11540 } 11541 return !!this.controls_; 11542 }; 11543 11544 /** 11545 * Toggle native controls on/off. Native controls are the controls built into 11546 * devices (e.g. default iPhone controls), Flash, or other techs 11547 * (e.g. Vimeo Controls) 11548 * **This should only be set by the current tech, because only the tech knows 11549 * if it can support native controls** 11550 * 11551 * @param {Boolean} bool True signals that native controls are on 11552 * @return {Player} Returns the player 11553 * @private 11554 * @method usingNativeControls 11555 */ 11556 11557 Player.prototype.usingNativeControls = function usingNativeControls(bool) { 11558 if (bool !== undefined) { 11559 bool = !!bool; // force boolean 11560 // Don't trigger a change event unless it actually changed 11561 if (this.usingNativeControls_ !== bool) { 11562 this.usingNativeControls_ = bool; 11563 if (bool) { 11564 this.addClass('vjs-using-native-controls'); 11565 11566 /** 11567 * player is using the native device controls 11568 * 11569 * @event usingnativecontrols 11570 * @memberof Player 11571 * @instance 11572 * @private 11573 */ 11574 this.trigger('usingnativecontrols'); 11575 } else { 11576 this.removeClass('vjs-using-native-controls'); 11577 11578 /** 11579 * player is using the custom HTML controls 11580 * 11581 * @event usingcustomcontrols 11582 * @memberof Player 11583 * @instance 11584 * @private 11585 */ 11586 this.trigger('usingcustomcontrols'); 11587 } 11588 } 11589 return this; 11590 } 11591 return !!this.usingNativeControls_; 11592 }; 11593 11594 /** 11595 * Set or get the current MediaError 11596 * 11597 * @param {*} err A MediaError or a String/Number to be turned into a MediaError 11598 * @return {MediaError|null} when getting 11599 * @return {Player} when setting 11600 * @method error 11601 */ 11602 11603 Player.prototype.error = function error(err) { 11604 if (err === undefined) { 11605 return this.error_ || null; 11606 } 11607 11608 // restoring to default 11609 if (err === null) { 11610 this.error_ = err; 11611 this.removeClass('vjs-error'); 11612 this.errorDisplay.close(); 11613 return this; 11614 } 11615 11616 // error instance 11617 if (err instanceof _mediaErrorJs2['default']) { 11618 this.error_ = err; 11619 } else { 11620 this.error_ = new _mediaErrorJs2['default'](err); 11621 } 11622 11623 // add the vjs-error classname to the player 11624 this.addClass('vjs-error'); 11625 11626 // log the name of the error type and any message 11627 // ie8 just logs "[object object]" if you just log the error object 11628 _utilsLogJs2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaErrorJs2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_); 11629 11630 // fire an error event on the player 11631 this.trigger('error'); 11632 11633 return this; 11634 }; 11635 11636 /** 11637 * Returns whether or not the player is in the "ended" state. 11638 * 11639 * @return {Boolean} True if the player is in the ended state, false if not. 11640 * @method ended 11641 */ 11642 11643 Player.prototype.ended = function ended() { 11644 return this.techGet_('ended'); 11645 }; 11646 11647 /** 11648 * Returns whether or not the player is in the "seeking" state. 11649 * 11650 * @return {Boolean} True if the player is in the seeking state, false if not. 11651 * @method seeking 11652 */ 11653 11654 Player.prototype.seeking = function seeking() { 11655 return this.techGet_('seeking'); 11656 }; 11657 11658 /** 11659 * Returns the TimeRanges of the media that are currently available 11660 * for seeking to. 11661 * 11662 * @return {TimeRanges} the seekable intervals of the media timeline 11663 * @method seekable 11664 */ 11665 11666 Player.prototype.seekable = function seekable() { 11667 return this.techGet_('seekable'); 11668 }; 11669 11670 /** 11671 * Report user activity 11672 * 11673 * @param {Object} event Event object 11674 * @method reportUserActivity 11675 */ 11676
11677 Player.prototype.reportUserActivity = function reportUserActivity(event) { 11678 this.userActivity_ = true; 11679 }; 11680 11681 /** 11682 * Get/set if user is active 11683 * 11684 * @param {Boolean} bool Value when setting 11685 * @return {Boolean} Value if user is active user when getting 11686 * @method userActive 11687 */ 11688 11689 Player.prototype.userActive = function userActive(bool) { 11690 if (bool !== undefined) { 11691 bool = !!bool; 11692 if (bool !== this.userActive_) { 11693 this.userActive_ = bool; 11694 if (bool) { 11695 // If the user was inactive and is now active we want to reset the 11696 // inactivity timer 11697 this.userActivity_ = true; 11698 this.removeClass('vjs-user-inactive'); 11699 this.addClass('vjs-user-active'); 11700 this.trigger('useractive'); 11701 } else { 11702 // We're switching the state to inactive manually, so erase any other 11703 // activity 11704 this.userActivity_ = false; 11705 11706 // Chrome/Safari/IE have bugs where when you change the cursor it can 11707 // trigger a mousemove event. This causes an issue when you're hiding 11708 // the cursor when the user is inactive, and a mousemove signals user 11709 // activity. Making it impossible to go into inactive mode. Specifically 11710 // this happens in fullscreen when we really need to hide the cursor. 11711 // 11712 // When this gets resolved in ALL browsers it can be removed 11713 // https://code.google.com/p/chromium/issues/detail?id=103041 11714 if (this.tech_) { 11715 this.tech_.one('mousemove', function (e) { 11716 e.stopPropagation(); 11717 e.preventDefault(); 11718 }); 11719 } 11720 11721 this.removeClass('vjs-user-active'); 11722 this.addClass('vjs-user-inactive'); 11723 this.trigger('userinactive'); 11724 } 11725 } 11726 return this; 11727 } 11728 return this.userActive_; 11729 }; 11730 11731 /** 11732 * Listen for user activity based on timeout value 11733 * 11734 * @private 11735 * @method listenForUserActivity_ 11736 */ 11737 11738 Player.prototype.listenForUserActivity_ = function listenForUserActivity_() { 11739 var mouseInProgress = undefined, 11740 lastMoveX = undefined, 11741 lastMoveY = undefined; 11742 11743 var handleActivity = Fn.bind(this, this.reportUserActivity); 11744 11745 var handleMouseMove = function handleMouseMove(e) { 11746 // #1068 - Prevent mousemove spamming 11747 // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970 11748 if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) { 11749 lastMoveX = e.screenX; 11750 lastMoveY = e.screenY; 11751 handleActivity(); 11752 } 11753 }; 11754 11755 var handleMouseDown = function handleMouseDown() { 11756 handleActivity(); 11757 // For as long as the they are touching the device or have their mouse down, 11758 // we consider them active even if they're not moving their finger or mouse. 11759 // So we want to continue to update that they are active 11760 this.clearInterval(mouseInProgress); 11761 // Setting userActivity=true now and setting the interval to the same time 11762 // as the activityCheck interval (250) should ensure we never miss the 11763 // next activityCheck 11764 mouseInProgress = this.setInterval(handleActivity, 250); 11765 }; 11766 11767 var handleMouseUp = function handleMouseUp(event) { 11768 handleActivity(); 11769 // Stop the interval that maintains activity if the mouse/touch is down 11770 this.clearInterval(mouseInProgress); 11771 }; 11772 11773 // Any mouse movement will be considered user activity 11774 this.on('mousedown', handleMouseDown); 11775 this.on('mousemove', handleMouseMove); 11776 this.on('mouseup', handleMouseUp); 11777 11778 // Listen for keyboard navigation 11779 // Shouldn't need to use inProgress interval because of key repeat 11780 this.on('keydown', handleActivity); 11781 this.on('keyup', handleActivity); 11782 11783 // Run an interval every 250 milliseconds instead of stuffing everything into 11784 // the mousemove/touchmove function itself, to prevent performance degradation. 11785 // `this.reportUserActivity` simply sets this.userActivity_ to true, which 11786 // then gets picked up by this loop 11787 // http://ejohn.org/blog/learning-from-twitter/ 11788 var inactivityTimeout = undefined; 11789 var activityCheck = this.setInterval(function () { 11790 // Check to see if mouse/touch activity has happened 11791 if (this.userActivity_) { 11792 // Reset the activity tracker 11793 this.userActivity_ = false;
11794 11795 // If the user state was inactive, set the state to active 11796 this.userActive(true); 11797 11798 // Clear any existing inactivity timeout to start the timer over 11799 this.clearTimeout(inactivityTimeout); 11800 11801 var timeout = this.options_['inactivityTimeout']; 11802 if (timeout > 0) { 11803 // In <timeout> milliseconds, if no more activity has occurred the 11804 // user will be considered inactive 11805 inactivityTimeout = this.setTimeout(function () { 11806 // Protect against the case where the inactivityTimeout can trigger just 11807 // before the next user activity is picked up by the activityCheck loop 11808 // causing a flicker 11809 if (!this.userActivity_) { 11810 this.userActive(false); 11811 } 11812 }, timeout); 11813 } 11814 } 11815 }, 250); 11816 }; 11817 11818 /** 11819 * Gets or sets the current playback rate. A playback rate of 11820 * 1.0 represents normal speed and 0.5 would indicate half-speed 11821 * playback, for instance. 11822 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate 11823 * 11824 * @param {Number} rate New playback rate to set. 11825 * @return {Number} Returns the new playback rate when setting 11826 * @return {Number} Returns the current playback rate when getting 11827 * @method playbackRate 11828 */ 11829 11830 Player.prototype.playbackRate = function playbackRate(rate) { 11831 if (rate !== undefined) { 11832 this.techCall_('setPlaybackRate', rate); 11833 return this; 11834 } 11835 11836 if (this.tech_ && this.tech_['featuresPlaybackRate']) { 11837 return this.techGet_('playbackRate'); 11838 } else { 11839 return 1.0; 11840 } 11841 }; 11842 11843 /** 11844 * Gets or sets the audio flag 11845 * 11846 * @param {Boolean} bool True signals that this is an audio player. 11847 * @return {Boolean} Returns true if player is audio, false if not when getting 11848 * @return {Player} Returns the player if setting 11849 * @private 11850 * @method isAudio 11851 */ 11852 11853 Player.prototype.isAudio = function isAudio(bool) { 11854 if (bool !== undefined) { 11855 this.isAudio_ = !!bool; 11856 return this; 11857 } 11858 11859 return !!this.isAudio_; 11860 }; 11861 11862 /** 11863 * Returns the current state of network activity for the element, from 11864 * the codes in the list below. 11865 * - NETWORK_EMPTY (numeric value 0) 11866 * The element has not yet been initialised. All attributes are in 11867 * their initial states. 11868 * - NETWORK_IDLE (numeric value 1) 11869 * The element's resource selection algorithm is active and has 11870 * selected a resource, but it is not actually using the network at 11871 * this time. 11872 * - NETWORK_LOADING (numeric value 2) 11873 * The user agent is actively trying to download data. 11874 * - NETWORK_NO_SOURCE (numeric value 3) 11875 * The element's resource selection algorithm is active, but it has 11876 * not yet found a resource to use. 11877 * 11878 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states 11879 * @return {Number} the current network activity state 11880 * @method networkState 11881 */ 11882 11883 Player.prototype.networkState = function networkState() { 11884 return this.techGet_('networkState'); 11885 }; 11886 11887 /** 11888 * Returns a value that expresses the current state of the element 11889 * with respect to rendering the current playback position, from the 11890 * codes in the list below. 11891 * - HAVE_NOTHING (numeric value 0) 11892 * No information regarding the media resource is available. 11893 * - HAVE_METADATA (numeric value 1) 11894 * Enough of the resource has been obtained that the duration of the 11895 * resource is available. 11896 * - HAVE_CURRENT_DATA (numeric value 2) 11897 * Data for the immediate current playback position is available. 11898 * - HAVE_FUTURE_DATA (numeric value 3) 11899 * Data for the immediate current playback position is available, as 11900 * well as enough data for the user agent to advance the current 11901 * playback position in the direction of playback. 11902 * - HAVE_ENOUGH_DATA (numeric value 4) 11903 * The user agent estimates that enough data is available for 11904 * playback to proceed uninterrupted. 11905 * 11906 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate 11907 * @return {Number} the current playback rendering state 11908 * @method readyState 11909 */ 11910 11911 Player.prototype.readyState = function readyState() { 11912 return this.techGet_('readyState'); 11913 }; 11914 11915 /* 11916 * Text tracks are tracks of timed text events. 11917 * Captions - text displayed over the video for the hearing impaired
11918 * Subtitles - text displayed over the video for those who don't understand language in the video 11919 * Chapters - text displayed in a menu allowing the user to jump to particular points (chapters) in the video 11920 * Descriptions (not supported yet) - audio descriptions that are read back to the user by a screen reading device 11921 */ 11922 11923 /** 11924 * Get an array of associated text tracks. captions, subtitles, chapters, descriptions 11925 * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks 11926 * 11927 * @return {Array} Array of track objects 11928 * @method textTracks 11929 */ 11930 11931 Player.prototype.textTracks = function textTracks() { 11932 // cannot use techGet_ directly because it checks to see whether the tech is ready. 11933 // Flash is unlikely to be ready in time but textTracks should still work. 11934 return this.tech_ && this.tech_['textTracks'](); 11935 }; 11936 11937 /** 11938 * Get an array of remote text tracks 11939 * 11940 * @return {Array} 11941 * @method remoteTextTracks 11942 */ 11943 11944 Player.prototype.remoteTextTracks = function remoteTextTracks() { 11945 return this.tech_ && this.tech_['remoteTextTracks'](); 11946 }; 11947 11948 /** 11949 * Get an array of remote html track elements 11950 * 11951 * @return {HTMLTrackElement[]} 11952 * @method remoteTextTrackEls 11953 */ 11954 11955 Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() { 11956 return this.tech_ && this.tech_['remoteTextTrackEls'](); 11957 }; 11958 11959 /** 11960 * Add a text track 11961 * In addition to the W3C settings we allow adding additional info through options. 11962 * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack 11963 * 11964 * @param {String} kind Captions, subtitles, chapters, descriptions, or metadata 11965 * @param {String=} label Optional label 11966 * @param {String=} language Optional language 11967 * @method addTextTrack 11968 */ 11969 11970 Player.prototype.addTextTrack = function addTextTrack(kind, label, language) { 11971 return this.tech_ && this.tech_['addTextTrack'](kind, label, language); 11972 }; 11973 11974 /** 11975 * Add a remote text track 11976 * 11977 * @param {Object} options Options for remote text track 11978 * @method addRemoteTextTrack 11979 */ 11980 11981 Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options) { 11982 return this.tech_ && this.tech_['addRemoteTextTrack'](options); 11983 }; 11984 11985 /** 11986 * Remove a remote text track 11987 * 11988 * @param {Object} track Remote text track to remove 11989 * @method removeRemoteTextTrack 11990 */ 11991 11992 Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) { 11993 this.tech_ && this.tech_['removeRemoteTextTrack'](track); 11994 }; 11995 11996 /** 11997 * Get video width 11998 * 11999 * @return {Number} Video width 12000 * @method videoWidth 12001 */ 12002 12003 Player.prototype.videoWidth = function videoWidth() { 12004 return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0; 12005 }; 12006 12007 /** 12008 * Get video height 12009 * 12010 * @return {Number} Video height 12011 * @method videoHeight 12012 */ 12013 12014 Player.prototype.videoHeight = function videoHeight() { 12015 return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0; 12016 }; 12017 12018 // Methods to add support for 12019 // initialTime: function(){ return this.techCall_('initialTime'); }, 12020 // startOffsetTime: function(){ return this.techCall_('startOffsetTime'); }, 12021 // played: function(){ return this.techCall_('played'); }, 12022 // videoTracks: function(){ return this.techCall_('videoTracks'); }, 12023 // audioTracks: function(){ return this.techCall_('audioTracks'); }, 12024 // defaultPlaybackRate: function(){ return this.techCall_('defaultPlaybackRate'); }, 12025 // defaultMuted: function(){ return this.techCall_('defaultMuted'); } 12026 12027 /** 12028 * The player's language code 12029 * NOTE: The language should be set in the player options if you want the 12030 * the controls to be built with a specific language. Changing the lanugage 12031 * later will not update controls text. 12032 * 12033 * @param {String} code The locale string 12034 * @return {String} The locale string when getting 12035 * @return {Player} self when setting 12036 * @method language 12037 */ 12038 12039 Player.prototype.language = function language(code) { 12040 if (code === undefined) { 12041 return this.language_; 12042 } 12043 12044 this.language_ = ('' + code).toLowerCase(); 12045 return this; 12046 }; 12047 12048 /**
12049 * Get the player's language dictionary 12050 * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time 12051 * Languages specified directly in the player options have precedence 12052 * 12053 * @return {Array} Array of languages 12054 * @method languages 12055 */ 12056 12057 Player.prototype.languages = function languages() { 12058 return _utilsMergeOptionsJs2['default'](Player.prototype.options_.languages, this.languages_); 12059 }; 12060 12061 /** 12062 * Converts track info to JSON 12063 * 12064 * @return {Object} JSON object of options 12065 * @method toJSON 12066 */ 12067 12068 Player.prototype.toJSON = function toJSON() { 12069 var options = _utilsMergeOptionsJs2['default'](this.options_); 12070 var tracks = options.tracks; 12071 12072 options.tracks = []; 12073 12074 for (var i = 0; i < tracks.length; i++) { 12075 var track = tracks[i]; 12076 12077 // deep merge tracks and null out player so no circular references 12078 track = _utilsMergeOptionsJs2['default'](track); 12079 track.player = undefined; 12080 options.tracks[i] = track; 12081 } 12082 12083 return options; 12084 }; 12085 12086 /** 12087 * Creates a simple modal dialog (an instance of the `ModalDialog` 12088 * component) that immediately overlays the player with arbitrary 12089 * content and removes itself when closed. 12090 * 12091 * @param {String|Function|Element|Array|Null} content 12092 * Same as `ModalDialog#content`'s param of the same name. 12093 * 12094 * The most straight-forward usage is to provide a string or DOM 12095 * element. 12096 * 12097 * @param {Object} [options] 12098 * Extra options which will be passed on to the `ModalDialog`. 12099 * 12100 * @return {ModalDialog} 12101 */ 12102 12103 Player.prototype.createModal = function createModal(content, options) { 12104 var player = this; 12105 12106 options = options || {}; 12107 options.content = content || ''; 12108 12109 var modal = new _modalDialog2['default'](player, options); 12110 12111 player.addChild(modal); 12112 modal.on('dispose', function () { 12113 player.removeChild(modal); 12114 }); 12115 12116 return modal.open(); 12117 }; 12118 12119 /** 12120 * Gets tag settings 12121 * 12122 * @param {Element} tag The player tag 12123 * @return {Array} An array of sources and track objects 12124 * @static 12125 * @method getTagSettings 12126 */ 12127 12128 Player.getTagSettings = function getTagSettings(tag) { 12129 var baseOptions = { 12130 'sources': [], 12131 'tracks': [] 12132 }; 12133 12134 var tagOptions = Dom.getElAttributes(tag); 12135 var dataSetup = tagOptions['data-setup']; 12136 12137 // Check if data-setup attr exists. 12138 if (dataSetup !== null) { 12139 // Parse options JSON 12140 12141 var _safeParseTuple = _safeJsonParseTuple2['default'](dataSetup || '{}'); 12142 12143 var err = _safeParseTuple[0]; 12144 var data = _safeParseTuple[1]; 12145 12146 if (err) { 12147 _utilsLogJs2['default'].error(err); 12148 } 12149 _objectAssign2['default'](tagOptions, data); 12150 } 12151 12152 _objectAssign2['default'](baseOptions, tagOptions); 12153 12154 // Get tag children settings 12155 if (tag.hasChildNodes()) { 12156 var children = tag.childNodes; 12157 12158 for (var i = 0, j = children.length; i < j; i++) { 12159 var child = children[i]; 12160 // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/ 12161 var childName = child.nodeName.toLowerCase(); 12162 if (childName === 'source') { 12163 baseOptions.sources.push(Dom.getElAttributes(child)); 12164 } else if (childName === 'track') { 12165 baseOptions.tracks.push(Dom.getElAttributes(child)); 12166 } 12167 } 12168 } 12169 12170 return baseOptions; 12171 }; 12172 12173 return Player; 12174})(_componentJs2['default']); 12175 12176Player.players = {}; 12177 12178var navigator = _globalWindow2['default'].navigator; 12179/* 12180 * Player instance options, surfaced using options 12181 * options = Player.prototype.options_ 12182 * Make changes in options, not here. 12183 * 12184 * @type {Object} 12185 * @private 12186 */ 12187Player.prototype.options_ = { 12188 // Default order of fallback technology 12189 techOrder: ['html5', 'flash'], 12190 // techOrder: ['flash','html5'], 12191 12192 html5: {}, 12193 flash: {}, 12194 12195 // defaultVolume: 0.85, 12196 defaultVolume: 0.00, // The freakin seaguls are driving me crazy! 12197 12198 // default inactivity timeout 12199 inactivityTimeout: 2000, 12200 12201 // default playback rates 12202 playbackRates: [], 12203 // Add playback rate selection by adding rates 12204 // 'playbackRates': [0.5, 1, 1.5, 2],
12205 12206 // Included control sets 12207 children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'], 12208 12209 language: _globalDocument2['default'].getElementsByTagName('html')[0].getAttribute('lang') || navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language || 'en', 12210 12211 // locales and their language translations 12212 languages: {}, 12213 12214 // Default message to show when a video cannot be played. 12215 notSupportedMessage: 'No compatible source was found for this video.' 12216}; 12217 12218/** 12219 * Fired when the player has initial duration and dimension information 12220 * 12221 * @event loadedmetadata 12222 */ 12223Player.prototype.handleLoadedMetaData_; 12224 12225/** 12226 * Fired when the player has downloaded data at the current playback position 12227 * 12228 * @event loadeddata 12229 */ 12230Player.prototype.handleLoadedData_; 12231 12232/** 12233 * Fired when the user is active, e.g. moves the mouse over the player 12234 * 12235 * @event useractive 12236 */ 12237Player.prototype.handleUserActive_; 12238 12239/** 12240 * Fired when the user is inactive, e.g. a short delay after the last mouse move or control interaction 12241 * 12242 * @event userinactive 12243 */ 12244Player.prototype.handleUserInactive_; 12245 12246/** 12247 * Fired when the current playback position has changed * 12248 * During playback this is fired every 15-250 milliseconds, depending on the 12249 * playback technology in use. 12250 * 12251 * @event timeupdate 12252 */ 12253Player.prototype.handleTimeUpdate_; 12254 12255/** 12256 * Fired when video playback ends 12257 * 12258 * @event ended 12259 */ 12260Player.prototype.handleTechEnded_; 12261 12262/** 12263 * Fired when the volume changes 12264 * 12265 * @event volumechange 12266 */ 12267Player.prototype.handleVolumeChange_; 12268 12269/** 12270 * Fired when an error occurs 12271 * 12272 * @event error 12273 */ 12274Player.prototype.handleError_; 12275 12276Player.prototype.flexNotSupported_ = function () { 12277 var elem = _globalDocument2['default'].createElement('i'); 12278 12279 // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more 12280 // common flex features that we can rely on when checking for flex support. 12281 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) */; 12282}; 12283 12284_componentJs2['default'].registerComponent('Player', Player); 12285exports['default'] = Player; 12286module.exports = exports['default']; 12287// If empty string, make it a parsable json object. 12288 12289},{"./big-play-button.js":62,"./component.js":66,"./control-bar/control-bar.js":67,"./error-display.js":97,"./fullscreen-api.js":100,"./loading-spinner.js":101,"./media-error.js":102,"./modal-dialog":106,"./poster-image.js":111,"./tech/html5.js":116,"./tech/loader.js":117,"./tech/tech.js":118,"./tracks/text-track-display.js":122,"./tracks/text-track-list-converter.js":124,"./tracks/text-track-settings.js":126,"./utils/browser.js":128,"./utils/buffer.js":129,"./utils/dom.js":131,"./utils/events.js":132,"./utils/fn.js":133,"./utils/guid.js":135,"./utils/log.js":136,"./utils/merge-options.js":137,"./utils/stylesheet.js":138,"./utils/time-ranges.js":139,"./utils/to-title-case.js":140,"global/document":1,"global/window":2,"object.assign":45,"safe-json-parse/tuple":53}],108:[function(_dereq_,module,exports){ 12290/** 12291 * @file plugins.js 12292 */ 12293'use strict'; 12294 12295exports.__esModule = true; 12296 12297function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12298 12299var _playerJs = _dereq_('./player.js'); 12300 12301var _playerJs2 = _interopRequireDefault(_playerJs); 12302 12303/** 12304 * The method for registering a video.js plugin 12305 * 12306 * @param {String} name The name of the plugin 12307 * @param {Function} init The function that is run when the player inits 12308 * @method plugin 12309 */ 12310var plugin = function plugin(name, init) { 12311 _playerJs2['default'].prototype[name] = init; 12312}; 12313 12314exports['default'] = plugin; 12315module.exports = exports['default']; 12316 12317},{"./player.js":107}],109:[function(_dereq_,module,exports){ 12318/** 12319 * @file popup-button.js 12320 */ 12321'use strict'; 12322 12323exports.__esModule = true; 12324 12325function _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; } } 12326 12327function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12328 12329function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 12330 12331function _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
12331onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 12332 12333var _clickableComponentJs = _dereq_('../clickable-component.js'); 12334 12335var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs); 12336 12337var _componentJs = _dereq_('../component.js'); 12338 12339var _componentJs2 = _interopRequireDefault(_componentJs); 12340 12341var _popupJs = _dereq_('./popup.js'); 12342 12343var _popupJs2 = _interopRequireDefault(_popupJs); 12344 12345var _utilsDomJs = _dereq_('../utils/dom.js'); 12346 12347var Dom = _interopRequireWildcard(_utilsDomJs); 12348 12349var _utilsFnJs = _dereq_('../utils/fn.js'); 12350 12351var Fn = _interopRequireWildcard(_utilsFnJs); 12352 12353var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js'); 12354 12355var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs); 12356 12357/** 12358 * A button class with a popup control 12359 * 12360 * @param {Player|Object} player 12361 * @param {Object=} options 12362 * @extends ClickableComponent 12363 * @class PopupButton 12364 */ 12365 12366var PopupButton = (function (_ClickableComponent) { 12367 _inherits(PopupButton, _ClickableComponent); 12368 12369 function PopupButton(player) { 12370 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 12371 12372 _classCallCheck(this, PopupButton); 12373 12374 _ClickableComponent.call(this, player, options); 12375 12376 this.update(); 12377 } 12378 12379 /** 12380 * Update popup 12381 * 12382 * @method update 12383 */ 12384 12385 PopupButton.prototype.update = function update() { 12386 var popup = this.createPopup(); 12387 12388 if (this.popup) { 12389 this.removeChild(this.popup); 12390 } 12391 12392 this.popup = popup; 12393 this.addChild(popup); 12394 12395 if (this.items && this.items.length === 0) { 12396 this.hide(); 12397 } else if (this.items && this.items.length > 1) { 12398 this.show(); 12399 } 12400 }; 12401 12402 /** 12403 * Create popup - Override with specific functionality for component 12404 * 12405 * @return {Popup} The constructed popup 12406 * @method createPopup 12407 */ 12408 12409 PopupButton.prototype.createPopup = function createPopup() {}; 12410 12411 /** 12412 * Create the component's DOM element 12413 * 12414 * @return {Element} 12415 * @method createEl 12416 */ 12417 12418 PopupButton.prototype.createEl = function createEl() { 12419 return _ClickableComponent.prototype.createEl.call(this, 'div', { 12420 className: this.buildCSSClass() 12421 }); 12422 }; 12423 12424 /** 12425 * Allow sub components to stack CSS class names 12426 * 12427 * @return {String} The constructed class name 12428 * @method buildCSSClass 12429 */ 12430 12431 PopupButton.prototype.buildCSSClass = function buildCSSClass() { 12432 var menuButtonClass = 'vjs-menu-button'; 12433 12434 // If the inline option is passed, we want to use different styles altogether. 12435 if (this.options_.inline === true) { 12436 menuButtonClass += '-inline'; 12437 } else { 12438 menuButtonClass += '-popup'; 12439 } 12440 12441 return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this); 12442 }; 12443 12444 return PopupButton; 12445})(_clickableComponentJs2['default']); 12446 12447_componentJs2['default'].registerComponent('PopupButton', PopupButton); 12448exports['default'] = PopupButton; 12449module.exports = exports['default']; 12450 12451},{"../clickable-component.js":64,"../component.js":66,"../utils/dom.js":131,"../utils/fn.js":133,"../utils/to-title-case.js":140,"./popup.js":110}],110:[function(_dereq_,module,exports){ 12452/** 12453 * @file popup.js 12454 */ 12455'use strict'; 12456 12457exports.__esModule = true; 12458 12459function _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; } } 12460 12461function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12462 12463function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 12464 12465function _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
12465onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 12466 12467var _componentJs = _dereq_('../component.js'); 12468 12469var _componentJs2 = _interopRequireDefault(_componentJs); 12470 12471var _utilsDomJs = _dereq_('../utils/dom.js'); 12472 12473var Dom = _interopRequireWildcard(_utilsDomJs); 12474 12475var _utilsFnJs = _dereq_('../utils/fn.js'); 12476 12477var Fn = _interopRequireWildcard(_utilsFnJs); 12478 12479var _utilsEventsJs = _dereq_('../utils/events.js'); 12480 12481var Events = _interopRequireWildcard(_utilsEventsJs); 12482 12483/** 12484 * The Popup component is used to build pop up controls. 12485 * 12486 * @extends Component 12487 * @class Popup 12488 */ 12489 12490var Popup = (function (_Component) { 12491 _inherits(Popup, _Component); 12492 12493 function Popup() { 12494 _classCallCheck(this, Popup); 12495 12496 _Component.apply(this, arguments); 12497 } 12498 12499 /** 12500 * Add a popup item to the popup 12501 * 12502 * @param {Object|String} component Component or component type to add 12503 * @method addItem 12504 */ 12505 12506 Popup.prototype.addItem = function addItem(component) { 12507 this.addChild(component); 12508 component.on('click', Fn.bind(this, function () { 12509 this.unlockShowing(); 12510 })); 12511 }; 12512 12513 /** 12514 * Create the component's DOM element 12515 * 12516 * @return {Element} 12517 * @method createEl 12518 */ 12519 12520 Popup.prototype.createEl = function createEl() { 12521 var contentElType = this.options_.contentElType || 'ul'; 12522 this.contentEl_ = Dom.createEl(contentElType, { 12523 className: 'vjs-menu-content' 12524 }); 12525 var el = _Component.prototype.createEl.call(this, 'div', { 12526 append: this.contentEl_, 12527 className: 'vjs-menu' 12528 }); 12529 el.appendChild(this.contentEl_); 12530 12531 // Prevent clicks from bubbling up. Needed for Popup Buttons, 12532 // where a click on the parent is significant 12533 Events.on(el, 'click', function (event) { 12534 event.preventDefault(); 12535 event.stopImmediatePropagation(); 12536 }); 12537 12538 return el; 12539 }; 12540 12541 return Popup; 12542})(_componentJs2['default']); 12543 12544_componentJs2['default'].registerComponent('Popup', Popup); 12545exports['default'] = Popup; 12546module.exports = exports['default']; 12547 12548},{"../component.js":66,"../utils/dom.js":131,"../utils/events.js":132,"../utils/fn.js":133}],111:[function(_dereq_,module,exports){ 12549/** 12550 * @file poster-image.js 12551 */ 12552'use strict'; 12553 12554exports.__esModule = true; 12555 12556function _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; } } 12557 12558function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12559 12560function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 12561 12562function _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; } 12563 12564var _clickableComponentJs = _dereq_('./clickable-component.js'); 12565 12566var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs); 12567 12568var _componentJs = _dereq_('./component.js'); 12569 12570var _componentJs2 = _interopRequireDefault(_componentJs); 12571 12572var _utilsFnJs = _dereq_('./utils/fn.js'); 12573 12574var Fn = _interopRequireWildcard(_utilsFnJs); 12575 12576var _utilsDomJs = _dereq_('./utils/dom.js'); 12577 12578var Dom = _interopRequireWildcard(_utilsDomJs); 12579 12580var _utilsBrowserJs = _dereq_('./utils/browser.js'); 12581 12582var browser = _interopRequireWildcard(_utilsBrowserJs); 12583 12584/** 12585 * The component that handles showing the poster image. 12586 * 12587 * @param {Player|Object} player 12588 * @param {Object=} options 12589 * @extends Button 12590 * @class PosterImage 12591 */ 12592 12593var PosterImage = (function (_ClickableComponent) { 12594 _inherits(PosterImage, _ClickableComponent); 12595 12596 function PosterImage(player, options) { 12597 _classCallCheck(this, PosterImage); 12598 12599 _ClickableComponent.call(this, player, options); 12600 12601 this.update(); 12602 player.on('posterchange', Fn.bind(this, this.update)); 12603 } 12604 12605 /** 12606 * Clean up the poster image 12607 * 12608 * @method dispose 12609 */ 12610 12611 PosterImage.prototype.dispose = function dispose() { 12612 this.player().off('posterchange', this.update); 12613 _ClickableComponent.prototype.dispose.call(this); 12614 }; 12615 12616 /** 12617 * Create the poster's image element 12618 * 12619 * @return {Element} 12620 * @method createEl 12621 */ 12622 12623 PosterImage.prototype.createEl = function createEl() { 12624 var el = Dom.createEl('div', { 12625 className: 'vjs-poster', 12626 12627 // Don't want poster to be tabbable. 12628 tabIndex: -1 12629 }); 12630 12631 // To ensure the poster image resizes while maintaining its original aspect 12632 // ratio, use a div with `background-size` when available. For browsers that 12633 // do not support `background-size` (e.g. IE8), fall back on using a regular
12634 // img element. 12635 if (!browser.BACKGROUND_SIZE_SUPPORTED) { 12636 this.fallbackImg_ = Dom.createEl('img'); 12637 el.appendChild(this.fallbackImg_); 12638 } 12639 12640 return el; 12641 }; 12642 12643 /** 12644 * Event handler for updates to the player's poster source 12645 * 12646 * @method update 12647 */ 12648 12649 PosterImage.prototype.update = function update() { 12650 var url = this.player().poster(); 12651 12652 this.setSrc(url); 12653 12654 // If there's no poster source we should display:none on this component 12655 // so it's not still clickable or right-clickable 12656 if (url) { 12657 this.show(); 12658 } else { 12659 this.hide(); 12660 } 12661 }; 12662 12663 /** 12664 * Set the poster source depending on the display method 12665 * 12666 * @param {String} url The URL to the poster source 12667 * @method setSrc 12668 */ 12669 12670 PosterImage.prototype.setSrc = function setSrc(url) { 12671 if (this.fallbackImg_) { 12672 this.fallbackImg_.src = url; 12673 } else { 12674 var backgroundImage = ''; 12675 // Any falsey values should stay as an empty string, otherwise 12676 // this will throw an extra error 12677 if (url) { 12678 backgroundImage = 'url("' + url + '")'; 12679 } 12680 12681 this.el_.style.backgroundImage = backgroundImage; 12682 } 12683 }; 12684 12685 /** 12686 * Event handler for clicks on the poster image 12687 * 12688 * @method handleClick 12689 */ 12690 12691 PosterImage.prototype.handleClick = function handleClick() { 12692 // We don't want a click to trigger playback when controls are disabled 12693 // but CSS should be hiding the poster to prevent that from happening 12694 if (this.player_.paused()) { 12695 this.player_.play(); 12696 } else { 12697 this.player_.pause(); 12698 } 12699 }; 12700 12701 return PosterImage; 12702})(_clickableComponentJs2['default']); 12703 12704_componentJs2['default'].registerComponent('PosterImage', PosterImage); 12705exports['default'] = PosterImage; 12706module.exports = exports['default']; 12707 12708},{"./clickable-component.js":64,"./component.js":66,"./utils/browser.js":128,"./utils/dom.js":131,"./utils/fn.js":133}],112:[function(_dereq_,module,exports){ 12709/** 12710 * @file setup.js 12711 * 12712 * Functions for automatically setting up a player 12713 * based on the data-setup attribute of the video tag 12714 */ 12715'use strict'; 12716 12717exports.__esModule = true; 12718 12719function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12720 12721function _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; } } 12722 12723var _utilsEventsJs = _dereq_('./utils/events.js'); 12724 12725var Events = _interopRequireWildcard(_utilsEventsJs); 12726 12727var _globalDocument = _dereq_('global/document'); 12728 12729var _globalDocument2 = _interopRequireDefault(_globalDocument); 12730 12731var _globalWindow = _dereq_('global/window'); 12732 12733var _globalWindow2 = _interopRequireDefault(_globalWindow); 12734 12735var _windowLoaded = false; 12736var videojs = undefined; 12737 12738// Automatically set up any tags that have a data-setup attribute 12739var autoSetup = function autoSetup() { 12740 // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack* 12741 // var vids = Array.prototype.slice.call(document.getElementsByTagName('video')); 12742 // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio')); 12743 // var mediaEls = vids.concat(audios); 12744 12745 // Because IE8 doesn't support calling slice on a node list, we need to loop through each list of elements 12746 // to build up a new, combined list of elements. 12747 var vids = _globalDocument2['default'].getElementsByTagName('video'); 12748 var audios = _globalDocument2['default'].getElementsByTagName('audio'); 12749 var mediaEls = []; 12750 if (vids && vids.length > 0) { 12751 for (var i = 0, e = vids.length; i < e; i++) { 12752 mediaEls.push(vids[i]); 12753 } 12754 } 12755 if (audios && audios.length > 0) { 12756 for (var i = 0, e = audios.length; i < e; i++) { 12757 mediaEls.push(audios[i]); 12758 } 12759 } 12760 12761 // Check if any media elements exist 12762 if (mediaEls && mediaEls.length > 0) { 12763 12764 for (var i = 0, e = mediaEls.length; i < e; i++) { 12765 var mediaEl = mediaEls[i]; 12766 12767 // Check if element exists, has getAttribute func. 12768 // IE seems to consider typeof el.getAttribute == 'object' instead of 'function' like expected, at least when loading the player immediately. 12769 if (mediaEl && mediaEl.getAttribute) { 12770 12771 // Make sure this player hasn't already been set up. 12772 if (mediaEl['player'] === undefined) { 12773 var options = mediaEl.getAttribute('data-setup'); 12774 12775 // Check if data-setup attr exists. 12776 // We only auto-setup if they've added the data-setup attr. 12777 if (options !== null) { 12778 // Create new video.js instance. 12779 var player = videojs(mediaEl); 12780 } 12781 } 12782 12783 // If getAttribute isn't defined, we need to wait for the DOM. 12784 } else { 12785 autoSetupTimeout(1); 12786 break; 12787 } 12788 } 12789 12790 // No videos were found, so keep looping unless page is finished loading. 12791 } else if (!_windowLoaded) { 12792 autoSetupTimeout(1); 12793 } 12794}; 12795 12796// Pause to let the DOM keep processing 12797var autoSetupTimeout = function autoSetupTimeout(wait, vjs) { 12798 videojs = vjs; 12799 setTimeout(autoSetup, wait); 12800}; 12801 12802if (_globalDocument2['default'].readyState === 'complete') { 12803 _windowLoaded = true; 12804} else { 12805 Events.one(_globalWindow2['default'], 'load', function () { 12806 _windowLoaded = true; 12807 }); 12808} 12809 12810var hasLoaded = function hasLoaded() { 12811 return _windowLoaded; 12812}; 12813 12814exports.autoSetup = autoSetup; 12815exports.autoSetupTimeout = autoSetupTimeout; 12816exports.hasLoaded = hasLoaded; 12817 12818},{"./utils/events.js":132,"global/document":1,"global/window":2}],113:[function(_dereq_,module,exports){ 12819/** 12820 * @file slider.js 12821 */ 12822'use strict'; 12823 12824exports.__esModule = true; 12825 12826function _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; } } 12827 12828function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 12829 12830function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 12831 12832function _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
12832onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 12833 12834var _componentJs = _dereq_('../component.js'); 12835 12836var _componentJs2 = _interopRequireDefault(_componentJs); 12837 12838var _utilsDomJs = _dereq_('../utils/dom.js'); 12839 12840var Dom = _interopRequireWildcard(_utilsDomJs); 12841 12842var _globalDocument = _dereq_('global/document'); 12843 12844var _globalDocument2 = _interopRequireDefault(_globalDocument); 12845 12846var _objectAssign = _dereq_('object.assign'); 12847 12848var _objectAssign2 = _interopRequireDefault(_objectAssign); 12849 12850/** 12851 * The base functionality for sliders like the volume bar and seek bar 12852 * 12853 * @param {Player|Object} player 12854 * @param {Object=} options 12855 * @extends Component 12856 * @class Slider 12857 */ 12858 12859var Slider = (function (_Component) { 12860 _inherits(Slider, _Component); 12861 12862 function Slider(player, options) { 12863 _classCallCheck(this, Slider); 12864 12865 _Component.call(this, player, options); 12866 12867 // Set property names to bar to match with the child Slider class is looking for 12868 this.bar = this.getChild(this.options_.barName); 12869 12870 // Set a horizontal or vertical class on the slider depending on the slider type 12871 this.vertical(!!this.options_.vertical); 12872 12873 this.on('mousedown', this.handleMouseDown); 12874 this.on('touchstart', this.handleMouseDown); 12875 this.on('focus', this.handleFocus); 12876 this.on('blur', this.handleBlur); 12877 this.on('click', this.handleClick); 12878 12879 this.on(player, 'controlsvisible', this.update); 12880 this.on(player, this.playerEvent, this.update); 12881 } 12882 12883 /** 12884 * Create the component's DOM element 12885 * 12886 * @param {String} type Type of element to create 12887 * @param {Object=} props List of properties in Object form 12888 * @return {Element} 12889 * @method createEl 12890 */ 12891 12892 Slider.prototype.createEl = function createEl(type) { 12893 var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 12894 var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; 12895 12896 // Add the slider element class to all sub classes 12897 props.className = props.className + ' vjs-slider'; 12898 props = _objectAssign2['default']({ 12899 tabIndex: 0 12900 }, props); 12901 12902 attributes = _objectAssign2['default']({ 12903 'role': 'slider', 12904 'aria-valuenow': 0, 12905 'aria-valuemin': 0, 12906 'aria-valuemax': 100, 12907 tabIndex: 0 12908 }, attributes); 12909 12910 return _Component.prototype.createEl.call(this, type, props, attributes); 12911 }; 12912 12913 /** 12914 * Handle mouse down on slider 12915 * 12916 * @param {Object} event Mouse down event object 12917 * @method handleMouseDown 12918 */ 12919 12920 Slider.prototype.handleMouseDown = function handleMouseDown(event) { 12921 event.preventDefault(); 12922 Dom.blockTextSelection(); 12923 12924 this.addClass('vjs-sliding'); 12925 this.trigger('slideractive'); 12926 12927 this.on(_globalDocument2['default'], 'mousemove', this.handleMouseMove); 12928 this.on(_globalDocument2['default'], 'mouseup', this.handleMouseUp); 12929 this.on(_globalDocument2['default'], 'touchmove', this.handleMouseMove); 12930 this.on(_globalDocument2['default'], 'touchend', this.handleMouseUp); 12931 12932 this.handleMouseMove(event); 12933 }; 12934 12935 /** 12936 * To be overridden by a subclass 12937 * 12938 * @method handleMouseMove 12939 */ 12940 12941 Slider.prototype.handleMouseMove = function handleMouseMove() {}; 12942 12943 /** 12944 * Handle mouse up on Slider 12945 * 12946 * @method handleMouseUp 12947 */ 12948 12949 Slider.prototype.handleMouseUp = function handleMouseUp() { 12950 Dom.unblockTextSelection(); 12951 12952 this.removeClass('vjs-sliding'); 12953 this.trigger('sliderinactive'); 12954 12955 this.off(_globalDocument2['default'], 'mousemove', this.handleMouseMove); 12956 this.off(_globalDocument2['default'], 'mouseup', this.handleMouseUp); 12957 this.off(_globalDocument2['default'], 'touchmove', this.handleMouseMove); 12958 this.off(_globalDocument2['default'], 'touchend', this.handleMouseUp); 12959 12960 this.update(); 12961 }; 12962 12963 /** 12964 * Update slider 12965 * 12966 * @method update 12967 */ 12968 12969 Slider.prototype.update = function update() { 12970 // In VolumeBar init we have a setTimeout for update that pops and update to the end of the 12971 // execution stack. The player is destroyed before then update will cause an error 12972 if (!this.el_) return; 12973 12974 // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse. 12975 // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later. 12976 // var progress = (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration(); 12977 var progress = this.getPercent(); 12978 var bar = this.bar; 12979 12980 // If there's no bar... 12981 if (!bar) return; 12982 12983 // Protect against no duration and other division issues 12984 if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) { 12985 progress = 0; 12986 } 12987 12988 // Convert to a percentage for setting 12989 var percentage = (progress * 100).toFixed(2) + '%'; 12990 12991 // Set the new bar width or height 12992 if (this.vertical()) { 12993 bar.el().style.height = percentage; 12994 } else { 12995 bar.el().style.width = percentage; 12996 } 12997 }; 12998 12999 /** 13000 * Calculate distance for slider 13001 * 13002 * @param {Object} event Event object 13003 * @method calculateDistance 13004 */ 13005 13006 Slider.prototype.calculateDistance = function calculateDistance(event) { 13007 var position = Dom.getPointerPosition(this.el_, event); 13008 if (this.vertical()) { 13009 return position.y; 13010 } 13011 return position.x; 13012 }; 13013 13014 /** 13015 * Handle on focus for slider 13016 * 13017 * @method handleFocus 13018 */ 13019 13020 Slider.prototype.handleFocus = function handleFocus() { 13021 this.on(_globalDocument2['default'], 'keydown', this.handleKeyPress); 13022 }; 13023 13024 /** 13025 * Handle key press for slider 13026 * 13027 * @param {Object} event Event object 13028 * @method handleKeyPress 13029 */ 13030 13031 Slider.prototype.handleKeyPress = function handleKeyPress(event) { 13032 if (event.which === 37 || event.which === 40) { 13033 // Left and Down Arrows 13034 event.preventDefault(); 13035 this.stepBack(); 13036 } else if (event.which === 38 || event.which === 39) { 13037 // Up and Right Arrows 13038 event.preventDefault(); 13039 this.stepForward(); 13040 } 13041 }; 13042 13043 /** 13044 * Handle on blur for slider 13045 * 13046 * @method handleBlur 13047 */ 13048 13049 Slider.prototype.handleBlur = function handleBlur() { 13050 this.off(_globalDocument2['default'], 'keydown', this.handleKeyPress); 13051 }; 13052 13053 /** 13054 * Listener for click events on slider, used to prevent clicks 13055 * from bubbling up to parent elements like button menus. 13056 * 13057 * @param {Object} event Event object 13058 * @method handleClick 13059 */ 13060 13061 Slider.prototype.handleClick = function handleClick(event) { 13062 event.stopImmediatePropagation(); 13063 event.preventDefault(); 13064 }; 13065 13066 /** 13067 * Get/set if slider is horizontal for vertical 13068 * 13069 * @param {Boolean} bool True if slider is vertical, false is horizontal 13070 * @return {Boolean} True if slider is vertical, false is horizontal 13071 * @method vertical 13072 */ 13073 13074 Slider.prototype.vertical = function vertical(bool) { 13075 if (bool === undefined) { 13076 return this.vertical_ || false; 13077 } 13078 13079 this.vertical_ = !!bool; 13080 13081 if (this.vertical_) { 13082 this.addClass('vjs-slider-vertical'); 13083 } else { 13084 this.addClass('vjs-slider-horizontal'); 13085 } 13086 13087 return this; 13088 }; 13089 13090 return Slider; 13091})(_componentJs2['default']); 13092 13093_componentJs2['default'].registerComponent('Slider', Slider); 13094exports['default'] = Slider; 13095module.exports = exports['default']; 13096 13097},{"../component.js":66,"../utils/dom.js":131,"global/document":1,"object.assign":45}],114:[function(_dereq_,module,exports){ 13098/** 13099 * @file flash-rtmp.js 13100 */ 13101'use strict'; 13102 13103exports.__esModule = true; 13104function FlashRtmpDecorator(Flash) { 13105 Flash.streamingFormats = { 13106 'rtmp/mp4': 'MP4', 13107 'rtmp/flv': 'FLV' 13108 }; 13109
13110 Flash.streamFromParts = function (connection, stream) { 13111 return connection + '&' + stream; 13112 }; 13113 13114 Flash.streamToParts = function (src) { 13115 var parts = { 13116 connection: '', 13117 stream: '' 13118 }; 13119 13120 if (!src) return parts; 13121 13122 // Look for the normal URL separator we expect, '&'. 13123 // If found, we split the URL into two pieces around the 13124 // first '&'. 13125 var connEnd = src.search(/&(?!\w+=)/); 13126 var streamBegin = undefined; 13127 if (connEnd !== -1) { 13128 streamBegin = connEnd + 1; 13129 } else { 13130 // If there's not a '&', we use the last '/' as the delimiter. 13131 connEnd = streamBegin = src.lastIndexOf('/') + 1; 13132 if (connEnd === 0) { 13133 // really, there's not a '/'? 13134 connEnd = streamBegin = src.length; 13135 } 13136 } 13137 parts.connection = src.substring(0, connEnd); 13138 parts.stream = src.substring(streamBegin, src.length); 13139 13140 return parts; 13141 }; 13142 13143 Flash.isStreamingType = function (srcType) { 13144 return srcType in Flash.streamingFormats; 13145 }; 13146 13147 // RTMP has four variations, any string starting 13148 // with one of these protocols should be valid 13149 Flash.RTMP_RE = /^rtmp[set]?:\/\//i; 13150 13151 Flash.isStreamingSrc = function (src) { 13152 return Flash.RTMP_RE.test(src); 13153 }; 13154 13155 /** 13156 * A source handler for RTMP urls 13157 * @type {Object} 13158 */ 13159 Flash.rtmpSourceHandler = {}; 13160 13161 /** 13162 * Check if Flash can play the given videotype 13163 * @param {String} type The mimetype to check 13164 * @return {String} 'probably', 'maybe', or '' (empty string) 13165 */ 13166 Flash.rtmpSourceHandler.canPlayType = function (type) { 13167 if (Flash.isStreamingType(type)) { 13168 return 'maybe'; 13169 } 13170 13171 return ''; 13172 }; 13173 13174 /** 13175 * Check if Flash can handle the source natively 13176 * @param {Object} source The source object 13177 * @return {String} 'probably', 'maybe', or '' (empty string) 13178 */ 13179 Flash.rtmpSourceHandler.canHandleSource = function (source) { 13180 var can = Flash.rtmpSourceHandler.canPlayType(source.type); 13181 13182 if (can) { 13183 return can; 13184 } 13185 13186 if (Flash.isStreamingSrc(source.src)) { 13187 return 'maybe'; 13188 } 13189 13190 return ''; 13191 }; 13192 13193 /** 13194 * Pass the source to the flash object 13195 * Adaptive source handlers will have more complicated workflows before passing 13196 * video data to the video element 13197 * @param {Object} source The source object 13198 * @param {Flash} tech The instance of the Flash tech 13199 */ 13200 Flash.rtmpSourceHandler.handleSource = function (source, tech) { 13201 var srcParts = Flash.streamToParts(source.src); 13202 13203 tech['setRtmpConnection'](srcParts.connection); 13204 tech['setRtmpStream'](srcParts.stream); 13205 }; 13206 13207 // Register the native source handler 13208 Flash.registerSourceHandler(Flash.rtmpSourceHandler); 13209 13210 return Flash; 13211} 13212 13213exports['default'] = FlashRtmpDecorator; 13214module.exports = exports['default']; 13215 13216},{}],115:[function(_dereq_,module,exports){ 13217/** 13218 * @file flash.js 13219 * VideoJS-SWF - Custom Flash Player with HTML5-ish API 13220 * https://github.com/zencoder/video-js-swf 13221 * Not using setupTriggers. Using global onEvent func to distribute events 13222 */ 13223 13224'use strict'; 13225 13226exports.__esModule = true; 13227 13228function _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; } } 13229 13230function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 13231 13232function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 13233 13234function _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; } 13235 13236var _tech = _dereq_('./tech'); 13237 13238var _tech2 = _interopRequireDefault(_tech); 13239 13240var _utilsDomJs = _dereq_('../utils/dom.js'); 13241 13242var Dom = _interopRequireWildcard(_utilsDomJs); 13243 13244var _utilsUrlJs = _dereq_('../utils/url.js'); 13245 13246var Url = _interopRequireWildcard(_utilsUrlJs); 13247 13248var _utilsTimeRangesJs = _dereq_('../utils/time-ranges.js'); 13249 13250var _flashRtmp = _dereq_('./flash-rtmp'); 13251 13252var _flashRtmp2 = _interopRequireDefault(_flashRtmp); 13253 13254var _component = _dereq_('../component'); 13255 13256var _component2 = _interopRequireDefault(_component); 13257 13258var _globalWindow = _dereq_('global/window'); 13259 13260var _globalWindow2 = _interopRequireDefault(_globalWindow); 13261 13262var _objectAssign = _dereq_('object.assign'); 13263 13264var _objectAssign2 = _interopRequireDefault(_objectAssign); 13265 13266var navigator = _globalWindow2['default'].navigator; 13267/** 13268 * Flash Media Controller - Wrapper for fallback SWF API 13269 * 13270 * @param {Object=} options Object of option names and values 13271 * @param {Function=} ready Ready callback function 13272 * @extends Tech 13273 * @class Flash 13274 */ 13275 13276var Flash = (function (_Tech) { 13277 _inherits(Flash, _Tech); 13278 13279 function Flash(options, ready) { 13280 _classCallCheck(this, Flash); 13281 13282 _Tech.call(this, options, ready); 13283 13284 // Set the source when ready 13285 if (options.source) { 13286 this.ready(function () { 13287 this.setSource(options.source); 13288 }, true); 13289 } 13290 13291 // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers 13292 // This allows resetting the playhead when we catch the reload 13293 if (options.startTime) { 13294 this.ready(function () { 13295 this.load(); 13296 this.play(); 13297 this.currentTime(options.startTime); 13298 }, true); 13299 } 13300 13301 // Add global window functions that the swf expects 13302 // A 4.x workflow we weren't able to solve for in 5.0 13303 // because of the need to hard code these functions 13304 // into the swf for security reasons 13305 _globalWindow2['default'].videojs = _globalWindow2['default'].videojs || {}; 13306 _globalWindow2['default'].videojs.Flash = _globalWindow2['default'].videojs.Flash || {}; 13307 _globalWindow2['default'].videojs.Flash.onReady = Flash.onReady; 13308 _globalWindow2['default'].videojs.Flash.onEvent = Flash.onEvent; 13309 _globalWindow2['default'].videojs.Flash.onError = Flash.onError; 13310 13311 this.on('seeked', function () { 13312 this.lastSeekTarget_ = undefined; 13313 }); 13314 } 13315 13316 // Create setters and getters for attributes 13317 13318 /** 13319 * Create the component's DOM element 13320 * 13321 * @return {Element} 13322 * @method createEl 13323 */ 13324 13325 Flash.prototype.createEl = function createEl() { 13326 var options = this.options_; 13327 13328 // If video.js is hosted locally you should also set the location 13329 // for the hosted swf, which should be relative to the page (not video.js) 13330 // Otherwise this adds a CDN url. 13331 // The CDN also auto-adds a swf URL for that specific version. 13332 if (!options.swf) { 13333 options.swf = '//vjs.zencdn.net/swf/5.0.1/video-js.swf'; 13334 } 13335 13336 // Generate ID for swf object 13337 var objId = options.techId; 13338 13339 // Merge default flashvars with ones passed in to init 13340 var flashVars = _objectAssign2['default']({ 13341 13342 // SWF Callback Functions 13343 'readyFunction': 'videojs.Flash.onReady', 13344 'eventProxyFunction': 'videojs.Flash.onEvent', 13345 'errorEventProxyFunction': 'videojs.Flash.onError', 13346 13347 // Player Settings 13348 'autoplay': options.autoplay, 13349 'preload': options.preload, 13350 'loop': options.loop, 13351 'muted': options.muted 13352 13353 }, options.flashVars); 13354 13355 // Merge default parames with ones passed in 13356 var params = _objectAssign2['default']({ 13357 'wmode': 'opaque', // Opaque is needed to overlay controls, but can affect playback performance 13358 'bgcolor': '#000000' // Using bgcolor prevents a white flash when the object is loading 13359 }, options.params); 13360 13361 // Merge default attributes with ones passed in 13362 var attributes = _objectAssign2['default']({ 13363 'id': objId, 13364 'name': objId, // Both ID and Name needed or swf to identify itself 13365 'class': 'vjs-tech' 13366 }, options.attributes); 13367 13368 this.el_ = Flash.embed(options.swf, flashVars, params, attributes); 13369 this.el_.tech = this; 13370 13371 return this.el_; 13372 }; 13373 13374 /** 13375 * Play for flash tech 13376 * 13377 * @method play 13378 */ 13379 13380 Flash.prototype.play = function play() { 13381 if (this.ended()) { 13382 this.setCurrentTime(0); 13383 } 13384 this.el_.vjs_play(); 13385 }; 13386 13387 /** 13388 * Pause for flash tech 13389 * 13390 * @method pause 13391 */ 13392 13393 Flash.prototype.pause = function pause() { 13394 this.el_.vjs_pause(); 13395 }; 13396 13397 /** 13398 * Get/set video 13399 * 13400 * @param {Object=} src Source object 13401 * @return {Object} 13402 * @method src 13403 */ 13404 13405 Flash.prototype.src = function src(_src) { 13406 if (_src === undefined) { 13407 return this.currentSrc(); 13408 } 13409 13410 // Setting src through `src` not `setSrc` will be deprecated 13411 return this.setSrc(_src); 13412 }; 13413 13414 /** 13415 * Set video 13416 * 13417 * @param {Object=} src Source object 13418 * @deprecated 13419 * @method setSrc 13420 */ 13421 13422 Flash.prototype.setSrc = function setSrc(src) { 13423 // Make sure source URL is absolute. 13424 src = Url.getAbsoluteURL(src); 13425 this.el_.vjs_src(src); 13426 13427 // Currently the SWF doesn't autoplay if you load a source later. 13428 // e.g. Load player w/ no source, wait 2s, set src. 13429 if (this.autoplay()) { 13430 var tech = this; 13431 this.setTimeout(function () { 13432 tech.play(); 13433 }, 0); 13434 } 13435 }; 13436 13437 /** 13438 * Returns true if the tech is currently seeking. 13439 * @return {boolean} true if seeking 13440 */ 13441 13442 Flash.prototype.seeking = function seeking() { 13443 return this.lastSeekTarget_ !== undefined; 13444 }; 13445 13446 /** 13447 * Set current time 13448 * 13449 * @param {Number} time Current time of video 13450 * @method setCurrentTime 13451 */ 13452 13453 Flash.prototype.setCurrentTime = function setCurrentTime(time) { 13454 var seekable = this.seekable(); 13455 if (seekable.length) { 13456 // clamp to the current seekable range 13457 time = time > seekable.start(0) ? time : seekable.start(0); 13458 time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1); 13459 13460 this.lastSeekTarget_ = time; 13461 this.trigger('seeking'); 13462 this.el_.vjs_setProperty('currentTime', time); 13463 _Tech.prototype.setCurrentTime.call(this); 13464 } 13465 }; 13466 13467 /** 13468 * Get current time 13469 * 13470 * @param {Number=}
13470 time Current time of video 13471 * @return {Number} Current time 13472 * @method currentTime 13473 */ 13474 13475 Flash.prototype.currentTime = function currentTime(time) { 13476 // when seeking make the reported time keep up with the requested time 13477 // by reading the time we're seeking to 13478 if (this.seeking()) { 13479 return this.lastSeekTarget_ || 0; 13480 } 13481 return this.el_.vjs_getProperty('currentTime'); 13482 }; 13483 13484 /** 13485 * Get current source 13486 * 13487 * @method currentSrc 13488 */ 13489 13490 Flash.prototype.currentSrc = function currentSrc() { 13491 if (this.currentSource_) { 13492 return this.currentSource_.src; 13493 } else { 13494 return this.el_.vjs_getProperty('currentSrc'); 13495 } 13496 }; 13497 13498 /** 13499 * Load media into player 13500 * 13501 * @method load 13502 */ 13503 13504 Flash.prototype.load = function load() { 13505 this.el_.vjs_load(); 13506 }; 13507 13508 /** 13509 * Get poster 13510 * 13511 * @method poster 13512 */ 13513 13514 Flash.prototype.poster = function poster() { 13515 this.el_.vjs_getProperty('poster'); 13516 }; 13517 13518 /** 13519 * Poster images are not handled by the Flash tech so make this a no-op 13520 * 13521 * @method setPoster 13522 */ 13523 13524 Flash.prototype.setPoster = function setPoster() {}; 13525 13526 /** 13527 * Determine if can seek in media 13528 * 13529 * @return {TimeRangeObject} 13530 * @method seekable 13531 */ 13532 13533 Flash.prototype.seekable = function seekable() { 13534 var duration = this.duration(); 13535 if (duration === 0) { 13536 return _utilsTimeRangesJs.createTimeRange(); 13537 } 13538 return _utilsTimeRangesJs.createTimeRange(0, duration); 13539 }; 13540 13541 /** 13542 * Get buffered time range 13543 * 13544 * @return {TimeRangeObject} 13545 * @method buffered 13546 */ 13547 13548 Flash.prototype.buffered = function buffered() { 13549 var ranges = this.el_.vjs_getProperty('buffered'); 13550 if (ranges.length === 0) { 13551 return _utilsTimeRangesJs.createTimeRange(); 13552 } 13553 return _utilsTimeRangesJs.createTimeRange(ranges[0][0], ranges[0][1]); 13554 }; 13555 13556 /** 13557 * Get fullscreen support - 13558 * Flash does not allow fullscreen through javascript 13559 * so always returns false 13560 * 13561 * @return {Boolean} false 13562 * @method supportsFullScreen 13563 */ 13564 13565 Flash.prototype.supportsFullScreen = function supportsFullScreen() { 13566 return false; // Flash does not allow fullscreen through javascript 13567 }; 13568 13569 /** 13570 * Request to enter fullscreen 13571 * Flash does not allow fullscreen through javascript 13572 * so always returns false 13573 * 13574 * @return {Boolean} false 13575 * @method enterFullScreen 13576 */ 13577 13578 Flash.prototype.enterFullScreen = function enterFullScreen() { 13579 return false; 13580 }; 13581 13582 return Flash; 13583})(_tech2['default']); 13584 13585var _api = Flash.prototype; 13586var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(','); 13587var _readOnly = 'networkState,readyState,initialTime,duration,startOffsetTime,paused,ended,videoTracks,audioTracks,videoWidth,videoHeight'.split(','); 13588 13589function _createSetter(attr) { 13590 var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1); 13591 _api['set' + attrUpper] = function (val) { 13592 return this.el_.vjs_setProperty(attr, val); 13593 }; 13594} 13595function _createGetter(attr) { 13596 _api[attr] = function () { 13597 return this.el_.vjs_getProperty(attr); 13598 }; 13599} 13600 13601// Create getter and setters for all read/write attributes 13602for (var i = 0; i < _readWrite.length; i++) { 13603 _createGetter(_readWrite[i]); 13604 _createSetter(_readWrite[i]); 13605} 13606 13607// Create getters for read-only attributes 13608for (var i = 0; i < _readOnly.length; i++) { 13609 _createGetter(_readOnly[i]); 13610} 13611 13612/* Flash Support Testing -------------------------------------------------------- */ 13613 13614Flash.isSupported = function () { 13615 return Flash.version()[0] >= 10; 13616 // return swfobject.hasFlashPlayerVersion('10'); 13617}; 13618 13619// Add Source Handler pattern functions to this tech 13620_tech2['default'].withSourceHandlers(Flash); 13621 13622/* 13623 * The default native source handler. 13624 * This simply passes the source to the video element. Nothing fancy. 13625 * 13626 * @param {Object} source The source object 13627 * @param {Flash} tech The instance of the Flash tech 13628 */ 13629Flash.nativeSourceHandler = {}; 13630 13631/** 13632 * Check if Flash can play the given videotype 13633 * @param {String} type The mimetype to check 13634 * @return {String} 'probably', 'maybe', or '' (empty string) 13635 */ 13636Flash.nativeSourceHandler.canPlayType = function (type) { 13637 if (type in Flash.formats) { 13638 return 'maybe'; 13639 } 13640 13641 return ''; 13642}; 13643 13644/* 13645 * Check Flash can handle the source natively 13646 * 13647 * @param {Object} source The source object 13648 * @return {String} 'probably', 'maybe', or '' (empty string) 13649 */ 13650Flash.nativeSourceHandler.canHandleSource = function (source) { 13651 var type; 13652 13653 function guessMimeType(src) { 13654 var ext = Url.getFileExtension(src); 13655 if (ext) { 13656 return 'video/' + ext; 13657 } 13658 return ''; 13659 } 13660 13661 if (!source.type) { 13662 type = guessMimeType(source.src); 13663 } else { 13664 // Strip code information from the type because we don't get that specific 13665 type = source.type.replace(/;.*/, '').toLowerCase(); 13666 } 13667 13668 return Flash.nativeSourceHandler.canPlayType(type); 13669}; 13670 13671/* 13672 * Pass the source to the flash object 13673 * Adaptive source handlers will have more complicated workflows before passing 13674 * video data to the video element 13675 * 13676 * @param {Object} source The source object 13677 * @param {Flash} tech The instance of the Flash tech 13678 */ 13679Flash.nativeSourceHandler.handleSource = function (source, tech) { 13680 tech.setSrc(source.src); 13681}; 13682 13683/* 13684 * Clean up the source handler when disposing the player or switching sources.. 13685 * (no cleanup is needed when supporting the format natively) 13686 */ 13687Flash.nativeSourceHandler.dispose = function () {}; 13688 13689// Register the native source handler 13690Flash.registerSourceHandler(Flash.nativeSourceHandler); 13691 13692Flash.formats = { 13693 'video/flv': 'FLV', 13694 'video/x-flv': 'FLV', 13695 'video/mp4': 'MP4', 13696 'video/m4v': 'MP4' 13697}; 13698 13699Flash.onReady = function (currSwf) { 13700 var el = Dom.getEl(currSwf); 13701 var tech = el && el.tech; 13702 13703 // if there is no el then the tech has been disposed 13704 // and the tech element was removed from the player div 13705 if (tech && tech.el()) { 13706 // check that the flash object is really ready 13707 Flash.checkReady(tech); 13708 } 13709}; 13710 13711// The SWF isn't always ready when it says it is. Sometimes the API functions still need to be added to the object. 13712// If it's not ready, we set a timeout to check again shortly. 13713Flash.checkReady = function (tech) {
13714 // stop worrying if the tech has been disposed 13715 if (!tech.el()) { 13716 return; 13717 } 13718 13719 // check if API property exists 13720 if (tech.el().vjs_getProperty) { 13721 // tell tech it's ready 13722 tech.triggerReady(); 13723 } else { 13724 // wait longer 13725 this.setTimeout(function () { 13726 Flash['checkReady'](tech); 13727 }, 50); 13728 } 13729}; 13730 13731// Trigger events from the swf on the player 13732Flash.onEvent = function (swfID, eventName) { 13733 var tech = Dom.getEl(swfID).tech; 13734 tech.trigger(eventName); 13735}; 13736 13737// Log errors from the swf 13738Flash.onError = function (swfID, err) { 13739 var tech = Dom.getEl(swfID).tech; 13740 13741 // trigger MEDIA_ERR_SRC_NOT_SUPPORTED 13742 if (err === 'srcnotfound') { 13743 return tech.error(4); 13744 } 13745 13746 // trigger a custom error 13747 tech.error('FLASH: ' + err); 13748}; 13749 13750// Flash Version Check 13751Flash.version = function () { 13752 var version = '0,0,0'; 13753 13754 // IE 13755 try { 13756 version = new _globalWindow2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; 13757 13758 // other browsers 13759 } catch (e) { 13760 try { 13761 if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) { 13762 version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; 13763 } 13764 } catch (err) {} 13765 } 13766 return version.split(','); 13767}; 13768 13769// Flash embedding method. Only used in non-iframe mode 13770Flash.embed = function (swf, flashVars, params, attributes) { 13771 var code = Flash.getEmbedCode(swf, flashVars, params, attributes); 13772 13773 // Get element by embedding code and retrieving created element 13774 var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0]; 13775 13776 return obj; 13777}; 13778 13779Flash.getEmbedCode = function (swf, flashVars, params, attributes) { 13780 var objTag = '<object type="application/x-shockwave-flash" '; 13781 var flashVarsString = ''; 13782 var paramsString = ''; 13783 var attrsString = ''; 13784 13785 // Convert flash vars to string 13786 if (flashVars) { 13787 Object.getOwnPropertyNames(flashVars).forEach(function (key) { 13788 flashVarsString += key + '=' + flashVars[key] + '&'; 13789 }); 13790 } 13791 13792 // Add swf, flashVars, and other default params 13793 params = _objectAssign2['default']({ 13794 'movie': swf, 13795 'flashvars': flashVarsString, 13796 'allowScriptAccess': 'always', // Required to talk to swf 13797 'allowNetworking': 'all' // All should be default, but having security issues. 13798 }, params); 13799 13800 // Create param tags string 13801 Object.getOwnPropertyNames(params).forEach(function (key) { 13802 paramsString += '<param name="' + key + '" value="' + params[key] + '" />'; 13803 }); 13804 13805 attributes = _objectAssign2['default']({ 13806 // Add swf to attributes (need both for IE and Others to work) 13807 'data': swf, 13808 13809 // Default to 100% width/height 13810 'width': '100%', 13811 'height': '100%' 13812 13813 }, attributes); 13814 13815 // Create Attributes string 13816 Object.getOwnPropertyNames(attributes).forEach(function (key) { 13817 attrsString += key + '="' + attributes[key] + '" '; 13818 }); 13819 13820 return '' + objTag + attrsString + '>' + paramsString + '</object>'; 13821}; 13822 13823// Run Flash through the RTMP decorator 13824_flashRtmp2['default'](Flash); 13825 13826_component2['default'].registerComponent('Flash', Flash); 13827_tech2['default'].registerTech('Flash', Flash); 13828exports['default'] = Flash; 13829module.exports = exports['default']; 13830 13831},{"../component":66,"../utils/dom.js":131,"../utils/time-ranges.js":139,"../utils/url.js":141,"./flash-rtmp":114,"./tech":118,"global/window":2,"object.assign":45}],116:[function(_dereq_,module,exports){ 13832/** 13833 * @file html5.js 13834 * HTML5 Media Controller - Wrapper for HTML5 Media API 13835 */ 13836 13837'use strict'; 13838 13839exports.__esModule = true; 13840 13841function _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; } } 13842 13843function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 13844 13845function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 13846 13847function _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
13847onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 13848 13849var _techJs = _dereq_('./tech.js'); 13850 13851var _techJs2 = _interopRequireDefault(_techJs); 13852 13853var _component = _dereq_('../component'); 13854 13855var _component2 = _interopRequireDefault(_component); 13856 13857var _utilsDomJs = _dereq_('../utils/dom.js'); 13858 13859var Dom = _interopRequireWildcard(_utilsDomJs); 13860 13861var _utilsUrlJs = _dereq_('../utils/url.js'); 13862 13863var Url = _interopRequireWildcard(_utilsUrlJs); 13864 13865var _utilsFnJs = _dereq_('../utils/fn.js'); 13866 13867var Fn = _interopRequireWildcard(_utilsFnJs); 13868 13869var _utilsLogJs = _dereq_('../utils/log.js'); 13870 13871var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 13872 13873var _utilsBrowserJs = _dereq_('../utils/browser.js'); 13874 13875var browser = _interopRequireWildcard(_utilsBrowserJs); 13876 13877var _globalDocument = _dereq_('global/document'); 13878 13879var _globalDocument2 = _interopRequireDefault(_globalDocument); 13880 13881var _globalWindow = _dereq_('global/window'); 13882 13883var _globalWindow2 = _interopRequireDefault(_globalWindow); 13884 13885var _objectAssign = _dereq_('object.assign'); 13886 13887var _objectAssign2 = _interopRequireDefault(_objectAssign); 13888 13889var _utilsMergeOptionsJs = _dereq_('../utils/merge-options.js'); 13890 13891var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs); 13892 13893/** 13894 * HTML5 Media Controller - Wrapper for HTML5 Media API 13895 * 13896 * @param {Object=} options Object of option names and values 13897 * @param {Function=} ready Ready callback function 13898 * @extends Tech 13899 * @class Html5 13900 */ 13901 13902var Html5 = (function (_Tech) { 13903 _inherits(Html5, _Tech); 13904 13905 function Html5(options, ready) { 13906 _classCallCheck(this, Html5); 13907 13908 _Tech.call(this, options, ready); 13909 13910 var source = options.source; 13911 13912 // Set the source if one is provided 13913 // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted) 13914 // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source 13915 // anyway so the error gets fired. 13916 if (source && (this.el_.currentSrc !== source.src || options.tag && options.tag.
13916initNetworkState_ === 3)) { 13917 this.setSource(source); 13918 } else { 13919 this.handleLateInit_(this.el_); 13920 } 13921 13922 if (this.el_.hasChildNodes()) { 13923 13924 var nodes = this.el_.childNodes; 13925 var nodesLength = nodes.length; 13926 var removeNodes = []; 13927 13928 while (nodesLength--) { 13929 var node = nodes[nodesLength]; 13930 var nodeName = node.nodeName.toLowerCase(); 13931 13932 if (nodeName === 'track') { 13933 if (!this.featuresNativeTextTracks) { 13934 // Empty video tag tracks so the built-in player doesn't use them also. 13935 // This may not be fast enough to stop HTML5 browsers from reading the tags 13936 // so we'll need to turn off any default tracks if we're manually doing 13937 // captions and subtitles. videoElement.textTracks 13938 removeNodes.push(node); 13939 } else { 13940 // store HTMLTrackElement and TextTrack to remote list 13941 this.remoteTextTrackEls().addTrackElement_(node); 13942 this.remoteTextTracks().addTrack_(node.track); 13943 } 13944 } 13945 } 13946 13947 for (var i = 0; i < removeNodes.length; i++) { 13948 this.el_.removeChild(removeNodes[i]); 13949 } 13950 } 13951 13952 if (this.featuresNativeTextTracks) { 13953 this.handleTextTrackChange_ = Fn.bind(this, this.handleTextTrackChange); 13954 this.handleTextTrackAdd_ = Fn.bind(this, this.handleTextTrackAdd); 13955 this.handleTextTrackRemove_ = Fn.bind(this, this.handleTextTrackRemove); 13956 this.proxyNativeTextTracks_(); 13957 } 13958 13959 // Determine if native controls should be used 13960 // Our goal should be to get the custom controls on mobile solid everywhere 13961 // so we can remove this all together. Right now this will block custom 13962 // controls on touch enabled laptops like the Chrome Pixel 13963 if (browser.TOUCH_ENABLED && options.nativeControlsForTouch === true || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) { 13964 this.setControls(true); 13965 } 13966 13967 this.triggerReady(); 13968 } 13969 13970 /* HTML5 Support Testing ---------------------------------------------------- */ 13971 13972 /* 13973 * Element for testing browser HTML5 video capabilities 13974 * 13975 * @type {Element} 13976 * @constant 13977 * @private 13978 */ 13979 13980 /** 13981 * Dispose of html5 media element 13982 * 13983 * @method dispose 13984 */ 13985 13986 Html5.prototype.dispose = function dispose() { 13987 var tt = this.el().textTracks; 13988 var emulatedTt = this.textTracks(); 13989 13990 // remove native event listeners 13991 if (tt && tt.removeEventListener) { 13992 tt.removeEventListener('change', this.handleTextTrackChange_); 13993 tt.removeEventListener('addtrack', this.handleTextTrackAdd_); 13994 tt.removeEventListener('removetrack', this.handleTextTrackRemove_); 13995 } 13996 13997 // clearout the emulated text track list. 13998 var i = emulatedTt.length; 13999 14000 while (i--) { 14001 emulatedTt.removeTrack_(emulatedTt[i]); 14002 } 14003 14004 Html5.disposeMediaElement(this.el_); 14005 _Tech.prototype.dispose.call(this); 14006 }; 14007 14008 /** 14009 * Create the component's DOM element 14010 * 14011 * @return {Element} 14012 * @method createEl 14013 */ 14014 14015 Html5.prototype.createEl = function createEl() { 14016 var el = this.options_.tag; 14017 14018 // Check if this browser supports moving the element into the box. 14019 // On the iPhone video will break if you move the element, 14020 // So we have to create a brand new element. 14021 if (!el || this['movingMediaElementInDOM'] === false) { 14022 14023 // If the original tag is still there, clone and remove it. 14024 if (el) { 14025 var clone = el.cloneNode(true); 14026 el.parentNode.insertBefore(clone, el); 14027 Html5.disposeMediaElement(el); 14028 el = clone; 14029 } else { 14030 el = _globalDocument2['default'].createElement('video'); 14031 14032 // determine if native controls should be used 14033 var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag); 14034 var attributes = _utilsMergeOptionsJs2['default']({}, tagAttributes); 14035 if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) { 14036 delete attributes.controls; 14037 } 14038 14039 Dom.setElAttributes(el, _objectAssign2['default'](attributes, { 14040 id: this.options_.techId, 14041 'class': 'vjs-tech' 14042 })); 14043 } 14044 } 14045 14046 // Update specific tag settings, in case they were overridden 14047 var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted']; 14048 for (var i = settingsAttrs.length - 1; i >= 0; i--) { 14049 var attr = settingsAttrs[i]; 14050 var overwriteAttrs = {}; 14051 if (typeof this.options_[attr] !== 'undefined') { 14052 overwriteAttrs[attr] = this.options_[attr]; 14053 } 14054 Dom.setElAttributes(el, overwriteAttrs); 14055 } 14056 14057 return el; 14058 // jenniisawesome = true; 14059 }; 14060 14061 // If we're loading the playback object after it has started loading 14062 // or playing the video (often with autoplay on) then the loadstart event 14063 // has already fired and we need to fire it manually because many things 14064 // rely on it. 14065 14066 Html5.prototype.handleLateInit_ = function handleLateInit_(el) { 14067 var _this = this; 14068 14069 if (el.networkState === 0 || el.networkState === 3) { 14070 // The video element hasn't started loading the source yet 14071 // or didn't find a source 14072 return; 14073 } 14074 14075 if (el.readyState === 0) { 14076 var _ret = (function () { 14077 // NetworkState is set synchronously BUT loadstart is fired at the 14078 // end of the current stack, usually before setInterval(fn, 0). 14079 // So at this point we know loadstart may have already fired or is 14080 // about to fire, and either way the player hasn't seen it yet. 14081 // We don't want to fire loadstart prematurely here and cause a 14082 // double loadstart so we'll wait and see if it happens between now 14083 // and the next loop, and fire it if not. 14084 // HOWEVER, we also want to make sure it fires before loadedmetadata 14085 // which could also happen between now and the next loop, so we'll 14086 // watch for that also. 14087 var loadstartFired = false;
14088 var setLoadstartFired = function setLoadstartFired() { 14089 loadstartFired = true; 14090 }; 14091 _this.on('loadstart', setLoadstartFired); 14092 14093 var triggerLoadstart = function triggerLoadstart() { 14094 // We did miss the original loadstart. Make sure the player 14095 // sees loadstart before loadedmetadata 14096 if (!loadstartFired) { 14097 this.trigger('loadstart'); 14098 } 14099 }; 14100 _this.on('loadedmetadata', triggerLoadstart); 14101 14102 _this.ready(function () { 14103 this.off('loadstart', setLoadstartFired); 14104 this.off('loadedmetadata', triggerLoadstart); 14105 14106 if (!loadstartFired) { 14107 // We did miss the original native loadstart. Fire it now. 14108 this.trigger('loadstart'); 14109 } 14110 }); 14111 14112 return { 14113 v: undefined 14114 }; 14115 })(); 14116 14117 if (typeof _ret === 'object') return _ret.v; 14118 } 14119 14120 // From here on we know that loadstart already fired and we missed it. 14121 // The other readyState events aren't as much of a problem if we double 14122 // them, so not going to go to as much trouble as loadstart to prevent 14123 // that unless we find reason to. 14124 var eventsToTrigger = ['loadstart']; 14125 14126 // loadedmetadata: newly equal to HAVE_METADATA (1) or greater 14127 eventsToTrigger.push('loadedmetadata'); 14128 14129 // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater 14130 if (el.readyState >= 2) { 14131 eventsToTrigger.push('loadeddata'); 14132 } 14133 14134 // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater 14135 if (el.readyState >= 3) { 14136 eventsToTrigger.push('canplay'); 14137 } 14138 14139 // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4) 14140 if (el.readyState >= 4) { 14141 eventsToTrigger.push('canplaythrough'); 14142 } 14143 14144 // We still need to give the player time to add event listeners 14145 this.ready(function () { 14146 eventsToTrigger.forEach(function (type) { 14147 this.trigger(type); 14148 }, this); 14149 }); 14150 }; 14151 14152 Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() { 14153 var tt = this.el().textTracks; 14154 14155 if (tt && tt.addEventListener) { 14156 tt.addEventListener('change', this.handleTextTrackChange_); 14157 tt.addEventListener('addtrack', this.handleTextTrackAdd_); 14158 tt.addEventListener('removetrack', this.handleTextTrackRemove_); 14159 } 14160 }; 14161 14162 Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) { 14163 var tt = this.textTracks(); 14164 this.textTracks().trigger({ 14165 type: 'change', 14166 target: tt, 14167 currentTarget: tt, 14168 srcElement: tt 14169 }); 14170 }; 14171 14172 Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) { 14173 this.textTracks().addTrack_(e.track); 14174 }; 14175 14176 Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) { 14177 this.textTracks().removeTrack_(e.track); 14178 }; 14179 14180 /** 14181 * Play for html5 tech 14182 * 14183 * @method play 14184 */ 14185 14186 Html5.prototype.play = function play() { 14187 this.el_.play(); 14188 }; 14189 14190 /** 14191 * Pause for html5 tech 14192 * 14193 * @method pause 14194 */ 14195 14196 Html5.prototype.pause = function pause() { 14197 this.el_.pause(); 14198 }; 14199 14200 /** 14201 * Paused for html5 tech 14202 * 14203 * @return {Boolean} 14204 * @method paused 14205 */ 14206 14207 Html5.prototype.paused = function paused() { 14208 return this.el_.paused; 14209 }; 14210 14211 /** 14212 * Get current time 14213 * 14214 * @return {Number} 14215 * @method currentTime 14216 */ 14217 14218 Html5.prototype.currentTime = function currentTime() { 14219 return this.el_.currentTime; 14220 }; 14221 14222 /** 14223 * Set current time 14224 * 14225 * @param {Number} seconds Current time of video 14226 * @method setCurrentTime 14227 */ 14228 14229 Html5.prototype.setCurrentTime = function setCurrentTime(seconds) { 14230 try { 14231 this.el_.currentTime = seconds; 14232 } catch (e) { 14233 _utilsLogJs2['default'](e, 'Video is not ready. (Video.js)'); 14234 // this.warning(VideoJS.warnings.videoNotReady); 14235 } 14236 }; 14237 14238 /** 14239 * Get duration 14240 * 14241 * @return {Number} 14242 * @method duration 14243 */ 14244 14245 Html5.prototype.duration = function duration() { 14246 return this.el_.duration || 0; 14247 }; 14248 14249 /** 14250 * Get a TimeRange object that represents the intersection 14251 * of the time ranges for which the user agent has all 14252 * relevant media 14253 * 14254 * @return {TimeRangeObject} 14255 * @method buffered 14256 */ 14257 14258 Html5.prototype.buffered = function buffered() { 14259 return this.el_.buffered; 14260 }; 14261 14262 /** 14263 * Get volume level 14264 * 14265 * @return {Number} 14266 * @method volume 14267 */ 14268 14269 Html5.prototype.volume = function volume() { 14270 return this.el_.volume; 14271 }; 14272 14273 /** 14274 * Set volume level 14275 * 14276 * @param {Number} percentAsDecimal Volume percent as a decimal 14277 * @method setVolume 14278 */ 14279 14280 Html5.prototype.setVolume = function setVolume(percentAsDecimal) { 14281 this.el_.volume = percentAsDecimal; 14282 }; 14283 14284 /** 14285 * Get if muted 14286 * 14287 * @return {Boolean} 14288 * @method muted 14289 */ 14290 14291 Html5.prototype.muted = function muted() { 14292 return this.el_.muted; 14293 }; 14294 14295 /** 14296 * Set muted 14297 * 14298 * @param {Boolean} If player is to be muted or note 14299 * @method setMuted 14300 */ 14301 14302 Html5.prototype.setMuted = function setMuted(muted) { 14303 this.el_.muted = muted; 14304 }; 14305 14306 /** 14307 * Get player width 14308 * 14309 * @return {Number} 14310 * @method width 14311 */ 14312 14313 Html5.prototype.width = function width() { 14314 return this.el_.offsetWidth; 14315 }; 14316 14317 /** 14318 * Get player height 14319 * 14320 * @return {Number} 14321 * @method height 14322 */ 14323 14324 Html5.prototype.height = function height() { 14325 return this.el_.offsetHeight; 14326 }; 14327 14328 /** 14329 * Get if there is fullscreen support 14330 * 14331 * @return {Boolean} 14332 * @method supportsFullScreen 14333 */ 14334 14335 Html5.prototype.supportsFullScreen = function supportsFullScreen() { 14336 if (typeof this.el_.webkitEnterFullScreen === 'function') { 14337 var userAgent = _globalWindow2['default'].navigator.userAgent; 14338 // Seems to be broken in Chromium/Chrome && Safari in Leopard 14339 if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) { 14340 return true; 14341 } 14342 } 14343 return false;
14344 }; 14345 14346 /** 14347 * Request to enter fullscreen 14348 * 14349 * @method enterFullScreen 14350 */ 14351 14352 Html5.prototype.enterFullScreen = function enterFullScreen() { 14353 var video = this.el_; 14354 14355 if ('webkitDisplayingFullscreen' in video) { 14356 this.one('webkitbeginfullscreen', function () { 14357 this.one('webkitendfullscreen', function () { 14358 this.trigger('fullscreenchange', { isFullscreen: false }); 14359 }); 14360 14361 this.trigger('fullscreenchange', { isFullscreen: true }); 14362 }); 14363 } 14364 14365 if (video.paused && video.networkState <= video.HAVE_METADATA) { 14366 // attempt to prime the video element for programmatic access 14367 // this isn't necessary on the desktop but shouldn't hurt 14368 this.el_.play(); 14369 14370 // playing and pausing synchronously during the transition to fullscreen 14371 // can get iOS ~6.1 devices into a play/pause loop 14372 this.setTimeout(function () { 14373 video.pause(); 14374 video.webkitEnterFullScreen(); 14375 }, 0); 14376 } else { 14377 video.webkitEnterFullScreen(); 14378 } 14379 }; 14380 14381 /** 14382 * Request to exit fullscreen 14383 * 14384 * @method exitFullScreen 14385 */ 14386 14387 Html5.prototype.exitFullScreen = function exitFullScreen() { 14388 this.el_.webkitExitFullScreen(); 14389 }; 14390 14391 /** 14392 * Get/set video 14393 * 14394 * @param {Object=} src Source object 14395 * @return {Object} 14396 * @method src 14397 */ 14398 14399 Html5.prototype.src = function src(_src) { 14400 if (_src === undefined) { 14401 return this.el_.src; 14402 } else { 14403 // Setting src through `src` instead of `setSrc` will be deprecated 14404 this.setSrc(_src); 14405 } 14406 }; 14407 14408 /** 14409 * Set video 14410 * 14411 * @param {Object} src Source object 14412 * @deprecated 14413 * @method setSrc 14414 */ 14415 14416 Html5.prototype.setSrc = function setSrc(src) { 14417 this.el_.src = src; 14418 }; 14419 14420 /** 14421 * Load media into player 14422 * 14423 * @method load 14424 */ 14425 14426 Html5.prototype.load = function load() { 14427 this.el_.load(); 14428 }; 14429 14430 /** 14431 * Reset the tech. Removes all sources and calls `load`. 14432 * 14433 * @method reset 14434 */ 14435 14436 Html5.prototype.reset = function reset() { 14437 Html5.resetMediaElement(this.el_); 14438 }; 14439 14440 /** 14441 * Get current source 14442 * 14443 * @return {Object} 14444 * @method currentSrc 14445 */ 14446 14447 Html5.prototype.currentSrc = function currentSrc() { 14448 if (this.currentSource_) { 14449 return this.currentSource_.src; 14450 } else { 14451 return this.el_.currentSrc; 14452 } 14453 }; 14454 14455 /** 14456 * Get poster 14457 * 14458 * @return {String} 14459 * @method poster 14460 */ 14461 14462 Html5.prototype.poster = function poster() { 14463 return this.el_.poster; 14464 }; 14465 14466 /** 14467 * Set poster 14468 * 14469 * @param {String} val URL to poster image 14470 * @method 14471 */ 14472 14473 Html5.prototype.setPoster = function setPoster(val) { 14474 this.el_.poster = val; 14475 }; 14476 14477 /** 14478 * Get preload attribute 14479 * 14480 * @return {String} 14481 * @method preload 14482 */ 14483 14484 Html5.prototype.preload = function preload() { 14485 return this.el_.preload; 14486 }; 14487 14488 /** 14489 * Set preload attribute 14490 * 14491 * @param {String} val Value for preload attribute 14492 * @method setPreload 14493 */ 14494 14495 Html5.prototype.setPreload = function setPreload(val) { 14496 this.el_.preload = val; 14497 }; 14498 14499 /** 14500 * Get autoplay attribute 14501 * 14502 * @return {String} 14503 * @method autoplay 14504 */ 14505 14506 Html5.prototype.autoplay = function autoplay() { 14507 return this.el_.autoplay; 14508 }; 14509 14510 /** 14511 * Set autoplay attribute 14512 * 14513 * @param {String} val Value for preload attribute 14514 * @method setAutoplay 14515 */ 14516 14517 Html5.prototype.setAutoplay = function setAutoplay(val) { 14518 this.el_.autoplay = val; 14519 }; 14520 14521 /** 14522 * Get controls attribute 14523 * 14524 * @return {String} 14525 * @method controls 14526 */ 14527 14528 Html5.prototype.controls = function controls() { 14529 return this.el_.controls; 14530 }; 14531 14532 /** 14533 * Set controls attribute 14534 * 14535 * @param {String} val Value for controls attribute 14536 * @method setControls 14537 */ 14538 14539 Html5.prototype.setControls = function setControls(val) { 14540 this.el_.controls = !!val; 14541 }; 14542 14543 /** 14544 * Get loop attribute 14545 * 14546 * @return {String} 14547 * @method loop 14548 */ 14549 14550 Html5.prototype.loop = function loop() { 14551 return this.el_.loop; 14552 }; 14553 14554 /** 14555 * Set loop attribute 14556 * 14557 * @param {String} val Value for loop attribute 14558 * @method setLoop 14559 */ 14560 14561 Html5.prototype.setLoop = function setLoop(val) { 14562 this.el_.loop = val; 14563 }; 14564 14565 /** 14566 * Get error value 14567 * 14568 * @return {String} 14569 * @method error 14570 */ 14571 14572 Html5.prototype.error = function error() { 14573 return this.el_.error; 14574 }; 14575 14576 /** 14577 * Get whether or not the player is in the "seeking" state 14578 * 14579 * @return {Boolean} 14580 * @method seeking 14581 */ 14582 14583 Html5.prototype.seeking = function seeking() { 14584 return this.el_.seeking; 14585 }; 14586 14587 /** 14588 * Get a TimeRanges object that represents the 14589 * ranges of the media resource to which it is possible 14590 * for the user agent to seek. 14591 * 14592 * @return {TimeRangeObject} 14593 * @method seekable 14594 */ 14595 14596 Html5.prototype.seekable = function seekable() { 14597 return this.el_.seekable; 14598 }; 14599 14600 /** 14601 * Get if video ended 14602 * 14603 * @return {Boolean} 14604 * @method ended 14605 */ 14606 14607 Html5.prototype.ended = function ended() { 14608 return this.el_.ended; 14609 }; 14610 14611 /** 14612 * Get the value of the muted content attribute 14613 * This attribute has no dynamic effect, it only 14614 * controls the default state of the element 14615 * 14616 * @return {Boolean} 14617 * @method defaultMuted 14618 */ 14619 14620 Html5.prototype.defaultMuted = function defaultMuted() { 14621 return this.el_.defaultMuted; 14622 }; 14623 14624 /** 14625 * Get desired speed at which the media resource is to play 14626 * 14627 * @return {Number} 14628 * @method playbackRate 14629 */ 14630 14631 Html5.prototype.playbackRate = function playbackRate() { 14632 return this.el_.playbackRate; 14633 }; 14634 14635 /** 14636 * Returns a TimeRanges object that represents the ranges of the 14637 * media resource that the user agent has played. 14638 * @return {TimeRangeObject} the range of points on the media 14639 * timeline that has been reached through normal playback 14640 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-played 14641 */ 14642 14643 Html5.prototype.played = function played() { 14644 return this.el_.played; 14645 }; 14646 14647 /** 14648 * Set desired speed at which the media resource is to play 14649 * 14650 * @param {Number} val Speed at which the media resource is to play 14651 * @method setPlaybackRate 14652 */ 14653 14654 Html5.prototype.setPlaybackRate = function setPlaybackRate(val) { 14655 this.el_.playbackRate = val; 14656 }; 14657 14658 /** 14659 * Get the current state of network activity for the element, from 14660 * the list below 14661 * NETWORK_EMPTY (numeric value 0) 14662 * NETWORK_IDLE (numeric value 1) 14663 * NETWORK_LOADING (numeric value 2) 14664 * NETWORK_NO_SOURCE (numeric value 3) 14665 * 14666 * @return {Number} 14667 * @method networkState 14668 */ 14669 14670 Html5.prototype.networkState = function networkState() { 14671 return this.el_.networkState; 14672 }; 14673 14674 /** 14675 * Get a value that expresses the current state of the element 14676 * with respect to rendering the current playback position, from 14677 * the codes in the list below 14678 * HAVE_NOTHING (numeric value 0) 14679 * HAVE_METADATA (numeric value 1) 14680 * HAVE_CURRENT_DATA (numeric value 2) 14681 * HAVE_FUTURE_DATA (numeric value 3) 14682 * HAVE_ENOUGH_DATA (numeric value 4) 14683 * 14684 * @return {Number} 14685 * @method readyState 14686 */ 14687 14688 Html5.prototype.readyState = function readyState() { 14689 return this.el_.readyState; 14690 }; 14691 14692 /** 14693 * Get width of video 14694 * 14695 * @return {Number} 14696 * @method videoWidth 14697 */ 14698 14699 Html5.prototype.videoWidth = function videoWidth() { 14700 return this.el_.videoWidth; 14701 }; 14702 14703 /** 14704 * Get height of video 14705 * 14706 * @return {Number} 14707 * @method videoHeight 14708 */ 14709 14710 Html5.prototype.videoHeight = function videoHeight() { 14711 return this.el_.videoHeight; 14712 }; 14713 14714 /** 14715 * Get text tracks 14716 * 14717 * @return {TextTrackList} 14718 * @method textTracks 14719 */ 14720 14721 Html5.prototype.textTracks = function textTracks() { 14722 return _Tech.prototype.textTracks.call(this); 14723 }; 14724 14725 /** 14726 * Creates and returns a text track object 14727 * 14728 * @param {String} kind Text track kind (subtitles, captions, descriptions 14729 * chapters and metadata) 14730 * @param {String=} label Label to identify the text track 14731 * @param {String=} language Two letter language abbreviation 14732 * @return {TextTrackObject} 14733 * @method addTextTrack 14734 */ 14735 14736 Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) { 14737 if (!this['featuresNativeTextTracks']) { 14738 return _Tech.prototype.addTextTrack.call(this, kind, label, language); 14739 } 14740 14741 return this.el_.addTextTrack(kind, label, language); 14742 }; 14743 14744 /** 14745 * Creates a remote text track object and returns a html track element 14746 * 14747 * @param {Object} options The object should contain values for 14748 * kind, language, label and src (location of the WebVTT file) 14749 * @return {HTMLTrackElement} 14750 * @method addRemoteTextTrack 14751 */ 14752 14753 Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack() { 14754 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 14755 14756 if (!this['featuresNativeTextTracks']) { 14757 return _Tech.prototype.addRemoteTextTrack.call(this, options); 14758 } 14759 14760 var htmlTrackElement = _globalDocument2['default'].createElement('track'); 14761 14762 if (options.kind) { 14763 htmlTrackElement.kind = options.kind; 14764 } 14765 if (options.label) { 14766 htmlTrackElement.label = options.label; 14767 } 14768 if (options.language || options.srclang) { 14769 htmlTrackElement.srclang = options.language || options.srclang; 14770 } 14771 if (options['default']) { 14772 htmlTrackElement['default'] = options['default']; 14773 } 14774 if (options.id) { 14775 htmlTrackElement.id = options.id; 14776 } 14777 if (options.src) { 14778 htmlTrackElement.src = options.src; 14779 } 14780 14781 this.el().appendChild(htmlTrackElement); 14782 14783 // store HTMLTrackElement and TextTrack to remote list 14784 this.remoteTextTrackEls().addTrackElement_(htmlTrackElement); 14785 this.remoteTextTracks().addTrack_(htmlTrackElement.track); 14786 14787 return htmlTrackElement; 14788 }; 14789 14790 /** 14791 * Remove remote text track from TextTrackList object 14792 * 14793 * @param {TextTrackObject} track Texttrack object to remove 14794 * @method removeRemoteTextTrack 14795 */ 14796 14797 Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) { 14798 if (!this['featuresNativeTextTracks']) { 14799 return _Tech.prototype.removeRemoteTextTrack.call(this, track); 14800 } 14801 14802 var tracks = undefined, 14803 i = undefined; 14804 14805 var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track); 14806 14807 // remove HTMLTrackElement and TextTrack from remote list 14808 this.remoteTextTrackEls().removeTrackElement_(trackElement); 14809 this.remoteTextTracks().removeTrack_(track); 14810 14811 tracks = this.$$('track'); 14812 14813 i = tracks.length; 14814 while (i--) { 14815 if (track === tracks[i] || track === tracks[i].track) { 14816 this.el().removeChild(tracks[i]); 14817 } 14818 } 14819 }; 14820 14821 return Html5; 14822})(_techJs2['default']); 14823
14824Html5.TEST_VID = _globalDocument2['default'].createElement('video'); 14825var track = _globalDocument2['default'].createElement('track'); 14826track.kind = 'captions'; 14827track.srclang = 'en'; 14828track.label = 'English'; 14829Html5.TEST_VID.appendChild(track); 14830 14831/* 14832 * Check if HTML5 video is supported by this browser/device 14833 * 14834 * @return {Boolean} 14835 */ 14836Html5.isSupported = function () { 14837 // IE9 with no Media Player is a LIAR! (#984) 14838 try { 14839 Html5.TEST_VID['volume'] = 0.5; 14840 } catch (e) { 14841 return false; 14842 } 14843 14844 return !!Html5.TEST_VID.canPlayType; 14845}; 14846 14847// Add Source Handler pattern functions to this tech 14848_techJs2['default'].withSourceHandlers(Html5); 14849 14850/* 14851 * The default native source handler. 14852 * This simply passes the source to the video element. Nothing fancy. 14853 * 14854 * @param {Object} source The source object 14855 * @param {Html5} tech The instance of the HTML5 tech 14856 */ 14857Html5.nativeSourceHandler = {}; 14858 14859/* 14860 * Check if the video element can play the given videotype 14861 * 14862 * @param {String} type The mimetype to check 14863 * @return {String} 'probably', 'maybe', or '' (empty string) 14864 */ 14865Html5.nativeSourceHandler.canPlayType = function (type) { 14866 // IE9 on Windows 7 without MediaPlayer throws an error here 14867 // https://github.com/videojs/video.js/issues/519 14868 try { 14869 return Html5.TEST_VID.canPlayType(type); 14870 } catch (e) { 14871 return ''; 14872 } 14873}; 14874 14875/* 14876 * Check if the video element can handle the source natively 14877 * 14878 * @param {Object} source The source object 14879 * @return {String} 'probably', 'maybe', or '' (empty string) 14880 */ 14881Html5.nativeSourceHandler.canHandleSource = function (source) { 14882 var match, ext; 14883 14884 // If a type was provided we should rely on that 14885 if (source.type) { 14886 return Html5.nativeSourceHandler.canPlayType(source.type); 14887 } else if (source.src) { 14888 // If no type, fall back to checking 'video/[EXTENSION]' 14889 ext = Url.getFileExtension(source.src); 14890 14891 return Html5.nativeSourceHandler.canPlayType('video/' + ext); 14892 } 14893 14894 return ''; 14895}; 14896 14897/* 14898 * Pass the source to the video element 14899 * Adaptive source handlers will have more complicated workflows before passing 14900 * video data to the video element 14901 * 14902 * @param {Object} source The source object 14903 * @param {Html5} tech The instance of the Html5 tech 14904 */ 14905Html5.nativeSourceHandler.handleSource = function (source, tech) { 14906 tech.setSrc(source.src); 14907}; 14908 14909/* 14910* Clean up the source handler when disposing the player or switching sources.. 14911* (no cleanup is needed when supporting the format natively) 14912*/ 14913Html5.nativeSourceHandler.dispose = function () {}; 14914 14915// Register the native source handler 14916Html5.registerSourceHandler(Html5.nativeSourceHandler); 14917 14918/* 14919 * Check if the volume can be changed in this browser/device. 14920 * Volume cannot be changed in a lot of mobile devices. 14921 * Specifically, it can't be changed from 1 on iOS. 14922 * 14923 * @return {Boolean} 14924 */ 14925Html5.canControlVolume = function () { 14926 var volume = Html5.TEST_VID.volume; 14927 Html5.TEST_VID.volume = volume / 2 + 0.1; 14928 return volume !== Html5.TEST_VID.volume; 14929}; 14930 14931/* 14932 * Check if playbackRate is supported in this browser/device. 14933 * 14934 * @return {Number} [description] 14935 */ 14936Html5.canControlPlaybackRate = function () { 14937 var playbackRate = Html5.TEST_VID.playbackRate; 14938 Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1; 14939 return playbackRate !== Html5.TEST_VID.playbackRate; 14940}; 14941 14942/* 14943 * Check to see if native text tracks are supported by this browser/device 14944 * 14945 * @return {Boolean} 14946 */ 14947Html5.supportsNativeTextTracks = function () { 14948 var supportsTextTracks; 14949 14950 // Figure out native text track support
14951 // If mode is a number, we cannot change it because it'll disappear from view. 14952 // Browsers with numeric modes include IE10 and older (<=2013) samsung android models. 14953 // Firefox isn't playing nice either with modifying the mode 14954 // TODO: Investigate firefox: https://github.com/videojs/video.js/issues/1862 14955 supportsTextTracks = !!Html5.TEST_VID.textTracks; 14956 if (supportsTextTracks && Html5.TEST_VID.textTracks.length > 0) { 14957 supportsTextTracks = typeof Html5.TEST_VID.textTracks[0]['mode'] !== 'number'; 14958 } 14959 if (supportsTextTracks && browser.IS_FIREFOX) { 14960 supportsTextTracks = false; 14961 } 14962 if (supportsTextTracks && !('onremovetrack' in Html5.TEST_VID.textTracks)) { 14963 supportsTextTracks = false; 14964 } 14965 14966 return supportsTextTracks; 14967}; 14968 14969/** 14970 * An array of events available on the Html5 tech. 14971 * 14972 * @private 14973 * @type {Array} 14974 */ 14975Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange']; 14976 14977/* 14978 * Set the tech's volume control support status 14979 * 14980 * @type {Boolean} 14981 */ 14982Html5.prototype['featuresVolumeControl'] = Html5.canControlVolume(); 14983 14984/* 14985 * Set the tech's playbackRate support status 14986 * 14987 * @type {Boolean} 14988 */ 14989Html5.prototype['featuresPlaybackRate'] = Html5.canControlPlaybackRate(); 14990 14991/* 14992 * Set the tech's status on moving the video element. 14993 * In iOS, if you move a video element in the DOM, it breaks video playback. 14994 * 14995 * @type {Boolean} 14996 */ 14997Html5.prototype['movingMediaElementInDOM'] = !browser.IS_IOS; 14998 14999/* 15000 * Set the the tech's fullscreen resize support status. 15001 * HTML video is able to automatically resize when going to fullscreen. 15002 * (No longer appears to be used. Can probably be removed.) 15003 */ 15004Html5.prototype['featuresFullscreenResize'] = true; 15005 15006/* 15007 * Set the tech's progress event support status 15008 * (this disables the manual progress events of the Tech) 15009 */ 15010Html5.prototype['featuresProgressEvents'] = true; 15011 15012/* 15013 * Sets the tech's status on native text track support 15014 * 15015 * @type {Boolean} 15016 */ 15017Html5.prototype['featuresNativeTextTracks'] = Html5.supportsNativeTextTracks(); 15018 15019// HTML5 Feature detection and Device Fixes --------------------------------- // 15020var canPlayType = undefined; 15021var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i; 15022var mp4RE = /^video\/mp4/i; 15023 15024Html5.patchCanPlayType = function () { 15025 // Android 4.0 and above can play HLS to some extent but it reports being unable to do so 15026 if (browser.ANDROID_VERSION >= 4.0) { 15027 if (!canPlayType) { 15028 canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType; 15029 } 15030 15031 Html5.TEST_VID.constructor.prototype.canPlayType = function (type) { 15032 if (type && mpegurlRE.test(type)) { 15033 return 'maybe'; 15034 } 15035 return canPlayType.call(this, type); 15036 }; 15037 } 15038 15039 // Override Android 2.2 and less canPlayType method which is broken 15040 if (browser.IS_OLD_ANDROID) { 15041 if (!canPlayType) { 15042 canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType; 15043 } 15044 15045 Html5.TEST_VID.constructor.prototype.canPlayType = function (type) { 15046 if (type && mp4RE.test(type)) { 15047 return 'maybe'; 15048 } 15049 return canPlayType.call(this, type); 15050 }; 15051 } 15052}; 15053 15054Html5.unpatchCanPlayType = function () { 15055 var r = Html5.TEST_VID.constructor.prototype.canPlayType; 15056 Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType; 15057 canPlayType = null; 15058 return r; 15059}; 15060 15061// by default, patch the video element 15062Html5.patchCanPlayType(); 15063 15064Html5.disposeMediaElement = function (el) { 15065 if (!el) { 15066 return; 15067 } 15068 15069 if (el.parentNode) { 15070 el.parentNode.removeChild(el); 15071 } 15072 15073 // remove any child track or source nodes to prevent their loading 15074 while (el.hasChildNodes()) { 15075 el.removeChild(el.firstChild); 15076 } 15077 15078 // remove any src reference. not setting `src=''` because that causes a warning 15079 // in firefox 15080 el.removeAttribute('src'); 15081 15082 // force the media element to update its loading state by calling load() 15083 // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793) 15084 if (typeof el.load === 'function') {
15085 // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473) 15086 (function () { 15087 try { 15088 el.load(); 15089 } catch (e) { 15090 // not supported 15091 } 15092 })(); 15093 } 15094}; 15095 15096Html5.resetMediaElement = function (el) { 15097 if (!el) { 15098 return; 15099 } 15100 15101 var sources = el.querySelectorAll('source'); 15102 var i = sources.length; 15103 while (i--) { 15104 el.removeChild(sources[i]); 15105 } 15106 15107 // remove any src reference. 15108 // not setting `src=''` because that throws an error 15109 el.removeAttribute('src'); 15110 15111 if (typeof el.load === 'function') { 15112 // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473) 15113 (function () { 15114 try { 15115 el.load(); 15116 } catch (e) {} 15117 })(); 15118 } 15119}; 15120 15121_component2['default'].registerComponent('Html5', Html5); 15122_techJs2['default'].registerTech('Html5', Html5); 15123exports['default'] = Html5; 15124module.exports = exports['default']; 15125 15126},{"../component":66,"../utils/browser.js":128,"../utils/dom.js":131,"../utils/fn.js":133,"../utils/log.js":136,"../utils/merge-options.js":137,"../utils/url.js":141,"./tech.js":118,"global/document":1,"global/window":2,"object.assign":45}
15126],117:[function(_dereq_,module,exports){ 15127/** 15128 * @file loader.js 15129 */ 15130'use strict'; 15131 15132exports.__esModule = true; 15133 15134function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 15135 15136function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 15137 15138function _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; } 15139 15140var _componentJs = _dereq_('../component.js'); 15141 15142var _componentJs2 = _interopRequireDefault(_componentJs); 15143 15144var _techJs = _dereq_('./tech.js'); 15145 15146var _techJs2 = _interopRequireDefault(_techJs); 15147 15148var _globalWindow = _dereq_('global/window'); 15149 15150var _globalWindow2 = _interopRequireDefault(_globalWindow); 15151 15152var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js'); 15153 15154var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs); 15155 15156/** 15157 * The Media Loader is the component that decides which playback technology to load 15158 * when the player is initialized. 15159 * 15160 * @param {Object} player Main Player 15161 * @param {Object=} options Object of option names and values 15162 * @param {Function=} ready Ready callback function 15163 * @extends Component 15164 * @class MediaLoader 15165 */ 15166 15167var MediaLoader = (function (_Component) { 15168 _inherits(MediaLoader, _Component); 15169 15170 function MediaLoader(player, options, ready) { 15171 _classCallCheck(this, MediaLoader); 15172 15173 _Component.call(this, player, options, ready); 15174 15175 // If there are no sources when the player is initialized, 15176 // load the first supported playback technology. 15177 15178 if (!options.playerOptions['sources'] || options.playerOptions['sources'].length === 0) { 15179 for (var i = 0, j = options.playerOptions['techOrder']; i < j.length; i++) { 15180 var techName = _utilsToTitleCaseJs2['default'](j[i]); 15181 var tech = _techJs2['default'].getTech(techName); 15182 // Support old behavior of techs being registered as components. 15183 // Remove once that deprecated behavior is removed. 15184 if (!techName) { 15185 tech = _componentJs2['default'].getComponent(techName); 15186 } 15187 15188 // Check if the browser supports this technology 15189 if (tech && tech.isSupported()) { 15190 player.loadTech_(techName); 15191 break; 15192 } 15193 } 15194 } else { 15195 // // Loop through playback technologies (HTML5, Flash) and check for support. 15196 // // Then load the best source. 15197 // // A few assumptions here: 15198 // // All playback technologies respect preload false. 15199 player.src(options.playerOptions['sources']); 15200 } 15201 } 15202 15203 return MediaLoader; 15204})(_componentJs2['default']); 15205 15206_componentJs2['default'].registerComponent('MediaLoader', MediaLoader); 15207exports['default'] = MediaLoader; 15208module.exports = exports['default']; 15209 15210},{"../component.js":66,"../utils/to-title-case.js":140,"./tech.js":118,"global/window":2}],118:[function(_dereq_,module,exports){ 15211/** 15212 * @file tech.js 15213 * Media Technology Controller - Base class for media playback 15214 * technology controllers like Flash and HTML5 15215 */ 15216 15217'use strict'; 15218 15219exports.__esModule = true; 15220 15221function _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; } } 15222 15223function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 15224 15225function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 15226 15227function _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
15227onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 15228 15229var _component = _dereq_('../component'); 15230 15231var _component2 = _interopRequireDefault(_component); 15232 15233var _tracksHtmlTrackElement = _dereq_('../tracks/html-track-element'); 15234 15235var _tracksHtmlTrackElement2 = _interopRequireDefault(_tracksHtmlTrackElement); 15236 15237var _tracksHtmlTrackElementList = _dereq_('../tracks/html-track-element-list'); 15238 15239var _tracksHtmlTrackElementList2 = _interopRequireDefault(_tracksHtmlTrackElementList); 15240 15241var _utilsMergeOptionsJs = _dereq_('../utils/merge-options.js'); 15242 15243var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs); 15244 15245var _tracksTextTrack = _dereq_('../tracks/text-track'); 15246 15247var _tracksTextTrack2 = _interopRequireDefault(_tracksTextTrack); 15248 15249var _tracksTextTrackList = _dereq_('../tracks/text-track-list'); 15250 15251var _tracksTextTrackList2 = _interopRequireDefault(_tracksTextTrackList); 15252 15253var _utilsFnJs = _dereq_('../utils/fn.js'); 15254 15255var Fn = _interopRequireWildcard(_utilsFnJs); 15256 15257var _utilsLogJs = _dereq_('../utils/log.js'); 15258 15259var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 15260 15261var _utilsTimeRangesJs = _dereq_('../utils/time-ranges.js'); 15262 15263var _utilsBufferJs = _dereq_('../utils/buffer.js'); 15264 15265var _mediaErrorJs = _dereq_('../media-error.js'); 15266 15267var _mediaErrorJs2 = _interopRequireDefault(_mediaErrorJs); 15268 15269var _globalWindow = _dereq_('global/window'); 15270 15271var _globalWindow2 = _interopRequireDefault(_globalWindow); 15272 15273var _globalDocument = _dereq_('global/document'); 15274 15275var _globalDocument2 = _interopRequireDefault(_globalDocument); 15276 15277/** 15278 * Base class for media (HTML5 Video, Flash) controllers 15279 * 15280 * @param {Object=} options Options object 15281 * @param {Function=} ready Ready callback function 15282 * @extends Component 15283 * @class Tech 15284 */ 15285 15286var Tech = (function (_Component) { 15287 _inherits(Tech, _Component); 15288 15289 function Tech() { 15290 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 15291 var ready = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1]; 15292 15293 _classCallCheck(this, Tech); 15294 15295 // we don't want the tech to report user activity automatically. 15296 // This is done manually in addControlsListeners 15297 options.reportTouchActivity = false; 15298 _Component.call(this, null, options, ready); 15299 15300 // keep track of whether the current source has played at all to 15301 // implement a very limited played() 15302 this.hasStarted_ = false; 15303 this.on('playing', function () { 15304 this.hasStarted_ = true; 15305 }); 15306 this.on('loadstart', function () { 15307 this.hasStarted_ = false; 15308 }); 15309 15310 this.textTracks_ = options.textTracks; 15311 15312 // Manually track progress in cases where the browser/flash player doesn't report it. 15313 if (!this.featuresProgressEvents) { 15314 this.manualProgressOn(); 15315 } 15316 15317 // Manually track timeupdates in cases where the browser/flash player doesn't report it. 15318 if (!this.featuresTimeupdateEvents) { 15319 this.manualTimeUpdatesOn(); 15320 } 15321 15322 if (options.nativeCaptions === false || options.nativeTextTracks === false) { 15323 this.featuresNativeTextTracks = false; 15324 } 15325 15326 if (!this.featuresNativeTextTracks) { 15327 this.on('ready', this.emulateTextTracks); 15328 } 15329 15330 this.initTextTrackListeners(); 15331 15332 // Turn on component tap events 15333 this.emitTapEvents(); 15334 } 15335 15336 /* 15337 * List of associated text tracks 15338 * 15339 * @type {Array} 15340 * @private 15341 */ 15342 15343 /* Fallbacks for unsupported event types 15344 ================================================================================ */ 15345 // Manually trigger progress events based on changes to the buffered amount 15346 // Many flash players and older HTML5 browsers don't send progress or progress-like events 15347 /** 15348 * Turn on progress events 15349 * 15350 * @method manualProgressOn 15351 */ 15352 15353 Tech.prototype.manualProgressOn = function manualProgressOn() { 15354 this.on('durationchange', this.onDurationChange); 15355 15356 this.manualProgress = true; 15357 15358 // Trigger progress watching when a source begins loading 15359 this.one('ready', this.trackProgress); 15360 }; 15361 15362 /** 15363 * Turn off progress events 15364 * 15365 * @method manualProgressOff 15366 */ 15367 15368 Tech.prototype.manualProgressOff = function manualProgressOff() { 15369 this.manualProgress = false;
15370 this.stopTrackingProgress(); 15371 15372 this.off('durationchange', this.onDurationChange); 15373 }; 15374 15375 /** 15376 * Track progress 15377 * 15378 * @method trackProgress 15379 */ 15380 15381 Tech.prototype.trackProgress = function trackProgress() { 15382 this.stopTrackingProgress(); 15383 this.progressInterval = this.setInterval(Fn.bind(this, function () { 15384 // Don't trigger unless buffered amount is greater than last time 15385 15386 var numBufferedPercent = this.bufferedPercent(); 15387 15388 if (this.bufferedPercent_ !== numBufferedPercent) { 15389 this.trigger('progress'); 15390 } 15391 15392 this.bufferedPercent_ = numBufferedPercent; 15393 15394 if (numBufferedPercent === 1) { 15395 this.stopTrackingProgress(); 15396 } 15397 }), 500); 15398 }; 15399 15400 /** 15401 * Update duration 15402 * 15403 * @method onDurationChange 15404 */ 15405 15406 Tech.prototype.onDurationChange = function onDurationChange() { 15407 this.duration_ = this.duration(); 15408 }; 15409 15410 /** 15411 * Create and get TimeRange object for buffering 15412 * 15413 * @return {TimeRangeObject} 15414 * @method buffered 15415 */ 15416 15417 Tech.prototype.buffered = function buffered() { 15418 return _utilsTimeRangesJs.createTimeRange(0, 0); 15419 }; 15420 15421 /** 15422 * Get buffered percent 15423 * 15424 * @return {Number} 15425 * @method bufferedPercent 15426 */ 15427 15428 Tech.prototype.bufferedPercent = function bufferedPercent() { 15429 return _utilsBufferJs.bufferedPercent(this.buffered(), this.duration_); 15430 }; 15431 15432 /** 15433 * Stops tracking progress by clearing progress interval 15434 * 15435 * @method stopTrackingProgress 15436 */ 15437 15438 Tech.prototype.stopTrackingProgress = function stopTrackingProgress() { 15439 this.clearInterval(this.progressInterval); 15440 }; 15441 15442 /*! Time Tracking -------------------------------------------------------------- */ 15443 /** 15444 * Set event listeners for on play and pause and tracking current time 15445 * 15446 * @method manualTimeUpdatesOn 15447 */ 15448 15449 Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() { 15450 this.manualTimeUpdates = true; 15451 15452 this.on('play', this.trackCurrentTime); 15453 this.on('pause', this.stopTrackingCurrentTime); 15454 }; 15455 15456 /** 15457 * Remove event listeners for on play and pause and tracking current time 15458 * 15459 * @method manualTimeUpdatesOff 15460 */ 15461 15462 Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() { 15463 this.manualTimeUpdates = false; 15464 this.stopTrackingCurrentTime(); 15465 this.off('play', this.trackCurrentTime); 15466 this.off('pause', this.stopTrackingCurrentTime); 15467 }; 15468 15469 /** 15470 * Tracks current time 15471 * 15472 * @method trackCurrentTime 15473 */ 15474 15475 Tech.prototype.trackCurrentTime = function trackCurrentTime() { 15476 if (this.currentTimeInterval) { 15477 this.stopTrackingCurrentTime(); 15478 } 15479 this.currentTimeInterval = this.setInterval(function () { 15480 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); 15481 }, 250); // 42 = 24 fps // 250 is what Webkit uses // FF uses 15 15482 }; 15483 15484 /** 15485 * Turn off play progress tracking (when paused or dragging) 15486 * 15487 * @method stopTrackingCurrentTime 15488 */ 15489 15490 Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() { 15491 this.clearInterval(this.currentTimeInterval); 15492 15493 // #1002 - if the video ends right before the next timeupdate would happen, 15494 // the progress bar won't make it all the way to the end 15495 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); 15496 }; 15497 15498 /** 15499 * Turn off any manual progress or timeupdate tracking 15500 * 15501 * @method dispose 15502 */ 15503 15504 Tech.prototype.dispose = function dispose() { 15505 // clear out text tracks because we can't reuse them between techs 15506 var textTracks = this.textTracks(); 15507 15508 if (textTracks) { 15509 var i = textTracks.length; 15510 while (i--) { 15511 this.removeRemoteTextTrack(textTracks[i]); 15512 } 15513 } 15514 15515 // Turn off any manual progress or timeupdate tracking 15516 if (this.manualProgress) { 15517 this.manualProgressOff(); 15518 } 15519 15520 if (this.manualTimeUpdates) { 15521 this.manualTimeUpdatesOff(); 15522 } 15523 15524 _Component.prototype.dispose.call(this); 15525 }; 15526 15527 /** 15528 * Reset the tech. Removes all sources and resets readyState. 15529 * 15530 * @method reset 15531 */ 15532 15533 Tech.prototype.reset = function reset() {}; 15534 15535 /** 15536 * When invoked without an argument, returns a MediaError object 15537 * representing the current error state of the player or null if 15538 * there is no error. When invoked with an argument, set the current 15539 * error state of the player. 15540 * @param {MediaError=} err Optional an error object 15541 * @return {MediaError} the current error object or null 15542 * @method error 15543 */ 15544 15545 Tech.prototype.error = function error(err) { 15546 if (err !== undefined) { 15547 if (err instanceof _mediaErrorJs2['default']) { 15548 this.error_ = err; 15549 } else { 15550 this.error_ = new _mediaErrorJs2['default'](err); 15551 } 15552 this.trigger('error'); 15553 } 15554 return this.error_; 15555 }; 15556 15557 /** 15558 * Return the time ranges that have been played through for the 15559 * current source. This implementation is incomplete. It does not 15560 * track the played time ranges, only whether the source has played 15561 * at all or not. 15562 * @return {TimeRangeObject} a single time range if this video has 15563 * played or an empty set of ranges if not. 15564 * @method played 15565 */ 15566 15567 Tech.prototype.played = function played() { 15568 if (this.hasStarted_) { 15569 return _utilsTimeRangesJs.createTimeRange(0, 0); 15570 } 15571 return _utilsTimeRangesJs.createTimeRange(); 15572 }; 15573 15574 /** 15575 * Set current time 15576 * 15577 * @method setCurrentTime 15578 */ 15579 15580 Tech.prototype.setCurrentTime = function setCurrentTime() { 15581 // improve the accuracy of manual timeupdates 15582 if (this.manualTimeUpdates) { 15583 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); 15584 } 15585 }; 15586 15587 /** 15588 * Initialize texttrack listeners 15589 * 15590 * @method initTextTrackListeners 15591 */ 15592 15593 Tech.prototype.initTextTrackListeners = function initTextTrackListeners() { 15594 var textTrackListChanges = Fn.bind(this, function () { 15595 this.trigger('texttrackchange'); 15596 }); 15597 15598 var tracks = this.textTracks(); 15599 15600 if (!tracks) return; 15601 15602 tracks.addEventListener('removetrack', textTrackListChanges); 15603 tracks.addEventListener('addtrack', textTrackListChanges); 15604 15605 this.on('dispose', Fn.bind(this, function () { 15606 tracks.removeEventListener('removetrack', textTrackListChanges); 15607 tracks.removeEventListener('addtrack', textTrackListChanges); 15608 })); 15609 }; 15610 15611 /** 15612 * Emulate texttracks 15613 * 15614 * @method emulateTextTracks 15615 */ 15616 15617 Tech.prototype.emulateTextTracks = function emulateTextTracks() { 15618 var _this = this; 15619 15620 var tracks = this.textTracks(); 15621 if (!tracks) { 15622 return; 15623 } 15624 15625 if (!_globalWindow2['default']['WebVTT'] && this.el().parentNode != null) { 15626 var script = _globalDocument2['default'].createElement('script'); 15627 script.src = this.options_['vtt.js'] || 'https://cdn.rawgit.com/gkatsev/vtt.js/vjs-v0.12.1/dist/vtt.min.js'; 15628 this.el().parentNode.appendChild(script); 15629 _globalWindow2['default']['WebVTT'] = true; 15630 } 15631 15632 var updateDisplay = function updateDisplay() { 15633 return _this.trigger('texttrackchange'); 15634 }; 15635 var textTracksChanges = function textTracksChanges() { 15636 updateDisplay(); 15637 15638 for (var i = 0; i < tracks.length; i++) { 15639 var track = tracks[i]; 15640 track.removeEventListener('cuechange', updateDisplay); 15641 if (track.mode === 'showing') { 15642 track.addEventListener('cuechange', updateDisplay); 15643 } 15644 } 15645 }; 15646 15647 textTracksChanges(); 15648 tracks.addEventListener('change', textTracksChanges); 15649 15650 this.on('dispose', function () { 15651 tracks.removeEventListener('change', textTracksChanges); 15652 }); 15653 }; 15654 15655 /* 15656 * Provide default methods for text tracks. 15657 * 15658 * Html5 tech overrides these. 15659 */ 15660 15661 /** 15662 * Get texttracks 15663 * 15664 * @returns {TextTrackList} 15665 * @method textTracks 15666 */ 15667 15668 Tech.prototype.textTracks = function textTracks() { 15669 this.textTracks_ = this.textTracks_ || new _tracksTextTrackList2['default'](); 15670 return this.textTracks_; 15671 }; 15672 15673 /** 15674 * Get remote texttracks 15675 * 15676 * @returns {TextTrackList} 15677 * @method remoteTextTracks 15678 */ 15679 15680 Tech.prototype.remoteTextTracks = function remoteTextTracks() { 15681 this.remoteTextTracks_ = this.remoteTextTracks_ || new _tracksTextTrackList2['default'](); 15682 return this.remoteTextTracks_; 15683 }; 15684 15685 /** 15686 * Get remote htmltrackelements 15687 * 15688 * @returns {HTMLTrackElementList} 15689 * @method remoteTextTrackEls 15690 */ 15691 15692 Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() { 15693 this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _tracksHtmlTrackElementList2['default'](); 15694 return this.remoteTextTrackEls_;
15695 }; 15696 15697 /** 15698 * Creates and returns a remote text track object 15699 * 15700 * @param {String} kind Text track kind (subtitles, captions, descriptions 15701 * chapters and metadata) 15702 * @param {String=} label Label to identify the text track 15703 * @param {String=} language Two letter language abbreviation 15704 * @return {TextTrackObject} 15705 * @method addTextTrack 15706 */ 15707 15708 Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) { 15709 if (!kind) { 15710 throw new Error('TextTrack kind is required but was not provided'); 15711 } 15712 15713 return createTrackHelper(this, kind, label, language); 15714 }; 15715 15716 /** 15717 * Creates a remote text track object and returns a emulated html track element 15718 * 15719 * @param {Object} options The object should contain values for 15720 * kind, language, label and src (location of the WebVTT file) 15721 * @return {HTMLTrackElement} 15722 * @method addRemoteTextTrack 15723 */ 15724 15725 Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack(options) { 15726 var track = _utilsMergeOptionsJs2['default'](options, { 15727 tech: this 15728 }); 15729 15730 var htmlTrackElement = new _tracksHtmlTrackElement2['default'](track); 15731 15732 // store HTMLTrackElement and TextTrack to remote list 15733 this.remoteTextTrackEls().addTrackElement_(htmlTrackElement); 15734 this.remoteTextTracks().addTrack_(htmlTrackElement.track); 15735 15736 // must come after remoteTextTracks() 15737 this.textTracks().addTrack_(htmlTrackElement.track); 15738 15739 return htmlTrackElement; 15740 }; 15741 15742 /** 15743 * Remove remote texttrack 15744 * 15745 * @param {TextTrackObject} track Texttrack to remove 15746 * @method removeRemoteTextTrack 15747 */ 15748 15749 Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) { 15750 this.textTracks().removeTrack_(track); 15751 15752 var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track); 15753 15754 // remove HTMLTrackElement and TextTrack from remote list 15755 this.remoteTextTrackEls().removeTrackElement_(trackElement); 15756 this.remoteTextTracks().removeTrack_(track); 15757 }; 15758 15759 /** 15760 * Provide a default setPoster method for techs 15761 * Poster support for techs should be optional, so we don't want techs to 15762 * break if they don't have a way to set a poster. 15763 * 15764 * @method setPoster 15765 */ 15766 15767 Tech.prototype.setPoster = function setPoster() {}; 15768 15769 /* 15770 * Check if the tech can support the given type 15771 * 15772 * The base tech does not support any type, but source handlers might 15773 * overwrite this. 15774 * 15775 * @param {String} type The mimetype to check 15776 * @return {String} 'probably', 'maybe', or '' (empty string) 15777 */ 15778 15779 Tech.prototype.canPlayType = function canPlayType() { 15780 return ''; 15781 }; 15782 15783 /* 15784 * Return whether the argument is a Tech or not. 15785 * Can be passed either a Class like `Html5` or a instance like `player.tech_` 15786 * 15787 * @param {Object} component An item to check 15788 * @return {Boolean} Whether it is a tech or not 15789 */ 15790 15791 Tech.isTech = function isTech(component) { 15792 return component.prototype instanceof Tech || component instanceof Tech || component === Tech; 15793 }; 15794 15795 /** 15796 * Registers a Tech 15797 * 15798 * @param {String} name Name of the Tech to register 15799 * @param {Object} tech The tech to register 15800 * @static 15801 * @method registerComponent 15802 */ 15803 15804 Tech.registerTech = function registerTech(name, tech) { 15805 if (!Tech.techs_) { 15806 Tech.techs_ = {}; 15807 } 15808 15809 if (!Tech.isTech(tech)) { 15810 throw new Error('Tech ' + name + ' must be a Tech'); 15811 } 15812 15813 Tech.techs_[name] = tech; 15814 return tech; 15815 }; 15816 15817 /** 15818 * Gets a component by name 15819 * 15820 * @param {String} name Name of the component to get 15821 * @return {Component} 15822 * @static 15823 * @method getComponent 15824 */ 15825 15826 Tech.getTech = function getTech(name) { 15827 if (Tech.techs_ && Tech.techs_[name]) { 15828 return Tech.techs_[name]; 15829 } 15830 15831 if (_globalWindow2['default'] && _globalWindow2['default'].videojs && _globalWindow2['default'].videojs[name]) { 15832 _utilsLogJs2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)'); 15833 return _globalWindow2['default'].videojs[name]; 15834 } 15835 }; 15836 15837 return Tech; 15838})(_component2['default']); 15839 15840Tech.prototype.textTracks_; 15841 15842var createTrackHelper = function createTrackHelper(self, kind, label, language) { 15843 var options = arguments.length <= 4 || arguments[4] === undefined ? {} : arguments[4]; 15844 15845 var tracks = self.textTracks(); 15846 15847 options.kind = kind; 15848 15849 if (label) { 15850 options.label = label; 15851 } 15852 if (language) { 15853 options.language = language; 15854 } 15855 options.tech = self; 15856 15857 var track = new _tracksTextTrack2['default'](options); 15858 tracks.addTrack_(track); 15859 15860 return track; 15861}; 15862 15863Tech.prototype.featuresVolumeControl = true; 15864 15865// Resizing plugins using request fullscreen reloads the plugin 15866Tech.prototype.featuresFullscreenResize = false;
15867Tech.prototype.featuresPlaybackRate = false; 15868 15869// Optional events that we can manually mimic with timers 15870// currently not triggered by video-js-swf 15871Tech.prototype.featuresProgressEvents = false; 15872Tech.prototype.featuresTimeupdateEvents = false; 15873 15874Tech.prototype.featuresNativeTextTracks = false; 15875 15876/* 15877 * A functional mixin for techs that want to use the Source Handler pattern. 15878 * 15879 * ##### EXAMPLE: 15880 * 15881 * Tech.withSourceHandlers.call(MyTech); 15882 * 15883 */ 15884Tech.withSourceHandlers = function (_Tech) { 15885 /* 15886 * Register a source handler 15887 * Source handlers are scripts for handling specific formats. 15888 * The source handler pattern is used for adaptive formats (HLS, DASH) that 15889 * manually load video data and feed it into a Source Buffer (Media Source Extensions) 15890 * @param {Function} handler The source handler 15891 * @param {Boolean} first Register it before any existing handlers 15892 */ 15893 _Tech.registerSourceHandler = function (handler, index) { 15894 var handlers = _Tech.sourceHandlers; 15895 15896 if (!handlers) { 15897 handlers = _Tech.sourceHandlers = []; 15898 } 15899 15900 if (index === undefined) { 15901 // add to the end of the list 15902 index = handlers.length; 15903 } 15904 15905 handlers.splice(index, 0, handler); 15906 }; 15907 15908 /* 15909 * Check if the tech can support the given type 15910 * @param {String} type The mimetype to check 15911 * @return {String} 'probably', 'maybe', or '' (empty string) 15912 */ 15913 _Tech.canPlayType = function (type) { 15914 var handlers = _Tech.sourceHandlers || []; 15915 var can = undefined; 15916 15917 for (var i = 0; i < handlers.length; i++) { 15918 can = handlers[i].canPlayType(type); 15919 15920 if (can) { 15921 return can; 15922 } 15923 } 15924 15925 return ''; 15926 }; 15927 15928 /* 15929 * Return the first source handler that supports the source 15930 * TODO: Answer question: should 'probably' be prioritized over 'maybe' 15931 * @param {Object} source The source object 15932 * @returns {Object} The first source handler that supports the source 15933 * @returns {null} Null if no source handler is found 15934 */ 15935 _Tech.selectSourceHandler = function (source) { 15936 var handlers = _Tech.sourceHandlers || []; 15937 var can = undefined; 15938 15939 for (var i = 0; i < handlers.length; i++) { 15940 can = handlers[i].canHandleSource(source); 15941 15942 if (can) { 15943 return handlers[i]; 15944 } 15945 } 15946 15947 return null; 15948 }; 15949 15950 /* 15951 * Check if the tech can support the given source 15952 * @param {Object} srcObj The source object 15953 * @return {String} 'probably', 'maybe', or '' (empty string) 15954 */ 15955 _Tech.canPlaySource = function (srcObj) { 15956 var sh = _Tech.selectSourceHandler(srcObj); 15957 15958 if (sh) { 15959 return sh.canHandleSource(srcObj); 15960 } 15961 15962 return ''; 15963 }; 15964 15965 /* 15966 * When using a source handler, prefer its implementation of 15967 * any function normally provided by the tech. 15968 */ 15969 var deferrable = ['seekable', 'duration']; 15970 15971 deferrable.forEach(function (fnName) { 15972 var originalFn = this[fnName]; 15973 15974 if (typeof originalFn !== 'function') { 15975 return; 15976 } 15977 15978 this[fnName] = function () { 15979 if (this.sourceHandler_ && this.sourceHandler_[fnName]) { 15980 return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments); 15981 } 15982 return originalFn.apply(this, arguments); 15983 }; 15984 }, _Tech.prototype); 15985 15986 /* 15987 * Create a function for setting the source using a source object 15988 * and source handlers. 15989 * Should never be called unless a source handler was found. 15990 * @param {Object} source A source object with src and type keys 15991 * @return {Tech} self 15992 */ 15993 _Tech.prototype.setSource = function (source) { 15994 var sh = _Tech.selectSourceHandler(source); 15995 15996 if (!sh) { 15997 // Fall back to a native source hander when unsupported sources are 15998 // deliberately set 15999 if (_Tech.nativeSourceHandler) { 16000 sh = _Tech.nativeSourceHandler; 16001 } else { 16002 _utilsLogJs2['default'].error('No source hander found for the current source.'); 16003 } 16004 } 16005 16006 // Dispose any existing source handler 16007 this.disposeSourceHandler(); 16008 this.off('dispose', this.disposeSourceHandler); 16009 16010 this.currentSource_ = source; 16011 this.sourceHandler_ = sh.handleSource(source, this); 16012 this.on('dispose', this.disposeSourceHandler); 16013 16014 return this; 16015 }; 16016 16017 /* 16018 * Clean up any existing source handler 16019 */ 16020 _Tech.prototype.disposeSourceHandler = function () { 16021 if (this.sourceHandler_ && this.sourceHandler_.dispose) { 16022 this.sourceHandler_.dispose(); 16023 } 16024 }; 16025}; 16026 16027_component2['default'].registerComponent('Tech', Tech); 16028// Old name for Tech 16029_component2['default'].registerComponent('MediaTechController', Tech);
16030Tech.registerTech('Tech', Tech); 16031exports['default'] = Tech; 16032module.exports = exports['default']; 16033 16034},{"../component":66,"../media-error.js":102,"../tracks/html-track-element":120,"../tracks/html-track-element-list":119,"../tracks/text-track":127,"../tracks/text-track-list":125,"../utils/buffer.js":129,"../utils/fn.js":133,"../utils/log.js":136,"../utils/merge-options.js":137,"../utils/time-ranges.js":139,"global/document":1,"global/window":2}],119:[function(_dereq_,module,exports){ 16035/** 16036 * @file html-track-element-list.js 16037 */ 16038 16039'use strict'; 16040 16041exports.__esModule = true; 16042 16043function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16044 16045function _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; } } 16046 16047function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 16048 16049var _utilsBrowserJs = _dereq_('../utils/browser.js'); 16050 16051var browser = _interopRequireWildcard(_utilsBrowserJs); 16052 16053var _globalDocument = _dereq_('global/document'); 16054 16055var _globalDocument2 = _interopRequireDefault(_globalDocument); 16056 16057var HtmlTrackElementList = (function () { 16058 function HtmlTrackElementList() { 16059 var trackElements = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; 16060 16061 _classCallCheck(this, HtmlTrackElementList); 16062 16063 var list = this; 16064 16065 if (browser.IS_IE8) { 16066 list = _globalDocument2['default'].createElement('custom'); 16067 16068 for (var prop in HtmlTrackElementList.prototype) { 16069 if (prop !== 'constructor') { 16070 list[prop] = HtmlTrackElementList.prototype[prop]; 16071 } 16072 } 16073 } 16074 16075 list.trackElements_ = []; 16076 16077 Object.defineProperty(list, 'length', { 16078 get: function get() { 16079 return this.trackElements_.length; 16080 } 16081 }); 16082 16083 for (var i = 0, _length = trackElements.length; i < _length; i++) { 16084 list.addTrackElement_(trackElements[i]); 16085 } 16086 16087 if (browser.IS_IE8) { 16088 return list; 16089 } 16090 } 16091 16092 HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) { 16093 this.trackElements_.push(trackElement); 16094 }; 16095 16096 HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) { 16097 var trackElement_ = undefined; 16098 16099 for (var i = 0, _length2 = this.trackElements_.length; i < _length2; i++) { 16100 if (track === this.trackElements_[i].track) { 16101 trackElement_ = this.trackElements_[i]; 16102 16103 break; 16104 } 16105 } 16106 16107 return trackElement_; 16108 }; 16109 16110 HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) { 16111 for (var i = 0, _length3 = this.trackElements_.length; i < _length3; i++) { 16112 if (trackElement === this.trackElements_[i]) { 16113 this.trackElements_.splice(i, 1); 16114 16115 break; 16116 } 16117 } 16118 }; 16119 16120 return HtmlTrackElementList; 16121})(); 16122 16123exports['default'] = HtmlTrackElementList; 16124module.exports = exports['default']; 16125 16126},{"../utils/browser.js":128,"global/document":1}],120:[function(_dereq_,module,exports){ 16127/** 16128 * @file html-track-element.js 16129 */ 16130 16131'use strict'; 16132 16133exports.__esModule = true; 16134 16135function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16136 16137function _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; } } 16138 16139function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 16140 16141function _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
16141onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 16142 16143var _utilsBrowserJs = _dereq_('../utils/browser.js'); 16144 16145var browser = _interopRequireWildcard(_utilsBrowserJs); 16146 16147var _globalDocument = _dereq_('global/document'); 16148 16149var _globalDocument2 = _interopRequireDefault(_globalDocument); 16150 16151var _eventTarget = _dereq_('../event-target'); 16152 16153var _eventTarget2 = _interopRequireDefault(_eventTarget); 16154 16155var _tracksTextTrack = _dereq_('../tracks/text-track'); 16156 16157var _tracksTextTrack2 = _interopRequireDefault(_tracksTextTrack); 16158 16159var NONE = 0; 16160var LOADING = 1; 16161var LOADED = 2; 16162var ERROR = 3; 16163 16164/** 16165 * https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement 16166 * 16167 * interface HTMLTrackElement : HTMLElement { 16168 * attribute DOMString kind; 16169 * attribute DOMString src; 16170 * attribute DOMString srclang; 16171 * attribute DOMString label; 16172 * attribute boolean default; 16173 * 16174 * const unsigned short NONE = 0; 16175 * const unsigned short LOADING = 1; 16176 * const unsigned short LOADED = 2; 16177 * const unsigned short ERROR = 3; 16178 * readonly attribute unsigned short readyState; 16179 * 16180 * readonly attribute TextTrack track; 16181 * }; 16182 * 16183 * @param {Object} options TextTrack configuration 16184 * @class HTMLTrackElement 16185 */ 16186 16187var HTMLTrackElement = (function (_EventTarget) { 16188 _inherits(HTMLTrackElement, _EventTarget); 16189 16190 function HTMLTrackElement() { 16191 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 16192 16193 _classCallCheck(this, HTMLTrackElement); 16194 16195 _EventTarget.call(this); 16196 16197 var readyState = undefined, 16198 trackElement = this; 16199 16200 if (browser.IS_IE8) { 16201 trackElement = _globalDocument2['default'].createElement('custom'); 16202 16203 for (var prop in HTMLTrackElement.prototype) { 16204 if (prop !== 'constructor') { 16205 trackElement[prop] = HTMLTrackElement.prototype[prop]; 16206 } 16207 } 16208 } 16209 16210 var track = new _tracksTextTrack2['default'](options); 16211 16212 trackElement.kind = track.kind; 16213 trackElement.src = track.src; 16214 trackElement.srclang = track.language; 16215 trackElement.label = track.label; 16216 trackElement['default'] = track['default']; 16217 16218 Object.defineProperty(trackElement, 'readyState', { 16219 get: function get() { 16220 return readyState; 16221 } 16222 }); 16223 16224 Object.defineProperty(trackElement, 'track', { 16225 get: function get() { 16226 return track; 16227 } 16228 }); 16229 16230 readyState = NONE; 16231 16232 track.addEventListener('loadeddata', function () { 16233 readyState = LOADED; 16234 16235 trackElement.trigger({ 16236 type: 'load', 16237 target: trackElement 16238 }); 16239 }); 16240 16241 if (browser.IS_IE8) { 16242 return trackElement; 16243 } 16244 } 16245 16246 return HTMLTrackElement; 16247})(_eventTarget2['default']); 16248 16249HTMLTrackElement.prototype.allowedEvents_ = { 16250 load: 'load' 16251}; 16252 16253HTMLTrackElement.NONE = NONE; 16254HTMLTrackElement.LOADING = LOADING; 16255HTMLTrackElement.LOADED = LOADED; 16256HTMLTrackElement.ERROR = ERROR; 16257 16258exports['default'] = HTMLTrackElement; 16259module.exports = exports['default']; 16260 16261},{"../event-target":98,"../tracks/text-track":127,"../utils/browser.js":128,"global/document":1}],121:[function(_dereq_,module,exports){ 16262/** 16263 * @file text-track-cue-list.js 16264 */ 16265'use strict'; 16266 16267exports.__esModule = true; 16268 16269function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16270 16271function _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; } } 16272 16273var _utilsBrowserJs = _dereq_('../utils/browser.js'); 16274 16275var browser = _interopRequireWildcard(_utilsBrowserJs); 16276 16277var _globalDocument = _dereq_('global/document'); 16278 16279var _globalDocument2 = _interopRequireDefault(_globalDocument); 16280 16281/* 16282 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist 16283 * 16284 * interface TextTrackCueList { 16285 * readonly attribute unsigned long length; 16286 * getter TextTrackCue (unsigned long index); 16287 * TextTrackCue? getCueById(DOMString id); 16288 * }; 16289 */ 16290 16291var TextTrackCueList = function TextTrackCueList(cues) { 16292 var list = this; 16293 16294 if (browser.IS_IE8) { 16295 list = _globalDocument2['default'].createElement('custom'); 16296 16297 for (var prop in TextTrackCueList.prototype) { 16298 if (prop !== 'constructor') { 16299 list[prop] = TextTrackCueList.prototype[prop]; 16300 } 16301 } 16302 } 16303 16304 TextTrackCueList.prototype.setCues_.call(list, cues); 16305 16306 Object.defineProperty(list, 'length', { 16307 get: function get() { 16308 return this.length_; 16309 } 16310 }); 16311 16312 if (browser.IS_IE8) { 16313 return list; 16314 } 16315}; 16316 16317TextTrackCueList.prototype.setCues_ = function (cues) { 16318 var oldLength = this.length || 0; 16319 var i = 0; 16320 var l = cues.length; 16321 16322 this.cues_ = cues; 16323 this.length_ = cues.length; 16324 16325 var defineProp = function defineProp(i) { 16326 if (!('' + i in this)) { 16327 Object.defineProperty(this, '' + i, { 16328 get: function get() { 16329 return this.cues_[i]; 16330 } 16331 }); 16332 } 16333 }; 16334 16335 if (oldLength < l) { 16336 i = oldLength; 16337 16338 for (; i < l; i++) { 16339 defineProp.call(this, i); 16340 } 16341 } 16342}; 16343 16344TextTrackCueList.prototype.getCueById = function (id) { 16345 var result = null; 16346 for (var i = 0, l = this.length; i < l; i++) { 16347 var cue = this[i]; 16348 if (cue.id === id) { 16349 result = cue; 16350 break; 16351 } 16352 } 16353 16354 return result; 16355}; 16356 16357exports['default'] = TextTrackCueList; 16358module.exports = exports['default']; 16359 16360},{"../utils/browser.js":128,"global/document":1}],122:[function(_dereq_,module,exports){ 16361/** 16362 * @file text-track-display.js 16363 */ 16364'use strict'; 16365 16366exports.__esModule = true; 16367 16368function _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; } } 16369 16370function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16371 16372function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 16373 16374function _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
16374onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 16375 16376var _component = _dereq_('../component'); 16377 16378var _component2 = _interopRequireDefault(_component); 16379 16380var _menuMenuJs = _dereq_('../menu/menu.js'); 16381 16382var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs); 16383 16384var _menuMenuItemJs = _dereq_('../menu/menu-item.js'); 16385 16386var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs); 16387 16388var _menuMenuButtonJs = _dereq_('../menu/menu-button.js'); 16389 16390var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs); 16391 16392var _utilsFnJs = _dereq_('../utils/fn.js'); 16393 16394var Fn = _interopRequireWildcard(_utilsFnJs); 16395 16396var _globalDocument = _dereq_('global/document'); 16397 16398var _globalDocument2 = _interopRequireDefault(_globalDocument); 16399 16400var _globalWindow = _dereq_('global/window'); 16401 16402var _globalWindow2 = _interopRequireDefault(_globalWindow); 16403 16404var darkGray = '#222'; 16405var lightGray = '#ccc'; 16406var fontMap = { 16407 monospace: 'monospace', 16408 sansSerif: 'sans-serif', 16409 serif: 'serif', 16410 monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace', 16411 monospaceSerif: '"Courier New", monospace', 16412 proportionalSansSerif: 'sans-serif', 16413 proportionalSerif: 'serif', 16414 casual: '"Comic Sans MS", Impact, fantasy', 16415 script: '"Monotype Corsiva", cursive', 16416 smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif' 16417}; 16418 16419/** 16420 * The component for displaying text track cues 16421 * 16422 * @param {Object} player Main Player 16423 * @param {Object=} options Object of option names and values 16424 * @param {Function=} ready Ready callback function 16425 * @extends Component 16426 * @class TextTrackDisplay 16427 */ 16428 16429var TextTrackDisplay = (function (_Component) { 16430 _inherits(TextTrackDisplay, _Component); 16431 16432 function TextTrackDisplay(player, options, ready) { 16433 _classCallCheck(this, TextTrackDisplay); 16434 16435 _Component.call(this, player, options, ready); 16436 16437 player.on('loadstart', Fn.bind(this, this.toggleDisplay)); 16438 player.on('texttrackchange', Fn.bind(this, this.updateDisplay)); 16439 16440 // This used to be called during player init, but was causing an error 16441 // if a track should show by default and the display hadn't loaded yet. 16442 // Should probably be moved to an external track loader when we support 16443 // tracks that don't need a display. 16444 player.ready(Fn.bind(this, function () { 16445 if (player.tech_ && player.tech_['featuresNativeTextTracks']) { 16446 this.hide(); 16447 return; 16448 } 16449 16450 player.on('fullscreenchange', Fn.bind(this, this.updateDisplay)); 16451 16452 var tracks = this.options_.playerOptions['tracks'] || []; 16453 for (var i = 0; i < tracks.length; i++) { 16454 var track = tracks[i]; 16455 this.player_.addRemoteTextTrack(track); 16456 } 16457 })); 16458 } 16459 16460 /** 16461 * Add cue HTML to display 16462 * 16463 * @param {Number} color Hex number for color, like #f0e 16464 * @param {Number} opacity Value for opacity,0.0 - 1.0 16465 * @return {RGBAColor} In the form 'rgba(255, 0, 0, 0.3)' 16466 * @method constructColor 16467 */ 16468 16469 /** 16470 * Toggle display texttracks 16471 * 16472 * @method toggleDisplay 16473 */ 16474 16475 TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() { 16476 if (this.player_.tech_ && this.player_.tech_['featuresNativeTextTracks']) { 16477 this.hide(); 16478 } else { 16479 this.show(); 16480 } 16481 }; 16482 16483 /** 16484 * Create the component's DOM element 16485 * 16486 * @return {Element} 16487 * @method createEl 16488 */ 16489 16490 TextTrackDisplay.prototype.createEl = function createEl() { 16491 return _Component.prototype.createEl.call(this, 'div', { 16492 className: 'vjs-text-track-display' 16493 }); 16494 }; 16495 16496 /** 16497 * Clear display texttracks 16498 * 16499 * @method clearDisplay 16500 */ 16501 16502 TextTrackDisplay.prototype.clearDisplay = function clearDisplay() { 16503 if (typeof _globalWindow2['default']['WebVTT'] === 'function') { 16504 _globalWindow2['default']['WebVTT']['processCues'](_globalWindow2['default'], [], this.el_); 16505 } 16506 }; 16507 16508 /** 16509 * Update display texttracks 16510 * 16511 * @method updateDisplay 16512 */ 16513 16514 TextTrackDisplay.prototype.updateDisplay = function updateDisplay() { 16515 var tracks = this.player_.textTracks(); 16516 16517 this.clearDisplay(); 16518 16519 if (!tracks) { 16520 return; 16521 } 16522 16523 for (var i = 0; i < tracks.length; i++) { 16524 var track = tracks[i]; 16525 if (track['mode'] === 'showing') { 16526 this.updateForTrack(track); 16527 } 16528 } 16529 }; 16530 16531 /** 16532 * Add texttrack to texttrack list 16533 * 16534 * @param {TextTrackObject} track Texttrack object to be added to list 16535 * @method updateForTrack 16536 */ 16537 16538 TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) { 16539 if (typeof _globalWindow2['default']['WebVTT'] !== 'function' || !track['activeCues']) { 16540 return; 16541 } 16542 16543 var overrides = this.player_['textTrackSettings'].getValues(); 16544 16545 var cues = []; 16546 for (var _i = 0; _i < track['activeCues'].length; _i++) { 16547 cues.push(track['activeCues'][_i]); 16548 } 16549 16550 _globalWindow2['default']['WebVTT']['processCues'](_globalWindow2['default'], track['activeCues'], this.el_); 16551 16552 var i = cues.length; 16553 while (i--) { 16554 var cue = cues[i]; 16555 if (!cue) { 16556 continue; 16557 } 16558 16559 var cueDiv = cue.displayState; 16560 if (overrides.color) { 16561 cueDiv.firstChild.style.color = overrides.color; 16562 } 16563 if (overrides.textOpacity) { 16564 tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity)); 16565 } 16566 if (overrides.backgroundColor) { 16567 cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor; 16568 } 16569 if (overrides.backgroundOpacity) { 16570 tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity)); 16571 } 16572 if (overrides.windowColor) { 16573 if (overrides.windowOpacity) { 16574 tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity)); 16575 } else { 16576 cueDiv.style.backgroundColor = overrides.windowColor; 16577 } 16578 } 16579 if (overrides.edgeStyle) { 16580 if (overrides.edgeStyle === 'dropshadow') { 16581 cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray; 16582 } else if (overrides.edgeStyle === 'raised') { 16583 cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray; 16584 } else if (overrides.edgeStyle === 'depressed') { 16585 cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray; 16586 } else if (overrides.edgeStyle === 'uniform') { 16587 cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray; 16588 } 16589 } 16590 if (overrides.fontPercent && overrides.fontPercent !== 1) { 16591 var fontSize = _globalWindow2['default'].parseFloat(cueDiv.style.fontSize); 16592 cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px'; 16593 cueDiv.style.height = 'auto'; 16594 cueDiv.style.top = 'auto'; 16595 cueDiv.style.bottom = '2px'; 16596 } 16597 if (overrides.fontFamily && overrides.fontFamily !== 'default') { 16598 if (overrides.fontFamily === 'small-caps') { 16599 cueDiv.firstChild.style.fontVariant = 'small-caps'; 16600 } else { 16601 cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily]; 16602 } 16603 } 16604 } 16605 }; 16606 16607 return TextTrackDisplay; 16608})(_component2['default']); 16609 16610function constructColor(color, opacity) { 16611 return 'rgba(' + 16612 // color looks like "#f0e" 16613 parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')'; 16614} 16615 16616/** 16617 * Try to update style 16618 * Some style changes will throw an error, particularly in IE8. Those should be noops. 16619 * 16620 * @param {Element} el The element to be styles 16621 * @param {CSSProperty} style The CSS property to be styled 16622 * @param {CSSStyle} rule The actual style to be applied to the property 16623 * @method tryUpdateStyle 16624 */ 16625function tryUpdateStyle(el, style, rule) { 16626 // 16627 try { 16628 el.style[style] = rule; 16629 } catch (e) {} 16630} 16631 16632_component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay); 16633exports['default'] = TextTrackDisplay; 16634module.exports = exports['default']; 16635 16636},{"../component":66,"../menu/menu-button.js":103,"../menu/menu-item.js":104,"../menu/menu.js":105,"../utils/fn.js":133,"global/document":1,"global/window":2}],123:[function(_dereq_,module,exports){ 16637/** 16638 * @file text-track-enums.js 16639 * 16640 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode 16641 * 16642 * enum TextTrackMode { "disabled", "hidden", "showing" }; 16643 */ 16644'use strict'; 16645 16646exports.__esModule = true; 16647var TextTrackMode = { 16648 'disabled': 'disabled', 16649 'hidden': 'hidden', 16650 'showing': 'showing' 16651}; 16652 16653/* 16654 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackkind 16655 * 16656 * enum TextTrackKind { "subtitles", "captions", "descriptions", "chapters", "metadata" }; 16657 */ 16658var TextTrackKind = {
16659 'subtitles': 'subtitles', 16660 'captions': 'captions', 16661 'descriptions': 'descriptions', 16662 'chapters': 'chapters', 16663 'metadata': 'metadata' 16664}; 16665 16666exports.TextTrackMode = TextTrackMode; 16667exports.TextTrackKind = TextTrackKind; 16668 16669},{}],124:[function(_dereq_,module,exports){ 16670/** 16671 * Utilities for capturing text track state and re-creating tracks 16672 * based on a capture. 16673 * 16674 * @file text-track-list-converter.js 16675 */ 16676 16677/** 16678 * Examine a single text track and return a JSON-compatible javascript 16679 * object that represents the text track's state. 16680 * @param track {TextTrackObject} the text track to query 16681 * @return {Object} a serializable javascript representation of the 16682 * @private 16683 */ 16684'use strict'; 16685 16686exports.__esModule = true; 16687var trackToJson_ = function trackToJson_(track) { 16688 var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) { 16689 if (track[prop]) { 16690 acc[prop] = track[prop]; 16691 } 16692 16693 return acc; 16694 }, { 16695 cues: track.cues && Array.prototype.map.call(track.cues, function (cue) { 16696 return { 16697 startTime: cue.startTime, 16698 endTime: cue.endTime, 16699 text: cue.text, 16700 id: cue.id 16701 }; 16702 }) 16703 }); 16704 16705 return ret; 16706}; 16707 16708/** 16709 * Examine a tech and return a JSON-compatible javascript array that 16710 * represents the state of all text tracks currently configured. The 16711 * return array is compatible with `jsonToTextTracks`. 16712 * @param tech {tech} the tech object to query 16713 * @return {Array} a serializable javascript representation of the 16714 * @function textTracksToJson 16715 */ 16716var textTracksToJson = function textTracksToJson(tech) { 16717 16718 var trackEls = tech.$$('track'); 16719 16720 var trackObjs = Array.prototype.map.call(trackEls, function (t) { 16721 return t.track; 16722 }); 16723 var tracks = Array.prototype.map.call(trackEls, function (trackEl) { 16724 var json = trackToJson_(trackEl.track); 16725 if (trackEl.src) { 16726 json.src = trackEl.src; 16727 } 16728 return json; 16729 }); 16730 16731 return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) { 16732 return trackObjs.indexOf(track) === -1; 16733 }).map(trackToJson_)); 16734}; 16735 16736/** 16737 * Creates a set of remote text tracks on a tech based on an array of 16738 * javascript text track representations. 16739 * @param json {Array} an array of text track representation objects, 16740 * like those that would be produced by `textTracksToJson` 16741 * @param tech {tech} the tech to create text tracks on 16742 * @function jsonToTextTracks 16743 */ 16744var jsonToTextTracks = function jsonToTextTracks(json, tech) { 16745 json.forEach(function (track) { 16746 var addedTrack = tech.addRemoteTextTrack(track).track; 16747 if (!track.src && track.cues) { 16748 track.cues.forEach(function (cue) { 16749 return addedTrack.addCue(cue); 16750 }); 16751 } 16752 }); 16753 16754 return tech.textTracks(); 16755}; 16756 16757exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ }; 16758module.exports = exports['default']; 16759 16760},{}],125:[function(_dereq_,module,exports){ 16761/** 16762 * @file text-track-list.js 16763 */ 16764'use strict'; 16765 16766exports.__esModule = true; 16767 16768function _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; } } 16769 16770function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16771 16772var _eventTarget = _dereq_('../event-target'); 16773 16774var _eventTarget2 = _interopRequireDefault(_eventTarget); 16775 16776var _utilsFnJs = _dereq_('../utils/fn.js'); 16777 16778var Fn = _interopRequireWildcard(_utilsFnJs); 16779 16780var _utilsBrowserJs = _dereq_('../utils/browser.js'); 16781 16782var browser = _interopRequireWildcard(_utilsBrowserJs); 16783 16784var _globalDocument = _dereq_('global/document'); 16785 16786var _globalDocument2 = _interopRequireDefault(_globalDocument); 16787 16788/* 16789 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist 16790 * 16791 * interface TextTrackList : EventTarget { 16792 * readonly attribute unsigned long length; 16793 * getter TextTrack (unsigned long index); 16794 * TextTrack? getTrackById(DOMString id); 16795 * 16796 * attribute EventHandler onchange; 16797 * attribute EventHandler onaddtrack; 16798 * attribute EventHandler onremovetrack; 16799 * }; 16800 */ 16801var TextTrackList = function TextTrackList(tracks) { 16802 var list = this; 16803 16804 if (browser.IS_IE8) { 16805 list = _globalDocument2['default'].createElement('custom'); 16806 16807 for (var prop in TextTrackList.prototype) { 16808 if (prop !== 'constructor') { 16809 list[prop] = TextTrackList.prototype[prop]; 16810 } 16811 } 16812 } 16813 16814 tracks = tracks || []; 16815 list.tracks_ = []; 16816 16817 Object.defineProperty(list, 'length', { 16818 get: function get() { 16819 return this.tracks_.length; 16820 } 16821 }); 16822 16823 for (var i = 0; i < tracks.length; i++) { 16824 list.addTrack_(tracks[i]); 16825 } 16826 16827 if (browser.IS_IE8) { 16828 return list; 16829 } 16830}; 16831 16832TextTrackList.prototype = Object.create(_eventTarget2['default'].prototype); 16833TextTrackList.prototype.constructor = TextTrackList; 16834 16835/* 16836 * change - One or more tracks in the track list have been enabled or disabled. 16837 * addtrack - A track has been added to the track list. 16838 * removetrack - A track has been removed from the track list. 16839 */ 16840TextTrackList.prototype.allowedEvents_ = { 16841 'change': 'change', 16842 'addtrack': 'addtrack', 16843 'removetrack': 'removetrack' 16844}; 16845 16846// emulate attribute EventHandler support to allow for feature detection 16847for (var _event in TextTrackList.prototype.allowedEvents_) { 16848 TextTrackList.prototype['on' + _event] = null; 16849} 16850 16851/** 16852 * Add TextTrack from TextTrackList 16853 * 16854 * @param {TextTrack} track 16855 * @method addTrack_ 16856 * @private 16857 */ 16858TextTrackList.prototype.addTrack_ = function (track) { 16859 var index = this.tracks_.length; 16860 if (!('' + index in this)) { 16861 Object.defineProperty(this, index, { 16862 get: function get() { 16863 return this.tracks_[index]; 16864 } 16865 }); 16866 } 16867 16868 track.addEventListener('modechange', Fn.bind(this, function () { 16869 this.trigger('change'); 16870 })); 16871 this.tracks_.push(track); 16872 16873 this.trigger({ 16874 type: 'addtrack', 16875 track: track 16876 }); 16877}; 16878 16879/** 16880 * Remove TextTrack from TextTrackList 16881 * NOTE: Be mindful of what is passed in as it may be a HTMLTrackElement 16882 * 16883 * @param {TextTrack} rtrack 16884 * @method removeTrack_ 16885 * @private 16886 */ 16887TextTrackList.prototype.removeTrack_ = function (rtrack) { 16888 var track = undefined; 16889 16890 for (var i = 0, l = this.length; i < l; i++) { 16891 if (this[i] === rtrack) { 16892 track = this[i]; 16893 if (track.off) { 16894 track.off(); 16895 } 16896 16897 this.tracks_.splice(i, 1); 16898 16899 break; 16900 } 16901 } 16902 16903 if (!track) { 16904 return; 16905 } 16906 16907 this.trigger({ 16908 type: 'removetrack', 16909 track: track 16910 }); 16911}; 16912 16913TextTrackList.prototype.getTrackById = function (id) { 16914 var result = null; 16915 16916 for (var i = 0, l = this.length; i < l; i++) { 16917 var track = this[i]; 16918 if (track.id === id) { 16919 result = track; 16920 break; 16921 } 16922 } 16923 16924 return result; 16925}; 16926 16927exports['default'] = TextTrackList; 16928module.exports = exports['default']; 16929 16930},{"../event-target":98,"../utils/browser.js":128,"../utils/fn.js":133,"global/document":1}],126:[function(_dereq_,module,exports){ 16931/** 16932 * @file text-track-settings.js 16933 */ 16934'use strict'; 16935 16936exports.__esModule = true; 16937 16938function _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; } } 16939 16940function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16941 16942function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 16943 16944function _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
16944onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 16945 16946var _component = _dereq_('../component'); 16947 16948var _component2 = _interopRequireDefault(_component); 16949 16950var _utilsEventsJs = _dereq_('../utils/events.js'); 16951 16952var Events = _interopRequireWildcard(_utilsEventsJs); 16953 16954var _utilsFnJs = _dereq_('../utils/fn.js'); 16955 16956var Fn = _interopRequireWildcard(_utilsFnJs); 16957 16958var _utilsLogJs = _dereq_('../utils/log.js'); 16959 16960var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 16961 16962var _safeJsonParseTuple = _dereq_('safe-json-parse/tuple'); 16963 16964var _safeJsonParseTuple2 = _interopRequireDefault(_safeJsonParseTuple); 16965 16966var _globalWindow = _dereq_('global/window'); 16967 16968var _globalWindow2 = _interopRequireDefault(_globalWindow); 16969 16970/** 16971 * Manipulate settings of texttracks 16972 * 16973 * @param {Object} player Main Player 16974 * @param {Object=} options Object of option names and values 16975 * @extends Component 16976 * @class TextTrackSettings 16977 */ 16978 16979var TextTrackSettings = (function (_Component) { 16980 _inherits(TextTrackSettings, _Component); 16981 16982 function TextTrackSettings(player, options) { 16983 _classCallCheck(this, TextTrackSettings); 16984 16985 _Component.call(this, player, options); 16986 this.hide(); 16987 16988 // Grab `persistTextTrackSettings` from the player options if not passed in child options 16989 if (options.persistTextTrackSettings === undefined) { 16990 this.options_.persistTextTrackSettings = this.options_.playerOptions.persistTextTrackSettings; 16991 } 16992 16993 Events.on(this.$('.vjs-done-button'), 'click', Fn.bind(this, function () { 16994 this.saveSettings(); 16995 this.hide(); 16996 })); 16997 16998 Events.on(this.$('.vjs-default-button'), 'click', Fn.bind(this, function () { 16999 this.$('.vjs-fg-color > select').selectedIndex = 0; 17000 this.$('.vjs-bg-color > select').selectedIndex = 0; 17001 this.$('.window-color > select').selectedIndex = 0; 17002 this.$('.vjs-text-opacity > select').selectedIndex = 0; 17003 this.$('.vjs-bg-opacity > select').selectedIndex = 0; 17004 this.$('.vjs-window-opacity > select').selectedIndex = 0; 17005 this.$('.vjs-edge-style select').selectedIndex = 0; 17006 this.$('.vjs-font-family select').selectedIndex = 0; 17007 this.$('.vjs-font-percent select').selectedIndex = 2; 17008 this.updateDisplay(); 17009 })); 17010 17011 Events.on(this.$('.vjs-fg-color > select'), 'change', Fn.bind(this, this.updateDisplay)); 17012 Events.on(this.$('.vjs-bg-color > select'), 'change', Fn.bind(this, this.updateDisplay)); 17013 Events.on(this.$('.window-color > select'), 'change', Fn.bind(this, this.updateDisplay)); 17014 Events.on(this.$('.vjs-text-opacity > select'), 'change', Fn.bind(this, this.updateDisplay)); 17015 Events.on(this.$('.vjs-bg-opacity > select'), 'change', Fn.bind(this, this.updateDisplay)); 17016 Events.on(this.$('.vjs-window-opacity > select'), 'change', Fn.bind(this, this.updateDisplay)); 17017 Events.on(this.$('.vjs-font-percent select'), 'change', Fn.bind(this, this.updateDisplay)); 17018 Events.on(this.$('.vjs-edge-style select'), 'change', Fn.bind(this, this.updateDisplay)); 17019 Events.on(this.$('.vjs-font-family select'), 'change', Fn.bind(this, this.updateDisplay)); 17020 17021 if (this.options_.persistTextTrackSettings) { 17022 this.restoreSettings(); 17023 } 17024 } 17025 17026 /** 17027 * Create the component's DOM element 17028 * 17029 * @return {Element} 17030 * @method createEl 17031 */ 17032 17033 TextTrackSettings.prototype.createEl = function createEl() { 17034 return _Component.prototype.createEl.call(this, 'div', { 17035 className: 'vjs-caption-settings vjs-modal-overlay', 17036 innerHTML: captionOptionsMenuTemplate() 17037 }); 17038 }; 17039 17040 /** 17041 * Get texttrack settings 17042 * Settings are 17043 * .vjs-edge-style 17044 * .vjs-font-family 17045 * .vjs-fg-color 17046 * .vjs-text-opacity 17047 * .vjs-bg-color 17048 * .vjs-bg-opacity 17049 * .window-color 17050 * .vjs-window-opacity 17051 * 17052 * @return {Object} 17053 * @method getValues 17054 */ 17055 17056 TextTrackSettings.prototype.getValues = function getValues() { 17057 var textEdge = getSelectedOptionValue(this.$('.vjs-edge-style select')); 17058 var fontFamily = getSelectedOptionValue(this.$('.vjs-font-family select')); 17059 var fgColor = getSelectedOptionValue(this.$('.vjs-fg-color > select')); 17060 var textOpacity = getSelectedOptionValue(this.$('.vjs-text-opacity > select')); 17061 var bgColor = getSelectedOptionValue(this.$('.vjs-bg-color > select')); 17062 var bgOpacity = getSelectedOptionValue(this.$('.vjs-bg-opacity > select')); 17063 var windowColor = getSelectedOptionValue(this.$('.window-color > select')); 17064 var windowOpacity = getSelectedOptionValue(this.$('.vjs-window-opacity > select')); 17065 var fontPercent = _globalWindow2['default']['parseFloat'](getSelectedOptionValue(this.$('.vjs-font-percent > select'))); 17066 17067 var result = { 17068 'backgroundOpacity': bgOpacity, 17069 'textOpacity': textOpacity, 17070 'windowOpacity': windowOpacity, 17071 'edgeStyle': textEdge, 17072 'fontFamily': fontFamily, 17073 'color': fgColor, 17074 'backgroundColor': bgColor, 17075 'windowColor': windowColor, 17076 'fontPercent': fontPercent 17077 }; 17078 for (var _name in result) { 17079 if (result[_name] === '' || result[_name] === 'none' || _name === 'fontPercent' && result[_name] === 1.00) { 17080 delete result[_name]; 17081 } 17082 } 17083 return result; 17084 }; 17085 17086 /** 17087 * Set texttrack settings 17088 * Settings are 17089 * .vjs-edge-style 17090 * .vjs-font-family 17091 * .vjs-fg-color 17092 * .vjs-text-opacity 17093 * .vjs-bg-color 17094 * .vjs-bg-opacity 17095 * .window-color 17096 * .vjs-window-opacity 17097 * 17098 * @param {Object} values Object with texttrack setting values 17099 * @method setValues 17100 */ 17101 17102 TextTrackSettings.prototype.setValues = function setValues(values) { 17103 setSelectedOption(this.$('.vjs-edge-style select'), values.edgeStyle); 17104 setSelectedOption(this.$('.vjs-font-family select'), values.fontFamily); 17105 setSelectedOption(this.$('.vjs-fg-color > select'), values.color); 17106 setSelectedOption(this.$('.vjs-text-opacity > select'), values.textOpacity); 17107 setSelectedOption(this.$('.vjs-bg-color > select'), values.backgroundColor); 17108 setSelectedOption(this.$('.vjs-bg-opacity > select'), values.backgroundOpacity); 17109 setSelectedOption(this.$('.window-color > select'), values.windowColor); 17110 setSelectedOption(this.$('.vjs-window-opacity > select'), values.windowOpacity); 17111 17112 var fontPercent = values.fontPercent; 17113 17114 if (fontPercent) { 17115 fontPercent = fontPercent.toFixed(2); 17116 } 17117 17118 setSelectedOption(this.$('.vjs-font-percent > select'), fontPercent); 17119 }; 17120 17121 /** 17122 * Restore texttrack settings 17123 * 17124 * @method restoreSettings 17125 */ 17126 17127 TextTrackSettings.prototype.restoreSettings = function restoreSettings() { 17128 var _safeParseTuple = _safeJsonParseTuple2['default'](_globalWindow2['default'].localStorage.getItem('vjs-text-track-settings')); 17129 17130 var err = _safeParseTuple[0]; 17131 var values = _safeParseTuple[1]; 17132 17133 if (err) { 17134 _utilsLogJs2['default'].error(err); 17135 } 17136 17137 if (values) { 17138 this.setValues(values); 17139 } 17140 }; 17141 17142 /** 17143 * Save texttrack settings to local storage 17144 * 17145 * @method saveSettings 17146 */ 17147 17148 TextTrackSettings.prototype.saveSettings = function saveSettings() { 17149 if (!this.options_.persistTextTrackSettings) { 17150 return; 17151 } 17152 17153 var values = this.getValues(); 17154 try { 17155 if (Object.getOwnPropertyNames(values).length > 0) { 17156 _globalWindow2['default'].localStorage.setItem('vjs-text-track-settings', JSON.stringify(values)); 17157 } else { 17158 _globalWindow2['default'].localStorage.removeItem('vjs-text-track-settings'); 17159 } 17160 } catch (e) {} 17161 }; 17162 17163 /** 17164 * Update display of texttrack settings 17165 * 17166 * @method updateDisplay 17167 */ 17168 17169 TextTrackSettings.prototype.updateDisplay = function updateDisplay() { 17170 var ttDisplay = this.player_.getChild('textTrackDisplay'); 17171 if (ttDisplay) { 17172 ttDisplay.updateDisplay(); 17173 } 17174 }; 17175 17176 return TextTrackSettings; 17177})(_component2['default']); 17178 17179_component2['default'].registerComponent('TextTrackSettings', TextTrackSettings); 17180 17181function getSelectedOptionValue(target) { 17182 var selectedOption = undefined; 17183 // not all browsers support selectedOptions, so, fallback to options 17184 if (target.selectedOptions) { 17185 selectedOption = target.selectedOptions[0]; 17186 } else if (target.options) { 17187 selectedOption = target.options[target.options.selectedIndex]; 17188 } 17189 17190 return selectedOption.value; 17191} 17192 17193function setSelectedOption(target, value) { 17194 if (!value) { 17195 return; 17196 } 17197 17198 var i = undefined; 17199 for (i = 0; i < target.options.length; i++) { 17200 var option = target.options[i]; 17201 if (option.value === value) { 17202 break; 17203 } 17204 } 17205 17206 target.selectedIndex = i; 17207} 17208 17209function captionOptionsMenuTemplate() { 17210 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>
17210\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>'; 17211 17212 return template; 17213} 17214 17215exports['default'] = TextTrackSettings; 17216module.exports = exports['default']; 17217 17218},{"../component":66,"../utils/events.js":132,"../utils/fn.js":133,"../utils/log.js":136,"global/window":2,"safe-json-parse/tuple":53}],127:[function(_dereq_,module,exports){ 17219/** 17220 * @file text-track.js 17221 */ 17222'use strict'; 17223 17224exports.__esModule = true; 17225 17226function _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; } } 17227 17228function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 17229 17230var _textTrackCueList = _dereq_('./text-track-cue-list'); 17231 17232var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList); 17233 17234var _utilsFnJs = _dereq_('../utils/fn.js'); 17235 17236var Fn = _interopRequireWildcard(_utilsFnJs); 17237 17238var _utilsGuidJs = _dereq_('../utils/guid.js'); 17239 17240var Guid = _interopRequireWildcard(_utilsGuidJs); 17241 17242var _utilsBrowserJs = _dereq_('../utils/browser.js'); 17243 17244var browser = _interopRequireWildcard(_utilsBrowserJs); 17245 17246var _textTrackEnums = _dereq_('./text-track-enums'); 17247 17248var TextTrackEnum = _interopRequireWildcard(_textTrackEnums); 17249 17250var _utilsLogJs = _dereq_('../utils/log.js'); 17251 17252var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 17253 17254var _eventTarget = _dereq_('../event-target'); 17255 17256var _eventTarget2 = _interopRequireDefault(_eventTarget); 17257 17258var _globalDocument = _dereq_('global/document'); 17259 17260var _globalDocument2 = _interopRequireDefault(_globalDocument); 17261 17262var _globalWindow = _dereq_('global/window'); 17263 17264var _globalWindow2 = _interopRequireDefault(_globalWindow); 17265 17266var _utilsUrlJs = _dereq_('../utils/url.js'); 17267 17268var _xhr = _dereq_('xhr'); 17269
17270var _xhr2 = _interopRequireDefault(_xhr); 17271 17272/* 17273 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack 17274 * 17275 * interface TextTrack : EventTarget { 17276 * readonly attribute TextTrackKind kind; 17277 * readonly attribute DOMString label; 17278 * readonly attribute DOMString language; 17279 * 17280 * readonly attribute DOMString id; 17281 * readonly attribute DOMString inBandMetadataTrackDispatchType; 17282 * 17283 * attribute TextTrackMode mode; 17284 * 17285 * readonly attribute TextTrackCueList? cues; 17286 * readonly attribute TextTrackCueList? activeCues; 17287 * 17288 * void addCue(TextTrackCue cue); 17289 * void removeCue(TextTrackCue cue); 17290 * 17291 * attribute EventHandler oncuechange; 17292 * }; 17293 */ 17294var TextTrack = function TextTrack() { 17295 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 17296 17297 if (!options.tech) { 17298 throw new Error('A tech was not provided.'); 17299 } 17300 17301 var tt = this; 17302 if (browser.IS_IE8) { 17303 tt = _globalDocument2['default'].createElement('custom'); 17304 17305 for (var prop in TextTrack.prototype) { 17306 if (prop !== 'constructor') { 17307 tt[prop] = TextTrack.prototype[prop]; 17308 } 17309 } 17310 } 17311 17312 tt.tech_ = options.tech; 17313 17314 var mode = TextTrackEnum.TextTrackMode[options['mode']] || 'disabled'; 17315 var kind = TextTrackEnum.TextTrackKind[options['kind']] || 'subtitles'; 17316 var label = options['label'] || ''; 17317 var language = options['language'] || options['srclang'] || ''; 17318 var id = options['id'] || 'vjs_text_track_' + Guid.newGUID(); 17319 17320 if (kind === 'metadata' || kind === 'chapters') { 17321 mode = 'hidden'; 17322 } 17323 17324 tt.cues_ = []; 17325 tt.activeCues_ = []; 17326 17327 var cues = new _textTrackCueList2['default'](tt.cues_); 17328 var activeCues = new _textTrackCueList2['default'](tt.activeCues_); 17329 17330 var changed = false; 17331 var timeupdateHandler = Fn.bind(tt, function () { 17332 this['activeCues']; 17333 if (changed) { 17334 this['trigger']('cuechange'); 17335 changed = false; 17336 } 17337 }); 17338 if (mode !== 'disabled') { 17339 tt.tech_.on('timeupdate', timeupdateHandler); 17340 } 17341 17342 Object.defineProperty(tt, 'kind', { 17343 get: function get() { 17344 return kind; 17345 }, 17346 set: Function.prototype 17347 }); 17348 17349 Object.defineProperty(tt, 'label', { 17350 get: function get() { 17351 return label; 17352 }, 17353 set: Function.prototype 17354 }); 17355 17356 Object.defineProperty(tt, 'language', { 17357 get: function get() { 17358 return language; 17359 }, 17360 set: Function.prototype 17361 }); 17362 17363 Object.defineProperty(tt, 'id', { 17364 get: function get() { 17365 return id; 17366 }, 17367 set: Function.prototype 17368 }); 17369 17370 Object.defineProperty(tt, 'mode', { 17371 get: function get() { 17372 return mode; 17373 }, 17374 set: function set(newMode) { 17375 if (!TextTrackEnum.TextTrackMode[newMode]) { 17376 return; 17377 } 17378 mode = newMode; 17379 if (mode === 'showing') { 17380 this.tech_.on('timeupdate', timeupdateHandler); 17381 } 17382 this.trigger('modechange'); 17383 } 17384 }); 17385 17386 Object.defineProperty(tt, 'cues', { 17387 get: function get() { 17388 if (!this.loaded_) { 17389 return null; 17390 } 17391 17392 return cues; 17393 }, 17394 set: Function.prototype 17395 }); 17396 17397 Object.defineProperty(tt, 'activeCues', { 17398 get: function get() { 17399 if (!this.loaded_) { 17400 return null; 17401 } 17402 17403 if (this['cues'].length === 0) { 17404 return activeCues; // nothing to do 17405 } 17406 17407 var ct = this.tech_.currentTime(); 17408 var active = []; 17409 17410 for (var i = 0, l = this['cues'].length; i < l; i++) { 17411 var cue = this['cues'][i]; 17412 if (cue['startTime'] <= ct && cue['endTime'] >= ct) { 17413 active.push(cue); 17414 } else if (cue['startTime'] === cue['endTime'] && cue['startTime'] <= ct && cue['startTime'] + 0.5 >= ct) { 17415 active.push(cue); 17416 } 17417 } 17418 17419 changed = false; 17420 17421 if (active.length !== this.activeCues_.length) { 17422 changed = true; 17423 } else { 17424 for (var i = 0; i < active.length; i++) { 17425 if (indexOf.call(this.activeCues_, active[i]) === -1) { 17426 changed = true; 17427 } 17428 } 17429 } 17430 17431 this.activeCues_ = active; 17432 activeCues.setCues_(this.activeCues_); 17433 17434 return activeCues; 17435 }, 17436 set: Function.prototype 17437 }); 17438 17439 if (options.src) { 17440 tt.src = options.src; 17441 loadTrack(options.src, tt); 17442 } else { 17443 tt.loaded_ = true; 17444 } 17445 17446 if (browser.IS_IE8) { 17447 return tt; 17448 } 17449}; 17450 17451TextTrack.prototype = Object.create(_eventTarget2['default'].prototype); 17452TextTrack.prototype.constructor = TextTrack; 17453 17454/* 17455 * cuechange - One or more cues in the track have become active or stopped being active. 17456 */ 17457TextTrack.prototype.allowedEvents_ = { 17458 'cuechange': 'cuechange' 17459}; 17460 17461TextTrack.prototype.addCue = function (cue) { 17462 var tracks = this.tech_.textTracks(); 17463 17464 if (tracks) { 17465 for (var i = 0; i < tracks.length; i++) { 17466 if (tracks[i] !== this) { 17467 tracks[i].removeCue(cue); 17468 } 17469 } 17470 } 17471 17472 this.cues_.push(cue); 17473 this['cues'].setCues_(this.cues_); 17474}; 17475 17476TextTrack.prototype.removeCue = function (removeCue) { 17477 var removed = false;
17478 17479 for (var i = 0, l = this.cues_.length; i < l; i++) { 17480 var cue = this.cues_[i]; 17481 if (cue === removeCue) { 17482 this.cues_.splice(i, 1); 17483 removed = true; 17484 } 17485 } 17486 17487 if (removed) { 17488 this.cues.setCues_(this.cues_); 17489 } 17490}; 17491 17492/* 17493* Downloading stuff happens below this point 17494*/ 17495var parseCues = function parseCues(srcContent, track) { 17496 var parser = new _globalWindow2['default'].WebVTT.Parser(_globalWindow2['default'], _globalWindow2['default'].vttjs, _globalWindow2['default'].WebVTT.StringDecoder()); 17497 17498 parser.oncue = function (cue) { 17499 track.addCue(cue); 17500 }; 17501 17502 parser.onparsingerror = function (error) { 17503 _utilsLogJs2['default'].error(error); 17504 }; 17505 17506 parser.onflush = function () { 17507 track.trigger({ 17508 type: 'loadeddata', 17509 target: track 17510 }); 17511 }; 17512 17513 parser.parse(srcContent); 17514 parser.flush(); 17515}; 17516 17517var loadTrack = function loadTrack(src, track) { 17518 var opts = { 17519 uri: src 17520 }; 17521 17522 var crossOrigin = _utilsUrlJs.isCrossOrigin(src); 17523 if (crossOrigin) { 17524 opts.cors = crossOrigin; 17525 } 17526 17527 _xhr2['default'](opts, Fn.bind(this, function (err, response, responseBody) { 17528 if (err) { 17529 return _utilsLogJs2['default'].error(err, response); 17530 } 17531 17532 track.loaded_ = true; 17533 17534 // NOTE: this is only used for the alt/video.novtt.js build 17535 if (typeof _globalWindow2['default'].WebVTT !== 'function') { 17536 _globalWindow2['default'].setTimeout(function () { 17537 parseCues(responseBody, track); 17538 }, 100); 17539 } else { 17540 parseCues(responseBody, track); 17541 } 17542 })); 17543}; 17544 17545var indexOf = function indexOf(searchElement, fromIndex) { 17546 if (this == null) { 17547 throw new TypeError('"this" is null or not defined'); 17548 } 17549 17550 var O = Object(this); 17551 17552 var len = O.length >>> 0; 17553 17554 if (len === 0) { 17555 return -1; 17556 } 17557 17558 var n = +fromIndex || 0; 17559 17560 if (Math.abs(n) === Infinity) { 17561 n = 0; 17562 } 17563 17564 if (n >= len) { 17565 return -1; 17566 } 17567 17568 var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); 17569 17570 while (k < len) { 17571 if (k in O && O[k] === searchElement) { 17572 return k; 17573 } 17574 k++; 17575 } 17576 return -1; 17577}; 17578 17579exports['default'] = TextTrack; 17580module.exports = exports['default']; 17581 17582},{"../event-target":98,"../utils/browser.js":128,"../utils/fn.js":133,"../utils/guid.js":135,"../utils/log.js":136,"../utils/url.js":141,"./text-track-cue-list":121,"./text-track-enums":123,"global/document":1,"global/window":2,"xhr":55}],128:[function(_dereq_,module,exports){ 17583/** 17584 * @file browser.js 17585 */ 17586'use strict'; 17587 17588exports.__esModule = true; 17589 17590function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 17591 17592var _globalDocument = _dereq_('global/document'); 17593 17594var _globalDocument2 = _interopRequireDefault(_globalDocument); 17595 17596var _globalWindow = _dereq_('global/window'); 17597 17598var _globalWindow2 = _interopRequireDefault(_globalWindow); 17599 17600var USER_AGENT = _globalWindow2['default'].navigator.userAgent; 17601var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT); 17602var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null; 17603 17604/* 17605 * Device is an iPhone 17606 * 17607 * @type {Boolean} 17608 * @constant 17609 * @private 17610 */ 17611var IS_IPAD = /iPad/i.test(USER_AGENT); 17612 17613exports.IS_IPAD = IS_IPAD; 17614// The Facebook app's UIWebView identifies as both an iPhone and iPad, so 17615// to identify iPhones, we need to exclude iPads. 17616// http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/ 17617var IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD; 17618exports.IS_IPHONE = IS_IPHONE; 17619var IS_IPOD = /iPod/i.test(USER_AGENT); 17620exports.IS_IPOD = IS_IPOD; 17621var IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD; 17622 17623exports.IS_IOS = IS_IOS; 17624var IOS_VERSION = (function () { 17625 var match = USER_AGENT.match(/OS (\d+)_/i); 17626 if (match && match[1]) { 17627 return match[1]; 17628 } 17629})(); 17630 17631exports.IOS_VERSION = IOS_VERSION; 17632var IS_ANDROID = /Android/i.test(USER_AGENT); 17633exports.IS_ANDROID = IS_ANDROID; 17634var ANDROID_VERSION = (function () { 17635 // This matches Android Major.Minor.Patch versions 17636 // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned 17637 var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i), 17638 major, 17639 minor; 17640 17641 if (!match) { 17642 return null; 17643 } 17644 17645 major = match[1] && parseFloat(match[1]); 17646 minor = match[2] && parseFloat(match[2]); 17647 17648 if (major && minor) { 17649 return parseFloat(match[1] + '.' + match[2]); 17650 } else if (major) { 17651 return major; 17652 } else { 17653 return null; 17654 } 17655})(); 17656exports.ANDROID_VERSION = ANDROID_VERSION; 17657// Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser 17658var IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3; 17659exports.IS_OLD_ANDROID = IS_OLD_ANDROID; 17660var IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537; 17661 17662exports.IS_NATIVE_ANDROID = IS_NATIVE_ANDROID; 17663var IS_FIREFOX = /Firefox/i.test(USER_AGENT); 17664exports.IS_FIREFOX = IS_FIREFOX; 17665var IS_CHROME = /Chrome/i.test(USER_AGENT); 17666exports.IS_CHROME = IS_CHROME; 17667var IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT); 17668 17669exports.IS_IE8 = IS_IE8; 17670var TOUCH_ENABLED = !!('ontouchstart' in _globalWindow2['default'] || _globalWindow2['default'].DocumentTouch && _globalDocument2['default'] instanceof _globalWindow2['default'].DocumentTouch); 17671exports.TOUCH_ENABLED = TOUCH_ENABLED; 17672var BACKGROUND_SIZE_SUPPORTED = ('backgroundSize' in _globalDocument2['default'].createElement('video').style); 17673exports.BACKGROUND_SIZE_SUPPORTED = BACKGROUND_SIZE_SUPPORTED; 17674 17675},{"global/document":1,"global/window":2}],129:[function(_dereq_,module,exports){ 17676/** 17677 * @file buffer.js 17678 */ 17679'use strict'; 17680 17681exports.__esModule = true; 17682exports.bufferedPercent = bufferedPercent; 17683 17684var _timeRangesJs = _dereq_('./time-ranges.js'); 17685 17686/** 17687 * Compute how much your video has been buffered 17688 * 17689 * @param {Object} Buffered object 17690 * @param {Number} Total duration 17691 * @return {Number} Percent buffered of the total duration 17692 * @private 17693 * @function bufferedPercent 17694 */ 17695 17696function bufferedPercent(buffered, duration) { 17697 var bufferedDuration = 0, 17698 start, 17699 end; 17700 17701 if (!duration) { 17702 return 0; 17703 } 17704 17705 if (!buffered || !buffered.length) { 17706 buffered = _timeRangesJs.createTimeRange(0, 0); 17707 } 17708 17709 for (var i = 0; i < buffered.length; i++) { 17710 start = buffered.start(i); 17711 end = buffered.end(i); 17712 17713 // buffered end can be bigger than duration by a very small fraction 17714 if (end > duration) { 17715 end = duration; 17716 } 17717 17718 bufferedDuration += end - start; 17719 } 17720 17721 return bufferedDuration / duration; 17722} 17723 17724},{"./time-ranges.js":139}],130:[function(_dereq_,module,exports){ 17725'use strict'; 17726 17727exports.__esModule = true; 17728 17729function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 17730 17731var _logJs = _dereq_('./log.js'); 17732 17733var _logJs2 = _interopRequireDefault(_logJs); 17734 17735/** 17736 * Object containing the default behaviors for available handler methods. 17737 * 17738 * @private 17739 * @type {Object} 17740 */ 17741var defaultBehaviors = { 17742 get: function get(obj, key) { 17743 return obj[key]; 17744 }, 17745 set: function set(obj, key, value) { 17746 obj[key] = value; 17747 return true; 17748 } 17749}; 17750 17751/** 17752 * Expose private objects publicly using a Proxy to log deprecation warnings. 17753 * 17754 * Browsers that do not support Proxy objects will simply return the `target`
17755 * object, so it can be directly exposed. 17756 * 17757 * @param {Object} target The target object. 17758 * @param {Object} messages Messages to display from a Proxy. Only operations 17759 * with an associated message will be proxied. 17760 * @param {String} [messages.get] 17761 * @param {String} [messages.set] 17762 * @return {Object} A Proxy if supported or the `target` argument. 17763 */ 17764 17765exports['default'] = function (target) { 17766 var messages = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 17767 17768 if (typeof Proxy === 'function') { 17769 var _ret = (function () { 17770 var handler = {}; 17771 17772 // Build a handler object based on those keys that have both messages 17773 // and default behaviors. 17774 Object.keys(messages).forEach(function (key) { 17775 if (defaultBehaviors.hasOwnProperty(key)) { 17776 handler[key] = function () { 17777 _logJs2['default'].warn(messages[key]); 17778 return defaultBehaviors[key].apply(this, arguments); 17779 }; 17780 } 17781 }); 17782 17783 return { 17784 v: new Proxy(target, handler) 17785 }; 17786 })(); 17787 17788 if (typeof _ret === 'object') return _ret.v; 17789 } 17790 return target; 17791}; 17792 17793module.exports = exports['default']; 17794 17795},{"./log.js":136}],131:[function(_dereq_,module,exports){ 17796/** 17797 * @file dom.js 17798 */ 17799'use strict'; 17800 17801exports.__esModule = true; 17802exports.getEl = getEl; 17803exports.createEl = createEl; 17804exports.textContent = textContent; 17805exports.insertElFirst = insertElFirst; 17806exports.getElData = getElData; 17807exports.hasElData = hasElData; 17808exports.removeElData = removeElData; 17809exports.hasElClass = hasElClass; 17810exports.addElClass = addElClass; 17811exports.removeElClass = removeElClass; 17812exports.toggleElClass = toggleElClass; 17813exports.setElAttributes = setElAttributes; 17814exports.getElAttributes = getElAttributes; 17815exports.blockTextSelection = blockTextSelection; 17816exports.unblockTextSelection = unblockTextSelection; 17817exports.findElPosition = findElPosition; 17818exports.getPointerPosition = getPointerPosition; 17819exports.isEl = isEl; 17820exports.isTextNode = isTextNode; 17821exports.emptyEl = emptyEl; 17822exports.normalizeContent = normalizeContent; 17823exports.appendContent = appendContent; 17824exports.insertContent = insertContent; 17825 17826var _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 ', '.']); 17827 17828function _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; } } 17829 17830function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 17831 17832function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } 17833 17834var _globalDocument = _dereq_('global/document'); 17835 17836var _globalDocument2 = _interopRequireDefault(_globalDocument); 17837 17838var _globalWindow = _dereq_('global/window'); 17839 17840var _globalWindow2 = _interopRequireDefault(_globalWindow); 17841 17842var _guidJs = _dereq_('./guid.js'); 17843 17844var Guid = _interopRequireWildcard(_guidJs); 17845 17846var _logJs = _dereq_('./log.js'); 17847 17848var _logJs2 = _interopRequireDefault(_logJs); 17849 17850var _tsml = _dereq_('tsml'); 17851 17852var _tsml2 = _interopRequireDefault(_tsml); 17853 17854/** 17855 * Detect if a value is a string with any non-whitespace characters. 17856 * 17857 * @param {String} str 17858 * @return {Boolean} 17859 */ 17860function isNonBlankString(str) { 17861 return typeof str === 'string' && /\S/.test(str); 17862} 17863 17864/** 17865 * Throws an error if the passed string has whitespace. This is used by 17866 * class methods to be relatively consistent with the classList API. 17867 * 17868 * @param {String} str 17869 * @return {Boolean} 17870 */ 17871function throwIfWhitespace(str) { 17872 if (/\s/.test(str)) { 17873 throw new Error('class has illegal whitespace characters'); 17874 } 17875} 17876 17877/** 17878 * Produce a regular expression for matching a class name. 17879 * 17880 * @param {String} className 17881 * @return {RegExp} 17882 */ 17883function classRegExp(className) { 17884 return new RegExp('(^|\\s)' + className + '($|\\s)'); 17885} 17886 17887/** 17888 * Creates functions to query the DOM using a given method. 17889 * 17890 * @function createQuerier 17891 * @private 17892 * @param {String} method 17893 * @return {Function} 17894 */ 17895function createQuerier(method) { 17896 return function (selector, context) { 17897 if (!isNonBlankString(selector)) { 17898 return _globalDocument2['default'][method](null); 17899 } 17900 if (isNonBlankString(context)) { 17901 context = _globalDocument2['default'].querySelector(context); 17902 } 17903 return (isEl(context) ? context : _globalDocument2['default'])[method](selector); 17904 }; 17905} 17906 17907/** 17908 * Shorthand for document.getElementById() 17909 * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs. 17910 * 17911 * @param {String} id Element ID 17912 * @return {Element} Element with supplied ID 17913 * @function getEl 17914 */ 17915 17916function getEl(id) { 17917 if (id.indexOf('#') === 0) { 17918 id = id.slice(1); 17919 } 17920 17921 return _globalDocument2['default'].getElementById(id); 17922} 17923 17924/** 17925 * Creates an element and applies properties. 17926 * 17927 * @param {String} [tagName='div'] Name of tag to be created. 17928 * @param {Object} [properties={}] Element properties to be applied. 17929 * @param {Object} [attributes={}] Element attributes to be applied. 17930 * @return {Element} 17931 * @function createEl 17932 */ 17933 17934function createEl() { 17935 var tagName = arguments.length <= 0 || arguments[0] === undefined ? 'div' : arguments[0]; 17936 var properties = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 17937 var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; 17938 17939 var el = _globalDocument2['default'].createElement(tagName); 17940
vendor: 4,103 bytes, lines 17941-18125
17941 Object.getOwnPropertyNames(properties).forEach(function (propName) { 17942 var val = properties[propName]; 17943 17944 // See #2176 17945 // We originally were accepting both properties and attributes in the 17946 // same object, but that doesn't work so well. 17947 if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') { 17948 _logJs2['default'].warn(_tsml2['default'](_templateObject, propName, val)); 17949 el.setAttribute(propName, val); 17950 } else { 17951 el[propName] = val; 17952 } 17953 }); 17954 17955 Object.getOwnPropertyNames(attributes).forEach(function (attrName) { 17956 var val = attributes[attrName]; 17957 el.setAttribute(attrName, attributes[attrName]); 17958 }); 17959 17960 return el; 17961} 17962 17963/** 17964 * Injects text into an element, replacing any existing contents entirely. 17965 * 17966 * @param {Element} el 17967 * @param {String} text 17968 * @return {Element} 17969 * @function textContent 17970 */ 17971 17972function textContent(el, text) { 17973 if (typeof el.textContent === 'undefined') { 17974 el.innerText = text; 17975 } else { 17976 el.textContent = text; 17977 } 17978} 17979 17980/** 17981 * Insert an element as the first child node of another 17982 * 17983 * @param {Element} child Element to insert 17984 * @param {Element} parent Element to insert child into 17985 * @private 17986 * @function insertElFirst 17987 */ 17988 17989function insertElFirst(child, parent) { 17990 if (parent.firstChild) { 17991 parent.insertBefore(child, parent.firstChild); 17992 } else { 17993 parent.appendChild(child); 17994 } 17995} 17996 17997/** 17998 * Element Data Store. Allows for binding data to an element without putting it directly on the element. 17999 * Ex. Event listeners are stored here. 18000 * (also from jsninja.com, slightly modified and updated for closure compiler) 18001 * 18002 * @type {Object} 18003 * @private 18004 */ 18005var elData = {}; 18006 18007/* 18008 * Unique attribute name to store an element's guid in 18009 * 18010 * @type {String} 18011 * @constant 18012 * @private 18013 */ 18014var elIdAttr = 'vdata' + new Date().getTime(); 18015 18016/** 18017 * Returns the cache object where data for an element is stored 18018 * 18019 * @param {Element} el Element to store data for. 18020 * @return {Object} 18021 * @function getElData 18022 */ 18023 18024function getElData(el) { 18025 var id = el[elIdAttr]; 18026 18027 if (!id) { 18028 id = el[elIdAttr] = Guid.newGUID(); 18029 } 18030 18031 if (!elData[id]) { 18032 elData[id] = {}; 18033 } 18034 18035 return elData[id]; 18036} 18037 18038/** 18039 * Returns whether or not an element has cached data 18040 * 18041 * @param {Element} el A dom element 18042 * @return {Boolean} 18043 * @private 18044 * @function hasElData 18045 */ 18046 18047function hasElData(el) { 18048 var id = el[elIdAttr]; 18049 18050 if (!id) { 18051 return false; 18052 } 18053 18054 return !!Object.getOwnPropertyNames(elData[id]).length; 18055} 18056 18057/** 18058 * Delete data for the element from the cache and the guid attr from getElementById 18059 * 18060 * @param {Element} el Remove data for an element 18061 * @private 18062 * @function removeElData 18063 */ 18064 18065function removeElData(el) { 18066 var id = el[elIdAttr]; 18067 18068 if (!id) { 18069 return; 18070 } 18071 18072 // Remove all stored data 18073 delete elData[id]; 18074 18075 // Remove the elIdAttr property from the DOM node 18076 try { 18077 delete el[elIdAttr]; 18078 } catch (e) { 18079 if (el.removeAttribute) { 18080 el.removeAttribute(elIdAttr); 18081 } else { 18082 // IE doesn't appear to support removeAttribute on the document element 18083 el[elIdAttr] = null; 18084 } 18085 } 18086} 18087 18088/** 18089 * Check if an element has a CSS class 18090 * 18091 * @function hasElClass 18092 * @param {Element} element Element to check 18093 * @param {String} classToCheck Classname to check 18094 */ 18095 18096function hasElClass(element, classToCheck) { 18097 if (element.classList) { 18098 return element.classList.contains(classToCheck); 18099 } else { 18100 throwIfWhitespace(classToCheck); 18101 return classRegExp(classToCheck).test(element.className); 18102 } 18103} 18104 18105/** 18106 * Add a CSS class name to an element 18107 * 18108 * @function addElClass 18109 * @param {Element} element Element to add class name to 18110 * @param {String} classToAdd Classname to add 18111 */ 18112 18113function addElClass(element, classToAdd) { 18114 if (element.classList) { 18115 element.classList.add(classToAdd); 18116 18117 // Don't need to `throwIfWhitespace` here because `hasElClass` will do it 18118 // in the case of classList not being supported. 18119 } else if (!hasElClass(element, classToAdd)) { 18120 element.className = (element.className + ' ' + classToAdd).trim(); 18121 } 18122 18123 return element; 18124} 18125
18126/** 18127 * Remove a CSS class name from an element 18128 * 18129 * @function removeElClass 18130 * @param {Element} element Element to remove from class name 18131 * @param {String} classToRemove Classname to remove 18132 */ 18133 18134function removeElClass(element, classToRemove) { 18135 if (element.classList) { 18136 element.classList.remove(classToRemove); 18137 } else { 18138 throwIfWhitespace(classToRemove); 18139 element.className = element.className.split(/\s+/).filter(function (c) { 18140 return c !== classToRemove; 18141 }).join(' '); 18142 } 18143 18144 return element; 18145} 18146 18147/** 18148 * Adds or removes a CSS class name on an element depending on an optional 18149 * condition or the presence/absence of the class name. 18150 * 18151 * @function toggleElClass 18152 * @param {Element} element 18153 * @param {String} classToToggle 18154 * @param {Boolean|Function} [predicate] 18155 * Can be a function that returns a Boolean. If `true`, the class 18156 * will be added; if `false`, the class will be removed. If not 18157 * given, the class will be added if not present and vice versa. 18158 */ 18159 18160function toggleElClass(element, classToToggle, predicate) { 18161 18162 // This CANNOT use `classList` internally because IE does not support the 18163 // second parameter to the `classList.toggle()` method! Which is fine because 18164 // `classList` will be used by the add/remove functions. 18165 var has = hasElClass(element, classToToggle); 18166 18167 if (typeof predicate === 'function') { 18168 predicate = predicate(element, classToToggle); 18169 } 18170 18171 if (typeof predicate !== 'boolean') { 18172 predicate = !has; 18173 } 18174 18175 // If the necessary class operation matches the current state of the 18176 // element, no action is required. 18177 if (predicate === has) { 18178 return; 18179 } 18180 18181 if (predicate) { 18182 addElClass(element, classToToggle); 18183 } else { 18184 removeElClass(element, classToToggle); 18185 } 18186 18187 return element; 18188} 18189 18190/** 18191 * Apply attributes to an HTML element. 18192 * 18193 * @param {Element} el Target element. 18194 * @param {Object=} attributes Element attributes to be applied. 18195 * @private 18196 * @function setElAttributes 18197 */ 18198 18199function setElAttributes(el, attributes) { 18200 Object.getOwnPropertyNames(attributes).forEach(function (attrName) { 18201 var attrValue = attributes[attrName]; 18202 18203 if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) { 18204 el.removeAttribute(attrName); 18205 } else { 18206 el.setAttribute(attrName, attrValue === true ? '' : attrValue); 18207 } 18208 }); 18209} 18210 18211/** 18212 * Get an element's attribute values, as defined on the HTML tag 18213 * Attributes are not the same as properties. They're defined on the tag 18214 * or with setAttribute (which shouldn't be used with HTML) 18215 * This will return true or false for boolean attributes. 18216 * 18217 * @param {Element} tag Element from which to get tag attributes 18218 * @return {Object} 18219 * @private 18220 * @function getElAttributes 18221 */ 18222 18223function getElAttributes(tag) { 18224 var obj, knownBooleans, attrs, attrName, attrVal; 18225 18226 obj = {}; 18227 18228 // known boolean attributes 18229 // we can check for matching boolean properties, but older browsers 18230 // won't know about HTML5 boolean attributes that we still read from 18231 knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ','; 18232 18233 if (tag && tag.attributes && tag.attributes.length > 0) { 18234 attrs = tag.attributes; 18235 18236 for (var i = attrs.length - 1; i >= 0; i--) { 18237 attrName = attrs[i].name; 18238 attrVal = attrs[i].value; 18239 18240 // check for known booleans 18241 // the matching element property will return a value for typeof 18242 if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) { 18243 // the value of an included boolean attribute is typically an empty 18244 // string ('') which would equal false if we just check for a false value. 18245 // we also don't want support bad code like autoplay='false' 18246 attrVal = attrVal !== null ? true : false; 18247 } 18248 18249 obj[attrName] = attrVal; 18250 } 18251 } 18252 18253 return obj; 18254} 18255 18256/** 18257 * Attempt to block the ability to select text while dragging controls 18258 * 18259 * @return {Boolean} 18260 * @function blockTextSelection 18261 */ 18262 18263function blockTextSelection() { 18264 _globalDocument2['default'].body.focus(); 18265 _globalDocument2['default'].onselectstart = function () { 18266 return false;
18267 }; 18268} 18269 18270/** 18271 * Turn off text selection blocking 18272 * 18273 * @return {Boolean} 18274 * @function unblockTextSelection 18275 */ 18276 18277function unblockTextSelection() { 18278 _globalDocument2['default'].onselectstart = function () { 18279 return true; 18280 }; 18281} 18282 18283/** 18284 * Offset Left 18285 * getBoundingClientRect technique from 18286 * John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/ 18287 * 18288 * @function findElPosition 18289 * @param {Element} el Element from which to get offset 18290 * @return {Object} 18291 */ 18292 18293function findElPosition(el) { 18294 var box = undefined; 18295 18296 if (el.getBoundingClientRect && el.parentNode) { 18297 box = el.getBoundingClientRect(); 18298 } 18299 18300 if (!box) { 18301 return { 18302 left: 0, 18303 top: 0 18304 }; 18305 } 18306 18307 var docEl = _globalDocument2['default'].documentElement; 18308 var body = _globalDocument2['default'].body; 18309 18310 var clientLeft = docEl.clientLeft || body.clientLeft || 0; 18311 var scrollLeft = _globalWindow2['default'].pageXOffset || body.scrollLeft; 18312 var left = box.left + scrollLeft - clientLeft; 18313 18314 var clientTop = docEl.clientTop || body.clientTop || 0; 18315 var scrollTop = _globalWindow2['default'].pageYOffset || body.scrollTop; 18316 var top = box.top + scrollTop - clientTop; 18317 18318 // Android sometimes returns slightly off decimal values, so need to round 18319 return { 18320 left: Math.round(left), 18321 top: Math.round(top) 18322 }; 18323} 18324 18325/** 18326 * Get pointer position in element 18327 * Returns an object with x and y coordinates. 18328 * The base on the coordinates are the bottom left of the element. 18329 * 18330 * @function getPointerPosition 18331 * @param {Element} el Element on which to get the pointer position on 18332 * @param {Event} event Event object 18333 * @return {Object} This object will have x and y coordinates corresponding to the mouse position 18334 */ 18335 18336function getPointerPosition(el, event) { 18337 var position = {}; 18338 var box = findElPosition(el); 18339 var boxW = el.offsetWidth; 18340 var boxH = el.offsetHeight; 18341 18342 var boxY = box.top; 18343 var boxX = box.left; 18344 var pageY = event.pageY; 18345 var pageX = event.pageX; 18346 18347 if (event.changedTouches) { 18348 pageX = event.changedTouches[0].pageX; 18349 pageY = event.changedTouches[0].pageY; 18350 } 18351 18352 position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH)); 18353 position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW)); 18354 18355 return position; 18356} 18357 18358/** 18359 * Determines, via duck typing, whether or not a value is a DOM element. 18360 * 18361 * @function isEl 18362 * @param {Mixed} value 18363 * @return {Boolean} 18364 */ 18365 18366function isEl(value) { 18367 return !!value && typeof value === 'object' && value.nodeType === 1; 18368} 18369 18370/** 18371 * Determines, via duck typing, whether or not a value is a text node. 18372 * 18373 * @param {Mixed} value 18374 * @return {Boolean} 18375 */ 18376 18377function isTextNode(value) { 18378 return !!value && typeof value === 'object' && value.nodeType === 3; 18379} 18380 18381/** 18382 * Empties the contents of an element. 18383 * 18384 * @function emptyEl 18385 * @param {Element} el 18386 * @return {Element} 18387 */ 18388 18389function emptyEl(el) { 18390 while (el.firstChild) { 18391 el.removeChild(el.firstChild); 18392 } 18393 return el; 18394} 18395 18396/** 18397 * Normalizes content for eventual insertion into the DOM. 18398 * 18399 * This allows a wide range of content definition methods, but protects 18400 * from falling into the trap of simply writing to `innerHTML`, which is 18401 * an XSS concern. 18402 * 18403 * The content for an element can be passed in multiple types and 18404 * combinations, whose behavior is as follows: 18405 * 18406 * - String 18407 * Normalized into a text node. 18408 * 18409 * - Element, TextNode 18410 * Passed through. 18411 * 18412 * - Array 18413 * A one-dimensional array of strings, elements, nodes, or functions (which 18414 * return single strings, elements, or nodes). 18415 * 18416 * - Function 18417 * If the sole argument, is expected to produce a string, element, 18418 * node, or array. 18419 * 18420 * @function normalizeContent 18421 * @param {String|Element|TextNode|Array|Function} content 18422 * @return {Array} 18423 */ 18424 18425function normalizeContent(content) { 18426 18427 // First, invoke content if it is a function. If it produces an array, 18428 // that needs to happen before normalization. 18429 if (typeof content === 'function') { 18430 content = content(); 18431 } 18432 18433 // Next up, normalize to an array, so one or many items can be normalized, 18434 // filtered, and returned.
18435 return (Array.isArray(content) ? content : [content]).map(function (value) { 18436 18437 // First, invoke value if it is a function to produce a new value, 18438 // which will be subsequently normalized to a Node of some kind. 18439 if (typeof value === 'function') { 18440 value = value(); 18441 } 18442 18443 if (isEl(value) || isTextNode(value)) { 18444 return value; 18445 } 18446 18447 if (typeof value === 'string' && /\S/.test(value)) { 18448 return _globalDocument2['default'].createTextNode(value); 18449 } 18450 }).filter(function (value) { 18451 return value; 18452 }); 18453} 18454 18455/** 18456 * Normalizes and appends content to an element. 18457 * 18458 * @function appendContent 18459 * @param {Element} el 18460 * @param {String|Element|TextNode|Array|Function} content 18461 * See: `normalizeContent` 18462 * @return {Element} 18463 */ 18464 18465function appendContent(el, content) { 18466 normalizeContent(content).forEach(function (node) { 18467 return el.appendChild(node); 18468 }); 18469 return el; 18470} 18471 18472/** 18473 * Normalizes and inserts content into an element; this is identical to 18474 * `appendContent()`, except it empties the element first. 18475 * 18476 * @function insertContent 18477 * @param {Element} el 18478 * @param {String|Element|TextNode|Array|Function} content 18479 * See: `normalizeContent` 18480 * @return {Element} 18481 */ 18482 18483function insertContent(el, content) { 18484 return appendContent(emptyEl(el), content); 18485} 18486 18487/** 18488 * Finds a single DOM element matching `selector` within the optional 18489 * `context` of another DOM element (defaulting to `document`). 18490 * 18491 * @function $ 18492 * @param {String} selector 18493 * A valid CSS selector, which will be passed to `querySelector`. 18494 * 18495 * @param {Element|String} [context=document] 18496 * A DOM element within which to query. Can also be a selector 18497 * string in which case the first matching element will be used 18498 * as context. If missing (or no element matches selector), falls 18499 * back to `document`. 18500 * 18501 * @return {Element|null} 18502 */ 18503var $ = createQuerier('querySelector'); 18504 18505exports.$ = $; 18506/** 18507 * Finds a all DOM elements matching `selector` within the optional 18508 * `context` of another DOM element (defaulting to `document`). 18509 * 18510 * @function $$ 18511 * @param {String} selector 18512 * A valid CSS selector, which will be passed to `querySelectorAll`. 18513 * 18514 * @param {Element|String} [context=document] 18515 * A DOM element within which to query. Can also be a selector 18516 * string in which case the first matching element will be used 18517 * as context. If missing (or no element matches selector), falls 18518 * back to `document`. 18519 * 18520 * @return {NodeList} 18521 */ 18522var $$ = createQuerier('querySelectorAll'); 18523exports.$$ = $$; 18524 18525},{"./guid.js":135,"./log.js":136,"global/document":1,"global/window":2,"tsml":54}],132:[function(_dereq_,module,exports){ 18526/** 18527 * @file events.js 18528 * 18529 * Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/) 18530 * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible) 18531 * This should work very similarly to jQuery's events, however it's based off the book version which isn't as 18532 * robust as jquery's, so there's probably some differences. 18533 */ 18534 18535'use strict'; 18536 18537exports.__esModule = true; 18538exports.on = on; 18539exports.off = off; 18540exports.trigger = trigger; 18541exports.one = one; 18542exports.fixEvent = fixEvent; 18543 18544function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18545 18546function _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; } } 18547 18548var _domJs = _dereq_('./dom.js'); 18549 18550var Dom = _interopRequireWildcard(_domJs); 18551 18552var _guidJs = _dereq_('./guid.js'); 18553 18554var Guid = _interopRequireWildcard(_guidJs); 18555 18556var _globalWindow = _dereq_('global/window'); 18557 18558var _globalWindow2 = _interopRequireDefault(_globalWindow); 18559 18560var _globalDocument = _dereq_('global/document'); 18561 18562var _globalDocument2 = _interopRequireDefault(_globalDocument); 18563 18564/** 18565 * Add an event listener to element 18566 * It stores the handler function in a separate cache object 18567 * and adds a generic handler to the element's event, 18568 * along with a unique id (guid) to the element. 18569 *
18570 * @param {Element|Object} elem Element or object to bind listeners to 18571 * @param {String|Array} type Type of event to bind to. 18572 * @param {Function} fn Event listener. 18573 * @method on 18574 */ 18575 18576function on(elem, type, fn) { 18577 if (Array.isArray(type)) { 18578 return _handleMultipleEvents(on, elem, type, fn); 18579 } 18580 18581 var data = Dom.getElData(elem); 18582 18583 // We need a place to store all our handler data 18584 if (!data.handlers) data.handlers = {}; 18585 18586 if (!data.handlers[type]) data.handlers[type] = []; 18587 18588 if (!fn.guid) fn.guid = Guid.newGUID(); 18589 18590 data.handlers[type].push(fn); 18591 18592 if (!data.dispatcher) { 18593 data.disabled = false; 18594 18595 data.dispatcher = function (event, hash) { 18596 18597 if (data.disabled) return; 18598 event = fixEvent(event); 18599 18600 var handlers = data.handlers[event.type]; 18601 18602 if (handlers) { 18603 // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off. 18604 var handlersCopy = handlers.slice(0); 18605 18606 for (var m = 0, n = handlersCopy.length; m < n; m++) { 18607 if (event.isImmediatePropagationStopped()) { 18608 break; 18609 } else { 18610 handlersCopy[m].call(elem, event, hash); 18611 } 18612 } 18613 } 18614 }; 18615 } 18616 18617 if (data.handlers[type].length === 1) { 18618 if (elem.addEventListener) { 18619 elem.addEventListener(type, data.dispatcher, false); 18620 } else if (elem.attachEvent) { 18621 elem.attachEvent('on' + type, data.dispatcher); 18622 } 18623 } 18624} 18625 18626/** 18627 * Removes event listeners from an element 18628 * 18629 * @param {Element|Object} elem Object to remove listeners from 18630 * @param {String|Array=} type Type of listener to remove. Don't include to remove all events from element. 18631 * @param {Function} fn Specific listener to remove. Don't include to remove listeners for an event type. 18632 * @method off 18633 */ 18634 18635function off(elem, type, fn) { 18636 // Don't want to add a cache object through getElData if not needed 18637 if (!Dom.hasElData(elem)) return; 18638 18639 var data = Dom.getElData(elem); 18640 18641 // If no events exist, nothing to unbind 18642 if (!data.handlers) { 18643 return; 18644 } 18645 18646 if (Array.isArray(type)) { 18647 return _handleMultipleEvents(off, elem, type, fn); 18648 } 18649 18650 // Utility function 18651 var removeType = function removeType(t) { 18652 data.handlers[t] = []; 18653 _cleanUpEvents(elem, t); 18654 }; 18655 18656 // Are we removing all bound events? 18657 if (!type) { 18658 for (var t in data.handlers) { 18659 removeType(t); 18660 }return; 18661 } 18662 18663 var handlers = data.handlers[type]; 18664 18665 // If no handlers exist, nothing to unbind 18666 if (!handlers) return; 18667 18668 // If no listener was provided, remove all listeners for type 18669 if (!fn) { 18670 removeType(type); 18671 return; 18672 } 18673 18674 // We're only removing a single handler 18675 if (fn.guid) { 18676 for (var n = 0; n < handlers.length; n++) { 18677 if (handlers[n].guid === fn.guid) { 18678 handlers.splice(n--, 1); 18679 } 18680 } 18681 } 18682 18683 _cleanUpEvents(elem, type); 18684} 18685 18686/** 18687 * Trigger an event for an element 18688 * 18689 * @param {Element|Object} elem Element to trigger an event on 18690 * @param {Event|Object|String} event A string (the type) or an event object with a type attribute 18691 * @param {Object} [hash] data hash to pass along with the event 18692 * @return {Boolean=} Returned only if default was prevented 18693 * @method trigger 18694 */ 18695 18696function trigger(elem, event, hash) { 18697 // Fetches element data and a reference to the parent (for bubbling). 18698 // Don't want to add a data object to cache for every parent, 18699 // so checking hasElData first. 18700 var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {}; 18701 var parent = elem.parentNode || elem.ownerDocument; 18702 // type = event.type || event, 18703 // handler; 18704 18705 // If an event name was passed as a string, creates an event out of it 18706 if (typeof event === 'string') { 18707 event = { type: event, target: elem }; 18708 } 18709 // Normalizes the event properties. 18710 event = fixEvent(event); 18711 18712 // If the passed element has a dispatcher, executes the established handlers. 18713 if (elemData.dispatcher) { 18714 elemData.dispatcher.call(elem, event, hash); 18715 } 18716 18717 // Unless explicitly stopped or the event does not bubble (e.g. media events) 18718 // recursively calls this function to bubble the event up the DOM. 18719 if (parent && !event.isPropagationStopped() && event.bubbles === true) { 18720 trigger.call(null, parent, event, hash); 18721 18722 // If at the top of the DOM, triggers the default action unless disabled. 18723 } else if (!parent && !event.defaultPrevented) { 18724 var targetData = Dom.getElData(event.target); 18725 18726 // Checks if the target has a default action for this event. 18727 if (event.target[event.type]) { 18728 // Temporarily disables event dispatching on the target as we have already executed the handler. 18729 targetData.disabled = true; 18730 // Executes the default action. 18731 if (typeof event.target[event.type] === 'function') { 18732 event.target[event.type](); 18733 } 18734 // Re-enables event dispatching. 18735 targetData.disabled = false;
vendor: 4,549 bytes, lines 18736-18877
18736 } 18737 } 18738 18739 // Inform the triggerer if the default was prevented by returning false 18740 return !event.defaultPrevented; 18741} 18742 18743/** 18744 * Trigger a listener only once for an event 18745 * 18746 * @param {Element|Object} elem Element or object to 18747 * @param {String|Array} type Name/type of event 18748 * @param {Function} fn Event handler function 18749 * @method one 18750 */ 18751 18752function one(elem, type, fn) { 18753 if (Array.isArray(type)) { 18754 return _handleMultipleEvents(one, elem, type, fn); 18755 } 18756 var func = function func() { 18757 off(elem, type, func); 18758 fn.apply(this, arguments); 18759 }; 18760 // copy the guid to the new function so it can removed using the original function's ID 18761 func.guid = fn.guid = fn.guid || Guid.newGUID(); 18762 on(elem, type, func); 18763} 18764 18765/** 18766 * Fix a native event to have standard property values 18767 * 18768 * @param {Object} event Event object to fix 18769 * @return {Object} 18770 * @private 18771 * @method fixEvent 18772 */ 18773 18774function fixEvent(event) { 18775 18776 function returnTrue() { 18777 return true; 18778 } 18779 function returnFalse() { 18780 return false; 18781 } 18782 18783 // Test if fixing up is needed 18784 // Used to check if !event.stopPropagation instead of isPropagationStopped 18785 // But native events return true for stopPropagation, but don't have 18786 // other expected methods like isPropagationStopped. Seems to be a problem 18787 // with the Javascript Ninja code. So we're just overriding all events now. 18788 if (!event || !event.isPropagationStopped) { 18789 var old = event || _globalWindow2['default'].event; 18790 18791 event = {}; 18792 // Clone the old object so that we can modify the values event = {}; 18793 // IE8 Doesn't like when you mess with native event properties 18794 // Firefox returns false for event.hasOwnProperty('type') and other props 18795 // which makes copying more difficult. 18796 // TODO: Probably best to create a whitelist of event props 18797 for (var key in old) { 18798 // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y 18799 // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation 18800 // and webkitMovementX/Y 18801 if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') { 18802 // Chrome 32+ warns if you try to copy deprecated returnValue, but 18803 // we still want to if preventDefault isn't supported (IE8). 18804 if (!(key === 'returnValue' && old.preventDefault)) { 18805 event[key] = old[key]; 18806 } 18807 } 18808 } 18809 18810 // The event occurred on this element 18811 if (!event.target) { 18812 event.target = event.srcElement || _globalDocument2['default']; 18813 } 18814 18815 // Handle which other element the event is related to 18816 if (!event.relatedTarget) { 18817 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; 18818 } 18819 18820 // Stop the default browser action 18821 event.preventDefault = function () { 18822 if (old.preventDefault) { 18823 old.preventDefault(); 18824 } 18825 event.returnValue = false; 18826 old.returnValue = false; 18827 event.defaultPrevented = true; 18828 }; 18829 18830 event.defaultPrevented = false; 18831 18832 // Stop the event from bubbling 18833 event.stopPropagation = function () { 18834 if (old.stopPropagation) { 18835 old.stopPropagation(); 18836 } 18837 event.cancelBubble = true; 18838 old.cancelBubble = true; 18839 event.isPropagationStopped = returnTrue; 18840 }; 18841 18842 event.isPropagationStopped = returnFalse; 18843 18844 // Stop the event from bubbling and executing other handlers 18845 event.stopImmediatePropagation = function () { 18846 if (old.stopImmediatePropagation) { 18847 old.stopImmediatePropagation(); 18848 } 18849 event.isImmediatePropagationStopped = returnTrue; 18850 event.stopPropagation(); 18851 }; 18852 18853 event.isImmediatePropagationStopped = returnFalse; 18854 18855 // Handle mouse position 18856 if (event.clientX != null) { 18857 var doc = _globalDocument2['default'].documentElement, 18858 body = _globalDocument2['default'].body; 18859 18860 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); 18861 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); 18862 } 18863 18864 // Handle key presses 18865 event.which = event.charCode || event.keyCode; 18866 18867 // Fix button for mouse clicks: 18868 // 0 == left; 1 == middle; 2 == right 18869 if (event.button != null) { 18870 event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0; 18871 } 18872 } 18873 18874 // Returns fixed-up instance 18875 return event; 18876} 18877
18878/** 18879 * Clean up the listener cache and dispatchers 18880* 18881 * @param {Element|Object} elem Element to clean up 18882 * @param {String} type Type of event to clean up 18883 * @private 18884 * @method _cleanUpEvents 18885 */ 18886function _cleanUpEvents(elem, type) { 18887 var data = Dom.getElData(elem); 18888 18889 // Remove the events of a particular type if there are none left 18890 if (data.handlers[type].length === 0) { 18891 delete data.handlers[type]; 18892 // data.handlers[type] = null; 18893 // Setting to null was causing an error with data.handlers 18894 18895 // Remove the meta-handler from the element 18896 if (elem.removeEventListener) { 18897 elem.removeEventListener(type, data.dispatcher, false); 18898 } else if (elem.detachEvent) { 18899 elem.detachEvent('on' + type, data.dispatcher); 18900 } 18901 } 18902 18903 // Remove the events object if there are no types left 18904 if (Object.getOwnPropertyNames(data.handlers).length <= 0) { 18905 delete data.handlers; 18906 delete data.dispatcher; 18907 delete data.disabled; 18908 } 18909 18910 // Finally remove the element data if there is no data left 18911 if (Object.getOwnPropertyNames(data).length === 0) { 18912 Dom.removeElData(elem); 18913 } 18914} 18915 18916/** 18917 * Loops through an array of event types and calls the requested method for each type. 18918 * 18919 * @param {Function} fn The event method we want to use. 18920 * @param {Element|Object} elem Element or object to bind listeners to 18921 * @param {String} type Type of event to bind to. 18922 * @param {Function} callback Event listener. 18923 * @private 18924 * @function _handleMultipleEvents 18925 */ 18926function _handleMultipleEvents(fn, elem, types, callback) { 18927 types.forEach(function (type) { 18928 //Call the event method for each one of the types 18929 fn(elem, type, callback); 18930 }); 18931} 18932 18933},{"./dom.js":131,"./guid.js":135,"global/document":1,"global/window":2}],133:[function(_dereq_,module,exports){ 18934/** 18935 * @file fn.js 18936 */ 18937'use strict'; 18938 18939exports.__esModule = true; 18940 18941var _guidJs = _dereq_('./guid.js'); 18942 18943/** 18944 * Bind (a.k.a proxy or Context). A simple method for changing the context of a function 18945 * It also stores a unique id on the function so it can be easily removed from events 18946 * 18947 * @param {*} context The object to bind as scope 18948 * @param {Function} fn The function to be bound to a scope 18949 * @param {Number=} uid An optional unique ID for the function to be set 18950 * @return {Function} 18951 * @private 18952 * @method bind 18953 */ 18954var bind = function bind(context, fn, uid) { 18955 // Make sure the function has a unique ID 18956 if (!fn.guid) { 18957 fn.guid = _guidJs.newGUID(); 18958 } 18959 18960 // Create the new function that changes the context 18961 var ret = function ret() { 18962 return fn.apply(context, arguments); 18963 }; 18964 18965 // Allow for the ability to individualize this function 18966 // Needed in the case where multiple objects might share the same prototype 18967 // IF both items add an event listener with the same function, then you try to remove just one 18968 // it will remove both because they both have the same guid. 18969 // when using this, you need to use the bind method when you remove the listener as well. 18970 // currently used in text tracks 18971 ret.guid = uid ? uid + '_' + fn.guid : fn.guid; 18972 18973 return ret; 18974}; 18975exports.bind = bind; 18976 18977},{"./guid.js":135}],134:[function(_dereq_,module,exports){ 18978/** 18979 * @file format-time.js 18980 * 18981 * Format seconds as a time string, H:MM:SS or M:SS 18982 * Supplying a guide (in seconds) will force a number of leading zeros 18983 * to cover the length of the guide 18984 * 18985 * @param {Number} seconds Number of seconds to be turned into a string 18986 * @param {Number} guide Number (in seconds) to model the string after 18987 * @return {String} Time formatted as H:MM:SS or M:SS 18988 * @private 18989 * @function formatTime 18990 */ 18991'use strict'; 18992 18993exports.__esModule = true; 18994function formatTime(seconds) { 18995 var guide = arguments.length <= 1 || arguments[1] === undefined ? seconds : arguments[1]; 18996 return (function () { 18997 seconds = seconds < 0 ? 0 : seconds; 18998 var s = Math.floor(seconds % 60); 18999 var m = Math.floor(seconds / 60 % 60); 19000 var h = Math.floor(seconds / 3600); 19001 var gm = Math.floor(guide / 60 % 60); 19002 var gh = Math.floor(guide / 3600); 19003 19004 // handle invalid times 19005 if (isNaN(seconds) || seconds === Infinity) { 19006 // '-' is false for all relational operators (e.g. <, >
19006=) so this setting 19007 // will add the minimum number of fields specified by the guide 19008 h = m = s = '-'; 19009 } 19010 19011 // Check if we need to show hours 19012 h = h > 0 || gh > 0 ? h + ':' : ''; 19013 19014 // If hours are showing, we may need to add a leading zero. 19015 // Always show at least one digit of minutes. 19016 m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':'; 19017 19018 // Check if leading zero is need for seconds 19019 s = s < 10 ? '0' + s : s; 19020 19021 return h + m + s; 19022 })(); 19023} 19024 19025exports['default'] = formatTime; 19026module.exports = exports['default']; 19027 19028},{}],135:[function(_dereq_,module,exports){ 19029/** 19030 * @file guid.js 19031 * 19032 * Unique ID for an element or function 19033 * @type {Number} 19034 * @private 19035 */ 19036"use strict"; 19037 19038exports.__esModule = true; 19039exports.newGUID = newGUID; 19040var _guid = 1; 19041 19042/** 19043 * Get the next unique ID 19044 * 19045 * @return {String} 19046 * @function newGUID 19047 */ 19048 19049function newGUID() { 19050 return _guid++; 19051} 19052 19053},{}],136:[function(_dereq_,module,exports){ 19054/** 19055 * @file log.js 19056 */ 19057'use strict'; 19058 19059exports.__esModule = true; 19060 19061function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19062 19063var _globalWindow = _dereq_('global/window'); 19064 19065var _globalWindow2 = _interopRequireDefault(_globalWindow); 19066 19067/** 19068 * Log plain debug messages 19069 */ 19070var log = function log() { 19071 _logType(null, arguments); 19072}; 19073 19074/** 19075 * Keep a history of log messages 19076 * @type {Array} 19077 */ 19078log.history = []; 19079 19080/** 19081 * Log error messages 19082 */ 19083log.error = function () { 19084 _logType('error', arguments); 19085}; 19086 19087/** 19088 * Log warning messages 19089 */ 19090log.warn = function () { 19091 _logType('warn', arguments); 19092}; 19093 19094/** 19095 * Log messages to the console and history based on the type of message 19096 * 19097 * @param {String} type The type of message, or `null` for `log` 19098 * @param {Object} args The args to be passed to the log 19099 * @private 19100 * @method _logType 19101 */ 19102function _logType(type, args) { 19103 // convert args to an array to get array functions 19104 var argsArray = Array.prototype.slice.call(args); 19105 // if there's no console then don't try to output messages 19106 // they will still be stored in log.history 19107 // Was setting these once outside of this function, but containing them 19108 // in the function makes it easier to test cases where console doesn't exist 19109 var noop = function noop() {}; 19110 19111 var console = _globalWindow2['default']['console'] || { 19112 'log': noop, 19113 'warn': noop, 19114 'error': noop 19115 }; 19116 19117 if (type) { 19118 // add the type to the front of the message 19119 argsArray.unshift(type.toUpperCase() + ':'); 19120 } else { 19121 // default to log with no prefix 19122 type = 'log'; 19123 } 19124 19125 // add to history 19126 log.history.push(argsArray); 19127 19128 // add console prefix after adding to history 19129 argsArray.unshift('VIDEOJS:'); 19130 19131 // call appropriate log function 19132 if (console[type].apply) { 19133 console[type].apply(console, argsArray); 19134 } else { 19135 // ie8 doesn't allow error.apply, but it will just join() the array anyway 19136 console[type](argsArray.join(' ')); 19137 } 19138} 19139 19140exports['default'] = log; 19141module.exports = exports['default']; 19142 19143},{"global/window":2}],137:[function(_dereq_,module,exports){ 19144/** 19145 * @file merge-options.js 19146 */ 19147'use strict'; 19148 19149exports.__esModule = true; 19150exports['default'] = mergeOptions; 19151 19152function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19153 19154var _lodashCompatObjectMerge = _dereq_('lodash-compat/object/merge'); 19155 19156var _lodashCompatObjectMerge2 = _interopRequireDefault(_lodashCompatObjectMerge); 19157 19158function isPlain(obj) { 19159 return !!obj && typeof obj === 'object' && obj.toString() === '[object Object]' && obj.constructor === Object; 19160} 19161 19162/** 19163 * Merge customizer. video.js simply overwrites non-simple objects 19164 * (like arrays) instead of attempting to overlay them. 19165 * @see https://lodash.com/docs#merge 19166 */ 19167var customizer = function customizer(destination, source) { 19168 // If we're not working with a plain object, copy the value as is 19169 // If source is an array, for instance, it will replace destination 19170 if (!isPlain(source)) { 19171 return source; 19172 } 19173 19174 // If the new value is a plain object but the first object value is not 19175 // we need to create a new object for the first object to merge with. 19176 // This makes it consistent with how merge() works by default 19177 // and also protects from later changes the to first object affecting 19178 // the second object's values. 19179 if (!isPlain(destination)) { 19180 return mergeOptions(source); 19181 } 19182}; 19183 19184/** 19185 * Merge one or more options objects, recursively merging **only** 19186 * plain object properties. Previously `deepMerge`. 19187 * 19188 * @param {...Object} source One or more objects to merge 19189 * @returns {Object} a new object that is the union of all 19190 * provided objects 19191 * @function mergeOptions 19192 */ 19193 19194function mergeOptions() { 19195 // contruct the call dynamically to handle the variable number of 19196 // objects to merge 19197 var args = Array.prototype.slice.call(arguments); 19198 19199 // unshift an empty object into the front of the call as the target 19200 // of the merge 19201 args.unshift({}); 19202 19203 // customize conflict resolution to match our historical merge behavior 19204 args.push(customizer); 19205
19206 _lodashCompatObjectMerge2['default'].apply(null, args); 19207 19208 // return the mutated result object 19209 return args[0]; 19210} 19211 19212module.exports = exports['default']; 19213 19214},{"lodash-compat/object/merge":40}],138:[function(_dereq_,module,exports){ 19215'use strict'; 19216 19217exports.__esModule = true; 19218 19219function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19220 19221var _globalDocument = _dereq_('global/document'); 19222 19223var _globalDocument2 = _interopRequireDefault(_globalDocument); 19224 19225var createStyleElement = function createStyleElement(className) { 19226 var style = _globalDocument2['default'].createElement('style'); 19227 style.className = className; 19228 19229 return style; 19230}; 19231 19232exports.createStyleElement = createStyleElement; 19233var setTextContent = function setTextContent(el, content) { 19234 if (el.styleSheet) { 19235 el.styleSheet.cssText = content; 19236 } else { 19237 el.textContent = content; 19238 } 19239}; 19240exports.setTextContent = setTextContent; 19241 19242},{"global/document":1}],139:[function(_dereq_,module,exports){ 19243'use strict'; 19244 19245exports.__esModule = true; 19246exports.createTimeRanges = createTimeRanges; 19247 19248function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19249 19250var _logJs = _dereq_('./log.js'); 19251 19252var _logJs2 = _interopRequireDefault(_logJs); 19253 19254/** 19255 * @file time-ranges.js 19256 * 19257 * Should create a fake TimeRange object 19258 * Mimics an HTML5 time range instance, which has functions that 19259 * return the start and end times for a range 19260 * TimeRanges are returned by the buffered() method 19261 * 19262 * @param {(Number|Array)} Start of a single range or an array of ranges 19263 * @param {Number} End of a single range 19264 * @private 19265 * @method createTimeRanges 19266 */ 19267 19268function createTimeRanges(start, end) { 19269 if (Array.isArray(start)) { 19270 return createTimeRangesObj(start); 19271 } else if (start === undefined || end === undefined) { 19272 return createTimeRangesObj(); 19273 } 19274 return createTimeRangesObj([[start, end]]); 19275} 19276 19277exports.createTimeRange = createTimeRanges; 19278 19279function createTimeRangesObj(ranges) { 19280 if (ranges === undefined || ranges.length === 0) { 19281 return { 19282 length: 0, 19283 start: function start() { 19284 throw new Error('This TimeRanges object is empty'); 19285 }, 19286 end: function end() { 19287 throw new Error('This TimeRanges object is empty'); 19288 } 19289 }; 19290 } 19291 return { 19292 length: ranges.length, 19293 start: getRange.bind(null, 'start', 0, ranges), 19294 end: getRange.bind(null, 'end', 1, ranges) 19295 }; 19296} 19297 19298function getRange(fnName, valueIndex, ranges, rangeIndex) { 19299 if (rangeIndex === undefined) { 19300 _logJs2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.'); 19301 rangeIndex = 0; 19302 } 19303 rangeCheck(fnName, rangeIndex, ranges.length - 1); 19304 return ranges[rangeIndex][valueIndex]; 19305} 19306 19307function rangeCheck(fnName, index, maxIndex) { 19308 if (index < 0 || index > maxIndex) { 19309 throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').'); 19310 } 19311} 19312 19313},{"./log.js":136}],140:[function(_dereq_,module,exports){ 19314/** 19315 * @file to-title-case.js 19316 * 19317 * Uppercase the first letter of a string 19318 * 19319 * @param {String} string String to be uppercased 19320 * @return {String} 19321 * @private 19322 * @method toTitleCase 19323 */ 19324"use strict"; 19325 19326exports.__esModule = true; 19327function toTitleCase(string) { 19328 return string.charAt(0).toUpperCase() + string.slice(1); 19329} 19330 19331exports["default"] = toTitleCase; 19332module.exports = exports["default"]; 19333 19334},{}],141:[function(_dereq_,module,exports){ 19335/** 19336 * @file url.js 19337 */ 19338'use strict'; 19339 19340exports.__esModule = true; 19341 19342function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19343 19344var _globalDocument = _dereq_('global/document'); 19345 19346var _globalDocument2 = _interopRequireDefault(_globalDocument); 19347 19348var _globalWindow = _dereq_('global/window'); 19349 19350var _globalWindow2 = _interopRequireDefault(_globalWindow); 19351 19352/** 19353 * Resolve and parse the elements of a URL 19354 * 19355 * @param {String} url The url to parse 19356 * @return {Object} An object of url details 19357 * @method parseUrl 19358 */ 19359var parseUrl = function parseUrl(url) { 19360 var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host']; 19361 19362 // add the url to an anchor and let the browser parse the URL 19363 var a = _globalDocument2['default'].createElement('a'); 19364 a.href = url; 19365 19366 // IE8 (and 9?) Fix
19367 // ie8 doesn't parse the URL correctly until the anchor is actually 19368 // added to the body, and an innerHTML is needed to trigger the parsing 19369 var addToBody = a.host === '' && a.protocol !== 'file:'; 19370 var div = undefined; 19371 if (addToBody) { 19372 div = _globalDocument2['default'].createElement('div'); 19373 div.innerHTML = '<a href="' + url + '"></a>'; 19374 a = div.firstChild; 19375 // prevent the div from affecting layout 19376 div.setAttribute('style', 'display:none; position:absolute;'); 19377 _globalDocument2['default'].body.appendChild(div); 19378 } 19379 19380 // Copy the specific URL properties to a new object 19381 // This is also needed for IE8 because the anchor loses its 19382 // properties when it's removed from the dom 19383 var details = {}; 19384 for (var i = 0; i < props.length; i++) { 19385 details[props[i]] = a[props[i]]; 19386 } 19387 19388 // IE9 adds the port to the host property unlike everyone else. If 19389 // a port identifier is added for standard ports, strip it. 19390 if (details.protocol === 'http:') { 19391 details.host = details.host.replace(/:80$/, ''); 19392 } 19393 if (details.protocol === 'https:') { 19394 details.host = details.host.replace(/:443$/, ''); 19395 } 19396 19397 if (addToBody) { 19398 _globalDocument2['default'].body.removeChild(div); 19399 } 19400 19401 return details; 19402}; 19403 19404exports.parseUrl = parseUrl; 19405/** 19406 * Get absolute version of relative URL. Used to tell flash correct URL. 19407 * http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue 19408 * 19409 * @param {String} url URL to make absolute 19410 * @return {String} Absolute URL 19411 * @private 19412 * @method getAbsoluteURL 19413 */ 19414var getAbsoluteURL = function getAbsoluteURL(url) { 19415 // Check if absolute URL 19416 if (!url.match(/^https?:\/\//)) { 19417 // Convert to absolute URL. Flash hosted off-site needs an absolute URL. 19418 var div = _globalDocument2['default'].createElement('div'); 19419 div.innerHTML = '<a href="' + url + '">x</a>'; 19420 url = div.firstChild.href; 19421 } 19422 19423 return url; 19424}; 19425 19426exports.getAbsoluteURL = getAbsoluteURL; 19427/** 19428 * Returns the extension of the passed file name. It will return an empty string if you pass an invalid path 19429 * 19430 * @param {String} path The fileName path like '/path/to/file.mp4' 19431 * @returns {String} The extension in lower case or an empty string if no extension could be found. 19432 * @method getFileExtension 19433 */ 19434var getFileExtension = function getFileExtension(path) { 19435 if (typeof path === 'string') { 19436 var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i; 19437 var pathParts = splitPathRe.exec(path); 19438 19439 if (pathParts) { 19440 return pathParts.pop().toLowerCase(); 19441 } 19442 } 19443 19444 return ''; 19445}; 19446 19447exports.getFileExtension = getFileExtension; 19448/** 19449 * Returns whether the url passed is a cross domain request or not. 19450 * 19451 * @param {String} url The url to check 19452 * @return {Boolean} Whether it is a cross domain request or not 19453 * @method isCrossOrigin 19454 */ 19455var isCrossOrigin = function isCrossOrigin(url) { 19456 var winLoc = _globalWindow2['default'].location; 19457 var urlInfo = parseUrl(url); 19458 19459 // IE8 protocol relative urls will return ':' for protocol 19460 var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol; 19461 19462 // Check if url is for another domain/origin 19463 // IE8 doesn't know location.origin, so we won't rely on it here 19464 var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host; 19465 19466 return crossOrigin; 19467}; 19468exports.isCrossOrigin = isCrossOrigin; 19469 19470},{"global/document":1,"global/window":2}],142:[function(_dereq_,module,exports){ 19471/** 19472 * @file video.js 19473 */ 19474'use strict'; 19475 19476exports.__esModule = true; 19477 19478function _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; } } 19479 19480function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19481 19482var _globalDocument = _dereq_('global/document'); 19483 19484var _globalDocument2 = _interopRequireDefault(_globalDocument); 19485 19486var _setup = _dereq_('./setup'); 19487 19488var setup = _interopRequireWildcard(_setup); 19489 19490var _utilsStylesheetJs = _dereq_('./utils/stylesheet.js'); 19491 19492var stylesheet = _interopRequireWildcard(_utilsStylesheetJs); 19493 19494var _component = _dereq_('./component'); 19495 19496var _component2 = _interopRequireDefault(_component); 19497 19498var _eventTarget = _dereq_('./event-target'); 19499 19500var _eventTarget2 = _interopRequireDefault(_eventTarget); 19501 19502var _utilsEventsJs = _dereq_('./utils/events.js'); 19503 19504var Events = _interopRequireWildcard(_utilsEventsJs); 19505 19506var _player = _dereq_('./player'); 19507 19508var _player2 = _interopRequireDefault(_player); 19509 19510var _pluginsJs = _dereq_('./plugins.js'); 19511 19512var _pluginsJs2 = _interopRequireDefault(_pluginsJs); 19513 19514var _srcJsUtilsMergeOptionsJs = _dereq_('../../src/js/utils/merge-options.js'); 19515 19516var _srcJsUtilsMergeOptionsJs2 = _interopRequireDefault(_srcJsUtilsMergeOptionsJs); 19517 19518var _utilsFnJs = _dereq_('./utils/fn.js'); 19519 19520var Fn = _interopRequireWildcard(_utilsFnJs); 19521 19522var _tracksTextTrackJs = _dereq_('./tracks/text-track.js'); 19523 19524var _tracksTextTrackJs2 = _interopRequireDefault(_tracksTextTrackJs); 19525 19526var _objectAssign = _dereq_('object.assign'); 19527 19528var _objectAssign2 = _interopRequireDefault(_objectAssign); 19529 19530var _utilsTimeRangesJs = _dereq_('./utils/time-ranges.js'); 19531 19532var _utilsFormatTimeJs = _dereq_('./utils/format-time.js'); 19533 19534var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs); 19535 19536var _utilsLogJs = _dereq_('./utils/log.js'); 19537 19538var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs); 19539 19540var _utilsDomJs = _dereq_('./utils/dom.js'); 19541 19542var Dom = _interopRequireWildcard(_utilsDomJs); 19543 19544var _utilsBrowserJs = _dereq_('./utils/browser.js'); 19545 19546var browser = _interopRequireWildcard(_utilsBrowserJs); 19547 19548var _utilsUrlJs = _dereq_('./utils/url.js'); 19549 19550var Url = _interopRequireWildcard(_utilsUrlJs); 19551 19552var _extendJs = _dereq_('./extend.js'); 19553 19554var _extendJs2 = _interopRequireDefault(_extendJs); 19555 19556var _lodashCompatObjectMerge = _dereq_('lodash-compat/object/merge'); 19557 19558var _lodashCompatObjectMerge2 = _interopRequireDefault(_lodashCompatObjectMerge); 19559 19560var _utilsCreateDeprecationProxyJs = _dereq_('./utils/create-deprecation-proxy.js'); 19561 19562var _utilsCreateDeprecationProxyJs2 = _interopRequireDefault(_utilsCreateDeprecationProxyJs); 19563 19564var _xhr = _dereq_('xhr'); 19565
19566var _xhr2 = _interopRequireDefault(_xhr); 19567 19568// Include the built-in techs 19569 19570var _techTechJs = _dereq_('./tech/tech.js'); 19571 19572var _techTechJs2 = _interopRequireDefault(_techTechJs); 19573 19574var _techHtml5Js = _dereq_('./tech/html5.js'); 19575 19576var _techHtml5Js2 = _interopRequireDefault(_techHtml5Js); 19577 19578var _techFlashJs = _dereq_('./tech/flash.js'); 19579 19580var _techFlashJs2 = _interopRequireDefault(_techFlashJs); 19581 19582// HTML5 Element Shim for IE8 19583if (typeof HTMLVideoElement === 'undefined') { 19584 _globalDocument2['default'].createElement('video'); 19585 _globalDocument2['default'].createElement('audio'); 19586 _globalDocument2['default'].createElement('track'); 19587} 19588 19589/** 19590 * Doubles as the main function for users to create a player instance and also 19591 * the main library object. 19592 * The `videojs` function can be used to initialize or retrieve a player. 19593 * ```js 19594 * var myPlayer = videojs('my_video_id'); 19595 * ``` 19596 * 19597 * @param {String|Element} id Video element or video element ID 19598 * @param {Object=} options Optional options object for config/settings 19599 * @param {Function=} ready Optional ready callback 19600 * @return {Player} A player instance 19601 * @mixes videojs 19602 * @method videojs 19603 */ 19604var videojs = function videojs(id, options, ready) { 19605 var tag = undefined; // Element of ID 19606 19607 // Allow for element or ID to be passed in 19608 // String ID 19609 if (typeof id === 'string') { 19610 19611 // Adjust for jQuery ID syntax 19612 if (id.indexOf('#') === 0) { 19613 id = id.slice(1); 19614 } 19615 19616 // If a player instance has already been created for this ID return it. 19617 if (videojs.getPlayers()[id]) { 19618 19619 // If options or ready funtion are passed, warn 19620 if (options) { 19621 _utilsLogJs2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.'); 19622 } 19623 19624 if (ready) { 19625 videojs.getPlayers()[id].ready(ready); 19626 } 19627 19628 return videojs.getPlayers()[id]; 19629 19630 // Otherwise get element for ID 19631 } else { 19632 tag = Dom.getEl(id); 19633 } 19634 19635 // ID is a media element 19636 } else { 19637 tag = id; 19638 } 19639 19640 // Check for a useable element 19641 if (!tag || !tag.nodeName) { 19642 // re: nodeName, could be a box div also 19643 throw new TypeError('The element or ID supplied is not valid. (videojs)'); // Returns 19644 } 19645 19646 // Element may have a player attr referring to an already created player instance. 19647 // If not, set up a new player and return the instance. 19648 return tag['player'] || _player2['default'].players[tag.playerId] || new _player2['default'](tag, options, ready); 19649}; 19650 19651// Add default styles 19652var style = Dom.$('.vjs-styles-defaults'); 19653if (!style) { 19654 style = stylesheet.createStyleElement('vjs-styles-defaults'); 19655 var head = Dom.$('head'); 19656 head.insertBefore(style, head.firstChild); 19657 stylesheet.setTextContent(style, '\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n '); 19658} 19659 19660// Run Auto-load players 19661// 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) 19662setup.autoSetupTimeout(1, videojs); 19663 19664/* 19665 * Current software version (semver) 19666 * 19667 * @type {String} 19668 */ 19669videojs.VERSION = '5.7.0'; 19670 19671/** 19672 * The global options object. These are the settings that take effect 19673 * if no overrides are specified when the player is created. 19674 * 19675 * ```js 19676 * videojs.options.autoplay = true 19677 * // -> all players will autoplay by default 19678 * ``` 19679 * 19680 * @type {Object} 19681 */ 19682videojs.options = _player2['default'].prototype.options_; 19683 19684/** 19685 * Get an object with the currently created players, keyed by player ID 19686 * 19687 * @return {Object} The created players 19688 * @mixes videojs 19689 * @method getPlayers 19690 */ 19691videojs.getPlayers = function () { 19692 return _player2['default'].players; 19693}; 19694 19695/** 19696 * For backward compatibility, expose players object. 19697 * 19698 * @deprecated 19699 * @memberOf videojs 19700 * @property {Object|Proxy} players 19701 */ 19702videojs.players = _utilsCreateDeprecationProxyJs2['default'](_player2['default'].players, { 19703 get: 'Access to videojs.players is deprecated; use videojs.getPlayers instead', 19704 set: 'Modification of videojs.players is deprecated' 19705}); 19706 19707/** 19708 * Get a component class object by name 19709 * ```js 19710 * var VjsButton = videojs.getComponent('Button'); 19711 * // Create a new instance of the component 19712 * var myButton = new VjsButton(myPlayer); 19713 * ``` 19714 * 19715 * @return {Component} Component identified by name 19716 * @mixes videojs 19717 * @method getComponent 19718 */ 19719videojs.getComponent = _component2['default'].getComponent; 19720 19721/** 19722 * Register a component so it can referred to by name 19723 * Used when adding to other 19724 * components, either through addChild 19725 * `component.addChild('myComponent')` 19726 * or through default children options 19727 * `{ children: ['myComponent'] }`. 19728 * ```js 19729 * // Get a component to subclass 19730 * var VjsButton = videojs.getComponent('Button'); 19731 * // Subclass the component (see 'extend' doc for more info) 19732 * var MySpecialButton = videojs.extend(VjsButton, {}); 19733 * // Register the new component 19734 * VjsButton.registerComponent('MySepcialButton', MySepcialButton); 19735 * // (optionally) add the new component as a default player child 19736 * myPlayer.addChild('MySepcialButton'); 19737 * ``` 19738 * NOTE: You could also just initialize the component before adding. 19739 * `component.addChild(new MyComponent());` 19740 * 19741 * @param {String} The class name of the component 19742 * @param {Component} The component class 19743 * @return {Component} The newly registered component 19744 * @mixes videojs 19745 * @method registerComponent 19746 */ 19747videojs.registerComponent = function (name, comp) { 19748 if (_techTechJs2['default'].isTech(comp)) { 19749 _utilsLogJs2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)'); 19750 } 19751 19752 _component2['default'].registerComponent.call(_component2['default'], name, comp); 19753}; 19754 19755/** 19756 * Get a Tech class object by name 19757 * ```js 19758 * var Html5 = videojs.getTech('Html5'); 19759 * // Create a new instance of the component 19760 * var html5 = new Html5(options); 19761 * ``` 19762 * 19763 * @return {Tech} Tech identified by name 19764 * @mixes videojs 19765 * @method getComponent 19766 */ 19767videojs.getTech = _techTechJs2['default'].getTech; 19768 19769/** 19770 * Register a Tech so it can referred to by name. 19771 * This is used in the tech order for the player. 19772 * 19773 * ```js 19774 * // get the Html5 Tech 19775 * var Html5 = videojs.getTech('Html5'); 19776 * var MyTech = videojs.extend(Html5, {}); 19777 * // Register the new Tech 19778 * VjsButton.registerTech('Tech', MyTech); 19779 * var player = videojs('myplayer', { 19780 * techOrder: ['myTech', 'html5'] 19781 * }); 19782 * ``` 19783 * 19784 * @param {String} The class name of the tech 19785 * @param {Tech} The tech class 19786 * @return {Tech} The newly registered Tech 19787 * @mixes videojs 19788 * @method registerTech 19789 */ 19790videojs.registerTech = _techTechJs2['default'].registerTech; 19791 19792/** 19793 * A suite of browser and device tests 19794 * 19795 * @type {Object} 19796 * @private 19797 */ 19798videojs.browser = browser; 19799 19800/** 19801 * Whether or not the browser supports touch events. Included for backward 19802 * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED` 19803 * instead going forward. 19804 * 19805 * @deprecated 19806 * @type {Boolean} 19807 */ 19808videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED; 19809 19810/** 19811 * Subclass an existing class 19812 * Mimics ES6 subclassing with the `extend` keyword 19813 * ```js 19814 * // Create a basic javascript 'class' 19815 * function MyClass(name){ 19816 * // Set a property at initialization 19817 * this.myName = name; 19818 * } 19819 * // Create an instance method 19820 * MyClass.prototype.sayMyName = function(){ 19821 * alert(this.myName); 19822 * }; 19823 * // Subclass the exisitng class and change the name 19824 * // when initializing 19825 * var MySubClass = videojs.extend(MyClass, { 19826 * constructor: function(name) { 19827 * // Call the super class constructor for the subclass 19828 * MyClass.call(this, name) 19829 * } 19830 * }); 19831 * // Create an instance of the new sub class 19832 * var myInstance = new MySubClass('John'); 19833 * myInstance.sayMyName(); // -> should alert "John" 19834 * ``` 19835 * 19836 * @param {Function} The Class to subclass 19837 * @param {Object} An object including instace methods for the new class 19838 * Optionally including a `constructor` function 19839 * @return {Function} The newly created subclass 19840 * @mixes videojs 19841 * @method extend 19842 */ 19843videojs.extend = _extendJs2['default']; 19844 19845/** 19846 * Merge two options objects recursively 19847 * Performs a deep merge like lodash.merge but **only merges plain objects** 19848 * (not arrays, elements, anything else) 19849 * Other values will be copied directly from the second object. 19850 * ```js 19851 * var defaultOptions = { 19852 * foo: true, 19853 * bar: { 19854 * a: true, 19855 * b: [1,2,3] 19856 * } 19857 * }; 19858 * var newOptions = { 19859 * foo: false, 19860 * bar: { 19861 * b: [4,5,6] 19862 * } 19863 * }; 19864 * var result = videojs.mergeOptions(defaultOptions, newOptions); 19865 * // result.foo = false;
19866 * // result.bar.a = true; 19867 * // result.bar.b = [4,5,6]; 19868 * ``` 19869 * 19870 * @param {Object} defaults The options object whose values will be overriden 19871 * @param {Object} overrides The options object with values to override the first 19872 * @param {Object} etc Any number of additional options objects 19873 * 19874 * @return {Object} a new object with the merged values 19875 * @mixes videojs 19876 * @method mergeOptions 19877 */ 19878videojs.mergeOptions = _srcJsUtilsMergeOptionsJs2['default']; 19879 19880/** 19881 * Change the context (this) of a function 19882 * 19883 * videojs.bind(newContext, function(){ 19884 * this === newContext 19885 * }); 19886 * 19887 * NOTE: as of v5.0 we require an ES5 shim, so you should use the native 19888 * `function(){}.bind(newContext);` instead of this. 19889 * 19890 * @param {*} context The object to bind as scope 19891 * @param {Function} fn The function to be bound to a scope 19892 * @param {Number=} uid An optional unique ID for the function to be set 19893 * @return {Function} 19894 */ 19895videojs.bind = Fn.bind; 19896 19897/** 19898 * Create a Video.js player plugin 19899 * Plugins are only initialized when options for the plugin are included 19900 * in the player options, or the plugin function on the player instance is 19901 * called. 19902 * **See the plugin guide in the docs for a more detailed example** 19903 * ```js 19904 * // Make a plugin that alerts when the player plays 19905 * videojs.plugin('myPlugin', function(myPluginOptions) { 19906 * myPluginOptions = myPluginOptions || {}; 19907 * 19908 * var player = this; 19909 * var alertText = myPluginOptions.text || 'Player is playing!' 19910 * 19911 * player.on('play', function(){ 19912 * alert(alertText); 19913 * }); 19914 * }); 19915 * // USAGE EXAMPLES 19916 * // EXAMPLE 1: New player with plugin options, call plugin immediately 19917 * var player1 = videojs('idOne', { 19918 * myPlugin: { 19919 * text: 'Custom text!' 19920 * } 19921 * }); 19922 * // Click play 19923 * // --> Should alert 'Custom text!' 19924 * // EXAMPLE 3: New player, initialize plugin later 19925 * var player3 = videojs('idThree'); 19926 * // Click play 19927 * // --> NO ALERT 19928 * // Click pause 19929 * // Initialize plugin using the plugin function on the player instance 19930 * player3.myPlugin({ 19931 * text: 'Plugin added later!' 19932 * }); 19933 * // Click play 19934 * // --> Should alert 'Plugin added later!' 19935 * ``` 19936 * 19937 * @param {String} name The plugin name 19938 * @param {Function} fn The plugin function that will be called with options 19939 * @mixes videojs 19940 * @method plugin 19941 */ 19942videojs.plugin = _pluginsJs2['default']; 19943 19944/** 19945 * Adding languages so that they're available to all players. 19946 * ```js 19947 * videojs.addLanguage('es', { 'Hello': 'Hola' }); 19948 * ``` 19949 * 19950 * @param {String} code The language code or dictionary property 19951 * @param {Object} data The data values to be translated 19952 * @return {Object} The resulting language dictionary object 19953 * @mixes videojs 19954 * @method addLanguage 19955 */ 19956videojs.addLanguage = function (code, data) { 19957 var _merge; 19958 19959 code = ('' + code).toLowerCase(); 19960 return _lodashCompatObjectMerge2['default'](videojs.options.languages, (_merge = {}, _merge[code] = data, _merge))[code]; 19961}; 19962 19963/** 19964 * Log debug messages. 19965 * 19966 * @param {...Object} messages One or more messages to log 19967 */ 19968videojs.log = _utilsLogJs2['default']; 19969 19970/** 19971 * Creates an emulated TimeRange object. 19972 * 19973 * @param {Number|Array} start Start time in seconds or an array of ranges 19974 * @param {Number} end End time in seconds 19975 * @return {Object} Fake TimeRange object 19976 * @method createTimeRange 19977 */ 19978videojs.createTimeRange = videojs.createTimeRanges = _utilsTimeRangesJs.createTimeRanges; 19979 19980/** 19981 * Format seconds as a time string, H:MM:SS or M:SS 19982 * Supplying a guide (in seconds) will force a number of leading zeros 19983 * to cover the length of the guide 19984 * 19985 * @param {Number} seconds Number of seconds to be turned into a string 19986 * @param {Number} guide Number (in seconds) to model the string after 19987 * @return {String} Time formatted as H:MM:SS or M:SS 19988 * @method formatTime 19989 */ 19990videojs.formatTime = _utilsFormatTimeJs2['default']; 19991 19992/** 19993 * Resolve and parse the elements of a URL 19994 * 19995 * @param {String} url The url to parse 19996 * @return {Object} An object of url details 19997 * @method parseUrl 19998 */ 19999videojs.parseUrl = Url.parseUrl; 20000 20001/** 20002 * Returns whether the url passed is a cross domain request or not. 20003 * 20004 * @param {String} url The url to check 20005 * @return {Boolean} Whether it is a cross domain request or not 20006 * @method isCrossOrigin 20007 */
20008videojs.isCrossOrigin = Url.isCrossOrigin; 20009 20010/** 20011 * Event target class. 20012 * 20013 * @type {Function} 20014 */ 20015videojs.EventTarget = _eventTarget2['default']; 20016 20017/** 20018 * Add an event listener to element 20019 * It stores the handler function in a separate cache object 20020 * and adds a generic handler to the element's event, 20021 * along with a unique id (guid) to the element. 20022 * 20023 * @param {Element|Object} elem Element or object to bind listeners to 20024 * @param {String|Array} type Type of event to bind to. 20025 * @param {Function} fn Event listener. 20026 * @method on 20027 */ 20028videojs.on = Events.on; 20029 20030/** 20031 * Trigger a listener only once for an event 20032 * 20033 * @param {Element|Object} elem Element or object to 20034 * @param {String|Array} type Name/type of event 20035 * @param {Function} fn Event handler function 20036 * @method one 20037 */ 20038videojs.one = Events.one; 20039 20040/** 20041 * Removes event listeners from an element 20042 * 20043 * @param {Element|Object} elem Object to remove listeners from 20044 * @param {String|Array=} type Type of listener to remove. Don't include to remove all events from element. 20045 * @param {Function} fn Specific listener to remove. Don't include to remove listeners for an event type. 20046 * @method off 20047 */ 20048videojs.off = Events.off; 20049 20050/** 20051 * Trigger an event for an element 20052 * 20053 * @param {Element|Object} elem Element to trigger an event on 20054 * @param {Event|Object|String} event A string (the type) or an event object with a type attribute 20055 * @param {Object} [hash] data hash to pass along with the event 20056 * @return {Boolean=} Returned only if default was prevented 20057 * @method trigger 20058 */ 20059videojs.trigger = Events.trigger; 20060 20061/** 20062 * A cross-browser XMLHttpRequest wrapper. Here's a simple example: 20063 * 20064 * videojs.xhr({ 20065 * body: someJSONString, 20066 * uri: "/foo", 20067 * headers: { 20068 * "Content-Type": "application/json" 20069 * } 20070 * }, function (err, resp, body) { 20071 * // check resp.statusCode 20072 * }); 20073 * 20074 * Check out the [full 20075 * documentation](https://github.com/Raynos/xhr/blob/v2.1.0/README.md) 20076 * for more options. 20077 * 20078 * @param {Object} options settings for the request. 20079 * @return {XMLHttpRequest|XDomainRequest} the request object. 20080 * @see https://github.com/Raynos/xhr 20081 */ 20082videojs.xhr = _xhr2['default']; 20083 20084/** 20085 * TextTrack class 20086 * 20087 * @type {Function} 20088 */ 20089videojs.TextTrack = _tracksTextTrackJs2['default']; 20090 20091/** 20092 * Determines, via duck typing, whether or not a value is a DOM element. 20093 * 20094 * @method isEl 20095 * @param {Mixed} value 20096 * @return {Boolean} 20097 */ 20098videojs.isEl = Dom.isEl; 20099 20100/** 20101 * Determines, via duck typing, whether or not a value is a text node. 20102 * 20103 * @method isTextNode 20104 * @param {Mixed} value 20105 * @return {Boolean} 20106 */ 20107videojs.isTextNode = Dom.isTextNode; 20108 20109/** 20110 * Creates an element and applies properties. 20111 * 20112 * @method createEl 20113 * @param {String} [tagName='div'] Name of tag to be created. 20114 * @param {Object} [properties={}] Element properties to be applied. 20115 * @param {Object} [attributes={}] Element attributes to be applied. 20116 * @return {Element} 20117 */ 20118videojs.createEl = Dom.createEl; 20119 20120/** 20121 * Check if an element has a CSS class 20122 * 20123 * @method hasClass 20124 * @param {Element} element Element to check 20125 * @param {String} classToCheck Classname to check 20126 */ 20127videojs.hasClass = Dom.hasElClass; 20128 20129/** 20130 * Add a CSS class name to an element 20131 * 20132 * @method addClass 20133 * @param {Element} element Element to add class name to 20134 * @param {String} classToAdd Classname to add 20135 */ 20136videojs.addClass = Dom.addElClass; 20137 20138/** 20139 * Remove a CSS class name from an element 20140 * 20141 * @method removeClass 20142 * @param {Element} element Element to remove from class name 20143 * @param {String} classToRemove Classname to remove 20144 */ 20145videojs.removeClass = Dom.removeElClass; 20146 20147/** 20148 * Adds or removes a CSS class name on an element depending on an optional 20149 * condition or the presence/absence of the class name. 20150 * 20151 * @method toggleElClass 20152 * @param {Element} element 20153 * @param {String} classToToggle 20154 * @param {Boolean|Function} [predicate] 20155 * Can be a function that returns a Boolean. If `true`, the class 20156 * will be added; if `false`, the class will be removed. If not 20157 * given, the class will be added if not present and vice versa. 20158 */ 20159videojs.toggleClass = Dom.toggleElClass; 20160 20161/** 20162 * Apply attributes to an HTML element. 20163 * 20164 * @method setAttributes 20165 * @param {Element} el Target element. 20166 * @param {Object=} attributes Element attributes to be applied. 20167 */ 20168videojs.setAttributes = Dom.setElAttributes; 20169 20170/** 20171 * Get an element's attribute values, as defined on the HTML tag 20172 * Attributes are not the same as properties. They're defined on the tag 20173 * or with setAttribute (which shouldn't be used with HTML) 20174 * This will return true or false for boolean attributes. 20175 * 20176 * @method getAttributes 20177 * @param {Element} tag Element from which to get tag attributes 20178 * @return {Object} 20179 */ 20180videojs.getAttributes = Dom.getElAttributes; 20181 20182/** 20183 * Empties the contents of an element. 20184 * 20185 * @method emptyEl 20186 * @param {Element} el 20187 * @return {Element} 20188 */ 20189videojs.emptyEl = Dom.emptyEl; 20190 20191/** 20192 * Normalizes and appends content to an element. 20193 * 20194 * The content for an element can be passed in multiple types and 20195 * combinations, whose behavior is as follows: 20196 * 20197 * - String 20198 * Normalized into a text node. 20199 * 20200 * - Element, TextNode 20201 * Passed through. 20202 * 20203 * - Array
20204 * A one-dimensional array of strings, elements, nodes, or functions (which 20205 * return single strings, elements, or nodes). 20206 * 20207 * - Function 20208 * If the sole argument, is expected to produce a string, element, 20209 * node, or array. 20210 * 20211 * @method appendContent 20212 * @param {Element} el 20213 * @param {String|Element|TextNode|Array|Function} content 20214 * @return {Element} 20215 */ 20216videojs.appendContent = Dom.appendContent; 20217 20218/** 20219 * Normalizes and inserts content into an element; this is identical to 20220 * `appendContent()`, except it empties the element first. 20221 * 20222 * The content for an element can be passed in multiple types and 20223 * combinations, whose behavior is as follows: 20224 * 20225 * - String 20226 * Normalized into a text node. 20227 * 20228 * - Element, TextNode 20229 * Passed through. 20230 * 20231 * - Array 20232 * A one-dimensional array of strings, elements, nodes, or functions (which 20233 * return single strings, elements, or nodes). 20234 * 20235 * - Function 20236 * If the sole argument, is expected to produce a string, element, 20237 * node, or array. 20238 * 20239 * @method insertContent 20240 * @param {Element} el 20241 * @param {String|Element|TextNode|Array|Function} content 20242 * @return {Element} 20243 */ 20244videojs.insertContent = Dom.insertContent; 20245 20246/* 20247 * Custom Universal Module Definition (UMD) 20248 * 20249 * Video.js will never be a non-browser lib so we can simplify UMD a bunch and 20250 * still support requirejs and browserify. This also needs to be closure 20251 * compiler compatible, so string keys are used. 20252 */ 20253if (typeof define === 'function' && define['amd']) { 20254 define('videojs', [], function () { 20255 return videojs; 20256 }); 20257 20258 // checking that module is an object too because of umdjs/umd#35 20259} else if (typeof exports === 'object' && typeof module === 'object') { 20260 module['exports'] = videojs; 20261 } 20262 20263exports['default'] = videojs; 20264module.exports = exports['default']; 20265 20266},{"../../src/js/utils/merge-options.js":137,"./component":66,"./event-target":98,"./extend.js":99,"./player":107,"./plugins.js":108,"./setup":112,"./tech/flash.js":115,"./tech/html5.js":116,"./tech/tech.js":118,"./tracks/text-track.js":127,"./utils/browser.js":128,"./utils/create-deprecation-proxy.js":130,"./utils/dom.js":131,"./utils/events.js":132,"./utils/fn.js":133,"./utils/format-time.js":134,"./utils/log.js":136,"./utils/stylesheet.js":138,"./utils/time-ranges.js":139,"./utils/url.js":141,"global/document":1,"lodash-compat/object/merge":40,"object.assign":45,"xhr":55}]},{},[142])(142) 20267}); 20268 20269 20270//# sourceMappingURL=video.js.map 20271/* vtt.js - v0.12.1 (https://github.com/mozilla/vtt.js) built on 08-07-2015 */ 20272 20273(function(root) { 20274 var vttjs = root.vttjs = {}; 20275 var cueShim = vttjs.VTTCue; 20276 var regionShim = vttjs.VTTRegion; 20277 var oldVTTCue = root.VTTCue; 20278 var oldVTTRegion = root.VTTRegion; 20279 20280 vttjs.shim = function() { 20281 vttjs.VTTCue = cueShim; 20282 vttjs.VTTRegion = regionShim; 20283 }; 20284 20285 vttjs.restore = function() { 20286 vttjs.VTTCue = oldVTTCue; 20287 vttjs.VTTRegion = oldVTTRegion; 20288 }; 20289}(this)); 20290 20291/** 20292 * Copyright 2013 vtt.js Contributors 20293 * 20294 * Licensed under the Apache License, Version 2.0 (the "License"); 20295 * you may not use this file except in compliance with the License. 20296 * You may obtain a copy of the License at 20297 * 20298 * http://www.apache.org/licenses/LICENSE-2.0 20299 * 20300 * Unless required by applicable law or agreed to in writing, software 20301 * distributed under the License is distributed on an "AS IS" BASIS, 20302 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20303 * See the License for the specific language governing permissions and 20304 * limitations under the License. 20305 */ 20306 20307(function(root, vttjs) { 20308 20309 var autoKeyword = "auto"; 20310 var directionSetting = { 20311 "": true, 20312 "lr": true, 20313 "rl": true 20314 }; 20315 var alignSetting = { 20316 "start": true, 20317 "middle": true, 20318 "end": true, 20319 "left": true, 20320 "right": true 20321 }; 20322 20323 function findDirectionSetting(value) { 20324 if (typeof value !== "string") { 20325 return false; 20326 } 20327 var dir = directionSetting[value.toLowerCase()]; 20328 return dir ? value.toLowerCase() : false; 20329 } 20330 20331 function findAlignSetting(value) { 20332 if (typeof value !== "string") { 20333 return false; 20334 } 20335 var align = alignSetting[value.toLowerCase()]; 20336 return align ? value.toLowerCase() : false;
20337 } 20338 20339 function extend(obj) { 20340 var i = 1; 20341 for (; i < arguments.length; i++) { 20342 var cobj = arguments[i]; 20343 for (var p in cobj) { 20344 obj[p] = cobj[p]; 20345 } 20346 } 20347 20348 return obj; 20349 } 20350 20351 function VTTCue(startTime, endTime, text) { 20352 var cue = this; 20353 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); 20354 var baseObj = {}; 20355 20356 if (isIE8) { 20357 cue = document.createElement('custom'); 20358 } else { 20359 baseObj.enumerable = true; 20360 } 20361 20362 /** 20363 * Shim implementation specific properties. These properties are not in 20364 * the spec. 20365 */ 20366 20367 // Lets us know when the VTTCue's data has changed in such a way that we need 20368 // to recompute its display state. This lets us compute its display state 20369 // lazily. 20370 cue.hasBeenReset = false; 20371 20372 /** 20373 * VTTCue and TextTrackCue properties 20374 * http://dev.w3.org/html5/webvtt/#vttcue-interface 20375 */ 20376 20377 var _id = ""; 20378 var _pauseOnExit = false; 20379 var _startTime = startTime; 20380 var _endTime = endTime; 20381 var _text = text; 20382 var _region = null; 20383 var _vertical = ""; 20384 var _snapToLines = true; 20385 var _line = "auto"; 20386 var _lineAlign = "start"; 20387 var _position = 50; 20388 var _positionAlign = "middle"; 20389 var _size = 50; 20390 var _align = "middle"; 20391 20392 Object.defineProperty(cue, 20393 "id", extend({}, baseObj, { 20394 get: function() { 20395 return _id; 20396 }, 20397 set: function(value) { 20398 _id = "" + value; 20399 } 20400 })); 20401 20402 Object.defineProperty(cue, 20403 "pauseOnExit", extend({}, baseObj, { 20404 get: function() { 20405 return _pauseOnExit; 20406 }, 20407 set: function(value) { 20408 _pauseOnExit = !!value; 20409 } 20410 })); 20411 20412 Object.defineProperty(cue, 20413 "startTime", extend({}, baseObj, { 20414 get: function() { 20415 return _startTime; 20416 }, 20417 set: function(value) { 20418 if (typeof value !== "number") { 20419 throw new TypeError("Start time must be set to a number."); 20420 } 20421 _startTime = value; 20422 this.hasBeenReset = true; 20423 } 20424 })); 20425 20426 Object.defineProperty(cue, 20427 "endTime", extend({}, baseObj, { 20428 get: function() { 20429 return _endTime; 20430 }, 20431 set: function(value) { 20432 if (typeof value !== "number") { 20433 throw new TypeError("End time must be set to a number."); 20434 } 20435 _endTime = value; 20436 this.hasBeenReset = true; 20437 } 20438 })); 20439 20440 Object.defineProperty(cue, 20441 "text", extend({}, baseObj, { 20442 get: function() { 20443 return _text; 20444 }, 20445 set: function(value) { 20446 _text = "" + value; 20447 this.hasBeenReset = true; 20448 } 20449 })); 20450 20451 Object.defineProperty(cue, 20452 "region", extend({}, baseObj, { 20453 get: function() { 20454 return _region; 20455 }, 20456 set: function(value) { 20457 _region = value; 20458 this.hasBeenReset = true; 20459 } 20460 })); 20461 20462 Object.defineProperty(cue, 20463 "vertical", extend({}, baseObj, { 20464 get: function() { 20465 return _vertical; 20466 }, 20467 set: function(value) { 20468 var setting = findDirectionSetting(value); 20469 // Have to check for false because the setting an be an empty string. 20470 if (setting === false) { 20471 throw new SyntaxError("An invalid or illegal string was specified."); 20472 } 20473 _vertical = setting; 20474 this.hasBeenReset = true; 20475 } 20476 })); 20477 20478 Object.defineProperty(cue, 20479 "snapToLines", extend({}, baseObj, { 20480 get: function() { 20481 return _snapToLines; 20482 }, 20483 set: function(value) { 20484 _snapToLines = !!value; 20485 this.hasBeenReset = true; 20486 } 20487 })); 20488 20489 Object.defineProperty(cue, 20490 "line", extend({}, baseObj, { 20491 get: function() { 20492 return _line; 20493 }, 20494 set: function(value) { 20495 if (typeof value !== "number" && value !== autoKeyword) { 20496 throw new SyntaxError("An invalid number or illegal string was specified."); 20497 } 20498 _line = value; 20499 this.hasBeenReset = true; 20500 } 20501 })); 20502 20503 Object.defineProperty(cue, 20504 "lineAlign", extend({}, baseObj, { 20505 get: function() { 20506 return _lineAlign; 20507 }, 20508 set: function(value) {
20509 var setting = findAlignSetting(value); 20510 if (!setting) { 20511 throw new SyntaxError("An invalid or illegal string was specified."); 20512 } 20513 _lineAlign = setting; 20514 this.hasBeenReset = true; 20515 } 20516 })); 20517 20518 Object.defineProperty(cue, 20519 "position", extend({}, baseObj, { 20520 get: function() { 20521 return _position; 20522 }, 20523 set: function(value) { 20524 if (value < 0 || value > 100) { 20525 throw new Error("Position must be between 0 and 100."); 20526 } 20527 _position = value; 20528 this.hasBeenReset = true; 20529 } 20530 })); 20531 20532 Object.defineProperty(cue, 20533 "positionAlign", extend({}, baseObj, { 20534 get: function() { 20535 return _positionAlign; 20536 }, 20537 set: function(value) { 20538 var setting = findAlignSetting(value); 20539 if (!setting) { 20540 throw new SyntaxError("An invalid or illegal string was specified."); 20541 } 20542 _positionAlign = setting; 20543 this.hasBeenReset = true; 20544 } 20545 })); 20546 20547 Object.defineProperty(cue, 20548 "size", extend({}, baseObj, { 20549 get: function() { 20550 return _size; 20551 }, 20552 set: function(value) { 20553 if (value < 0 || value > 100) { 20554 throw new Error("Size must be between 0 and 100."); 20555 } 20556 _size = value; 20557 this.hasBeenReset = true; 20558 } 20559 })); 20560 20561 Object.defineProperty(cue, 20562 "align", extend({}, baseObj, { 20563 get: function() { 20564 return _align; 20565 }, 20566 set: function(value) { 20567 var setting = findAlignSetting(value); 20568 if (!setting) { 20569 throw new SyntaxError("An invalid or illegal string was specified."); 20570 } 20571 _align = setting; 20572 this.hasBeenReset = true; 20573 } 20574 })); 20575 20576 /** 20577 * Other <track> spec defined properties 20578 */ 20579 20580 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state 20581 cue.displayState = undefined; 20582 20583 if (isIE8) { 20584 return cue; 20585 } 20586 } 20587 20588 /** 20589 * VTTCue methods 20590 */ 20591 20592 VTTCue.prototype.getCueAsHTML = function() { 20593 // Assume WebVTT.convertCueToDOMTree is on the global. 20594 return WebVTT.convertCueToDOMTree(window, this.text); 20595 }; 20596 20597 root.VTTCue = root.VTTCue || VTTCue; 20598 vttjs.VTTCue = VTTCue; 20599}(this, (this.vttjs || {}))); 20600 20601/** 20602 * Copyright 2013 vtt.js Contributors 20603 * 20604 * Licensed under the Apache License, Version 2.0 (the "License"); 20605 * you may not use this file except in compliance with the License. 20606 * You may obtain a copy of the License at 20607 * 20608 * http://www.apache.org/licenses/LICENSE-2.0 20609 * 20610 * Unless required by applicable law or agreed to in writing, software 20611 * distributed under the License is distributed on an "AS IS" BASIS, 20612 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20613 * See the License for the specific language governing permissions and 20614 * limitations under the License. 20615 */ 20616 20617(function(root, vttjs) { 20618 20619 var scrollSetting = { 20620 "": true, 20621 "up": true 20622 }; 20623 20624 function findScrollSetting(value) { 20625 if (typeof value !== "string") { 20626 return false; 20627 } 20628 var scroll = scrollSetting[value.toLowerCase()]; 20629 return scroll ? value.toLowerCase() : false; 20630 } 20631 20632 function isValidPercentValue(value) { 20633 return typeof value === "number" && (value >= 0 && value <= 100); 20634 } 20635 20636 // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface 20637 function VTTRegion() { 20638 var _width = 100; 20639 var _lines = 3; 20640 var _regionAnchorX = 0; 20641 var _regionAnchorY = 100; 20642 var _viewportAnchorX = 0; 20643 var _viewportAnchorY = 100; 20644 var _scroll = ""; 20645 20646 Object.defineProperties(this, { 20647 "width": { 20648 enumerable: true, 20649 get: function() { 20650 return _width; 20651 }, 20652 set: function(value) { 20653 if (!isValidPercentValue(value)) { 20654 throw new Error("Width must be between 0 and 100."); 20655 } 20656 _width = value; 20657 } 20658 }, 20659 "lines": { 20660 enumerable: true, 20661 get: function() { 20662 return _lines; 20663 }, 20664 set: function(value) {
vendor: 16,471 bytes, lines 20665-21169
20665 if (typeof value !== "number") { 20666 throw new TypeError("Lines must be set to a number."); 20667 } 20668 _lines = value; 20669 } 20670 }, 20671 "regionAnchorY": { 20672 enumerable: true, 20673 get: function() { 20674 return _regionAnchorY; 20675 }, 20676 set: function(value) { 20677 if (!isValidPercentValue(value)) { 20678 throw new Error("RegionAnchorX must be between 0 and 100."); 20679 } 20680 _regionAnchorY = value; 20681 } 20682 }, 20683 "regionAnchorX": { 20684 enumerable: true, 20685 get: function() { 20686 return _regionAnchorX; 20687 }, 20688 set: function(value) { 20689 if(!isValidPercentValue(value)) { 20690 throw new Error("RegionAnchorY must be between 0 and 100."); 20691 } 20692 _regionAnchorX = value; 20693 } 20694 }, 20695 "viewportAnchorY": { 20696 enumerable: true, 20697 get: function() { 20698 return _viewportAnchorY; 20699 }, 20700 set: function(value) { 20701 if (!isValidPercentValue(value)) { 20702 throw new Error("ViewportAnchorY must be between 0 and 100."); 20703 } 20704 _viewportAnchorY = value; 20705 } 20706 }, 20707 "viewportAnchorX": { 20708 enumerable: true, 20709 get: function() { 20710 return _viewportAnchorX; 20711 }, 20712 set: function(value) { 20713 if (!isValidPercentValue(value)) { 20714 throw new Error("ViewportAnchorX must be between 0 and 100."); 20715 } 20716 _viewportAnchorX = value; 20717 } 20718 }, 20719 "scroll": { 20720 enumerable: true, 20721 get: function() { 20722 return _scroll; 20723 }, 20724 set: function(value) { 20725 var setting = findScrollSetting(value); 20726 // Have to check for false as an empty string is a legal value. 20727 if (setting === false) { 20728 throw new SyntaxError("An invalid or illegal string was specified."); 20729 } 20730 _scroll = setting; 20731 } 20732 } 20733 }); 20734 } 20735 20736 root.VTTRegion = root.VTTRegion || VTTRegion; 20737 vttjs.VTTRegion = VTTRegion; 20738}(this, (this.vttjs || {}))); 20739 20740/** 20741 * Copyright 2013 vtt.js Contributors 20742 * 20743 * Licensed under the Apache License, Version 2.0 (the "License"); 20744 * you may not use this file except in compliance with the License. 20745 * You may obtain a copy of the License at 20746 * 20747 * http://www.apache.org/licenses/LICENSE-2.0 20748 * 20749 * Unless required by applicable law or agreed to in writing, software 20750 * distributed under the License is distributed on an "AS IS" BASIS, 20751 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20752 * See the License for the specific language governing permissions and 20753 * limitations under the License. 20754 */ 20755 20756/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 20757/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 20758 20759(function(global) { 20760 20761 var _objCreate = Object.create || (function() { 20762 function F() {} 20763 return function(o) { 20764 if (arguments.length !== 1) { 20765 throw new Error('Object.create shim only accepts one parameter.'); 20766 } 20767 F.prototype = o; 20768 return new F(); 20769 }; 20770 })(); 20771 20772 // Creates a new ParserError object from an errorData object. The errorData 20773 // object should have default code and message properties. The default message 20774 // property can be overriden by passing in a message parameter. 20775 // See ParsingError.Errors below for acceptable errors. 20776 function ParsingError(errorData, message) { 20777 this.name = "ParsingError"; 20778 this.code = errorData.code; 20779 this.message = message || errorData.message; 20780 } 20781 ParsingError.prototype = _objCreate(Error.prototype); 20782 ParsingError.prototype.constructor = ParsingError; 20783 20784 // ParsingError metadata for acceptable ParsingErrors. 20785 ParsingError.Errors = { 20786 BadSignature: { 20787 code: 0, 20788 message: "Malformed WebVTT signature." 20789 }, 20790 BadTimeStamp: { 20791 code: 1, 20792 message: "Malformed time stamp." 20793 } 20794 }; 20795 20796 // Try to parse input as a time stamp. 20797 function parseTimeStamp(input) { 20798 20799 function computeSeconds(h, m, s, f) { 20800 return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000; 20801 } 20802 20803 var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/); 20804 if (!m) { 20805 return null; 20806 } 20807 20808 if (m[3]) { 20809 // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds] 20810 return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]); 20811 } else if (m[1] > 59) { 20812 // Timestamp takes the form of [hours]:[minutes].[milliseconds] 20813 // First position is hours as it's over 59. 20814 return computeSeconds(m[1], m[2], 0, m[4]); 20815 } else { 20816 // Timestamp takes the form of [minutes]:[seconds].[milliseconds] 20817 return computeSeconds(0, m[1], m[2], m[4]); 20818 } 20819 } 20820 20821 // A settings object holds key/value pairs and will ignore anything but the first 20822 // assignment to a specific key. 20823 function Settings() { 20824 this.values = _objCreate(null); 20825 } 20826 20827 Settings.prototype = { 20828 // Only accept the first assignment to any key. 20829 set: function(k, v) { 20830 if (!this.get(k) && v !== "") { 20831 this.values[k] = v; 20832 } 20833 }, 20834 // Return the value for a key, or a default value. 20835 // If 'defaultKey' is passed then 'dflt' is assumed to be an object with 20836 // a number of possible default values as properties where 'defaultKey' is 20837 // the key of the property that will be chosen; otherwise it's assumed to be 20838 // a single value. 20839 get: function(k, dflt, defaultKey) { 20840 if (defaultKey) { 20841 return this.has(k) ? this.values[k] : dflt[defaultKey]; 20842 } 20843 return this.has(k) ? this.values[k] : dflt; 20844 }, 20845 // Check whether we have a value for a key. 20846 has: function(k) { 20847 return k in this.values; 20848 }, 20849 // Accept a setting if its one of the given alternatives. 20850 alt: function(k, v, a) { 20851 for (var n = 0; n < a.length; ++n) { 20852 if (v === a[n]) { 20853 this.set(k, v); 20854 break; 20855 } 20856 } 20857 }, 20858 // Accept a setting if its a valid (signed) integer. 20859 integer: function(k, v) { 20860 if (/^-?\d+$/.test(v)) { // integer 20861 this.set(k, parseInt(v, 10)); 20862 } 20863 }, 20864 // Accept a setting if its a valid percentage. 20865 percent: function(k, v) { 20866 var m; 20867 if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) { 20868 v = parseFloat(v); 20869 if (v >= 0 && v <= 100) { 20870 this.set(k, v); 20871 return true; 20872 } 20873 } 20874 return false; 20875 } 20876 }; 20877 20878 // Helper function to parse input into groups separated by 'groupDelim', and 20879 // interprete each group as a key/value pair separated by 'keyValueDelim'. 20880 function parseOptions(input, callback, keyValueDelim, groupDelim) { 20881 var groups = groupDelim ? input.split(groupDelim) : [input]; 20882 for (var i in groups) { 20883 if (typeof groups[i] !== "string") { 20884 continue; 20885 } 20886 var kv = groups[i].split(keyValueDelim); 20887 if (kv.length !== 2) { 20888 continue; 20889 } 20890 var k = kv[0]; 20891 var v = kv[1]; 20892 callback(k, v); 20893 } 20894 } 20895 20896 function parseCue(input, cue, regionList) { 20897 // Remember the original input if we need to throw an error. 20898 var oInput = input; 20899 // 4.1 WebVTT timestamp 20900 function consumeTimeStamp() { 20901 var ts = parseTimeStamp(input); 20902 if (ts === null) { 20903 throw new ParsingError(ParsingError.Errors.BadTimeStamp, 20904 "Malformed timestamp: " + oInput); 20905 } 20906 // Remove time stamp from input. 20907 input = input.replace(/^[^\sa-zA-Z-]+/, ""); 20908 return ts; 20909 } 20910 20911 // 4.4.2 WebVTT cue settings 20912 function consumeCueSettings(input, cue) { 20913 var settings = new Settings(); 20914 20915 parseOptions(input, function (k, v) { 20916 switch (k) { 20917 case "region": 20918 // Find the last region we parsed with the same region id. 20919 for (var i = regionList.length - 1; i >= 0; i--) { 20920 if (regionList[i].id === v) { 20921 settings.set(k, regionList[i].region); 20922 break; 20923 } 20924 } 20925 break; 20926 case "vertical": 20927 settings.alt(k, v, ["rl", "lr"]); 20928 break; 20929 case "line": 20930 var vals = v.split(","), 20931 vals0 = vals[0]; 20932 settings.integer(k, vals0); 20933 settings.percent(k, vals0) ? settings.set("snapToLines", false) : null; 20934 settings.alt(k, vals0, ["auto"]); 20935 if (vals.length === 2) { 20936 settings.alt("lineAlign", vals[1], ["start", "middle", "end"]); 20937 } 20938 break; 20939 case "position": 20940 vals = v.split(","); 20941 settings.percent(k, vals[0]); 20942 if (vals.length === 2) { 20943 settings.alt("positionAlign", vals[1], ["start", "middle", "end"]); 20944 } 20945 break; 20946 case "size": 20947 settings.percent(k, v); 20948 break; 20949 case "align": 20950 settings.alt(k, v, ["start", "middle", "end", "left", "right"]); 20951 break; 20952 } 20953 }, /:/, /\s/); 20954 20955 // Apply default values for any missing fields. 20956 cue.region = settings.get("region", null); 20957 cue.vertical = settings.get("vertical", ""); 20958 cue.line = settings.get("line", "auto"); 20959 cue.lineAlign = settings.get("lineAlign", "start"); 20960 cue.snapToLines = settings.get("snapToLines", true); 20961 cue.size = settings.get("size", 100); 20962 cue.align = settings.get("align", "middle"); 20963 cue.position = settings.get("position", { 20964 start: 0, 20965 left: 0, 20966 middle: 50, 20967 end: 100, 20968 right: 100 20969 }, cue.align); 20970 cue.positionAlign = settings.get("positionAlign", { 20971 start: "start", 20972 left: "start", 20973 middle: "middle", 20974 end: "end", 20975 right: "end" 20976 }, cue.align); 20977 } 20978 20979 function skipWhitespace() { 20980 input = input.replace(/^\s+/, ""); 20981 } 20982 20983 // 4.1 WebVTT cue timings. 20984 skipWhitespace(); 20985 cue.startTime = consumeTimeStamp(); // (1) collect cue start time 20986 skipWhitespace(); 20987 if (input.substr(0, 3) !== "-->") { // (3) next characters must match "-->" 20988 throw new ParsingError(ParsingError.Errors.BadTimeStamp, 20989 "Malformed time stamp (time stamps must be separated by '-->'): " + 20990 oInput); 20991 } 20992 input = input.substr(3); 20993 skipWhitespace(); 20994 cue.endTime = consumeTimeStamp(); // (5) collect cue end time 20995 20996 // 4.1 WebVTT cue settings list. 20997 skipWhitespace(); 20998 consumeCueSettings(input, cue); 20999 } 21000 21001 var ESCAPE = { 21002 "&": "&", 21003 "<": "<", 21004 ">": ">", 21005 "‎": "\u200e", 21006 "‏": "\u200f", 21007 " ": "\u00a0" 21008 }; 21009 21010 var TAG_NAME = { 21011 c: "span", 21012 i: "i", 21013 b: "b", 21014 u: "u", 21015 ruby: "ruby", 21016 rt: "rt", 21017 v: "span", 21018 lang: "span" 21019 }; 21020 21021 var TAG_ANNOTATION = { 21022 v: "title", 21023 lang: "lang" 21024 }; 21025 21026 var NEEDS_PARENT = { 21027 rt: "ruby" 21028 }; 21029 21030 // Parse content into a document fragment. 21031 function parseContent(window, input) { 21032 function nextToken() { 21033 // Check for end-of-string. 21034 if (!input) { 21035 return null; 21036 } 21037 21038 // Consume 'n' characters from the input. 21039 function consume(result) { 21040 input = input.substr(result.length); 21041 return result; 21042 } 21043 21044 var m = input.match(/^([^<]*)(<[^>]+>?)?/); 21045 // If there is some text before the next tag, return it, otherwise return 21046 // the tag. 21047 return consume(m[1] ? m[1] : m[2]); 21048 } 21049 21050 // Unescape a string 's'. 21051 function unescape1(e) { 21052 return ESCAPE[e]; 21053 } 21054 function unescape(s) { 21055 while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) { 21056 s = s.replace(m[0], unescape1); 21057 } 21058 return s; 21059 } 21060 21061 function shouldAdd(current, element) { 21062 return !NEEDS_PARENT[element.localName] || 21063 NEEDS_PARENT[element.localName] === current.localName; 21064 } 21065 21066 // Create an element for this tag. 21067 function createElement(type, annotation) { 21068 var tagName = TAG_NAME[type]; 21069 if (!tagName) { 21070 return null; 21071 } 21072 var element = window.document.createElement(tagName); 21073 element.localName = tagName; 21074 var name = TAG_ANNOTATION[type]; 21075 if (name && annotation) { 21076 element[name] = annotation.trim(); 21077 } 21078 return element; 21079 } 21080 21081 var rootDiv = window.document.createElement("div"), 21082 current = rootDiv, 21083 t, 21084 tagStack = []; 21085 21086 while ((t = nextToken()) !== null) { 21087 if (t[0] === '<') { 21088 if (t[1] === "/") { 21089 // If the closing tag matches, move back up to the parent node. 21090 if (tagStack.length && 21091 tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) { 21092 tagStack.pop(); 21093 current = current.parentNode; 21094 } 21095 // Otherwise just ignore the end tag. 21096 continue; 21097 } 21098 var ts = parseTimeStamp(t.substr(1, t.length - 2)); 21099 var node; 21100 if (ts) { 21101 // Timestamps are lead nodes as well. 21102 node = window.document.createProcessingInstruction("timestamp", ts); 21103 current.appendChild(node); 21104 continue; 21105 } 21106 var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/); 21107 // If we can't parse the tag, skip to the next tag. 21108 if (!m) { 21109 continue; 21110 } 21111 // Try to construct an element, and ignore the tag if we couldn't. 21112 node = createElement(m[1], m[3]); 21113 if (!node) { 21114 continue; 21115 } 21116 // Determine if the tag should be added based on the context of where it 21117 // is placed in the cuetext. 21118 if (!shouldAdd(current, node)) { 21119 continue; 21120 } 21121 // Set the class list (as a list of classes, separated by space). 21122 if (m[2]) { 21123 node.className = m[2].substr(1).replace('.', ' '); 21124 } 21125 // Append the node to the current node, and enter the scope of the new 21126 // node. 21127 tagStack.push(m[1]); 21128 current.appendChild(node); 21129 current = node; 21130 continue; 21131 } 21132 21133 // Text nodes are leaf nodes. 21134 current.appendChild(window.document.createTextNode(unescape(t))); 21135 } 21136 21137 return rootDiv; 21138 } 21139 21140 // This is a list of all the Unicode characters that have a strong 21141 // right-to-left category. What this means is that these characters are 21142 // written right-to-left for sure. It was generated by pulling all the strong 21143 // right-to-left characters out of the Unicode data table. That table can 21144 // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt 21145 var strongRTLChars = [0x05BE, 0x05C0, 0x05C3, 0x05C6, 0x05D0, 0x05D1, 21146 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 21147 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 21148 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x05F0, 0x05F1, 21149 0x05F2, 0x05F3, 0x05F4, 0x0608, 0x060B, 0x060D, 0x061B, 0x061E, 0x061F, 21150 0x0620, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 21151 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 21152 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 21153 0x063B, 0x063C, 0x063D, 0x063E, 0x063F, 0x0640, 0x0641, 0x0642, 0x0643, 21154 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x066D, 0x066E, 21155 0x066F, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0x0677, 0x0678, 21156 0x0679, 0x067A, 0x067B, 0x067C, 0x067D, 0x067E, 0x067F, 0x0680, 0x0681, 21157 0x0682, 0x0683, 0x0684, 0x0685, 0x0686, 0x0687, 0x0688, 0x0689, 0x068A, 21158 0x068B, 0x068C, 0x068D, 0x068E, 0x068F, 0x0690, 0x0691, 0x0692, 0x0693, 21159 0x0694, 0x0695, 0x0696, 0x0697, 0x0698, 0x0699, 0x069A, 0x069B, 0x069C, 21160 0x069D, 0x069E, 0x069F, 0x06A0, 0x06A1, 0x06A2, 0x06A3, 0x06A4, 0x06A5, 21161 0x06A6, 0x06A7, 0x06A8, 0x06A9, 0x06AA, 0x06AB, 0x06AC, 0x06AD, 0x06AE, 21162 0x06AF, 0x06B0, 0x06B1, 0x06B2, 0x06B3, 0x06B4, 0x06B5, 0x06B6, 0x06B7, 21163 0x06B8, 0x06B9, 0x06BA, 0x06BB, 0x06BC, 0x06BD, 0x06BE, 0x06BF, 0x06C0, 21164 0x06C1, 0x06C2, 0x06C3, 0x06C4, 0x06C5, 0x06C6, 0x06C7, 0x06C8, 0x06C9, 21165 0x06CA, 0x06CB, 0x06CC, 0x06CD, 0x06CE, 0x06CF, 0x06D0, 0x06D1, 0x06D2, 21166 0x06D3, 0x06D4, 0x06D5, 0x06E5, 0x06E6, 0x06EE, 0x06EF, 0x06FA, 0x06FB, 21167 0x06FC, 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, 0x0703, 0x0704, 21168 0x0705, 0x0706, 0x0707, 0x0708, 0x0709, 0x070A, 0x070B, 0x070C, 0x070D, 21169 0x070F, 0x0710, 0x0712, 0x0713, 0x0714, 0x0715, 0x0716, 0x0717, 0x0718,
21170 0x0719, 0x071A, 0x071B, 0x071C, 0x071D, 0x071E, 0x071F, 0x0720, 0x0721, 21171 0x0722, 0x0723, 0x0724, 0x0725, 0x0726, 0x0727, 0x0728, 0x0729, 0x072A, 21172 0x072B, 0x072C, 0x072D, 0x072E, 0x072F, 0x074D, 0x074E, 0x074F, 0x0750, 21173 0x0751, 0x0752, 0x0753, 0x0754, 0x0755, 0x0756, 0x0757, 0x0758, 0x0759, 21174 0x075A, 0x075B, 0x075C, 0x075D, 0x075E, 0x075F, 0x0760, 0x0761, 0x0762, 21175 0x0763, 0x0764, 0x0765, 0x0766, 0x0767, 0x0768, 0x0769, 0x076A, 0x076B, 21176 0x076C, 0x076D, 0x076E, 0x076F, 0x0770, 0x0771, 0x0772, 0x0773, 0x0774, 21177 0x0775, 0x0776, 0x0777, 0x0778, 0x0779, 0x077A, 0x077B, 0x077C, 0x077D, 21178 0x077E, 0x077F, 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0786, 21179 0x0787, 0x0788, 0x0789, 0x078A, 0x078B, 0x078C, 0x078D, 0x078E, 0x078F, 21180 0x0790, 0x0791, 0x0792, 0x0793, 0x0794, 0x0795, 0x0796, 0x0797, 0x0798, 21181 0x0799, 0x079A, 0x079B, 0x079C, 0x079D, 0x079E, 0x079F, 0x07A0, 0x07A1, 21182 0x07A2, 0x07A3, 0x07A4, 0x07A5, 0x07B1, 0x07C0, 0x07C1, 0x07C2, 0x07C3, 21183 0x07C4, 0x07C5, 0x07C6, 0x07C7, 0x07C8, 0x07C9, 0x07CA, 0x07CB, 0x07CC, 21184 0x07CD, 0x07CE, 0x07CF, 0x07D0, 0x07D1, 0x07D2, 0x07D3, 0x07D4, 0x07D5, 21185 0x07D6, 0x07D7, 0x07D8, 0x07D9, 0x07DA, 0x07DB, 0x07DC, 0x07DD, 0x07DE, 21186 0x07DF, 0x07E0, 0x07E1, 0x07E2, 0x07E3, 0x07E4, 0x07E5, 0x07E6, 0x07E7, 21187 0x07E8, 0x07E9, 0x07EA, 0x07F4, 0x07F5, 0x07FA, 0x0800, 0x0801, 0x0802, 21188 0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809, 0x080A, 0x080B, 21189 0x080C, 0x080D, 0x080E, 0x080F, 0x0810, 0x0811, 0x0812, 0x0813, 0x0814, 21190 0x0815, 0x081A, 0x0824, 0x0828, 0x0830, 0x0831, 0x0832, 0x0833, 0x0834, 21191 0x0835, 0x0836, 0x0837, 0x0838, 0x0839, 0x083A, 0x083B, 0x083C, 0x083D, 21192 0x083E, 0x0840, 0x0841, 0x0842, 0x0843, 0x0844, 0x0845, 0x0846, 0x0847, 21193 0x0848, 0x0849, 0x084A, 0x084B, 0x084C, 0x084D, 0x084E, 0x084F, 0x0850, 21194 0x0851, 0x0852, 0x0853, 0x0854, 0x0855, 0x0856, 0x0857, 0x0858, 0x085E, 21195 0x08A0, 0x08A2, 0x08A3, 0x08A4, 0x08A5, 0x08A6, 0x08A7, 0x08A8, 0x08A9, 21196 0x08AA, 0x08AB, 0x08AC, 0x200F, 0xFB1D, 0xFB1F, 0xFB20, 0xFB21, 0xFB22, 21197 0xFB23, 0xFB24, 0xFB25, 0xFB26, 0xFB27, 0xFB28, 0xFB2A, 0xFB2B, 0xFB2C, 21198 0xFB2D, 0xFB2E, 0xFB2F, 0xFB30, 0xFB31, 0xFB32, 0xFB33, 0xFB34, 0xFB35, 21199 0xFB36, 0xFB38, 0xFB39, 0xFB3A, 0xFB3B, 0xFB3C, 0xFB3E, 0xFB40, 0xFB41, 21200 0xFB43, 0xFB44, 0xFB46, 0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C, 21201 0xFB4D, 0xFB4E, 0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54, 0xFB55,
21202 0xFB56, 0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B, 0xFB5C, 0xFB5D, 0xFB5E, 21203 0xFB5F, 0xFB60, 0xFB61, 0xFB62, 0xFB63, 0xFB64, 0xFB65, 0xFB66, 0xFB67, 21204 0xFB68, 0xFB69, 0xFB6A, 0xFB6B, 0xFB6C, 0xFB6D, 0xFB6E, 0xFB6F, 0xFB70, 21205 0xFB71, 0xFB72, 0xFB73, 0xFB74, 0xFB75, 0xFB76, 0xFB77, 0xFB78, 0xFB79, 21206 0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D, 0xFB7E, 0xFB7F, 0xFB80, 0xFB81, 0xFB82, 21207 0xFB83, 0xFB84, 0xFB85, 0xFB86, 0xFB87, 0xFB88, 0xFB89, 0xFB8A, 0xFB8B, 21208 0xFB8C, 0xFB8D, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91, 0xFB92, 0xFB93, 0xFB94, 21209 0xFB95, 0xFB96, 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B, 0xFB9C, 0xFB9D, 21210 0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3, 0xFBA4, 0xFBA5, 0xFBA6, 21211 0xFBA7, 0xFBA8, 0xFBA9, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD, 0xFBAE, 0xFBAF, 21212 0xFBB0, 0xFBB1, 0xFBB2, 0xFBB3, 0xFBB4, 0xFBB5, 0xFBB6, 0xFBB7, 0xFBB8, 21213 0xFBB9, 0xFBBA, 0xFBBB, 0xFBBC, 0xFBBD, 0xFBBE, 0xFBBF, 0xFBC0, 0xFBC1, 21214 0xFBD3, 0xFBD4, 0xFBD5, 0xFBD6, 0xFBD7, 0xFBD8, 0xFBD9, 0xFBDA, 0xFBDB, 21215 0xFBDC, 0xFBDD, 0xFBDE, 0xFBDF, 0xFBE0, 0xFBE1, 0xFBE2, 0xFBE3, 0xFBE4, 21216 0xFBE5, 0xFBE6, 0xFBE7, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEB, 0xFBEC, 0xFBED, 21217 0xFBEE, 0xFBEF, 0xFBF0, 0xFBF1, 0xFBF2, 0xFBF3, 0xFBF4, 0xFBF5, 0xFBF6, 21218 0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF, 21219 0xFC00, 0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08, 21220 0xFC09, 0xFC0A, 0xFC0B, 0xFC0C, 0xFC0D, 0xFC0E, 0xFC0F, 0xFC10, 0xFC11, 21221 0xFC12, 0xFC13, 0xFC14, 0xFC15, 0xFC16, 0xFC17, 0xFC18, 0xFC19, 0xFC1A, 21222 0xFC1B, 0xFC1C, 0xFC1D, 0xFC1E, 0xFC1F, 0xFC20, 0xFC21, 0xFC22, 0xFC23, 21223 0xFC24, 0xFC25, 0xFC26, 0xFC27, 0xFC28, 0xFC29, 0xFC2A, 0xFC2B, 0xFC2C, 21224 0xFC2D, 0xFC2E, 0xFC2F, 0xFC30, 0xFC31, 0xFC32, 0xFC33, 0xFC34, 0xFC35, 21225 0xFC36, 0xFC37, 0xFC38, 0xFC39, 0xFC3A, 0xFC3B, 0xFC3C, 0xFC3D, 0xFC3E, 21226 0xFC3F, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44, 0xFC45, 0xFC46, 0xFC47, 21227 0xFC48, 0xFC49, 0xFC4A, 0xFC4B, 0xFC4C, 0xFC4D, 0xFC4E, 0xFC4F, 0xFC50,
21228 0xFC51, 0xFC52, 0xFC53, 0xFC54, 0xFC55, 0xFC56, 0xFC57, 0xFC58, 0xFC59, 21229 0xFC5A, 0xFC5B, 0xFC5C, 0xFC5D, 0xFC5E, 0xFC5F, 0xFC60, 0xFC61, 0xFC62, 21230 0xFC63, 0xFC64, 0xFC65, 0xFC66, 0xFC67, 0xFC68, 0xFC69, 0xFC6A, 0xFC6B, 21231 0xFC6C, 0xFC6D, 0xFC6E, 0xFC6F, 0xFC70, 0xFC71, 0xFC72, 0xFC73, 0xFC74, 21232 0xFC75, 0xFC76, 0xFC77, 0xFC78, 0xFC79, 0xFC7A, 0xFC7B, 0xFC7C, 0xFC7D, 21233 0xFC7E, 0xFC7F, 0xFC80, 0xFC81, 0xFC82, 0xFC83, 0xFC84, 0xFC85, 0xFC86, 21234 0xFC87, 0xFC88, 0xFC89, 0xFC8A, 0xFC8B, 0xFC8C, 0xFC8D, 0xFC8E, 0xFC8F, 21235 0xFC90, 0xFC91, 0xFC92, 0xFC93, 0xFC94, 0xFC95, 0xFC96, 0xFC97, 0xFC98, 21236 0xFC99, 0xFC9A, 0xFC9B, 0xFC9C, 0xFC9D, 0xFC9E, 0xFC9F, 0xFCA0, 0xFCA1, 21237 0xFCA2, 0xFCA3, 0xFCA4, 0xFCA5, 0xFCA6, 0xFCA7, 0xFCA8, 0xFCA9, 0xFCAA, 21238 0xFCAB, 0xFCAC, 0xFCAD, 0xFCAE, 0xFCAF, 0xFCB0, 0xFCB1, 0xFCB2, 0xFCB3, 21239 0xFCB4, 0xFCB5, 0xFCB6, 0xFCB7, 0xFCB8, 0xFCB9, 0xFCBA, 0xFCBB, 0xFCBC, 21240 0xFCBD, 0xFCBE, 0xFCBF, 0xFCC0, 0xFCC1, 0xFCC2, 0xFCC3, 0xFCC4, 0xFCC5, 21241 0xFCC6, 0xFCC7, 0xFCC8, 0xFCC9, 0xFCCA, 0xFCCB, 0xFCCC, 0xFCCD, 0xFCCE, 21242 0xFCCF, 0xFCD0, 0xFCD1, 0xFCD2, 0xFCD3, 0xFCD4, 0xFCD5, 0xFCD6, 0xFCD7, 21243 0xFCD8, 0xFCD9, 0xFCDA, 0xFCDB, 0xFCDC, 0xFCDD, 0xFCDE, 0xFCDF, 0xFCE0, 21244 0xFCE1, 0xFCE2, 0xFCE3, 0xFCE4, 0xFCE5, 0xFCE6, 0xFCE7, 0xFCE8, 0xFCE9, 21245 0xFCEA, 0xFCEB, 0xFCEC, 0xFCED, 0xFCEE, 0xFCEF, 0xFCF0, 0xFCF1, 0xFCF2, 21246 0xFCF3, 0xFCF4, 0xFCF5, 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, 0xFCFA, 0xFCFB, 21247 0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04, 21248 0xFD05, 0xFD06, 0xFD07, 0xFD08, 0xFD09, 0xFD0A, 0xFD0B, 0xFD0C, 0xFD0D, 21249 0xFD0E, 0xFD0F, 0xFD10, 0xFD11, 0xFD12, 0xFD13, 0xFD14, 0xFD15, 0xFD16, 21250 0xFD17, 0xFD18, 0xFD19, 0xFD1A, 0xFD1B, 0xFD1C, 0xFD1D, 0xFD1E, 0xFD1F, 21251 0xFD20, 0xFD21, 0xFD22, 0xFD23, 0xFD24, 0xFD25, 0xFD26, 0xFD27, 0xFD28, 21252 0xFD29, 0xFD2A, 0xFD2B, 0xFD2C, 0xFD2D, 0xFD2E, 0xFD2F, 0xFD30, 0xFD31, 21253 0xFD32, 0xFD33, 0xFD34, 0xFD35, 0xFD36, 0xFD37, 0xFD38, 0xFD39, 0xFD3A, 21254 0xFD3B, 0xFD3C, 0xFD3D, 0xFD50, 0xFD51, 0xFD52, 0xFD53, 0xFD54, 0xFD55, 21255 0xFD56, 0xFD57, 0xFD58, 0xFD59, 0xFD5A, 0xFD5B, 0xFD5C, 0xFD5D, 0xFD5E, 21256 0xFD5F, 0xFD60, 0xFD61, 0xFD62, 0xFD63, 0xFD64, 0xFD65, 0xFD66, 0xFD67, 21257 0xFD68, 0xFD69, 0xFD6A, 0xFD6B, 0xFD6C, 0xFD6D, 0xFD6E, 0xFD6F, 0xFD70, 21258 0xFD71, 0xFD72, 0xFD73, 0xFD74, 0xFD75, 0xFD76, 0xFD77, 0xFD78, 0xFD79, 21259 0xFD7A, 0xFD7B, 0xFD7C, 0xFD7D, 0xFD7E, 0xFD7F, 0xFD80, 0xFD81, 0xFD82, 21260 0xFD83, 0xFD84, 0xFD85, 0xFD86, 0xFD87, 0xFD88, 0xFD89, 0xFD8A, 0xFD8B, 21261 0xFD8C, 0xFD8D, 0xFD8E, 0xFD8F, 0xFD92, 0xFD93, 0xFD94, 0xFD95, 0xFD96, 21262 0xFD97, 0xFD98, 0xFD99, 0xFD9A, 0xFD9B, 0xFD9C, 0xFD9D, 0xFD9E, 0xFD9F, 21263 0xFDA0, 0xFDA1, 0xFDA2, 0xFDA3, 0xFDA4, 0xFDA5, 0xFDA6, 0xFDA7, 0xFDA8, 21264 0xFDA9, 0xFDAA, 0xFDAB, 0xFDAC, 0xFDAD, 0xFDAE, 0xFDAF, 0xFDB0, 0xFDB1, 21265 0xFDB2, 0xFDB3, 0xFDB4, 0xFDB5, 0xFDB6, 0xFDB7, 0xFDB8, 0xFDB9, 0xFDBA, 21266 0xFDBB, 0xFDBC, 0xFDBD, 0xFDBE, 0xFDBF, 0xFDC0, 0xFDC1, 0xFDC2, 0xFDC3, 21267 0xFDC4, 0xFDC5, 0xFDC6, 0xFDC7, 0xFDF0, 0xFDF1, 0xFDF2, 0xFDF3, 0xFDF4, 21268 0xFDF5, 0xFDF6, 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, 0xFE70, 21269 0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE76, 0xFE77, 0xFE78, 0xFE79, 0xFE7A, 21270 0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F, 0xFE80, 0xFE81, 0xFE82, 0xFE83, 21271 0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C, 21272 0xFE8D, 0xFE8E, 0xFE8F, 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95, 21273 0xFE96, 0xFE97, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E, 21274 0xFE9F, 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7, 21275 0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF, 0xFEB0, 21276 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9, 21277 0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0, 0xFEC1, 0xFEC2, 21278 0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9, 0xFECA, 0xFECB, 21279 0xFECC, 0xFECD, 0xFECE, 0xFECF, 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4, 21280 0xFED5, 0xFED6, 0xFED7, 0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD, 21281 0xFEDE, 0xFEDF, 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6,
21282 0xFEE7, 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF, 21283 0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8, 21284 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0x10800, 0x10801, 0x10802, 0x10803, 21285 0x10804, 0x10805, 0x10808, 0x1080A, 0x1080B, 0x1080C, 0x1080D, 0x1080E, 21286 0x1080F, 0x10810, 0x10811, 0x10812, 0x10813, 0x10814, 0x10815, 0x10816, 21287 0x10817, 0x10818, 0x10819, 0x1081A, 0x1081B, 0x1081C, 0x1081D, 0x1081E, 21288 0x1081F, 0x10820, 0x10821, 0x10822, 0x10823, 0x10824, 0x10825, 0x10826, 21289 0x10827, 0x10828, 0x10829, 0x1082A, 0x1082B, 0x1082C, 0x1082D, 0x1082E, 21290 0x1082F, 0x10830, 0x10831, 0x10832, 0x10833, 0x10834, 0x10835, 0x10837, 21291 0x10838, 0x1083C, 0x1083F, 0x10840, 0x10841, 0x10842, 0x10843, 0x10844, 21292 0x10845, 0x10846, 0x10847, 0x10848, 0x10849, 0x1084A, 0x1084B, 0x1084C, 21293 0x1084D, 0x1084E, 0x1084F, 0x10850, 0x10851, 0x10852, 0x10853, 0x10854, 21294 0x10855, 0x10857, 0x10858, 0x10859, 0x1085A, 0x1085B, 0x1085C, 0x1085D, 21295 0x1085E, 0x1085F, 0x10900, 0x10901, 0x10902, 0x10903, 0x10904, 0x10905, 21296 0x10906, 0x10907, 0x10908, 0x10909, 0x1090A, 0x1090B, 0x1090C, 0x1090D, 21297 0x1090E, 0x1090F, 0x10910, 0x10911, 0x10912, 0x10913, 0x10914, 0x10915, 21298 0x10916, 0x10917, 0x10918, 0x10919, 0x1091A, 0x1091B, 0x10920, 0x10921, 21299 0x10922, 0x10923, 0x10924, 0x10925, 0x10926, 0x10927, 0x10928, 0x10929, 21300 0x1092A, 0x1092B, 0x1092C, 0x1092D, 0x1092E, 0x1092F, 0x10930, 0x10931, 21301 0x10932, 0x10933, 0x10934, 0x10935, 0x10936, 0x10937, 0x10938, 0x10939, 21302 0x1093F, 0x10980, 0x10981, 0x10982, 0x10983, 0x10984, 0x10985, 0x10986, 21303 0x10987, 0x10988, 0x10989, 0x1098A, 0x1098B, 0x1098C, 0x1098D, 0x1098E, 21304 0x1098F, 0x10990, 0x10991, 0x10992, 0x10993, 0x10994, 0x10995, 0x10996, 21305 0x10997, 0x10998, 0x10999, 0x1099A, 0x1099B, 0x1099C, 0x1099D, 0x1099E, 21306 0x1099F, 0x109A0, 0x109A1, 0x109A2, 0x109A3, 0x109A4, 0x109A5, 0x109A6, 21307 0x109A7, 0x109A8, 0x109A9, 0x109AA, 0x109AB, 0x109AC, 0x109AD, 0x109AE, 21308 0x109AF, 0x109B0, 0x109B1, 0x109B2, 0x109B3, 0x109B4, 0x109B5, 0x109B6, 21309 0x109B7, 0x109BE, 0x109BF, 0x10A00, 0x10A10, 0x10A11, 0x10A12, 0x10A13, 21310 0x10A15, 0x10A16, 0x10A17, 0x10A19, 0x10A1A, 0x10A1B, 0x10A1C, 0x10A1D, 21311 0x10A1E, 0x10A1F, 0x10A20, 0x10A21, 0x10A22, 0x10A23, 0x10A24, 0x10A25, 21312 0x10A26, 0x10A27, 0x10A28, 0x10A29, 0x10A2A, 0x10A2B, 0x10A2C, 0x10A2D, 21313 0x10A2E, 0x10A2F, 0x10A30, 0x10A31, 0x10A32, 0x10A33, 0x10A40, 0x10A41, 21314 0x10A42, 0x10A43, 0x10A44, 0x10A45, 0x10A46, 0x10A47, 0x10A50, 0x10A51, 21315 0x10A52, 0x10A53, 0x10A54, 0x10A55, 0x10A56, 0x10A57, 0x10A58, 0x10A60, 21316 0x10A61, 0x10A62, 0x10A63, 0x10A64, 0x10A65, 0x10A66, 0x10A67, 0x10A68, 21317 0x10A69, 0x10A6A, 0x10A6B, 0x10A6C, 0x10A6D, 0x10A6E, 0x10A6F, 0x10A70, 21318 0x10A71, 0x10A72, 0x10A73, 0x10A74, 0x10A75, 0x10A76, 0x10A77, 0x10A78, 21319 0x10A79, 0x10A7A, 0x10A7B, 0x10A7C, 0x10A7D, 0x10A7E, 0x10A7F, 0x10B00, 21320 0x10B01, 0x10B02, 0x10B03, 0x10B04, 0x10B05, 0x10B06, 0x10B07, 0x10B08, 21321 0x10B09, 0x10B0A, 0x10B0B, 0x10B0C, 0x10B0D, 0x10B0E, 0x10B0F, 0x10B10, 21322 0x10B11, 0x10B12, 0x10B13, 0x10B14, 0x10B15, 0x10B16, 0x10B17, 0x10B18, 21323 0x10B19, 0x10B1A, 0x10B1B, 0x10B1C, 0x10B1D, 0x10B1E, 0x10B1F, 0x10B20, 21324 0x10B21, 0x10B22, 0x10B23, 0x10B24, 0x10B25, 0x10B26, 0x10B27, 0x10B28, 21325 0x10B29, 0x10B2A, 0x10B2B, 0x10B2C, 0x10B2D, 0x10B2E, 0x10B2F, 0x10B30, 21326 0x10B31, 0x10B32, 0x10B33, 0x10B34, 0x10B35, 0x10B40, 0x10B41, 0x10B42, 21327 0x10B43, 0x10B44, 0x10B45, 0x10B46, 0x10B47, 0x10B48, 0x10B49, 0x10B4A, 21328 0x10B4B, 0x10B4C, 0x10B4D, 0x10B4E, 0x10B4F, 0x10B50, 0x10B51, 0x10B52, 21329 0x10B53, 0x10B54, 0x10B55, 0x10B58, 0x10B59, 0x10B5A, 0x10B5B, 0x10B5C, 21330 0x10B5D, 0x10B5E, 0x10B5F, 0x10B60, 0x10B61, 0x10B62, 0x10B63, 0x10B64, 21331 0x10B65, 0x10B66, 0x10B67, 0x10B68, 0x10B69, 0x10B6A, 0x10B6B, 0x10B6C, 21332 0x10B6D, 0x10B6E, 0x10B6F, 0x10B70, 0x10B71, 0x10B72, 0x10B78, 0x10B79, 21333 0x10B7A, 0x10B7B, 0x10B7C, 0x10B7D, 0x10B7E, 0x10B7F, 0x10C00, 0x10C01, 21334 0x10C02, 0x10C03, 0x10C04, 0x10C05, 0x10C06, 0x10C07, 0x10C08, 0x10C09, 21335 0x10C0A, 0x10C0B, 0x10C0C, 0x10C0D, 0x10C0E, 0x10C0F, 0x10C10, 0x10C11, 21336 0x10C12, 0x10C13, 0x10C14, 0x10C15, 0x10C16, 0x10C17, 0x10C18, 0x10C19, 21337 0x10C1A, 0x10C1B, 0x10C1C, 0x10C1D, 0x10C1E, 0x10C1F, 0x10C20, 0x10C21, 21338 0x10C22, 0x10C23, 0x10C24, 0x10C25, 0x10C26, 0x10C27, 0x10C28, 0x10C29, 21339 0x10C2A, 0x10C2B, 0x10C2C, 0x10C2D, 0x10C2E, 0x10C2F, 0x10C30, 0x10C31, 21340 0x10C32, 0x10C33, 0x10C34, 0x10C35, 0x10C36, 0x10C37, 0x10C38, 0x10C39, 21341 0x10C3A, 0x10C3B, 0x10C3C, 0x10C3D, 0x10C3E, 0x10C3F, 0x10C40, 0x10C41, 21342 0x10C42, 0x10C43, 0x10C44, 0x10C45, 0x10C46, 0x10C47, 0x10C48, 0x1EE00, 21343 0x1EE01, 0x1EE02, 0x1EE03, 0x1EE05, 0x1EE06, 0x1EE07, 0x1EE08, 0x1EE09, 21344 0x1EE0A, 0x1EE0B, 0x1EE0C, 0x1EE0D, 0x1EE0E, 0x1EE0F, 0x1EE10, 0x1EE11, 21345 0x1EE12, 0x1EE13, 0x1EE14, 0x1EE15, 0x1EE16, 0x1EE17, 0x1EE18, 0x1EE19, 21346 0x1EE1A, 0x1EE1B, 0x1EE1C, 0x1EE1D, 0x1EE1E, 0x1EE1F, 0x1EE21, 0x1EE22, 21347 0x1EE24, 0x1EE27, 0x1EE29, 0x1EE2A, 0x1EE2B, 0x1EE2C, 0x1EE2D, 0x1EE2E, 21348 0x1EE2F, 0x1EE30, 0x1EE31, 0x1EE32, 0x1EE34, 0x1EE35, 0x1EE36, 0x1EE37, 21349 0x1EE39, 0x1EE3B, 0x1EE42, 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE4D, 0x1EE4E, 21350 0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE57, 0x1EE59, 0x1EE5B, 0x1EE5D, 21351 0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE67, 0x1EE68, 0x1EE69, 0x1EE6A, 21352 0x1EE6C, 0x1EE6D, 0x1EE6E, 0x1EE6F, 0x1EE70, 0x1EE71, 0x1EE72, 0x1EE74, 21353 0x1EE75, 0x1EE76, 0x1EE77, 0x1EE79, 0x1EE7A, 0x1EE7B, 0x1EE7C, 0x1EE7E, 21354 0x1EE80, 0x1EE81, 0x1EE82, 0x1EE83, 0x1EE84, 0x1EE85, 0x1EE86, 0x1EE87, 21355 0x1EE88, 0x1EE89, 0x1EE8B, 0x1EE8C, 0x1EE8D, 0x1EE8E, 0x1EE8F, 0x1EE90, 21356 0x1EE91, 0x1EE92, 0x1EE93, 0x1EE94, 0x1EE95, 0x1EE96, 0x1EE97, 0x1EE98, 21357 0x1EE99, 0x1EE9A, 0x1EE9B, 0x1EEA1, 0x1EEA2, 0x1EEA3, 0x1EEA5, 0x1EEA6, 21358 0x1EEA7, 0x1EEA8, 0x1EEA9, 0x1EEAB, 0x1EEAC, 0x1EEAD, 0x1EEAE, 0x1EEAF, 21359 0x1EEB0, 0x1EEB1, 0x1EEB2, 0x1EEB3, 0x1EEB4, 0x1EEB5, 0x1EEB6, 0x1EEB7, 21360 0x1EEB8, 0x1EEB9, 0x1EEBA, 0x1EEBB, 0x10FFFD]; 21361 21362 function determineBidi(cueDiv) { 21363 var nodeStack = [], 21364 text = "",
vendor: 6,425 bytes, lines 21365-21568
21365 charCode; 21366 21367 if (!cueDiv || !cueDiv.childNodes) { 21368 return "ltr"; 21369 } 21370 21371 function pushNodes(nodeStack, node) { 21372 for (var i = node.childNodes.length - 1; i >= 0; i--) { 21373 nodeStack.push(node.childNodes[i]); 21374 } 21375 } 21376 21377 function nextTextNode(nodeStack) { 21378 if (!nodeStack || !nodeStack.length) { 21379 return null; 21380 } 21381 21382 var node = nodeStack.pop(), 21383 text = node.textContent || node.innerText; 21384 if (text) { 21385 // TODO: This should match all unicode type B characters (paragraph 21386 // separator characters). See issue #115. 21387 var m = text.match(/^.*(\n|\r)/); 21388 if (m) { 21389 nodeStack.length = 0; 21390 return m[0]; 21391 } 21392 return text; 21393 } 21394 if (node.tagName === "ruby") { 21395 return nextTextNode(nodeStack); 21396 } 21397 if (node.childNodes) { 21398 pushNodes(nodeStack, node); 21399 return nextTextNode(nodeStack); 21400 } 21401 } 21402 21403 pushNodes(nodeStack, cueDiv); 21404 while ((text = nextTextNode(nodeStack))) { 21405 for (var i = 0; i < text.length; i++) { 21406 charCode = text.charCodeAt(i); 21407 for (var j = 0; j < strongRTLChars.length; j++) { 21408 if (strongRTLChars[j] === charCode) { 21409 return "rtl"; 21410 } 21411 } 21412 } 21413 } 21414 return "ltr"; 21415 } 21416 21417 function computeLinePos(cue) { 21418 if (typeof cue.line === "number" && 21419 (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) { 21420 return cue.line; 21421 } 21422 if (!cue.track || !cue.track.textTrackList || 21423 !cue.track.textTrackList.mediaElement) { 21424 return -1; 21425 } 21426 var track = cue.track, 21427 trackList = track.textTrackList, 21428 count = 0; 21429 for (var i = 0; i < trackList.length && trackList[i] !== track; i++) { 21430 if (trackList[i].mode === "showing") { 21431 count++; 21432 } 21433 } 21434 return ++count * -1; 21435 } 21436 21437 function StyleBox() { 21438 } 21439 21440 // Apply styles to a div. If there is no div passed then it defaults to the 21441 // div on 'this'. 21442 StyleBox.prototype.applyStyles = function(styles, div) { 21443 div = div || this.div; 21444 for (var prop in styles) { 21445 if (styles.hasOwnProperty(prop)) { 21446 div.style[prop] = styles[prop]; 21447 } 21448 } 21449 }; 21450 21451 StyleBox.prototype.formatStyle = function(val, unit) { 21452 return val === 0 ? 0 : val + unit; 21453 }; 21454 21455 // Constructs the computed display state of the cue (a div). Places the div 21456 // into the overlay which should be a block level element (usually a div). 21457 function CueStyleBox(window, cue, styleOptions) { 21458 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); 21459 var color = "rgba(255, 255, 255, 1)"; 21460 var backgroundColor = "rgba(0, 0, 0, 0.8)"; 21461 21462 if (isIE8) { 21463 color = "rgb(255, 255, 255)"; 21464 backgroundColor = "rgb(0, 0, 0)"; 21465 } 21466 21467 StyleBox.call(this); 21468 this.cue = cue; 21469 21470 // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will 21471 // have inline positioning and will function as the cue background box. 21472 this.cueDiv = parseContent(window, cue.text); 21473 var styles = { 21474 color: color, 21475 backgroundColor: backgroundColor, 21476 position: "relative", 21477 left: 0, 21478 right: 0, 21479 top: 0, 21480 bottom: 0, 21481 display: "inline" 21482 }; 21483 21484 if (!isIE8) { 21485 styles.writingMode = cue.vertical === "" ? "horizontal-tb" 21486 : cue.vertical === "lr" ? "vertical-lr" 21487 : "vertical-rl"; 21488 styles.unicodeBidi = "plaintext"; 21489 } 21490 this.applyStyles(styles, this.cueDiv); 21491 21492 // Create an absolutely positioned div that will be used to position the cue 21493 // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS 21494 // mirrors of them except "middle" which is "center" in CSS. 21495 this.div = window.document.createElement("div"); 21496 styles = { 21497 textAlign: cue.align === "middle" ? "center" : cue.align, 21498 font: styleOptions.font, 21499 whiteSpace: "pre-line", 21500 position: "absolute" 21501 }; 21502 21503 if (!isIE8) { 21504 styles.direction = determineBidi(this.cueDiv); 21505 styles.writingMode = cue.vertical === "" ? "horizontal-tb" 21506 : cue.vertical === "lr" ? "vertical-lr" 21507 : "vertical-rl". 21508 stylesunicodeBidi = "plaintext"; 21509 } 21510 21511 this.applyStyles(styles); 21512 21513 this.div.appendChild(this.cueDiv); 21514 21515 // Calculate the distance from the reference edge of the viewport to the text 21516 // position of the cue box. The reference edge will be resolved later when 21517 // the box orientation styles are applied. 21518 var textPos = 0; 21519 switch (cue.positionAlign) { 21520 case "start": 21521 textPos = cue.position; 21522 break; 21523 case "middle": 21524 textPos = cue.position - (cue.size / 2); 21525 break; 21526 case "end": 21527 textPos = cue.position - cue.size; 21528 break; 21529 } 21530 21531 // Horizontal box orientation; textPos is the distance from the left edge of the 21532 // area to the left edge of the box and cue.size is the distance extending to 21533 // the right from there. 21534 if (cue.vertical === "") { 21535 this.applyStyles({ 21536 left: this.formatStyle(textPos, "%"), 21537 width: this.formatStyle(cue.size, "%") 21538 }); 21539 // Vertical box orientation; textPos is the distance from the top edge of the 21540 // area to the top edge of the box and cue.size is the height extending 21541 // downwards from there. 21542 } else { 21543 this.applyStyles({ 21544 top: this.formatStyle(textPos, "%"), 21545 height: this.formatStyle(cue.size, "%") 21546 }); 21547 } 21548 21549 this.move = function(box) { 21550 this.applyStyles({ 21551 top: this.formatStyle(box.top, "px"), 21552 bottom: this.formatStyle(box.bottom, "px"), 21553 left: this.formatStyle(box.left, "px"), 21554 right: this.formatStyle(box.right, "px"), 21555 height: this.formatStyle(box.height, "px"), 21556 width: this.formatStyle(box.width, "px") 21557 }); 21558 }; 21559 } 21560 CueStyleBox.prototype = _objCreate(StyleBox.prototype); 21561 CueStyleBox.prototype.constructor = CueStyleBox; 21562 21563 // Represents the co-ordinates of an Element in a way that we can easily 21564 // compute things with such as if it overlaps or intersects with another Element. 21565 // Can initialize it with either a StyleBox or another BoxPosition. 21566 function BoxPosition(obj) { 21567 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); 21568
vendor: 11,730 bytes, lines 21569-21906
21569 // Either a BoxPosition was passed in and we need to copy it, or a StyleBox 21570 // was passed in and we need to copy the results of 'getBoundingClientRect' 21571 // as the object returned is readonly. All co-ordinate values are in reference 21572 // to the viewport origin (top left). 21573 var lh, height, width, top; 21574 if (obj.div) { 21575 height = obj.div.offsetHeight; 21576 width = obj.div.offsetWidth; 21577 top = obj.div.offsetTop; 21578 21579 var rects = (rects = obj.div.childNodes) && (rects = rects[0]) && 21580 rects.getClientRects && rects.getClientRects(); 21581 obj = obj.div.getBoundingClientRect(); 21582 // In certain cases the outter div will be slightly larger then the sum of 21583 // the inner div's lines. This could be due to bold text, etc, on some platforms. 21584 // In this case we should get the average line height and use that. This will 21585 // result in the desired behaviour. 21586 lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length) 21587 : 0; 21588 21589 } 21590 this.left = obj.left; 21591 this.right = obj.right; 21592 this.top = obj.top || top; 21593 this.height = obj.height || height; 21594 this.bottom = obj.bottom || (top + (obj.height || height)); 21595 this.width = obj.width || width; 21596 this.lineHeight = lh !== undefined ? lh : obj.lineHeight; 21597 21598 if (isIE8 && !this.lineHeight) { 21599 this.lineHeight = 13; 21600 } 21601 } 21602 21603 // Move the box along a particular axis. Optionally pass in an amount to move 21604 // the box. If no amount is passed then the default is the line height of the 21605 // box. 21606 BoxPosition.prototype.move = function(axis, toMove) { 21607 toMove = toMove !== undefined ? toMove : this.lineHeight; 21608 switch (axis) { 21609 case "+x": 21610 this.left += toMove; 21611 this.right += toMove; 21612 break; 21613 case "-x": 21614 this.left -= toMove; 21615 this.right -= toMove; 21616 break; 21617 case "+y": 21618 this.top += toMove; 21619 this.bottom += toMove; 21620 break; 21621 case "-y": 21622 this.top -= toMove; 21623 this.bottom -= toMove; 21624 break; 21625 } 21626 }; 21627 21628 // Check if this box overlaps another box, b2. 21629 BoxPosition.prototype.overlaps = function(b2) { 21630 return this.left < b2.right && 21631 this.right > b2.left && 21632 this.top < b2.bottom && 21633 this.bottom > b2.top; 21634 }; 21635 21636 // Check if this box overlaps any other boxes in boxes. 21637 BoxPosition.prototype.overlapsAny = function(boxes) { 21638 for (var i = 0; i < boxes.length; i++) { 21639 if (this.overlaps(boxes[i])) { 21640 return true; 21641 } 21642 } 21643 return false; 21644 }; 21645 21646 // Check if this box is within another box. 21647 BoxPosition.prototype.within = function(container) { 21648 return this.top >= container.top && 21649 this.bottom <= container.bottom && 21650 this.left >= container.left && 21651 this.right <= container.right; 21652 }; 21653 21654 // Check if this box is entirely within the container or it is overlapping 21655 // on the edge opposite of the axis direction passed. For example, if "+x" is 21656 // passed and the box is overlapping on the left edge of the container, then 21657 // return true. 21658 BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) { 21659 switch (axis) { 21660 case "+x": 21661 return this.left < container.left; 21662 case "-x": 21663 return this.right > container.right; 21664 case "+y": 21665 return this.top < container.top; 21666 case "-y": 21667 return this.bottom > container.bottom; 21668 } 21669 }; 21670 21671 // Find the percentage of the area that this box is overlapping with another 21672 // box. 21673 BoxPosition.prototype.intersectPercentage = function(b2) { 21674 var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)), 21675 y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)), 21676 intersectArea = x * y; 21677 return intersectArea / (this.height * this.width); 21678 }; 21679 21680 // Convert the positions from this box to CSS compatible positions using 21681 // the reference container's positions. This has to be done because this 21682 // box's positions are in reference to the viewport origin, whereas, CSS 21683 // values are in referecne to their respective edges. 21684 BoxPosition.prototype.toCSSCompatValues = function(reference) { 21685 return { 21686 top: this.top - reference.top, 21687 bottom: reference.bottom - this.bottom, 21688 left: this.left - reference.left, 21689 right: reference.right - this.right, 21690 height: this.height, 21691 width: this.width 21692 }; 21693 }; 21694 21695 // Get an object that represents the box's position without anything extra. 21696 // Can pass a StyleBox, HTMLElement, or another BoxPositon. 21697 BoxPosition.getSimpleBoxPosition = function(obj) { 21698 var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0; 21699 var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0; 21700 var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0; 21701 21702 obj = obj.div ? obj.div.getBoundingClientRect() : 21703 obj.tagName ? obj.getBoundingClientRect() : obj; 21704 var ret = { 21705 left: obj.left, 21706 right: obj.right, 21707 top: obj.top || top, 21708 height: obj.height || height, 21709 bottom: obj.bottom || (top + (obj.height || height)), 21710 width: obj.width || width 21711 }; 21712 return ret; 21713 }; 21714 21715 // Move a StyleBox to its specified, or next best, position. The containerBox 21716 // is the box that contains the StyleBox, such as a div. boxPositions are 21717 // a list of other boxes that the styleBox can't overlap with. 21718 function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) { 21719 21720 // Find the best position for a cue box, b, on the video. The axis parameter 21721 // is a list of axis, the order of which, it will move the box along. For example: 21722 // Passing ["+x", "-x"] will move the box first along the x axis in the positive 21723 // direction. If it doesn't find a good position for it there it will then move 21724 // it along the x axis in the negative direction. 21725 function findBestPosition(b, axis) { 21726 var bestPosition, 21727 specifiedPosition = new BoxPosition(b), 21728 percentage = 1; // Highest possible so the first thing we get is better. 21729 21730 for (var i = 0; i < axis.length; i++) { 21731 while (b.overlapsOppositeAxis(containerBox, axis[i]) || 21732 (b.within(containerBox) && b.overlapsAny(boxPositions))) { 21733 b.move(axis[i]); 21734 } 21735 // We found a spot where we aren't overlapping anything. This is our 21736 // best position. 21737 if (b.within(containerBox)) { 21738 return b; 21739 } 21740 var p = b.intersectPercentage(containerBox); 21741 // If we're outside the container box less then we were on our last try 21742 // then remember this position as the best position. 21743 if (percentage > p) { 21744 bestPosition = new BoxPosition(b); 21745 percentage = p; 21746 } 21747 // Reset the box position to the specified position. 21748 b = new BoxPosition(specifiedPosition); 21749 } 21750 return bestPosition || specifiedPosition; 21751 } 21752 21753 var boxPosition = new BoxPosition(styleBox), 21754 cue = styleBox.cue, 21755 linePos = computeLinePos(cue), 21756 axis = []; 21757 21758 // If we have a line number to align the cue to. 21759 if (cue.snapToLines) { 21760 var size; 21761 switch (cue.vertical) { 21762 case "": 21763 axis = [ "+y", "-y" ]; 21764 size = "height"; 21765 break; 21766 case "rl": 21767 axis = [ "+x", "-x" ]; 21768 size = "width"; 21769 break; 21770 case "lr": 21771 axis = [ "-x", "+x" ]; 21772 size = "width"; 21773 break; 21774 } 21775 21776 var step = boxPosition.lineHeight, 21777 position = step * Math.round(linePos), 21778 maxPosition = containerBox[size] + step, 21779 initialAxis = axis[0]; 21780 21781 // If the specified intial position is greater then the max position then 21782 // clamp the box to the amount of steps it would take for the box to 21783 // reach the max position. 21784 if (Math.abs(position) > maxPosition) { 21785 position = position < 0 ? -1 : 1; 21786 position *= Math.ceil(maxPosition / step) * step; 21787 } 21788 21789 // If computed line position returns negative then line numbers are 21790 // relative to the bottom of the video instead of the top. Therefore, we 21791 // need to increase our initial position by the length or width of the 21792 // video, depending on the writing direction, and reverse our axis directions. 21793 if (linePos < 0) { 21794 position += cue.vertical === "" ? containerBox.height : containerBox.width; 21795 axis = axis.reverse(); 21796 } 21797 21798 // Move the box to the specified position. This may not be its best 21799 // position. 21800 boxPosition.move(initialAxis, position); 21801 21802 } else { 21803 // If we have a percentage line value for the cue. 21804 var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100; 21805 21806 switch (cue.lineAlign) { 21807 case "middle": 21808 linePos -= (calculatedPercentage / 2); 21809 break; 21810 case "end": 21811 linePos -= calculatedPercentage; 21812 break; 21813 } 21814 21815 // Apply initial line position to the cue box. 21816 switch (cue.vertical) { 21817 case "": 21818 styleBox.applyStyles({ 21819 top: styleBox.formatStyle(linePos, "%") 21820 }); 21821 break; 21822 case "rl": 21823 styleBox.applyStyles({ 21824 left: styleBox.formatStyle(linePos, "%") 21825 }); 21826 break; 21827 case "lr": 21828 styleBox.applyStyles({ 21829 right: styleBox.formatStyle(linePos, "%") 21830 }); 21831 break; 21832 } 21833 21834 axis = [ "+y", "-x", "+x", "-y" ]; 21835 21836 // Get the box position again after we've applied the specified positioning 21837 // to it. 21838 boxPosition = new BoxPosition(styleBox); 21839 } 21840 21841 var bestPosition = findBestPosition(boxPosition, axis); 21842 styleBox.move(bestPosition.toCSSCompatValues(containerBox)); 21843 } 21844 21845 function WebVTT() { 21846 // Nothing 21847 } 21848 21849 // Helper to allow strings to be decoded instead of the default binary utf8 data. 21850 WebVTT.StringDecoder = function() { 21851 return { 21852 decode: function(data) { 21853 if (!data) { 21854 return ""; 21855 } 21856 if (typeof data !== "string") { 21857 throw new Error("Error - expected string data."); 21858 } 21859 return decodeURIComponent(encodeURIComponent(data)); 21860 } 21861 }; 21862 }; 21863 21864 WebVTT.convertCueToDOMTree = function(window, cuetext) { 21865 if (!window || !cuetext) { 21866 return null; 21867 } 21868 return parseContent(window, cuetext); 21869 }; 21870 21871 var FONT_SIZE_PERCENT = 0.05; 21872 var FONT_STYLE = "sans-serif"; 21873 var CUE_BACKGROUND_PADDING = "1.5%"; 21874 21875 // Runs the processing model over the cues and regions passed to it. 21876 // @param overlay A block level element (usually a div) that the computed cues 21877 // and regions will be placed into. 21878 WebVTT.processCues = function(window, cues, overlay) { 21879 if (!window || !cues || !overlay) { 21880 return null; 21881 } 21882 21883 // Remove all previous children. 21884 while (overlay.firstChild) { 21885 overlay.removeChild(overlay.firstChild); 21886 } 21887 21888 var paddedOverlay = window.document.createElement("div"); 21889 paddedOverlay.style.position = "absolute"; 21890 paddedOverlay.style.left = "0"; 21891 paddedOverlay.style.right = "0"; 21892 paddedOverlay.style.top = "0"; 21893 paddedOverlay.style.bottom = "0"; 21894 paddedOverlay.style.margin = CUE_BACKGROUND_PADDING; 21895 overlay.appendChild(paddedOverlay); 21896 21897 // Determine if we need to compute the display states of the cues. This could 21898 // be the case if a cue's state has been changed since the last computation or 21899 // if it has not been computed yet. 21900 function shouldCompute(cues) { 21901 for (var i = 0; i < cues.length; i++) { 21902 if (cues[i].hasBeenReset || !cues[i].displayState) { 21903 return true; 21904 } 21905 } 21906 return false;
vendor: 9,362 bytes, lines 21907-22196
21907 } 21908 21909 // We don't need to recompute the cues' display states. Just reuse them. 21910 if (!shouldCompute(cues)) { 21911 for (var i = 0; i < cues.length; i++) { 21912 paddedOverlay.appendChild(cues[i].displayState); 21913 } 21914 return; 21915 } 21916 21917 var boxPositions = [], 21918 containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay), 21919 fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100; 21920 var styleOptions = { 21921 font: fontSize + "px " + FONT_STYLE 21922 }; 21923 21924 (function() { 21925 var styleBox, cue; 21926 21927 for (var i = 0; i < cues.length; i++) { 21928 cue = cues[i]; 21929 21930 // Compute the intial position and styles of the cue div. 21931 styleBox = new CueStyleBox(window, cue, styleOptions); 21932 paddedOverlay.appendChild(styleBox.div); 21933 21934 // Move the cue div to it's correct line position. 21935 moveBoxToLinePosition(window, styleBox, containerBox, boxPositions); 21936 21937 // Remember the computed div so that we don't have to recompute it later 21938 // if we don't have too. 21939 cue.displayState = styleBox.div; 21940 21941 boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox)); 21942 } 21943 })(); 21944 }; 21945 21946 WebVTT.Parser = function(window, vttjs, decoder) { 21947 if (!decoder) { 21948 decoder = vttjs; 21949 vttjs = {}; 21950 } 21951 if (!vttjs) { 21952 vttjs = {}; 21953 } 21954 21955 this.window = window; 21956 this.vttjs = vttjs; 21957 this.state = "INITIAL"; 21958 this.buffer = ""; 21959 this.decoder = decoder || new TextDecoder("utf8"); 21960 this.regionList = []; 21961 }; 21962 21963 WebVTT.Parser.prototype = { 21964 // If the error is a ParsingError then report it to the consumer if 21965 // possible. If it's not a ParsingError then throw it like normal. 21966 reportOrThrowError: function(e) { 21967 if (e instanceof ParsingError) { 21968 this.onparsingerror && this.onparsingerror(e); 21969 } else { 21970 throw e; 21971 } 21972 }, 21973 parse: function (data) { 21974 var self = this; 21975 21976 // If there is no data then we won't decode it, but will just try to parse 21977 // whatever is in buffer already. This may occur in circumstances, for 21978 // example when flush() is called. 21979 if (data) { 21980 // Try to decode the data that we received. 21981 self.buffer += self.decoder.decode(data, {stream: true}); 21982 } 21983 21984 function collectNextLine() { 21985 var buffer = self.buffer; 21986 var pos = 0; 21987 while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') { 21988 ++pos; 21989 } 21990 var line = buffer.substr(0, pos); 21991 // Advance the buffer early in case we fail below. 21992 if (buffer[pos] === '\r') { 21993 ++pos; 21994 } 21995 if (buffer[pos] === '\n') { 21996 ++pos; 21997 } 21998 self.buffer = buffer.substr(pos); 21999 return line; 22000 } 22001 22002 // 3.4 WebVTT region and WebVTT region settings syntax 22003 function parseRegion(input) { 22004 var settings = new Settings(); 22005 22006 parseOptions(input, function (k, v) { 22007 switch (k) { 22008 case "id": 22009 settings.set(k, v); 22010 break; 22011 case "width": 22012 settings.percent(k, v); 22013 break; 22014 case "lines": 22015 settings.integer(k, v); 22016 break; 22017 case "regionanchor": 22018 case "viewportanchor": 22019 var xy = v.split(','); 22020 if (xy.length !== 2) { 22021 break; 22022 } 22023 // We have to make sure both x and y parse, so use a temporary 22024 // settings object here. 22025 var anchor = new Settings(); 22026 anchor.percent("x", xy[0]); 22027 anchor.percent("y", xy[1]); 22028 if (!anchor.has("x") || !anchor.has("y")) { 22029 break; 22030 } 22031 settings.set(k + "X", anchor.get("x")); 22032 settings.set(k + "Y", anchor.get("y")); 22033 break; 22034 case "scroll": 22035 settings.alt(k, v, ["up"]); 22036 break; 22037 } 22038 }, /=/, /\s/); 22039 22040 // Create the region, using default values for any values that were not 22041 // specified. 22042 if (settings.has("id")) { 22043 var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)(); 22044 region.width = settings.get("width", 100); 22045 region.lines = settings.get("lines", 3); 22046 region.regionAnchorX = settings.get("regionanchorX", 0); 22047 region.regionAnchorY = settings.get("regionanchorY", 100); 22048 region.viewportAnchorX = settings.get("viewportanchorX", 0); 22049 region.viewportAnchorY = settings.get("viewportanchorY", 100); 22050 region.scroll = settings.get("scroll", ""); 22051 // Register the region. 22052 self.onregion && self.onregion(region); 22053 // Remember the VTTRegion for later in case we parse any VTTCues that 22054 // reference it. 22055 self.regionList.push({ 22056 id: settings.get("id"), 22057 region: region 22058 }); 22059 } 22060 } 22061 22062 // 3.2 WebVTT metadata header syntax 22063 function parseHeader(input) { 22064 parseOptions(input, function (k, v) { 22065 switch (k) { 22066 case "Region": 22067 // 3.3 WebVTT region metadata header syntax 22068 parseRegion(v); 22069 break; 22070 } 22071 }, /:/); 22072 } 22073 22074 // 5.1 WebVTT file parsing. 22075 try { 22076 var line; 22077 if (self.state === "INITIAL") { 22078 // We can't start parsing until we have the first line. 22079 if (!/\r\n|\n/.test(self.buffer)) { 22080 return this; 22081 } 22082 22083 line = collectNextLine(); 22084 22085 var m = line.match(/^WEBVTT([ \t].*)?$/); 22086 if (!m || !m[0]) { 22087 throw new ParsingError(ParsingError.Errors.BadSignature); 22088 } 22089 22090 self.state = "HEADER"; 22091 } 22092 22093 var alreadyCollectedLine = false; 22094 while (self.buffer) { 22095 // We can't parse a line until we have the full line. 22096 if (!/\r\n|\n/.test(self.buffer)) { 22097 return this; 22098 } 22099 22100 if (!alreadyCollectedLine) { 22101 line = collectNextLine(); 22102 } else { 22103 alreadyCollectedLine = false; 22104 } 22105 22106 switch (self.state) { 22107 case "HEADER": 22108 // 13-18 - Allow a header (metadata) under the WEBVTT line. 22109 if (/:/.test(line)) { 22110 parseHeader(line); 22111 } else if (!line) { 22112 // An empty line terminates the header and starts the body (cues). 22113 self.state = "ID"; 22114 } 22115 continue; 22116 case "NOTE": 22117 // Ignore NOTE blocks. 22118 if (!line) { 22119 self.state = "ID"; 22120 } 22121 continue; 22122 case "ID": 22123 // Check for the start of NOTE blocks. 22124 if (/^NOTE($|[ \t])/.test(line)) { 22125 self.state = "NOTE"; 22126 break; 22127 } 22128 // 19-29 - Allow any number of line terminators, then initialize new cue values. 22129 if (!line) { 22130 continue; 22131 } 22132 self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, ""); 22133 self.state = "CUE"; 22134 // 30-39 - Check if self line contains an optional identifier or timing data. 22135 if (line.indexOf("-->") === -1) { 22136 self.cue.id = line; 22137 continue; 22138 } 22139 // Process line as start of a cue. 22140 /*falls through*/ 22141 case "CUE": 22142 // 40 - Collect cue timings and settings. 22143 try { 22144 parseCue(line, self.cue, self.regionList); 22145 } catch (e) { 22146 self.reportOrThrowError(e); 22147 // In case of an error ignore rest of the cue. 22148 self.cue = null; 22149 self.state = "BADCUE"; 22150 continue; 22151 } 22152 self.state = "CUETEXT"; 22153 continue; 22154 case "CUETEXT": 22155 var hasSubstring = line.indexOf("-->") !== -1; 22156 // 34 - If we have an empty line then report the cue. 22157 // 35 - If we have the special substring '-->' then report the cue, 22158 // but do not collect the line as we need to process the current 22159 // one as a new cue. 22160 if (!line || hasSubstring && (alreadyCollectedLine = true)) { 22161 // We are done parsing self cue. 22162 self.oncue && self.oncue(self.cue); 22163 self.cue = null; 22164 self.state = "ID"; 22165 continue; 22166 } 22167 if (self.cue.text) { 22168 self.cue.text += "\n"; 22169 } 22170 self.cue.text += line; 22171 continue; 22172 case "BADCUE": // BADCUE 22173 // 54-62 - Collect and discard the remaining cue. 22174 if (!line) { 22175 self.state = "ID"; 22176 } 22177 continue; 22178 } 22179 } 22180 } catch (e) { 22181 self.reportOrThrowError(e); 22182 22183 // If we are currently parsing a cue, report what we have. 22184 if (self.state === "CUETEXT" && self.cue && self.oncue) { 22185 self.oncue(self.cue); 22186 } 22187 self.cue = null; 22188 // Enter BADWEBVTT state if header was not parsed correctly otherwise 22189 // another exception occurred so enter BADCUE state. 22190 self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE"; 22191 } 22192 return this; 22193 }, 22194 flush: function () { 22195 var self = this; 22196 try {
22197 // Finish decoding the stream. 22198 self.buffer += self.decoder.decode(); 22199 // Synthesize the end of the current cue or region. 22200 if (self.cue || self.state === "HEADER") { 22201 self.buffer += "\n\n"; 22202 self.parse(); 22203 } 22204 // If we've flushed, parsed, and we're still on the INITIAL state then 22205 // that means we don't have enough of the stream to parse the first 22206 // line. 22207 if (self.state === "INITIAL") { 22208 throw new ParsingError(ParsingError.Errors.BadSignature); 22209 } 22210 } catch(e) { 22211 self.reportOrThrowError(e); 22212 } 22213 self.onflush && self.onflush(); 22214 return this; 22215 } 22216 }; 22217 22218 global.WebVTT = WebVTT; 22219 22220}(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.